; © 1997 Russian Digital Computing
; e-mail: r_d_c@usa.net

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

	include	/system
	include	intuition/intuition.i
	include	intuition/intuition_lib.i
	include	exec/exec_lib.i
	include	graphics/graphics_lib.i
	include	exec/memory.i
	include	libraries/dos_lib.i
	include	libraries/dos.i
	include	dos/dosextens.i
	include	dos/dostags.i

	section	emu,code

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

;
;------------------------------------------------
; Beginning init
;
start	move.l	$4.w,_SysBase
	movem.l	d0/a0,-(sp)		;save initial values
	clr.l	WB_return_message
	sub.l	a1,a1
	CALLEXEC FindTask
	move.l	d0,a4
	move.l	d0,control_proc_ptr	;pointer to our process
	tst.l	pr_CLI(a4)		;CLI structure present?
	bne.s	10$			;yes
	lea	pr_MsgPort(a4),a0	;no - we started from WB
	CALLEXEC WaitPort
	lea	pr_MsgPort(a4),a0
	CALLEXEC GetMsg			;get WB msg
	move.l	d0,WB_return_message
10$	movem.l	(sp)+,d0/a0
	lea	intname,a1
	moveq	#0,d0
	CALLEXEC OpenLibrary		;Intuition
	move.l	d0,_IntuitionBase
	beq	err_exit
	lea	grafname,a1
	moveq	#0,d0
	CALLEXEC OpenLibrary		;Graphics
	move.l	d0,_GfxBase
	beq	err_exit
	lea	dosname,a1
	moveq	#0,d0
	CALLEXEC OpenLibrary		;DOS
	move.l	d0,_DOSBase
	beq	err_exit

; --------------------------------------
; 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	30$
	move.w	(a0)+,d1
	subq.l	#1,d1
20$	move.l	d0,(a1)+
	dbf	d1,20$
	bra.s	10$
30$

; 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$

; screen convert table for reverse order of bits in screen
; for monochrome screen mode and chunky2planar for color mode

generate_conv_table
	lea	conv_table,a0
	move.l	#$10000-1,d0
	clr.l	d1
10$	move.l	d1,d2
	rol.w	#8,d2
	moveq.l	#7,d5
	clr.w	d3
	clr.w	d4
20$	roxr.w	#1,d2
	roxl.w	#1,d3
	roxr.w	#1,d2
	roxl.w	#1,d4
	dbf	d5,20$
	rol.w	#8,d4
	or.w	d3,d4
	move.w	d4,(a0)+
	addq.l	#1,d1
	dbf	d0,10$
	move.l	#$10000-1,d0
	clr.l	d1
30$	move.l	d1,d2
	moveq.l	#7,d4
40$	roxr.w	#1,d2
	roxl.w	#1,d3
	roxr.w	#1,d2
	roxl.w	#1,d3
	dbf	d4,40$
	rol.w	#8,d3
	move.w	d3,(a0)+
	addq.l	#1,d1
	dbf	d0,30$

emulation_preparing
; ROM-file reading
	move.l	#ROM_file_name,d1
	move.l	#MODE_OLDFILE,d2
	CALLDOS	Open
	move.l	d0,ROM_file_handle
	beq	err_exit
	move.l	d0,d1
	move.l	#emul_buffer_begin,d2
	move.l	#$8000,d3
	CALLDOS Read
	cmp.l	#-1,d0
	beq	err_exit
; allocate signal
	moveq.l	#-1,d0
	CALLEXEC AllocSignal
	tst.b	d0
	bmi	err_exit
	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

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

emt36_handler
	move.l	emt36_block_ptr,a5
	move.l	a5,a0
	move.b	#4,1(a0)	;"STOP" code in response byte
	move.w	2(a0),d0	;beginning address
	rol.w	#8,d0
	move.w	d0,emt36_adr
	ext.l	d0
	lea	emul_buffer_mid,a1
	add.l	d0,a1		;physical address in memory
	move.l	a1,emt36_ptr
	move.w	4(a0),d0
	rol.w	#8,d0
	move.w	d0,emt36_len	;length of file
	add.l	#22,a0		;end of file name
	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_end	;empty name
	lea	6(a5),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)+	;null terminated string
	dbf	d1,30$
	clr.b	(a1)+
	cmp.b	#2,(a5)
	beq	emt36_write	;command #2 - write
	cmp.b	#3,(a5)
	bne	emt36_end

emt36_read
	move.l	#MODE_OLDFILE,d2
	move.l	#name_full,d1
	CALLDOS	Open
	move.l	d0,emt36_handle
	beq	emt36_end	;error during file open....
	move.l	d0,d1
	move.l	#fib_buffer,d2
	CALLDOS ExamineFH	;reading file info block
	tst.l	d0
	beq	100$
	lea	fib_buffer+fib_Comment,a0	;comment
	clr.b	ROM_load_enable	;same flag
	clr.l	d0	;address counter
20$	clr.l	d1
30$	move.b	(a0)+,d0	;extract address from comment
	beq.s	40$
	cmp.b	#"M",d0
	bne.s	33$
	clr.b	bk_color_mode	;set monochrome mode
33$	cmp.b	#"C",d0
	bne.s	34$
	move.b	#-1,bk_color_mode	;set color mode
34$	cmp.b	#"R",d0
	bne.s	35$
	not.b	ROM_load_enable		;enable loading in ROM
35$	cmp.b	#"S",d0
	bne.s	36$
	bset.b	#7,int_flags	;enable delay
36$	cmp.b	#"F",d0
	bne.s	37$
	bclr.b	#7,int_flags	;disable delay
37$	cmp.b	#"7",d0
	bhi.s	20$
	sub.b	#"0",d0
	bmi.s	20$
	asl.w	#3,d1	;next digit
	add.w	d0,d1
	bra.s	30$
