www.pudn.com > sn068s.zip > CPUMACRO.NI


; SNEeSe 65c816 CPU emulation core 
; Originally written by Savoury SnaX (Not quite sure if I like AT&T) 
; Maintained/rewritten by Charles Bilyue' 
; 
; Compile under DJGPP (GNU-AS) 
;  NOTE - This must have .S (capital) or the # stuff wont be pre-processed!!! 
; 
; This file contains: 
;  CPU opcode macros 
; 
; Examples of usage: 
;  EM_LDA Direct = 8-bit LDA using "direct" address mode 
;  BFC SNES_FLAG_C = Branch if carry flag clear (BCC) 
 
;%1 = label, %2 = addr 
%macro EM_ADC 2 
ALIGNC 
EXPORT_C EM_ADC_%1 
;STORE_FLAGS_V ah 
 READ8_%2 
 JUMP_FLAG SNES_FLAG_D,%%decimal_mode 
 mov cl,B_C_flag 
 mov bl,B_A 
 add cl,255 ;MAKE_CARRY 
 adc bl,al 
;jno %%no_overflow 
;STORE_FLAGS_V 1 
 seto B_V_flag 
%%no_overflow: 
 sbb al,al 
 mov B_A,bl 
 STORE_FLAGS_NZC bl,al 
 OPCODE_EPILOG 
 
ALIGNC 
%%decimal_mode: 
 mov cl,B_C_flag 
 mov bl,al 
 mov al,B_A 
 add cl,255 ;MAKE_CARRY 
 adc al,bl 
 daa 
 mov B_A,al 
;jno %%no_overflow_decimal 
%%overflow: 
;STORE_FLAGS_V 1 
 seto B_V_flag 
%%no_overflow_decimal: 
 sbb bl,bl 
 STORE_FLAGS_NZC al,bl 
 OPCODE_EPILOG 
%endmacro 
 
;%1 = label, %2 = addr 
%macro E0_ADC 2 
ALIGNC 
EXPORT_C E0_ADC_%1 
;STORE_FLAGS_V ah 
 READ16_%2 
 JUMP_FLAG SNES_FLAG_D,%%decimal_mode 
 mov cl,B_C_flag 
 mov ebx,B_A 
 add cl,255 ;MAKE_CARRY 
 adc bx,ax 
;jno %%no_overflow 
;STORE_FLAGS_V 1 
 seto B_V_flag 
%%no_overflow: 
 sbb al,al 
 STORE_FLAGS_N bh 
 mov B_A,ebx 
 or bl,bh 
 STORE_FLAGS_C al 
 STORE_FLAGS_Z bl 
 OPCODE_EPILOG 
 
ALIGNC 
%%decimal_mode: 
 mov cl,B_C_flag 
 mov ebx,eax 
 mov eax,B_A 
 add cl,255 ;MAKE_CARRY 
 adc al,bl 
 daa 
 mov bl,al 
 mov al,ah 
 adc al,bh 
 daa 
 mov bh,al 
;jno %%no_overflow_decimal 
;STORE_FLAGS_V 1 
 seto B_V_flag 
%%no_overflow_decimal: 
 sbb al,al 
 STORE_FLAGS_N bh 
 mov B_A,ebx 
 or bl,bh 
 STORE_FLAGS_C al 
 STORE_FLAGS_Z bl 
 OPCODE_EPILOG 
%endmacro 
 
;%1 = label, %2 = addr 
%macro EM_AND 2 
ALIGNC 
EXPORT_C EM_AND_%1 
 READ8_%2 
 mov bl,B_A 
 and bl,al 
 mov B_A,bl 
 STORE_FLAGS_NZ bl 
 OPCODE_EPILOG 
%endmacro 
 
;%1 = label, %2 = addr 
%macro E0_AND 2 
ALIGNC 
EXPORT_C E0_AND_%1 
 READ16_%2 
 mov ebx,B_A 
 and ebx,eax 
 mov B_A,bx 
 or bl,bh 
 STORE_FLAGS_N bh 
 STORE_FLAGS_Z bl 
 OPCODE_EPILOG 
