**
**	file: std_instr.a
**
** The non-implementation-dependent Z80 instructions.


** Following opcodes exactly follow Zaks' "Programming the Z80" with the
** exceptions that 'rr' replaces 'ss' where 'ss' is exactly 'rr', and the
** badly named 'dd' is replaced by 'rr' in all places. Also, I have
** consequently used 's' for sources and 'm' for destination modes.
**
** Notation for describing instructions:
**
**	r  = 8-bit register (A, B, C, D, E, H, L)
**	rr = 16-bit register pair (BC, DE, HL, SP)
**	ii = 16-bit index register (IX, IY)
**	qq = 16-bit register pair (BC, DE, HL, AF)
**	n  = 8-bit immediate data
**	nn = 16-bit immediate data
**	s  = 8-bit source
**	ss = 16-bit source
**	m  = 8-bit addressing mode
**	e  = 8-bit relative jump offset (signed, immediate data)
**	d  = 8-bit indexing displacement (signed, immediate data)
**	pq = 16-bit address (immediate data)
**	p  = 8-bit address (immediate data)
**	cc = condition code
**
** Flag effects notation:
**
**	- = not affected
**	* = straightforward dependence on machine state and result
**	0 = reset by operation
**	1 = set by operation
**	? = the effect on the flag is 'random'
**	+ = special case, see instruction notes
**
** Label notation:	Underscore used for SPACE, comma and +
**
**			1 (one) used for ( and )

** -------------------------------------------------------------------------

** Quick 680x0 reference:
**
**	CCR bits:	4 3 2 1 0
**			X N Z V C	(Note that 'N' is Z80 'S'.)

** =========================================================================


**	ADC A,s
**
**	A <- A + s + Carry
**
**	s can be r, n, (HL) or (ii+d)
**
**	Flags:	S Z H V N C
**		* * * * 0 *

adc_A_r 	MACRO
Adc_A_\1
	IFD BCDFLAGS
		moveq	#$F,tmpD0
		and.w	A,tmpD0 	;keep original low nybble of A

		move.b	Z80_\1(TableB),tmpD1
		lsr.w	#1,stCCR	;C to X
		ori	#4,CCR		;set Z
		addx.b	tmpD1,A ;Z reset if nonzero, unchanged if zero
		putccr	stCCR

		;Bits 4-7 of tmpD0 (and Carry) become set if H:
		and.w	#$F,tmpD1	;get low nybble of other operand
		add.b	tmpD0,tmpD1	;sum operand nybbles in tmpD1
		moveq	#$F,tmpD0
		and.w	A,tmpD0 	;get low nybble of result
		sub.b	tmpD1,tmpD0	;subtract sum of operand nybbles
		and.w	#$10,tmpD0	;reset N flag, keeping only H
		move.b	tmpD0,Z80_BCDF(TableB)	;store BCD flags
	ELSE
		move.b	Z80_\1(TableB),tmpD1
		lsr.w	#1,stCCR	;C to X
		moveq	#0,tmpD0	;set Z
		addx.b	tmpD1,A ;Z reset if nonzero, unchanged if zero
		putccr	stCCR
	ENDC
		next
		ENDM

	do_r adc_A_r


Adc_A_H
	IFD BCDFLAGS
		moveq	#$F,tmpD0
		and.w	A,tmpD0

		getH	HL,tmpD1
		lsr.w	#1,stCCR
		ori	#4,CCR
		addx.b	tmpD1,A
		putccr	stCCR

		and.w	#$F,tmpD1
		add.b	tmpD0,tmpD1
		moveq	#$F,tmpD0
		and.w	A,tmpD0
		sub.b	tmpD1,tmpD0
		and.w	#$10,tmpD0
		move.b	tmpD0,Z80_BCDF(TableB)
	ELSE
		getH	HL,tmpD1
		lsr.w	#1,stCCR
		moveq	#0,tmpD0
		addx.b	tmpD1,A
		putccr	stCCR
	ENDC
		next


Adc_A_L
	IFD BCDFLAGS
		moveq	#$F,tmpD1
		and.w	A,tmpD1

		lsr.w	#1,stCCR
		moveq	#0,tmpD0
		addx.b	HL,A	;only L is added
		putccr	stCCR

		moveq	#$F,tmpD0
		and.w	HL,tmpD0	;extract low nybble of L
		add.b	tmpD0,tmpD1
		moveq	#$F,tmpD0
		and.w	A,tmpD0
		sub.b	tmpD1,tmpD0
		and.w	#$10,tmpD0
		move.b	tmpD0,Z80_BCDF(TableB)
	ELSE
		lsr.w	#1,stCCR
		moveq	#0,tmpD0
		addx.b	HL,A	;only L is added
		putccr	stCCR
	ENDC
		next


Adc_A_A
	IFD BCDFLAGS
		moveq	#$F,tmpD1
		and.w	A,tmpD1 	;keep original low nybble of A

		lsr.w	#1,stCCR
		moveq	#0,tmpD0
		addx.b	A,A
		putccr	stCCR

		add.b	tmpD1,tmpD1	;add operand nybbles
		moveq	#$F,tmpD0
		and.w	A,tmpD0 	;get low nybble of result
		sub.b	tmpD1,tmpD0
		and.w	#$10,tmpD0
		move.b	tmpD0,Z80_BCDF(TableB)
	ELSE
		lsr.w	#1,stCCR
		moveq	#0,tmpD0
		addx.b	A,A
		putccr	stCCR
	ENDC
		next


Adc_A_n 	getRPC	tmpD0
		getz	tmpD0,tmpD1
	IFD BCDFLAGS
		moveq	#$F,tmpD0
		and.w	A,tmpD0

		lsr.w	#1,stCCR
		ori	#4,CCR
		addx.b	tmpD1,A
		putccr	stCCR

		and.w	#$F,tmpD1
		add.b	tmpD0,tmpD1
		moveq	#$F,tmpD0
		and.w	A,tmpD0
		sub.b	tmpD1,tmpD0
		and.w	#$10,tmpD0
		move.b	tmpD0,Z80_BCDF(TableB)
	ELSE
		lsr.w	#1,stCCR
		moveq	#0,tmpD0
		addx.b	tmpD1,A
		putccr	stCCR
	ENDC
		skip 1
		next


Adc_A_1HL1	getz	HL,tmpD1
	IFD BCDFLAGS
		moveq	#$F,tmpD0
		and.w	A,tmpD0

		lsr.w	#1,stCCR
		ori	#4,CCR
		addx.b	tmpD1,A
		putccr	stCCR

		and.w	#$F,tmpD1
		add.b	tmpD0,tmpD1
		moveq	#$F,tmpD0
		and.w	A,tmpD0
		sub.b	tmpD1,tmpD0
		and.w	#$10,tmpD0
		move.b	tmpD0,Z80_BCDF(TableB)
	ELSE
		lsr.w	#1,stCCR
		moveq	#0,tmpD0
		addx.b	tmpD1,A
		putccr	stCCR
	ENDC
		next


adc_A_1ii1	MACRO
Adc_A_1I\1_d1	opcode_2_bytes
		index	I\1,tmpD0
		getz	tmpD0,tmpD1
	IFD BCDFLAGS
		moveq	#$F,tmpD0
		and.w	A,tmpD0

		lsr.w	#1,stCCR
		ori	#4,CCR
		addx.b	tmpD1,A
		putccr	stCCR

		and.w	#$F,tmpD1
		add.b	tmpD0,tmpD1
		moveq	#$F,tmpD0
		and.w	A,tmpD0
		sub.b	tmpD1,tmpD0
		and.w	#$10,tmpD0
		move.b	tmpD0,Z80_BCDF(TableB)
	ELSE
		lsr.w	#1,stCCR
		moveq	#0,tmpD0
		addx.b	tmpD1,A
		putccr	stCCR
	ENDC
		skip 2
		next
		ENDM

	do_ii adc_A_1ii1

** -----

**	ADC HL,rr
**
**	HL <- HL + rr + Carry
**
**	Flags:	S Z H V N C
**		* * + * 0 *	(H set by carry from bit 11)

adc_HL_rr	MACRO
Adc_HL_\1\2	opcode_2_bytes
		move.w	Z80_\1\2(TableB),tmpD1
	IFD BCDFLAGS
		move.w	#$FFF,tmpD0
		and.w	HL,tmpD0	;keep original HL minus high nybble

		lsr.w	#1,stCCR	;C to X
		ori	#4,CCR		;set Z
		addx.w	tmpD1,HL ;Z reset if nonzero, unchanged if zero
		putccr	stCCR

		;Bits 12-15 of tmpD0 (and Carry) become set if H:
		and.w	#$FFF,tmpD1	;get other operand minus high nybble
		add.w	tmpD0,tmpD1	;sum low nybbles of operands
		move.w	#$FFF,tmpD0
		and.w	HL,tmpD0	;get result minus high nybble
		sub.w	tmpD1,tmpD0	;subtract sum of operand nybbles
	IFNE PROCESSOR<68030
		move.w	tmpD0,(Work)
		move.b	(Work),tmpD0
	ELSE
		lsr.w	#8,tmpD0
	ENDC ;IFNE PROCESSOR<68030
		and.w	#$10,tmpD0	;reset N flag, keeping only H
		move.b	tmpD0,Z80_BCDF(TableB)
	ELSE
		lsr.w	#1,stCCR
		moveq	#0,tmpD0
		addx.w	tmpD1,HL
		putccr	stCCR
	ENDC ;IFD BCDFLAGS
		skip 1
		next
		ENDM

	do_rr adc_HL_rr


Adc_HL_HL	opcode_2_bytes
	IFD BCDFLAGS
		move.w	#$FFF,tmpD1
		and.w	HL,tmpD1

		lsr.w	#1,stCCR
		moveq	#0,tmpD0
		addx.w	HL,HL
		putccr	stCCR

		add.w	tmpD1,tmpD1
		move.w	#$FFF,tmpD0
		and.w	HL,tmpD0
		sub.w	tmpD1,tmpD0
	IFNE PROCESSOR<68030
		move.w	tmpD0,(Work)
		move.b	(Work),tmpD0
	ELSE
		lsr.w	#8,tmpD0
	ENDC ;IFNE PROCESSOR<68030
		and.w	#$10,tmpD0
		move.b	tmpD0,Z80_BCDF(TableB)
	ELSE
		lsr.w	#1,stCCR
		moveq	#0,tmpD0
		addx.w	HL,HL
		putccr	stCCR
	ENDC ;IFD BCDFLAGS
		skip 1
		next


Adc_HL_SP	opcode_2_bytes
	IFD BCDFLAGS
		move.w	#$FFF,tmpD0
		and.w	HL,tmpD0

		lsr.w	#1,stCCR
		ori	#4,CCR
		addx.w	ZSP,HL
		putccr	stCCR

		move.w	#$FFF,tmpD1
		and.w	ZSP,tmpD1
		add.w	tmpD0,tmpD1
		move.w	#$FFF,tmpD0
		and.w	HL,tmpD0
		sub.w	tmpD1,tmpD0
	IFNE PROCESSOR<68030
		move.w	tmpD0,(Work)
		move.b	(Work),tmpD0
	ELSE
		lsr.w	#8,tmpD0
	ENDC ;IFNE PROCESSOR<68030
		and.w	#$10,tmpD0
		move.b	tmpD0,Z80_BCDF(TableB)
	ELSE
		lsr.w	#1,stCCR
		moveq	#0,tmpD0
		addx.w	ZSP,HL
		putccr	stCCR
	ENDC ;IFD BCDFLAGS
		skip 1
		next

** -----

**	ADD A,s
**
**	A <- A + s
**
**	s can be r, n, (HL) or (ii+d)
**
**	Flags:	S Z H V N C
**		* * * * 0 *

add_A_r 	MACRO
Add_A_\1
	IFD BCDFLAGS
		move.b	Z80_\1(TableB),tmpD1
		add.b	tmpD1,A
		putccr	stCCR

	;Bits 4-7 of tmpD0 (and Carry) become set if H:
		moveq	#$F,tmpD0
		and.w	tmpD0,tmpD1	;get low nybble of other operand
		and.w	A,tmpD0 	;get low nybble of result
		sub.b	tmpD1,tmpD0	;subtract operand from result
		and.w	#$10,tmpD0	;reset N flag, keeping only H
		move.b	tmpD0,Z80_BCDF(TableB)	;store BCD flags
	ELSE
		add.b	Z80_\1(TableB),A
		putccr	stCCR
	ENDC
		next
		ENDM

	do_r add_A_r


Add_A_H 	getH	HL,tmpD1
		add.b	tmpD1,A
		putccr	stCCR
	IFD BCDFLAGS
		moveq	#$F,tmpD0
		and.w	tmpD0,tmpD1
		and.w	A,tmpD0
		sub.b	tmpD1,tmpD0
		and.w	#$10,tmpD0
		move.b	tmpD0,Z80_BCDF(TableB)
	ENDC
		next


Add_A_L 	add.b	HL,A	;only L is added
		putccr	stCCR
	IFD BCDFLAGS
		move.l	HL,tmpD1
		moveq	#$F,tmpD0
		and.w	tmpD0,tmpD1	;extract low nybble of L
		and.w	A,tmpD0
		sub.b	tmpD1,tmpD0
		and.w	#$10,tmpD0
		move.b	tmpD0,Z80_BCDF(TableB)
	ENDC
		next


Add_A_A
	IFD BCDFLAGS
		move.l	A,tmpD1
		add.b	A,A
		putccr	stCCR
		moveq	#$F,tmpD0
		and.w	tmpD0,tmpD1
		and.w	A,tmpD0
		sub.b	tmpD1,tmpD0
		and.w	#$10,tmpD0
		move.b	tmpD0,Z80_BCDF(TableB)
	ELSE
		add.b	A,A
		putccr	stCCR
	ENDC
		next


Add_A_n 	getRPC	tmpD0
		getz	tmpD0,tmpD1
		add.b	tmpD1,A
		putccr	stCCR
	IFD BCDFLAGS
		moveq	#$F,tmpD0
		and.w	tmpD0,tmpD1
		and.w	A,tmpD0
		sub.b	tmpD1,tmpD0
		and.w	#$10,tmpD0
		move.b	tmpD0,Z80_BCDF(TableB)
	ENDC
		skip 1
		next


Add_A_1HL1	getz	HL,tmpD1
		add.b	tmpD1,A
		putccr	stCCR
	IFD BCDFLAGS
		moveq	#$F,tmpD0
		and.w	tmpD0,tmpD1
		and.w	A,tmpD0
		sub.b	tmpD1,tmpD0
		and.w	#$10,tmpD0
		move.b	tmpD0,Z80_BCDF(TableB)
	ENDC
		next


add_A_1ii1	MACRO
Add_A_1I\1_d1	opcode_2_bytes
		index	I\1,tmpD0
		getz	tmpD0,tmpD1
		add.b	tmpD1,A
		putccr	stCCR
	IFD BCDFLAGS
		moveq	#$F,tmpD0
		and.w	tmpD0,tmpD1
		and.w	A,tmpD0
		sub.b	tmpD1,tmpD0
		and.w	#$10,tmpD0
		move.b	tmpD0,Z80_BCDF(TableB)
	ENDC
		skip 2
		next
		ENDM

	do_ii add_A_1ii1

** -----

**	ADD HL,rr
**
**	HL <- HL + rr
**
**	ss can be BC, DE, HL or SP
**
**	Flags:	S Z H V N C
**		- - + - 0 *	(H set by carry from bit 11)

add_HL_rr	MACRO
Add_HL_\1\2	move.w	Z80_\1\2(TableB),tmpD1
	IFD BCDFLAGS
		move.w	#$FFF,tmpD0
		and.w	HL,tmpD0	;keep original HL minus high nybble

		and.w	#$FFFE,stCCR	;reset C
		add.w	tmpD1,HL
		bcc.s	.cc
		or.w	#1,stCCR	;set C depending on result
.cc
		;Bits 12-15 of tmpD0 (and Carry) become set if H:
		and.w	#$FFF,tmpD1	;get other operand minus high nybble
		add.w	tmpD0,tmpD1	;sum low nybbles of operands
		move.w	#$FFF,tmpD0
		and.w	HL,tmpD0	;get result minus high nybble
		sub.w	tmpD1,tmpD0	;subtract sum of operand nybbles
	IFNE PROCESSOR<68030
		move.w	tmpD0,(Work)
		move.b	(Work),tmpD0
	ELSE
		lsr.w	#8,tmpD0
	ENDC ;IFNE PROCESSOR<68030
		and.w	#$10,tmpD0	;reset N flag, keeping only H
		move.b	tmpD0,Z80_BCDF(TableB)
	ELSE
		and.w	#$FFFE,stCCR	;reset Carry
		add.w	tmpD1,HL
		bcc.s	.cc
		or.w	#1,stCCR	;set Carry depending on result
.cc
	ENDC ;IFD BCDFLAGS
		next
		ENDM

	do_rr add_HL_rr


Add_HL_HL
	IFD BCDFLAGS
		move.w	#$FFF,tmpD0	;low nybbles mask in tmpD0
		move.l	HL,tmpD1
		and.w	tmpD0,tmpD1	;keep original HL minus high nybble

		and.w	#$FFFE,stCCR
		add.w	HL,HL
		bcc.s	.cc
		or.w	#1,stCCR
.cc
		add.w	tmpD1,tmpD1
		and.w	HL,tmpD0	;get result minus high nybble
		sub.w	tmpD1,tmpD0
	IFNE PROCESSOR<68030
		move.w	tmpD0,(Work)
		move.b	(Work),tmpD0
	ELSE
		lsr.w	#8,tmpD0
	ENDC ;IFNE PROCESSOR<68030
		and.w	#$10,tmpD0
		move.b	tmpD0,Z80_BCDF(TableB)
	ELSE
		and.w	#$FFFE,stCCR
		add.w	HL,HL
		bcc.s	.cc
		or.w	#1,stCCR
.cc
	ENDC ;IFD BCDFLAGS
		next


Add_HL_SP
	IFD BCDFLAGS
		move.w	#$FFF,tmpD0
		and.w	HL,tmpD0

		and.w	#$FFFE,stCCR
		add.w	ZSP,HL
		bcc.s	.cc
		or.w	#1,stCCR
.cc
		move.w	#$FFF,tmpD1
		and.w	ZSP,tmpD1
		add.w	tmpD0,tmpD1
		move.w	#$FFF,tmpD0
		and.w	HL,tmpD0
		sub.w	tmpD1,tmpD0
	IFNE PROCESSOR<68030
		move.w	tmpD0,(Work)
		move.b	(Work),tmpD0
	ELSE
		lsr.w	#8,tmpD0
	ENDC ;IFNE PROCESSOR<68030
		and.w	#$10,tmpD0
		move.b	tmpD0,Z80_BCDF(TableB)
	ELSE
		and.w	#$FFFE,stCCR
		add.w	ZSP,HL
		bcc.s	.cc
		or.w	#1,stCCR
.cc
	ENDC ;IFD BCDFLAGS
		next

** -----

**	ADD ii,rr
**
**	ii <- ii + rr
**
**	ss can be BC, DE, HL or SP
**
**	Flags:	S Z H V N C
**		- - + - 0 *	(H set by carry from bit 11)

add_ii_rr	MACRO
Add_I\1_\2	opcode_2_bytes
		move.w	Z80_\2(TableB),tmpD1
	IFD BCDFLAGS
		move.w	Z80_I\1(TableB),tmpD2
		move.w	#$FFF,tmpD0
		and.w	tmpD2,tmpD0	;keep original ii minus high nybble

		and.w	#$FFFE,stCCR	;reset C
		add.w	tmpD1,tmpD2
		bcc.s	.cc
		or.w	#1,stCCR	;set C depending on result
.cc		move.w	tmpD2,Z80_I\1(TableB)

		;Bits 12-15 of tmpD0 (and Carry) become set if H:
		and.w	#$FFF,tmpD1	;get other operand minus high nybble
		add.w	tmpD0,tmpD1	;sum low nybbles of operands
		move.w	#$FFF,tmpD0
		and.w	tmpD2,tmpD0	;get result minus high nybble
		sub.w	tmpD1,tmpD0	;subtract sum of operand nybbles
	IFNE PROCESSOR<68030
		move.w	tmpD0,(Work)
		move.b	(Work),tmpD0
	ELSE
		lsr.w	#8,tmpD0
	ENDC ;IFNE PROCESSOR<68030
		and.w	#$10,tmpD0	;reset N flag, keeping only H
		move.b	tmpD0,Z80_BCDF(TableB)
	ELSE
		and.w	#$FFFE,stCCR	;reset C
		add.w	tmpD1,Z80_I\1(TableB)
		bcc.s	.cc
		or.w	#1,stCCR	;set C depending on result
.cc
	ENDC ;IFD BCDFLAGS
		skip 1
		next
		ENDM


add_ii_ii	MACRO
Add_I\1_I\1	opcode_2_bytes
		move.w	Z80_I\1(TableB),tmpD0
	IFD BCDFLAGS
		move.w	#$FFF,tmpD1
		and.w	tmpD0,tmpD1	;keep original ii minus high nybble

		and.w	#$FFFE,stCCR
		add.w	tmpD0,tmpD0
		bcc.s	.cc
		or.w	#1,stCCR
.cc		move.w	tmpD0,Z80_I\1(TableB)

		add.w	tmpD1,tmpD1
		and.w	#$FFF,tmpD0
		sub.w	tmpD1,tmpD0
	IFNE PROCESSOR<68030
		move.w	tmpD0,(Work)
		move.b	(Work),tmpD0
	ELSE
		lsr.w	#8,tmpD0
	ENDC ;IFNE PROCESSOR<68030
		and.w	#$10,tmpD0
		move.b	tmpD0,Z80_BCDF(TableB)
	ELSE
		and.w	#$FFFE,stCCR
		add.w	tmpD0,tmpD0
		bcc.s	.cc
		or.w	#1,stCCR
