; *** Amoric. Oric Emulator V0.9 by JF FABRE copyright 1995

; *** Macro functions for CPU emulation

;***************************************************
;*************** MODES D'ADRESSAGE *****************
;***************************************************

;*** Le mode d'adressage immediat est programme directement pour optimiser

ZERO_PAGE: MACRO	
	moveq.l	#0,D6
	move.b	(A4)+,D6
	ENDM

ZERO_PAGE_X: MACRO
	ZERO_PAGE
	add.b	D2,D6		; +X sans changement de page quoi qu'il arrive
	ENDM
	
ZERO_PAGE_Y: MACRO
	ZERO_PAGE
	add.b	D3,D6		; +Y sans changement de page quoi qu'il arrive
	ENDM

ABSOLU: MACRO
	moveq.l	#0,D6
	move.b	(A4)+,D6
	lsl.w	#8,D6
	move.b	(A4)+,D6
	rol.w	#8,D6
	ENDM	
	
ABSOLU_X: MACRO
	ABSOLU
	add.w	D2,D6		; +X
	ENDM		

ABSOLU_Y: MACRO
	ABSOLU
	add.w	D3,D6		; +Y
	ENDM		

INDIRECT: MACRO		
	moveq.l	#0,D6
	moveq.l	#0,D7

	move.b	(A4)+,D7
	lsl.w	#8,D7
	move.b	(A4)+,D7
	rol.w	#8,D7

	move.b	$1(A0,D7.L),D6
	lsl.w	#8,D6
	move.b	(A0,D7.L),D6	
	ENDM
	
ZERO_PAGE_INDIRECT_X: MACRO
	moveq.l	#0,D6
	moveq.l	#0,D7
	move.b	(A4)+,D7
	add.w	D2,D7		; +X
	move.b	$1(A0,D7.L),D6
	lsl.w	#8,D6
	move.b	(A0,D7.L),D6	
	ENDM

ZERO_PAGE_INDIRECT_Y: MACRO
	moveq.l	#0,D6
	moveq.l	#0,D7
	move.b	(A4)+,D7
	move.b	$1(A0,D7.L),D6
	lsl.w	#8,D6
	move.b	(A0,D7.L),D6	
	add.w	D3,D6		; +Y	
	ENDM

	
BRANCH: MACRO
	btst	#\1,D4
	beq.b	BRANCH_NON\@
	moveq.l	#0,D6
	move.b	(A4),D6
	bmi.B	Reverse\@
	add.l	D6,A4
	addq.l	#1,A4
	GOOD_INST
Reverse\@: 
	eor.b	#$FF,D6
	sub.l	D6,A4
	GOOD_INST
BRANCH_NON\@: 
	addq.l	#1,A4
	GOOD_INST
	ENDM
	
DONT_BRANCH: MACRO
	btst	#\1,D4
	bne.b	DONT_BRANCH_NON\@
	moveq.l	#0,D6
	move.b	(A4),D6
	bmi.B	DONT_Reverse\@
	add.l	D6,A4
	addq.l	#1,A4
	GOOD_INST
DONT_Reverse\@:
	eor.b	#$FF,D6
	sub.l	D6,A4
	GOOD_INST
DONT_BRANCH_NON\@:
	addq.l	#1,A4
	GOOD_INST
	ENDM

CLEAR_BIT_P: MACRO
	bclr	#\1,D4
	GOOD_INST
	ENDM
			
SET_BIT_P: MACRO
	bset	#\1,D4
	GOOD_INST
	ENDM
			
MODESADD: MACRO
\1_ZRP		; *** PAGE ZERO ***
	ZERO_PAGE
	bra	\1
\1_ZRPX		; *** PAGE ZERO INDEXE X ***
	ZERO_PAGE_X
	bra	\1
\1_ZRPY		; *** PAGE ZERO INDEXE Y ***
	ZERO_PAGE_Y
	bra	\1