%endmacro 
 
;%1 = label, %2 = addr 
%macro EM_ASL 2 
ALIGNC 
EXPORT_C EM_ASL_%1 
 READ8_%2 
 add al,al 
 sbb cl,cl 
 STORE_FLAGS_NZC al,cl 
 SET_BYTE 
 OPCODE_EPILOG 
%endmacro 
 
;%1 = label, %2 = addr 
%macro E0_ASL 2 
ALIGNC 
EXPORT_C E0_ASL_%1 
 READ16_%2 
 add ax,ax 
 sbb cl,cl 
 SET_WORD_HL 
 or al,ah 
 STORE_FLAGS_C cl 
 STORE_FLAGS_N ah 
 STORE_FLAGS_Z al 
 OPCODE_EPILOG 
%endmacro 
 
;%1 = label, %2 = flag 
%macro BFC 2 
ALIGNC 
EXPORT_C ALL_%1 
 add R_NativePC,byte 2 
 JUMP_FLAG %2,CPU_RETURN,near       ; flag set 
 movsx eax,byte [R_NativePC - 1]    ; sign extend for addition 
 add R_Cycles,byte 6            ; branch taken 
 add R_NativePC,eax 
 OPCODE_EPILOG 
%endmacro 
 
;%1 = label, %2 = flag 
%macro BFS 2 
ALIGNC 
EXPORT_C ALL_%1 
 add R_NativePC,byte 2 
 JUMP_NOT_FLAG %2,CPU_RETURN,near   ; flag clear 
 movsx eax,byte [R_NativePC - 1]    ; sign extend for addition 
 add R_Cycles,byte 6            ; branch taken 
 add R_NativePC,eax 
 OPCODE_EPILOG 
%endmacro 
 
;%1 = label, %2 = addr 
%macro EM_BIT 2 
ALIGNC 
EXPORT_C EM_BIT_%1 
 READ8_%2 
 mov cl,B_A 
 STORE_FLAGS_N al 
 and cl,al 
 and al,0x40 
 STORE_FLAGS_Z cl 
 STORE_FLAGS_V al 
 OPCODE_EPILOG 
%endmacro 
 
;%1 = label, %2 = addr 
%macro E0_BIT 2 
ALIGNC 
EXPORT_C E0_BIT_%1 
 READ16_%2 
 mov ecx,B_A 
 STORE_FLAGS_N ah 
 and ecx,eax 
 and ah,0x40 
 or cl,ch 
 STORE_FLAGS_V ah 
 STORE_FLAGS_Z cl 
 OPCODE_EPILOG 
%endmacro 
 
;%1 = label, %2 = addr 
%macro EM_CMP 2 
ALIGNC 
EXPORT_C EM_CMP_%1 
 mov cl,B_A 
 READ8_%2 
 sub cl,al 
 sbb al,al 
 STORE_FLAGS_N cl 
 xor al,0xFF 
 STORE_FLAGS_Z cl 
 STORE_FLAGS_C al 
 OPCODE_EPILOG 
%endmacro 
 
;%1 = label, %2 = addr 
%macro E0_CMP 2 
ALIGNC 
EXPORT_C E0_CMP_%1 
 mov ecx,B_A 
 READ16_%2 
 sub cx,ax 
 sbb al,al 
 STORE_FLAGS_N ch 
 or cl,ch 
 xor al,0xFF 
 STORE_FLAGS_Z cl 
 STORE_FLAGS_C al 
 OPCODE_EPILOG 
%endmacro 
 
;%1 = label, %2 = addr 
%macro EX_CPX 2 
ALIGNC 
EXPORT_C EX_CPX_%1 
 mov cl,B_X 
 READ8_%2 
 sub cl,al 
 sbb al,al 
 STORE_FLAGS_N cl 
 xor al,0xFF 
 STORE_FLAGS_Z cl 
 STORE_FLAGS_C al 
 OPCODE_EPILOG 
