; © 1998 Russian Digital Computing
; e-mail: rdc@cch.pmc.ru

;	bchg.b	#1,$bfe001	; versatile universal debugging tool =)

	include	rdc_macros.i

	include	/system
	include	intuition/intuition.i
	include	intuition/intuition_lib.i
	include	exec/exec_lib.i
	include	exec/execbase.i
	include	graphics/graphics_lib.i
	include	graphics/displayinfo.i
	include	graphics/gfxbase.i
	include	exec/memory.i
	include	libraries/dos_lib.i
	include	libraries/dos.i
	include	libraries/reqtools.i
	include	libraries/reqtools_lib.i
	include	libraries/locale.i
	include	libraries/locale_lib.i
	include	libraries/gadtools.i
	include	libraries/xpkmaster_lib.i
	include	libraries/xpk.i
	include	dos/dosextens.i
	include	dos/dostags.i
	include workbench/workbench.i
	include workbench/icon_lib.i
	include workbench/startup.i
	include	utility/utility.i

	STRUCTURE bkemulBase,LIB_SIZE
	UWORD	unused
	ULONG	_bb_SysBase
	ULONG	_bb_SegList
	ULONG	_bb_ColorTable
	ULONG	_bb_ROM
	LABEL	bkemulBase_SIZEOF

p0	equr	a0
p1	equr	a1
p2	equr	a2
p3	equr	a3
p4	equr	d0
p5	equr	d1
p6	equr	d2
p7	equr	d3

PC_sp	equ	18
SP_sp	equ	14
R5_sp	equ	10
R4_sp	equ	6
R3_sp	equ	50
R2_sp	equ	46
R1_sp	equ	42
R0_sp	equ	38
A4_sp	equ	52

ALL_BREAKF	equ	$f000

;------------------------------------------------
; Beginning init
;
	_SECTION
start	_STARTUP
	_OPENLIBS openlibs_table
	_NEXTERR
	btst.b	#1,AttnFlags+1(a6)	;check CPU type (68020 required)
	beq	err_exit
	_NEXTERR
	tst.l	_bkemulBase
	beq	err_exit
	_NEXTERR
	_NEXTERR
	tst.l	_ReqToolsBase
	beq.s	.cant_open_reqtools
	sub.l	a0,a0
	moveq.l	#RT_FILEREQ,d0
	CALLRT	rtAllocRequestA
	move.l	d0,emt_filereq
.cant_open_reqtools

	move.l	WB_return_message,a0
	tst.l	a0			;started from WB?
	bne.s	started_from_WB
	move.l	#rdargs_template,d1	;started from CLI
	move.l	#rdargs_array,d2
	clr.l	d3
	CALLDOS	ReadArgs
	move.l	d0,args
	bne.s	10$
	bra	err_exit
10$	_NEXTERR
	move.l	rdargs_array,a0
	tst.l	a0
	bne.s	filename_present
	clr.l	-(sp)
	bra.s	filename_absent
started_from_WB
	_NEXTERR
	move.l	sm_ArgList(a0),a1
	moveq.l	#1,d0
	cmp.l	sm_NumArgs(a0),d0
	beq.s	.one_arg_passed
	addq.l	#wa_SIZEOF,a1
.one_arg_passed
	move.l	(a1)+,d1
	move.l	(a1),-(sp)
	CALLDOS	CurrentDir
	move.l	(sp)+,a0
	tst.l	a0
	beq.s	no_dir_lock_needed
filename_present
	move.l	a0,emt36_block_ptr	;pointer to started file name
	CALLICON GetDiskObjectNew
	move.l	d0,disk_object
	beq.s	no_dir_lock_needed
	move.l	d0,a0
	move.l	do_ToolTypes(a0),-(sp)
filename_absent
	lea	tooltype_table,a2
.next_tooltype
	move.l	(a2)+,a1
	tst.l	a1
	beq.s	.end_tooltype
	clr.l	d0
	move.l	(sp),a0
	tst.l	a0			;icon present?
	beq.s	10$			;no
	move.l	a2,-(sp)
	CALLICON FindToolType
	move.l	(sp)+,a2
10$	move.l	(a2)+,a1
	move.l	(a2)+,a0
	tst.l	a0
	beq.s	20$
	move.l	(a0),d1
	beq.s	20$
	move.l	d1,d0
20$	move.l	d0,a0
	tst.l	(a2)+
	tst.l	d0
	jsr	(a1)
	tst.l	return_code
	beq.s	.next_tooltype
.end_tooltype
	tst.l	(sp)+
no_dir_lock_needed
	tst.l	return_code
	bne	err_exit
	_NEXTERR


	section	data_l

tooltype_table	dc.l	_tt_lang,_tth_lang,rdarg_language,0
		dc.l	_tt_prefs,_tth_prefs,rdarg_prefs,0
		dc.l	_tt_patch,_tth_patch,rdarg_patch,_tte_offon
		dc.l	_tt_spd,_tth_spd,rdarg_speed,_tte_spd
		dc.l	_tt_mach,_tth_mach,rdarg_machine,_tte_mach
		dc.l	_tt_snd,_tth_snd,rdarg_sound,_tte_snd
		dc.l	_tt_vid,_tth_vid,rdarg_video,_tte_vid
		dc.l	_tt_ar,_tth_ar,rdarg_auto,_tte_offon
		dc.l	_tt_port,_tth_port,rdarg_port,_tte_port
		dc.l	_tt_nofile,_tth_nofile,0,0
		dc.l	0
		dc.l	_tt_file,_tth_file,rdarg_filename,0
		dc.l	_tt_addr,_tth_addr,rdarg_address,0
		dc.l	0

	section	bss_l

rdargs_array	ds.l	1
rdarg_prefs	ds.l	1
rdarg_language	ds.l	1
rdarg_speed	ds.l	1
rdarg_machine	ds.l	1
rdarg_sound	ds.l	1
rdarg_video	ds.l	1
rdarg_auto	ds.l	1
rdarg_port	ds.l	1
rdarg_filename	ds.l	1
rdarg_address	ds.l	1
rdarg_patch	ds.l	1

	section	data_b

config_keywords
; control options
	dc.b	'SPEED',0,'SOUND',0,'VIDEO',0,'VIEW',0,'AUTOREPEAT',0
	dc.b	'PORT',0,'HARDWARE_SCROLL',0,'PAUSE_IF_INACTIVE',0
	dc.b	'SKIP_EMPTY_LOOP',0
; misc options
	dc.b	'LANGUAGE',0,'ROMPATCH',0,'JOYSTICK_MAPPING',0
	dc.b	'JOYSTICK_MODE',0,'USE_AMIRUS',0,'LATIN_KEYMAP',0
	dc.b	'CYRILLIC_KEYMAP',0,'BLOCK_KM_MODE',0,'PRINTER',0
	dc.b	'SERIAL_MODE',0,'SERIAL_DEVICE',0,'AHI',0
	dc.b	'SOFTWARE_AY',0,'KEY_CLICK',0,'SCREEN_REFRESH_PERIOD'
	dc.b	0,'SCREEN_REFRESH_DELAY',0,'SCREEN_OFF_IF_INACTIVE',0
	dc.b	'SCREEN_OFF_IF_BACKGROUND',0,'WIN_FREE_SCALE',0
	dc.b	'WIN_BORDERLESS',0,'WIN_REFRESH_PERIOD',0
	dc.b	'WIN_OFF_IF_INACTIVE',0,'WIN_X_SIZE',0
	dc.b	'WIN_Y_SIZE',0
; startup options
	dc.b	'MACHINE',0,0


	section	data_l
config_table
; control options
	dc.l	_cfg_speed
	dc.l	_cfg_sound
	dc.l	_cfg_video
	dc.l	_cfg_view
	dc.l	_cfg_autorepeat
	dc.l	_cfg_port
	dc.l	_cfg_scroll
	dc.l	_cfg_pause_if_inactive
	dc.l	_cfg_skip_empty_loop
; misc options
	dc.l	_cfg_language
	dc.l	_cfg_rompatch
	dc.l	_cfg_joystick_mapping
	dc.l	_cfg_joystick_mode
	dc.l	_cfg_use_amirus
	dc.l	_cfg_latin_keymap
	dc.l	_cfg_cyrillic_keymap
	dc.l	_cfg_block_km_mode
	dc.l	_cfg_printer
	dc.l	_cfg_serial_mode
	dc.l	_cfg_serial_device
	dc.l	_cfg_ahi
	dc.l	_cfg_ay
	dc.l	_cfg_key_click
	dc.l	_cfg_screen_refresh_period
	dc.l	_cfg_screen_refresh_delay
	dc.l	_cfg_screen_off_if_inactive
	dc.l	_cfg_screen_off_if_background
	dc.l	_cfg_window_free_scale
	dc.l	_cfg_window_borderless
	dc.l	_cfg_window_refresh_period
	dc.l	_cfg_window_off_if_inactive
	dc.l	_cfg_window_x_size
	dc.l	_cfg_window_y_size
; startup options
	dc.l	_cfg_machine

	section	sub

_cfg_speed
_cfg_sound
_cfg_view
_cfg_port
_cfg_scroll
_cfg_pause_if_inactive
_cfg_language
_cfg_joystick_mode
_cfg_use_amirus
_cfg_latin_keymap
_cfg_cyrillic_keymap
_cfg_block_km_mode
_cfg_printer
_cfg_serial_mode
_cfg_serial_device
_cfg_ahi
_cfg_ay
_cfg_key_click
_cfg_screen_refresh_period
_cfg_screen_refresh_delay
_cfg_screen_off_if_inactive
_cfg_screen_off_if_background
_cfg_window_free_scale
_cfg_window_borderless
_cfg_window_refresh_period
_cfg_window_off_if_inactive
_cfg_window_x_size
_cfg_window_y_size
	rts

	section	data_b

_tt_lang	dc.b	'LANGUAGE',0
_tt_file	dc.b	'FILENAME',0
_tt_nofile	dc.b	'NOFILE',0
_tt_prefs	dc.b	'PREFS',0
_tt_spd		dc.b	'SPEED',0
_tt_mach	dc.b	'MACHINE',0
_tt_addr	dc.b	'ADDRESS',0
_tt_snd		dc.b	'SOUND',0
_tt_vid		dc.b	'VIDEO',0
_tt_ar		dc.b	'AUTOREPEAT',0
_tt_port	dc.b	'PORT',0
_tt_patch	dc.b	'ROMPATCH',0

_tte_spd	dc.b	'1, 2, 3, 4, 5, 6, FAST',0
_tte_mach	dc.b	'10, 10.01, 11, 11M',0
_tte_snd	dc.b	'BEEPER, COVOX, AY',0
_tte_vid	dc.b	'COLOR, MONO',0
_tte_port	dc.b	'MOUSE, R/L/U/D/A/F/_',0
_tte_offon	dc.b	'ON, OFF',0

_ct_on		dc.b	'ON',0,'YES',0,'TRUE',0,'1',0,0
_ct_off		dc.b	'OFF',0,'NO',0,'FALSE',0,'0',0,0
_ct_mono	dc.b	'MONO',0,'M',0,'1',0,0
_ct_color	dc.b	'COLOR',0,'C',0,'0',0,0
_ct_snd1	dc.b	'BEEPER',0,'COVOX',0,'AY',0,0
_ct_snd2	dc.b	'0',0,'1',0,'2',0,0
_ct_mhz		dc.b	'1',0,'2',0,'3',0,'4',0,'5',0,'6',0,0
_ct_spd		dc.b	'0',0,'F',0,'FAST',0,0
_ct_mach	dc.b	'10',0,'10.01',0,'11',0,'11M',0,0
_ct_port	dc.b	'M',0,'MOUSE',0,0

rdargs_template	dc.b	'F=File/K,Prefs/K,L=Language/K,D=Speed/K,'
		dc.b	'M=Machine/K,S=Sound/K,V=Video/K,R=AutoRepeat/K,'
		dc.b	'P=Port/K,N=FileName/K,A=Address/K,RP=ROMPatch/K',0

default_prefs	dc.b	'bkemul:bkemul.prefs',0

	section	sub

_tth_lang
	beq.s	read_catalog
	lea	faked_locale,a0
	move.l	d0,loc_PrefLanguages(a0)
read_catalog
	tst.l	_LocaleBase
	beq.s	.rts
	tst.l	catalog
	bne.s	.rts
	move.l	a2,-(sp)
	lea	catalog_name,a1
	lea	opencat_tags,a2
	CALLLOC	OpenCatalogA
	move.l	d0,-(sp)
	clr.l	d0
	lea	catalog_table,a2
10$	move.l	(sp),a0
	move.l	(a2),a1
	tst.l	a1
	beq.s	20$
	move.l	(a1),a1
	move.l	d0,-(sp)
	move.l	a2,-(sp)
	CALLLOC	GetCatalogStr
	move.l	(sp)+,a2
	move.l	(a2)+,a1
	move.l	d0,(a1)
	move.l	(sp)+,d0
	addq.l	#1,d0
	bra.s	10$
20$	move.l	(sp)+,catalog
	move.l	(sp)+,a2
.rts	rts

	section	bss_l

faked_locale	ds.l	12

	section	sub

_tth_nofile
	bne.s	.rts
	addq.l	#4,a2
	move.l	emt36_block_ptr,d1
	beq.s	.rts
	move.l	#MODE_OLDFILE,d2
	move.l	a2,-(sp)
	CALLDOS	Open
	move.l	d0,emt36_startup_handle
	move.l	(sp)+,a2
.rts	rts
_tth_patch
_cfg_rompatch
	beq.s	.rts
	bsr	compare_onoff
	bne	err_in_parameter
	move.b	d0,ROMpatch_flag
.rts	rts
_tth_file
	rts
_tth_prefs
	bne.s	10$
	lea	default_prefs,a0
10$	move.l	a0,d1
	move.l	#MODE_OLDFILE,d2
	CALLDOS	Open
	move.l	d0,prefs_filehandle
	beq	.endline
	clr.l	config_line
.nextline
	addq.l	#1,config_line
	move.l	prefs_filehandle,d1
	move.l	#config_string_buffer,d2
	moveq.l	#80,d3
	CALLDOS	FGets
	tst.l	d0
	beq.s	.endline
	move.l	d0,a0
	move.b	(a0),d0
	btst	#6,d0
	beq.s	.nextline	; comment
	bsr.s	find_line_end
	lea	config_keywords,a5
	move.l	a1,-(sp)
	bsr	compare_strings
	move.l	(sp)+,a0
	bne.s	.error
	bsr.s	find_line_end
	lea	config_table,a1
	move.l	-4(a1,d7.l*4),a1
	move.l	a0,d0
	jsr	(a1)
	tst.l	return_code
	beq.s	.nextline
.error	move.l	config_line,substrings
	addq.l	#1,return_code
	bra.s	.end
.endline
	clr.l	return_code
	_NEXTERR
.end	move.l	prefs_filehandle,d1
	beq.s	.rts
	CALLDOS	Close
.rts	rts
find_line_end
	move.l	a0,-(sp)
10$	move.b	(a0)+,d1
	beq.s	20$
	btst	#6,d1
	bne.s	10$
	move.l	a0,a1
