;-----------------------------------------------------------------------
;WinSTon 68000 effective address execution
;
;NOTE: Do not corrupt 'edx'(OpCode) or 'eax'(CCode) and 'ecx'(OpCode[]) in any of these routines
;Return 'bl','bx', or 'ebx' as value, and increment 'esi'(PC in memory space)
;Also take care when using pre decrement/post increment on A7 when address BYTEs as is seen as WORD length
;-----------------------------------------------------------------------

include code\68000asm\effaddr.inc

;-----------------------------------------------------------------------
;
;(d8,PC,Xn)
;
_readeffaddr_111_011 PROC NEAR
	movsx	ebx,WORD PTR IMM_WORD[esi]				;Immediate, RRRRw000dddddddd(d's in high byte, sign extented)

	mov		ebp,ebx									;Copy immediate
	shr		ebp,2
	and		ebp,03ch								;Offset register(*4)
	test	ebx,00008h								;Bit 11, 0-.W or 1-.L (NOTE - endian wrong way!)
	je		word_offset
	mov		ebp,_Regs[ebp]							;Xn.L
	jmp		got_offset
word_offset:
	movsx	ebp,WORD PTR _Regs[ebp]					;Xn.W signed extended
got_offset:

	add		ebp,esi									;PC - Will this over/underflow???
	sub		ebp,STRAM_OFFSET						;As ST address space
	add		esi,SIZE_WORD							;Inc Program Counter

	sar		ebx,8									;8-bit displacement signed offset
	add		ebp,ebx
	ret
_readeffaddr_111_011 ENDP

_effaddr_read_111_011_byte PROC NEAR
	call	_readeffaddr_111_011
	MASK_24BIT_ADDR(ebp)							;as 24-bit address in PC memory
	mov		bl,BYTE PTR _STRam[ebp]
	ret
_effaddr_read_111_011_byte ENDP

_effaddr_read_111_011_word PROC NEAR
	call	_readeffaddr_111_011
	MASK_24BIT_ADDR(ebp)							;as 24-bit address in PC memory
	mov		bx,WORD PTR _STRam[ebp]
	SWAP_ENDIAN_WORD_BX
	ret
_effaddr_read_111_011_word ENDP

_effaddr_read_111_011_long PROC NEAR
	call	_readeffaddr_111_011
	MASK_24BIT_ADDR(ebp)							;as 24-bit address in PC memory
	mov		ebx,DWORD PTR _STRam[ebp]
	SWAP_ENDIAN_LONG_EBX
	ret
_effaddr_read_111_011_long ENDP

_loadeffaddr_111_011 PROC NEAR
	call	_readeffaddr_111_011
	mov		ebx,ebp
	ret
_loadeffaddr_111_011 ENDP

;-----------------------------------------------------------------------
;
;(d16,PC)
;
_readeffaddr_111_010 PROC NEAR
	mov		bx,IMM_WORD[esi]						;Read immediate
	mov		ebp,esi									;Program Counter
	SWAP_ENDIAN_WORD_BX
	sub		ebp,STRAM_OFFSET						;As ST address space
	add		esi,SIZE_WORD							;Inc Program Counter
	movsx	ebx,bx									;d16 - signed offset

	add		ebp,ebx									;Add offset
	ret
_readeffaddr_111_010 ENDP

_effaddr_read_111_010_byte PROC NEAR
	call	_readeffaddr_111_010
	MASK_24BIT_ADDR(ebp)							;as 24-bit address in PC memory
	mov		bl,BYTE PTR _STRam[ebp]
	ret
_effaddr_read_111_010_byte ENDP

_effaddr_read_111_010_word PROC NEAR
	call	_readeffaddr_111_010
	MASK_24BIT_ADDR(ebp)							;as 24-bit address in PC memory
	mov		bx,WORD PTR _STRam[ebp]
	SWAP_ENDIAN_WORD_BX
	ret
_effaddr_read_111_010_word ENDP

_effaddr_read_111_010_long PROC NEAR
	call	_readeffaddr_111_010
	MASK_24BIT_ADDR(ebp)							;as 24-bit address in PC memory
	mov		ebx,DWORD PTR _STRam[ebp]
	SWAP_ENDIAN_LONG_EBX
	ret
_effaddr_read_111_010_long ENDP

_loadeffaddr_111_010 PROC NEAR
	call	_readeffaddr_111_010
	mov		ebx,ebp
	ret
_loadeffaddr_111_010 ENDP

;-----------------------------------------------------------------------
;
;#<data>
;
_effaddr_read_111_100_byte PROC NEAR
	mov		bl,IMM_BYTE[esi]						;Read immediate
	add		esi,SIZE_WORD							;Inc Program Counter
	ret
_effaddr_read_111_100_byte ENDP

_effaddr_read_111_100_word PROC NEAR
	mov		bx,IMM_WORD[esi]						;Read immediate
	add		esi,SIZE_WORD							;Inc Program Counter
	SWAP_ENDIAN_WORD_BX
	ret
_effaddr_read_111_100_word ENDP

_effaddr_read_111_100_long PROC NEAR
	mov		ebx,IMM_LONG[esi]						;Read immediate
	add		esi,SIZE_LONG							;Inc Program Counter
	SWAP_ENDIAN_LONG_EBX
	ret
_effaddr_read_111_100_long ENDP

;-----------------------------------------------------------------------
;
;(xxx).L
;
_effaddr_read_111_001_byte PROC NEAR
	mov		ebp,IMM_LONG[esi]						;Read immediate
	add		esi,SIZE_LONG				            ;Inc Program Counter
	bswap	ebp										;Swap endian on address register

	INTERCEPT_CHECK_ADDR_READBYTE					;Read 'bl' from 'ebp' and ret
_effaddr_read_111_001_byte ENDP

_effaddr_read_111_001_word PROC NEAR
	mov		ebp,IMM_LONG[esi]						;Read immediate
	add		esi,SIZE_LONG				            ;Inc Program Counter
	bswap	ebp										;Swap endian on address register

	INTERCEPT_CHECK_ADDR_READWORD					;Read 'bx' from 'ebp' and ret
_effaddr_read_111_001_word ENDP

_effaddr_read_111_001_long PROC NEAR
	mov		ebp,IMM_LONG[esi]						;Read immediate
	add		esi,SIZE_LONG				            ;Inc Program Counter
	bswap	ebp										;Swap endian on address register

	INTERCEPT_CHECK_ADDR_READLONG					;Read 'ebx' from 'ebp' and ret
_effaddr_read_111_001_long ENDP

_loadeffaddr_111_001 PROC NEAR
	mov		ebx,IMM_LONG[esi]						;Read immediate
	add		esi,SIZE_LONG				            ;Inc Program Counter
	bswap	ebx										;Swap endian on address register
	ret
_loadeffaddr_111_001 ENDP

;-----------------------------------------------------------------------
;
;(xxx).W
;
_effaddr_read_111_000_byte PROC NEAR
	mov		bx,IMM_WORD[esi]						;Read immediate
	add		esi,SIZE_WORD				            ;Inc Program Counter
	SWAP_ENDIAN_WORD_BX
	movsx	ebp,bx								    ;d16 - signed offset

	INTERCEPT_CHECK_ADDR_READBYTE					;Read 'bl' from 'ebp' and ret
_effaddr_read_111_000_byte ENDP

_effaddr_read_111_000_word PROC NEAR
	mov		bx,IMM_WORD[esi]						;Read immediate
	add		esi,SIZE_WORD				            ;Inc Program Counter
	SWAP_ENDIAN_WORD_BX
	movsx	ebp,bx								    ;d16 - signed offset

	INTERCEPT_CHECK_ADDR_READWORD					;Read 'bx' from 'ebp' and ret
_effaddr_read_111_000_word ENDP

_effaddr_read_111_000_long PROC NEAR
	mov		bx,IMM_WORD[esi]						;Read immediate
	add		esi,SIZE_WORD				            ;Inc Program Counter
	SWAP_ENDIAN_WORD_BX
	movsx	ebp,bx								    ;d16 - signed offset

	INTERCEPT_CHECK_ADDR_READLONG					;Read 'ebx' from 'ebp' and ret
_effaddr_read_111_000_long ENDP

_loadeffaddr_111_000 PROC NEAR
	mov		bx,IMM_WORD[esi]						;Read immediate
	add		esi,SIZE_WORD				            ;Inc Program Counter
	SWAP_ENDIAN_WORD_BX
	movsx	ebx,bx								    ;d16 - signed offset
	ret
_loadeffaddr_111_000 ENDP

;-----------------------------------------------------------------------
;
;(d8,An,Xn)
;
_readeffaddr_110 PROC NEAR
	movsx	ebx,WORD PTR IMM_WORD[esi]				;Immediate, RRRRw000dddddddd(d's in high byte, sign extented)
	mov		ebp,ebx									;Copy immediate
	shr		ebp,2
	and		ebp,03ch								;Offset register(*4)
	test	ebx,00008h								;Bit 11, 0-.W or 1-.L (NOTE - endian wrong way!)
	je		word_offset
	mov		ebp,_Regs[ebp]							;Xn.L
	jmp		got_offset
word_offset:
	movsx	ebp,WORD PTR _Regs[ebp]					;Xn.W signed extended
got_offset:

	mov		ebx,DECODE_1[ecx]						;An
	add		ebp,[ebx]								;Look up contents

	movsx	ebx,WORD PTR IMM_WORD[esi]				;Immediate, RRRRw000dddddddd(d's in high byte, sign extented)
	add		esi,SIZE_WORD                           ;Increase Program Counter
	sar		ebx,8									;8-bit displacement signed offset
	add		ebp,ebx
	ret
_readeffaddr_110 ENDP

_effaddr_read_110_byte PROC NEAR
	call	_readeffaddr_110
	INTERCEPT_CHECK_ADDR_READBYTE					;Read 'bl' from 'ebp' and ret
_effaddr_read_110_byte ENDP

_effaddr_read_110_word PROC NEAR
	call	_readeffaddr_110
	INTERCEPT_CHECK_ADDR_READWORD					;Read 'bx' from 'ebp' and ret
_effaddr_read_110_word ENDP

_effaddr_read_110_long PROC NEAR
	call	_readeffaddr_110
	INTERCEPT_CHECK_ADDR_READLONG					;Read 'ebx' from 'ebp' and ret
_effaddr_read_110_long ENDP

_loadeffaddr_110 PROC NEAR
	call	_readeffaddr_110
	mov		ebx,ebp
	ret
_loadeffaddr_110 ENDP

;-----------------------------------------------------------------------
;
;(d16,An)
;
_readeffaddr_101 PROC NEAR
	mov		bx,IMM_WORD[esi]						;Read immediate
	add		esi,SIZE_WORD							;Increase Program Counter
	SWAP_ENDIAN_WORD_BX
	movsx	ebx,bx									;d16 - signed offset
	mov		ebp,DECODE_1[ecx]						;Effective register
	mov		ebp,[ebp]								;Look up contents
	add		ebp,ebx									;Add offset
	ret
_readeffaddr_101 ENDP

_effaddr_read_101_byte PROC NEAR
	call	_readeffaddr_101
	INTERCEPT_CHECK_ADDR_READBYTE					;Read 'bl' from 'ebp' and ret
_effaddr_read_101_byte ENDP

_effaddr_read_101_word PROC NEAR
	call	_readeffaddr_101
	INTERCEPT_CHECK_ADDR_READWORD					;Read 'bx' from 'ebp' and ret
_effaddr_read_101_word ENDP

_effaddr_read_101_long PROC NEAR
	call	_readeffaddr_101
	INTERCEPT_CHECK_ADDR_READLONG					;Read 'ebx' from 'ebp' and ret
_effaddr_read_101_long ENDP

_loadeffaddr_101 PROC NEAR
	call	_readeffaddr_101
	mov		ebx,ebp
	ret
_loadeffaddr_101 ENDP

;-----------------------------------------------------------------------
;
;-(An)
;Note -(A7) decrements by a WORD - special case effective address
;
_effaddr_read_100_byte PROC NEAR
	mov		ebx,DECODE_1[ecx]						;Effective register
	sub		DWORD PTR [ebx],SIZE_BYTE
	mov		ebp,[ebx]								;Look up contents
	INTERCEPT_CHECK_ADDR_READBYTE					;Read 'bl' from 'ebp' and ret
_effaddr_read_100_byte ENDP

_effaddr_read_100_byte_A7 PROC NEAR
	sub		DWORD PTR _Regs[REG_A7*4],SIZE_WORD		;Decrement by WORD for A7
	mov		ebp,_Regs[REG_A7*4]						;Effective register
	INTERCEPT_CHECK_ADDR_READBYTE					;Read 'bl' from 'ebp' and ret
_effaddr_read_100_byte_A7 ENDP

_effaddr_read_100_word PROC NEAR
	mov		ebx,DECODE_1[ecx]						;Effective register
	sub		DWORD PTR [ebx],SIZE_WORD
	mov		ebp,[ebx]								;Look up contents
	INTERCEPT_CHECK_ADDR_READWORD					;Read 'bx' from 'ebp' and ret
_effaddr_read_100_word ENDP

_effaddr_read_100_long PROC NEAR
	mov		ebx,DECODE_1[ecx]						;Effective register
	sub		DWORD PTR [ebx],SIZE_LONG
	mov		ebp,[ebx]								;Look up contents
	INTERCEPT_CHECK_ADDR_READLONG					;Read 'ebx' from 'ebp' and ret
_effaddr_read_100_long ENDP

;-----------------------------------------------------------------------
;
;(An)+
;Note (A7)+ increments by a WORD - special case effective address
;
_effaddr_read_011_byte PROC NEAR
	mov		ebx,DECODE_1[ecx]						;Effective register
	mov		ebp,[ebx]								;Look up contents
	add		DWORD PTR [ebx],SIZE_BYTE
	INTERCEPT_CHECK_ADDR_READBYTE					;Read 'bl' from 'ebp' and ret
_effaddr_read_011_byte ENDP

_effaddr_read_011_byte_A7 PROC NEAR
	mov		ebp,_Regs[REG_A7*4]						;Effective register
	add		DWORD PTR _Regs[REG_A7*4],SIZE_WORD		;Increment by WORD for A7
	INTERCEPT_CHECK_ADDR_READBYTE					;Read 'bl' from 'ebp' and ret
_effaddr_read_011_byte_A7 ENDP

_effaddr_read_011_word PROC NEAR
	mov		ebx,DECODE_1[ecx]						;Effective register
	mov		ebp,[ebx]								;Look up contents
	add		DWORD PTR [ebx],SIZE_WORD
	INTERCEPT_CHECK_ADDR_READWORD					;Read 'bx' from 'ebp' and ret
_effaddr_read_011_word ENDP

_effaddr_read_011_long PROC NEAR
	mov		ebx,DECODE_1[ecx]						;Effective register
	mov		ebp,[ebx]								;Look up contents
	add		DWORD PTR [ebx],SIZE_LONG
	INTERCEPT_CHECK_ADDR_READLONG					;Read 'ebx' from 'ebp' and ret
_effaddr_read_011_long ENDP

;-----------------------------------------------------------------------
;
;(An)
;
_effaddr_read_010_byte PROC NEAR
	mov		ebx,DECODE_1[ecx]						;Effective register
	mov		ebp,[ebx]								;Look up contents
	INTERCEPT_CHECK_ADDR_READBYTE					;Read 'bl' from 'ebp' and ret
_effaddr_read_010_byte ENDP

_effaddr_read_010_word PROC NEAR
	mov		ebx,DECODE_1[ecx]						;Effective register
	mov		ebp,[ebx]								;Look up contents
	INTERCEPT_CHECK_ADDR_READWORD					;Read 'bx' from 'ebp' and ret
_effaddr_read_010_word ENDP

_effaddr_read_010_long PROC NEAR
	mov		ebx,DECODE_1[ecx]						;Effective register
	mov		ebp,[ebx]								;Look up contents
	INTERCEPT_CHECK_ADDR_READLONG					;Read 'ebx' from 'ebp' and ret
_effaddr_read_010_long ENDP

_loadeffaddr_010 PROC NEAR
	mov		ebx,DECODE_1[ecx]						;Effective register
	mov		ebx,[ebx]
	ret
_loadeffaddr_010 ENDP

;-----------------------------------------------------------------------
;
;An
;
_effaddr_read_001_A0 PROC NEAR
	mov		ebx,_Regs[REG_A0*4]
	ret
_effaddr_read_001_A0 ENDP

_effaddr_read_001_A1 PROC NEAR
	mov		ebx,_Regs[REG_A1*4]
	ret
_effaddr_read_001_A1 ENDP

_effaddr_read_001_A2 PROC NEAR
	mov		ebx,_Regs[REG_A2*4]
	ret
_effaddr_read_001_A2 ENDP

_effaddr_read_001_A3 PROC NEAR
	mov		ebx,_Regs[REG_A3*4]
	ret
_effaddr_read_001_A3 ENDP

_effaddr_read_001_A4 PROC NEAR
	mov		ebx,_Regs[REG_A4*4]
	ret
_effaddr_read_001_A4 ENDP

_effaddr_read_001_A5 PROC NEAR
	mov		ebx,_Regs[REG_A5*4]
	ret
_effaddr_read_001_A5 ENDP

_effaddr_read_001_A6 PROC NEAR
	mov		ebx,_Regs[REG_A6*4]
	ret
_effaddr_read_001_A6 ENDP

_effaddr_read_001_A7 PROC NEAR
	mov		ebx,_Regs[REG_A7*4]
	ret
_effaddr_read_001_A7 ENDP

;-----------------------------------------------------------------------
;
;Dn
;
_effaddr_read_000_D0 PROC NEAR
	mov		ebx,_Regs[REG_D0*4]
	ret
_effaddr_read_000_D0 ENDP

_effaddr_read_000_D1 PROC NEAR
	mov		ebx,_Regs[REG_D1*4]
	ret
_effaddr_read_000_D1 ENDP

_effaddr_read_000_D2 PROC NEAR
	mov		ebx,_Regs[REG_D2*4]
	ret
_effaddr_read_000_D2 ENDP

_effaddr_read_000_D3 PROC NEAR
	mov		ebx,_Regs[REG_D3*4]
	ret
_effaddr_read_000_D3 ENDP

_effaddr_read_000_D4 PROC NEAR
	mov		ebx,_Regs[REG_D4*4]
	ret
_effaddr_read_000_D4 ENDP

_effaddr_read_000_D5 PROC NEAR
	mov		ebx,_Regs[REG_D5*4]
	ret
_effaddr_read_000_D5 ENDP

_effaddr_read_000_D6 PROC NEAR
	mov		ebx,_Regs[REG_D6*4]
	ret
_effaddr_read_000_D6 ENDP

_effaddr_read_000_D7 PROC NEAR
	mov		ebx,_Regs[REG_D7*4]
	ret
_effaddr_read_000_D7 ENDP