40$	tst.w	d1
	bne.s	50$		;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
				;it is used on FAT disks in BK OSes.
	bne.s	50$
	move.w	#@40000,d1	;in zero case
50$	ext.l	d1		;sign extension
	move.w	d1,d0
	rol.w	#8,d0
	move.w	d0,d4
	move.l	emt36_block_ptr,a5
	move.l	emt36_ptr,d2	;address for loading
	move.w	2(a5),d5	;address = zero?
	bne.s	60$		;no
	add.l	d1,d2		;yes - add real address to physical
	bra.s	70$
60$	move.w	d5,d0	;address not zero - replace default with it
70$	tst.b	d0
	bpl.s	75$
	tst.b	ROM_load_enable
	beq.s	100$
75$	move.w	d0,emul_buffer_mid+@264	;real load address
	move.w	d4,@26(a5)		;default load address
	move.l	fib_buffer+fib_Size,d3	;real length
	tst.w	fib_buffer+fib_Size	;test MSW
	beq.s	80$			;length less than 65535 bytes
	clr.l	d3
	moveq.w	#-1,d3			;if file longer
80$	move.w	d3,d0
	rol.w	#8,d0
	move.w	d0,@30(a5)		;length no more than 65535
	move.w	d0,emul_buffer_mid+@266	;--//--
	move.l	d2,d7			;buffer
	add.l	d3,d7			;end address of loaded data
	sub.l	#emul_buffer_end,d7	;load over ROM?
	bmi.s	90$
	sub.l	d7,d3			;yes - decrease of reading length
90$	move.l	emt36_handle,d1
	CALLDOS Read
	tst.l	d0
	bmi.s	100$	;load error
	move.l	emt36_block_ptr,a5
	clr.b	1(a5)			;operation finished succesfully
	addq.l	#6,a5
	lea	20(a5),a6
	move.l	(a5)+,(a6)+		;copy name to second part
	move.l	(a5)+,(a6)+		;of parameter block
	move.l	(a5)+,(a6)+
	move.l	(a5)+,(a6)+
100$	move.l	emt36_handle,d1
	CALLDOS Close
	bra	emt36_end

emt36_write
	move.l	#MODE_NEWFILE,d2
	move.l	#name_full,d1
	CALLDOS	Open
	move.l	d0,emt36_handle
	beq	emt36_end
	move.l	d0,d1
	move.l	emt36_ptr,d2
	clr.l	d3
	move.w	emt36_len,d3
	clr.l	-(sp)
	move.l	d2,d7			;buffer
	add.l	d3,d7			;end address of loaded data
	sub.l	#emul_buffer_end,d7	;load over ROM?
	bmi.s	10$
	move.l	d7,(sp)		;overload
	sub.l	d7,d3		;yes - decrease of reading length
10$	CALLDOS	Write
	move.l	(sp)+,d3
	beq.s	20$
	move.l	#emul_buffer_begin,d2
	move.l	emt36_handle,d1
	CALLDOS	Write
20$	move.l	emt36_handle,d1
	CALLDOS Close
	lea	comment_buffer,a0
	move.w	emt36_adr,d4
30$	move.w	d4,d0
	beq.s	40$
	lsr.w	#3,d4
	and.w	#@7,d0
	add.l	#48,d0
	move.b	d0,-(a0)
	bra.s	30$
40$	move.l	a0,d2
	move.l	#name_full,d1
	CALLDOS	SetComment
	move.l	emt36_block_ptr,a5
	clr.b	1(a5)

emt36_end
	move.l	decode_proc_ptr,a1
	move.l	decode_emt36_signal,d0
	CALLEXEC Signal
	bra	main_loop


err_exit
	move.l	#20,return_code
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	#ALL_BREAKF,d0		;wait for Break signal
	CALLEXEC Wait			;(maybe received from anybody)
	tst.b	control_break_flag
	beq.s	10$
cf1	move.l	ROM_file_handle,d1
	beq.s	cl1
	CALLDOS	Close
cl1	move.l	_DOSBase,a1
	tst.l	a1
	beq.s	cl2
	CALLEXEC CloseLibrary
cl2	move.l	_GfxBase,a1
	tst.l	a1
	beq.s	cl3
	CALLEXEC CloseLibrary
cl3	move.l	_IntuitionBase,a1
	tst.l	a1
	beq.s	ca1
	CALLEXEC CloseLibrary
ca1	tst.l	WB_return_message
	beq.s	10$
	CALLEXEC Forbid
	move.l	WB_return_message,a1
	CALLEXEC ReplyMsg
10$	move.l	return_code,d0
	rts

;----------------------------------------
;  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	refresh_proc
20$	asr.w	#1,d0
	move.l	d0,color_x+4
	move.l	a1,color_y+4

refresh_proc
	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	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
	bra.s	30$
215$	lea	keytab2,a0
	bsr.s	key_compare
25$	bsr	send_code
30$	tst.b	refresh_break_flag	;Break received?
	bne	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
	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	20$
	move.l	d0,sbs_cop
	lea	c_bk_screen,a0
	CALLINT	OpenWindow		;open main backdrop window
	move.l	d0,cbs_ptr
	beq	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
	tst.l	a0
	beq.s	10$
	move.l	a1,-(sp)
	move.l	a2,-(sp)
	CALLINT	CloseWindow
	move.l	(sp)+,a2
	move.l	(sp)+,a1
10$	move.l	a1,a0
	tst.l	a0
	beq.s	20$
	move.l	a2,-(sp)
	CALLINT	CloseWindow
	move.l	(sp)+,a2
20$	move.l	a2,a0
	tst.l	a0
	beq.s	30$
	CALLINT	CloseScreen
30$	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
	lea	conv_table,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,$00
	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$	add.w	#32,a1
	add.w	#32,a2
	cmp.l	a0,a4
	bne.s	20$
	sub.l	#$4000,a0