20$	clr.b	-(a0)
.end	move.l	(sp)+,a0
	rts

	section	bss_l
prefs_filehandle	ds.l	1
config_string_buffer	ds.l	21
	section sub

_tth_spd
	beq.s	.rts
	lea	_ct_mhz,a5
	bsr	compare_strings
	bne.s	10$
	mulu.w	#1200,d7
	move.w	d7,speed
	addq.b	#1,delay_flag
.rts	rts
10$	lea	_ct_spd,a5
	bsr	compare_strings
	bne	err_in_parameter
	rts
_tth_mach
_cfg_machine
	beq.s	.rts
	lea	_ct_mach,a5
	bsr	compare_strings
	bne	err_in_parameter
	move.b	d7,machine_type
.rts	rts
_tth_addr
	rts
_tth_snd
	beq.s	.rts
	lea	_ct_snd1,a5
	bsr	compare_strings
	beq.s	10$
	lea	_ct_snd2,a5
	bsr	compare_strings
	bne	err_in_parameter
10$	move.b	d7,sound_device
.rts	rts

_tth_vid
_cfg_video
	beq.s	.rts
	lea	_ct_color,a4
	lea	_ct_mono,a5
	bsr	compare_2_values
	bne	err_in_parameter
	move.w	d0,bk_color_mode_flag
.rts	rts

_cfg_skip_empty_loop
	bsr	compare_onoff
	bne	err_in_parameter
	move.b	d0,skip_SOB_flag
	rts

_tth_ar
_cfg_autorepeat
	beq.s	.rts
	bsr	compare_onoff
	bne	err_in_parameter
	move.b	d0,autorepeat_flag
.rts	rts
_tth_port
	beq.s	.rts
	lea	_ct_port,a5
	bsr	compare_strings
	bne.s	_cfg_joystick_mapping
;	mouse set - don't done now
.rts	rts
_cfg_joystick_mapping
	move.l	a0,a4
	lea	joytempstring,a3
	moveq.w	#1,d6
20$	move.b	(a4)+,(a3)
	beq.s	40$
	tst.w	d6
	beq	err_in_parameter
	cmp.b	#"_",(a3)
	beq.s	30$
	lea	joymaptext,a5
	move.l	a0,-(sp)
	move.l	a3,a0
	bsr	compare_strings
	move.l	(sp)+,a0
	bne	err_in_parameter
	asl.l	#1,d7
	move.l	d7,a1
	add.l	#joystick_mapping-2,a1
	tst.w	(a1)
	bne	err_in_parameter
	move.w	d6,(a1)
30$	asl.w	#1,d6
	bra.s	20$
40$	move.l	#5,d7
	lea	joystick_mapping,a1
50$	tst.w	(a1)+
	beq	err_in_parameter
	dbf	d7,50$
	rts

	section	data_b

; Joystick mapping for some famous games

; WayOfHell  = ldrfu
; KLADs      = rludaf
; BolderDash = __r______d_u_l
; SuperMan   = rludaf
; Digger     = rdlfu
; HOUSE      = f___l_ru(da)
; NAVVY      = rludaf
; ZOOM       = f___rd___lu

joymaptext	dc.b	'L',0,'U',0,'R',0,'D',0,'F',0,'A',0,0

	section	bss_w

joystick_mapping	ds.w	6
joytempstring		ds.w	1

	section	sub


;
; Comparison (A1) with ON & OFF values.
; Result: non-zero - error, d0=0 - OFF, d0=1 - ON
;
compare_onoff
	lea	_ct_on,a4
	lea	_ct_off,a5
;
; Comparison (A1) with two any values.
;
compare_2_values
	move.l	a4,-(sp)
	bsr.s	compare_strings
	move.l	(sp)+,a5
	bne.s	10$
	clr.l	d0
.rts	rts
10$	bsr.s	compare_strings
	bne.s	.rts
	moveq.l	#-1,d0
	clr.l	d7
	rts

compare_strings
	clr.l	d7
10$	addq.l	#1,d7
	move.l	a5,a1
	tst.b	(a1)
	bne.s	30$
	moveq.l	#-1,d7
	rts
30$	tst.b	(a5)+
	bne.s	30$
	move.l	a0,-(sp)
40$	move.b	(a0)+,d0
	bne.s	50$
	move.b	(a1)+,d0
	bra.s	70$
50$	btst	#6,d0
	beq.s	60$
	bclr	#5,d0
60$	move.b	d0,d1
	sub.b	(a1)+,d0
	beq.s	40$
70$	move.l	(sp)+,a0
	bne.s	10$
	rts

err_in_parameter
	lea	substrings,a1
	move.l	-16(a2),(a1)+
	move.l	a0,(a1)+
	move.l	-(a2),(a1)
	move.w	#20,return_code
	rts

	section	main

; --------------------------------------
; CREATE PROCESSOR COMMAND ADDRESS TABLE
; --------------------------------------
;
; Table with 65536 addresses of opcode emulating procedures
;
generate_decode_table
	lea	ct_vm1,a0
	lea	decode_table,a1
10$	move.l	(a0)+,d0
	beq.s	generate_addressing_mode_decode_table
	move.w	(a0)+,d1
	subq.l	#1,d1
20$	move.l	d0,(a1)+
	addq.l	#4,a1
	dbf	d1,20$
	bra.s	10$

generate_addressing_mode_decode_table

	lea	amt_vm1,a0
	lea	decode_table,a1
	moveq.l	#4,d7
10$	move.l	(a0)+,d0
	beq.s	generate_time_table
	lea	4(a1,d0.l*8),a3
	move.l	(a0)+,a4
	move.l	(a0)+,d0
	move.l	(a0)+,d1
20$	move.l	a4,a2
	move.l	#63,d3
30$	move.l	d1,d2
40$	move.l	(a2),(a3)+
	add.l	d7,a3
	dbf	d2,40$
	add.l	d7,a2
	dbf	d3,30$
	dbf	d0,20$
	bra.s	10$

; create opcode timing table (sorry, fake yet)

generate_time_table
	lea	time_table,a1
	move.w	#$ffff,d0
10$	move.w	#1,(a1)+
	dbf	d0,10$

copy_ROM
	move.l	_bkemulBase,a0
	move.l	_bb_ROM(a0),a0
	lea	emul_buffer_begin,a1
	move.w	#4079,d0
10$	move.l	(a0)+,(a1)+
	move.l	(a0)+,(a1)+
	dbf	d0,10$

	tst.b	ROMpatch_flag
	beq.s	40$
	lea	ROMpatchTab,a0
	lea	emul_buffer_begin,a1
20$	move.l	(a0)+,d0
	beq.s	40$
	move.l	(a0)+,a2
	tst.l	a2
	beq.s	20$
	move.w	#@240,$201a(a1)
	lea	(a1,d0.l),a3
	clr.l	d1
	cmp.l	#$13dc,d0
	bne.s	30$
	moveq.b	#@20,d1
30$	move.b	(a2)+,d0
	beq.s	20$
	sub.b	d1,d0
	move.b	d0,(a3)+
	bra.s	30$
40$
	lea	emul_buffer_begin,a0
	move.w	#16383,d1
50$	move.w	(a0),d0
	rol.w	#8,d0
	move.w	d0,(a0)+
	dbf	d1,50$

; allocate signal
	moveq.l	#-1,d0
	CALLEXEC AllocSignal
	tst.b	d0
	bmi	err_exit
	_NEXTERR
	move.b	d0,control_proc_signal_bit
	moveq.l	#1,d1
	lsl.l	d0,d1
	move.l	d1,control_proc_signal
; emulation process creation
	move.l	#decode_proc_tags,d1
	CALLDOS	CreateNewProc
	move.l	d0,decode_proc_ptr
	beq	err_exit
; interface and refresh process creation
	move.l	#refresh_proc_tags,d1
	CALLDOS	CreateNewProc
	move.l	d0,refresh_proc_ptr
	beq	err_exit

;	move.l	d0,a0
;	move.l	#testpoint,TC_SWITCH(a0)
;	move.l	#testpoint,TC_LAUNCH(a0)
;	bset.b	#6,TC_FLAGS(a0)
;	bset.b	#7,TC_FLAGS(a0)

main_loop
	move.l	control_proc_signal,d0
	or.l	#ALL_BREAKF,d0
	CALLEXEC Wait
	and.l	#ALL_BREAKF,d0
	bne	closeall

emt36_handler
	bsr	emt36_cleanup
	lea	emt36_startup_handle,a0
	move.l	(a0),d0
	beq.s	5$
	clr.l	(a0)
	bra	emt36_startup_read
5$	move.l	emt36_block_ptr,a5
	move.l	a5,a0
	lea	6(a0),a1
	lea	temp_name_buffer,a0
	move.w	#7,d1
10$	move.w	(a1)+,d0
	rol.w	#8,d0
	move.w	d0,(a0)+
	dbf	d1,10$
	move.w	#15,d1		;name - 16 characters max
20$	move.b	-(a0),d0	;find real end of file name
	cmp.b	#32,d0
	dbhi	d1,20$		;if character code more than space
	tst.w	d1		;d1=name length minus one
	bmi	emt36_filereq	;empty name
	lea	temp_name_buffer,a0	;begin of name
	lea	name_buffer,a1
	lea	koi8_to_1251_table,a2
	clr.l	d2
30$	move.b	(a0)+,d0	;copy name to buffer for dos call
	bpl.s	40$
	cmp.b	#@240,d0
	bls.s	50$
	ext.w	d0
	move.b	(a2,d0.w),d0
	bra.s	60$
40$	cmp.b	#32,d0
	bhi.s	60$
	blo.s	50$
	addq.l	#1,d2
	bra.s	80$
50$	moveq.b	#"_",d0
60$	cmp.b	#".",d0
	bne.s	70$
	sub.l	d2,a1
70$	clr.l	d2
80$	move.b	d0,(a1)+
	dbf	d1,30$
	clr.b	(a1)+		;null terminated string
	bra	emt36_decode_operation

emt36_filereq
	move.l	emt_filereq,a1
	tst.l	a1
	beq	emt36_break		;no reqtools
	lea	name_buffer,a2
	lea	loadreq_title,a3
	lea	loadreq_tags,a0
	cmp.b	#2,1(a5)
	bne.s	.load_operation
	lea	savereq_title,a3
	lea	savereq_tags,a0
.load_operation
	CALLRT	rtFileRequestA
	tst.l	d0
	beq	emt36_break		;cancelled requester

emt36_decode_operation
	lea	name_full,a1
	move.l	a1,-(sp)
	move.l	emt_filereq,a0
	tst.l	a0
	beq.s	.no_reqtools
	move.l	rtfi_Dir(a0),a0
	move.w	#256,d0
10$	move.b	(a0)+,(a1)+
	dbeq	d0,10$
.no_reqtools
	clr.b	(a1)
	move.l	(sp)+,d1
	move.l	#name_buffer,d2
	move.l	#256,d3
	CALLDOS	AddPart
	move.l	emt36_block_ptr,a5
;	cmp.b	#2,1(a5)
;	beq	emt36_write	;command #2 - write
	cmp.b	#3,1(a5)
	bne	emt36_break


; ===================================
;  DATA PREPARING FOR LOAD OPERATION
; ===================================

emt36_read
	move.l	#MODE_OLDFILE,d2
	move.l	#name_full,d1
	CALLDOS	Open
emt36_startup_read
	move.l	d0,emt36_handle
	beq	emt36_break	;error during file open....
	move.l	d0,d1
	move.l	#fib_buffer,d2
	CALLDOS ExamineFH	;reading file info block
	tst.l	d0
	beq	emt36_break
	lea	fib_buffer+fib_Comment,a0	;comment
	clr.b	ROM_load_enable	;same flag
	clr.l	d0	;address counter
.nexts	clr.l	d1
.nextd	move.b	(a0)+,d0	;extract address from comment
	beq.s	.ends
	cmp.b	#"R",d0
	bne.s	.dig
	not.b	ROM_load_enable		;enable loading in ROM
.dig	cmp.b	#"7",d0
	bhi.s	.nexts
	sub.b	#"0",d0
	bmi.s	.nexts
	asl.w	#3,d1		;next digit
	add.w	d0,d1
	bra.s	.nextd
.ends	tst.w	d1
	bne.s	.zeroad		;address present and not zero
	lea	fib_buffer+fib_DateStamp+ds_Minute,a0	;time
	move.l	(a0)+,d1	;minutes from a.m.
	divul.l	#60,d2:d1	;d2 - minutes, d1 - hours
	lsl.w	#6,d1		;shift hours
	add.w	d2,d1		;add minutes
	lsl.w	#5,d1		;shift
	move.l	(a0)+,d2	;number of ticks from last minute
	divu.l	#100,d2		;number of seconds/2
	add.w	d2,d1		;get result - time in MS-DOS format
	bne.s	.zeroad		;(it is used on FAT disks in BK OSes)
	move.w	#@1000,d1	;in zero case
.zeroad	rol.w	#8,d1
	move.w	d1,emt36_header
	lea	fib_buffer+fib_Size,a0
	tst.w	(a0)
	bne	emt36_break	;file too big (more than 65535 bytes)
	move.l	_XpkBase,a6
	tst.l	a6
	beq.s	emt36_noXpk
	lea	emt36_xpk_tags,a0
	jsr	_LVOXpkUnpack(a6)
	tst.l	d0
	bne.s	emt36_break	;unpacking error
	tst.w	emt36_length
	beq.s	emt36_readok	;too big

emt36_break
	bsr	emt36_cleanup
	moveq.l	#1,d1
	CALLDOS	Delay
	bset.b	#1,int_flags		;STOP
	bra	main_loop

emt36_noXpk
	move.l	(a0),d0
	lea	emt36_buflen,a0
	move.l	d0,(a0)+
	move.l	d0,(a0)
	move.l	d0,-(sp)
	clr.l	d1
	CALLEXEC AllocMem
	move.l	(sp)+,d3
	move.l	d0,emt36_buffer
	beq	emt36_break
	move.l	d0,d2
	move.l	emt36_handle,d1
	CALLDOS	Read
	tst.l	d0
	bmi	emt36_break

emt36_readok
	move.w	emt36_length+2,d0
	move.w	d0,-(sp)
	rol.w	#8,d0
	move.w	d0,emt36_header+2
	bsr	emt36_close
	move.l	emt36_buffer,a0
	move.w	(sp)+,d0
	beq.s	20$
	subq.w	#1,d0
	clr.l	d1
	clr.l	d2
10$	clr.l	d3
	move.b	(a0)+,d3
	add.w	d3,d1
	addx.w	d2,d1
	dbf	d0,10$
	rol.w	#8,d1
	move.w	d1,emt36_CRC
20$	addq.b	#1,emt36_ready
	bra	main_loop

emt36_cleanup
	move.l	emt36_buffer,a1
	tst.l	a1
	beq.s	emt36_close
	move.l	emt36_buflen,d0
	CALLEXEC FreeMem
	clr.l	emt36_buffer
emt36_close
	move.l	emt36_handle,d1
	beq.s	.ret
	CALLDOS Close
	clr.l	emt36_handle
.ret	rts