%endmacro 
 
;%1 = label, %2 = addr 
%macro E0_CPX 2 
ALIGNC 
EXPORT_C E0_CPX_%1 
 mov ecx,B_X 
 READ16_%2 
 sub cx,ax 
 sbb al,al 
 STORE_FLAGS_N ch 
 or cl,ch 
 xor al,0xFF 
 STORE_FLAGS_Z cl 
 STORE_FLAGS_C al 
 OPCODE_EPILOG 
%endmacro 
 
;%1 = label, %2 = addr 
%macro EX_CPY 2 
ALIGNC 
EXPORT_C EX_CPY_%1 
 mov cl,B_Y 
 READ8_%2 
 sub cl,al 
 sbb al,al 
 STORE_FLAGS_N cl 
 xor al,0xFF 
 STORE_FLAGS_Z cl 
 STORE_FLAGS_C al 
 OPCODE_EPILOG 
%endmacro 
 
;%1 = label, %2 = addr 
%macro E0_CPY 2 
ALIGNC 
EXPORT_C E0_CPY_%1 
 mov ecx,B_Y 
 READ16_%2 
 sub cx,ax 
 sbb al,al 
 STORE_FLAGS_N ch 
 or cl,ch 
 xor al,0xFF 
 STORE_FLAGS_Z cl 
 STORE_FLAGS_C al 
 OPCODE_EPILOG 
%endmacro 
 
;%1 = label, %2 = addr 
%macro EM_DEC 2 
ALIGNC 
EXPORT_C EM_DEC_%1 
 READ8_%2 
 dec al 
 SET_BYTE 
 STORE_FLAGS_NZ al 
 OPCODE_EPILOG 
%endmacro 
 
;%1 = label, %2 = addr 
%macro E0_DEC 2 
ALIGNC 
EXPORT_C E0_DEC_%1 
 READ16_%2 
 dec eax 
 SET_WORD_HL 
 or al,ah 
 STORE_FLAGS_N ah 
 STORE_FLAGS_Z al 
 OPCODE_EPILOG 
%endmacro 
 
;%1 = label, %2 = addr 
%macro EM_EOR 2 
ALIGNC 
EXPORT_C EM_EOR_%1 
 READ8_%2 
 mov bl,B_A 
 xor bl,al 
 mov B_A,bl 
 STORE_FLAGS_NZ bl 
 OPCODE_EPILOG 
%endmacro 
 
;%1 = label, %2 = addr 
%macro E0_EOR 2 
ALIGNC 
EXPORT_C E0_EOR_%1 
 READ16_%2 
 mov ebx,B_A 
 xor ebx,eax 
 mov B_A,bx 
 or bl,bh 
 STORE_FLAGS_N bh 
 STORE_FLAGS_Z bl 
 OPCODE_EPILOG 
%endmacro 
 
;%1 = label, %2 = addr 
%macro EM_INC 2 
ALIGNC 
EXPORT_C EM_INC_%1 
 READ8_%2 
 inc al 
 SET_BYTE 
 STORE_FLAGS_NZ al 
 OPCODE_EPILOG 
%endmacro 
 
;%1 = label, %2 = addr 
%macro E0_INC 2 
ALIGNC 
EXPORT_C E0_INC_%1 
 READ16_%2 
 inc eax 
 SET_WORD_HL 
 or al,ah 
 STORE_FLAGS_N ah 
 STORE_FLAGS_Z al 
 OPCODE_EPILOG 
%endmacro 
 
;%1 = label, %2 = addr 
%macro EM_LDA 2 
ALIGNC 
EXPORT_C EM_LDA_%1 
 READ8_%2 
 mov B_A,al 
 STORE_FLAGS_NZ al 
 OPCODE_EPILOG 
%endmacro 
 
;%1 = label, %2 = addr 
%macro E0_LDA 2 
ALIGNC 
EXPORT_C E0_LDA_%1 
 READ16_%2 
 mov B_A,ax 
 or al,ah 
 STORE_FLAGS_N ah 
 STORE_FLAGS_Z al 
 OPCODE_EPILOG 