20$	dbf	d4,10$

	bsr	test_delay
	tst.w	d5
	beq.s	80$
	add.w	#$3000,a5
	add.w	#$1800,a1
	add.w	#$1800,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,$00
	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$	add.w	#64,a1
	cmp.l	a0,a4
	bne.s	20$
	sub.l	#$4000,a0
20$	dbf	d4,10$
	bsr	test_delay
	tst.w	d5
	beq.s	80$
	add.w	#$3000,a5
	add.w	#$3000,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	10$			;yes
	cmp.l	#1024,d3		;half screen or more was refreshed?
	blo	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

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

; ------------------
; MACRO COMMANDS SET
; ------------------
;
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
	move.b	(a4,\1.w),\2	;done
	ENDM
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
	rol.w	#8,\2		;swap bytes
	ENDM
BK_SB	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_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
	rol.w	#8,\1		;swap bytes
	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
BK_RRW	MACRO		;BK_RW without \1 trashing
	move.w	\1,\2
	BK_RW	\2,\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

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	#4,(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	#6,(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	#4,(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	#6,(sp)		;skip ROL.W #8 and 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
	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.l	sp,a5
	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
	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
	rts
rp177716
	move.w	p177716,d6
	rts

wp177714
	rts
rp177714
	move.w	p177714,d6
	rts

setjoy	clr.l	d6	;joystick emulation
	move.w	$dff00c,d0
	btst.l	#9,d0
	beq.s	10$
	bset.l	#1,d6	;left
	btst.l	#8,d0
	bne.s	30$
	bra.s	20$
10$	btst.l	#8,d0
	beq.s	30$
20$	bset.l	#2,d6	;forward
30$	btst.l	#1,d0
	beq.s	40$
	bset.l	#0,d6	;right
	btst.l	#0,d0
	bne.s	60$
	bra.s	50$
40$	btst.l	#0,d0
	beq.s	60$
50$	bset.l	#3,d6	;back
60$	tst.b	$bfe001
	bmi.s	70$
	bset.l	#5,d6	;fire0
70$	btst.b	#6,$dff016
	bne.s	80$
	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

_emt_36
	movem.l	d0-a6,-(sp)
	add.w	p1,a4
	move.l	a4,emt36_block_ptr
	move.l	control_proc_signal,d0
	move.l	control_proc_ptr,a1
	CALLEXEC Signal
	move.l	decode_emt36_signal,d0
	CALLEXEC Wait
	movem.l	(sp)+,d0-a6
	RETCMD

	wbp	d4,p0
	wbp	d4,p1
	wbp	d4,p2
	wbp	d4,p3
	wbp	d4,p4
	wbp	d4,p5
	wbp	d4,p6
	wbp	d4,p7
	wbp	d6,p0
	wbp	d6,p1
	wbp	d6,p2
	wbp	d6,p3
	wbp	d6,p4
	wbp	d6,p5
	wbp	d6,p6
	wbp	d6,p7
	wbp	d4,d6
	wbp	d6,d7
	wbp	d5,d4

	rbp	p0,d4
	rbp	p1,d4
	rbp	p2,d4
	rbp	p3,d4
	rbp	p4,d4
	rbp	p5,d4
	rbp	p6,d4
	rbp	p7,d4
	rbp	p0,d6
	rbp	p1,d6
	rbp	p2,d6
	rbp	p3,d6
	rbp	p4,d6
	rbp	p5,d6
	rbp	p6,d6
	rbp	p7,d6
	rbp	d4,d4
	rbp	d7,d6
	rbp	d6,d5
	rbp	d4,d5

	rwp	d4,d4
	rwp	d6,d6
	rwp	d6,d3
	rwp	d4,d3
	rwp	d7,d7
	rwp	d7,d6
	rwp	d4,d6
	rwp	d1,d1

	wwp	d3,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_SB	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___	and.w	#%111111,d4
	lea	ad_jw(pc),a6
	move.l	(a6,d4.l*4),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

	FCMD_Rn	sob_
;
;---------------------------------
; 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
;
_clr___	move.l	d4,d6
	and.w	#%11110000,d5
	or.w	#%00000100,d5
	clr.l	d4
	and.w	#%111111,d6
	lea	ad_ww(pc),a6
	move.l	(a6,d6.l*4),a6
	jmp	(a6)
_clrb__	move.l	d4,d6
	and.w	#%11110000,d5
	or.w	#%00000100,d5
	clr.l	d4
	and.w	#%111111,d6
	lea	ad_wb(pc),a6
	move.l	(a6,d6.l*4),a6
	jmp	(a6)

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___	and.w	#%111111,d4
	lea	ad_rw(pc),a6
	move.l	(a6,d4.l*4),a6
	CALL	a6,a5
	tst.w	d4
_tst_rx	move.w	ccr,d4
	and.w	#%00001100,d4
	and.w	#%11110000,d5
	or.w	d4,d5
	RETCMD
_tstb__	and.w	#%111111,d4
	lea	ad_rb(pc),a6
	move.l	(a6,d4.l*4),a6
	CALL	a6,a5
	tst.b	d4
	move.w	ccr,d4
	and.w	#%00001100,d4
	and.w	#%11110000,d5
	or.w	d4,d5
	RETCMD

;-------------------------------------
; COM(B) D - Inversion
;
_com___	and.w	#%111111,d4
	lea	ad_mw(pc),a6
	move.l	(a6,d4.l*4),a6
	lea	1$(pc),a5
	jmp	(a6)
1$	not.w	d6
	move.w	ccr,d4
	and.w	#%00001100,d4
	addq.w	#1,d4
	and.w	#%11110000,d5
	or.w	d4,d5
	RET	a6
_comb__	and.w	#%111111,d4
	lea	ad_mb(pc),a6
	move.l	(a6,d4.l*4),a6
	lea	1$(pc),a5
	jmp	(a6)