.cc		move.w	tmpD0,Z80_I\1(TableB)
	ENDC ;IFD BCDFLAGS
		skip 1
		next
		ENDM


add_ii_SP	MACRO
Add_I\1_SP	opcode_2_bytes
	IFD BCDFLAGS
		move.w	Z80_I\1(TableB),tmpD2
		move.w	#$FFF,tmpD0
		and.w	tmpD2,tmpD0	;keep original ii minus high nybble

		and.w	#$FFFE,stCCR
		add.w	ZSP,tmpD2
		bcc.s	.cc
		or.w	#1,stCCR
.cc		move.w	tmpD2,Z80_I\1(TableB)

		move.w	#$FFF,tmpD1
		and.w	ZSP,tmpD1
		add.w	tmpD0,tmpD1
		move.w	#$FFF,tmpD0
		and.w	tmpD2,tmpD0
		sub.w	tmpD1,tmpD0
	IFNE PROCESSOR<68030
		move.w	tmpD0,(Work)
		move.b	(Work),tmpD0
	ELSE
		lsr.w	#8,tmpD0
	ENDC ;IFNE PROCESSOR<68030
		and.w	#$10,tmpD0
		move.b	tmpD0,Z80_BCDF(TableB)
	ELSE
		and.w	#$FFFE,stCCR
		add.w	ZSP,Z80_I\1(TableB)
		bcc.s	.cc
		or.w	#1,stCCR
.cc
	ENDC ;IFD BCDFLAGS
		skip 1
		next
		ENDM


add_ii_ss	MACRO
		add_ii_rr \1,BC
		add_ii_rr \1,DE
		add_ii_ii \1
		add_ii_SP \1
		ENDM

	do_ii add_ii_ss

** -----

**	AND s
**
**	A <- A /\ s
**
**	The bitwise logical and of A and s is stored in A.
**
**	s can be r, n, (HL) or (ii+d)
**
**	Flags:	S Z H P N C
**		* * 1 * 0 0
**
**	Note that AND sets the H flag, while OR and XOR clear it.

and_r		MACRO
And_\1		and.b	Z80_\1(TableB),A	;V and C are cleared
		putccr	stCCR	;Sign and Zero depend on the result
		parity	A	;set V depending on parity of result
	IFD BCDFLAGS
		move.b	#$10,Z80_BCDF(TableB)	;set H and reset N
	ENDC
		next
		ENDM

	do_r and_r


And_H		getH	HL,tmpD0
		and.b	tmpD0,A
		putccr	stCCR
		parity	A
	IFD BCDFLAGS
		move.b	#$10,Z80_BCDF(TableB)
	ENDC
		next


And_L		and.b	HL,A	;only L is used
		putccr	stCCR
		parity	A
	IFD BCDFLAGS
		move.b	#$10,Z80_BCDF(TableB)
	ENDC
		next


And_A		and.b	A,A
		putccr	stCCR
		parity	A
	IFD BCDFLAGS
		move.b	#$10,Z80_BCDF(TableB)
	ENDC
		next


And_n		getRPC	tmpD0
		getz	tmpD0,tmpD1
		and.b	tmpD1,A
		putccr	stCCR
		parity	A
	IFD BCDFLAGS
		move.b	#$10,Z80_BCDF(TableB)
	ENDC
		skip 1
		next


And_1HL1	getz	HL,tmpD0
		and.b	tmpD0,A
		putccr	stCCR
		parity	A
	IFD BCDFLAGS
		move.b	#$10,Z80_BCDF(TableB)
	ENDC
		next


and_1ii1	MACRO
And_1I\1_d1	opcode_2_bytes
		index	I\1,tmpD0
		getz	tmpD0,tmpD1
		and.b	tmpD1,A
		putccr	stCCR
		parity	A
	IFD BCDFLAGS
		move.b	#$10,Z80_BCDF(TableB)
	ENDC
		skip 2
		next
		ENDM

	do_ii and_1ii1

** -----

**	BIT b,s
**
**	Z <- NOT(s[b])
**
**	s can be r, (HL) or (ii+d)
**
**	Flags:	S Z H V N C
**		+ * 1 ? 0 -
**
**	Undocumented flag effect: If b is 7 then S is set to the sign
**	(bit 7) of the tested value; otherwise S is cleared.

** Note that P/V is unaffected in this implementation.

** The following are the bit 0-6 cases:

bit_b_r 	MACRO
Bit_\1_\2	opcode_2_bytes
		and.w	#3,stCCR	;S and Z reset, V and C unaffected
		btst	#\1,Z80_\2(TableB)
		bne.s	.nz
		or.w	#4,stCCR	;set Z depending on result
.nz
	IFD BCDFLAGS
		move.b	#$10,Z80_BCDF(TableB)	;set H and reset N
	ENDC
		skip 1
		next
		ENDM


bit_b_H 	MACRO
Bit_\1_H	opcode_2_bytes
		and.w	#3,stCCR
		btst	#8+\1,HL	;H is in bits 8-15 of the register
		bne.s	.nz
		or.w	#4,stCCR
.nz
	IFD BCDFLAGS
		move.b	#$10,Z80_BCDF(TableB)
	ENDC
		skip 1
		next
		ENDM


bit_b_L 	MACRO
Bit_\1_L	opcode_2_bytes
		and.w	#3,stCCR
		btst	#\1,HL		;L is the low byte of the register
		bne.s	.nz
		or.w	#4,stCCR
.nz
	IFD BCDFLAGS
		move.b	#$10,Z80_BCDF(TableB)
	ENDC
		skip 1
		next
		ENDM


bit_b_A 	MACRO
Bit_\1_A	opcode_2_bytes
		and.w	#3,stCCR
		btst	#\1,A
		bne.s	.nz
		or.w	#4,stCCR
.nz
	IFD BCDFLAGS
		move.b	#$10,Z80_BCDF(TableB)
	ENDC
		skip 1
		next
		ENDM


bit_b_1HL1	MACRO
Bit_\1_1HL1	opcode_2_bytes
		and.w	#3,stCCR
		getz	HL,tmpD0
		btst	#\1,tmpD0
		bne.s	.nz
		or.w	#4,stCCR
.nz
	IFD BCDFLAGS
		move.b	#$10,Z80_BCDF(TableB)
	ENDC
		skip 1
		next
		ENDM


bit_b_1ii1	MACRO
Bit_\1_1I\2_d1	opcode_3_bytes
		index	I\2,tmpD0
		getz	tmpD0,tmpD1
		and.w	#3,stCCR
		btst	#\1,tmpD1
		bne.s	.nz
		or.w	#4,stCCR
.nz
	IFD BCDFLAGS
		move.b	#$10,Z80_BCDF(TableB)
	ENDC
		skip 3
		next
		ENDM


bit_b		MACRO
	bit_b_r \1,B
	bit_b_r \1,C
	bit_b_r \1,D
	bit_b_r \1,E
	bit_b_H \1
	bit_b_L \1
	bit_b_A \1
	bit_b_1HL1 \1
	bit_b_1ii1 \1,X
	bit_b_1ii1 \1,Y
		ENDM

	bit_b 0
	bit_b 1
	bit_b 2
	bit_b 3
	bit_b 4
	bit_b 5
	bit_b 6


** Here follow the bit 7 cases:

bit_7_r 	MACRO
Bit_7_\1	opcode_2_bytes
		moveq	#-$80,tmpD0	;bit 7 set
		and.b	Z80_\1(TableB),tmpD0	;extract bit 7 of source
		putccr	tmpD1		;S and Z tested, V and C cleared
		and.w	#3,stCCR	;keep original V and C
		or.w	tmpD1,stCCR	;join the flags in stCCR
	IFD BCDFLAGS
		move.b	#$10,Z80_BCDF(TableB)	;set H and reset N
	ENDC
		skip 1
		next
		ENDM

	do_r bit_7_r


Bit_7_H 	opcode_2_bytes
		move.w	#$8000,tmpD0	;extracting bit 15 of source
		and.w	HL,tmpD0	;H is in bits 8-15 of the register
		putccr	tmpD1
		and.w	#3,stCCR
		or.w	tmpD1,stCCR
	IFD BCDFLAGS
		move.b	#$10,Z80_BCDF(TableB)	;set H and reset N
	ENDC
		skip 1
		next


Bit_7_L 	opcode_2_bytes
		moveq	#-$80,tmpD0
		and.b	HL,tmpD0	;L is the low byte of the register
		putccr	tmpD1
		and.w	#3,stCCR
		or.w	tmpD1,stCCR
	IFD BCDFLAGS
		move.b	#$10,Z80_BCDF(TableB)	;set H and reset N
	ENDC
		skip 1
		next


Bit_7_A 	opcode_2_bytes
		moveq	#-$80,tmpD0
		and.b	A,tmpD0
		putccr	tmpD1
		and.w	#3,stCCR
		or.w	tmpD1,stCCR
	IFD BCDFLAGS
		move.b	#$10,Z80_BCDF(TableB)	;set H and reset N
	ENDC
		skip 1
		next


Bit_7_1HL1	opcode_2_bytes
		getz	HL,tmpD1
		moveq	#-$80,tmpD0
		and.b	tmpD1,tmpD0
		putccr	tmpD1
		and.w	#3,stCCR
		or.w	tmpD1,stCCR
	IFD BCDFLAGS
		move.b	#$10,Z80_BCDF(TableB)
	ENDC
		skip 1
		next


bit_7_1ii1	MACRO
Bit_7_1I\1_d1	opcode_3_bytes
		index	I\1,tmpD0
		getz	tmpD0,tmpD1
		moveq	#-$80,tmpD0
		and.b	tmpD1,tmpD0
		putccr	tmpD1
		and.w	#3,stCCR
		or.w	tmpD1,stCCR
	IFD BCDFLAGS
		move.b	#$10,Z80_BCDF(TableB)
	ENDC
		skip 3
		next
		ENDM

	do_ii bit_7_1ii1

** -----

**	CALL cc,pq
**
**	If cc true:	(SP-1) <- PC [H], (SP-2) <- PC [L],
**			SP <- SP - 2, PC <- pq
**
**	Flags:	not affected

call_cc_pq	MACRO
Call_\1_pq
	;We advance PPC directly, so getRPC yields the correct return
	;address (safe, since the arithmetic is modulo $10000), and if
	;the test is false, we can thread on directly.

		skip 2
		move	stCCR,CCR
		b\2.s	.true

		next

.true		getRPC	tmpD1	;real-PC return address to tmpD1
		decw	ZSP
	IFNE PROCESSOR<68030
		move.w	tmpD1,(Work)
		putz	(Work),ZSP	;push PC-high (putz uses tmpD0)
		decw	ZSP
		putz	tmpD1,ZSP,2	;push PC-low (2nd use of putz)

		decw	tmpD1		;back down real-PC to get pq
		getz	tmpD1,(Work)	;get pq-high
		move.w	(Work),tmpD0
		decw	tmpD1
		getz	tmpD1,tmpD0	;get pq-low (pq now in tmpD0)
	ELSE
		move.w	tmpD1,tmpD2
		lsr.w	#8,tmpD2
		putz	tmpD2,ZSP	;push PC-high (putz uses tmpD0)
		decw	ZSP
		putz	tmpD1,ZSP,2	;push PC-low (2nd use of putz)

		decw	tmpD1		;back down real-PC to get pq
		getz	tmpD1,tmpD0	;get pq-high
		lsl.w	#8,tmpD0
		decw	tmpD1
		getz	tmpD1,tmpD0	;get pq-low, giving pq in tmpD0
	ENDC ;IFNE PROCESSOR<68030
		makePPC tmpD0		;PC <- pq
		testreq 	;handle exception or thread to next
		ENDM

	call_cc_pq NZ,ne
	call_cc_pq  Z,eq
	call_cc_pq NC,cc
	call_cc_pq  C,cs
	call_cc_pq PO,vc
	call_cc_pq PE,vs
	call_cc_pq  P,pl
	call_cc_pq  M,mi

** -----

**	CALL pq
**
**	(SP-1) <- PC [H], (SP-2) <- PC [L], SP <- SP - 2, PC <- pq
**
**	Flags:	not affected

Call_pq 	getRPC	tmpD1		;get real-PC in tmpD1
		addq.w	#2,tmpD1	;adjust it to the return address

		decw	ZSP
	IFNE PROCESSOR<68030
		move.w	tmpD1,(Work)
		putz	(Work),ZSP	;push PC-high (putz uses tmpD0)
		decw	ZSP
		putz	tmpD1,ZSP,2	;push PC-low (2nd use of putz)

		decw	tmpD1		;back down real-PC to get pq
		getz	tmpD1,(Work)	;get pq-high
		move.w	(Work),tmpD0
		decw	tmpD1
		getz	tmpD1,tmpD0	;get pq-low (pq now in tmpD0)
	ELSE
		move.w	tmpD1,tmpD2
		lsr.w	#8,tmpD2
		putz	tmpD2,ZSP	;push PC-high (putz uses tmpD0)
		decw	ZSP
		putz	tmpD1,ZSP,2	;push PC-low (2nd use of putz)

		decw	tmpD1		;back down real-PC to get pq
		getz	tmpD1,tmpD0	;get pq-high
		lsl.w	#8,tmpD0
		decw	tmpD1
		getz	tmpD1,tmpD0	;get pq-low, giving pq in tmpD0
	ENDC ;IFNE PROCESSOR<68030
		makePPC tmpD0		;PC <- pq
		testreq 	;handle exception or thread to next

** -----

**	CCF
**
**	C <- NOT(C)
**
**	Flags:	S Z H V N C
**		- - ? - 0 *

** Note that H is unaffected in this implementation.

Ccf		eori.w	#1,stCCR		;complement C
	IFD BCDFLAGS
		bclr	#1,Z80_BCDF(TableB)	;clear N
	ENDC
		next

** -----

**	CP s
**
**	cc <- A - s
**
**	s can be r, n, (HL) or (ii+d)
**
**	Flags:	S Z H V N C
**		* * * * 1 *

cp_r		MACRO
Cp_\1
	IFD BCDFLAGS
		move.b	Z80_\1(TableB),tmpD1
		cmp.b	tmpD1,A
	ELSE
		cmp.b	Z80_\1(TableB),A
	ENDC
		putccr	stCCR
	IFD BCDFLAGS
	;Bits 4-7 of tmpD0 (and Carry) become set if H:
		moveq	#$F,tmpD0
		and.w	tmpD0,tmpD1	;low nybble of source in tmpD1
		and.w	A,tmpD0 	;low nybble of A in tmpD0
		sub.b	tmpD1,tmpD0
		and.w	#$10,tmpD0	;clear all but H
		addq.b	#2,tmpD0	;set N flag
		move.b	tmpD0,Z80_BCDF(TableB)	;store BCD flags
	ENDC
		next
		ENDM

	do_r cp_r


Cp_H		getH	HL,tmpD1
		cmp.b	tmpD1,A
		putccr	stCCR
	IFD BCDFLAGS
		moveq	#$F,tmpD0
		and.w	tmpD0,tmpD1
		and.w	A,tmpD0
		sub.b	tmpD1,tmpD0
		and.w	#$10,tmpD0
		addq.b	#2,tmpD0
		move.b	tmpD0,Z80_BCDF(TableB)
	ENDC
		next


Cp_L		cmp.b	HL,A	;only L is used
		putccr	stCCR
	IFD BCDFLAGS
		move.l	HL,tmpD1
		moveq	#$F,tmpD0
		and.w	tmpD0,tmpD1
		and.w	A,tmpD0
		sub.b	tmpD1,tmpD0
		and.w	#$10,tmpD0
		addq.b	#2,tmpD0
		move.b	tmpD0,Z80_BCDF(TableB)
	ENDC
		next


Cp_A		cmp.b	A,A
		putccr	stCCR
	IFD BCDFLAGS
		;H always becomes reset
		move.b	#2,Z80_BCDF(TableB)
	ENDC
		next


Cp_n		getRPC	tmpD0
		getz	tmpD0,tmpD1
		cmp.b	tmpD1,A
		putccr	stCCR
	IFD BCDFLAGS
		moveq	#$F,tmpD0
		and.w	tmpD0,tmpD1
		and.w	A,tmpD0
		sub.b	tmpD1,tmpD0
		and.w	#$10,tmpD0
		addq.b	#2,tmpD0
		move.b	tmpD0,Z80_BCDF(TableB)
	ENDC
		skip 1
		next


Cp_1HL1		getz	HL,tmpD1
		cmp.b	tmpD1,A
		putccr	stCCR
	IFD BCDFLAGS
		moveq	#$F,tmpD0
		and.w	tmpD0,tmpD1
		and.w	A,tmpD0
		sub.b	tmpD1,tmpD0
		and.w	#$10,tmpD0
		addq.b	#2,tmpD0
		move.b	tmpD0,Z80_BCDF(TableB)
	ENDC
		next


cp_1ii1 	MACRO
Cp_1I\1_d1	opcode_2_bytes
		index	I\1,tmpD0
		getz	tmpD0,tmpD1
		cmp.b	tmpD1,A
		putccr	stCCR
	IFD BCDFLAGS
		moveq	#$F,tmpD0
		and.w	tmpD0,tmpD1
		and.w	A,tmpD0
		sub.b	tmpD1,tmpD0
		and.w	#$10,tmpD0
		addq.b	#2,tmpD0
		move.b	tmpD0,Z80_BCDF(TableB)
	ENDC
		skip 2
		next
		ENDM

	do_ii cp_1ii1

** -----

**	CPD
**
**	cc <- A - (HL), HL <- HL - 1, BC <- BC - 1
**
**	Flags:	S Z H V N C
**		* * ? + 1 -
**
**	P/V is reset if BC is 0 after the instruction, otherwise set.

** Note that H is unaffected in this implementation.

Cpd		opcode_2_bytes
		and.w	#1,stCCR	;keep only C
		addq.w	#2,stCCR	;set V

		getz	HL,tmpD1
		cmp.b	tmpD1,A
		putccr	tmpD0

		eor.w	tmpD0,stCCR	;insert new S and Z
		and.w	#3,stCCR
		eor.w	tmpD0,stCCR
	IFD BCDFLAGS
	** Section commented out, assuming H should be neglected:
	**
	**;Bits 4-7 of tmpD0 (and Carry) become set if H:
	**	moveq	#$F,tmpD0
	**	and.w	tmpD0,tmpD1
	**	and.w	A,tmpD0
	**	sub.b	tmpD1,tmpD0
	**	and.w	#$10,tmpD0	;clear all but H
	**	addq.b	#2,tmpD0	;set the N flag
	**	move.b	tmpD0,Z80_BCDF(TableB)	;store BCD flags
	** This is used instead:
		bset	#1,Z80_BCDF(TableB)	;set the N flag
	ENDC
		decw	HL		;HL <- HL - 1
		decw	Z80_BC(TableB)	;BC <- BC - 1
		bne.s	.nz
		subq	#2,stCCR	;reset V if BC becomes zero
.nz		skip 1
		next

** -----

**	CPDR
**
**	cc <- A - (HL), HL <- HL - 1, BC <- BC - 1,
**	repeated until BC = 0 or A = (HL)
**
**	Flags:	S Z H V N C
**		* * ? + 1 -
**
**	P/V is reset if BC is 0 after the instruction, otherwise set.

** Note that H is unaffected in this implementation.

Cpdr		opcode_2_bytes
		and.w	#1,stCCR	;keep only C
		addq.w	#2,stCCR	;set V

		getz	HL,tmpD1
		cmp.b	tmpD1,A
		putccr	tmpD0

		eor.w	tmpD0,stCCR	;insert new S and Z
		and.w	#3,stCCR
		eor.w	tmpD0,stCCR
	IFD BCDFLAGS
	** Section commented out, assuming H should be neglected:
	**
	**;Bits 4-7 of tmpD0 (and Carry) become set if H:
	**	moveq	#$F,tmpD0
	**	and.w	tmpD0,tmpD1
	**	and.w	A,tmpD0
	**	sub.b	tmpD1,tmpD0
	**	and.w	#$10,tmpD0	;clear all but H
	**	addq.b	#2,tmpD0	;set the N flag
	**	move.b	tmpD0,Z80_BCDF(TableB)	;store BCD flags
	** This is used instead:
		bset	#1,Z80_BCDF(TableB)	;set the N flag
	ENDC
		decw	HL		;HL <- HL - 1
		decw	Z80_BC(TableB)	;BC <- BC - 1
		bne.s	.nz
		subq	#2,stCCR	;reset V if BC becomes zero

.nz		moveq	#6,tmpD0
		and.w	stCCR,tmpD0	;extract Z and V
		subq.w	#2,tmpD0
		beq.s	.loop		;loop if Z reset and V set

		skip 1
		next

.loop		getRPC	tmpD0
		decw	tmpD0	;get real-PC address of first opcode byte
		makePPC tmpD0	;recalculate PPC
		testreq 	;handle exception or thread-to-loop

** -----

**	CPI
**
**	cc <- A - (HL), HL <- HL + 1, BC <- BC - 1
**
**	Flags:	S Z H V N C
**		* * ? + 1 -
**
**	P/V is reset if BC is 0 after the instruction, otherwise set.

** Note that H is unaffected in this implementation.

Cpi		opcode_2_bytes
		and.w	#1,stCCR	;keep only C
		addq.w	#2,stCCR	;set V

		getz	HL,tmpD1
		cmp.b	tmpD1,A
		putccr	tmpD0

		eor.w	tmpD0,stCCR	;insert new S and Z
		and.w	#3,stCCR
		eor.w	tmpD0,stCCR
	IFD BCDFLAGS
	** Section commented out, assuming H should be neglected:
	**
	**;Bits 4-7 of tmpD0 (and Carry) become set if H:
	**	moveq	#$F,tmpD0
	**	and.w	tmpD0,tmpD1
	**	and.w	A,tmpD0
	**	sub.b	tmpD1,tmpD0
	**	and.w	#$10,tmpD0	;clear all but H
	**	addq.b	#2,tmpD0	;set the N flag
	**	move.b	tmpD0,Z80_BCDF(TableB)	;store BCD flags
	** This is used instead:
		bset	#1,Z80_BCDF(TableB)	;set the N flag
	ENDC
		incw	HL		;HL <- HL + 1
		decw	Z80_BC(TableB)	;BC <- BC - 1
		bne.s	.nz
		subq	#2,stCCR	;reset V if BC becomes zero
