;-----------------------------------------------------------------------
;WinSTon 68000 decoder, and emulation instructions
;-----------------------------------------------------------------------

;Defines

;Bool
TRUE	equ	1
FALSE	equ	0

;68000 Register defines
REG_D0					equ	0
REG_D1					equ	1
REG_D2					equ	2
REG_D3					equ	3
REG_D4					equ	4
REG_D5					equ	5
REG_D6					equ	6
REG_D7					equ	7
REG_A0					equ	8
REG_A1					equ	9
REG_A2					equ	10
REG_A3					equ	11
REG_A4					equ	12
REG_A5					equ	13
REG_A6					equ	14
REG_A7					equ	15				;A7(also referenced as SP)
REG_A8					equ	16				;User/Super Stack Pointer

;Sizes of integers
SIZE_BYTE				equ	1
SIZE_WORD				equ	2
SIZE_LONG				equ	4

;Offsets from memory space program counter to immediate data(in wrong endian)
IMM_BYTE				equ	1				;Byte offset 
IMM_WORD				equ	0
IMM_LONG				equ	0

;PC Condition code's
PC_CARRY				equ	000000001h		;Bit 0
PC_AUX					equ	000000010h		;Bit 4
PC_ZERO					equ	000000040h		;Bit 6
PC_NEG					equ	000000080h		;Bit 7
PC_OVERFLOW				equ	000000800h		;Bit 11

;Emulation condition codes, ordered so can do 'xor al,al' to set XNZVC -0000
EMU_X					equ	00100h
EMU_N					equ	00080h
EMU_Z					equ	00040h
EMU_V					equ	00020h
EMU_C					equ	00010h
EMU_CLEAR_X				equ	0feffh
EMU_CLEAR_N				equ	0ff7fh
EMU_CLEAR_Z				equ	0ffbfh
EMU_CLEAR_V				equ	0ffdfh
EMU_CLEAR_C				equ	0ffefh

;68000 Condition code's
SR_AUX					equ	00010h
SR_NEG					equ	00008h
SR_ZERO					equ	00004h
SR_OVERFLOW				equ	00002h
SR_CARRY				equ	00001h

SR_CLEAR_AUX			equ	0ffefh
SR_CLEAR_NEG			equ	0fff7h
SR_CLEAR_ZERO			equ	0fffbh
SR_CLEAR_OVERFLOW		equ	0fffdh
SR_CLEAR_CARRY			equ	0fffeh

SR_CCODE_MASK			equ	(SR_AUX+SR_NEG+SR_ZERO+SR_OVERFLOW+SR_CARRY)
SR_MASK					equ	0ffe0h

;And status bits
SR_TRACEMODE			equ	08000h
SR_SUPERMODE			equ	02000h
SR_IPL					equ	00700h

SR_CLEAR_IPL			equ	0f8ffh
SR_CLEAR_TRACEMODE		equ	07fffh
SR_CLEAR_SUPERMODE		equ	0dfffh

;Exception vectors
EXCEPTION_BUSERROR		equ	000000008h
EXCEPTION_ADDRERROR		equ	00000000ch
EXCEPTION_ILLEGALINS	equ	000000010h
EXCEPTION_DIVZERO		equ	000000014h
EXCEPTION_CHK			equ	000000018h
EXCEPTION_TRAPV			equ	00000001ch
EXCEPTION_TRACE			equ	000000024h
EXCEPTION_LINE_A		equ	000000028h
EXCEPTION_LINE_F		equ	00000002ch
EXCEPTION_TRAP			equ	000000080h

;DecodeTable structure
DECODE_CYCLES			equ	0				;Cycles for this instruction, includes <ea> etc...
DECODE_FUNCTION			equ	4				;Decode function to call
DECODE_EA				equ	8				;<ea> Decode function
DECODE_1				equ	12
DECODE_2				equ	16
SIZEOF_DECODE			equ	8

;ST Memory defines
STRAM_OFFSET			equ	edi
INTERCEPT_HIADDRESS		equ	[_STRamEnd]		;End of ST Memory(eg 1 Mb) - Above here addresses need to be checked for errors/hardware access

;Breakpoints
BRK_DISABLED			equ	0ffffffffh
BRK_SINGLE_INSTRUCTION	equ	0fffffffeh
BRK_STOP				equ	0fffffffdh

;Pending interrupt masks
PENDING_INTERRUPT_FLAG_MFP			equ	00001h	;MUST match 'decode.h'
PENDING_INTERRUPT_FLAG_TRACE		equ	00002h
CLEAR_PENDING_INTERRUPT_FLAG_MFP	equ	0fffeh
CLEAR_PENDING_INTERRUPT_FLAG_TRACE	equ	0fffdh

;Instruction history size
INSTRUCTION_HISTORY_SIZE			equ	8192	;Must be ^2
INSTRUCTION_HISTORY_MASK			equ	(INSTRUCTION_HISTORY_SIZE-1)

;-----------------------------------------------------------------------
;Swap upper and lower bytes of 16-bit word
SWAP_ENDIAN_WORD_AX	MACRO
	ror	ax,8
	ENDM
SWAP_ENDIAN_WORD_BX MACRO
	ror	bx,8
	ENDM
SWAP_ENDIAN_WORD_CX MACRO
	ror	cx,8
	ENDM
SWAP_ENDIAN_WORD_DX MACRO
	ror	dx,8
	ENDM
;Swap upper and lower words of 32-bit word
SWAP_ENDIAN_LONG_EAX MACRO
	bswap	eax
	ENDM
SWAP_ENDIAN_LONG_EBX MACRO
	bswap	ebx
	ENDM
SWAP_ENDIAN_LONG_ECX MACRO
	bswap	ecx
	ENDM
SWAP_ENDIAN_LONG_EDX MACRO
	bswap	edx
	ENDM

;-----------------------------------------------------------------------
;Add cycles to pending interrupt count
ADD_CYCLES MACRO s
	sub		[_PendingInterruptCount],s
	add		[_SoundCycles],s
	ENDM
ADD_CYCLES_EBX MACRO
	sub		[_PendingInterruptCount],bx
	add		[_SoundCycles],ebx
	ENDM
ADD_SHIFT_CYCLES_BYTEWORD MACRO s
	mov		ebx,_ShiftCycleTable_ByteWord[ecx*4]
	sub		[_PendingInterruptCount],bx
	add		[_SoundCycles],ebx
	ENDM
ADD_SHIFT_CYCLES_LONG MACRO s
	mov		ebx,_ShiftCycleTable_Long[ecx*4]
	sub		[_PendingInterruptCount],bx
	add		[_SoundCycles],ebx
	ENDM

;-----------------------------------------------------------------------
FRET MACRO
	jmp		_InstructionLoop
	ENDM

;-----------------------------------------------------------------------
;Mask register to 24-bit 68000 address space
MASK_24BIT_ADDR MACRO p
	and		p,000ffffffh
	ENDM

;-----------------------------------------------------------------------
;Set registers for use during decode, and restore when leave
SAVE_ASSEM_REGS MACRO
	mov		[_EmuCCode],eax
	sub		esi,STRAM_OFFSET							;'esi' is in PC address space, so offset to give ST space
	and		[_PC],0ff000000h							;Combine with stored Program Counter to retain top byte
	or		[_PC],esi
	ENDM

RESTORE_ASSEM_REGS MACRO
	mov		edi,OFFSET [_STRam]							;'edi' is always ST Ram base
	mov		esi,[_PC]									;'esi' is 68000 Program Counter in PC's address space
	and		esi,000ffffffh
	add		esi,STRAM_OFFSET
	mov		eax,[_EmuCCode]								;'eax' is 68000 condition codes, in emulator format(left shifted)
	ENDM

;-----------------------------------------------------------------------
;Read 'bl, 'bx' or 'ebx' from address 'ebp' and check for intercepts. These do a 'ret' when complete
INTERCEPT_CHECK_ADDR_READBYTE MACRO
	MASK_24BIT_ADDR(ebp)
	cmp		ebp,INTERCEPT_HIADDRESS
	jge		_Intercept_ReadByte							;ret
	mov		bl,BYTE PTR _STRam[ebp]
	ret
	ENDM
INTERCEPT_CHECK_ADDR_READWORD MACRO
	MASK_24BIT_ADDR(ebp)
	bt		ebp,0										;Check address-error
	jc		_Intercept_ReadWord							;ret
	cmp		ebp,INTERCEPT_HIADDRESS
	jge		_Intercept_ReadWord							;ret
	mov		bx,WORD PTR _STRam[ebp]
	SWAP_ENDIAN_WORD_BX
	ret
	ENDM