1$	not.b	d6
	move.w	ccr,d4
	and.w	#%00001100,d4
	addq.w	#1,d4
	and.w	#%11110000,d5
	or.w	d4,d5
	RET	a6

;-------------------------------------
; INC(B) D - Increment
;
_inc___	and.w	#%111111,d4
	lea	ad_mw(pc),a6
	move.l	(a6,d4.l*4),a6
	lea	1$(pc),a5
	jmp	(a6)
1$	addq.w	#1,d6
	move.w	ccr,d4
	and.w	#%00001110,d4
	and.w	#%11110001,d5
	or.w	d4,d5
	RET	a6
_incb__	and.w	#%111111,d4
	lea	ad_mb(pc),a6
	move.l	(a6,d4.l*4),a6
	lea	1$(pc),a5
	jmp	(a6)
1$	addq.b	#1,d6
	move.w	ccr,d4
	and.w	#%00001110,d4
	and.w	#%11110001,d5
	or.w	d4,d5
	RET	a6

;-------------------------------------
; DEC(B) D - Decrement
;
_dec___	and.w	#%111111,d4
	lea	ad_mw(pc),a6
	move.l	(a6,d4.l*4),a6
	lea	1$(pc),a5
	jmp	(a6)
1$	subq.w	#1,d6
	move.w	ccr,d4
	and.w	#%00001110,d4
	and.w	#%11110001,d5
	or.w	d4,d5
	RET	a6
_decb__	and.w	#%111111,d4
	lea	ad_mb(pc),a6
	move.l	(a6,d4.l*4),a6
	lea	1$(pc),a5
	jmp	(a6)
1$	subq.b	#1,d6
	move.w	ccr,d4
	and.w	#%00001110,d4
	and.w	#%11110001,d5
	or.w	d4,d5
	RET	a6

;------------------------------------------
; SWAB D - Swap bytes in word
;
_swab__	and.w	#%111111,d4
	lea	ad_mw(pc),a6
	move.l	(a6,d4.l*4),a6
	lea	1$(pc),a5
	jmp	(a6)
1$	rol.w	#8,d6
	tst.b	d6
	move.w	ccr,d4
	and.w	#%00001100,d4
	and.w	#%11110000,d5
	or.w	d4,d5
	RET	a6
;------------------------------------------
; SXT D - Sign flag extension
;
_sxt___	and.w	#%111111,d4
	lea	ad_mw(pc),a6
	move.l	(a6,d4.l*4),a6
	lea	1$(pc),a5
	jmp	(a6)
1$	move.w	d5,d6
	rol.w	#4,d6
	extb.l	d6
	swap	d6
	tst.w	d6
	move.w	ccr,d4
	and.w	#%00000100,d4
	and.w	#%11111001,d5
	or.w	d4,d5
	RET	a6

;-------------------------------------
; NEG(B) D - Sign change
;
_neg___	and.w	#%111111,d4
	lea	ad_mw(pc),a6
	move.l	(a6,d4.l*4),a6
	lea	1$(pc),a5
	jmp	(a6)
1$	neg.w	d6
	move.w	ccr,d4
	and.w	#%00001111,d4
	and.w	#%11110000,d5
	or.w	d4,d5
	RET	a6
_negb__	and.w	#%111111,d4
	lea	ad_mb(pc),a6
	move.l	(a6,d4.l*4),a6
	lea	1$(pc),a5
	jmp	(a6)
1$	neg.b	d6
	move.w	ccr,d4
	and.w	#%00001111,d4
	and.w	#%11110000,d5
	or.w	d4,d5
	RET	a6

;-------------------------------------
; ASL(B) D - Arithmetic left shift
;
asl_rn	MACRO
	move.w	\1,d6
	asl.w	#1,d6
	move.w	ccr,d4
	and.w	#%00001111,d4
	and.w	#%11110000,d5
	or.w	d4,d5
	move.w	d6,\1
	RETCMD
	ENDM
aslbrn	MACRO
	move.w	\1,d6
	asl.b	#1,d6
	move.w	ccr,d4
	and.w	#%00001111,d4
	and.w	#%11110000,d5
	or.w	d4,d5
	move.w	d6,\1
	RETCMD
	ENDM

	FCMD_Rn	asl_
	FCMD_Rn	aslb

_asl___	and.w	#%111111,d4
	lea	ad_mw(pc),a6
	move.l	(a6,d4.l*4),a6
	lea	1$(pc),a5
	jmp	(a6)
1$	asl.w	#1,d6
	move.w	ccr,d4
	and.w	#%00001111,d4
	and.w	#%11110000,d5
	or.w	d4,d5
	RET	a6
_aslb__	and.w	#%111111,d4
	lea	ad_mb(pc),a6
	move.l	(a6,d4.l*4),a6
	lea	1$(pc),a5
	jmp	(a6)
1$	asl.b	#1,d6
	move.w	ccr,d4
	and.w	#%00001111,d4
	and.w	#%11110000,d5
	or.w	d4,d5
	RET	a6

;-------------------------------------
; ASR(B) D - Arithmetic rigth shift
;
asr_rn	MACRO
	move.w	\1,d6
	asr.w	#1,d6
	move.w	ccr,d4
	move.w	d6,\1
	and.w	#%00001111,d4
	and.w	#%11110000,d5
	or.w	d4,d5
	RETCMD
	ENDM
asrbrn	MACRO
	move.w	\1,d6
	asr.b	#1,d6
	move.w	ccr,d4
	move.w	d6,\1
	and.w	#%00001111,d4
	and.w	#%11110000,d5
	or.w	d4,d5
	RETCMD
	ENDM

	FCMD_Rn	asr_
	FCMD_Rn	asrb

_asr___	and.w	#%111111,d4
	lea	ad_mw(pc),a6
	move.l	(a6,d4.l*4),a6
	lea	1$(pc),a5
	jmp	(a6)
1$	asr.w	#1,d6
	move.w	ccr,d4
	and.w	#%00001111,d4
	and.w	#%11110000,d5
	or.w	d4,d5
	RET	a6
_asrb__	and.w	#%111111,d4
	lea	ad_mb(pc),a6
	move.l	(a6,d4.l*4),a6
	lea	1$(pc),a5
	jmp	(a6)
1$	asr.b	#1,d6
	move.w	ccr,d4
	and.w	#%00001111,d4
	and.w	#%11110000,d5
	or.w	d4,d5
	RET	a6

;-------------------------------------
; 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$	move.w	ccr,d4
	move.w	d6,\1
	and.w	#%00001111,d4
	and.w	#%11110000,d5
	or.w	d4,d5
	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$	move.w	ccr,d4
	move.w	d6,\1
	and.w	#%00001111,d4
	and.w	#%11110000,d5
	or.w	d4,d5
	RETCMD
	ENDM

	FCMD_Rn	rol_
	FCMD_Rn	rolb

_rol___	and.w	#%111111,d4
	lea	ad_mw(pc),a6
	move.l	(a6,d4.l*4),a6
	lea	1$(pc),a5
	jmp	(a6)
1$	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$	move.w	ccr,d4
	and.w	#%00001111,d4
	and.w	#%11110000,d5
	or.w	d4,d5
	RET	a6
_rolb__	and.w	#%111111,d4
	lea	ad_mb(pc),a6
	move.l	(a6,d4.l*4),a6
	lea	1$(pc),a5
	jmp	(a6)
1$	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$	move.w	ccr,d4
	and.w	#%00001111,d4
	and.w	#%11110000,d5
	or.w	d4,d5
	RET	a6

;-------------------------------------
; 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$	move.w	ccr,d4
	move.w	d6,\1
	and.w	#%00001111,d4
	and.w	#%11110000,d5
	or.w	d4,d5
	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$	move.w	ccr,d4
	move.w	d6,\1
	and.w	#%00001111,d4
	and.w	#%11110000,d5
	or.w	d4,d5
	RETCMD
	ENDM

	FCMD_Rn	ror_
	FCMD_Rn	rorb

_ror___	and.w	#%111111,d4
	lea	ad_mw(pc),a6
	move.l	(a6,d4.l*4),a6
	lea	1$(pc),a5
	jmp	(a6)
1$	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$	move.w	ccr,d4
	and.w	#%00001111,d4
	and.w	#%11110000,d5
	or.w	d4,d5
	RET	a6
_rorb__	and.w	#%111111,d4
	lea	ad_mb(pc),a6
	move.l	(a6,d4.l*4),a6
	lea	1$(pc),a5
	jmp	(a6)
1$	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$	move.w	ccr,d4
	and.w	#%00001111,d4
	and.w	#%11110000,d5
	or.w	d4,d5
	RET	a6

;------------------------------------------
; ADC(B) D - Add carry bit
;
_adc___	and.w	#%111111,d4
	lea	ad_mw(pc),a6
	move.l	(a6,d4.l*4),a6
	lea	1$(pc),a5
	jmp	(a6)
1$	move.w	d5,d4
	and.w	#1,d4
	add.w	d4,d6
	move.w	ccr,d4
	and.w	#%00001111,d4
	and.w	#%11110000,d5
	or.w	d4,d5
	RET	a6
_adcb__	and.w	#%111111,d4
	lea	ad_mb(pc),a6
	move.l	(a6,d4.l*4),a6
	lea	1$(pc),a5
	jmp	(a6)
1$	move.w	d5,d4
	and.w	#1,d4
	add.b	d4,d6
	move.w	ccr,d4
	and.w	#%00001111,d4
	and.w	#%11110000,d5
	or.w	d4,d5
	RET	a6

;------------------------------------------
; SBC(B) D - Subtract carry bit
;
_sbc___	and.w	#%111111,d4
	lea	ad_mw(pc),a6
	move.l	(a6,d4.l*4),a6
	lea	1$(pc),a5
	jmp	(a6)
1$	move.w	d5,d4
	and.w	#1,d4
	sub.w	d4,d6
	move.w	ccr,d4
	and.w	#%00001111,d4
	and.w	#%11110000,d5
	or.w	d4,d5
	RET	a6
_sbcb__	and.w	#%111111,d4
	lea	ad_mb(pc),a6
	move.l	(a6,d4.l*4),a6
	lea	1$(pc),a5
	jmp	(a6)
1$	move.w	d5,d4
	and.w	#1,d4
	sub.b	d4,d6
	move.w	ccr,d4
	and.w	#%00001111,d4
	and.w	#%11110000,d5
	or.w	d4,d5
	RET	a6

;---------------------------------
; CMP(B) S,D - Compare
;
_cmp___	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
	move.w	d4,d7
	and.w	#%111111,d6
	lea	ad_rw(pc),a6
	move.l	(a6,d6.l*4),a6
	CALL	a6,a5
	cmp.w	d4,d7
	move.w	ccr,d4
	and.w	#%00001111,d4
	and.w	#%11110000,d5
	or.w	d4,d5
	RETCMD
_cmpb__	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
	move.w	d4,d7
	and.w	#%111111,d6
	lea	ad_rb(pc),a6
	move.l	(a6,d6.l*4),a6
	CALL	a6,a5
	cmp.b	d4,d7
	move.w	ccr,d4
	and.w	#%00001111,d4
	and.w	#%11110000,d5
	or.w	d4,d5
	RETCMD