.nz		skip 1
		next

** -----

**	CPIR
**
**	cc <- A - (HL), HL <- HL + 1, BC <- BC - 1,
**	repeated until BC = 0 or A = (HL)
**
**	Flags:	S Z H V N C
**		* * ? + 1 -
**
**	P/V is reset if BC is 0 after the instruction, otherwise set.

** Note that H is unaffected in this implementation.

Cpir		opcode_2_bytes
		and.w	#1,stCCR	;keep only C
		addq.w	#2,stCCR	;set V

		getz	HL,tmpD1
		cmp.b	tmpD1,A
		putccr	tmpD0

		eor.w	tmpD0,stCCR	;insert new S and Z
		and.w	#3,stCCR
		eor.w	tmpD0,stCCR
	IFD BCDFLAGS
	** Section commented out, assuming H should be neglected:
	**
	**;Bits 4-7 of tmpD0 (and Carry) become set if H:
	**	moveq	#$F,tmpD0
	**	and.w	tmpD0,tmpD1
	**	and.w	A,tmpD0
	**	sub.b	tmpD1,tmpD0
	**	and.w	#$10,tmpD0	;clear all but H
	**	addq.b	#2,tmpD0	;set the N flag
	**	move.b	tmpD0,Z80_BCDF(TableB)	;store BCD flags
	** This is used instead:
		bset	#1,Z80_BCDF(TableB)	;set the N flag
	ENDC
		incw	HL		;HL <- HL + 1
		decw	Z80_BC(TableB)	;BC <- BC - 1
		bne.s	.nz
		subq	#2,stCCR	;reset V if BC becomes zero

.nz		moveq	#6,tmpD0
		and.w	stCCR,tmpD0	;extract Z and V
		subq.w	#2,tmpD0
		beq.s	.loop		;loop if Z reset and V set

		skip 1
		next

.loop		getRPC	tmpD0
		decw	tmpD0	;get real-PC address of first opcode byte
		makePPC tmpD0	;recalculate PPC
		testreq 	;handle exception or thread-to-loop

** -----

**	CPL
**
**	A <- NOT(A)
**
**	Flags:	S Z H V N C
**		- - 1 - 1 -

Cpl		not.b	A
	IFD BCDFLAGS
		move.b	#$12,Z80_BCDF(TableB)	;set H and N
	ENDC
		next

** -----

**	DAA
**
**	A <- decimal_adjust(A)
**
**	Flags:	S Z H P N C
**		* * * * - *

**	Note that the routine is not conditionally compiled.
**	Even if BCD flags are not emulated in the other instructions,
**	Daa still performs correctly according to the current H and N
**	flags (which only Pop AF and Daa will be able to affect).

Daa		move.b	Z80_BCDF(TableB),tmpD1	;BCD flags in tmpD1
		moveq	#2,tmpD0
		and.b	tmpD1,tmpD0	;test N
		bne.s	.minus

	;N reset - plus case:

		moveq	#$10,tmpD0
		and.b	tmpD1,tmpD0	;test H
		bne.s	.pl_H_set	;if H is set, always add $06

		;If H is reset, add $06 iff the low nybble of A is > 9
		moveq	#0,tmpD1	;initially assume <= 9 case
		move.l	A,tmpD0
		and.b	#$F,tmpD0	;low nybble extracted
		cmpi.b	#$A,tmpD0	;and compared
		bcs.s	.pl_test_C	;skip if assumption correct
.pl_H_set
		moveq	#$06,tmpD1
.pl_test_C
		moveq	#1,tmpD0
		and.w	stCCR,tmpD0	;test C
		bne.s	.pl_C_set	;if C is set, always add $60

		;If C is reset, add $60 iff the high nybble of A
		;after adding the low-nybble adjustment is > 9
		move.l	A,tmpD0
		add.b	tmpD1,tmpD0	;low-nybble adjustment added
		and.b	#$F0,tmpD0	;high nybble extracted
		cmpi.b	#$A0,tmpD0	;and compared
		bcs.s	.pl_add 	;skip if still <= 9
.pl_C_set
		add.b	#$60,tmpD1
.pl_add
		add.b	tmpD1,A 	;add BCD adjustment

		;Now turn the nybble adjustments into 8's or 2's:
		add.b	#$22,tmpD1

		;Rotate so that bit 4 (F position of H) is set iff the
		;low nybble was adjusted, and bit 0 (F position of C)
		;is set iff the high nybble was adjusted:
		rol.b	#1,tmpD1

		;tmpD1 holds resulting H and C flags.
		bra.s	.finish


	;N set - minus case:
.minus
		and.b	#$10,tmpD1	;extract H from tmpD1
		beq.s	.mi_H_reset	;if H is reset, tmpD1 is now $00
		moveq	#$0A,tmpD1	;otherwise set tmpD1 to $0A
.mi_H_reset
		moveq	#1,tmpD0
		and.w	stCCR,tmpD0	;test C
		beq.s	.mi_C_reset
		add.b	#$A0,tmpD1	;if C is set, add $A0
.mi_C_reset
		add.b	tmpD1,A 	;add BCD adjustment

		;Turn adjustments into C and H flags (see plus case):
		rol.b	#1,tmpD1

		moveq	#$10,tmpD0
		and.b	tmpD1,tmpD0	;$10 if H, 0 otherwise
		sub.b	tmpD0,A 	;compensate for low nybble adjust

		;fall through


	;Common exit code for both cases (C and H flags in tmpD1):
.finish
		moveq	#$10,tmpD0
		and.b	tmpD1,tmpD0		;extract H (N is cleared)
		btst	#1,Z80_BCDF(TableB)	;test old N
		beq.s	.no_N
		addq.b	#2,tmpD0	;set N if it was set before
.no_N		move.b	tmpD0,Z80_BCDF(TableB)	;store BCD flags

		tst.b	A		;test Sign and Zero of resulting A
		putccr	stCCR		;C and V of CCR are cleared
		parity	A		;set V according to parity
		and.w	#1,tmpD1	;extract C from tmpD1

		;The C flags are in bit 0 of both Z80 F and 680x0 CCR,
		;so we can simply OR the Z80 C onto the CCR:
		or.w	tmpD1,stCCR

		next	;We're done!

** -----

**	DEC m
**
**	m <- m - 1
**
**	m can be r, (HL) or (ii+d)
**
**	Flags:	S Z H V N C
**		* * * * 1 -

dec_r		MACRO
Dec_\1
	IFD BCDFLAGS
		move.b	Z80_\1(TableB),tmpD1
		decb	tmpD1
		putccr	tmpD0
		move.b	tmpD1,Z80_\1(TableB)

		;Bit 4 of tmpD1 becomes set if H:
		and.w	#$F,tmpD1	;get low nybble of result
		incb	tmpD1		;add back the 1
		or.w	#2,tmpD1	;set the N flag
		move.b	tmpD1,Z80_BCDF(TableB)	;store BCD flags
	ELSE
		decb	Z80_\1(TableB)
		putccr	tmpD0
	ENDC
		eor.w	tmpD0,stCCR
		and.w	#1,stCCR	;keep old C
		eor.w	tmpD0,stCCR
		next
		ENDM

	do_r dec_r


Dec_H
	IFNE PROCESSOR<68030
		move.w	HL,(Work)
	IFD BCDFLAGS
		move.b	(Work),tmpD1	;get H
		decb	tmpD1
		putccr	tmpD0
		move.b	tmpD1,(Work)	;restore decremented H
	ELSE
		decb	(Work)	;decrements H
		putccr	tmpD0
	ENDC ;IFD BCDFLAGS
		move.w	(Work),HL
	ELSE
		rol.w	#8,HL
		decb	HL	;decrements H
		putccr	tmpD0
	IFD BCDFLAGS
		move.b	HL,tmpD1	;get a copy of result
	ENDC ;IFD BCDFLAGS
		rol.w	#8,HL	;restore HL
	ENDC ;IFNE PROCESSOR<68030
		;Now tmpD0 holds the flags, and if BCD flags are
		;being emulated, tmpD1 holds the resulting H.
	IFD BCDFLAGS
		and.w	#$F,tmpD1
		incb	tmpD1
		or.w	#2,tmpD1
		move.b	tmpD1,Z80_BCDF(TableB)
	ENDC ;IFD BCDFLAGS
		eor.w	tmpD0,stCCR
		and.w	#1,stCCR
		eor.w	tmpD0,stCCR
		next


Dec_L		decb	HL		;only L is affected
		putccr	tmpD0
	IFD BCDFLAGS
		moveq	#$F,tmpD1
		and.w	HL,tmpD1
		incb	tmpD1
		or.w	#2,tmpD1
		move.b	tmpD1,Z80_BCDF(TableB)
	ENDC
		eor.w	tmpD0,stCCR
		and.w	#1,stCCR
		eor.w	tmpD0,stCCR
		next


Dec_A		decb	A
		putccr	tmpD0
	IFD BCDFLAGS
		moveq	#$F,tmpD1
		and.w	A,tmpD1
		incb	tmpD1
		or.w	#2,tmpD1
		move.b	tmpD1,Z80_BCDF(TableB)
	ENDC
		eor.w	tmpD0,stCCR
		and.w	#1,stCCR
		eor.w	tmpD0,stCCR
		next


Dec_1HL1	getz	HL,tmpD1
		decb	tmpD1
		putccr	tmpD0
		eor.w	tmpD0,stCCR
		and.w	#1,stCCR
		eor.w	tmpD0,stCCR
	IFD BCDFLAGS
		moveq	#$F,tmpD0
		and.w	tmpD1,tmpD0
		incb	tmpD0
		or.w	#2,tmpD0
		move.b	tmpD0,Z80_BCDF(TableB)
	ENDC
		putz	tmpD1,HL	;write result (putz uses tmpD0)
		next


dec_1ii1	MACRO
Dec_1I\1_d1	opcode_2_bytes
		index	I\1,tmpD1	;indexed address in tmpD1
		getz	tmpD1,tmpD2
		decb	tmpD2
		putccr	tmpD0
		eor.w	tmpD0,stCCR
		and.w	#1,stCCR
		eor.w	tmpD0,stCCR
	IFD BCDFLAGS
		moveq	#$F,tmpD0
		and.w	tmpD2,tmpD0
		incb	tmpD0
		or.w	#2,tmpD0
		move.b	tmpD0,Z80_BCDF(TableB)
	ENDC
		putz	tmpD2,tmpD1	;write result (putz uses tmpD0)
		skip 2
		next
		ENDM

	do_ii dec_1ii1

** -----

**	DEC rr
**
**	rr <- rr - 1
**
**	Flags:	not affected

dec_rr		MACRO
Dec_\1\2	decw	Z80_\1\2(TableB)
		next
		ENDM

	do_rr dec_rr


Dec_HL		decw	HL
		next


Dec_SP		decw	ZSP
		next

** -----

**	DEC ii
**
**	ii <- ii - 1
**
**	Flags:	not affected

dec_ii		MACRO
Dec_I\1 	opcode_2_bytes
		decw	Z80_I\1(TableB)
		skip 1
		next
		ENDM

	do_ii dec_ii

** -----

**	DI
**
**	IFF1 <- 0, IFF2 <- 0
**
**	Flags:	not affected

Di		clr.b	Z80_IFF(TableB) ;clear both flags (bits 6-7)

		next

** -----

**	DJNZ e
**
**	B <- B - 1
**
**	If B <> 0 after the decrement, e is added (sign extended) to the
**	PC (which is pointing to the address following the instruction).
**
**	Flags:	not affected

Djnz_e		decb	Z80_B(TableB)
		bne.s	.branch

		skip 1
		next

.branch 	getRPC	tmpD0
		getz	tmpD0,tmpD1	;get branch offset
		incw	tmpD0	;real-PC address of next instruction
		ext.w	tmpD1
		add.w	tmpD1,tmpD0
		makePPC tmpD0
		testreq

** -----

**	EI
**
**	IFF1 <- 1, IFF2 <- 1
**
**	Flags:	not affected

Ei		move.b	#$C0,Z80_IFF(TableB)	;set both flags (bits 6-7)
		next

** -----

**	EX AF,AF'
**
**	A <-> A', F <-> F'
**
**	Flags:	not affected

Ex_AF_AF	move.l	A,tmpD0
		move.b	Z80_alt_A(TableB),A		;A <-> A'
		move.b	tmpD0,Z80_alt_A(TableB)

		move.l	stCCR,tmpD0
		move.w	Z80_alt_CCR(TableB),stCCR	;swap CCR flags
		move.w	tmpD0,Z80_alt_CCR(TableB)

		move.b	Z80_F(TableB),tmpD0		;swap unused bits
		move.b	Z80_alt_F(TableB),tmpD1
		move.b	tmpD1,Z80_F(TableB)
		move.b	tmpD0,Z80_alt_F(TableB)

		move.b	Z80_BCDF(TableB),tmpD0		;swap BCD flags
		move.b	Z80_alt_BCDF(TableB),tmpD1
		move.b	tmpD1,Z80_BCDF(TableB)
		move.b	tmpD0,Z80_alt_BCDF(TableB)

		next

** -----

**	EX DE,HL
**
**	D <-> H, E <-> L
**
**	Flags:	not affected

Ex_DE_HL	move.l	HL,tmpD0
		move.w	Z80_DE(TableB),HL
		move.w	tmpD0,Z80_DE(TableB)
		next

** -----

**	EX (SP),HL
**
**	(SP) <-> L, (SP+1) <-> H
**
**	Flags:	not affected

Ex_1SP1_HL	getz	ZSP,tmpD1	;get (SP)
		putz	HL,ZSP		;write L (putz uses tmpD0)
		incw	ZSP
	IFNE PROCESSOR<68030
		getz	ZSP,(Work)	;get (SP+1)
		move.w	(Work),tmpD0
		move.b	tmpD1,tmpD0	;join (SP+1) and (SP) in tmpD0
		move.w	HL,(Work)	;copy old HL
		move.w	tmpD0,HL	;set new HL
		putz	(Work),ZSP,2	;write old H (2nd use of putz)
	ELSE
		getz	ZSP,tmpD0	;get (SP+1)
		lsl.w	#8,tmpD0
		move.b	tmpD1,tmpD0	;join (SP+1) and (SP) in tmpD0
		move.l	HL,tmpD1	;copy old HL
		move.w	tmpD0,HL	;set new HL
		lsr.w	#8,tmpD1
		putz	tmpD1,ZSP,2	;write old H (2nd use of putz)
	ENDC ;IFNE PROCESSOR<68030
		decw	ZSP
		next

** -----

**	EX (SP),ii
**
**	(SP) <-> ii [L], (SP+1) <-> ii [H]
**
**	Flags:	not affected

ex_1SP1_ii	MACRO
Ex_1SP1_I\1	opcode_2_bytes
		getz	ZSP,tmpD1		;get (SP)
		putz	Z80_\1L(TableB),ZSP	;write ii [L] (uses tmpD0)
		move.b	tmpD1,Z80_\1L(TableB)	;set new ii [L]
		incw	ZSP
		getz	ZSP,tmpD1		;get (SP+1)
		putz	Z80_\1H(TableB),ZSP,2	;(2nd use) write ii [H]
		move.b	tmpD1,Z80_\1H(TableB)	;set new ii [H]
		decw	ZSP
		skip 1
		next
		ENDM

	do_ii ex_1SP1_ii

** -----

**	EXX
**
**	B <-> B', C <-> C', D <-> D', E <-> E', H <-> H', L <-> L'
**
**	Flags:	not affected

Exx		move.w	HL,tmpD0
		move.w	Z80_alt_HL(TableB),HL		;HL <-> H'L'
		move.w	tmpD0,Z80_alt_HL(TableB)

		move.w	Z80_DE(TableB),tmpD0		;DE <-> D'E'
		move.w	Z80_alt_DE(TableB),tmpD1
		move.w	tmpD1,Z80_DE(TableB)
		move.w	tmpD0,Z80_alt_DE(TableB)

		move.w	Z80_BC(TableB),tmpD0		;BC <-> B'C'
		move.w	Z80_alt_BC(TableB),tmpD1
		move.w	tmpD1,Z80_BC(TableB)
		move.w	tmpD0,Z80_alt_BC(TableB)

		next

** -----

**	HALT
**
**	The CPU is stopped (executing NOP's) until an interrupt or reset
**	signal is received (and accepted).
**
**	Flags:	not affected

**	Note that Halt is handled by busy-waiting for a request. This is
**	no big deal, since the emulation in general hogs equally much of
**	the CPU anyway.
**	  If someone wants to modify this to make the emulator go to sleep
**	upon a Halt, they will also have to modify the request sending
**	routines to wake the emulator up when a request arrives (and put
**	it back to sleep again if the request could not be served).

Halt		nop	;delay and synchronize between reads
		move.w	Z80_ReqV(TableB),tmpD0
		beq.s	Halt
		jmp	(InstrB,tmpD0.w)

** -----

**	IM 0
**
**	Sets interrupt mode 0 (8080 Interrupt Acknowledge mode).
**
**	Flags:	not affected

Im_0		opcode_2_bytes
		move.b	#%00,Z80_IMF(TableB)	;IMF = 00 -> mode 0
		skip 1
		next

** -----

**	IM 1
**
**	Sets interrupt mode 1 (RST $0038 mode).
**
**	Flags:	not affected

Im_1		opcode_2_bytes
		move.b	#%10,Z80_IMF(TableB)	;IMF = 10 -> mode 1
		skip 1
		next

** -----

**	IM 2
**
**	Sets interrupt mode 2 (vectorised interrupt mode).
**
**	Flags:	not affected

Im_2		opcode_2_bytes
		move.b	#%11,Z80_IMF(TableB)	;IMF = 11 -> mode 2
		skip 1
		next

** -----

**	IN r,(C)
**
**	r <- PORT(C)
**
**	Bits 0-7 of the address bus are given by the C register, and
**	bits 8-15 by the B register.
**
**	Flags:	S Z H P N C
**		* * 0 * 0 -
**
**	Note: 'In x,(C)' is a (mostly) undocumented version of this
**	instruction. It reads from the port but does not store the
**	value. The flags are affected by the read value as usual, and
**	the instruction is sometimes referred to as 'In F,(C)'. The name
**	'In (HL),(C)' would be symmetric with the bit pattern, but is
**	not correct.

**	IN r,(C) is in 'impldept.a'.

** -----

**	IN A,(n)
**
**	A <- PORT(n)
**
**	Bits 0-7 of the address bus are given by the immediate 'n' byte,
**	and bits 8-15 by the value of the A register before the operation.
**
**	Flags:	not affected

**	IN A,(n) is in 'impldept.a'.

** -----

**	INC m
**
**	m <- m + 1
**
**	m can be r, (HL) or (ii+d)
**
**	Flags:	S Z H V N C
**		* * * * 0 -

inc_r		MACRO
Inc_\1
	IFD BCDFLAGS
		move.b	Z80_\1(TableB),tmpD1
		incb	tmpD1
		putccr	tmpD0
		move.b	tmpD1,Z80_\1(TableB)

		;Bit 4 of tmpD1 becomes set if H:
		and.w	#$F,tmpD1	;get low nybble of result
		decb	tmpD1		;subtract away the 1
		and.w	#$10,tmpD1	;clear N flag, keeping only H
		move.b	tmpD1,Z80_BCDF(TableB)	;store BCD flags
	ELSE
		incb	Z80_\1(TableB)
		putccr	tmpD0
	ENDC
		eor.w	tmpD0,stCCR
		and.w	#1,stCCR	;keep old C
		eor.w	tmpD0,stCCR
		next
		ENDM

	do_r inc_r


Inc_H
	IFNE PROCESSOR<68030
		move.w	HL,(Work)
	IFD BCDFLAGS
		move.b	(Work),tmpD1	;get H
		incb	tmpD1
		putccr	tmpD0
		move.b	tmpD1,(Work)	;restore incremented H
	ELSE
		incb	(Work)	;increments H
		putccr	tmpD0
	ENDC ;IFD BCDFLAGS
		move.w	(Work),HL
	ELSE
		rol.w	#8,HL
		incb	HL	;increments H
		putccr	tmpD0
	IFD BCDFLAGS
		move.b	HL,tmpD1	;get a copy of result
	ENDC ;IFD BCDFLAGS
		rol.w	#8,HL	;restore HL
	ENDC ;IFNE PROCESSOR<68030
		;Now tmpD0 holds the flags, and if BCD flags are
		;being emulated, tmpD1 holds the resulting H.
	IFD BCDFLAGS
		and.w	#$F,tmpD1
		decb	tmpD1
		and.w	#$10,tmpD1
		move.b	tmpD1,Z80_BCDF(TableB)
	ENDC ;IFD BCDFLAGS
		eor.w	tmpD0,stCCR
		and.w	#1,stCCR
		eor.w	tmpD0,stCCR
		next


Inc_L		incb	HL		;only L is affected
		putccr	tmpD0
	IFD BCDFLAGS
		moveq	#$F,tmpD1
		and.w	HL,tmpD1
		decb	tmpD1
		and.w	#$10,tmpD1
		move.b	tmpD1,Z80_BCDF(TableB)
	ENDC
		eor.w	tmpD0,stCCR
		and.w	#1,stCCR
		eor.w	tmpD0,stCCR
		next


Inc_A		incb	A
		putccr	tmpD0
	IFD BCDFLAGS
		moveq	#$F,tmpD1
		and.w	A,tmpD1
		decb	tmpD1
		and.w	#$10,tmpD1
		move.b	tmpD1,Z80_BCDF(TableB)
	ENDC
		eor.w	tmpD0,stCCR
		and.w	#1,stCCR
		eor.w	tmpD0,stCCR
		next


Inc_1HL1	getz	HL,tmpD1
		incb	tmpD1
		putccr	tmpD0
		eor.w	tmpD0,stCCR
		and.w	#1,stCCR
		eor.w	tmpD0,stCCR
	IFD BCDFLAGS
		moveq	#$F,tmpD0
		and.w	tmpD1,tmpD0
		decb	tmpD0
		and.w	#$10,tmpD0
		move.b	tmpD0,Z80_BCDF(TableB)
	ENDC
		putz	tmpD1,HL	;write result (putz uses tmpD0)
		next


inc_1ii1	MACRO
Inc_1I\1_d1	opcode_2_bytes
		index	I\1,tmpD1	;indexed address in tmpD1
		getz	tmpD1,tmpD2
		incb	tmpD2
		putccr	tmpD0
		eor.w	tmpD0,stCCR
		and.w	#1,stCCR
		eor.w	tmpD0,stCCR
	IFD BCDFLAGS
		moveq	#$F,tmpD0
		and.w	tmpD2,tmpD0
		decb	tmpD0
		and.w	#$10,tmpD0
		move.b	tmpD0,Z80_BCDF(TableB)
	ENDC
		putz	tmpD2,tmpD1	;write result (putz uses tmpD0)
		skip 2
		next
		ENDM

	do_ii inc_1ii1

** -----

**	INC rr
**
**	rr <- rr + 1
**
**	Flags:	not affected

inc_rr		MACRO
Inc_\1\2	incw	Z80_\1\2(TableB)
		next
		ENDM

	do_rr inc_rr


Inc_HL		incw	HL
		next


Inc_SP		incw	ZSP
		next

** -----

**	INC ii
**
**	ii <- ii + 1
**
**	Flags:	not affected

inc_ii		MACRO
Inc_I\1 	opcode_2_bytes
		incw	Z80_I\1(TableB)
		skip 1
		next
		ENDM

	do_ii inc_ii

** -----

**	IND
**
**	B <- B - 1, (HL) <- PORT(C), HL <- HL - 1
**
**	Bits 0-7 of the address bus are given by the C register, and
**	bits 8-15 by the value of the B register after the decrement.
**
**	Flags:	S Z H V N C
**		? * ? ? 1 -
**
**	Z is set if B is 0 after the instruction, otherwise reset.

**	IND is in 'impldept.a'.

** -----

**	INDR
**
**	B <- B - 1, (HL) <- PORT(C), HL <- HL - 1, repeated until B = 0
**
**	Bits 0-7 of the address bus are given by the C register, and
**	bits 8-15 by the value of the B register after the decrement.
**
**	Flags:	S Z H V N C
**		? 1 ? ? 1 -

**	INDR is in 'impldept.a'.

** -----

**	INI
**
**	B <- B - 1, (HL) <- PORT(C), HL <- HL + 1
**
**	Bits 0-7 of the address bus are given by the C register, and
**	bits 8-15 by the value of the B register after the decrement.
**
**	Flags:	S Z H V N C
**		? * ? ? 1 -
**
**	Z is set if B is 0 after the instruction, otherwise reset.

**	INI is in 'impldept.a'.

** -----

**	INIR
**
**	B <- B - 1, (HL) <- PORT(C), HL <- HL + 1, repeated until B = 0
**
**	Bits 0-7 of the address bus are given by the C register, and
**	bits 8-15 by the value of the B register after the decrement.
**
**	Flags:	S Z H V N C
**		? 1 ? ? 1 -

**	INIR is in 'impldept.a'.

** -----

**	JP cc,pq
**
**	If cc true:	PC <- pq
**
**	Flags:	not affected

jp_cc_pq	MACRO
Jp_\1_pq	skip 2			;advance PPC before the test
		move	stCCR,CCR
		b\2.s	.true

		next

.true		getRPC	tmpD0	;yields real-PC of following instruction
		decw	tmpD0
	IFNE PROCESSOR<68030
		getz	tmpD0,(Work)	;get high address byte
		move.w	(Work),tmpD1
		decw	tmpD0
		getz	tmpD0,tmpD1	;complete address in tmpD1
	ELSE
		getz	tmpD0,tmpD1	;get high address byte
		lsl.w	#8,tmpD1
		decw	tmpD0
		getz	tmpD0,tmpD1	;complete address in tmpD1
	ENDC ;IFNE PROCESSOR<68030

		makePPC tmpD1
		testreq
		ENDM

	jp_cc_pq NZ,ne
	jp_cc_pq  Z,eq
	jp_cc_pq NC,cc
	jp_cc_pq  C,cs
	jp_cc_pq PO,vc
	jp_cc_pq PE,vs
	jp_cc_pq  P,pl
	jp_cc_pq  M,mi

** -----

**	JP pq
**
**	PC <- pq
**
**	Flags:	not affected

Jp_pq		getRPC	tmpD0
		getz	tmpD0,tmpD1	;get low pq byte
		incw	tmpD0
	IFNE PROCESSOR<68030
		getz	tmpD0,(Work)
		move.w	(Work),tmpD0	;get high pq byte
	ELSE
		getz	tmpD0,tmpD0
		lsl.w	#8,tmpD0	;get high pq byte
	ENDC ;IFNE PROCESSOR<68030
		move.b	tmpD1,tmpD0	;complete pq in tmpD0
		makePPC tmpD0		;PC <- pq
		testreq

** -----

**	JP (HL)
**
**	PC <- HL
**
**	Flags:	not affected

Jp_1HL1 	makePPC HL
		testreq

** -----

**	JP (ii)
**
**	PC <- ii
**
**	Flags:	not affected

jp_1ii1 	MACRO
Jp_1I\11	opcode_2_bytes
		move.w	Z80_I\1(TableB),tmpD0
		makePPC tmpD0
		testreq
		ENDM

	do_ii jp_1ii1

** -----

**	JR cc,e
**
**	If cc is true, e is added (sign extended) to the PC (which is
**	pointing to the address following the instruction).
**
**	Flags:	not affected

jr_cc_e 	MACRO
Jr_\1_e 	move	stCCR,CCR
		b\2.s	.true

		skip 1
		next

.true		getRPC	tmpD0
		getz	tmpD0,tmpD1	;get branch offset
		incw	tmpD0	;real-PC address of next instruction
		ext.w	tmpD1
		add.w	tmpD1,tmpD0
		makePPC tmpD0
		testreq
		ENDM

	jr_cc_e NZ,ne
	jr_cc_e  Z,eq
	jr_cc_e NC,cc
	jr_cc_e  C,cs

** -----

**	JR e
**
**	e is added (sign extended) to the PC (which is pointing to the
**	address following the instruction).
**
**	Flags:	not affected

Jr_e		getRPC	tmpD0
		getz	tmpD0,tmpD1	;get branch offset
		incw	tmpD0	;real-PC address of next instruction
		ext.w	tmpD1
		add.w	tmpD1,tmpD0
		makePPC tmpD0
		testreq

** -----

**	LD m,n
**
**	m <- n
**
**	m can be r, (HL) or (ii+d)
**
**	Flags:	not affected

ld_r_n		MACRO
Ld_\1_n 	getRPC	tmpD0
		getz	tmpD0,Z80_\1(TableB)
		skip 1
		next
		ENDM

	do_r ld_r_n


Ld_H_n		getRPC	tmpD0
	IFNE PROCESSOR<68030
		move.w	HL,(Work)
		getz	tmpD0,(Work)
		move.w	(Work),HL
	ELSE
		rol.w	#8,HL
		getz	tmpD0,HL
		rol.w	#8,HL
	ENDC ;PROCESSOR<68030
		skip 1
		next


Ld_L_n		getRPC	tmpD0
		getz	tmpD0,HL	;only L is affected
		skip 1
		next


Ld_A_n		getRPC	tmpD0
		getz	tmpD0,A
		skip 1
		next


Ld_1HL1_n	getRPC	tmpD0
		getz	tmpD0,tmpD1
		putz	tmpD1,HL	;putz uses tmpD0
		skip 1
		next


ld_1ii1_n	MACRO
Ld_1I\1_d1_n	opcode_2_bytes
		index	I\1,tmpD1	;indexed address in tmpD1
	;after the 'index' macro, tmpD0 points to the offset byte

		incw	tmpD0
		getz	tmpD0,tmpD2	;get immediate data
		putz	tmpD2,tmpD1	;putz uses tmpD0
		skip 3
		next
		ENDM

	do_ii ld_1ii1_n

** -----

**	LD m,s
**
**	m <- s
**
**	m and s can be any of r, (HL) or (ii+d), with the exception that
**	not both can be indirect modes, i.e. (HL) or (ii+d).
**
**	Flags:	not affected

ld_r_r		MACRO		;(not from or to H, L or A)
Ld_\1_\2	move.b	Z80_\2(TableB),Z80_\1(TableB)
		next
		ENDM


ld_r_H		MACRO		;(not to H, L or A)
Ld_\1_H
	IFNE PROCESSOR<68030
		move.w	HL,(Work)
		move.b	(Work),Z80_\1(TableB)
	ELSE
		getH	HL,tmpD0
		move.b	tmpD0,Z80_\1(TableB)
	ENDC ;PROCESSOR<68030
		next
		ENDM


ld_r_L		MACRO		;(not to H, L or A)
Ld_\1_L 	move.b	HL,Z80_\1(TableB)
		next
		ENDM


ld_r_A		MACRO		;(not to H, L or A)
Ld_\1_A 	move.b	A,Z80_\1(TableB)
		next
		ENDM


ld_r_1HL1	MACRO		;(not to H, L or A)
Ld_\1_1HL1	getz	HL,Z80_\1(TableB)
		next
		ENDM


ld_r_1ii1	MACRO		;(not to H, L or A)
Ld_\1_1I\2_d1	opcode_2_bytes
		index	I\2,tmpD0
		getz	tmpD0,Z80_\1(TableB)
		skip 2
		next
		ENDM


ld_r_s		MACRO
	ld_r_r	\1,B
	ld_r_r	\1,C
	ld_r_r	\1,D
	ld_r_r	\1,E
	ld_r_H	\1
	ld_r_L	\1
	ld_r_A	\1
	ld_r_1HL1 \1
	ld_r_1ii1 \1,X
	ld_r_1ii1 \1,Y
		ENDM

	do_r ld_r_s


ld_H_r		MACRO		;(not from H, L or A)
Ld_H_\1
	IFNE PROCESSOR<68030
		move.w	HL,(Work)
		move.b	Z80_\1(TableB),(Work)
		move.w	(Work),HL
	ELSE
		rol.w	#8,HL
		move.b	Z80_\1(TableB),HL
		rol.w	#8,HL
	ENDC ;PROCESSOR<68030
		next
		ENDM

	do_r ld_H_r


Ld_H_H		next		;Well, I want it to have a unique label.


Ld_H_L
	IFNE PROCESSOR<68030
		move.w	HL,(Work)
		move.b	HL,(Work)
		move.w	(Work),HL
	ELSE
		move.b	HL,tmpD0
		lsl.w	#8,HL
		move.b	tmpD0,HL
	ENDC ;PROCESSOR<68030
		next


Ld_H_A
	IFNE PROCESSOR<68030
		move.w	HL,(Work)
		move.b	A,(Work)
		move.w	(Work),HL
	ELSE
		rol.w	#8,HL
		move.b	A,HL
		rol.w	#8,HL
	ENDC ;PROCESSOR<68030
		next


Ld_H_1HL1
	IFNE PROCESSOR<68030
		move.w	HL,(Work)
		getz	HL,(Work)
		move.w	(Work),HL
	ELSE
		getz	HL,tmpD0
		rol.w	#8,HL
		move.b	tmpD0,HL
		rol.w	#8,HL
	ENDC ;PROCESSOR<68030
		next


ld_H_1ii1	MACRO
Ld_H_1I\1_d1	opcode_2_bytes
		index	I\1,tmpD0
	IFNE PROCESSOR<68030
		move.w	HL,(Work)
		getz	tmpD0,(Work)
		move.w	(Work),HL
	ELSE
		getz	tmpD0,tmpD0
		rol.w	#8,HL
		move.b	tmpD0,HL
		rol.w	#8,HL
	ENDC ;PROCESSOR<68030
		skip 2
		next
		ENDM

	do_ii ld_H_1ii1


ld_L_r		MACRO		;(not from H, L or A)
Ld_L_\1 	move.b	Z80_\1(TableB),HL	;only L affected
		next
		ENDM

	do_r ld_L_r


Ld_L_H
	IFNE PROCESSOR<68030
		move.w	HL,(Work)
		move.b	(Work),HL	;only L affected
	ELSE
		getH	HL,tmpD0
		move.b	tmpD0,HL	;only L affected
	ENDC ;PROCESSOR<68030
		next


Ld_L_L		next		;Well, I want it to have a unique label.


Ld_L_A		move.b	A,HL	;only L affected
		next


Ld_L_1HL1	getz	HL,HL	;only L affected
		next


ld_L_1ii1	MACRO
Ld_L_1I\1_d1	opcode_2_bytes
		index	I\1,tmpD0
		getz	tmpD0,HL	;only L affected
		skip 2
		next
		ENDM

	do_ii ld_L_1ii1


ld_A_r		MACRO		;(not from H, L or A)
Ld_A_\1 	move.b	Z80_\1(TableB),A
		next
		ENDM

	do_r ld_A_r


Ld_A_H
	IFNE PROCESSOR<68030
		move.w	HL,(Work)
		move.b	(Work),A
	ELSE
		move.w	HL,A	;bits 16-31 of A unaffected
		lsr.w	#8,A	;bits 8-15 cleared, H in bits 0-7
	ENDC ;PROCESSOR<68030
		next


Ld_A_L		move.b	HL,A
		next


Ld_A_A		next		;Well, I want it to have a unique label.


Ld_A_1HL1	getz	HL,A
		next


ld_A_1ii1	MACRO
Ld_A_1I\1_d1	opcode_2_bytes
		index	I\1,tmpD0
		getz	tmpD0,A
		skip 2
		next
		ENDM

	do_ii ld_A_1ii1


ld_1HL1_r	MACRO		;(not from H, L or A)
Ld_1HL1_\1	putz	Z80_\1(TableB),HL
		next
		ENDM

	do_r ld_1HL1_r


Ld_1HL1_H
	IFNE PROCESSOR<68030
		move.w	HL,(Work)
		putz	(Work),HL
	ELSE
		getH	HL,tmpD1
		putz	tmpD1,HL	;(putz uses tmpD0)
	ENDC ;PROCESSOR<68030
		next


Ld_1HL1_L	putz	HL,HL	;only L written
		next


Ld_1HL1_A	putz	A,HL
		next


ld_1ii1_r	MACRO		;(not from H, L or A)
Ld_1I\1_d1_\2	opcode_2_bytes
		index	I\1,tmpD1
		putz	Z80_\2(TableB),tmpD1	;(putz uses tmpD0)
		skip 2
		next
		ENDM


ld_1ii1_H	MACRO
Ld_1I\1_d1_H	opcode_2_bytes
		index	I\1,tmpD1
	IFNE PROCESSOR<68030
		move.w	HL,(Work)
		putz	(Work),tmpD1	;(putz uses tmpD0)
	ELSE
		getH	HL,tmpD2
		putz	tmpD2,tmpD1	;(putz uses tmpD0)
	ENDC ;PROCESSOR<68030
		skip 2
		next
		ENDM


ld_1ii1_L	MACRO
Ld_1I\1_d1_L	opcode_2_bytes
		index	I\1,tmpD1
		putz	HL,tmpD1	;(putz uses tmpD0)
		skip 2
		next
		ENDM


ld_1ii1_A	MACRO
Ld_1I\1_d1_A	opcode_2_bytes
		index	I\1,tmpD1
		putz	A,tmpD1 	;(putz uses tmpD0)
		skip 2
		next
		ENDM


ld_1ii1_s	MACRO
	ld_1ii1_r \1,B
	ld_1ii1_r \1,C
	ld_1ii1_r \1,D
	ld_1ii1_r \1,E
	ld_1ii1_H \1
	ld_1ii1_L \1
	ld_1ii1_A \1
		ENDM

	do_ii ld_1ii1_s

** -----

**	LD A,(nn)
**
**	A <- (nn)
**
**	Flags:	not affected

Ld_A_1nn1	getRPC	tmpD0
		getz	tmpD0,tmpD1	;get nn [L]
		incw	tmpD0
	IFNE PROCESSOR<68030
		getz	tmpD0,(Work)	;get nn [H]
		move.w	(Work),tmpD0
	ELSE
		getz	tmpD0,tmpD0	;get nn [H]
		lsl.w	#8,tmpD0
	ENDC ;IFNE PROCESSOR<68030
		move.b	tmpD1,tmpD0	;complete nn in tmpD0
		getz	tmpD0,A
		skip 2
		next

** -----

**	LD (nn),A
**
**	(nn) <- A
**
**	Flags:	not affected

Ld_1nn1_A	getRPC	tmpD1
		getz	tmpD1,tmpD0	;get nn [L]
		incw	tmpD1
	IFNE PROCESSOR<68030
		getz	tmpD1,(Work)	;get nn [H]
		move.w	(Work),tmpD1
	ELSE
		getz	tmpD1,tmpD1	;get nn [H]
		lsl.w	#8,tmpD1
	ENDC ;IFNE PROCESSOR<68030
		move.b	tmpD0,tmpD1	;complete nn in tmpD1
		putz	A,tmpD1 	;(putz uses tmpD0)
		skip 2
		next

** -----

**	LD A,(BC)
**
**	A <- (BC)
**
**	Flags:	not affected

Ld_A_1BC1	move.w	Z80_BC(TableB),tmpD0
		getz	tmpD0,A
		next

** -----

**	LD A,(DE)
**
**	A <- (DE)
**
**	Flags:	not affected

Ld_A_1DE1	move.w	Z80_DE(TableB),tmpD0
		getz	tmpD0,A
		next

** -----

**	LD (BC),A
**
**	(BC) <- A
**
**	Flags:	not affected

Ld_1BC1_A	move.w	Z80_BC(TableB),tmpD1
		putz	A,tmpD1 	;(putz uses tmpD0)
		next

** -----

**	LD (DE),A
**
**	(DE) <- A
**
**	Flags:	not affected

Ld_1DE1_A	move.w	Z80_DE(TableB),tmpD1
		putz	A,tmpD1 	;(putz uses tmpD0)
		next

** -----

**	LD rr,nn
**
**	rr <- nn
**
**	Flags:	not affected

ld_rr_nn	MACRO
Ld_\1\2_nn	getRPC	tmpD0
		getz	tmpD0,Z80_\2(TableB)	;rr [L] <- nn [L]
		incw	tmpD0
		getz	tmpD0,Z80_\1(TableB)	;rr [H] <- nn [H]
		skip 2
		next
		ENDM

	do_rr ld_rr_nn


Ld_HL_nn	getRPC	tmpD0
		getz	tmpD0,tmpD1	;get nn [L]
		incw	tmpD0
	IFNE PROCESSOR<68030
		getz	tmpD0,(Work)	;get nn [H]
		move.w	(Work),HL
	ELSE
		getz	tmpD0,HL	;get nn [H]
		lsl.w	#8,HL
	ENDC ;IFNE PROCESSOR<68030
		move.b	tmpD1,HL	;assemble HL
		skip 2
		next


Ld_SP_nn	getRPC	tmpD0
		getz	tmpD0,tmpD1	;get nn [L]
		incw	tmpD0
	IFNE PROCESSOR<68030
		getz	tmpD0,(Work)	;get nn [H]
		move.w	(Work),ZSP
	ELSE
		getz	tmpD0,ZSP	;get nn [H]
		lsl.w	#8,ZSP
	ENDC ;IFNE PROCESSOR<68030
		move.b	tmpD1,ZSP	;assemble SP
		skip 2
		next

** -----

**	LD ii,nn
**
**	ii <- nn
**
**	Flags:	not affected

ld_ii_nn	MACRO
Ld_I\1_nn	opcode_2_bytes
		getRPC	tmpD0
		incw	tmpD0			;address of nn
		getz	tmpD0,Z80_\1L(TableB)	;ii [L] <- nn [L]
		incw	tmpD0
		getz	tmpD0,Z80_\1H(TableB)	;ii [H] <- nn [H]
		skip 3
		next
		ENDM

	do_ii ld_ii_nn

** -----

**	LD rr,(nn)
**
**	rr [L] <- (nn), rr [H] <- (nn+1)
**
**	Flags:	not affected
**
**	Note that for rr = HL, this is the 'nonstandard' (ED-prefixed)
**	version of the LD HL,(nn) instruction.

ld_rr_1nn1	MACRO
Ld_\1\2_1nn1	opcode_2_bytes
		getRPC	tmpD0
		incw	tmpD0		;address of nn
		getz	tmpD0,tmpD1	;get nn [L]
		incw	tmpD0
	IFNE PROCESSOR<68030
		getz	tmpD0,(Work)	;get nn [H]
		move.w	(Work),tmpD0
	ELSE
		getz	tmpD0,tmpD0	;get nn [H]
		lsl.w	#8,tmpD0
	ENDC ;IFNE PROCESSOR<68030
		move.b	tmpD1,tmpD0	;complete nn in tmpD0
		getz	tmpD0,Z80_\2(TableB)	;rr [L] <- (nn)
		incw	tmpD0
		getz	tmpD0,Z80_\1(TableB)	;rr [H] <- (nn+1)
		skip 3
		next
		ENDM

	do_rr ld_rr_1nn1


ED_Ld_HL_1nn1	opcode_2_bytes		;The ED-prefixed Ld HL,(nn)
		getRPC	tmpD0
		incw	tmpD0
		getz	tmpD0,tmpD1
		incw	tmpD0
	IFNE PROCESSOR<68030
		getz	tmpD0,(Work)
		move.w	(Work),tmpD0
	ELSE
		getz	tmpD0,tmpD0
		lsl.w	#8,tmpD0
	ENDC ;IFNE PROCESSOR<68030
		move.b	tmpD1,tmpD0
		getz	tmpD0,tmpD1	;get (nn)
		incw	tmpD0
	IFNE PROCESSOR<68030
		getz	tmpD0,(Work)	;get (nn+1)
		move.w	(Work),HL
	ELSE
		getz	tmpD0,HL	;get (nn+1)
		lsl.w	#8,HL
	ENDC ;IFNE PROCESSOR<68030
		move.b	tmpD1,HL	;assemble HL
		skip 3
		next


Ld_SP_1nn1	opcode_2_bytes
		getRPC	tmpD0
		incw	tmpD0
		getz	tmpD0,tmpD1
		incw	tmpD0
	IFNE PROCESSOR<68030
		getz	tmpD0,(Work)
		move.w	(Work),tmpD0
	ELSE
		getz	tmpD0,tmpD0
		lsl.w	#8,tmpD0
	ENDC ;IFNE PROCESSOR<68030
		move.b	tmpD1,tmpD0
		getz	tmpD0,tmpD1	;get (nn)
		incw	tmpD0
	IFNE PROCESSOR<68030
		getz	tmpD0,(Work)	;get (nn+1)
		move.w	(Work),ZSP
	ELSE
		getz	tmpD0,ZSP	;get (nn+1)
		lsl.w	#8,ZSP
	ENDC ;IFNE PROCESSOR<68030
		move.b	tmpD1,ZSP	;assemble SP
		skip 3
		next

** -----

**	LD HL,(nn)
**
**	L <- (nn), H <- (nn+1)
**
**	Flags:	not affected

**	Note that the ED-prefixed synonym is labeled ED_Ld_HL_1nn1

Ld_HL_1nn1	getRPC	tmpD0
		getz	tmpD0,tmpD1
		incw	tmpD0
	IFNE PROCESSOR<68030
		getz	tmpD0,(Work)
		move.w	(Work),tmpD0
	ELSE
		getz	tmpD0,tmpD0
		lsl.w	#8,tmpD0
	ENDC ;IFNE PROCESSOR<68030
		move.b	tmpD1,tmpD0
		getz	tmpD0,tmpD1	;get (nn)
		incw	tmpD0
	IFNE PROCESSOR<68030
		getz	tmpD0,(Work)	;get (nn+1)
		move.w	(Work),HL
	ELSE
		getz	tmpD0,HL	;get (nn+1)
		lsl.w	#8,HL
	ENDC ;IFNE PROCESSOR<68030
		move.b	tmpD1,HL	;assemble HL
		skip 2
		next

** -----

**	LD ii,(nn)
**
**	ii [L] <- (nn), ii [H] <- (nn+1)
**
**	Flags:	not affected

ld_ii_1nn1	MACRO
Ld_I\1_1nn1	opcode_2_bytes
		getRPC	tmpD0
		incw	tmpD0		;address of nn
		getz	tmpD0,tmpD1	;get nn [L]
		incw	tmpD0
	IFNE PROCESSOR<68030
		getz	tmpD0,(Work)	;get nn [H]
		move.w	(Work),tmpD0
	ELSE
		getz	tmpD0,tmpD0	;get nn [H]
		lsl.w	#8,tmpD0
	ENDC ;IFNE PROCESSOR<68030
		move.b	tmpD1,tmpD0	;complete nn in tmpD0
		getz	tmpD0,Z80_\1L(TableB)	;ii [L] <- (nn)
		incw	tmpD0
		getz	tmpD0,Z80_\1H(TableB)	;ii [H] <- (nn+1)
		skip 3
		next
		ENDM

	do_ii ld_ii_1nn1

** -----

**	LD (nn),rr
**
**	(nn) <- rr [L], (nn+1) <- rr [H]
**
**	Flags:	not affected
**
**	Note that for rr = HL, this is the 'nonstandard' (ED-prefixed)
**	version of the LD (nn),HL instruction.

ld_1nn1_rr	MACRO
Ld_1nn1_\1\2	opcode_2_bytes
		getRPC	tmpD1
		incw	tmpD1		;address of nn
		getz	tmpD1,tmpD0	;get nn [L]
		incw	tmpD1
	IFNE PROCESSOR<68030
		getz	tmpD1,(Work)	;get nn [H]
		move.w	(Work),tmpD1
	ELSE
		getz	tmpD1,tmpD1	;get nn [H]
		lsl.w	#8,tmpD1
	ENDC ;IFNE PROCESSOR<68030
		move.b	tmpD0,tmpD1 ;complete nn in tmpD1 (putz uses tmpD0)
		putz	Z80_\2(TableB),tmpD1	;(nn) <- rr [L]
		incw	tmpD1
		putz	Z80_\1(TableB),tmpD1,2	;(nn+1) <- rr [H] (2nd use)
		skip 3
		next
		ENDM

	do_rr ld_1nn1_rr


ED_Ld_1nn1_HL	opcode_2_bytes		;The ED-prefixed Ld (nn),HL
		getRPC	tmpD1
		incw	tmpD1
		getz	tmpD1,tmpD0
		incw	tmpD1
	IFNE PROCESSOR<68030
		getz	tmpD1,(Work)
		move.w	(Work),tmpD1
	ELSE
		getz	tmpD1,tmpD1
		lsl.w	#8,tmpD1
	ENDC ;IFNE PROCESSOR<68030
		move.b	tmpD0,tmpD1
		putz	HL,tmpD1	;(nn) <- L (putz uses tmpD0)
		incw	tmpD1
	IFNE PROCESSOR<68030
		move.w	HL,(Work)
		putz	(Work),tmpD1,2	;(nn+1) <- H (2nd use)
	ELSE
		move.l	HL,tmpD2
		lsr.w	#8,tmpD2
		putz	tmpD2,tmpD1,2	;(nn+1) <- H (2nd use)
	ENDC ;IFNE PROCESSOR<68030
		skip 3
		next


Ld_1nn1_SP	opcode_2_bytes
		getRPC	tmpD1
		incw	tmpD1
		getz	tmpD1,tmpD0
		incw	tmpD1
	IFNE PROCESSOR<68030
		getz	tmpD1,(Work)
		move.w	(Work),tmpD1
	ELSE
		getz	tmpD1,tmpD1
		lsl.w	#8,tmpD1
	ENDC ;IFNE PROCESSOR<68030
		move.b	tmpD0,tmpD1
		putz	ZSP,tmpD1	;(nn) <- SP [L] (putz uses tmpD0)
		incw	tmpD1
	IFNE PROCESSOR<68030
		move.w	ZSP,(Work)
		putz	(Work),tmpD1,2	;(nn+1) <- SP [H] (2nd use)
	ELSE
		move.l	ZSP,tmpD2
		lsr.w	#8,tmpD2
		putz	tmpD2,tmpD1,2	;(nn+1) <- SP [H] (2nd use)
	ENDC ;IFNE PROCESSOR<68030
		skip 3
		next

** -----

**	LD (nn),HL
**
**	(nn) <- L, (nn+1) <- H
**
**	Flags:	not affected

**	Note that the ED-prefixed synonym is labeled ED_Ld_1nn1_HL

Ld_1nn1_HL	getRPC	tmpD1
		getz	tmpD1,tmpD0
		incw	tmpD1
	IFNE PROCESSOR<68030
		getz	tmpD1,(Work)
		move.w	(Work),tmpD1
	ELSE
		getz	tmpD1,tmpD1
		lsl.w	#8,tmpD1
	ENDC ;IFNE PROCESSOR<68030
		move.b	tmpD0,tmpD1
		putz	HL,tmpD1	;(nn) <- L (putz uses tmpD0)
		incw	tmpD1
	IFNE PROCESSOR<68030
		move.w	HL,(Work)
		putz	(Work),tmpD1,2	;(nn+1) <- H (2nd use)
	ELSE
		move.l	HL,tmpD2
		lsr.w	#8,tmpD2
		putz	tmpD2,tmpD1,2	;(nn+1) <- H (2nd use)
	ENDC ;IFNE PROCESSOR<68030
		skip 2
		next

** -----

**	LD (nn),ii
**
**	(nn) <- ii [L] , (nn+1) <- ii [H]
**
**	Flags:	not affected

ld_1nn1_ii	MACRO
Ld_1nn1_I\1	opcode_2_bytes
		getRPC	tmpD1
		incw	tmpD1		;address of nn
		getz	tmpD1,tmpD0	;get nn [L]
		incw	tmpD1
	IFNE PROCESSOR<68030
		getz	tmpD1,(Work)	;get nn [H]
		move.w	(Work),tmpD1
	ELSE
		getz	tmpD1,tmpD1	;get nn [H]
		lsl.w	#8,tmpD1
	ENDC ;IFNE PROCESSOR<68030
		move.b	tmpD0,tmpD1 ;complete nn in tmpD1 (putz uses tmpD0)
		putz	Z80_\1L(TableB),tmpD1	;(nn) <- ii [L]
		incw	tmpD1
		putz	Z80_\1H(TableB),tmpD1,2 ;(nn+1) <- ii [H] (2nd use)
		skip 3
		next
		ENDM

	do_ii ld_1nn1_ii

** -----

**	LD SP,HL
**
**	SP <- HL
**
**	Flags:	not affected

Ld_SP_HL	move.w	HL,ZSP
		next

** -----

**	LD SP,ii
**
**	SP <- ii
**
**	Flags:	not affected

ld_SP_ii	MACRO
Ld_SP_I\1	opcode_2_bytes
		move.w	Z80_I\1(TableB),ZSP
		skip 1
		next
		ENDM

	do_ii ld_SP_ii

** -----

**	LD A,I
**
**	A <- I
**
**	Flags:	S Z H V N C
**		* * 0 + 0 -	P/V is set to the value of IFF2

Ld_A_I		opcode_2_bytes
		move.b	Z80_I(TableB),A ;Z and N tested, V and C cleared
		putccr	tmpD0
		and.w	#1,stCCR	;keep old C
		or.w	tmpD0,stCCR	;insert other flags
		tst.b	Z80_IFF(TableB) ;test IFF2 (bit 7 = sign bit)
		bpl.s	.clear
		addq.w	#2,stCCR	;set V if IFF2 was set
.clear
	IFD BCDFLAGS
		clr.b	Z80_BCDF(TableB)	;reset H and N
	ENDC
		skip 1
		next

** -----

**	LD I,A
**
**	I <- A
**
**	Flags:	not affected

Ld_I_A		opcode_2_bytes
		move.b	A,Z80_I(TableB)
		skip 1
		next

** -----

**	LD A,R
**
**	A <- R
**
**	Flags:	S Z H V N C
**		* * 0 + 0 -	P/V is set to the value of IFF2

**	LD A,R is in 'impldept.a'.

** -----

**	LD R,A
**
**	R <- A
**
**	Flags:	not affected

Ld_R_A		opcode_2_bytes
		move.b	A,Z80_R(TableB)
		skip 1
		next

** -----

**	LDD
**
**	(DE) <- (HL), DE <- DE - 1, HL <- HL - 1, BC <- BC - 1
**
**	Flags:	S Z H V N C
**		? ? 0 + 0 -
**
**	P/V is reset if BC is 0 after the instruction, otherwise set.

** Note that S and Z are unaffected in this implementation.

Ldd		opcode_2_bytes
		or.w	#2,stCCR		;set V
		move.w	Z80_DE(TableB),tmpD1
		getz	HL,tmpD2
		putz	tmpD2,tmpD1	;(DE) <- (HL) (uses tmpD0)
		decw	tmpD1			;DE <- DE - 1
		move.w	tmpD1,Z80_DE(TableB)
		decw	HL			;HL <- HL - 1
		decw	Z80_BC(TableB)		;BC <- BC - 1
		bne.s	.nz
		and.w	#$FFFD,stCCR		;clear V if BC = 0
.nz
	IFD BCDFLAGS
		clr.b	Z80_BCDF(TableB)	;reset H and N
	ENDC
		skip 1
		next

** -----

**	LDDR
**
**	(DE) <- (HL), DE <- DE - 1, HL <- HL - 1, BC <- BC - 1,
**	repeated until BC = 0
**
**	Flags:	S Z H V N C
**		? ? 0 0 0 -

** Note that S and Z are unaffected in this implementation.

Lddr		opcode_2_bytes
		move.w	Z80_DE(TableB),tmpD1
		getz	HL,tmpD2
		putz	tmpD2,tmpD1	;(DE) <- (HL) (uses tmpD0)
		decw	tmpD1			;DE <- DE - 1
		move.w	tmpD1,Z80_DE(TableB)
		decw	HL			;HL <- HL - 1
		decw	Z80_BC(TableB)		;BC <- BC - 1
		bne.s	.nz

		and.w	#$FFFD,stCCR		;clear V
	IFD BCDFLAGS
		clr.b	Z80_BCDF(TableB)	;reset H and N
	ENDC
		skip 1
		next

.nz		getRPC	tmpD0
		decw	tmpD0	;get real-PC address of first opcode byte
		makePPC tmpD0	;recalculate PPC
		testreq 	;handle exception or thread-to-loop

** -----

**	LDI
**
**	(DE) <- (HL), DE <- DE + 1, HL <- HL + 1, BC <- BC - 1
**
**	Flags:	S Z H V N C
**		? ? 0 + 0 -
**
**	P/V is reset if BC is 0 after the instruction, otherwise set.

** Note that S and Z are unaffected in this implementation.

Ldi		opcode_2_bytes
		or.w	#2,stCCR		;set V
		move.w	Z80_DE(TableB),tmpD1
		getz	HL,tmpD2
		putz	tmpD2,tmpD1	;(DE) <- (HL) (uses tmpD0)
		incw	tmpD1			;DE <- DE + 1
		move.w	tmpD1,Z80_DE(TableB)
		incw	HL			;HL <- HL + 1
		decw	Z80_BC(TableB)		;BC <- BC - 1
		bne.s	.nz
		and.w	#$FFFD,stCCR		;clear V if BC = 0
.nz
	IFD BCDFLAGS
		clr.b	Z80_BCDF(TableB)	;reset H and N
	ENDC
		skip 1
		next

** -----

**	LDIR
**
**	(DE) <- (HL), DE <- DE + 1, HL <- HL + 1, BC <- BC - 1,
**	repeated until BC = 0
**
**	Flags:	S Z H V N C
**		? ? 0 0 0 -

** Note that S and Z are unaffected in this implementation.

Ldir		opcode_2_bytes
		move.w	Z80_DE(TableB),tmpD1
		getz	HL,tmpD2
		putz	tmpD2,tmpD1	;(DE) <- (HL) (uses tmpD0)
		incw	tmpD1			;DE <- DE + 1
		move.w	tmpD1,Z80_DE(TableB)
		incw	HL			;HL <- HL + 1
		decw	Z80_BC(TableB)		;BC <- BC - 1
		bne.s	.nz

		and.w	#$FFFD,stCCR		;clear V
	IFD BCDFLAGS
		clr.b	Z80_BCDF(TableB)	;reset H and N
	ENDC
		skip 1
		next

.nz		getRPC	tmpD0
		decw	tmpD0	;get real-PC address of first opcode byte
		makePPC tmpD0	;recalculate PPC
		testreq 	;handle exception or thread-to-loop

** -----

**	NEG
**
**	A <- 0 - A
**
**	Flags:	S Z H V N C
**		* * * * 1 *

Neg		opcode_2_bytes
	IFD BCDFLAGS
		move.l	A,tmpD0
		neg.b	A
		putccr	stCCR
		moveq	#$F,tmpD1
		and.w	tmpD0,tmpD1	;get low nybble of original A
		neg.b	tmpD1		;bits 4-7 become set if H
		or.w	#2,tmpD1	;set N flag
		move.b	tmpD1,Z80_BCDF(TableB)	;store BCD flags
	ELSE
		neg.b	A
		putccr	stCCR
	ENDC
		skip 1
		next

** -----

**	NOP
**
**	Delay; nothing is done under one machine cycle.
**
**	Flags:	not affected

Nop		nop	;synchronizes 680x0 pipelines
		next

** -----

**	OR s
**
**	A <- A \/ s
**
**	The bitwise logical inclusive-or of A and s is stored in A.
**
**	s can be r, n, (HL) or (ii+d)
**
**	Flags:	S Z H P N C
**		* * 0 * 0 0

or_r		MACRO
Or_\1		or.b	Z80_\1(TableB),A	;V and C are cleared
		putccr	stCCR	;Sign and Zero depend on the result
		parity	A	;set V depending on parity of result
	IFD BCDFLAGS
		clr.b	Z80_BCDF(TableB)	;clear H and N
	ENDC
		next
		ENDM

	do_r or_r


Or_H		getH	HL,tmpD0
		or.b	tmpD0,A
		putccr	stCCR
		parity	A
	IFD BCDFLAGS
		clr.b	Z80_BCDF(TableB)
	ENDC
		next


Or_L		or.b	HL,A	;only L is used
		putccr	stCCR
		parity	A
	IFD BCDFLAGS
		clr.b	Z80_BCDF(TableB)
	ENDC
		next


Or_A		or.b	A,A
		putccr	stCCR
		parity	A
	IFD BCDFLAGS
		clr.b	Z80_BCDF(TableB)
	ENDC
		next


Or_n		getRPC	tmpD0
		getz	tmpD0,tmpD1
		or.b	tmpD1,A
		putccr	stCCR
		parity	A
	IFD BCDFLAGS
		clr.b	Z80_BCDF(TableB)
	ENDC
		skip 1
		next


Or_1HL1 	getz	HL,tmpD0
		or.b	tmpD0,A
		putccr	stCCR
		parity	A
	IFD BCDFLAGS
		clr.b	Z80_BCDF(TableB)
	ENDC
		next


or_1ii1 	MACRO
Or_1I\1_d1	opcode_2_bytes
		index	I\1,tmpD0
		getz	tmpD0,tmpD1
		or.b	tmpD1,A
		putccr	stCCR
		parity	A
	IFD BCDFLAGS
		clr.b	Z80_BCDF(TableB)
	ENDC
		skip 2
		next
		ENDM

	do_ii or_1ii1

** -----

**	OTDR
**
**	B <- B - 1, PORT(C) <- (HL), HL <- HL - 1, repeated until B = 0
**
**	Bits 0-7 of the address bus are given by the C register, and
**	bits 8-15 by the value of the B register after the decrement.
**
**	Flags:	S Z H V N C
**		? 1 ? ? 1 -

**	OTDR is in 'impldept.a'.

** -----

**	OTIR
**
**	B <- B - 1, PORT(C) <- (HL), HL <- HL + 1, repeated until B = 0
**
**	Bits 0-7 of the address bus are given by the C register, and
**	bits 8-15 by the value of the B register after the decrement.
**
**	Flags:	S Z H V N C
**		? 1 ? ? 1 -

**	OTIR is in 'impldept.a'.

** -----

**	OUT (C),r
**
**	PORT(C) <- r
**
**	Bits 0-7 of the address bus are given by the C register, and
**	bits 8-15 by the B register.
**
**	Flags:	not affected
**
**	Note: 'Out (C),x' is an undocumented version of this
**	instruction. It seems to output a zero value to the port. The
**	name 'Out (C),(HL)' would be symmetric with the bit pattern,
**	but is not correct.

**	OUT (C),r is in 'impldept.a'.

** -----

**	OUT (n),A
**
**	PORT(n) <- A
**
**	Bits 0-7 of the address bus are given by the immediate 'n' byte,
**	and bits 8-15 by the value of the A register before the operation.
**
**	Flags:	not affected

**	OUT (n),A is in 'impldept.a'.

** -----

**	OUTD
**
**	B <- B - 1, PORT(C) <- (HL), HL <- HL - 1
**
**	Bits 0-7 of the address bus are given by the C register, and
**	bits 8-15 by the value of the B register after the decrement.
**
**	Flags:	S Z H V N C
**		? * ? ? 1 -
**
**	Z is set if B is 0 after the instruction, otherwise reset.

**	OUTD is in 'impldept.a'.

** -----

**	OUTI
**
**	B <- B - 1, PORT(C) <- (HL), HL <- HL + 1
**
**	Bits 0-7 of the address bus are given by the C register, and
**	bits 8-15 by the value of the B register after the decrement.
**
**	Flags:	S Z H V N C
**		? * ? ? 1 -
**
**	Z is set if B is 0 after the instruction, otherwise reset.

**	OUTI is in 'impldept.a'.

** -----

**	POP qq
**
**	qq [L] <- (SP), qq [H] <- (SP+1), SP <- SP + 2
**
**	Flags:	if qq = AF then F <- (SP), otherwise not affected

pop_rr		MACRO
Pop_\1\2	getz	ZSP,Z80_\2(TableB)	;get qq [L]
		incw	ZSP
		getz	ZSP,Z80_\1(TableB)	;get qq [H]
		incw	ZSP
		next
		ENDM

	do_rr pop_rr


Pop_HL		getz	ZSP,tmpD0	;get L
		incw	ZSP
	IFNE PROCESSOR<68030
		getz	ZSP,(Work)
		move.w	(Work),HL	;get H
	ELSE
		getz	ZSP,HL
		lsl.w	#8,HL		;get H
	ENDC ;IFNE PROCESSOR<68030
		move.b	tmpD0,HL	;insert L
		incw	ZSP
		next


**	POP AF notes:
**
**	Popping the BCD flags is not conditionally compiled. They are
**	always read along with the other flags.
**	  The unused F register bits are not guaranteed to survive an
**	operation that affects any of the flags. It *is* guaranteed,
**	however, that a 'Pop AF' with a subsequent 'Push AF' and no
**	flag-affecting instructions there inbetween, will preserve all the
**	F register bits.

Pop_AF		clr.w	tmpD0			;for the indexing below
		getz	ZSP,tmpD0		;pop F
		move.b	tmpD0,Z80_BCDF(TableB)	;store the BCD flags
		move.b	tmpD0,Z80_F(TableB)	;store the unused bits

		;now map the Z80 S, Z, V and C flags onto the 680x0 CCR
		move.b	F_to_CCR_table(PC,tmpD0.w),stCCR

		incw	ZSP
		getz	ZSP,A		;pop A
		incw	ZSP
		next


F_to_CCR_table

	;Z80 SZ?H?VNC to 680x0 ----NZVC translation table:
	;Z80 S -> 680x0 N. Z80 H and N flags and unused bits map to zero.

		;--------, -------C, ------+-, ------+C
	dc.b	%0000,%0001,%0000,%0001

		;-----V--, -----V-C, -----V+-, -----V+C
	dc.b	%0010,%0011,%0010,%0011

		;----+---, ----+--C, ----+-+-, ----+-+C
	dc.b	%0000,%0001,%0000,%0001

		;----+V--, ----+V-C, ----+V+-, ----+V+C
	dc.b	%0010,%0011,%0010,%0011

		;---+----, ---+---C, ---+--+-, ---+--+C
	dc.b	%0000,%0001,%0000,%0001

		;---+-V--, ---+-V-C, ---+-V+-, ---+-V+C
	dc.b	%0010,%0011,%0010,%0011

		;---++---, ---++--C, ---++-+-, ---++-+C
	dc.b	%0000,%0001,%0000,%0001

		;---++V--, ---++V-C, ---++V+-, ---++V+C
	dc.b	%0010,%0011,%0010,%0011

		;--+-----, --+----C, --+---+-, --+---+C
	dc.b	%0000,%0001,%0000,%0001

		;--+--V--, --+--V-C, --+--V+-, --+--V+C
	dc.b	%0010,%0011,%0010,%0011

		;--+-+---, --+-+--C, --+-+-+-, --+-+-+C
	dc.b	%0000,%0001,%0000,%0001

		;--+-+V--, --+-+V-C, --+-+V+-, --+-+V+C
	dc.b	%0010,%0011,%0010,%0011

		;--++----, --++---C, --++--+-, --++--+C
	dc.b	%0000,%0001,%0000,%0001

		;--++-V--, --++-V-C, --++-V+-, --++-V+C
	dc.b	%0010,%0011,%0010,%0011

		;--+++---, --+++--C, --+++-+-, --+++-+C
	dc.b	%0000,%0001,%0000,%0001

		;--+++V--, --+++V-C, --+++V+-, --+++V+C
	dc.b	%0010,%0011,%0010,%0011

		;-Z------, -Z-----C, -Z----+-, -Z----+C
	dc.b	%0100,%0101,%0100,%0101

		;-Z---V--, -Z---V-C, -Z---V+-, -Z---V+C
	dc.b	%0110,%0111,%0110,%0111

		;-Z--+---, -Z--+--C, -Z--+-+-, -Z--+-+C
	dc.b	%0100,%0101,%0100,%0101

		;-Z--+V--, -Z--+V-C, -Z--+V+-, -Z--+V+C
	dc.b	%0110,%0111,%0110,%0111

		;-Z-+----, -Z-+---C, -Z-+--+-, -Z-+--+C
	dc.b	%0100,%0101,%0100,%0101

		;-Z-+-V--, -Z-+-V-C, -Z-+-V+-, -Z-+-V+C
	dc.b	%0110,%0111,%0110,%0111

		;-Z-++---, -Z-++--C, -Z-++-+-, -Z-++-+C
	dc.b	%0100,%0101,%0100,%0101

		;-Z-++V--, -Z-++V-C, -Z-++V+-, -Z-++V+C
	dc.b	%0110,%0111,%0110,%0111

		;-Z+-----, -Z+----C, -Z+---+-, -Z+---+C
	dc.b	%0100,%0101,%0100,%0101

		;-Z+--V--, -Z+--V-C, -Z+--V+-, -Z+--V+C
	dc.b	%0110,%0111,%0110,%0111

		;-Z+-+---, -Z+-+--C, -Z+-+-+-, -Z+-+-+C
	dc.b	%0100,%0101,%0100,%0101

		;-Z+-+V--, -Z+-+V-C, -Z+-+V+-, -Z+-+V+C
	dc.b	%0110,%0111,%0110,%0111

		;-Z++----, -Z++---C, -Z++--+-, -Z++--+C
	dc.b	%0100,%0101,%0100,%0101

		;-Z++-V--, -Z++-V-C, -Z++-V+-, -Z++-V+C
	dc.b	%0110,%0111,%0110,%0111

		;-Z+++---, -Z+++--C, -Z+++-+-, -Z+++-+C
	dc.b	%0100,%0101,%0100,%0101

		;-Z+++V--, -Z+++V-C, -Z+++V+-, -Z+++V+C
	dc.b	%0110,%0111,%0110,%0111

		;S-------, S------C, S-----+-, S-----+C
	dc.b	%1000,%1001,%1000,%1001

		;S----V--, S----V-C, S----V+-, S----V+C
	dc.b	%1010,%1011,%1010,%1011

		;S---+---, S---+--C, S---+-+-, S---+-+C
	dc.b	%1000,%1001,%1000,%1001

		;S---+V--, S---+V-C, S---+V+-, S---+V+C
	dc.b	%1010,%1011,%1010,%1011

		;S--+----, S--+---C, S--+--+-, S--+--+C
	dc.b	%1000,%1001,%1000,%1001

		;S--+-V--, S--+-V-C, S--+-V+-, S--+-V+C
	dc.b	%1010,%1011,%1010,%1011

		;S--++---, S--++--C, S--++-+-, S--++-+C
	dc.b	%1000,%1001,%1000,%1001

		;S--++V--, S--++V-C, S--++V+-, S--++V+C
	dc.b	%1010,%1011,%1010,%1011

		;S-+-----, S-+----C, S-+---+-, S-+---+C
	dc.b	%1000,%1001,%1000,%1001

		;S-+--V--, S-+--V-C, S-+--V+-, S-+--V+C
	dc.b	%1010,%1011,%1010,%1011

		;S-+-+---, S-+-+--C, S-+-+-+-, S-+-+-+C
	dc.b	%1000,%1001,%1000,%1001

		;S-+-+V--, S-+-+V-C, S-+-+V+-, S-+-+V+C
	dc.b	%1010,%1011,%1010,%1011

		;S-++----, S-++---C, S-++--+-, S-++--+C
	dc.b	%1000,%1001,%1000,%1001

		;S-++-V--, S-++-V-C, S-++-V+-, S-++-V+C
	dc.b	%1010,%1011,%1010,%1011

		;S-+++---, S-+++--C, S-+++-+-, S-+++-+C
	dc.b	%1000,%1001,%1000,%1001

		;S-+++V--, S-+++V-C, S-+++V+-, S-+++V+C
	dc.b	%1010,%1011,%1010,%1011

		;SZ------, SZ-----C, SZ----+-, SZ----+C
	dc.b	%1100,%1101,%1100,%1101

		;SZ---V--, SZ---V-C, SZ---V+-, SZ---V+C
	dc.b	%1110,%1111,%1110,%1111

		;SZ--+---, SZ--+--C, SZ--+-+-, SZ--+-+C
	dc.b	%1100,%1101,%1100,%1101

		;SZ--+V--, SZ--+V-C, SZ--+V+-, SZ--+V+C
	dc.b	%1110,%1111,%1110,%1111

		;SZ-+----, SZ-+---C, SZ-+--+-, SZ-+--+C
	dc.b	%1100,%1101,%1100,%1101

		;SZ-+-V--, SZ-+-V-C, SZ-+-V+-, SZ-+-V+C
	dc.b	%1110,%1111,%1110,%1111

		;SZ-++---, SZ-++--C, SZ-++-+-, SZ-++-+C
	dc.b	%1100,%1101,%1100,%1101

		;SZ-++V--, SZ-++V-C, SZ-++V+-, SZ-++V+C
	dc.b	%1110,%1111,%1110,%1111

		;SZ+-----, SZ+----C, SZ+---+-, SZ+---+C
	dc.b	%1100,%1101,%1100,%1101

		;SZ+--V--, SZ+--V-C, SZ+--V+-, SZ+--V+C
	dc.b	%1110,%1111,%1110,%1111

		;SZ+-+---, SZ+-+--C, SZ+-+-+-, SZ+-+-+C
	dc.b	%1100,%1101,%1100,%1101

		;SZ+-+V--, SZ+-+V-C, SZ+-+V+-, SZ+-+V+C
	dc.b	%1110,%1111,%1110,%1111

		;SZ++----, SZ++---C, SZ++--+-, SZ++--+C
	dc.b	%1100,%1101,%1100,%1101

		;SZ++-V--, SZ++-V-C, SZ++-V+-, SZ++-V+C
	dc.b	%1110,%1111,%1110,%1111

		;SZ+++---, SZ+++--C, SZ+++-+-, SZ+++-+C
	dc.b	%1100,%1101,%1100,%1101

		;SZ+++V--, SZ+++V-C, SZ+++V+-, SZ+++V+C
	dc.b	%1110,%1111,%1110,%1111

** -----

**	POP ii
**
**	ii [L] <- (SP), ii [H] <- (SP+1), SP <- SP + 2
**
**	Flags:	not affected

pop_ii		MACRO
Pop_I\1 	opcode_2_bytes
		getz	ZSP,Z80_\1L(TableB)	;get ii [L]
		incw	ZSP
		getz	ZSP,Z80_\1H(TableB)	;get ii [H]
		incw	ZSP
		skip 1
		next
		ENDM

	do_ii pop_ii

** -----

**	PUSH qq
**
**	(SP-1) <- qq [H], (SP-2) <- qq [L], SP <- SP - 2
**
**	Flags:	not affected

push_rr 	MACRO
Push_\1\2	decw	ZSP
		putz	Z80_\1(TableB),ZSP	;write qq [H]
		decw	ZSP
		putz	Z80_\2(TableB),ZSP,2	;(2nd use) write qq [L]
		next
		ENDM

	do_rr push_rr


Push_HL 	decw	ZSP
	IFNE PROCESSOR<68030
		move.w	HL,(Work)
		putz	(Work),ZSP	;write H
	ELSE
		getH	HL,tmpD1
		putz	tmpD1,ZSP	;write H (putz uses tmpD0)
	ENDC ;IFNE PROCESSOR<68030
		decw	ZSP
		putz	HL,ZSP,2	;(2nd use) write L
		next


**	PUSH AF notes:
**
**	Pushing the BCD flags is not conditionally compiled. They are
**	always written along with the other flags.
**	  The unused F register bits are not guaranteed to survive an
**	operation that affects any of the flags. It *is* guaranteed,
**	however, that a 'Pop AF' with a subsequent 'Push AF' and no
**	flag-affecting instructions there inbetween, will preserve all the
**	F register bits.

Push_AF 	decw	ZSP
		putz	A,ZSP		;write A
		decw	ZSP
		moveq	#$F,tmpD0
		and.w	stCCR,tmpD0	;bits 0-3 from stCCR, 4-15 cleared

		;map the CCR N,Z,V and C flags onto the Z80 F register
		move.b	CCR_to_F_table(PC,tmpD0.w),tmpD1

		moveq	#%00010010,tmpD0
		and.b	Z80_BCDF(TableB),tmpD0	;get H and N flags
		or.b	tmpD0,tmpD1		;and insert them

		moveq	#%00101000,tmpD0
		and.b	Z80_F(TableB),tmpD0	;get unused bits
		or.b	tmpD0,tmpD1		;and insert them

		putz	tmpD1,ZSP,2	;push F (2nd use, putz uses tmpD0)
		next


CCR_to_F_table

	;680x0 NZVC to Z80 SZ---V-C translation table:
	;680x0 N -> Z80 S.

		;----, ---C, --V-, --VC
	dc.b	%00000000,%00000001,%00000100,%00000101

		;-Z--, -Z-C, -ZV-, -ZVC
	dc.b	%01000000,%01000001,%01000100,%01000101

		;N---, N--C, N-V-, N-VC
	dc.b	%10000000,%10000001,%10000100,%10000101

		;NZ--, NZ-C, NZV-, NZVC
	dc.b	%11000000,%11000001,%11000100,%11000101

** -----

**	PUSH ii
**
**	(SP-1) <- ii [H], (SP-2) <- ii [L], SP <- SP - 2
**
**	Flags:	not affected

push_ii 	MACRO
Push_I\1	opcode_2_bytes
		decw	ZSP
		putz	Z80_\1H(TableB),ZSP	;write ii [H]
		decw	ZSP
		putz	Z80_\1L(TableB),ZSP,2	;(2nd use) write ii [L]
		skip 1
		next
		ENDM

	do_ii push_ii

** -----

**	RES b,m
**
**	m[b] <- 0
**
**	m can be r, (HL) or (ii+d)
**
**	Flags:	not affected

** Note: the actual routines are in 'distant.a'.

res_b_r 	MACRO
Res_\1_\2	bra	d_Res_\1_\2
		ENDM


res_b_H 	MACRO
Res_\1_H	bra	d_Res_\1_H
		ENDM


res_b_L 	MACRO
Res_\1_L	bra	d_Res_\1_L
		ENDM


res_b_A 	MACRO
Res_\1_A	bra	d_Res_\1_A
		ENDM


res_b_1HL1	MACRO
Res_\1_1HL1	bra	d_Res_\1_1HL1
		ENDM


res_b_1ii1	MACRO
Res_\1_1I\2_d1	bra	d_Res_\1_1I\2_d1
		ENDM


res_b		MACRO
	res_b_r \1,B
	res_b_r \1,C
	res_b_r \1,D
	res_b_r \1,E
	res_b_H \1
	res_b_L \1
	res_b_A \1
	res_b_1HL1 \1
	res_b_1ii1 \1,X
	res_b_1ii1 \1,Y
		ENDM

	res_b 0
	res_b 1
	res_b 2
	res_b 3
	res_b 4
	res_b 5
	res_b 6
	res_b 7

** -----

**	RET
**
**	PC [L] <- (SP), PC [H] <- (SP+1), SP <- SP + 2
**
**	Flags:	not affected

Ret		getz	ZSP,tmpD1	;get PC [L]
		incw	ZSP
	IFNE PROCESSOR<68030
		getz	ZSP,(Work)
		move.w	(Work),tmpD0	;get PC [H]
	ELSE
		getz	ZSP,tmpD0
		lsl.w	#8,tmpD0	;get PC [H]
	ENDC ;IFNE PROCESSOR<68030
		move.b	tmpD1,tmpD0	;make complete address
		incw	ZSP
		makePPC tmpD0
		testreq 	;handle exception or thread to next

** -----

**	RET cc
**
**	If cc true:	PC [L] <- (SP), PC [H] <- (SP+1), SP <- SP + 2
**
**	Flags:	not affected

ret_cc		MACRO
Ret_\1		move	stCCR,CCR
		b\2.s	.true

		next

.true		getz	ZSP,tmpD1	;get PC [L]
		incw	ZSP
	IFNE PROCESSOR<68030
		getz	ZSP,(Work)
		move.w	(Work),tmpD0	;get PC [H]
	ELSE
		getz	ZSP,tmpD0
		lsl.w	#8,tmpD0	;get PC [H]
	ENDC ;IFNE PROCESSOR<68030
		move.b	tmpD1,tmpD0	;make complete address
		incw	ZSP
		makePPC tmpD0
		testreq 	;handle exception or thread to next
		ENDM

	ret_cc NZ,ne
	ret_cc	Z,eq
	ret_cc NC,cc
	ret_cc	C,cs
	ret_cc PO,vc
	ret_cc PE,vs
	ret_cc	P,pl
	ret_cc	M,mi

** -----

**	RETI
**
**	PC [L] <- (SP), PC [H] <- (SP+1), SP <- SP + 2
**
**	Flags:	not affected
**
**	Note: The RETI instruction does not in itself cause any
**	signalling, but a common scheme is to have interrupt-controlling
**	hardware snoop the bus to see when an interrupt finishes.

**	RETI is in 'impldept.a'.

** -----

**	RETN
**
**	PC [L] <- (SP), PC [H] <- (SP+1), SP <- SP + 2, IFF1 <- IFF2
**
**	Flags:	not affected

Retn		opcode_2_bytes
		move.b	Z80_IFF(TableB),tmpD0
		;Note that the arithmetic shift preserves IFF2 (bit 7)
		asr.b	#1,tmpD0	;IFF2 -> IFF1 -> bit 5 (discarded)
		move.b	tmpD0,Z80_IFF(TableB)

		getz	ZSP,tmpD1	;get PC [L]
		incw	ZSP
	IFNE PROCESSOR<68030
		getz	ZSP,(Work)
		move.w	(Work),tmpD0	;get PC [H]
	ELSE
		getz	ZSP,tmpD0
		lsl.w	#8,tmpD0	;get PC [H]
	ENDC ;IFNE PROCESSOR<68030
		move.b	tmpD1,tmpD0	;make complete address
		incw	ZSP
		makePPC tmpD0
		testreq 	;handle exception or thread to next

** -----

**	RL m
**	 __________________________
**	|			   |
**	 - C <- m[7] <- ... m[0] <-
**
**	m is rotated left one bit position, the previous value of Carry
**	rotated into bit 0 of m and bit 7 of m rotated out to Carry.
**
**	m can be r, (HL) or (ii+d)
**
**	Flags:	S Z H P N C
**		* * 0 * 0 *

rl_r		MACRO
Rl_\1		opcode_2_bytes
		clr.w	tmpD0		;bits 8-15 reset for parity index
		move.b	Z80_\1(TableB),tmpD0
		lsr.w	#1,stCCR	;Z80 C to X
		roxl.b	#1,tmpD0	;S and Z tested, V cleared
		putccr	stCCR
		parity	tmpD0
		move.b	tmpD0,Z80_\1(TableB)
	IFD BCDFLAGS
		clr.b	Z80_BCDF(TableB)	;clear H and N
	ENDC
		skip 1
		next
		ENDM

	do_r rl_r


Rl_H		opcode_2_bytes
	IFNE PROCESSOR<68030
		clr.w	tmpD0
		move.w	HL,(Work)
		move.b	(Work),tmpD0
	ELSE
		move.l	HL,tmpD0
		lsr.w	#8,tmpD0	;bits 8-15 are reset
	ENDC ;IFNE PROCESSOR<68030
		lsr.w	#1,stCCR
		roxl.b	#1,tmpD0
		putccr	stCCR
		parity	tmpD0
	IFNE PROCESSOR<68030
		move.b	tmpD0,(Work)	;note that L is still in (Work+1)
		move.w	(Work),HL
	ELSE
		lsl.w	#8,tmpD0
		move.b	HL,tmpD0
		move.l	tmpD0,HL
	ENDC ;IFNE PROCESSOR<68030
	IFD BCDFLAGS
		clr.b	Z80_BCDF(TableB)	;clear H and N
	ENDC
		skip 1
		next


Rl_L		opcode_2_bytes
		clr.w	tmpD0
		move.b	HL,tmpD0	;extract L
		lsr.w	#1,stCCR
		roxl.b	#1,tmpD0
		putccr	stCCR
		parity	tmpD0
		move.b	tmpD0,HL	;restore L
	IFD BCDFLAGS
		clr.b	Z80_BCDF(TableB)	;clear H and N
	ENDC
		skip 1
		next


Rl_A		opcode_2_bytes
		lsr.w	#1,stCCR
		roxl.b	#1,A
		putccr	stCCR
		parity	A
	IFD BCDFLAGS
		clr.b	Z80_BCDF(TableB)	;clear H and N
	ENDC
		skip 1
		next


Rl_1HL1 	opcode_2_bytes
		clr.w	tmpD1
		getz	HL,tmpD1
		lsr.w	#1,stCCR
		roxl.b	#1,tmpD1
		putccr	stCCR
		parity	tmpD1
		putz	tmpD1,HL	;(putz uses tmpD0)
	IFD BCDFLAGS
		clr.b	Z80_BCDF(TableB)	;clear H and N
	ENDC
		skip 1
		next


rl_1ii1 	MACRO
Rl_1I\1_d1	opcode_3_bytes
		index	I\1,tmpD2
		clr.w	tmpD1
		getz	tmpD2,tmpD1
		lsr.w	#1,stCCR
		roxl.b	#1,tmpD1
		putccr	stCCR
		parity	tmpD1
		putz	tmpD1,tmpD2	;(putz uses tmpD0)
	IFD BCDFLAGS
		clr.b	Z80_BCDF(TableB)	;clear H and N
	ENDC
		skip 3
		next
		ENDM

	do_ii rl_1ii1

** -----

**	RLA
**	 __________________________
**	|			   |
**	 - C <- A[7] <- ... A[0] <-
**
**	A is rotated left one bit position, the previous value of Carry
**	rotated into bit 0 of A and bit 7 of A rotated out to Carry.
**
**	Flags:	S Z H V N C
**		- - 0 - 0 *

Rla		lsr.w	#1,stCCR	;Z80 C to X (other flags displaced)
		roxl.b	#1,A		;bit 7 of A to X and C
		addx.w	stCCR,stCCR	;X to Z80 C (other flags restored)
	IFD BCDFLAGS
		clr.b	Z80_BCDF(TableB)	;clear H and N
	ENDC
		next

** -----

**	RLC m
**	     _____________________
**	    |			  |
**	C <--- m[7] <- ... m[0] <-
**
**	m is rotated left one bit position, bit 7 of m rotated into bit 0
**	and to Carry.
**
**	m can be r, (HL) or (ii+d)
**
**	Flags:	S Z H P N C
**		* * 0 * 0 *

rlc_r		MACRO
Rlc_\1		opcode_2_bytes
		clr.w	tmpD0		;bits 8-15 reset for parity index
		move.b	Z80_\1(TableB),tmpD0
		rol.b	#1,tmpD0	;S and Z tested, V cleared
		putccr	stCCR
		parity	tmpD0
		move.b	tmpD0,Z80_\1(TableB)
	IFD BCDFLAGS
		clr.b	Z80_BCDF(TableB)	;clear H and N
	ENDC
		skip 1
		next
		ENDM

	do_r rlc_r


Rlc_H		opcode_2_bytes
	IFNE PROCESSOR<68030
		clr.w	tmpD0
		move.w	HL,(Work)
		move.b	(Work),tmpD0
	ELSE
		move.l	HL,tmpD0
		lsr.w	#8,tmpD0	;bits 8-15 are reset
	ENDC ;IFNE PROCESSOR<68030
		rol.b	#1,tmpD0
		putccr	stCCR
		parity	tmpD0
	IFNE PROCESSOR<68030
		move.b	tmpD0,(Work)	;note that L is still in (Work+1)
		move.w	(Work),HL
	ELSE
		lsl.w	#8,tmpD0
		move.b	HL,tmpD0
		move.l	tmpD0,HL
	ENDC ;IFNE PROCESSOR<68030
	IFD BCDFLAGS
		clr.b	Z80_BCDF(TableB)	;clear H and N
	ENDC
		skip 1
		next


Rlc_L		opcode_2_bytes
		clr.w	tmpD0
		move.b	HL,tmpD0	;extract L
		rol.b	#1,tmpD0
		putccr	stCCR
		parity	tmpD0
		move.b	tmpD0,HL	;restore L
	IFD BCDFLAGS
		clr.b	Z80_BCDF(TableB)	;clear H and N
	ENDC
		skip 1
		next


Rlc_A		opcode_2_bytes
		rol.b	#1,A
		putccr	stCCR
		parity	A
	IFD BCDFLAGS
		clr.b	Z80_BCDF(TableB)	;clear H and N
	ENDC
		skip 1
		next


Rlc_1HL1	opcode_2_bytes
		clr.w	tmpD1
		getz	HL,tmpD1
		rol.b	#1,tmpD1
		putccr	stCCR
		parity	tmpD1
		putz	tmpD1,HL	;(putz uses tmpD0)
	IFD BCDFLAGS
		clr.b	Z80_BCDF(TableB)	;clear H and N
	ENDC
		skip 1
		next


rlc_1ii1	MACRO
Rlc_1I\1_d1	opcode_3_bytes
		index	I\1,tmpD2
		clr.w	tmpD1
		getz	tmpD2,tmpD1
		rol.b	#1,tmpD1
		putccr	stCCR
		parity	tmpD1
		putz	tmpD1,tmpD2	;(putz uses tmpD0)
	IFD BCDFLAGS
		clr.b	Z80_BCDF(TableB)	;clear H and N
	ENDC
		skip 3
		next
		ENDM

	do_ii rlc_1ii1

** -----

**	RLCA
**	     _____________________
**	    |			  |
**	C <--- m[7] <- ... m[0] <-
**
**	A is rotated left one bit position, bit 7 of A rotated into bit 0
**	and to Carry.
**
**	Flags:	S Z H V N C
**		- - 0 - 0 *

Rlca		and.w	#$FFFE,stCCR	;clear C
		rol.b	#1,A
		bcc.s	.cc
		or.w	#1,stCCR	;set C according to result
.cc
	IFD BCDFLAGS
		clr.b	Z80_BCDF(TableB)	;clear H and N
	ENDC
		next

** -----

**	RLD
**	 _____________________________________
**	|				      |
**	 - A[3-0] <- (HL)[7-4] <- (HL)[3-0] <-
**
**	The high nybble (bits 4-7) of (HL) is moved to the low nybble
**	(bits 0-3) of A. The low nybble of (HL) is moved to the high
**	nybble, and the previous contents of the low nybble of A is
**	moved to the low nybble of (HL). The high nybble of A is not
**	affected. All substitutions are simultaneous.
**
**	Flags:	S Z H P N C
**		* * 0 * 0 -

** Note: I have assumed that the Sign, Zero and Parity flags indicate the
** status of the ackumulator. I have not found any documentation on this.

Rld		opcode_2_bytes
		getz	HL,tmpD0
		rol.b	#4,tmpD0	;(HL), nybbles swapped, in tmpD0
		move.l	tmpD0,tmpD1	;make a copy in tmpD1
		eor.b	A,tmpD1 	;insert low nybble of A in tmpD1
		and.w	#$F0,tmpD1
		eor.b	A,tmpD1
		eor.b	tmpD0,A 	;insert low nybble of tmpD0 in A
		and.w	#$F0,A
		eor.b	tmpD0,A 	;N and Z tested, V and C cleared
		putccr	tmpD0
		and.w	#1,stCCR	;keep old C
		or.w	tmpD0,stCCR	;insert the other flags
		parity	A		;set V according to parity
		putz	tmpD1,HL	;write tmpD1 to (HL) (uses tmpD0)
	IFD BCDFLAGS
		clr.b	Z80_BCDF(TableB)	;clear H and N
	ENDC
		skip 1
		next

** -----

**	RR m
**	 __________________________
**	|			   |
**	 -> m[7] ... -> m[0] -> C -
**
**	m is rotated right one bit position, the previous value of Carry
**	rotated into bit 7 of m and bit 0 of m rotated out to Carry.
**
**	m can be r, (HL) or (ii+d)
**
**	Flags:	S Z H P N C
**		* * 0 * 0 *

rr_r		MACRO
Rr_\1		opcode_2_bytes
		clr.w	tmpD0		;bits 8-15 reset for parity index
		move.b	Z80_\1(TableB),tmpD0
		lsr.w	#1,stCCR	;Z80 C to X
		roxr.b	#1,tmpD0	;S and Z tested, V cleared
		putccr	stCCR
		parity	tmpD0
		move.b	tmpD0,Z80_\1(TableB)
	IFD BCDFLAGS
		clr.b	Z80_BCDF(TableB)	;clear H and N
	ENDC
		skip 1
		next
		ENDM

	do_r rr_r


Rr_H		opcode_2_bytes
	IFNE PROCESSOR<68030
		clr.w	tmpD0
		move.w	HL,(Work)
		move.b	(Work),tmpD0
	ELSE
		move.l	HL,tmpD0
		lsr.w	#8,tmpD0	;bits 8-15 are reset
	ENDC ;IFNE PROCESSOR<68030
		lsr.w	#1,stCCR
		roxr.b	#1,tmpD0
		putccr	stCCR
		parity	tmpD0
	IFNE PROCESSOR<68030
		move.b	tmpD0,(Work)	;note that L is still in (Work+1)
		move.w	(Work),HL
	ELSE
		lsl.w	#8,tmpD0
		move.b	HL,tmpD0
		move.l	tmpD0,HL
	ENDC ;IFNE PROCESSOR<68030
	IFD BCDFLAGS
		clr.b	Z80_BCDF(TableB)	;clear H and N
	ENDC
		skip 1
		next


Rr_L		opcode_2_bytes
		clr.w	tmpD0
		move.b	HL,tmpD0	;extract L
		lsr.w	#1,stCCR
		roxr.b	#1,tmpD0
		putccr	stCCR
		parity	tmpD0
		move.b	tmpD0,HL	;restore L
	IFD BCDFLAGS
		clr.b	Z80_BCDF(TableB)	;clear H and N
	ENDC
		skip 1
		next


Rr_A		opcode_2_bytes
		lsr.w	#1,stCCR
		roxr.b	#1,A
		putccr	stCCR
		parity	A
	IFD BCDFLAGS
		clr.b	Z80_BCDF(TableB)	;clear H and N
	ENDC
		skip 1
		next


Rr_1HL1 	opcode_2_bytes
		clr.w	tmpD1
		getz	HL,tmpD1
		lsr.w	#1,stCCR
		roxr.b	#1,tmpD1
		putccr	stCCR
		parity	tmpD1
		putz	tmpD1,HL	;(putz uses tmpD0)
	IFD BCDFLAGS
		clr.b	Z80_BCDF(TableB)	;clear H and N
	ENDC
		skip 1
		next


rr_1ii1 	MACRO
Rr_1I\1_d1	opcode_3_bytes
		index	I\1,tmpD2
		clr.w	tmpD1
		getz	tmpD2,tmpD1
		lsr.w	#1,stCCR
		roxr.b	#1,tmpD1
		putccr	stCCR
		parity	tmpD1
		putz	tmpD1,tmpD2	;(putz uses tmpD0)
	IFD BCDFLAGS
		clr.b	Z80_BCDF(TableB)	;clear H and N
	ENDC
		skip 3
		next
		ENDM

	do_ii rr_1ii1

** -----

**	RRA
**	 __________________________
**	|			   |
**	 -> A[7] ... -> A[0] -> C -
**
**	A is rotated right one bit position, the previous value of Carry
**	rotated into bit 7 of A and bit 0 of A rotated out to Carry.
**
**	Flags:	S Z H V N C
**		- - 0 - 0 *

Rra		lsr.w	#1,stCCR	;Z80 C to X (other flags displaced)
		roxr.b	#1,A		;bit 0 of A to X and C
		addx.w	stCCR,stCCR	;X to Z80 C (other flags restored)
	IFD BCDFLAGS
		clr.b	Z80_BCDF(TableB)	;clear H and N
	ENDC
		next

** -----

**	RRC m
**	 _____________________
**	|		      |
**	 -> m[7] ... -> m[0] ---> C
**
**	m is rotated right one bit position, bit 0 of m rotated into bit 7
**	and to Carry.
**
**	m can be r, (HL) or (ii+d)
**
**	Flags:	S Z H P N C
**		* * 0 * 0 *

rrc_r		MACRO
Rrc_\1		opcode_2_bytes
		clr.w	tmpD0		;bits 8-15 reset for parity index
		move.b	Z80_\1(TableB),tmpD0
		ror.b	#1,tmpD0	;S and Z tested, V cleared
		putccr	stCCR
		parity	tmpD0
		move.b	tmpD0,Z80_\1(TableB)
	IFD BCDFLAGS
		clr.b	Z80_BCDF(TableB)	;clear H and N
	ENDC
		skip 1
		next
		ENDM

	do_r rrc_r


Rrc_H		opcode_2_bytes
	IFNE PROCESSOR<68030
		clr.w	tmpD0
		move.w	HL,(Work)
		move.b	(Work),tmpD0
	ELSE
		move.l	HL,tmpD0
		lsr.w	#8,tmpD0	;bits 8-15 are reset
	ENDC ;IFNE PROCESSOR<68030
		ror.b	#1,tmpD0
		putccr	stCCR
		parity	tmpD0
	IFNE PROCESSOR<68030
		move.b	tmpD0,(Work)	;note that L is still in (Work+1)
		move.w	(Work),HL
	ELSE
		lsl.w	#8,tmpD0
		move.b	HL,tmpD0
		move.l	tmpD0,HL
	ENDC ;IFNE PROCESSOR<68030
	IFD BCDFLAGS
		clr.b	Z80_BCDF(TableB)	;clear H and N
	ENDC
		skip 1
		next


Rrc_L		opcode_2_bytes
		clr.w	tmpD0
		move.b	HL,tmpD0	;extract L
		ror.b	#1,tmpD0
		putccr	stCCR
		parity	tmpD0
		move.b	tmpD0,HL	;restore L
	IFD BCDFLAGS
		clr.b	Z80_BCDF(TableB)	;clear H and N
	ENDC
		skip 1
		next


Rrc_A		opcode_2_bytes
		ror.b	#1,A
		putccr	stCCR
		parity	A
	IFD BCDFLAGS
		clr.b	Z80_BCDF(TableB)	;clear H and N
	ENDC
		skip 1
		next


Rrc_1HL1	opcode_2_bytes
		clr.w	tmpD1
		getz	HL,tmpD1
		ror.b	#1,tmpD1
		putccr	stCCR
		parity	tmpD1
		putz	tmpD1,HL	;(putz uses tmpD0)
	IFD BCDFLAGS
		clr.b	Z80_BCDF(TableB)	;clear H and N
	ENDC
		skip 1
		next


rrc_1ii1	MACRO
Rrc_1I\1_d1	opcode_3_bytes
		index	I\1,tmpD2
		clr.w	tmpD1
		getz	tmpD2,tmpD1
		ror.b	#1,tmpD1
		putccr	stCCR
		parity	tmpD1
		putz	tmpD1,tmpD2	;(putz uses tmpD0)
	IFD BCDFLAGS
		clr.b	Z80_BCDF(TableB)	;clear H and N
	ENDC
		skip 3
		next
		ENDM

	do_ii rrc_1ii1

** -----

**	RRCA
**	 _____________________
**	|		      |
**	 -> A[7] ... -> A[0] ---> C
**
**	A is rotated right one bit position, bit 0 of A rotated into bit 7
**	and to Carry.
**
**	Flags:	S Z H V N C
**		- - 0 - 0 *

Rrca		and.w	#$FFFE,stCCR	;clear C
		ror.b	#1,A
		bcc.s	.cc
		or.w	#1,stCCR	;set C according to result
.cc
	IFD BCDFLAGS
		clr.b	Z80_BCDF(TableB)	;clear H and N
	ENDC
		next

** -----

**	RRD
**	 _____________________________________
**	|				      |
**	 -> A[3-0] -> (HL)[7-4] -> (HL)[3-0] -
**
**	The low nybble (bits 0-3) of (HL) is moved to the low nybble
**	of A. The high nybble (bits 4-7) of (HL) is moved to the low
**	nybble, and the previous contents of the low nybble of A is
**	moved to the high nybble of (HL). The high nybble of A is not
**	affected. All substitutions are simultaneous.
**
**	Flags:	S Z H P N C
**		* * 0 * 0 -

** Note: I have assumed that the Sign, Zero and Parity flags indicate the
** status of the ackumulator. I have not found any documentation on this.

Rrd		opcode_2_bytes
		getz	HL,tmpD0	;(HL) in tmpD0
		move.l	tmpD0,tmpD1	;make a copy in tmpD1
		eor.b	A,tmpD1 	;insert low nybble of A in tmpD1
		and.w	#$F0,tmpD1
		eor.b	A,tmpD1
		eor.b	tmpD0,A 	;insert low nybble of tmpD0 in A
		and.w	#$F0,A
		eor.b	tmpD0,A 	;N and Z tested, V and C cleared
		putccr	tmpD0
		and.w	#1,stCCR	;keep old C
		or.w	tmpD0,stCCR	;insert the other flags
		parity	A		;set V according to parity
		rol.b	#4,tmpD1	;swap nybbles of tmpD1
		putz	tmpD1,HL	;write tmpD1 to (HL) (uses tmpD0)
	IFD BCDFLAGS
		clr.b	Z80_BCDF(TableB)	;clear H and N
	ENDC
		skip 1
		next

** -----

**	RST p
**
**	(SP-1) <- PC [H], (SP-2) <- PC [L], SP <- SP - 2,
**	PC [H] <- 0, PC [L] <- p
**
**	p is one of 0, 8, 16, 24, 32, 40, 48, and 56 (i.e. $00, $08, $10,
**	$18, $20, $28, $30 and $38)
**
**	Flags:	not affected

rst_p		MACRO
Rst_\1		getRPC	tmpD1		;get real-PC (after opcode)
		decw	ZSP
	IFNE PROCESSOR<68030
		move.w	tmpD1,(Work)
		putz	(Work),ZSP	;push PC-high (putz uses tmpD0)
	ELSE
		move.l	tmpD1,tmpD2
		lsr.w	#8,tmpD2
		putz	tmpD2,ZSP	;push PC-high (putz uses tmpD0)
	ENDC ;IFNE PROCESSOR<68030
		decw	ZSP
		putz	tmpD1,ZSP,2	;push PC-low (2nd use of putz)
		moveq	#\1,tmpD0
		makePPC tmpD0		;PC <- p
		testreq 	;handle exception or thread to next
		ENDM

	;We use decimal numbers because of the text substitution:
	rst_p	0
	rst_p	8
	rst_p	16
	rst_p	24
	rst_p	32
	rst_p	40
	rst_p	48
	rst_p	56

** -----

**	SBC A,s
**
**	A <- A - s - Carry
**
**	s can be r, n, (HL) or (ii+d)
**
**	Flags:	S Z H V N C
**		* * * * 1 *

sbc_A_r 	MACRO
Sbc_A_\1
	IFD BCDFLAGS
		moveq	#$F,tmpD0
		and.w	A,tmpD0 	;original low nybble of A in tmpD0

		move.b	Z80_\1(TableB),tmpD1
		lsr.w	#1,stCCR	;C to X
		ori	#4,CCR		;set Z
		subx.b	tmpD1,A ;Z reset if nonzero, unchanged if zero
		putccr	stCCR

		;Bits 4-7 of tmpD0 (and Carry) become set if H:
		and.w	#$F,tmpD1	;get low nybble of other operand
		sub.b	tmpD1,tmpD0	;subtract it from tmpD0
		moveq	#$F,tmpD1
		and.w	A,tmpD1 	;get low nybble of result
		sub.b	tmpD1,tmpD0	;subtract that too from tmpD0
		or.w	#2,tmpD0	;set the N flag
		move.b	tmpD0,Z80_BCDF(TableB)	;store BCD flags
	ELSE
		move.b	Z80_\1(TableB),tmpD1
		lsr.w	#1,stCCR	;C to X
		moveq	#0,tmpD0	;set Z
		subx.b	tmpD1,A ;Z reset if nonzero, unchanged if zero
		putccr	stCCR
	ENDC
		next
		ENDM

	do_r sbc_A_r


Sbc_A_H
	IFD BCDFLAGS
		moveq	#$F,tmpD0
		and.w	A,tmpD0

		getH	HL,tmpD1
		lsr.w	#1,stCCR
		ori	#4,CCR
		subx.b	tmpD1,A
		putccr	stCCR

		and.w	#$F,tmpD1
		sub.b	tmpD1,tmpD0
		moveq	#$F,tmpD1
		and.w	A,tmpD1
		sub.b	tmpD1,tmpD0
		or.w	#2,tmpD0
		move.b	tmpD0,Z80_BCDF(TableB)
	ELSE
		getH	HL,tmpD1
		lsr.w	#1,stCCR
		moveq	#0,tmpD0
		subx.b	tmpD1,A
		putccr	stCCR
	ENDC
		next


Sbc_A_L
	IFD BCDFLAGS
		moveq	#$F,tmpD0
		and.w	A,tmpD0

		lsr.w	#1,stCCR
		moveq	#0,tmpD1
		subx.b	HL,A	;only L is subtracted
		putccr	stCCR

		moveq	#$F,tmpD1
		and.w	HL,tmpD1	;extract low nybble of L
		sub.b	tmpD1,tmpD0
		moveq	#$F,tmpD1
		and.w	A,tmpD1
		sub.b	tmpD1,tmpD0
		or.w	#2,tmpD0
		move.b	tmpD0,Z80_BCDF(TableB)
	ELSE
		lsr.w	#1,stCCR
		moveq	#0,tmpD0
		subx.b	HL,A	;only L is subtracted
		putccr	stCCR
	ENDC
		next


Sbc_A_A
	IFD BCDFLAGS
		moveq	#$F,tmpD0
		and.w	A,tmpD0 	;keep original low nybble of A

		lsr.w	#1,stCCR
		moveq	#0,tmpD1
		subx.b	A,A
		putccr	stCCR

		sub.b	tmpD0,tmpD0	;subtract operand nybbles
		moveq	#$F,tmpD1
		and.w	A,tmpD1
		sub.b	tmpD1,tmpD0
		or.w	#2,tmpD0
		move.b	tmpD0,Z80_BCDF(TableB)
	ELSE
		lsr.w	#1,stCCR
		moveq	#0,tmpD0
		subx.b	A,A
		putccr	stCCR
	ENDC
		next


Sbc_A_n 	getRPC	tmpD0
		getz	tmpD0,tmpD1
	IFD BCDFLAGS
		moveq	#$F,tmpD0
		and.w	A,tmpD0

		lsr.w	#1,stCCR
		ori	#4,CCR
		subx.b	tmpD1,A
		putccr	stCCR

		and.w	#$F,tmpD1
		sub.b	tmpD1,tmpD0
		moveq	#$F,tmpD1
		and.w	A,tmpD1
		sub.b	tmpD1,tmpD0
		or.w	#2,tmpD0
		move.b	tmpD0,Z80_BCDF(TableB)
	ELSE
		lsr.w	#1,stCCR
		moveq	#0,tmpD0
		subx.b	tmpD1,A
		putccr	stCCR
	ENDC
		skip 1
		next


Sbc_A_1HL1	getz	HL,tmpD1
	IFD BCDFLAGS
		moveq	#$F,tmpD0
		and.w	A,tmpD0

		lsr.w	#1,stCCR
		ori	#4,CCR
		subx.b	tmpD1,A
		putccr	stCCR

		and.w	#$F,tmpD1
		sub.b	tmpD1,tmpD0
		moveq	#$F,tmpD1
		and.w	A,tmpD1
		sub.b	tmpD1,tmpD0
		or.w	#2,tmpD0
		move.b	tmpD0,Z80_BCDF(TableB)
	ELSE
		lsr.w	#1,stCCR
		moveq	#0,tmpD0
		subx.b	tmpD1,A
		putccr	stCCR
	ENDC
		next


sbc_A_1ii1	MACRO
Sbc_A_1I\1_d1	opcode_2_bytes
		index	I\1,tmpD0
		getz	tmpD0,tmpD1
	IFD BCDFLAGS
		moveq	#$F,tmpD0
		and.w	A,tmpD0

		lsr.w	#1,stCCR
		ori	#4,CCR
		subx.b	tmpD1,A
		putccr	stCCR

		and.w	#$F,tmpD1
		sub.b	tmpD1,tmpD0
		moveq	#$F,tmpD1
		and.w	A,tmpD1
		sub.b	tmpD1,tmpD0
		or.w	#2,tmpD0
		move.b	tmpD0,Z80_BCDF(TableB)
	ELSE
		lsr.w	#1,stCCR
		moveq	#0,tmpD0
		subx.b	tmpD1,A
		putccr	stCCR
	ENDC
		skip 2
		next
		ENDM

	do_ii sbc_A_1ii1

** -----

**	SBC HL,rr
**
**	HL <- HL - rr - Carry
**
**	Flags:	S Z H V N C
**		* * + * 1 *	(H set by borrow from bit 12)

sbc_HL_rr	MACRO
Sbc_HL_\1\2	opcode_2_bytes
		move.w	Z80_\1\2(TableB),tmpD1
	IFD BCDFLAGS
		move.w	#$FFF,tmpD0
		and.w	HL,tmpD0	;get original HL minus high nybble

		lsr.w	#1,stCCR	;C to X
		ori	#4,CCR		;set Z
		subx.w	tmpD1,HL ;Z reset if nonzero, unchanged if zero
		putccr	stCCR

		;Bits 12-15 of tmpD0 (and Carry) become set if H:
		and.w	#$FFF,tmpD1	;get other operand minus high nybble
		sub.w	tmpD1,tmpD0	;subtract from tmpD0
		move.w	#$FFF,tmpD1
		and.w	HL,tmpD1	;get result minus high nybble
		sub.w	tmpD1,tmpD0	;subtract that too from tmpD0
	IFNE PROCESSOR<68030
		move.w	tmpD0,(Work)
		move.b	(Work),tmpD0
	ELSE
		lsr.w	#8,tmpD0
	ENDC ;IFNE PROCESSOR<68030
		or.w	#2,tmpD0	;set the N flag
		move.b	tmpD0,Z80_BCDF(TableB)	;store BCD flags
	ELSE
		lsr.w	#1,stCCR
		moveq	#0,tmpD0
		subx.w	tmpD1,HL
		putccr	stCCR
	ENDC ;IFD BCDFLAGS
		skip 1
		next
		ENDM

	do_rr sbc_HL_rr


Sbc_HL_HL	opcode_2_bytes
	IFD BCDFLAGS
		move.w	#$FFF,tmpD0
		and.w	HL,tmpD0

		lsr.w	#1,stCCR
		moveq	#0,tmpD1
		subx.w	HL,HL
		putccr	stCCR

		sub.w	tmpD0,tmpD0	;subtract operand lower nybbles
		move.w	#$FFF,tmpD1
		and.w	HL,tmpD1
		sub.w	tmpD1,tmpD0
	IFNE PROCESSOR<68030
		move.w	tmpD0,(Work)
		move.b	(Work),tmpD0
	ELSE
		lsr.w	#8,tmpD0
	ENDC ;IFNE PROCESSOR<68030
		or.w	#2,tmpD0
		move.b	tmpD0,Z80_BCDF(TableB)
	ELSE
		lsr.w	#1,stCCR
		moveq	#0,tmpD0
		subx.w	HL,HL
		putccr	stCCR
	ENDC ;IFD BCDFLAGS
		skip 1
		next


Sbc_HL_SP	opcode_2_bytes
	IFD BCDFLAGS
		move.w	#$FFF,tmpD0
		and.w	HL,tmpD0

		lsr.w	#1,stCCR
		ori	#4,CCR
		subx.w	ZSP,HL
		putccr	stCCR

		move.w	#$FFF,tmpD1
		and.w	ZSP,tmpD1
		sub.w	tmpD1,tmpD0
		move.w	#$FFF,tmpD1
		and.w	HL,tmpD1
		sub.w	tmpD1,tmpD0
	IFNE PROCESSOR<68030
		move.w	tmpD0,(Work)
		move.b	(Work),tmpD0
	ELSE
		lsr.w	#8,tmpD0
	ENDC ;IFNE PROCESSOR<68030
		or.w	#2,tmpD0
		move.b	tmpD0,Z80_BCDF(TableB)
	ELSE
		lsr.w	#1,stCCR
		moveq	#0,tmpD0
		subx.w	ZSP,HL
		putccr	stCCR
	ENDC ;IFD BCDFLAGS
		skip 1
		next

** -----

**	SCF
**
**	C <- 1
**
**	Flags:	S Z H V N C
**		- - ? - 0 1

** Note that H is unaffected in this implementation.

Scf		or.w	#1,stCCR	;set C
	IFD BCDFLAGS
		bclr	#1,Z80_BCDF(TableB)	;clear N
	ENDC
		next

** -----

**	SET b,m
**
**	m[b] <- 1
**
**	m can be r, (HL) or (ii+d)
**
**	Flags:	not affected

** Note: the actual routines are in 'distant.a'.

set_b_r 	MACRO
Set_\1_\2	bra	d_Set_\1_\2
		ENDM


set_b_H 	MACRO
Set_\1_H	bra	d_Set_\1_H
		ENDM


set_b_L 	MACRO
Set_\1_L	bra	d_Set_\1_L
		ENDM


set_b_A 	MACRO
Set_\1_A	bra	d_Set_\1_A
		ENDM


set_b_1HL1	MACRO
Set_\1_1HL1	bra	d_Set_\1_1HL1
		ENDM


set_b_1ii1	MACRO
Set_\1_1I\2_d1	bra	d_Set_\1_1I\2_d1
		ENDM


set_b		MACRO
	set_b_r \1,B
	set_b_r \1,C
	set_b_r \1,D
	set_b_r \1,E
	set_b_H \1
	set_b_L \1
	set_b_A \1
	set_b_1HL1 \1
	set_b_1ii1 \1,X
	set_b_1ii1 \1,Y
		ENDM

	set_b 0
	set_b 1
	set_b 2
	set_b 3
	set_b 4
	set_b 5
	set_b 6
	set_b 7

** -----

**	SLA m
**
**	C <- m[7] <- ... m[0] <- 0
**
**	m is shifted left one bit position, a zero shifted into bit 0
**	and bit 7 shifted out to Carry. (Arithmetic/logical shift.)
**
**	m can be r, (HL) or (ii+d)
**
**	Flags:	S Z H P N C
**		* * 0 * 0 *

** Note: for the 680x0 arithmetic shift instructions, the V flag is
** set if the sign bit of the operand changes at any time during the
** operation, and cleared otherwise. For the logical shifts, V is always
** cleared. For this reason, Z80 'Sla' uses 680x0 'LSL'.

sla_r 		MACRO
Sla_\1		opcode_2_bytes
		clr.w	tmpD0		;bits 8-15 reset for parity index
		move.b	Z80_\1(TableB),tmpD0
		lsl.b	#1,tmpD0	;S and Z tested, V cleared
		putccr	stCCR
		parity	tmpD0
		move.b	tmpD0,Z80_\1(TableB)
	IFD BCDFLAGS
		clr.b	Z80_BCDF(TableB)	;clear H and N
	ENDC
		skip 1
		next
		ENDM

	do_r sla_r


Sla_H 		opcode_2_bytes
	IFNE PROCESSOR<68030
		clr.w	tmpD0
		move.w	HL,(Work)
		move.b	(Work),tmpD0
	ELSE
		move.l	HL,tmpD0
		lsr.w	#8,tmpD0	;bits 8-15 are reset
	ENDC ;IFNE PROCESSOR<68030
		lsl.b	#1,tmpD0
		putccr	stCCR
		parity	tmpD0
	IFNE PROCESSOR<68030
		move.b	tmpD0,(Work)	;note that L is still in (Work+1)
		move.w	(Work),HL
	ELSE
		lsl.w	#8,tmpD0
		move.b	HL,tmpD0
		move.l	tmpD0,HL
	ENDC ;IFNE PROCESSOR<68030
	IFD BCDFLAGS
		clr.b	Z80_BCDF(TableB)	;clear H and N
	ENDC
		skip 1
		next


Sla_L 		opcode_2_bytes
		clr.w	tmpD0
		move.b	HL,tmpD0	;extract L
		lsl.b	#1,tmpD0
		putccr	stCCR
		parity	tmpD0
		move.b	tmpD0,HL	;restore L
	IFD BCDFLAGS
		clr.b	Z80_BCDF(TableB)	;clear H and N
	ENDC
		skip 1
		next


Sla_A 		opcode_2_bytes
		lsl.b	#1,A
		putccr	stCCR
		parity	A
	IFD BCDFLAGS
		clr.b	Z80_BCDF(TableB)	;clear H and N
	ENDC
		skip 1
		next


Sla_1HL1	opcode_2_bytes
		clr.w	tmpD1
		getz	HL,tmpD1
		lsl.b	#1,tmpD1
		putccr	stCCR
		parity	tmpD1
		putz	tmpD1,HL	;(putz uses tmpD0)
	IFD BCDFLAGS
		clr.b	Z80_BCDF(TableB)	;clear H and N
	ENDC
		skip 1
		next


sla_1ii1	MACRO
Sla_1I\1_d1	opcode_3_bytes
		index	I\1,tmpD2
		clr.w	tmpD1
		getz	tmpD2,tmpD1
		lsl.b	#1,tmpD1
		putccr	stCCR
		parity	tmpD1
		putz	tmpD1,tmpD2	;(putz uses tmpD0)
	IFD BCDFLAGS
		clr.b	Z80_BCDF(TableB)	;clear H and N
	ENDC
		skip 3
		next
		ENDM

	do_ii sla_1ii1

** -----

**	SRA m
**
**	m[7] ... -> m[0] -> C
**
**	m is shifted right one bit position, bit 0 shifted out to
**	Carry while bit 7 remains unchanged. (Arithmetic shift.)
**
**	m can be r, (HL) or (ii+d)
**
**	Flags:	S Z H P N C
**		* * 0 * 0 *

** Note: for the 680x0 arithmetic shift instructions, the V flag is
** set if the sign bit of the operand changes at any time during the
** operation, and cleared otherwise. Since ASR preserves the sign bit,
** it always clears V.

sra_r 		MACRO
Sra_\1		opcode_2_bytes
		clr.w	tmpD0		;bits 8-15 reset for parity index
		move.b	Z80_\1(TableB),tmpD0
		asr.b	#1,tmpD0	;S and Z tested, V cleared
		putccr	stCCR
		parity	tmpD0
		move.b	tmpD0,Z80_\1(TableB)
	IFD BCDFLAGS
		clr.b	Z80_BCDF(TableB)	;clear H and N
	ENDC
		skip 1
		next
		ENDM

	do_r sra_r


Sra_H 		opcode_2_bytes
	IFNE PROCESSOR<68030
		clr.w	tmpD0
		move.w	HL,(Work)
		move.b	(Work),tmpD0
	ELSE
		move.l	HL,tmpD0
		lsr.w	#8,tmpD0	;bits 8-15 are reset
	ENDC ;IFNE PROCESSOR<68030
		asr.b	#1,tmpD0
		putccr	stCCR
		parity	tmpD0
	IFNE PROCESSOR<68030
		move.b	tmpD0,(Work)	;note that L is still in (Work+1)
		move.w	(Work),HL
	ELSE
		lsl.w	#8,tmpD0
		move.b	HL,tmpD0
		move.l	tmpD0,HL
	ENDC ;IFNE PROCESSOR<68030
	IFD BCDFLAGS
		clr.b	Z80_BCDF(TableB)	;clear H and N
	ENDC
		skip 1
		next


Sra_L 		opcode_2_bytes
		clr.w	tmpD0
		move.b	HL,tmpD0	;extract L
		asr.b	#1,tmpD0
		putccr	stCCR
		parity	tmpD0
		move.b	tmpD0,HL	;restore L
	IFD BCDFLAGS
		clr.b	Z80_BCDF(TableB)	;clear H and N
	ENDC
		skip 1
		next


Sra_A 		opcode_2_bytes
		asr.b	#1,A
		putccr	stCCR
		parity	A
	IFD BCDFLAGS
		clr.b	Z80_BCDF(TableB)	;clear H and N
	ENDC
		skip 1
		next


Sra_1HL1	opcode_2_bytes
		clr.w	tmpD1
		getz	HL,tmpD1
		asr.b	#1,tmpD1
		putccr	stCCR
		parity	tmpD1
		putz	tmpD1,HL	;(putz uses tmpD0)
	IFD BCDFLAGS
		clr.b	Z80_BCDF(TableB)	;clear H and N
	ENDC
		skip 1
		next


sra_1ii1	MACRO
Sra_1I\1_d1	opcode_3_bytes
		index	I\1,tmpD2
		clr.w	tmpD1
		getz	tmpD2,tmpD1
		asr.b	#1,tmpD1
		putccr	stCCR
		parity	tmpD1
		putz	tmpD1,tmpD2	;(putz uses tmpD0)
	IFD BCDFLAGS
		clr.b	Z80_BCDF(TableB)	;clear H and N
	ENDC
		skip 3
		next
		ENDM

	do_ii sra_1ii1

** -----

**	SRL m
**
**	0 -> m[7] ... -> m[0] -> C
**
**	m is shifted right one bit position, bit 0 shifted out to
**	Carry and a zero shifted into bit 7. (Logical shift.)
**
**	m can be r, (HL) or (ii+d)
**
**	Flags:	S Z H P N C
**		* * 0 * 0 *

srl_r 		MACRO
Srl_\1		opcode_2_bytes
		clr.w	tmpD0		;bits 8-15 reset for parity index
		move.b	Z80_\1(TableB),tmpD0
		lsr.b	#1,tmpD0	;S and Z tested, V cleared
		putccr	stCCR
		parity	tmpD0
		move.b	tmpD0,Z80_\1(TableB)
	IFD BCDFLAGS
		clr.b	Z80_BCDF(TableB)	;clear H and N
	ENDC
		skip 1
		next
		ENDM

	do_r srl_r


Srl_H 		opcode_2_bytes
	IFNE PROCESSOR<68030
		clr.w	tmpD0
		move.w	HL,(Work)
		move.b	(Work),tmpD0
	ELSE
		move.l	HL,tmpD0
		lsr.w	#8,tmpD0	;bits 8-15 are reset
	ENDC ;IFNE PROCESSOR<68030
		lsr.b	#1,tmpD0
		putccr	stCCR
		parity	tmpD0
	IFNE PROCESSOR<68030
		move.b	tmpD0,(Work)	;note that L is still in (Work+1)
		move.w	(Work),HL
	ELSE
		lsl.w	#8,tmpD0
		move.b	HL,tmpD0
		move.l	tmpD0,HL
	ENDC ;IFNE PROCESSOR<68030
	IFD BCDFLAGS
		clr.b	Z80_BCDF(TableB)	;clear H and N
	ENDC
		skip 1
		next


Srl_L 		opcode_2_bytes
		clr.w	tmpD0
		move.b	HL,tmpD0	;extract L
		lsr.b	#1,tmpD0
		putccr	stCCR
		parity	tmpD0
		move.b	tmpD0,HL	;restore L
	IFD BCDFLAGS
		clr.b	Z80_BCDF(TableB)	;clear H and N
	ENDC
		skip 1
		next


Srl_A 		opcode_2_bytes
		lsr.b	#1,A
		putccr	stCCR
		parity	A
	IFD BCDFLAGS
		clr.b	Z80_BCDF(TableB)	;clear H and N
	ENDC
		skip 1
		next


Srl_1HL1	opcode_2_bytes
		clr.w	tmpD1
		getz	HL,tmpD1
		lsr.b	#1,tmpD1
		putccr	stCCR
		parity	tmpD1
		putz	tmpD1,HL	;(putz uses tmpD0)
	IFD BCDFLAGS
		clr.b	Z80_BCDF(TableB)	;clear H and N
	ENDC
		skip 1
		next


srl_1ii1	MACRO
Srl_1I\1_d1	opcode_3_bytes
		index	I\1,tmpD2
		clr.w	tmpD1
		getz	tmpD2,tmpD1
		lsr.b	#1,tmpD1
		putccr	stCCR
		parity	tmpD1
		putz	tmpD1,tmpD2	;(putz uses tmpD0)
	IFD BCDFLAGS
		clr.b	Z80_BCDF(TableB)	;clear H and N
	ENDC
		skip 3
		next
		ENDM

	do_ii srl_1ii1

** -----

**	SUB s
**
**	A <- A - s
**
**	s can be r, n, (HL) or (ii+d)
**
**	Flags:	S Z H V N C
**		* * * * 1 *

sub_r		MACRO
Sub_\1	
	IFD BCDFLAGS
		move.b	Z80_\1(TableB),tmpD1
		sub.b	tmpD1,A
		putccr	stCCR
	;Bit 4 of tmpD0 becomes set if H:
		moveq	#$F,tmpD0
		and.w	tmpD0,tmpD1	;get low nybble of other operand
		and.w	A,tmpD0 	;get low nybble of result
		add.b	tmpD1,tmpD0	;add operand and result nybbles
		or.w	#2,tmpD0	;set N flag
		move.b	tmpD0,Z80_BCDF(TableB)	;store BCD flags
	ELSE
		sub.b	Z80_\1(TableB),A
		putccr	stCCR
	ENDC
		next
		ENDM

	do_r sub_r


Sub_H		getH	HL,tmpD1
		sub.b	tmpD1,A
		putccr	stCCR
	IFD BCDFLAGS
		moveq	#$F,tmpD0
		and.w	tmpD0,tmpD1
		and.w	A,tmpD0
		add.b	tmpD1,tmpD0
		or.w	#2,tmpD0
		move.b	tmpD0,Z80_BCDF(TableB)
	ENDC
		next


Sub_L		sub.b	HL,A	;only L is added
		putccr	stCCR
	IFD BCDFLAGS
		moveq	#$F,tmpD0
		move.l	HL,tmpD1
		and.w	tmpD0,tmpD1	;extract low nybble of L
		and.w	A,tmpD0
		add.b	tmpD1,tmpD0
		or.w	#2,tmpD0
		move.b	tmpD0,Z80_BCDF(TableB)
	ENDC
		next


Sub_A
	IFD BCDFLAGS
		move.l	A,tmpD1
		sub.b	A,A
		putccr	stCCR
		moveq	#$F,tmpD0
		and.w	tmpD0,tmpD1
		and.w	A,tmpD0
		add.b	tmpD1,tmpD0
		or.w	#2,tmpD0
		move.b	tmpD0,Z80_BCDF(TableB)
	ELSE
		sub.b	A,A
		putccr	stCCR
	ENDC
		next


Sub_n		getRPC	tmpD0
		getz	tmpD0,tmpD1
		sub.b	tmpD1,A
		putccr	stCCR
	IFD BCDFLAGS
		moveq	#$F,tmpD0
		and.w	tmpD0,tmpD1
		and.w	A,tmpD0
		add.b	tmpD1,tmpD0
		or.w	#2,tmpD0
		move.b	tmpD0,Z80_BCDF(TableB)
	ENDC
		skip 1
		next


Sub_1HL1	getz	HL,tmpD1
		sub.b	tmpD1,A
		putccr	stCCR
	IFD BCDFLAGS
		moveq	#$F,tmpD0
		and.w	tmpD0,tmpD1
		and.w	A,tmpD0
		add.b	tmpD1,tmpD0
		or.w	#2,tmpD0
		move.b	tmpD0,Z80_BCDF(TableB)
	ENDC
		next


sub_1ii1	MACRO
Sub_1I\1_d1	opcode_2_bytes
		index	I\1,tmpD0
		getz	tmpD0,tmpD1
		sub.b	tmpD1,A
		putccr	stCCR
	IFD BCDFLAGS
		moveq	#$F,tmpD0
		and.w	tmpD0,tmpD1
		and.w	A,tmpD0
		add.b	tmpD1,tmpD0
		or.w	#2,tmpD0
		move.b	tmpD0,Z80_BCDF(TableB)
	ENDC
		skip 2
		next
		ENDM

	do_ii sub_1ii1

** -----

**	XOR s
**
**	A <- (A \/ s) /\ NOT(A /\ s)
**
**	The bitwise logical exclusive-or of A and s is stored in A.
**
**	s can be r, n, (HL) or (ii+d)
**
**	Flags:	S Z H P N C
**		* * 0 * 0 0

xor_r		MACRO
Xor_\1		move.b	Z80_\1(TableB),tmpD0	;eor only from Dn
		eor.b	tmpD0,A ;V and C are cleared
		putccr	stCCR	;Sign and Zero depend on the result
		parity	A	;set V depending on parity of result
	IFD BCDFLAGS
		clr.b	Z80_BCDF(TableB)	;clear H and N
	ENDC
		next
		ENDM

	do_r xor_r


Xor_H		getH	HL,tmpD0
		eor.b	tmpD0,A
		putccr	stCCR
		parity	A
	IFD BCDFLAGS
		clr.b	Z80_BCDF(TableB)
	ENDC
		next


Xor_L		eor.b	HL,A	;only L is used
		putccr	stCCR
		parity	A
	IFD BCDFLAGS
		clr.b	Z80_BCDF(TableB)
	ENDC
		next


Xor_A		eor.b	A,A
		putccr	stCCR
		parity	A
	IFD BCDFLAGS
		clr.b	Z80_BCDF(TableB)
	ENDC
		next


Xor_n		getRPC	tmpD0
		getz	tmpD0,tmpD1
		eor.b	tmpD1,A
		putccr	stCCR
		parity	A
	IFD BCDFLAGS
		clr.b	Z80_BCDF(TableB)
	ENDC
		skip 1
		next


Xor_1HL1	getz	HL,tmpD0
		eor.b	tmpD0,A
		putccr	stCCR
		parity	A
	IFD BCDFLAGS
		clr.b	Z80_BCDF(TableB)
	ENDC
		next


xor_1ii1	MACRO
Xor_1I\1_d1	opcode_2_bytes
		index	I\1,tmpD0
		getz	tmpD0,tmpD1
		eor.b	tmpD1,A
		putccr	stCCR
		parity	A
	IFD BCDFLAGS
		clr.b	Z80_BCDF(TableB)
	ENDC
		skip 2
		next
		ENDM

	do_ii xor_1ii1

** =========================================================================

** Why stop now, just when I'm hating it?