INTERCEPT_CHECK_ADDR_READLONG MACRO
	MASK_24BIT_ADDR(ebp)
	bt		ebp,0										;Check address-error
	jc		_Intercept_ReadLong							;ret
	cmp		ebp,INTERCEPT_HIADDRESS
	jge		_Intercept_ReadLong							;ret
	mov		ebx,DWORD PTR _STRam[ebp]
	SWAP_ENDIAN_LONG_EBX
	ret
	ENDM

;-----------------------------------------------------------------------
;Write value 'bl', 'bx' or 'ebx' to address 'ebp', and check for intercepts.
;NOTE! Corrupts 'ecx', but 'ebx' remains the same as when the macro was called
INTERCEPT_CHECK_ADDR_WRITEBYTE MACRO
	MASK_24BIT_ADDR(ebp)
IF USE_DEBUGGER
	call	check_address_breakpoints
ENDIF
	cmp		ebp,INTERCEPT_HIADDRESS
	jl		address_ok
	call	_Intercept_WriteByte
	jmp		intercept_address
address_ok:
	mov		BYTE PTR _STRam[ebp],bl
intercept_address:
	ENDM

INTERCEPT_CHECK_ADDR_WRITEWORD MACRO
	MASK_24BIT_ADDR(ebp)
IF USE_DEBUGGER
	call	check_address_breakpoints
ENDIF
	bt		ebp,0										;Check address-error
	jc		address_error
	cmp		ebp,INTERCEPT_HIADDRESS
	jl		address_ok
address_error:
	call	_Intercept_WriteWord
	jmp		intercept_address
address_ok:
	mov		ecx,ebx
	SWAP_ENDIAN_WORD_CX
	mov		WORD PTR _STRam[ebp],cx
intercept_address:
	ENDM

INTERCEPT_CHECK_ADDR_WRITELONG MACRO
	MASK_24BIT_ADDR(ebp)
IF USE_DEBUGGER
	call	check_address_breakpoints
ENDIF
	bt		ebp,0										;Check address-error
	jc		address_error
	cmp		ebp,INTERCEPT_HIADDRESS
	jl		address_ok
address_error:
	call	_Intercept_WriteLong
	jmp		intercept_address
address_ok:
	mov		ecx,ebx
	SWAP_ENDIAN_LONG_ECX
	mov		DWORD PTR _STRam[ebp],ecx
intercept_address:
	ENDM

;-----------------------------------------------------------------------
;Extern 'C' variables/functions which are used in the assembler
EXTRN _STRam:PROC
EXTRN _M68000_Exception:PROC
EXTRN _M68000_CheckUserSuperToggle:PROC
EXTRN _M68000_TraceModeTriggered:PROC
EXTRN _M68000_OutputHistory:PROC
EXTRN _MFP_CheckPendingInterrupts:PROC
EXTRN _Intercept_ReadByte:PROC
EXTRN _Intercept_ReadWord:PROC
EXTRN _Intercept_ReadLong:PROC
EXTRN _Intercept_WriteByte:PROC
EXTRN _Intercept_WriteWord:PROC
EXTRN _Intercept_WriteLong:PROC

;-----------------------------------------------------------------------
;Assembler variables/functions
PUBLIC _PCCodeTable_NZV_CX_SAME
PUBLIC _PCCodeTable_NZVC
PUBLIC _ShiftCycleTable_ByteWord
PUBLIC _ShiftCycleTable_Long
PUBLIC _Regs
PUBLIC _STRamEnd
PUBLIC _STRamEnd_BusErr
PUBLIC _PendingInterruptCount
PUBLIC _PendingInterruptFlag
PUBLIC _PendingInterruptFunction
PUBLIC _InsPC
PUBLIC _SoundCycles
PUBLIC _PC
PUBLIC _SR
PUBLIC _SR_Before
PUBLIC _bInSuperMode
PUBLIC _Reg_SuperSP
PUBLIC _Reg_UserSP
PUBLIC _EmuCCode
PUBLIC _StackSave
PUBLIC _ExceptionVector
PUBLIC _BusAddressLocation
PUBLIC _DecodeTable
PUBLIC _InstructionHistory
PUBLIC _InstructionHistoryIndex
PUBLIC _BreakPointInstruction
PUBLIC _AddressBreakpoints
PUBLIC _BreakOnAddress
PUBLIC _CPUStopped

PUBLIC _RunIntructions
PUBLIC _InstructionLoop