;-------------------------------------
; BIT(B) S,D - Bit test
;
_bit___	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
	move.w	d4,d7
	and.w	#%111111,d6
	lea	ad_rw(pc),a6
	move.l	(a6,d6.l*4),a6
	CALL	a6,a5
	and.w	d7,d4
	move.w	ccr,d4
	and.w	#%00001100,d4
	and.w	#%11110001,d5
	or.w	d4,d5
	RETCMD
_bitb__	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
	move.w	d4,d7
	and.w	#%111111,d6
	lea	ad_rb(pc),a6
	move.l	(a6,d6.l*4),a6
	CALL	a6,a5
	and.b	d7,d4
	move.w	ccr,d4
	and.w	#%00001100,d4
	and.w	#%11110001,d5
	or.w	d4,d5
	RETCMD

;-------------------------------------
; BIS(B) S,D - Bit set
;
_bis___	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
	and.w	#%111111,d6
	lea	ad_mw(pc),a6
	move.l	(a6,d6.l*4),a6
	lea	1$(pc),a5
	jmp	(a6)
1$	or.w	d4,d6
	move.w	ccr,d4
	and.w	#%00001100,d4
	and.w	#%11110001,d5
	or.w	d4,d5
	RET	a6
_bisb__	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
	and.w	#%111111,d6
	lea	ad_mb(pc),a6
	move.l	(a6,d6.l*4),a6
	lea	1$(pc),a5
	jmp	(a6)
1$	or.b	d4,d6
	move.w	ccr,d4
	and.w	#%00001100,d4
	and.w	#%11110001,d5
	or.w	d4,d5
	RET	a6

;-------------------------------------
; BIC(B) S,D - Bit clearing
;
_bic___	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
	and.w	#%111111,d6
	lea	ad_mw(pc),a6
	move.l	(a6,d6.l*4),a6
	lea	1$(pc),a5
	jmp	(a6)
1$	not.w	d4
	and.w	d4,d6
	move.w	ccr,d4
	and.w	#%00001100,d4
	and.w	#%11110001,d5
	or.w	d4,d5
	RET	a6
_bicb__	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
	and.w	#%111111,d6
	lea	ad_mb(pc),a6
	move.l	(a6,d6.l*4),a6
	lea	1$(pc),a5
	jmp	(a6)
1$	not.b	d4
	and.b	d4,d6
	move.w	ccr,d4
	and.w	#%00001100,d4
	and.w	#%11110001,d5
	or.w	d4,d5
	RET	a6

;-------------------------------------
; ADD S,D - Add
;
_add___	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
	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
	move.w	ccr,d4
	and.w	#%00001111,d4
	and.w	#%11110000,d5
	or.w	d4,d5
	RET	a6

;-------------------------------------
; SUB S,D - Subtract
;
_sub___	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
	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
	move.w	ccr,d4
	and.w	#%00001111,d4
	and.w	#%11110000,d5
	or.w	d4,d5
	RET	a6

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

xor_rx	eor.w	d4,d6
	move.w	ccr,d4
	and.w	#%00001100,d4
	and.w	#%11110001,d5
	or.w	d4,d5
	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_emt36_signal
	moveq.l	#-1,d0
	CALLEXEC AllocSignal
	moveq.l	#1,d1
	lsl.l	d0,d1
	move.l	d1,decode_delay_signal
	moveq.l	#-1,d0
	CALLEXEC AllocSignal
	moveq.l	#1,d1
	lsl.l	d0,d1
	move.l	d1,decode_sleep_signal
	move.l	sp,decode_init_stack
	move.l	#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
reset	move.l	#$8000,d3	;PC
	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_RW	d4,d4		;get opcode
	move.l	#time_table,a6
	move.w	(a6,d4.l*2),d6	;get precalculated opcode timing
	sub.w	d6,delay_counter
	bpl.s	10$
	move.w	#3500,delay_counter	;reset timing counter
	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
10$	move.l	#decode_table,a6
	move.l	(a6,d4.l*4),a6	;get opcode procedure address
	jmp	(a6)

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
	beq.s	80$
	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
80$	clr.l	d4
dc_rtt	move.w	d3,d4
	addq.w	#2,d3
	BK_RW	d4,d4
	move.l	#decode_table,a6
	move.l	(a6,d4.l*4),a6
	jmp	(a6)

; int_flags bits:
; 0 - RESET
; 1 - STOP
; 2 - trace
; 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)


;--------------------------------
;  BYTE SOURCE ADDRESSING MODES
;--------------------------------
ad0xrb	MACRO			; move byte from R
	move.w	\1,d4
	RET	a5
	ENDM
ad1xrb	MACRO			; move byte from (R)
	BK_RB	\1,d4
	RET	a5
	ENDM
ad2xrb	MACRO			; move byte from (R)+
	BK_RB	\1,d4
	IFC	'\1','p6'
	addq.w	#2,\1
	ELSE
	IFC	'\1','p7'
	addq.w	#2,\1
	ELSE
	addq.w	#1,\1
	ENDC
	ENDC
	RET	a5
	ENDM
ad3xrb	MACRO			; move byte from @(R)+
	BK_RRW	\1,d4
	addq.w	#2,\1
	BK_RB	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_RB	\1,d4
	RET	a5
	ENDM
ad5xrb	MACRO			; move byte from @-(R)
	subq.w	#2,\1
	BK_RRW	\1,d4
	BK_RB	d4,d4
	RET	a5
	ENDM
ad6xrb	MACRO			; move byte from N(R)
	BK_RRW	d3,d4
	addq.w	#2,d3
	add.w	\1,d4
	BK_RB	d4,d4
	RET	a5
	ENDM
ad7xrb	MACRO			; move byte from @N(R)
	BK_RRW	d3,d4
	addq.w	#2,d3
	add.w	\1,d4
	BK_RW	d4,d4
	BK_RB	d4,d4
	RET	a5
	ENDM

;--------------------------------
;  WORD SOURCE ADDRESSING MODES
;--------------------------------
ad0xrw	MACRO			; move word from R
	move.w	\1,d4
	RET	a5
	ENDM
