⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 spcmacro.inc

📁 NES game Emulator in Linux.c and asm codes.
💻 INC
字号:
%if 0

SNEeSe, an Open Source Super NES emulator.


Copyright (c) 1998-2004 Charles Bilyue'.
Portions Copyright (c) 2003-2004 Daniel Horchner.

This is free software.  See 'LICENSE' for details.
You must read and accept the license prior to use.

%endif

; SPC instruction macros
;  Original code by Savoury SnaX
;  Rewritten/maintained by TRAC

; TCALL: Call through table in pageable 64-bytes of RAM
;%1 = vecnum
%macro TCALL 0-1
ALIGNC
EXPORT_C SPC_TCALL_%1
 GET_PC eax
 inc eax
 PUSH_W
 xor eax,eax
 mov ax,[C_LABEL(SPCRAM)+0xFFC0+((15 - (%1)) << 1)]
 cmp eax,0xFFC0
 mov R_NativePC,eax
 mov eax,[SPC_FFC0_Address]
 jnb .possible_rom
 mov eax,C_LABEL(SPCRAM)
.possible_rom:
 add R_NativePC,eax
 mov [SPC_Code_Base],eax
 OPCODE_EPILOG
%endmacro

;eax = sign-extended branch offset
%macro short_branch 0
%if 0
 GET_PC ebx
 mov edx,ebx
 add R_NativePC,eax
 inc R_Cycles   ; branch taken
 add ebx,eax
 xor edx,ebx
 add dh,255
 sbb edx,edx
 and edx,1      ;address page wrap?
 add R_Cycles,edx
%else
 add R_NativePC,eax
 add R_Cycles,2 ; branch taken
%endif
%endmacro

;%1 = label, %2 = flag
%macro SPC_BFC 2
ALIGNC
EXPORT_C SPC_%1
 add R_NativePC,byte 2
 JUMP_FLAG_SPC %2,SPC_RETURN            ; flag set
 movsx eax,byte [-1+R_NativePC]     ; sign extend for addition
 short_branch
 OPCODE_EPILOG
%endmacro

;%1 = label, %2 = flag
%macro SPC_BFS 2
ALIGNC
EXPORT_C SPC_%1
 add R_NativePC,byte 2
 JUMP_NOT_FLAG_SPC %2,SPC_RETURN        ; flag set
 movsx eax,byte [-1+R_NativePC]     ; sign extend for addition
 short_branch
 OPCODE_EPILOG
%endmacro

;%1 = op
%macro SPC_OP_A_IM_NZ 1
 mov al,[1+R_NativePC]
 mov cl,B_A
 add R_NativePC,byte 2
 SPC_BASE_%1 cl,al
 mov B_A,cl
 STORE_FLAGS_NZ cl
 OPCODE_EPILOG
%endmacro

;%1 = reg
%macro SPC_MOV_reg_IM 1
 mov al,[1+R_NativePC]
 add R_NativePC,byte 2
 mov %1,al
 STORE_FLAGS_NZ al
 OPCODE_EPILOG
%endmacro

;%1 = reg
%macro SPC_CMP_reg_IM 1
 mov al,[1+R_NativePC]
 mov cl,%1
 add R_NativePC,byte 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 = op, %2 = reg, %3 = addr
%macro SPC_OP_REG_NZ 3
 ADDR_%3
 mov cl,%2
 GET_BYTE_SPC
 SPC_BASE_%1 cl,al
 mov %2,cl
 STORE_FLAGS_NZ cl
 OPCODE_EPILOG
%endmacro

;%1 = op, %2 = addr
%macro SPC_OP_mem_NZ 2
 ADDR2_%2 cl        ; cl is source byte, bx dest address
 GET_BYTE_SPC       ; al contains byte at dest address
 SPC_BASE_%1 al,cl
 STORE_FLAGS_NZ al
 SET_BYTE_SPC
 OPCODE_EPILOG
%endmacro

;%1 = dest, %2 = src
%macro SPC_BASE_MOV 2
 mov byte %1,%2
%endmacro

;%1 = dest, %2 = src
%macro SPC_BASE_OR 2
 or %1,%2
%endmacro

;%1 = addr
%macro SPC_OR_A 1
ALIGNC
EXPORT_C SPC_OR_A_%1
 SPC_OP_REG_NZ OR,B_A,%1
%endmacro

;%1 = addr
%macro SPC_OR_mem 1
ALIGNC
EXPORT_C SPC_OR_%1
 SPC_OP_mem_NZ OR,%1
%endmacro

;%1 = dest, %2 = src
%macro SPC_BASE_AND 2
 and %1,%2
%endmacro

;%1 = addr
%macro SPC_AND_A 1
ALIGNC
EXPORT_C SPC_AND_A_%1
 SPC_OP_REG_NZ AND,B_A,%1
%endmacro

;%1 = addr
%macro SPC_AND_mem 1
ALIGNC
EXPORT_C SPC_AND_%1
 SPC_OP_mem_NZ AND,%1