; ***************
;  Error Handler
; ***************

err_exit
	tst.b	error_number
	bne	.os_v36
	clr.l	d0
	lea	intname+2,a1
	CALLEXEC OpenLibrary
	move.l	d0,_IntuitionBase
	beq	.end_exit
	lea	os_alert,a0
	clr.b	err0len+2(a0)
	moveq.l	#RECOVERY_ALERT,d0
	moveq.l	#40,d1
	CALLINT	DisplayAlert
	bra	.end_exit
.os_v36	sub.l	a0,a0
	jsr	read_catalog
	tst.l	WB_return_message	
	beq	.started_from_cli
	lea	startup_err_req_data,a1
	clr.l	d0
	move.b	error_number,d0
	lea	message_table,a4
	move.l	(a4,d0),12(a1)
	jsr	request
	bra	.end_exit

.started_from_cli
	tst.l	_DOSBase
	bne.s	.dos_already_opened
	clr.l	d0
	lea	dosname,a1
	CALLEXEC OpenLibrary
	move.l	d0,_DOSBase
	beq	.end_exit
.dos_already_opened
	clr.l	d0
	move.b	error_number,d0
	lea	message_table,a0
	move.l	(a0,d0),d1
	move.l	#substrings,d2
	CALLDOS	VPrintf
	move.l	#endstring,d1
	clr.l	d2
	CALLDOS	VPrintf
.end_exit
	move.l	#20,return_code

	section	sub

request	tst.l	emt_filereq
	bne.s	.reqtools_present	;for requester centering
	sub.l	a0,a0
	sub.l	a2,a2
	lea	substrings,a3
	CALLINT	EasyRequestArgs
	rts
.reqtools_present
	lea	req_tags,a0
	lea	8(a1),a5
	move.l	(a5)+,4(a0)
	move.l	(a5)+,a1
	move.l	(a5),a2
	move.l	emt_filereq,a3
	lea	substrings,a4
	CALLRT	rtEZRequestA
	rts

	section	main

closeall

;	move.l	#MODE_NEWFILE,d2
;	move.l	#data_file_name,d1
;	CALLDOS	Open
;	move.l	d0,emt36_handle
;	move.l	d0,d1
;	move.l	#data_buffer,d2
;	move.l	#$40000,d3
;	CALLDOS	Write
;	move.l	emt36_handle,d1
;	CALLDOS Close

fs1	tst.l	control_proc_signal
	beq.s	rt1
	move.b	control_proc_signal_bit,d0
	CALLEXEC FreeSignal
rt1	tst.l	refresh_proc_ptr	;refresh process created?
	beq.s	rt2			;no
	tst.b	control_break_flag	;refresh process terminated?
	bne.s	rt2			;yes
	addq.b	#1,refresh_break_flag	;terminate refresh
10$	move.l	#ALL_BREAKF,d0		;wait for Break signal
	CALLEXEC Wait			;(maybe received from anybody)
	tst.b	control_break_flag	;refresh process terminated?
	beq.s	10$			;NO??? Wait again...
rt2	clr.b	control_break_flag
	tst.l	decode_proc_ptr
	beq.s	cf1
	bset.b	#6,int_flags
10$	move.l	decode_proc_ptr,a1
	move.l	decode_delay_signal,d0
	CALLEXEC Signal			;start of sleeping emul proc
	move.l	#ALL_BREAKF,d0		;wait for Break signal
	CALLEXEC Wait			;(maybe received from anybody)
	tst.b	control_break_flag
	beq.s	10$
cf1	move.l	emt36_startup_handle,d1
	beq.s	cb1
	CALLDOS	Close
cb1	bsr	emt36_cleanup
	move.l	emt_filereq,a1
	tst.l	a1
	beq.s	10$
	CALLRT	rtFreeRequest
10$	move.l	disk_object,a0
	tst.l	a0
	beq.s	20$
	CALLICON FreeDiskObject
20$	move.l	catalog,a0
	tst.l	a0
	beq.s	30$
	CALLLOC	CloseCatalog
30$	move.l	args,d1
	beq.s	cl1
	CALLDOS	FreeArgs
cl1	_CLOSELIBS openlibs_table	;close all libraries
	_END

;----------------------------------------
;  SCREEN REFRESH AND CONTROL INTERFACE
;----------------------------------------
;
change_screen_mode			;prepare data for open screen
	lea	delta_buffer,a0
	move.w	#1023,d0
10$	clr.l	(a0)+
	clr.l	(a0)+
	clr.l	(a0)+
	clr.l	(a0)+
	dbf	d0,10$
	move.l	sbs_ptr,a0
	clr.l	d0
	move.w	sc_LeftEdge(a0),d0	;new screen opened over old screen
	move.w	sc_TopEdge(a0),a1	;then old screen closed
	move.l	a0,old_sbs_ptr		;
	clr.l	sbs_ptr			;
	move.l	wbs_ptr,old_wbs_ptr	;
	clr.l	wbs_ptr
	move.l	cbs_ptr,old_cbs_ptr
	clr.l	cbs_ptr
	not.b	bk_color_mode_flag
	move.b	bk_color_mode_flag,bk_color_mode
	bne.s	20$
	asl.w	#1,d0			;this is for open new screen
	move.l	d0,mono_x+4		;at same physical screen place
	move.l	a1,mono_y+4		;where was old screen
	bra.s	refresh_proc
20$	asr.w	#1,d0
	move.l	d0,color_x+4
	move.l	a1,color_y+4

refresh_proc
	tst.l	emt36_startup_handle
	beq.s	7$
3$	moveq.l	#1,d1
	CALLDOS	Delay
	subq.b	#1,startup_flag
	bne.s	3$
5$	tst.b	delay_flag
	beq.s	7$
	bset.b	#7,int_flags
7$	bsr	screen_open		;open new screen
	beq	refresh_end		;not opened - error
	bsr	get_bitplane_pointers
	clr.l	(a1)			;remove point in upper left corner
10$	move.b	#1,refresh_counter	;number of vblanks to refresh
	bsr	refresh			;do refresh
	bsr	old_screen_close	;close old screen if opened
20$	move.b	bk_color_mode_flag,d0
	cmp.b	bk_color_mode,d0	;was color mode changed?
	bne	change_screen_mode	;yes
	bsr	setjoy			;set joystick bits
	bsr	get_event		;got any event?
	beq.s	30$			;no
	btst	#9,d0			;screen close button pressed?
	bne	refresh_end		;end of process
	btst	#10,d0			;scancode?
	beq.s	205$			;no
	cmp.b	#$5f,d1			;HELP?
	bne.s	201$			;no
	tst.b	d2			;rcommand pressed?
	bpl	change_screen_mode	;no
	bchg.b	#7,int_flags		;delay on/off
201$	lea	keytab1,a0
	bsr	key_compare
	beq.s	30$
	cmp.b	#14,d1			;RUS?
	beq.s	203$			;yes
	cmp.b	#15,d1			;LAT?
	bne.s	25$			;no
	clr.b	rus_flag
	bra.s	25$
203$	move.b	d1,rus_flag
	bra.s	25$
205$	cmp.b	#27,d1			;ESC?
	bne.s	215$
	tst.b	d2
	bmi.s	207$
	bset.b	#1,int_flags		;STOP
	bra.s	30$
207$	bset.b	#0,int_flags		;RESET
	clr.b	emt36_ready
	bra.s	30$
215$	lea	keytab2,a0
	bsr.s	key_compare
25$	bsr	send_code
30$	tst.b	refresh_break_flag	;Break received?
	bne.s	refresh_end		;yes
	move.l	decode_proc_ptr,a1
	move.l	decode_delay_signal,d0
	CALLEXEC Signal			;start of sleeping emul proc
	btst	#0,$bfec01
	bne.s	40$
	bset	#6,p177716+1
40$	CALLGRAF WaitTOF		;wait for vblank
41$	subq.b	#1,refresh_counter	;decrease refresh wait counter
	bne	20$			;wait for next event
	bra	10$			;counter=zero -> refresh!

key_compare
10$	move.b	(a0)+,d7
	beq.s	20$
	move.b	(a0)+,d6
	cmp.b	d1,d7
	bne.s	10$
	move.b	d6,d1
20$	rts

refresh_end
	bsr	all_screens_close	;close all opened screens
	addq.b	#1,control_break_flag	;terminate main process
	move.l	control_proc_ptr,a1
	move.l	#ALL_BREAKF,d0
	CALLEXEC Signal			;send Break to it
	rts

get_event
	move.l	cbs_ptr,a0		;window with
	move.l	wd_UserPort(a0),a0	;screen close button
	CALLEXEC GetMsg
	tst.l	d0
	bne.s	10$			;event received
	move.l	wbs_ptr,a0		;main backdrop window
	move.l	wd_UserPort(a0),a0
	CALLEXEC GetMsg
	tst.l	d0
	beq.s	20$			;no new events
10$	move.l	d0,a1
	move.l	im_Class(a1),-(sp)	;what event
	move.w	im_Code(a1),-(sp)
	move.w	im_Qualifier(a1),-(sp)
	CALLEXEC ReplyMsg		;recycle msg
	clr.l	d1
	clr.l	d2
	move.w	(sp)+,d2
	move.w	(sp)+,d1
	move.l	(sp)+,d0
20$	rts

send_code
	btst	#6,p177716+1
	beq.s	30$
	btst	#7,p177660+1
	bne.s	30$
	bset	#7,p177660+1
	bclr	#6,p177716+1
	btst	#6,p177660+1
	bne.s	20$
	tst.b	d1
	bmi.s	12$
	tst.b	d2
	bpl.s	14$
12$	bset.b	#2,int_flags+1
	bra.s	20$
14$	bset.b	#1,int_flags+1
20$	and.w	#@177,d1
	btst	#6,d1
	beq.s	25$
	tst.b	rus_flag
	bne.s	25$
	bchg	#5,d1
25$	move.w	d1,p177662
30$	rts

screen_open
	sub.l	a0,a0
	lea	colortag,a1
	move.w	#256,wwidth
	tst.b	bk_color_mode_flag
	bne.s	10$
	lea	monotag,a1
	move.w	#512,wwidth
10$	CALLINT	OpenScreenTagList	;open screen
	move.l	d0,sbs_ptr
	beq.s	20$
	move.l	d0,sbs_cop
	lea	c_bk_screen,a0
	CALLINT	OpenWindow		;open main backdrop window
	move.l	d0,cbs_ptr
	beq.s	20$
	lea	w_bk_screen,a0
	CALLINT	OpenWindow		;open window with screen
	move.l	d0,wbs_ptr		;close button
20$	rts

all_screens_close		;close all opened screens
	move.l	wbs_ptr,a0
	clr.l	wbs_ptr
	move.l	cbs_ptr,a1
	clr.l	cbs_ptr
	move.l	sbs_ptr,a2
	clr.l	sbs_ptr
	bsr.s	screens_close
old_screen_close
	move.l	old_wbs_ptr,a0
	clr.l	old_wbs_ptr
	move.l	old_cbs_ptr,a1
	clr.l	old_cbs_ptr
	move.l	old_sbs_ptr,a2
	clr.l	old_sbs_ptr
screens_close
	move.l	a2,-(sp)
	tst.l	a0
	beq.s	10$
	move.l	a1,-(sp)
	CALLINT	CloseWindow
	move.l	(sp)+,a1
10$	move.l	a1,a0
	tst.l	a0
	beq.s	20$
	CALLINT	CloseWindow
20$	move.l	(sp),a0
	tst.l	a0
	beq.s	30$
	CALLINT	CloseScreen
	tst.l	d0
	bne.s	30$
	lea	screen_err_req_data,a1
	jsr	request
	bra.s	20$
30$	tst.l	(sp)+
	rts

refresh
	lea	emul_buffer_mid+@40000,a0	;begin screen address
	lea	@40000(a0),a4			;end screen address
	lea	delta_buffer,a5			;delta-buffer
	bsr	get_bitplane_pointers
	move.l	_bkemulBase,a3
	move.l	_bb_ColorTable(a3),a3	;color conversion table
	tst.b	bk_color_mode_flag	;color or monochrome
	bne.s	20$			;if monochrome - then get
	add.l	#$20000,a3		;second half of table
20$	clr.l	d1
	clr.l	d3
	move.w	#256,d4
	clr.l	d5
	move.w	p177664,d3
	move.w	d3,d6
	and.w	#@1000,d6
	bne.s	30$
	asr.w	#2,d4
	cmp.w	c177664,d6
	beq.s	30$
	move.w	#1535,d5
30$	move.w	d6,c177664
	sub.w	#@330,d3	;calculate real address
	and.w	#$ff,d3		;beginning of screen
	asl.w	#6,d3
	add.l	d3,a0
	subq.w	#1,d4
	clr.l	d3		;refresh cycles counter
	tst.b	bk_color_mode_flag
	beq	mono_refresh


color_refresh

CSC	MACRO
10\1$	cmp.l	(a0)+,(a5)+
	beq.s	11\1$
	move.l	(a0),(a5)
	bra.s	12\1$
11\1$	cmp.l	(a0)+,(a5)+
	beq.s	10\2$
	move.l	-(a0),-(a5)
12\1$	move.l	-(a0),-(a5)
	bsr	color_converter
	move.l	d6,\3(a1)
	move.l	d7,\3(a2)
	ENDM

10$	CSC	0,1,
	CSC	1,2,$04
	CSC	2,3,$08
	CSC	3,4,$0C
	CSC	4,5,$10
	CSC	5,6,$14
	CSC	6,7,$18
	CSC	7,8,$1C
108$	lea	32(a1),a1
	lea	32(a2),a2
	cmp.l	a0,a4
	bne.s	20$
	lea	-$4000(a0),a0
20$	dbf	d4,10$

	bsr	test_delay
	tst.w	d5
	beq.s	80$
	lea	$3000(a5),a5
	lea	$1800(a1),a1
	lea	$1800(a2),a2
30$	tst.l	-(a5)
	bne.s	50$
	tst.l	-(a5)
	beq.s	40$
	clr.l	(a5)
	bra.s	60$
40$	subq.l	#4,a1
	subq.l	#4,a2
	bra.s	70$
50$	clr.l	(a5)
	clr.l	-(a5)
60$	clr.l	-(a1)
	clr.l	-(a2)
70$	dbf	d5,30$
80$	rts


mono_refresh

CSM	MACRO
10\1$	cmp.l	(a0)+,(a5)+
	beq.s	11\1$
	move.l	(a0),(a5)
	bra.s	12\1$
11\1$	cmp.l	(a0)+,(a5)+
	beq.s	10\2$
	move.l	-(a0),-(a5)
12\1$	move.l	-(a0),-(a5)
	bsr	mono_converter
	move.l	d2,\3(a1)
	move.l	d6,\3+4(a1)
	ENDM

10$	CSM	0,1,
	CSM	1,2,$08
	CSM	2,3,$10
	CSM	3,4,$18
	CSM	4,5,$20
	CSM	5,6,$28
	CSM	6,7,$30
	CSM	7,8,$38
108$	lea	64(a1),a1
	cmp.l	a0,a4
	bne.s	20$
	lea	-$4000(a0),a0