ad1xrw	MACRO			; move word from (R)
	BK_RRW	\1,d4
	RET	a5
	ENDM
ad2xrw	MACRO			; move word from (R)+
	BK_RRW	\1,d4
	addq.w	#2,\1
	RET	a5
	ENDM
ad3xrw	MACRO			; move word from @(R)+
	BK_RRW	\1,d4
	addq.w	#2,\1
	BK_RW	d4,d4
	RET	a5
	ENDM
ad4xrw	MACRO			; move word from -(R)
	subq.w	#2,\1
	BK_RRW	\1,d4
	RET	a5
	ENDM
ad5xrw	MACRO			; move word from @-(R)
	subq.w	#2,\1
	BK_RRW	\1,d4
	BK_RW	d4,d4
	RET	a5
	ENDM
ad6xrw	MACRO			; move word from N(R)
	BK_RRW	d3,d4
	addq.w	#2,d3
	add.w	\1,d4
	BK_RW	d4,d4
	RET	a5
	ENDM
ad7xrw	MACRO			; move word from @N(R)
	BK_RRW	d3,d4
	addq.w	#2,d3
	add.w	\1,d4
	BK_RW	d4,d4
	BK_RW	d4,d4
	RET	a5
	ENDM

;-------------------------------------
;  BYTE DESTINATION ADDRESSING MODES
;-------------------------------------
ad0xwb	MACRO			; move byte to R
	move.w	d4,\1
	RETCMD
	ENDM
ad1xwb	MACRO			; move byte to (R)
	BK_SB	d4,\1
	RETCMD
	ENDM
ad2xwb	MACRO			; move byte to (R)+
	BK_SB	d4,\1
	IFC	'\1','p6'
	addq.w	#2,\1
	ELSE
	IFC	'\1','p7'
	addq.w	#2,\1
	ELSE
	addq.w	#1,\1
	ENDC
	ENDC
	RETCMD
	ENDM
ad3xwb	MACRO			; move byte to @(R)+
	BK_RRW	\1,d6
	addq.w	#2,\1
	BK_SB	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
	BK_SB	d4,\1
	RETCMD
	ENDM
ad5xwb	MACRO			; move byte to @-(R)
	subq.w	#2,\1
	BK_RRW	\1,d6
	BK_SB	d4,d6
	RETCMD
	ENDM
ad6xwb	MACRO			; move byte to N(R)
	BK_RRW	d3,d6
	addq.w	#2,d3
	add.w	\1,d6
	BK_SB	d4,d6
	RETCMD
	ENDM
ad7xwb	MACRO			; move byte to @N(R)
	BK_RRW	d3,d6
	addq.w	#2,d3
	add.w	\1,d6
	BK_RW	d6,d6
	BK_SB	d4,d6
	RETCMD
	ENDM

;-------------------------------------
;  WORD DESTINATION ADDRESSING MODES
;-------------------------------------
ad0xww	MACRO			; move word to R
	move.w	d4,\1
	RETCMD
	ENDM
ad1xww	MACRO			; move word to (R)
	move.w	\1,d6
	BK_SW	d4,d6
	RETCMD
	ENDM
ad2xww	MACRO			; move word to (R)+
	move.w	\1,d6
	BK_SW	d4,d6
	addq.w	#2,\1
	RETCMD
	ENDM
ad3xww	MACRO			; move word to @(R)+
	BK_RRW	\1,d6
	addq.w	#2,\1
	BK_SW	d4,d6
	RETCMD
	ENDM
ad4xww	MACRO			; move word to -(R)
	subq.w	#2,\1
	move.w	\1,d6
	BK_SW	d4,d6
	RETCMD
	ENDM
ad5xww	MACRO			; move word to @-(R)
	subq.w	#2,\1
	BK_RRW	\1,d6
	BK_SW	d4,d6
	RETCMD
	ENDM
ad6xww	MACRO			; move word to N(R)
	BK_RRW	d3,d6
	addq.w	#2,d3
	add.w	\1,d6
	BK_SW	d4,d6
	RETCMD
	ENDM
ad7xww	MACRO			; move word to @N(R)
	BK_RRW	d3,d6
	addq.w	#2,d3
	add.w	\1,d6
	BK_RW	d6,d6
	BK_SW	d4,d6
	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_RRW	\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_RRW	\1,d6
	RET	a5
	ENDM
ad6xjw	MACRO			; move word from N(R)
	BK_RRW	d3,d6
	addq.w	#2,d3
	add.w	\1,d6
	RET	a5
	ENDM
ad7xjw	MACRO			; move word from @N(R)
	BK_RRW	d3,d4
	addq.w	#2,d3
	add.w	\1,d4
	BK_RW	d4,d6
	RET	a5
	ENDM

;--------------------------------------
;  BYTE MODIFICATION ADDRESSING MODES
;--------------------------------------
ad0xmb	MACRO			; byte modification in R
	move.w	\1,d6
	CALL	a5,a6
	move.w	d6,\1
	RETCMD
	ENDM
ad1xmb	MACRO			; byte modification in (R)
	BK_RB	\1,d6
	CALL	a5,a6
	BK_SB	d6,\1
	RETCMD
	ENDM
ad2xmb	MACRO			; byte modification in (R)+
	BK_RB	\1,d6
	CALL	a5,a6
	BK_SB	d6,\1
	IFC	'\1','p6'
	addq.w	#2,\1
	ELSE
	IFC	'\1','p7'
	addq.w	#2,\1
	ELSE
	addq.w	#1,\1
	ENDC
	ENDC
	RETCMD
	ENDM