%endmacro

;%1 = dest, %2 = src
%macro SPC_BASE_EOR 2
 xor %1,%2
%endmacro

;%1 = addr
%macro SPC_EOR_A 1
ALIGNC
EXPORT_C SPC_EOR_A_%1
 SPC_OP_REG_NZ EOR,B_A,%1
%endmacro

;%1 = addr
%macro SPC_EOR_mem 1
ALIGNC
EXPORT_C SPC_EOR_%1
 SPC_OP_mem_NZ EOR,%1
%endmacro

;%1 = reg, %2 = addr
%macro SPC_CMP 2
 ADDR_%2
 mov cl,%1
 GET_BYTE_SPC
 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 = addr
%macro SPC_CMP_A 1
ALIGNC
EXPORT_C SPC_CMP_A_%1
 SPC_CMP B_A,%1
%endmacro

;%1 = addr
%macro SPC_CMP_X 1
ALIGNC
EXPORT_C SPC_CMP_X_%1
 SPC_CMP B_X,%1
%endmacro

;%1 = addr
%macro SPC_CMP_Y 1
ALIGNC
EXPORT_C SPC_CMP_Y_%1
 SPC_CMP B_Y,%1
%endmacro

;%1 = addr
%macro SPC_CMP_mem 1
ALIGNC
EXPORT_C SPC_CMP_%1
 ADDR2_%1 cl        ; cl is source byte, bx dest address
 GET_BYTE_SPC       ; al contains byte at dest address
 sub al,cl
 sbb cl,cl
 STORE_FLAGS_N al
 xor cl,0xFF
 STORE_FLAGS_Z al
 STORE_FLAGS_C cl
 OPCODE_EPILOG
%endmacro

;%1 = addr
%macro SPC_ADC_A 1
ALIGNC
EXPORT_C SPC_ADC_A_%1
;STORE_FLAGS_V ah
 ADDR_%1
 mov cl,B_C_flag
 GET_BYTE_SPC
 add cl,255 ;MAKE_CARRY
 mov cl,B_A
 adc cl,al
 lahf
 mov B_A,cl
;jno .no_overflow
;STORE_FLAGS_V 1
 seto B_V_flag
.no_overflow:
 sbb al,al
 STORE_FLAGS_NZC cl,al
 STORE_FLAGS_H ah
 OPCODE_EPILOG
%endmacro

;%1 = addr
%macro SPC_ADC_mem 1
ALIGNC
EXPORT_C SPC_ADC_%1
;STORE_FLAGS_V ah
 ADDR2_%1 cl
 mov ah,B_C_flag
 GET_BYTE_SPC
 add ah,255 ;MAKE_CARRY
 adc al,cl
 lahf
 STORE_FLAGS_N al
;jno .no_overflow
;STORE_FLAGS_V 1
 seto B_V_flag
.no_overflow:
 sbb cl,cl
 STORE_FLAGS_Z al
 STORE_FLAGS_C cl
 STORE_FLAGS_H ah
 SET_BYTE_SPC
 OPCODE_EPILOG
%endmacro

;%1 = addr
%macro SPC_SBC_A 1
ALIGNC
EXPORT_C SPC_SBC_A_%1
;STORE_FLAGS_V ah
 ADDR_%1
 mov cl,B_C_flag
 GET_BYTE_SPC
 cmp cl,1 ;MAKE_NOT_CARRY
 mov cl,B_A
 sbb cl,al
 lahf
 mov B_A,cl
;jno .no_overflow
;STORE_FLAGS_V 1
 seto B_V_flag
.no_overflow:
 sbb al,al
 STORE_FLAGS_N cl
 xor al,0xFF
 STORE_FLAGS_Z cl
 STORE_FLAGS_C al
 STORE_FLAGS_H ah
 OPCODE_EPILOG
%endmacro

;%1 = addr
%macro SPC_SBC_mem 1
ALIGNC
EXPORT_C SPC_SBC_%1
;STORE_FLAGS_V ah
 ADDR2_%1 cl
 mov ah,B_C_flag
 GET_BYTE_SPC
 cmp ah,1 ;MAKE_NOT_CARRY
 sbb al,cl      ; (0.30) Butcha - switched these, wrong order
 lahf
 STORE_FLAGS_N al
;jno .no_overflow
;STORE_FLAGS_V 1
 seto B_V_flag
.no_overflow:
 sbb cl,cl
 STORE_FLAGS_Z al
 xor cl,0xFF
 STORE_FLAGS_H ah
 STORE_FLAGS_C cl
 SET_BYTE_SPC
 OPCODE_EPILOG
%endmacro

;%1 = label, %2 = reg
%macro SPC_DEC_reg 2
ALIGNC
EXPORT_C SPC_DEC_%1
 mov al,%2
 inc R_NativePC
 dec al
 mov %2,al
 STORE_FLAGS_NZ al
 OPCODE_EPILOG
%endmacro