20$	dbf	d4,10$
	bsr.s	test_delay
	tst.w	d5
	beq.s	80$
	lea	$3000(a5),a5
	lea	$3000(a1),a1
30$	tst.l	-(a5)
	bne.s	40$
	subq.l	#4,a1
	bra.s	50$
40$	clr.l	(a5)
	clr.l	-(a1)
50$	tst.l	-(a5)
	bne.s	60$
	subq.l	#4,a1
	bra.s	70$
60$	clr.l	(a5)
	clr.l	-(a1)
70$	dbf	d5,30$
80$	rts

test_delay
	btst.b	#7,int_flags		;delay on?
	bne.s	10$			;yes
	cmp.l	#1024,d3		;half screen or more was refreshed?
	blo.s	10$
	addq.b	#1,refresh_counter	;more - delay next refresh
10$	rts

get_bitplane_pointers
	move.l	sbs_ptr,a1
	move.l	sc_RastPort+rp_BitMap(a1),a1	;screen bitmap
	move.l	bm_Planes+4(a1),a2		;second bitplane
	move.l	bm_Planes(a1),a1		;first bitplane
	rts

color_converter
	addq.l	#1,d3
	addq.l	#8,a5
	move.w	(a0)+,d1
	move.w	0(a3,d1.l*2),d2
	move.b	d2,d6
	move.w	d2,d7
	rol.w	#8,d6
	move.w	(a0)+,d1
	move.w	0(a3,d1.l*2),d2
	move.b	d2,d6
	rol.w	#8,d2
	move.b	d2,d7
	swap	d6
	swap	d7
	move.w	(a0)+,d1
	move.w	0(a3,d1.l*2),d2
	move.b	d2,d6
	move.w	d2,d7
	rol.w	#8,d6
	move.w	(a0)+,d1
	move.w	0(a3,d1.l*2),d2
	move.b	d2,d6
	rol.w	#8,d2
	move.b	d2,d7
	rts

mono_converter
	addq.l	#1,d3
	addq.l	#8,a5
	move.w	(a0)+,d1
	move.w	0(a3,d1.l*2),d2
	swap	d2
	move.w	(a0)+,d1
	move.w	0(a3,d1.l*2),d2
	move.w	(a0)+,d1
	move.w	0(a3,d1.l*2),d6
	swap	d6
	move.w	(a0)+,d1
	move.w	0(a3,d1.l*2),d6
	rts


;testpoint
;	move.l	d0,-(sp)
;	movec.l	CACR,d0
;	move.l	(sp)+,d0
;	bchg.b	#1,$bfe001	; versatile universal debugging tool =)
;	rts

;------------------------------
;------------------------------
; PROCESSOR EMULATION ROUTINES
;------------------------------
;------------------------------

; ------------------
; MACRO COMMANDS SET
; ------------------
;
; Byte reading
;
BK_RB	MACRO		;reading byte (\1) to \2
	cmp.w	#@177600,\1	;check ports address space
	blo.s	*+6		;no
	bsr	rbp_\1\2	;port reading
	bchg.l	#0,\1
	move.b	(a4,\1.w),\2	;done
	ENDM
BK_RRB	MACRO		;BK_RB without \1 trashing
	move.w	\1,\2
	BK_RB	\2,\2
	ENDM

BK_IB	MACRO		;reading byte (\1) to \2
	bchg.l	#0,\1
	move.b	(a4,\1.w),\2	;done
	ENDM
BK_IRB	MACRO		;BK_IB without \1 trashing
	move.w	\1,\2
	BK_IB	\2,\2
	ENDM

; Word reading

BK_RW	MACRO		;reading word (\1) to \2
	bclr.l	#0,\1	;align to even
	cmp.w	#@177600,\1	;check ports address space
	blo.s	*+6		;no
	bsr	rwp_\1\2	;port reading
	move.w	(a4,\1.w),\2	;done
	ENDM
BK_RRW	MACRO		;BK_RW without \1 trashing
	move.w	\1,\2
	BK_RW	\2,\2
	ENDM

BK_IW	MACRO		;reading word (\1) to \2
	bclr.l	#0,\1	;align to even
	move.w	(a4,\1.w),\2	;done
	ENDM
BK_IRW	MACRO		;BK_IW without \1 trashing
	move.w	\1,\2
	BK_IW	\2,\2
	ENDM

; Byte saving

BK_NSB	MACRO		;write byte \1 to (\2)
	tst.w	\2		;check ports & ROM address space
	bpl.s	*+6		;no
	bsr	wbp_\1\2	;write to port or bus error
	move.b	\1,(a4,\2.w)	;done
	ENDM
BK_SB	MACRO		;BK_NSB plus address align
	tst.w	\2		;check ports & ROM address space
	bpl.s	*+6		;no
	bsr	wbp_\1\2	;write to port or bus error
	bchg.l	#0,\2
	move.b	\1,(a4,\2.w)	;done
	ENDM

; Word saving

BK_NSW	MACRO		;write word \1 to (\2)
	tst.w	\2		;check ports & ROM address space
	bpl.s	*+6		;no
	bsr	wwp_\1\2	;write to port or bus error
	move.w	\1,(a4,\2.w)	;done
	ENDM
BK_SW	MACRO		;BK_NSW plus address align
	bclr.l	#0,\2
	BK_NSW	\1,\2
	ENDM

;;;;;;;;;;;;;;;;

CALL	MACRO		;JSR without stack operations
	lea	*+6(pc),\2
	jmp	(\1)
	ENDM
RET	MACRO		;RTS without stack operations
	jmp	(\1)
	ENDM
RETCMD	MACRO
	bra	dc_next
	ENDM
PSW	MACRO
	move.w	ccr,d4
	and.w	#%\1,d4
	and.w	#%1111\2,d5
	or.w	d4,d5
	ENDM

rbp	MACRO
rbp_\1\2
	movem.l	d0-a6,-(sp)
	move.l	\1,a6
	bsr	rbp_
	move.w	d6,rmem
	movem.l	(sp)+,d0-a6
	move.w	rmem,\2
	addq.l	#8,(sp)
	rts
	ENDM
rwp	MACRO
rwp_\1\2
	movem.l	d0-a6,-(sp)
	move.l	\1,a6
	bsr	rwp_
	move.w	d6,rmem
	movem.l	(sp)+,d0-a6
	move.w	rmem,\2
	addq.l	#4,(sp)
	rts
	ENDM
wbp	MACRO
wbp_\1\2
	movem.l	d0-a6,-(sp)
	move.l	\2,a6
	move.l	\1,d6
	bsr	wbp_
	movem.l	(sp)+,d0-a6
	addq.l	#8,(sp)		;skip write operation
	rts
	ENDM
wwp	MACRO
wwp_\1\2
	movem.l	d0-a6,-(sp)
	move.l	\2,a6
	move.l	\1,d6
	bsr	wwp_
	movem.l	(sp)+,d0-a6
	addq.l	#4,(sp)		;skip write operation
	rts
	ENDM

dCMD	MACRO
	dc.l	\1
	dc.w	\2
	ENDM

CMD_Rx	MACRO
	dCMD	\1r0,1
	dCMD	\1r1,1
	dCMD	\1r2,1
	dCMD	\1r3,1
	dCMD	\1r4,1
	dCMD	\1r5,1
	dCMD	\1r6,1
	dCMD	\1r7,1
	dCMD	\1__,56
	ENDM
CMD_Rm	MACRO
	dCMD	\1r0,1
	dCMD	\1r1,1
	dCMD	\1r2,1
	dCMD	\1r3,1
	dCMD	\1r4,1
	dCMD	\1r5,1
	dCMD	\1r6,1
	dCMD	\1r7,1
	ENDM
CMD_Rn	MACRO
	dCMD	\1r0,64
	dCMD	\1r1,64
	dCMD	\1r2,64
	dCMD	\1r3,64
	dCMD	\1r4,64
	dCMD	\1r5,64
	dCMD	\1r6,64
	dCMD	\1r7,64
	ENDM
FCMD_Rn	MACRO
_\1r0	\1rn	p0
_\1r1	\1rn	p1
_\1r2	\1rn	p2
_\1r3	\1rn	p3
_\1r4	\1rn	p4
_\1r5	\1rn	p5
_\1r6	\1rn	p6
_\1r7	\1rn	p7
	ENDM

; -----------------
;  PORTS EMULATION
; -----------------

rmem	dc.w	0

rbp_	move.l	sp,a5
	move.w	a6,d0	;reading byte from port
	btst.l	#0,d0	;check LSbit of address
	beq.s	rwp_	;even address
	bsr.s	rwp__	;odd address
	rol.w	#8,d6	;swap bytes
	rts
rwp_	move.l	sp,a5
rwp__	move.w	a6,d0
	asr.w	#1,d0
	lea	prt_vm1,a0
	move.l	(a0,d0.w*4),a0
	tst.l	a0
	beq.s	halt
	jmp	(a0)

wbp_	move.w	a6,d0
	and.w	#$ff,d6		;clear MSbyte
	btst.l	#0,d0		;check if address even
	beq.s	wwp_		;even
	rol.w	#8,d6		;odd - write byte as MS
wwp_	move.l	sp,a5
	move.w	a6,d0
	cmp.w	#@177600,d0	;write to ports?
	blo.s	halt		;write to ROM!
	asr.w	#1,d0		;convert byte address to word address
	lea	pwt_vm1,a0	;hardware emulating routines table
	move.l	(a0,d0.w*4),a0	;select address
	tst.l	a0
	beq.s	halt		;no device response - bus error
	jmp	(a0)		;emulating device

halt	move.l	a5,sp
	addq.l	#4,sp
	movem.l	(sp)+,d0-a6	;restore registers
	move.l	decode_init_stack,sp	;restore stack
	btst.b	#0,int_flags	;check reset flag
	bne.l	reset
	btst.b	#6,int_flags	; check termination flag
	bne.l	emul_end
	moveq.l	#4,d6	;bus error exception
	bsr.l	int
	RETCMD

reset_hw
	clr.b	rus_flag
	move.w	#@100,p177660
	rts

wp177660
	move.w	p177660,d1
	bclr.l	#6,d1
	and.w	#@100,d6
	or.w	d6,d1
	move.w	d1,p177660
	rts
rp177660
	move.w	p177660,d6
	rts

rp177662
	move.w	p177662,d6
	move.w	p177660,d1
	bclr.l	#7,d1
	move.w	d1,p177660
	rts

wp177664
	and.w	#%1011111111,d6
	move.w	d6,p177664
	rts
rp177664
	move.w	p177664,d6
	rts

wp177716
	cmp.w	#@116650,PC_sp(a5)
	beq.s	20$
	tst.b	emt36_ready
	beq.s	30$
	cmp.w	#@116710,PC_sp(a5)
	beq.s	10$
	cmp.w	#@116232,PC_sp(a5)
	beq.s	10$
	tst.w	PC_sp(a5)
	bmi.s	30$
10$	clr.b	emt36_ready
	bra.s	30$
20$	move.w	R1_sp(a5),a0
	add.l	A4_sp(a5),a0
	move.l	a0,emt36_block_ptr
	move.l	control_proc_signal,d0
	move.l	control_proc_ptr,a1
	CALLEXEC Signal
30$	rts
rp177716
	lea	emt36_ready,a2
	tst.b	(a2)
	beq	end_716
	cmp.w	#@117410,PC_sp(a5)
	beq.s	10$
	cmp.w	#@117436,PC_sp(a5)
	bne	60$
10$	move.l	emt36_pointer,a0
	move.l	A4_sp(a5),a1	;frame pointer
	move.w	SP_sp(a5),d0	;stack pointer
	move.w	2(a1,d0.w),d3
	move.w	R1_sp(a5),d1	;address of reading block
	move.w	R2_sp(a5),d2	;length of reading block
	subq.w	#1,d2		;for dbf
20$	move.w	d1,d0
	bchg.l	#0,d0		;change bytes order
	bpl.s	30$
	tst.b	ROM_load_enable
	beq.s	40$		;ROM address
30$	move.b	(a0)+,(a1,d0.w)
	addq.w	#1,d1
	dbf	d2,20$
	move.w	SP_sp(a5),d0
	move.w	#@117374,(a1,d0.w)	;change return address
	clr.w	R0_sp(a5)
	cmp.b	#3,(a2)			;CRC read completed?
	bne.s	40$
	move.w	2(a1,d0.w),d1
	cmp.w	d3,d1			;check if stack was modified
	bne.s	40$			;yes
	move.w	#@117242,2(a1,d0.w)	;disable CRC calculation
	move.w	emt36_CRC,d1
	rol.w	#8,d1
	move.w	d1,R0_sp(a5)		;fake CRC
	clr.b	emt36_ready
40$	addq.w	#1,d2
	move.w	d2,R2_sp(a5)
	move.w	d1,R1_sp(a5)
	move.w	#@117432,PC_sp(a5)
	addq.b	#1,(a2)
	cmp.b	#2,(a2)
	beq.s	50$
	move.l	#emt36_CRC,emt36_pointer
	move.b	#1,startup_flag
	bra	end_716
50$	move.l	emt36_buffer,emt36_pointer
	bra	end_716
60$	cmp.w	#@117300,PC_sp(a5)
	bne.s	70$
	move.w	#@117336,PC_sp(a5)
	bra	end_716
70$	cmp.w	#@116724,PC_sp(a5)
	beq.s	80$
	cmp.w	#@116732,PC_sp(a5)
	bne.s	90$
80$	move.w	#10,@314(a1)
	move.w	#@117060,PC_sp(a5)
	move.l	#emt36_header,emt36_pointer
	bra	end_716
90$	tst.w	PC_sp(a5)
	bmi.s	end_716
	clr.b	emt36_ready
end_716	move.w	p177716,d6
	rts


wp177714
	rts
rp177714
	move.w	p177714,d6
	rts

setjoy	clr.l	d6	;joystick emulation
	lea	joystick_mapping,a0
	move.w	$dff00c,d0
	btst.l	#9,d0
	beq.s	10$
	or.w	(a0),d6
;	bset.l	#1,d6	;left
	btst.l	#8,d0
	bne.s	30$
	bra.s	20$
10$	btst.l	#8,d0
	beq.s	30$
20$
	or.w	2(a0),d6
;	bset.l	#2,d6	;forward
30$	btst.l	#1,d0
	beq.s	40$
	or.w	4(a0),d6
;	bset.l	#0,d6	;right
	btst.l	#0,d0
	bne.s	60$
	bra.s	50$
40$	btst.l	#0,d0
	beq.s	60$
50$
	or.w	6(a0),d6
;	bset.l	#3,d6	;back
60$	tst.b	$bfe001
	bmi.s	70$
	or.w	8(a0),d6
;	bset.l	#5,d6	;fire0
70$	btst.b	#6,$dff016
	bne.s	80$
	or.w	10(a0),d6
;	bset.l	#4,d6	;fire1
80$	move.w	d6,p177714
	rts


rp177700
	rts
rp177702
	rts
rp177704
	rts
rp177706
	rts
rp177710
	rts
rp177712
	rts

wp177700
	rts
wp177702
	rts
wp177704
	rts