ad3xmb	MACRO			; byte modification in @(R)+
	BK_RRW	\1,d7
	addq.w	#2,\1
	BK_RB	d7,d6
	CALL	a5,a6
	BK_SB	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
	BK_RB	\1,d6
	CALL	a5,a6
	BK_SB	d6,\1
	RETCMD
	ENDM
ad5xmb	MACRO			; byte modification in @-(R)
	subq.w	#2,\1
	BK_RRW	\1,d7
	BK_RB	d7,d6
	CALL	a5,a6
	BK_SB	d6,d7
	RETCMD
	ENDM
ad6xmb	MACRO			; byte modification in N(R)
	BK_RRW	d3,d7
	addq.w	#2,d3
	add.w	\1,d7
	BK_RB	d7,d6
	CALL	a5,a6
	BK_SB	d6,d7
	RETCMD
	ENDM
ad7xmb	MACRO			; byte modification in @N(R)
	BK_RRW	d3,d7
	addq.w	#2,d3
	add.w	\1,d7
	BK_RW	d7,d7
	BK_RB	d7,d6
	CALL	a5,a6
	BK_SB	d6,d7
	RETCMD
	ENDM

;--------------------------------------
;  WORD MODIFICATION ADDRESSING MODES
;--------------------------------------
ad0xmw	MACRO			; word modification in R
	move.w	\1,d6
	CALL	a5,a6
	move.w	d6,\1
	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
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
ad3xmw	MACRO			; word modification in @(R)+
	BK_RRW	\1,d7
	addq.w	#2,\1
	BK_RW	d7,d6
	CALL	a5,a6
	BK_NSW	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
ad5xmw	MACRO			; word modification in @-(R)
	subq.w	#2,\1
	BK_RRW	\1,d7
	BK_RW	d7,d6
	CALL	a5,a6
	BK_NSW	d6,d7
	RETCMD
	ENDM
ad6xmw	MACRO			; word modification in N(R)
	BK_RRW	d3,d7
	addq.w	#2,d3
	add.w	\1,d7
	BK_RW	d7,d6
	CALL	a5,a6
	BK_NSW	d6,d7
	RETCMD
	ENDM
ad7xmw	MACRO			; word modification in @N(R)
	BK_RRW	d3,d7
	addq.w	#2,d3
	add.w	\1,d7
	BK_RW	d7,d7
	BK_RW	d7,d6
	CALL	a5,a6
	BK_NSW	d6,d7
	RETCMD
	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


	section	tables,data

	cnop	0,4
;-------------------------------------
;  HARDWARE REGISTERS TABLE FOR READ
;-------------------------------------
; 
	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
;-----------------------------------
;
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
	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___,30	;104000
	dCMD	_emt_36,1	;104036
	dCMD	_emt___,225	;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

		cnop	0,4

monotag		dc.l	SA_DisplayID,$8000
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,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
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

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


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


	dc.b	$87,$B6,$D4,$AF,$83,$AA,$BF,$94
	dc.b	$82,$D4,$AD,$BE,$81,$76,$B5,$95
	dc.b	$A5,$3C,$9A,$5E,$D4,$A1,$9E,$A2
	dc.b	$2A,$B4,$9F,$87,$80,$8D,$3E,$9C
	dc.b	$FE,$E0,$E1,$F6,$E4,$E5,$F4,$E3
	dc.b	$F5,$E8,$E9,$EA,$EB,$EC,$ED,$EE
	dc.b	$EF,$FF,$F0,$F1,$F2,$F3,$E6,$E2
	dc.b	$FC,$FB,$E7,$F8,$FD,$F9,$F7,$FA
	dc.b	$DE,$C0,$C1,$D6,$C4,$C5,$D4,$C3
	dc.b	$D5,$C8,$C9,$CA,$CB,$CC,$CD,$CE
	dc.b	$CF,$DF,$D0,$D1,$D2,$D3,$C6,$C2
	dc.b	$DC,$DB,$C7,$D8,$DD,$D9,$D7,$DA

koi8_to_1251_table

			cnop	0,4

_SysBase		dc.l	0
_IntuitionBase		dc.l	0		;intuition
_GfxBase		dc.l	0		;graphics
_DOSBase		dc.l	0		;dos
WB_return_message	dc.l	0
emt36_block_ptr		dc.l	0
wbs_ptr			dc.l	0
cbs_ptr			dc.l	0
old_wbs_ptr		dc.l	0
old_cbs_ptr		dc.l	0
old_sbs_ptr		dc.l	0
return_code		dc.l	0
ROM_file_handle		dc.l	0
emt36_handle		dc.l	0
emt36_ptr		dc.l	0
decode_init_stack	dc.l	0
decode_emt36_signal	dc.l	0
decode_delay_signal	dc.l	0
decode_sleep_signal	dc.l	0
decode_proc_ptr		dc.l	0
refresh_proc_ptr	dc.l	0
control_proc_ptr	dc.l	0
control_proc_signal	dc.l	0
intl_flags		dc.w	0
int_flags		dc.w	0
delay_counter		dc.w	2000
slow_counter		dc.w	50
emt36_adr		dc.w	0
emt36_len		dc.w	0
p177660			dc.w	0
p177662			dc.w	0
p177664			dc.w	@1330
c177664			dc.w	@1330
p177714			dc.w	0
p177716			dc.w	@100340
intm_flags		dc.b	0
refresh_counter		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
rus_flag		dc.b	0
ROM_load_enable		dc.b	0
version			dc.b	'$VER: '
w_s_title		dc.b	'bkemul 1.6 beta',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
name_full		dc.b	'PROGDIR:bkfiles/'
name_buffer		ds.b	18
			ds.b	6
comment_buffer		dc.b	0
intname			INTNAME
grafname		GRAFNAME
dosname			DOSNAME

			even

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

	section	decode,bss
decode_table
	ds.l	$10000

	section	time,bss
time_table
	ds.w	$10000

	section	conv,bss
conv_table
	ds.l	$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