\1_ABS		; *** ABSOLU ***
	ABSOLU
	bra	\1
\1_ABSX		; *** ABSOLU INDEXE X ***
	ABSOLU_X
	bra	\1
\1_ABSY		; *** ABSOLU INDEXE Y ***
	ABSOLU_Y
	bra	\1
\1_INDX		; *** ZERO PAGE INDIRECT X ***
	ZERO_PAGE_INDIRECT_X
	bra	\1
\1_INDY		; *** ZERO PAGE INDIRECT Y ***
	ZERO_PAGE_INDIRECT_Y
	bra	\1
	ENDM

LDz:MACRO
	move.b	(A0,D6.L),\1
	TEST_NZ	\1
	GOOD_INST
	ENDM

LDz_IMM:MACRO
	move.b	(A4)+,\1
	TEST_NZ	\1
	GOOD_INST
	ENDM

STz:MACRO
	move.b	\1,D7
	jsr	@Place
	GOOD_INST
	ENDM

CPz:MACRO
	move.b	(A0,D6.L),D7
	cmp.b	\1,D7
	TEST_CMP
	GOOD_INST
	ENDM

CPz_IMM:MACRO
	move.b	(A4)+,D7
	cmp.b	\1,D7
	TEST_CMP
	GOOD_INST
	ENDM

Txy:MACRO
	move.b	\1,\2
	TEST_NZ
	GOOD_INST	
	ENDM

EMPILER: MACRO
	subq.b	#1,D5
	move.b	\1,1(A0,D5.L) ; il faut faire le move en dernier
	ENDM
		
DEPILER: MACRO
	addq.b	#1,D5
	move.b	(A0,D5.L),\1
	ENDM
	

SAVE_ADR:MACRO
	move.w	A4,D6
	subq.l	#1,D6
	sub.l	A0,D6
	move.w	D6,D0
	lsr.w	#8,D6
	EMPILER D6
	EMPILER D0
	ENDM

RESTORE_ADR:MACRO
	moveq.l	#0,D0
	DEPILER	D6
	DEPILER	D0					
	lsl.w	#8,D0
	move.b	D6,D0
	move.l	A0,A4
	add.l	D0,A4
	ENDM

BIT_MACRO:MACRO
	move.b	D1,D7
	and.b	D6,D7
	bne.b	BIT_NZERO\@
	SET_PB	Z_BIT
	bra.b	BIT_FIN\@
BIT_NZERO\@
	CLR_PB	Z_BIT	
BIT_FIN\@
	ANDI.B	#$3F,D4
	move.b	D6,D7
	ANDI.B	#$C0,D7		; Bits 6 et 7
	OR.B	D7,D4
	ENDM

ADC_MACRO:MACRO
	btst	#D_BIT,D4
	bne.w	ADCDecimal\@
ADCBinary\@:
	SET_XZ_ADC		; Prepare Z=1 et X en fonction de C de P
	addx.b	D7,D1
	TEST_NZCV
	GOOD_INST

ADCDecimal\@:
	SET_XZ_ADC
	ABCD.B	D7,D1
	TEST_NZCV	; en fait N est indefini
	CLR_PB	V_BIT
	GOOD_INST
	ENDM

SBC_MACRO:MACRO
	btst	#D_BIT,D4
	bne	SBCDecimal\@
	
	; *** Mode Binaire

SBCBinary\@:
	SET_XZ_SBC
	subx.b	D7,D1
	TEST_NZCV
	CHG_PB	C_BIT	; Inverser la retenue par rapport au 68000
	GOOD_INST

SBCDecimal\@:
	CHG_PB	C_BIT	; Inverser la retenue par rapport au 68000
	SET_XZ_SBC
	SBCD.B	D7,D1
	TEST_NZCV	; en fait N est indefini
	CLR_PB	V_BIT
	GOOD_INST
	ENDM

GET_WORD:MACRO
	move.l	A0,A4
	add.l	#\1,A4
	ABSOLU
	ENDM
	