%endmacro 
 
;%1 = label, %2 = addr 
%macro EX_LDX 2 
ALIGNC 
EXPORT_C EX_LDX_%1 
 READ8_%2 
 mov B_X,al 
 STORE_FLAGS_NZ al 
 OPCODE_EPILOG 
%endmacro 
 
;%1 = label, %2 = addr 
%macro E0_LDX 2 
ALIGNC 
EXPORT_C E0_LDX_%1 
 READ16_%2 
 mov B_X,ax 
 or al,ah 
 STORE_FLAGS_N ah 
 STORE_FLAGS_Z al 
 OPCODE_EPILOG 
%endmacro 
 
;%1 = label, %2 = addr 
%macro EX_LDY 2 
ALIGNC 
EXPORT_C EX_LDY_%1 
 READ8_%2 
 mov B_Y,al 
 STORE_FLAGS_NZ al 
 OPCODE_EPILOG 
%endmacro 
 
;%1 = label, %2 = addr 
%macro E0_LDY 2 
ALIGNC 
EXPORT_C E0_LDY_%1 
 READ16_%2 
 mov B_Y,ax 
 or al,ah 
 STORE_FLAGS_N ah 
 STORE_FLAGS_Z al 
 OPCODE_EPILOG 
%endmacro 
 
;%1 = label, %2 = addr 
%macro EM_LSR 2 
ALIGNC 
EXPORT_C EM_LSR_%1 
 READ8_%2 
 shr al,byte 1 
 sbb cl,cl 
 STORE_FLAGS_NZC al,cl 
 SET_BYTE 
 OPCODE_EPILOG 
%endmacro 
 
;%1 = label, %2 = addr 
%macro E0_LSR 2 
ALIGNC 
EXPORT_C E0_LSR_%1 
 READ16_%2 
 shr ax,byte 1 
 sbb cl,cl 
 SET_WORD_HL 
 or al,ah 
 STORE_FLAGS_C cl 
 STORE_FLAGS_N ah 
 STORE_FLAGS_Z al 
 OPCODE_EPILOG 
%endmacro 
 
;%1 = label, %2 = addr 
%macro EM_ORA 2 
ALIGNC 
EXPORT_C EM_ORA_%1 
 READ8_%2 
 mov bl,B_A 
 or bl,al 
 mov B_A,bl 
 STORE_FLAGS_NZ bl 
 OPCODE_EPILOG 
%endmacro 
 
;%1 = label, %2 = addr 
%macro E0_ORA 2 
ALIGNC 
EXPORT_C E0_ORA_%1 
 READ16_%2 
 mov ebx,B_A 
 or ebx,eax 
 mov B_A,bx 
 or bl,bh 
 STORE_FLAGS_N bh 
 STORE_FLAGS_Z bl 
 OPCODE_EPILOG 
%endmacro 
 
;%1 = label, %2 = addr 
%macro EM_ROL 2 
ALIGNC 
EXPORT_C EM_ROL_%1 
 mov cl,B_C_flag 
 READ8_%2 
 add cl,255 ;MAKE_CARRY 
 adc al,al 
 sbb cl,cl 
 STORE_FLAGS_NZC al,cl 
 SET_BYTE 
 OPCODE_EPILOG 
%endmacro 
 
;%1 = label, %2 = addr 
%macro E0_ROL 2 
ALIGNC 
EXPORT_C E0_ROL_%1 
 mov cl,B_C_flag 
 READ16_%2 
 add cl,255 ;MAKE_CARRY 
 adc ax,ax 
 sbb cl,cl 
 SET_WORD_HL 
 or al,ah 
 STORE_FLAGS_C cl 
 STORE_FLAGS_N ah 
 STORE_FLAGS_Z al 
 OPCODE_EPILOG 
%endmacro 
 
;%1 = label, %2 = addr 
%macro EM_ROR 2 
ALIGNC 
EXPORT_C EM_ROR_%1 
 mov cl,B_C_flag 
 READ8_%2 
 add cl,255 ;MAKE_CARRY 
 rcr al,1 
 sbb cl,cl 
 STORE_FLAGS_NZC al,cl 
 SET_BYTE 
 OPCODE_EPILOG 
%endmacro 
 
;%1 = label, %2 = addr 
%macro E0_ROR 2 
ALIGNC 
EXPORT_C E0_ROR_%1 
 mov cl,B_C_flag 
 READ16_%2 
 add cl,255 ;MAKE_CARRY 
 rcr ax,1 
 sbb cl,cl 
 SET_WORD_HL 
 or al,ah 
 STORE_FLAGS_C cl 
 STORE_FLAGS_N ah 
 STORE_FLAGS_Z al 
 OPCODE_EPILOG 
%endmacro 
 
;%1 = label, %2 = addr 
%macro EM_SBC 2 
ALIGNC 
EXPORT_C EM_SBC_%1 
;STORE_FLAGS_V ah 
 READ8_%2 
 JUMP_FLAG SNES_FLAG_D,%%decimal_mode 
 mov cl,B_C_flag 
 mov bl,B_A 
 cmp cl,1   ;MAKE_NOT_CARRY 
 sbb bl,al 
;jno %%no_overflow 
;STORE_FLAGS_V 1 
 seto B_V_flag 
%%no_overflow: 
 sbb al,al 
 mov B_A,bl 
 xor al,0xFF 
 STORE_FLAGS_NZC bl,al 
 OPCODE_EPILOG 
 
ALIGNC 
%%decimal_mode: 
 mov cl,B_C_flag 
 mov bl,al 
 mov al,B_A 
 cmp cl,1   ;MAKE_NOT_CARRY 
 sbb al,bl 
 das 
 mov B_A,al 
;jno %%no_overflow_decimal 
%%overflow: 
;STORE_FLAGS_V 1 
 seto B_V_flag 
%%no_overflow_decimal: 
 sbb bl,bl 
 STORE_FLAGS_N al 
 xor bl,0xFF 
 STORE_FLAGS_Z al 
 STORE_FLAGS_C bl 
 OPCODE_EPILOG 
%endmacro 
 
;%1 = label, %2 = addr 
%macro E0_SBC 2 
ALIGNC 
EXPORT_C E0_SBC_%1 
;STORE_FLAGS_V ah 
 READ16_%2 
 JUMP_FLAG SNES_FLAG_D,%%decimal_mode 
 mov cl,B_C_flag 
 mov ebx,B_A 
 cmp cl,1   ;MAKE_NOT_CARRY 
 sbb bx,ax 
;jno %%no_overflow 
;STORE_FLAGS_V 1 
 seto B_V_flag 
%%no_overflow: 
 sbb al,al 
 mov B_A,ebx 
 xor al,0xFF 
 STORE_FLAGS_N bh 
 or bl,bh 
 STORE_FLAGS_C al 
 STORE_FLAGS_Z bl 
 OPCODE_EPILOG 
 
ALIGNC 
%%decimal_mode: 
 mov cl,B_C_flag 
 mov ebx,eax 
 mov eax,B_A 
 cmp cl,1   ;MAKE_NOT_CARRY 
 sbb al,bl 
 das 
 mov bl,al 
 mov al,ah 
 sbb al,bh 
 das 
 mov bh,al 
;jno %%no_overflow_decimal 
;STORE_FLAGS_V 1 
 seto B_V_flag 
%%no_overflow_decimal: 
 sbb al,al 
 STORE_FLAGS_N bh 
 xor al,0xFF 
 mov B_A,ebx 
 or bl,bh 
 STORE_FLAGS_C al 
 STORE_FLAGS_Z bl 
 OPCODE_EPILOG 
%endmacro 
 