wp177706
	rts
wp177710
	rts
wp177712
	rts


	wbp	d4,d6
	wbp	d6,d7
	rbp	d4,d4
	rbp	d7,d6
	rbp	d6,d5
	rbp	d4,d5
	rwp	d4,d4
	rwp	d6,d3
	rwp	d4,d3
	rwp	d7,d7
	rwp	d7,d6
	rwp	d1,d1
	wwp	d3,d4
	wwp	d5,d4
	wwp	d4,d7
	wwp	d4,d6
	wwp	d6,d7

; ----------------------------
;  OPCODES EMULATING ROUTINES
; ----------------------------
;
; Software exceptions
;
_halt__	moveq.l	#4,d6
	bra.s	intc
_rsrv__	moveq.l	#@10,d6
	bra.s	intc
_bpt___	moveq.l	#@14,d6
	bra.s	intc
_iot___	moveq.l	#@20,d6
	bra.s	intc
_emt___	moveq.l	#@30,d6
	bra.s	intc
_trap__	moveq.l	#@34,d6
intc	bsr.s	int
	RETCMD
;
;----------------------------
; EXCEPTION HANDLING
; d6 - vector
;
int	move.w	d2,d4
	subq.w	#2,d4
	bclr.l	#0,d4
	BK_SW	d5,d4
	subq.w	#2,d4
	BK_NSW	d3,d4
	BK_RW	d6,d3
	addq.w	#2,d6
	BK_RB	d6,d5
	bclr.b	#2,int_flags
	btst.l	#4,d5
	beq.s	10$
	bset.b	#2,int_flags
10$	subq.w	#4,d2
	rts

_reset_	bsr	reset_hw
	RETCMD

_wait__
;	movem.l	d0-a6,-(sp)
;	addq.b	#1,wait_flag
;	move.l	decode_emt36_signal,d0
;	CALLEXEC Wait
;	movem.l	(sp)+,d0-a6
	RETCMD

;----------------------------
; Return from exception
;
_rti___
	move.w	d2,d4
	BK_RW	d4,d3
	addq.w	#2,d4
	BK_RB	d4,d5
	bclr.b	#2,int_flags
	btst.l	#4,d5
	beq.s	10$
	bset.b	#2,int_flags
10$	addq.w	#4,d2
	RETCMD
_rtt___
	move.w	d2,d4
	BK_RW	d4,d3
	addq.w	#2,d4
	BK_RB	d4,d5
	bclr.b	#2,int_flags
	btst.l	#4,d5
	beq.s	10$
	bset.b	#2,int_flags
10$	addq.w	#4,d2
	clr.l	d4
	bra.l	dc_rtt

; Condition flags changing

_se____	and.w	#$F,d4
	or.w	d4,d5
	RETCMD
_cl____	and.w	#$F,d4
	not.w	d4
	and.w	d4,d5
	RETCMD

;------------------------------------------------
; conditional and unconditional branches
; fully same as Motorola's
;
_bne___	move.b	d5,ccr
	bne.s	_br____
	RETCMD
_beq___	move.b	d5,ccr
	beq.s	_br____
	RETCMD
_bvc___	move.b	d5,ccr
	bvc.s	_br____
	RETCMD
_bvs___	move.b	d5,ccr
	bvs.s	_br____
	RETCMD
_bcc___	move.b	d5,ccr
	bcc.s	_br____
	RETCMD
_bcs___	move.b	d5,ccr
	bcc	dc_next
_br____	ext.w	d4
	asl.w	#1,d4
	add.w	d4,d3
	RETCMD
_bge___	move.b	d5,ccr
	bge.s	_br____
	RETCMD
_blt___	move.b	d5,ccr
	blt.s	_br____
	RETCMD
_bgt___	move.b	d5,ccr
	bgt.s	_br____
	RETCMD
_ble___	move.b	d5,ccr
	ble.s	_br____
	RETCMD
_bhi___	move.b	d5,ccr
	bhi.s	_br____
	RETCMD
_blos__	move.b	d5,ccr
	bls.s	_br____
	RETCMD
_bpl___ move.b	d5,ccr
	bpl.s	_br____
	RETCMD
_bmi___	move.b	d5,ccr
	bmi.s	_br____
	RETCMD
;
;-------------------------------
; JSR Rn,N - Subroutine call
;
jsr_rn	MACRO
	and.w	#%111111,d4
	lea	ad_jw(pc),a6
	move.l	(a6,d4.l*4),a6
	CALL	a6,a5
	move.w	\1,d4
	subq.w	#2,d2		;shift stack
	move.w	d2,d7
	BK_SW	d4,d7
	move.w	d3,\1
	move.w	d6,d3
	RETCMD
	ENDM

	FCMD_Rn	jsr_	;set of eight routines
;
;-------------------------------
; JMP N - Unconditional jump
;
_jmp___	move.l	4(a6,d4.l*8),a6
	CALL	a6,a5
	move.w	d6,d3
	RETCMD

;-----------------------------------
; RTS Rn - Return from subroutine
;
rts_rn	MACRO
	move.w	\1,d3	;copy register to program counter
	BK_RRW	d2,d4
 	move.w	d4,\1
	addq.w	#2,d2	;stack increment
	RETCMD
	ENDM

	FCMD_Rn	rts_
;
;-----------------------------------------
; MARK N - Stack restore
; big thanx to Alexei Saveliev for description
;
_mark__	and.w	#%111111,d4	;lower six bits
	asl.w	#1,d4		;x2
	add.w	d3,d4		;add program counter
	move.w	d4,d2		;PC+2N->SP
	move.w	d1,d3		;R5->PC
	BK_RRW	d2,d1		;(SP)->R5
	addq.w	#2,d2		;(SP)+
	RETCMD
;
;-------------------------------
; SOB Rn,N - Cycle
;
sob_rn	MACRO
	subq.w	#1,\1
	tst.w	\1
	beq.l	dc_next		;register=zero
	and.w	#%111111,d4	;extract offset
	asl.w	#1,d4		;x2
	sub.w	d4,d3		;decrease program counter by offset x 2
	RETCMD
	ENDM

sobzrn	MACRO
	move.w	\1,d6
	sub.w	d6,delay_counter
	move.w	#0,\1
	RETCMD
	ENDM

	FCMD_Rn	sob_
	FCMD_Rn	sobz
;
;---------------------------------
; MOV(B) S,D - Move
;
m_f_rn	MACRO
	and.w	#@77,d4
	lea	ad_ww(pc),a6
	move.l	(a6,d4.l*4),a6
	move.w	\1,d4
	move.w	ccr,d7
	and.w	#%00001100,d7
	and.w	#%11110001,d5
	or.w	d7,d5
	jmp	(a6)
	ENDM
mbf_rn	MACRO
	and.w	#@77,d4
	lea	ad_wb(pc),a6
	move.l	(a6,d4.l*4),a6
	move.w	\1,d4
	ext.w	d4
	move.w	ccr,d7
	and.w	#%00001100,d7
	and.w	#%11110001,d5
	or.w	d7,d5
	jmp	(a6)
	ENDM

m_t_rn	MACRO
	and.w	#@7700,d4
	asr.l	#6,d4
	lea	ad_rw(pc),a6
	move.l	(a6,d4.l*4),a6
	CALL	a6,a5
	tst.w	d4
	move.w	ccr,d7
	and.w	#%00001100,d7
	and.w	#%11110001,d5
	or.w	d7,d5
	move.w	d4,\1
	RETCMD
	ENDM
mbt_rn	MACRO
	and.w	#@7700,d4
	asr.l	#6,d4
	lea	ad_rb(pc),a6
	move.l	(a6,d4.l*4),a6
	CALL	a6,a5
	ext.w	d4
	move.w	ccr,d7
	and.w	#%00001100,d7
	and.w	#%11110001,d5
	or.w	d7,d5
	move.w	d4,\1
	RETCMD
	ENDM

	FCMD_Rn	m_f_
	FCMD_Rn	mbf_
	FCMD_Rn	m_t_
	FCMD_Rn	mbt_

_mov___	move.l	d4,d6
	and.w	#%111111000000,d4
	asr.l	#6,d4
	lea	ad_rw(pc),a6
	move.l	(a6,d4.l*4),a6
	CALL	a6,a5
	tst.w	d4
	move.w	ccr,d7
	and.w	#%00001100,d7
	and.w	#%11110001,d5
	or.w	d7,d5
	and.w	#%111111,d6
	lea	ad_ww(pc),a6
	move.l	(a6,d6.l*4),a6
	jmp	(a6)

_movb__	move.l	d4,d6
	and.w	#%111111000000,d4
	asr.l	#6,d4
	lea	ad_rb(pc),a6
	move.l	(a6,d4.l*4),a6
	CALL	a6,a5
	ext.w	d4
	move.w	ccr,d7
	and.w	#%00001100,d7
	and.w	#%11110001,d5
	or.w	d7,d5
	and.w	#%111111,d6
	lea	ad_wb(pc),a6
	move.l	(a6,d6.l*4),a6
	jmp	(a6)


;--------------------------------------------
;  ADDRESSING MODES ADDRESS ROUTINES TABLES
;--------------------------------------------
;
at_reg	MACRO
	dc.l	ad\2\1\3
	ENDM
at_nreg	MACRO
	at_reg	0,\1,\2
	at_reg	1,\1,\2
	at_reg	2,\1,\2
	at_reg	3,\1,\2
	at_reg	4,\1,\2
	at_reg	5,\1,\2
	at_reg	6,\1,\2
	at_reg	7,\1,\2
	ENDM
at_nad	MACRO
ad_\1	at_nreg	0,\1
	at_nreg	1,\1
	at_nreg	2,\1
	at_nreg	3,\1
	at_nreg	4,\1
	at_nreg	5,\1
	at_nreg	6,\1
	at_nreg	7,\1
	ENDM

	cnop	0,4
	at_nad	rb
	at_nad	rw
	at_nad	wb
	at_nad	ww
	at_nad	mb
	at_nad	mw
	at_nad	jw

;------------------------------------------------
; MxPS S(D) - Move processor status word
;
_mfps__	move.l	d4,d6
	move.w	d5,d4
	move.w	ccr,d7
	and.w	#%00001100,d7
	and.w	#%11110001,d5
	or.w	d7,d5
	and.w	#%111111,d6
	lea	ad_wb(pc),a6
	move.l	(a6,d6.l*4),a6
	jmp	(a6)
_mtps__	and.w	#%111111,d4
	lea	ad_rb(pc),a6
	move.l	(a6,d4.l*4),a6
	CALL	a6,a5
	and.l	#%11101111,d4
	and.l	#%00010000,d5
	or.l	d4,d5
	RETCMD

;---------------------------------
; CLR(B) D - Clear
;
clrx	MACRO
	move.l	d4,d6
	and.w	#%11110000,d5
	or.w	#%00000100,d5
	clr.l	d4
	and.w	#%111111,d6
	lea	ad_w\1(pc),a6
	move.l	(a6,d6.l*4),a6
	jmp	(a6)
	ENDM

_clr___	clrx	w
_clrb__	clrx	b

clr_rn	MACRO
	clr.w	d4
	move.w	d4,\1
	bra.s	_clr_rx
	ENDM
clrbrn	MACRO
	move.w	\1,d4
	clr.b	d4
	move.w	d4,\1
	bra.s	_clr_rx
	ENDM

	FCMD_Rn	clr_
	FCMD_Rn	clrb

	nop

_clr_rx	and.w	#%11110000,d5
	or.w	#%00000100,d5
	RETCMD


;---------------------------------
; TST(B) S - Test and set flags
;
tst_rn	MACRO
	tst.w	\1
	bra.s	_tst_rx
	ENDM
tstbrn	MACRO
	move.w	\1,d4
	tst.b	d4
	bra.s	_tst_rx
	ENDM

	FCMD_Rn	tst_
	FCMD_Rn	tstb

_tst___	move.l	4(a6,d4.l*8),a6
	CALL	a6,a5
	tst.w	d4
_tst_rx	PSW	1100,0000
	RETCMD
_tstb__	move.l	4(a6,d4.l*8),a6
	CALL	a6,a5
	tst.b	d4
	PSW	1100,0000
	RETCMD

;-------------------------------------
; COM(B) D - Inversion
;
comx	MACRO
	move.l	4(a6,d4.l*8),a6
	lea	1$(pc),a5
	jmp	(a6)
1$	not.\1	d6
	PSW	1100,0000
	addq.w	#1,d5
	RET	a6
	ENDM

_com___	comx	w
_comb__	comx	b

;-------------------------------------
; INC(B) D - Increment
;
incx	MACRO
	move.l	4(a6,d4.l*8),a6
	lea	1$(pc),a5
	jmp	(a6)
1$	addq.\1	#1,d6
	PSW	1110,0001
	RET	a6
	ENDM

_inc___	incx	w
_incb__	incx	b

;-------------------------------------
; DEC(B) D - Decrement
;
decx	MACRO
	move.l	4(a6,d4.l*8),a6
	lea	1$(pc),a5
	jmp	(a6)
1$	subq.\1	#1,d6
	PSW	1110,0001
	RET	a6
	ENDM

_dec___	decx	w
_decb__	decx	b

;------------------------------------------
; SWAB D - Swap bytes in word
;
_swab__	move.l	4(a6,d4.l*8),a6
	lea	1$(pc),a5
	jmp	(a6)
1$	rol.w	#8,d6
	tst.b	d6
	PSW	1100,0000
	RET	a6
;------------------------------------------
; SXT D - Sign flag extension
;
_sxt___	move.l	4(a6,d4.l*8),a6
	lea	1$(pc),a5
	jmp	(a6)
1$	move.w	d5,d6
	rol.w	#4,d6
	extb.l	d6
	swap	d6
	tst.w	d6
	PSW	0100,1001
	RET	a6

;-------------------------------------
; NEG(B) D - Sign change
;
negx_	MACRO
	move.l	4(a6,d4.l*8),a6
	lea	1$(pc),a5
	jmp	(a6)
1$	neg.\1	d6
	PSW	1111,0000
	RET	a6
	ENDM

_neg___	negx_	w
_negb__	negx_	b

;-------------------------------------
; ASL(B) D - Arithmetic left shift
;
asl_rn	MACRO
	move.w	\1,d6
	asl.w	#1,d6
	PSW	1111,0000
	move.w	d6,\1
	RETCMD
	ENDM
aslbrn	MACRO
	move.w	\1,d6
	asl.b	#1,d6
	PSW	1111,0000
	move.w	d6,\1
	RETCMD
	ENDM

	FCMD_Rn	asl_
	FCMD_Rn	aslb

aslx	MACRO
	move.l	4(a6,d4.l*8),a6
	lea	1$(pc),a5
	jmp	(a6)
1$	asl.\1	#1,d6
	PSW	1111,0000
	RET	a6
	ENDM

_asl___	aslx	w
_aslb__	aslx	b

;-------------------------------------
; ASR(B) D - Arithmetic rigth shift
;
asr_rn	MACRO
	move.w	\1,d6
	asr.w	#1,d6
	PSW	1111,0000
	move.w	d6,\1
	RETCMD
	ENDM