;%1 = addr
%macro SPC_DEC 1
ALIGNC
EXPORT_C SPC_DEC_%1
 ADDR_%1
 GET_BYTE_SPC
 dec al
 STORE_FLAGS_NZ al
 SET_BYTE_SPC
 OPCODE_EPILOG
%endmacro

;%1 = label, %2 = reg
%macro SPC_INC_reg 2
ALIGNC
EXPORT_C SPC_INC_%1
 mov al,%2
 inc R_NativePC
 inc al
 mov %2,al
 STORE_FLAGS_NZ al
 OPCODE_EPILOG
%endmacro

;%1 = addr
%macro SPC_INC 1
ALIGNC
EXPORT_C SPC_INC_%1
 ADDR_%1
 GET_BYTE_SPC
 inc al
 STORE_FLAGS_NZ al
 SET_BYTE_SPC
 OPCODE_EPILOG
%endmacro

;%1 = addr
%macro SPC_ASL 1
ALIGNC
EXPORT_C SPC_ASL_%1
 ADDR_%1
 GET_BYTE_SPC
 add al,al
 sbb cl,cl
 STORE_FLAGS_NZC al,cl
 SET_BYTE_SPC
 OPCODE_EPILOG
%endmacro

;%1 = addr
%macro SPC_LSR 1
ALIGNC
EXPORT_C SPC_LSR_%1
 ADDR_%1
 GET_BYTE_SPC
 shr al,byte 1
 sbb cl,cl
 STORE_FLAGS_NZC al,cl
 SET_BYTE_SPC
 OPCODE_EPILOG
%endmacro

;%1 = addr
%macro SPC_ROL 1
ALIGNC
EXPORT_C SPC_ROL_%1
 ADDR_%1
 mov cl,B_C_flag
 GET_BYTE_SPC
 add cl,255 ;MAKE_CARRY
 adc al,al
 sbb cl,cl
 STORE_FLAGS_NZC al,cl
 SET_BYTE_SPC
 OPCODE_EPILOG
%endmacro

;%1 = addr
%macro SPC_ROR 1
ALIGNC
EXPORT_C SPC_ROR_%1
 ADDR_%1
 mov cl,B_C_flag
 GET_BYTE_SPC
 add cl,255 ;MAKE_CARRY
 rcr al,1
 sbb cl,cl
 STORE_FLAGS_NZC al,cl
 SET_BYTE_SPC
 OPCODE_EPILOG
%endmacro

;%1 = label, %2 = dest, %3 = src
%macro SPC_MOV_reg_reg 3
ALIGNC
EXPORT_C SPC_MOV_%1
 mov al,%3
 inc R_NativePC
 mov %2,al
 STORE_FLAGS_NZ al
 OPCODE_EPILOG
%endmacro

;%1 = addr, %2 = reg
%macro SPC_MOV_mem_reg 2
 ADDR_%1
 mov al,%2
 SET_BYTE_SPC
 OPCODE_EPILOG
%endmacro

;%1 = addr
%macro SPC_MOV_mem_A 1
ALIGNC
EXPORT_C SPC_MOV_%1__A
 SPC_MOV_mem_reg %1,B_A
%endmacro

;%1 = addr
%macro SPC_MOV_mem_X 1
ALIGNC
EXPORT_C SPC_MOV_%1__X
 SPC_MOV_mem_reg %1,B_X
%endmacro

;%1 = addr
%macro SPC_MOV_mem_Y 1
ALIGNC
EXPORT_C SPC_MOV_%1__Y
 SPC_MOV_mem_reg %1,B_Y
%endmacro

;%1 = reg, %2 = addr
%macro SPC_MOV_reg_mem 2
 ADDR_%2
 GET_BYTE_SPC
 mov %1,al
 STORE_FLAGS_NZ al
 OPCODE_EPILOG
%endmacro

;%1 = addr
%macro SPC_MOV_A_mem 1
ALIGNC
EXPORT_C SPC_MOV_A_%1
 SPC_MOV_reg_mem B_A,%1
%endmacro

;%1 = addr
%macro SPC_MOV_X_mem 1
ALIGNC
EXPORT_C SPC_MOV_X_%1
 SPC_MOV_reg_mem B_X,%1
%endmacro

;%1 = addr
%macro SPC_MOV_Y_mem 1
ALIGNC
EXPORT_C SPC_MOV_Y_%1
 SPC_MOV_reg_mem B_Y,%1
%endmacro

;%1 = label, %2 = reg
%macro SPC_PUSH_reg 2
ALIGNC
EXPORT_C SPC_PUSH_%1
 inc R_NativePC
 mov al,%2
 PUSH_B
 OPCODE_EPILOG
%endmacro

;%1 = label, %2 = reg
%macro SPC_POP_reg 2
ALIGNC
EXPORT_C SPC_POP_%1
 inc R_NativePC
 POP_B
 mov %2,al
 OPCODE_EPILOG
%endmacro

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -