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