asrbrn	MACRO
	move.w	\1,d6
	asr.b	#1,d6
	PSW	1111,0000
	move.w	d6,\1
	RETCMD
	ENDM

	FCMD_Rn	asr_
	FCMD_Rn	asrb

asrx	MACRO
	move.l	4(a6,d4.l*8),a6
	lea	1$(pc),a5
	jmp	(a6)
1$	asr.\1	#1,d6
	PSW	1111,0000
	RET	a6
	ENDM

_asr___	asrx	w
_asrb__	asrx	b

;-------------------------------------
; ROL(B) D - Cycle left shift
;
rol_rn	MACRO
	move.w	\1,d6
	move.l	d5,d4
	roxr.l	#1,d4
	roxl.w	#1,d6
	bmi.s	2$
	bcc.s	3$
	or	#2,ccr
	bra.s	3$
2$	bcs.s	3$
	or	#2,ccr
3$	PSW	1111,0000
	move.w	d6,\1
	RETCMD
	ENDM
rolbrn	MACRO
	move.w	\1,d6
	move.l	d5,d4
	roxr.l	#1,d4
	roxl.b	#1,d6
	bmi.s	2$
	bcc.s	3$
	or	#2,ccr
	bra.s	3$
2$	bcs.s	3$
	or	#2,ccr
3$	PSW	1111,0000
	move.w	d6,\1
	RETCMD
	ENDM

	FCMD_Rn	rol_
	FCMD_Rn	rolb

rolx	MACRO
	move.l	4(a6,d4.l*8),a6
	lea	1$(pc),a5
	jmp	(a6)
1$	move.l	d5,d4
	roxr.l	#1,d4
	roxl.\1	#1,d6
	bmi.s	2$
	bcc.s	3$
	or	#2,ccr
	bra.s	3$
2$	bcs.s	3$
	or	#2,ccr
3$	PSW	1111,0000
	RET	a6
	ENDM

_rol___	rolx	w
_rolb__	rolx	b

;-------------------------------------
; ROR(B) D - Cycle right shift
;
ror_rn	MACRO
	move.w	\1,d6
	move.l	d5,d4
	roxr.l	#1,d4
	roxr.w	#1,d6
	bmi.s	2$
	bcc.s	3$
	or	#2,ccr
	bra.s	3$
2$	bcs.s	3$
	or	#2,ccr
3$	PSW	1111,0000
	move.w	d6,\1
	RETCMD
	ENDM
rorbrn	MACRO
	move.w	\1,d6
	move.l	d5,d4
	roxr.l	#1,d4
	roxr.b	#1,d6
	bmi.s	2$
	bcc.s	3$
	or	#2,ccr
	bra.s	3$
2$	bcs.s	3$
	or	#2,ccr
3$	PSW	1111,0000
	move.w	d6,\1
	RETCMD
	ENDM

	FCMD_Rn	ror_
	FCMD_Rn	rorb

rorx	MACRO
	move.l	4(a6,d4.l*8),a6
	lea	1$(pc),a5
	jmp	(a6)
1$	move.l	d5,d4
	roxr.l	#1,d4
	roxr.\1	#1,d6
	bmi.s	2$
	bcc.s	3$
	or	#2,ccr
	bra.s	3$
2$	bcs.s	3$
	or	#2,ccr
3$	PSW	1111,0000
	RET	a6
	ENDM

_ror___	rorx	w
_rorb__	rorx	b

;------------------------------------------
; ADC(B) D - Add carry bit
;
adcx	MACRO
	move.l	4(a6,d4.l*8),a6
	lea	1$(pc),a5
	jmp	(a6)
1$	move.w	d5,d4
	and.w	#1,d4
	add.\1	d4,d6
	PSW	1111,0000
	RET	a6
	ENDM

_adc___	adcx	w
_adcb__	adcx	b

;------------------------------------------
; SBC(B) D - Subtract carry bit
;
sbcx	MACRO
	move.l	4(a6,d4.l*8),a6
	lea	1$(pc),a5
	jmp	(a6)
1$	move.w	d5,d4
	and.w	#1,d4
	sub.\1	d4,d6
	PSW	1111,0000
	RET	a6
	ENDM

_sbc___	sbcx	w
_sbcb__	sbcx	b

;---------------------------------
; CMP(B) S,D - Compare
;
cmpx	MACRO
	move.l	d4,d6
	move.l	4(a6,d4.l*8),a6
	CALL	a6,a5
	move.w	d4,d7
	and.w	#%111111,d6
	lea	ad_r\1(pc),a6
	move.l	(a6,d6.l*4),a6
	CALL	a6,a5
	cmp.\1	d4,d7
	PSW	1111,0000
	RETCMD
	ENDM

_cmp___	cmpx	w
_cmpb__	cmpx	b

;-------------------------------------
; BIT(B) S,D - Bit test
;
bitx	MACRO
	move.l	d4,d6
	move.l	4(a6,d4.l*8),a6
	CALL	a6,a5
	move.w	d4,d7
	and.w	#%111111,d6
	lea	ad_r\1(pc),a6
	move.l	(a6,d6.l*4),a6
	CALL	a6,a5
	and.\1	d7,d4
	PSW	1100,0001
	RETCMD
	ENDM

_bit___	bitx	w
_bitb__	bitx	b

;-------------------------------------
; BIS(B) S,D - Bit set
;
bisx	MACRO
	move.l	d4,d6
	move.l	4(a6,d4.l*8),a6
	CALL	a6,a5
	and.w	#%111111,d6
	lea	ad_m\1(pc),a6
	move.l	(a6,d6.l*4),a6
	lea	1$(pc),a5
	jmp	(a6)
1$	or.\1	d4,d6
	PSW	1100,0001
	RET	a6
	ENDM

_bis___	bisx	w
_bisb__	bisx	b

;-------------------------------------
; BIC(B) S,D - Bit clearing
;
bicx	MACRO
	move.l	d4,d6
	move.l	4(a6,d4.l*8),a6
	CALL	a6,a5
	and.w	#%111111,d6
	lea	ad_m\1(pc),a6
	move.l	(a6,d6.l*4),a6
	lea	1$(pc),a5
	jmp	(a6)
1$	not.\1	d4
	and.\1	d4,d6
	PSW	1100,0001
	RET	a6
	ENDM

_bic___	bicx	w
_bicb__	bicx	b

;-------------------------------------
; ADD S,D - Add
;
_add___	move.l	d4,d6
	move.l	4(a6,d4.l*8),a6
	CALL	a6,a5
	and.w	#%111111,d6
	lea	ad_mw(pc),a6
	move.l	(a6,d6.l*4),a6
	lea	1$(pc),a5
	jmp	(a6)
1$	add.w	d4,d6
	PSW	1111,0000
	RET	a6

;-------------------------------------
; SUB S,D - Subtract
;
_sub___	move.l	d4,d6
	move.l	4(a6,d4.l*8),a6
	CALL	a6,a5
	and.w	#%111111,d6
	lea	ad_mw(pc),a6
	move.l	(a6,d6.l*4),a6
	lea	1$(pc),a5
	jmp	(a6)
1$	sub.w	d4,d6
	PSW	1111,0000
	RET	a6

;--------------------------------------
; XOR Rn,D - Exclusive OR
;
xor_rn	MACRO
	move.l	4(a6,d4.l*8),a6
	move.w	\1,d4
	lea	xor_rx(pc),a5
	jmp	(a6)
	ENDM

xor_rx	eor.w	d4,d6
	PSW	1100,0001
	RET	a6

	FCMD_Rn	xor_

;--------------------------
;  OPCODES DECODE ROUTINE
;--------------------------

; registers: R0-R7 as A0,A1,A2,A3,D0,D1,D2,D3
; D4 - working data
; A4 - emulation memory address
; D5 - processor status word (PSW)

decod	moveq.l	#-1,d0
	CALLEXEC AllocSignal
	moveq.l	#1,d1
	lsl.l	d0,d1
	move.l	d1,decode_delay_signal
	move.l	sp,decode_init_stack
	lea	emul_buffer_mid,a4
	clr.l	d5		;PS
	move.l	d5,a0		;R0
	move.l	d5,a1		;R1
	move.l	d5,a2		;R2
	move.l	d5,a3		;R3
	clr.l	d0		;R4
	clr.l	d1		;R5
	move.l	#512,d2		;SP
	tst.l	emt36_startup_handle
	beq.s	reset
	move.l	#$818280FA,@774(a4)
	move.w	#@100140,d3	;PC
	move.w	#@774,d2
	move.w	#3,@320(a4)
	bra.s	reset_
reset	move.l	#$8000,d3	;PC
reset_	clr.w	int_flags
	bsr	reset_hw

dc_next
	move.l	intl_flags,d4
	beq	dc_rtt		;no flags
	cmp.w	#$8000,d4	;only delay flag present?
	bne	20$		;no
	clr.l	d4
	move.w	d3,d4		;get program counter
	addq.w	#2,d3		;increase program counter
	BK_IW	d4,d4		;get opcode
	move.l	#time_table,a6
	move.w	(a6,d4.l*2),d6	;get precalculated opcode timing
3$	sub.w	d6,delay_counter
	bpl.s	10$
	movem.l	d0-a6,-(sp)
	subq.w	#1,slow_counter
	bpl.s	5$
	bclr.b	#7,int_flags
	bra.s	6$
5$	clr.l	d0
	clr.l	d1
	CALLEXEC SetSignal
	and.l	decode_delay_signal,d0
	bne.s	7$
6$	move.w	#50,slow_counter
7$	move.l	decode_delay_signal,d0
	CALLEXEC Wait			;wait for vblank
	movem.l	(sp)+,d0-a6
	move.w	speed,d6
	neg.w	d6
	bra.s	3$
10$	move.l	#decode_table,a6
	move.l	(a6,d4.l*8),a5	;get opcode procedure address
	jmp	(a5)

20$	btst.l	#10,d4		; trace bit exception
	beq.s	30$
	move.w	#@14,d6
	bsr	int
	move.w	int_flags,d4
30$	btst.l	#8,d4		; cpu restart
	bne	reset
	btst.l	#9,d4		; STOP key exception
	beq.s	40$
	bclr.b	#1,int_flags
	move.w	#4,d6
	addq.w	#2,d3		;increase program counter
	bra	intc
40$	btst.l	#0,d4		; vector 100 - vblank exception
	beq.s	50$
	bclr.b	#0,int_flags+1
	bclr.b	#0,intm_flags
	move.w	#@100,d6
	bra	intc
50$	btst.l	#1,d4		; vector 60 - first keyboard exception
	beq.s	60$
	bclr.b	#1,int_flags+1
	bclr.b	#1,intm_flags
	move.w	#@60,d6
	bra	intc
60$	btst.l	#2,d4		; vector 274 - second keyboard exception
	beq.s	70$
	bclr.b	#2,int_flags+1
	bclr.b	#2,intm_flags
	move.w	#@274,d6
	bra	intc
70$	btst.l	#14,d4		; terminate emulation process
	bne.s	emul_end
	clr.l	d4
dc_rtt	move.w	d3,d4
	addq.w	#2,d3
	BK_IW	d4,d4
	move.l	#decode_table,a6
	move.l	(a6,d4.l*8),a5
	jmp	(a5)

emul_end
	addq.b	#1,control_break_flag	;terminate main process
	move.l	control_proc_ptr,a1
	move.l	#ALL_BREAKF,d0
	CALLEXEC Signal			;send Break to it
	rts

; int_flags bits:
; 0 - RESET
; 1 - STOP
; 2 - trace
; 5 - skip empty loop
; 6 - terminate process
; 7 - delay
; int_flags+1 & intm_flags bits:
; 0 - vector 100
; 1 - vector 60 (keyboard)
; 2 - vector 274 (--//--)

; registers: R0-R7 as A0,A1,A2,A3,D0,D1,D2,D3
; D4 - working data
; A4 - emulation memory address
; D5 - processor status word (PSW)
; label format: ad(addressing_mode_number)(register_number)(data_size)

;--------------------------------
;  SOURCE ADDRESSING MODES
;--------------------------------
ad0xrb	MACRO			; move byte from R
	move.w	\1,d4
	RET	a5
	ENDM
ad0xrw	MACRO			; move word from R
	move.w	\1,d4
	RET	a5
	ENDM

ad1xrb	MACRO			; move byte from (R)
	BK_RRB	\1,d4
	RET	a5
	ENDM
ad1xrw	MACRO			; move word from (R)
	BK_RRW	\1,d4
	RET	a5
	ENDM

ad2xrb	MACRO			; move byte from (R)+
	IFC	'\1','p6'
	BK_RRB	\1,d4
	addq.w	#2,\1
	ELSE
	IFC	'\1','p7'
	BK_IRB	\1,d4
	addq.w	#2,\1
	ELSE
	BK_RRB	\1,d4
	addq.w	#1,\1
	ENDC
	ENDC
	RET	a5
	ENDM
ad2xrw	MACRO			; move word from (R)+
	IFC	'\1','p7'
	BK_IRW	\1,d4
	ELSE
	BK_RRW	\1,d4
	ENDC
	addq.w	#2,\1
	RET	a5
	ENDM

ad3xrb	MACRO			; move byte from @(R)+
	BK_IRW	\1,d4
	addq.w	#2,\1
	BK_RB	d4,d4
	RET	a5
	ENDM
ad3xrw	MACRO			; move word from @(R)+
	BK_IRW	\1,d4
	addq.w	#2,\1
	BK_RW	d4,d4
	RET	a5
	ENDM

ad4xrb	MACRO			; move byte from -(R)
	IFC	'\1','p6'
	subq.w	#2,\1
	ELSE
	IFC	'\1','p7'
	subq.w	#2,\1
	ELSE
	subq.w	#1,\1
	ENDC
	ENDC
	BK_RRB	\1,d4
	RET	a5
	ENDM
ad4xrw	MACRO			; move word from -(R)
	subq.w	#2,\1
	BK_RRW	\1,d4
	RET	a5
	ENDM

ad5xrb	MACRO			; move byte from @-(R)
	subq.w	#2,\1
	BK_IRW	\1,d4
	BK_RB	d4,d4
	RET	a5
	ENDM
ad5xrw	MACRO			; move word from @-(R)
	subq.w	#2,\1
	BK_IRW	\1,d4
	BK_RW	d4,d4
	RET	a5
	ENDM

ad6xrb	MACRO			; move byte from N(R)
	BK_IRW	d3,d4
	addq.w	#2,d3
	add.w	\1,d4
	BK_RB	d4,d4
	RET	a5
	ENDM
ad6xrw	MACRO			; move word from N(R)
	BK_IRW	d3,d4
	addq.w	#2,d3
	add.w	\1,d4
	BK_RW	d4,d4
	RET	a5
	ENDM

ad7xrb	MACRO			; move byte from @N(R)
	BK_IRW	d3,d4
	addq.w	#2,d3
	add.w	\1,d4
	BK_IW	d4,d4
	BK_RB	d4,d4
	RET	a5
	ENDM
ad7xrw	MACRO			; move word from @N(R)
	BK_IRW	d3,d4
	addq.w	#2,d3
	add.w	\1,d4
	BK_IW	d4,d4
	BK_RW	d4,d4
	RET	a5
	ENDM

;-------------------------------------
;  DESTINATION ADDRESSING MODES
;-------------------------------------
ad0xwb	MACRO			; move byte to R
	move.w	d4,\1
	RETCMD
	ENDM
ad0xww	MACRO			; move word to R
	move.w	d4,\1
	RETCMD
	ENDM

ad1xwb	MACRO			; move byte to (R)
	move.w	\1,d6
	BK_SB	d4,d6
	RETCMD
	ENDM
ad1xww	MACRO			; move word to (R)
	move.w	\1,d6
	BK_SW	d4,d6
	RETCMD
	ENDM

ad2xwb	MACRO			; move byte to (R)+
	move.w	\1,d6
	BK_SB	d4,d6
	IFC	'\1','p6'
	addq.w	#2,\1
	ELSE
	IFC	'\1','p7'
	addq.w	#2,\1
	ELSE
	addq.w	#1,\1
	ENDC
	ENDC
	RETCMD
	ENDM
ad2xww	MACRO			; move word to (R)+
	move.w	\1,d6
	BK_SW	d4,d6
	addq.w	#2,\1
	RETCMD
	ENDM

ad3xwb	MACRO			; move byte to @(R)+
	BK_IRW	\1,d6
	addq.w	#2,\1
	BK_SB	d4,d6
	RETCMD
	ENDM
ad3xww	MACRO			; move word to @(R)+
	BK_IRW	\1,d6
	addq.w	#2,\1
	BK_SW	d4,d6
	RETCMD
	ENDM

ad4xwb	MACRO			; move byte to -(R)
	IFC	'\1','p6'
	subq.w	#2,\1
	ELSE
	IFC	'\1','p7'
	subq.w	#2,\1
	ELSE
	subq.w	#1,\1
	ENDC
	ENDC
	move.w	\1,d6
	BK_SB	d4,d6
	RETCMD
	ENDM
ad4xww	MACRO			; move word to -(R)
	subq.w	#2,\1
	move.w	\1,d6
	BK_SW	d4,d6
	RETCMD
	ENDM

ad5xwb	MACRO			; move byte to @-(R)
	subq.w	#2,\1
	BK_IRW	\1,d6
	BK_SB	d4,d6
	RETCMD
	ENDM
ad5xww	MACRO			; move word to @-(R)
	subq.w	#2,\1
	BK_IRW	\1,d6
	BK_SW	d4,d6
	RETCMD
	ENDM

ad6xwb	MACRO			; move byte to N(R)
	BK_IRW	d3,d6
	addq.w	#2,d3
	add.w	\1,d6
	BK_SB	d4,d6
	RETCMD
	ENDM
ad6xww	MACRO			; move word to N(R)
	BK_IRW	d3,d6
	addq.w	#2,d3
	add.w	\1,d6
	BK_SW	d4,d6
	RETCMD
	ENDM

ad7xwb	MACRO			; move byte to @N(R)
	BK_IRW	d3,d6
	addq.w	#2,d3
	add.w	\1,d6
	BK_IW	d6,d6
	BK_SB	d4,d6
	RETCMD
	ENDM
ad7xww	MACRO			; move word to @N(R)
	BK_IRW	d3,d6
	addq.w	#2,d3
	add.w	\1,d6
	BK_IW	d6,d6
	BK_SW	d4,d6
	RETCMD
	ENDM

;--------------------------------------
;  MODIFICATION ADDRESSING MODES
;--------------------------------------
ad0xmb	MACRO			; byte modification in R
	move.w	\1,d6
	CALL	a5,a6
	move.w	d6,\1
	RETCMD
	ENDM
ad0xmw	MACRO			; word modification in R
	move.w	\1,d6
	CALL	a5,a6
	move.w	d6,\1
	RETCMD
	ENDM

ad1xmb	MACRO			; byte modification in (R)
	move.w	\1,d7
	BK_RB	d7,d6
	CALL	a5,a6
	BK_NSB	d6,d7
	RETCMD
	ENDM
ad1xmw	MACRO			; word modification in (R)
	move.w	\1,d7
	BK_RW	d7,d6
	CALL	a5,a6
	BK_NSW	d6,d7
	RETCMD
	ENDM

ad2xmb	MACRO			; byte modification in (R)+
	move.w	\1,d7
	IFC	'\1','p6'
	addq.w	#2,\1
	ELSE
	IFC	'\1','p7'
	addq.w	#2,\1
	ELSE
	addq.w	#1,\1
	ENDC
	ENDC
	BK_RB	d7,d6
	CALL	a5,a6
	BK_NSB	d6,d7
	RETCMD
	ENDM
ad2xmw	MACRO			; word modification in (R)+
	move.w	\1,d7
	addq.w	#2,\1
	BK_RW	d7,d6
	CALL	a5,a6
	BK_NSW	d6,d7
	RETCMD
	ENDM

ad3xmb	MACRO			; byte modification in @(R)+
	BK_IRW	\1,d7
	addq.w	#2,\1
	BK_RB	d7,d6
	CALL	a5,a6
	BK_NSB	d6,d7
	RETCMD
	ENDM
ad3xmw	MACRO			; word modification in @(R)+
	BK_IRW	\1,d7
	addq.w	#2,\1
	BK_RW	d7,d6
	CALL	a5,a6
	BK_NSW	d6,d7
	RETCMD
	ENDM

ad4xmb	MACRO			; byte modification in -(R)
	IFC	'\1','p6'
	subq.w	#2,\1
	ELSE
	IFC	'\1','p7'
	subq.w	#2,\1
	ELSE
	subq.w	#1,\1
	ENDC
	ENDC
	move.w	\1,d7
	BK_RB	d7,d6
	CALL	a5,a6
	BK_NSB	d6,d7
	RETCMD
	ENDM
ad4xmw	MACRO			; word modification in -(R)
	subq.w	#2,\1
	move.w	\1,d7
	BK_RW	d7,d6
	CALL	a5,a6
	BK_NSW	d6,d7
	RETCMD
	ENDM

ad5xmb	MACRO			; byte modification in @-(R)
	subq.w	#2,\1
	BK_IRW	\1,d7
	BK_RB	d7,d6
	CALL	a5,a6
	BK_NSB	d6,d7
	RETCMD
	ENDM
ad5xmw	MACRO			; word modification in @-(R)
	subq.w	#2,\1
	BK_IRW	\1,d7
	BK_RW	d7,d6
	CALL	a5,a6
	BK_NSW	d6,d7
	RETCMD
	ENDM

ad6xmb	MACRO			; byte modification in N(R)
	BK_IRW	d3,d7
	addq.w	#2,d3
	add.w	\1,d7
	BK_RB	d7,d6
	CALL	a5,a6
	BK_NSB	d6,d7
	RETCMD
	ENDM
ad6xmw	MACRO			; word modification in N(R)
	BK_IRW	d3,d7
	addq.w	#2,d3
	add.w	\1,d7
	BK_RW	d7,d6
	CALL	a5,a6
	BK_NSW	d6,d7
	RETCMD
	ENDM

ad7xmb	MACRO			; byte modification in @N(R)
	BK_IRW	d3,d7
	addq.w	#2,d3
	add.w	\1,d7
	BK_IW	d7,d7
	BK_RB	d7,d6
	CALL	a5,a6
	BK_NSB	d6,d7
	RETCMD
	ENDM
ad7xmw	MACRO			; word modification in @N(R)
	BK_IRW	d3,d7
	addq.w	#2,d3
	add.w	\1,d7
	BK_IW	d7,d7
	BK_RW	d7,d6
	CALL	a5,a6
	BK_NSW	d6,d7
	RETCMD
	ENDM

;-----------------------------------------
;  WORD SOURCE ADDRESSING MODES FOR JUMP
;-----------------------------------------
ad0xjw	MACRO			; move word from R
	move.w	d3,d6		; = NOP
	RET	a5
	ENDM
ad1xjw	MACRO			; move word from (R)
	move.w	\1,d6
	RET	a5
	ENDM
ad2xjw	MACRO			; move word from (R)+
	move.w	\1,d6
	addq.w	#2,\1
	RET	a5
	ENDM
ad3xjw	MACRO			; move word from @(R)+
	BK_IRW	\1,d6
	addq.w	#2,\1
	RET	a5
	ENDM
ad4xjw	MACRO			; move word from -(R)
	subq.w	#2,\1
	move.w	\1,d6
	RET	a5
	ENDM
ad5xjw	MACRO			; move word from @-(R)
	subq.w	#2,\1
	BK_IRW	\1,d6
	RET	a5
	ENDM
ad6xjw	MACRO			; move word from N(R)
	BK_IRW	d3,d6
	addq.w	#2,d3
	add.w	\1,d6
	RET	a5
	ENDM
ad7xjw	MACRO			; move word from @N(R)
	BK_IRW	d3,d4
	addq.w	#2,d3
	add.w	\1,d4
	BK_IW	d4,d6
	RET	a5
	ENDM

;-----------------------------
;  ADDRESSING MODES ROUTINES
;-----------------------------
;
ad_reg	MACRO
ad\2\1\3
	ad\2x\3	p\1
	ENDM
ad_nreg	MACRO
	ad_reg	0,\1,\2
	ad_reg	1,\1,\2
	ad_reg	2,\1,\2
	ad_reg	3,\1,\2
	ad_reg	4,\1,\2
	ad_reg	5,\1,\2
	ad_reg	6,\1,\2
	ad_reg	7,\1,\2
	ENDM
ad_nad	MACRO
	ad_nreg	0,\1
	ad_nreg	1,\1
	ad_nreg	2,\1
	ad_nreg	3,\1
	ad_nreg	4,\1
	ad_nreg	5,\1
	ad_nreg	6,\1
	ad_nreg	7,\1
	ENDM

	ad_nad	rb
	ad_nad	rw
	ad_nad	wb
	ad_nad	ww
	ad_nad	mb
	ad_nad	mw
	ad_nad	jw

;-------------------------------------
;  HARDWARE REGISTERS TABLE FOR READ
;-------------------------------------
	section	data_l

	dc.l	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
	dc.l	rp177660
	dc.l	rp177662
	dc.l	rp177664
	dc.l	0,0,0,0,0
	dc.l	rp177700
	dc.l	rp177702
	dc.l	rp177704
	dc.l	rp177706
	dc.l	rp177710
	dc.l	rp177712
	dc.l	rp177714
	dc.l	rp177716
	dc.l	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
prt_vm1

;--------------------------------------
;  HARDWARE REGISTERS TABLE FOR WRITE
;--------------------------------------
;
	dc.l	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
	dc.l	wp177660
	dc.l	0
	dc.l	wp177664
	dc.l	0,0,0,0,0
	dc.l	wp177700
	dc.l	wp177702
	dc.l	wp177704
	dc.l	wp177706
	dc.l	wp177710
	dc.l	wp177712
	dc.l	wp177714
	dc.l	wp177716
	dc.l	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
pwt_vm1

;-----------------------------------
;  PROCESSOR OPCODES ADDRESS TABLE
;-----------------------------------
;

amt_vm1		;opcode, addr mode table, table repeat, entry repeat
	dc.l	@100,ad_jw,0,0
	dc.l	@300,ad_mw,0,0
	dc.l	@4000,ad_jw,7,0
	dc.l	@5000,ad_ww,0,0
	dc.l	@5100,ad_mw,5,0
	dc.l	@5700,ad_rw,0,0
	dc.l	@6000,ad_mw,3,0
	dc.l	@6700,ad_mw,0,0
	dc.l	@10000,ad_rw,5,63
	dc.l	@74000,ad_mw,7,0
	dc.l	@105000,ad_wb,0,0
	dc.l	@105100,ad_mb,5,0
	dc.l	@105700,ad_rb,0,0
	dc.l	@106000,ad_mb,3,0
	dc.l	@106400,ad_rb,0,0
	dc.l	@106700,ad_wb,0,0
	dc.l	@110000,ad_rb,4,63
	dc.l	@160000,ad_rw,0,63
	dc.l	0

ct_vm1
	dCMD	_halt__,1	;000000
	dCMD	_wait__,1	;000001
	dCMD	_rti___,1	;000002
	dCMD	_bpt___,1	;000003
	dCMD	_iot___,1	;000004
	dCMD	_reset_,1	;000005
	dCMD	_rtt___,1	;000006
	dCMD	_rsrv__,57
	dCMD	_jmp___,64	;0001xx
	CMD_Rm	_rts_		;000200
	dCMD	_rsrv__,24
	dCMD	_cl____,16	;000240
	dCMD	_se____,16	;000260
	dCMD	_swab__,64	;0003xx
	dCMD	_br____,256	;000400
	dCMD	_bne___,256	;001000
	dCMD	_beq___,256	;001400
	dCMD	_bge___,256	;002000
	dCMD	_blt___,256	;002400
	dCMD	_bgt___,256	;003000
	dCMD	_ble___,256	;003400
	CMD_Rn	_jsr_		;004xxx
	CMD_Rx	_clr_		;0050xx
	dCMD	_com___,64	;0051xx
	dCMD	_inc___,64	;0052xx
	dCMD	_dec___,64	;0053xx
	dCMD	_neg___,64	;0054xx
	dCMD	_adc___,64	;0055xx
	dCMD	_sbc___,64	;0056xx
	CMD_Rx	_tst_		;0057xx
	CMD_Rx	_ror_		;0060xx
	CMD_Rx	_rol_		;0061xx
	CMD_Rx	_asr_		;0062xx
	CMD_Rx	_asl_		;0063xx
	dCMD	_mark__,64	;0064xx
	dCMD	_rsrv__,128	;006500
	dCMD	_sxt___,64	;0067xx
	dCMD	_rsrv__,512	;007000
; MOV
tm__rx	MACRO
	CMD_Rm	_m_t_
	dCMD	_m_f_\1,56
	ENDM

	tm__rx	r0
	tm__rx	r1
	tm__rx	r2
	tm__rx	r3
	tm__rx	r4
	tm__rx	r5
	tm__rx	r6
	tm__rx	r7

	REPT	56
	CMD_Rm	_m_t_
	dCMD	_mov___,56
	ENDR
;
	dCMD	_cmp___,4096	;02xxxx
	dCMD	_bit___,4096	;03xxxx
	dCMD	_bic___,4096	;04xxxx
	dCMD	_bis___,4096	;05xxxx
	dCMD	_add___,4096	;06xxxx
	dCMD	_rsrv__,2048	;070000
	CMD_Rn	_xor_		;074xxx
	dCMD	_rsrv__,1024	;075xxx
	CMD_Rn	_sob_		;077xxx

dSOB	MACRO
	dCMD	_sob_\1,1
	dCMD	_sobz\1,1
	dCMD	_sob_\1,62
	ENDM

;	dSOB	r0
;	dSOB	r1
;	dSOB	r2
;	dSOB	r3
;	dSOB	r4
;	dSOB	r5
;	dSOB	r6
;	dSOB	r7

	dCMD	_bpl___,256	;100000
	dCMD	_bmi___,256	;100400
	dCMD	_bhi___,256	;101000
	dCMD	_blos__,256	;101400
	dCMD	_bvc___,256	;102000
	dCMD	_bvs___,256	;102400
	dCMD	_bcc___,256	;103000
	dCMD	_bcs___,256	;103400
	dCMD	_emt___,256	;104000
	dCMD	_trap__,256	;104400
	CMD_Rx	_clrb		;1050xx
	dCMD	_comb__,64	;1051xx
	dCMD	_incb__,64	;1052xx
	dCMD	_decb__,64	;1053xx
	dCMD	_negb__,64	;1054xx
	dCMD	_adcb__,64	;1055xx
	dCMD	_sbcb__,64	;1056xx
	CMD_Rx	_tstb		;1057xx
	CMD_Rx	_rorb		;1060xx
	CMD_Rx	_rolb		;1061xx
	CMD_Rx	_asrb		;1062xx
	CMD_Rx	_aslb		;1063xx
	dCMD	_mtps__,64	;1064xx
	dCMD	_rsrv__,128	;1065xx
	dCMD	_mfps__,64	;1067xx
	dCMD	_rsrv__,512	;107xxx
; MOVB
tmb_rx	MACRO
	CMD_Rm	_mbt_
	dCMD	_mbf_\1,56
	ENDM

	tmb_rx	r0
	tmb_rx	r1
	tmb_rx	r2
	tmb_rx	r3
	tmb_rx	r4
	tmb_rx	r5
	tmb_rx	r6
	tmb_rx	r7

	REPT	56
	CMD_Rm	_mbt_
	dCMD	_movb__,56
	ENDR

	dCMD	_cmpb__,4096	;12xxxx
	dCMD	_bitb__,4096	;13xxxx
	dCMD	_bicb__,4096	;14xxxx
	dCMD	_bisb__,4096	;15xxxx
	dCMD	_sub___,4096	;16xxxx
	dCMD	_rsrv__,4096	;17xxxx
	dc.l	0

monotag		dc.l	SA_DisplayID,$8000
;monotag	dc.l	SA_DisplayID,$89020
mono_x		dc.l	SA_Left,64
mono_y		dc.l	SA_Top,0
		dc.l	SA_Quiet,1
		dc.l	SA_AutoScroll,1
		dc.l	SA_Width,512
		dc.l	SA_Height,256
		dc.l	SA_Depth,2	;;;1!
		dc.l	SA_Title,w_s_title
		dc.l	SA_Colors,mono_colorspec
		dc.l	TAG_END,0

colortag	dc.l	SA_DisplayID,0
;colortag	dc.l	SA_DisplayID,$89000
color_x		dc.l	SA_Left,32
color_y		dc.l	SA_Top,0
		dc.l	SA_Quiet,1
		dc.l	SA_AutoScroll,1
		dc.l	SA_Width,256
		dc.l	SA_Height,256
		dc.l	SA_Depth,2
		dc.l	SA_Title,w_s_title
		dc.l	SA_Colors,color_colorspec
		dc.l	TAG_END,0

decode_proc_tags
		dc.l	NP_Entry,decod
		dc.l	NP_Priority,-1
		dc.l	NP_Name,decode_proc_name
		dc.l	TAG_END,0

refresh_proc_tags
		dc.l	NP_Entry,refresh_proc
		dc.l	NP_Priority,1
		dc.l	NP_Name,refresh_proc_name
		dc.l	TAG_END,0

	section	data_w

mono_colorspec	dc.w	0,0,0,0
		dc.w	1,12,12,12
		dc.w	17,0,0,0
		dc.w	18,0,0,0
		dc.w	19,0,0,0
		dc.w	-1
color_colorspec	dc.w	0,0,0,0
		dc.w	1,0,0,15
		dc.w	2,0,15,0
		dc.w	3,15,0,0
		dc.w	17,0,0,0
		dc.w	18,0,0,0
		dc.w	19,0,0,0
		dc.w	-1
monotab		dc.w	$0000,$0DDD
colortab	dc.w	$0000,$000F,$00F0,$0F00

w_bk_screen
	dc.w	0,0				;x&y coordinates
wwidth	dc.w	256,256				;width and height
	dc.b	0,0				;default pens
	dc.l	VANILLAKEY!RAWKEY		;IDCMP flags
	dc.l	ACTIVATE!SIMPLE_REFRESH!BORDERLESS!BACKDROP!RMBTRAP
	dc.l	0				;no gadgets
	dc.l	0				;no checkmarks
	dc.l	w_s_title
sbs_ptr	dc.l	0		;emulator screen
	dc.l	0		;no bitmap
	dc.w	0,0,0,0		;minimum, irrelevant as no sizing gadget
	dc.w	CUSTOMSCREEN

c_bk_screen
	dc.w	0,0
	dc.w	1,1
	dc.b	0,0
	dc.l	CLOSEWINDOW!VANILLAKEY!RAWKEY
	dc.l	WINDOWCLOSE!ACTIVATE!SIMPLE_REFRESH!BORDERLESS!RMBTRAP
	dc.l	0
	dc.l	0
	dc.l	w_s_title
sbs_cop	dc.l	0
	dc.l	0
	dc.w	0,0,0,0
	dc.w	CUSTOMSCREEN

	section	data_b

keytab1	dc.b	$50,128+01
	dc.b	$51,000+03
	dc.b	$52,128+11
	dc.b	$53,000+22
	dc.b	$54,000+23
	dc.b	$55,128+02
	dc.b	$56,128+04
	dc.b	$57,128+00
	dc.b	$58,000+12
	dc.b	$64,000+14	;RUS
	dc.b	$65,000+15	;LAT
	dc.b	$4C,000+26	;up
	dc.b	$4D,000+27	;down
	dc.b	$4F,000+08	;left
	dc.b	$4E,000+25	;right
	dc.b	0

keytab2	dc.b	009,128+09
	dc.b	008,000+24
	dc.b	127,000+19
	dc.b	013,000+10
	dc.b	0

	section	texts

	dc.b	'‡¶ФЇѓЄї”‚Ф­ѕЃvµ•Ґ<љ^ФЎћў*ґџ‡ЂЌ>њ'
	dc.b	'юабцдефгхийклмнопярстужвьызшэщчъ'
	dc.b	'ЮАБЦДЕФГХИЙКЛМНОПЯРСТУЖВЬЫЗШЭЩЧЪ'

koi8_to_1251_table

	section	data_l
			dc.l	0
_LocaleBase		dc.l	0,localename
_IntuitionBase		dc.l	0,intname
_GfxBase		dc.l	0,grafname
_DOSBase		dc.l	0,dosname
;_UtilityBase		dc.l	0,utilityname
_IconBase		dc.l	0,iconname
_ReqToolsBase		dc.l	0,rtname
_XpkBase		dc.l	0,xpkname
_bkemulBase		dc.l	0,bkemulname
openlibs_table

emt36_xpk_tags		dc.l	XPK_InFH
emt36_handle		dc.l	0
			dc.l	XPK_GetOutBuf,emt36_buffer
			dc.l	XPK_GetOutLen,emt36_length
			dc.l	XPK_GetOutBufLen,emt36_buflen
			dc.l	XPK_PassThru,-1
			dc.l	TAG_DONE

	section	data_b

intname			dc.b	36,0,'intuition.library',0
grafname		dc.b	36,0,'graphics.library',0
dosname			dc.b	36,0,'dos.library',0
rtname			dc.b	38,1,'reqtools.library',0
iconname		dc.b	36,0,'icon.library',0
;utilityname		dc.b	37,1,'utility.library',0
diskfontname		dc.b	36,0,'diskfont.library',0
localename		dc.b	38,1,'locale.library',0
xpkname			dc.b	2,1,'xpkmaster.library',0
bkemulname		dc.b	1,1,'PROGDIR:bkemul_resident',0
;muiname		dc.b	0,1,'muimaster.library',0

	section	bss_l

_SysBase		ds.l	1
WB_return_message	ds.l	1
disk_object		ds.l	1
catalog			ds.l	1
args			ds.l	1
substrings		ds.l	3
emt_filereq		ds.l	1
config_line		ds.l	1
emt36_block_ptr		ds.l	1
wbs_ptr			ds.l	1
cbs_ptr			ds.l	1
old_wbs_ptr		ds.l	1
old_cbs_ptr		ds.l	1
old_sbs_ptr		ds.l	1
return_code		ds.l	1
emt36_startup_handle	ds.l	1
emt36_pointer		ds.l	1
emt36_buffer		ds.l	1
emt36_buflen		ds.l	1
emt36_length		ds.l	1
decode_init_stack	ds.l	1
decode_delay_signal	ds.l	1
decode_proc_ptr		ds.l	1
refresh_proc_ptr	ds.l	1
control_proc_ptr	ds.l	1
control_proc_signal	ds.l	1

	section	bss_w

intl_flags		ds.w	1
int_flags		ds.w	1
emt36_CRC		ds.w	1
emt36_header		ds.w	2
temp_name_buffer	ds.w	8

	section	data_w

delay_counter		dc.w	2000
speed			dc.w	3500
slow_counter		dc.w	50
p177660			dc.w	0
p177662			dc.w	0
p177664			dc.w	@1330
c177664			dc.w	@1330
p177714			dc.w	0
p177716			dc.w	@100340

	section	data_b

intm_flags		dc.b	0
refresh_counter		dc.b	0
emt36_ready		dc.b	0
control_proc_signal_bit	dc.b	0
bk_color_mode_flag	dc.b	-1
bk_color_mode		dc.b	-1
control_break_flag	dc.b	0
refresh_break_flag	dc.b	0
autorepeat_flag		dc.b	0
startup_flag		dc.b	-1
machine_type		dc.b	2
sound_device		dc.b	0
skip_SOB_flag		dc.b	0
ROMpatch_flag		dc.b	0
rus_flag		dc.b	0
delay_flag		dc.b	0
error_number		dc.b	0
ROM_load_enable		dc.b	0

	section	data_b

version			dc.b	'$VER: '
w_s_title		dc.b	'bkemul 2.0 beta 3',0
ROM_file_name		dc.b	'PROGDIR:bk_rom',0
decode_proc_name	dc.b	'1801BM1 emulation',0
refresh_proc_name	dc.b	'Screen refresh',0
catalog_name		dc.b	'bkemul.catalog',0
internal_language	dc.b	'russian',0
endstring		dc.b	10,0

	section	bss_b

name_full		ds.b	260
name_buffer		ds.b	110
			ds.b	6
comment_buffer		ds.b	1

	section	data_l

ROMpatchTab		dc.l	$1d5
pt_ROMpatch_name	dc.l	0
			dc.l	$1dc
pt_ROMpatch_err		dc.l	0
			dc.l	$13dc
pt_ROMpatch_ruslat	dc.l	0
			dc.l	$2097
pt_ROMpatch_STOP	dc.l	0
			dc.l	$35b8
pt_ROMpatch_BASIC	dc.l	0
			dc.l	$4dc6
pt_ROMpatch_err_num	dc.l	0
			dc.l	$5a71
pt_ROMpatch_in_line	dc.l	0
			dc.l	0

startup_err_req_data	dc.l	20,0
pt_startup_err_title	dc.l	startup_err_title,0
pt_startup_err_gadget	dc.l	startup_err_gadget

screen_err_req_data	dc.l	20,0
pt_screen_err_title	dc.l	screen_err_title
pt_screen_err_msg	dc.l	screen_err_msg
pt_screen_err_gadget	dc.l	screen_err_gadget

savereq_tags		dc.l	RTFI_Flags,FREQF_SAVE
loadreq_tags		dc.l	TAG_END
req_tags		dc.l	RTEZ_ReqTitle,0
			dc.l	TAG_END
opencat_tags		dc.l	OC_BuiltInLanguage,internal_language
			dc.l	OC_Version,2
			dc.l	TAG_END

	section	data_b

		even
os_alert	dc.w	(640-((err0len-1)*8))/2		;for DisplayAlert
		dc.b	22
err0		dc.b	"OS 2.0 (v36) or higher required",0
err0len		equ	*-err0
		dc.b	0

	section	data_l

message_table
pt_err0			dc.l	err0
pt_err1			dc.l	err1
pt_err2			dc.l	err2
pt_err3			dc.l	err3
pt_err4			dc.l	err4
pt_err5			dc.l	err5
pt_err6			dc.l	err6
pt_err7			dc.l	err7
pt_err8			dc.l	err8
pt_loadreq_title	dc.l	loadreq_title
pt_savereq_title	dc.l	savereq_title


catalog_table
	dc.l	pt_err1
	dc.l	pt_err2
	dc.l	pt_err3
	dc.l	pt_err4
	dc.l	pt_err5
	dc.l	pt_err6
	dc.l	pt_err7
	dc.l	pt_err8
	dc.l	pt_loadreq_title
	dc.l	pt_savereq_title
	dc.l	pt_startup_err_title
	dc.l	pt_startup_err_gadget
	dc.l	pt_screen_err_title
	dc.l	pt_screen_err_msg
	dc.l	pt_screen_err_gadget
	dc.l	pt_ROMpatch_name
	dc.l	pt_ROMpatch_err
	dc.l	pt_ROMpatch_ruslat
	dc.l	pt_ROMpatch_STOP
	dc.l	pt_ROMpatch_BASIC
	dc.l	pt_ROMpatch_err_num
	dc.l	pt_ROMpatch_in_line
	dc.l	0

	section	texts

				;68020 required
err1			dc.b	"Хочу процессор 68020 или ещё круче",0
				;can't open resident module
err2			dc.b	"Не могу открыть PROGDIR:bkemul_resident",0
				;can't open CPU emulation library
err3			dc.b	"Не могу открыть PDP11.library",0
				;error in arguments
err4			dc.b	"Ошибка в аргументах",0
				;error in config file
err5			dc.b	"Ошибка в %ld строке файла конфигурации",0
				;error in parameter
err6			dc.b	"Ошибка в параметре %s: «%.15s»",10
			dc.b	"Допустимы только значения %s",0
				;can't open
err7			dc.b	"Не могу захватить сигнал",0
				;can't create process
err8			dc.b	"Не могу создать процесс",0
				;load file
loadreq_title		dc.b	'Эмулятор БК: читаем файл',0
				;save file
savereq_title		dc.b	'Эмулятор БК: пишем файл',0
				;bkemul startup error
startup_err_title	dc.b	'Ошибка запуска эмулятора БК',0
				;quit
startup_err_gadget	dc.b	'Выход',0
				;can't close screen
screen_err_title	dc.b	'Не могу закрыть экран',0
				;close window!
screen_err_msg		dc.b	'На экране эмулятора открыто окно',10
			dc.b	'другой программы.  Закройте его.',0
				;Repeat
screen_err_gadget	dc.b	'Повторить',0

;	section	databuf,bss
;data_buffer
;	ds.l	$10000

	section	decode,bss
decode_table
	ds.l	$20000

	section	time,bss
time_table
	ds.w	$10000

	section	delta,bss
delta_buffer
	ds.b	$4000

	section	embuf,bss
emul_buffer_begin
	ds.b	$8000
emul_buffer_mid
	ds.b	$8000
emul_buffer_end

	section	fibbuf,bss
fib_buffer
	ds.b	fib_SIZEOF

	end