;%1 = label, %2 = addr 
%macro EM_STA 2 
ALIGNC 
EXPORT_C EM_STA_%1 
 ADDR_%2 
 mov eax,B_A 
 SET_BYTE 
 OPCODE_EPILOG 
%endmacro 
 
;%1 = label, %2 = addr 
%macro E0_STA 2 
ALIGNC 
EXPORT_C E0_STA_%1 
 ADDR_%2 
 mov eax,B_A 
 SET_WORD NoSave 
 OPCODE_EPILOG 
%endmacro 
 
;%1 = label, %2 = addr 
%macro EX_STX 2 
ALIGNC 
EXPORT_C EX_STX_%1 
 ADDR_%2 
 mov eax,B_X 
 SET_BYTE 
 OPCODE_EPILOG 
%endmacro 
 
;%1 = label, %2 = addr 
%macro E0_STX 2 
ALIGNC 
EXPORT_C E0_STX_%1 
 ADDR_%2 
 mov eax,B_X 
 SET_WORD NoSave 
 OPCODE_EPILOG 
%endmacro 
 
;%1 = label, %2 = addr 
%macro EX_STY 2 
ALIGNC 
EXPORT_C EX_STY_%1 
 ADDR_%2 
 mov eax,B_Y 
 SET_BYTE 
 OPCODE_EPILOG 
%endmacro 
 
;%1 = label, %2 = addr 
%macro E0_STY 2 
ALIGNC 
EXPORT_C E0_STY_%1 
 ADDR_%2 
 mov eax,B_Y 
 SET_WORD NoSave 
 OPCODE_EPILOG 
%endmacro 
 
;%1 = label, %2 = addr 
%macro EM_STZ 2 
ALIGNC 
EXPORT_C EM_STZ_%1 
 ADDR_%2 
 xor eax,eax 
 SET_BYTE 
 OPCODE_EPILOG 
%endmacro 
 
;%1 = label, %2 = addr 
%macro E0_STZ 2 
ALIGNC 
EXPORT_C E0_STZ_%1 
 ADDR_%2 
 xor eax,eax 
 SET_WORD Double 
 OPCODE_EPILOG 
%endmacro 
 
; TRB set flag Z on A & Memory Operand not A & !Memory Operand! 
;%1 = label, %2 = addr 
%macro EM_TRB 2 
ALIGNC 
EXPORT_C EM_TRB_%1 
 mov cl,B_A 
 READ8_%2 
 mov ah,cl 
 xor cl,0xFF 
 and ah,al      ; Z set for: mem & A 
 STORE_FLAGS_Z ah 
 and al,cl 
 SET_BYTE       ; mem &= ~A 
 OPCODE_EPILOG 
%endmacro 
 
;%1 = label, %2 = addr 
%macro E0_TRB 2 
ALIGNC 
EXPORT_C E0_TRB_%1 
 READ16_%2 
 mov ecx,B_A 
 test ecx,eax 
 setnz B_Z_flag ; Z set for: mem & A 
 xor ecx,-1 
 and eax,ecx 
 SET_WORD_HL    ; mem &= ~A 
 OPCODE_EPILOG 
%endmacro 
 
; TSB set flag Z on A & Memory Operand not A | Memory Operand! 
 
;%1 = label, %2 = addr 
%macro EM_TSB 2 
ALIGNC 
EXPORT_C EM_TSB_%1 
 mov cl,B_A 
 READ8_%2 
 mov ah,cl 
 and cl,al      ; Z set for: mem & A 
 STORE_FLAGS_Z cl 
 or al,ah 
 SET_BYTE       ; mem |= A 
 OPCODE_EPILOG 
%endmacro 
 
;%1 = label, %2 = addr 
%macro E0_TSB 2 
ALIGNC 
EXPORT_C E0_TSB_%1 
 READ16_%2 
 mov ecx,B_A 
 test ecx,eax 
 setnz B_Z_flag ; Z set for: mem & A 
 or eax,ecx 
 SET_WORD_HL    ; mem |= A 
 OPCODE_EPILOG 
%endmacro