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

📄 spc700.asm

📁 NES game Emulator in Linux.c and asm codes.
💻 ASM
📖 第 1 页 / 共 3 页
字号:

;%1 = flag
%macro SET_FLAG_SPC 1
%if %1 & SPC_FLAG_N
 mov byte [_N_flag],0x80
%endif
%if %1 & SPC_FLAG_V
 mov byte [_V_flag],1
%endif
%if %1 & SPC_FLAG_Z
 mov byte [_Z_flag],0
%endif
%if %1 & SPC_FLAG_C
 mov byte [_C_flag],1
%endif
%if %1 & SPC_FLAG_P
 mov byte [_P_flag],1
%endif
%if %1 & SPC_FLAG_I
 mov byte [_I_flag],1
%endif
%if %1 &~ (SPC_FLAG_N | SPC_FLAG_V | SPC_FLAG_Z | SPC_FLAG_C | SPC_FLAG_P | SPC_FLAG_I)
%error Unhandled flag in SET_FLAG_SPC
%endif
%endmacro

;%1 = flag
%macro CLR_FLAG_SPC 1
%if %1 == SPC_FLAG_H
 mov byte [_H_flag],0
%endif
%if %1 == SPC_FLAG_V
 mov byte [_V_flag],0
%endif
%if %1 == SPC_FLAG_Z
 mov byte [_Z_flag],1
%endif
%if %1 == SPC_FLAG_C
 mov byte [_C_flag],0
%endif
%if %1 == SPC_FLAG_P
 mov byte [_P_flag],0
%endif
%if %1 == SPC_FLAG_I
 mov byte [_I_flag],0
%endif
%if %1 &~ (SPC_FLAG_H | SPC_FLAG_V | SPC_FLAG_Z | SPC_FLAG_C | SPC_FLAG_P | SPC_FLAG_I)
%error Unhandled flag in CLR_FLAG_SPC
%endif
%endmacro

;%1 = flag
%macro CPL_FLAG_SPC 1
%if %1 == SPC_FLAG_C
 push eax
 mov al,[_C_flag]
 test al,al
 setz [_C_flag]
 pop eax
%endif
%endmacro

;%1 = flag, %2 = wheretogo
%macro JUMP_FLAG_SPC 2
%if %1 == SPC_FLAG_N
 mov ch,B_N_flag
 test ch,ch
 js %2
%elif %1 == SPC_FLAG_Z
 mov ch,B_Z_flag
 test ch,ch
 jz %2
%elif %1 == SPC_FLAG_V
 mov ch,B_V_flag
 test ch,ch
 jnz %2
%elif %1 == SPC_FLAG_C
 mov ch,B_C_flag
 test ch,ch
 jnz %2
%else
%error Unhandled flag in JUMP_FLAG_SPC
%endif
%endmacro

;%1 = flag, %2 = wheretogo
%macro JUMP_NOT_FLAG_SPC 2
%if %1 == SPC_FLAG_N
 mov ch,B_N_flag
 test ch,ch
 jns %2
%elif %1 == SPC_FLAG_Z
 mov ch,B_Z_flag
 test ch,ch
 jnz %2
%elif %1 == SPC_FLAG_V
 mov ch,B_V_flag
 test ch,ch
 jz %2
%elif %1 == SPC_FLAG_C
 mov ch,B_C_flag
 test ch,ch
 jz %2
%else
%error Unhandled flag in JUMP_NOT_FLAG_SPC
%endif
%endmacro

%macro STORE_FLAGS_P 1
 mov byte B_P_flag,%1
%endmacro

%macro STORE_FLAGS_V 1
 mov byte B_V_flag,%1
%endmacro

%macro STORE_FLAGS_H 1
 mov byte B_H_flag,%1
%endmacro

%macro STORE_FLAGS_N 1
 mov byte B_N_flag,%1
%endmacro

%macro STORE_FLAGS_Z 1
 mov byte B_Z_flag,%1
%endmacro

%macro STORE_FLAGS_I 1
 mov byte B_I_flag,%1
%endmacro

%macro STORE_FLAGS_C 1
 mov byte B_C_flag,%1
%endmacro

%macro STORE_FLAGS_NZ 1
 STORE_FLAGS_N %1
 STORE_FLAGS_Z %1
%endmacro

%macro STORE_FLAGS_NZC 2
 STORE_FLAGS_N %1
 STORE_FLAGS_Z %1
 STORE_FLAGS_C %2
%endmacro

section .data
ALIGND
EXPORT SPCOpTable
dd  C_LABEL(SPC_NOP)           ,C_LABEL(SPC_TCALL_0)    ; 00
dd  C_LABEL(SPC_SET1)          ,C_LABEL(SPC_BBS)
dd  C_LABEL(SPC_OR_A_dp)       ,C_LABEL(SPC_OR_A_abs)
dd  C_LABEL(SPC_OR_A_OXO)      ,C_LABEL(SPC_OR_A_OOdp_XOO)
dd  C_LABEL(SPC_OR_A_IM)       ,C_LABEL(SPC_OR_dp_dp)
dd  C_LABEL(SPC_OR1)           ,C_LABEL(SPC_ASL_dp)
dd  C_LABEL(SPC_ASL_abs)       ,C_LABEL(SPC_PUSH_PSW)
dd  C_LABEL(SPC_TSET1)         ,C_LABEL(SPC_INVALID)
dd  C_LABEL(SPC_BPL)           ,C_LABEL(SPC_TCALL_1)    ; 10
dd  C_LABEL(SPC_CLR1)          ,C_LABEL(SPC_BBC)
dd  C_LABEL(SPC_OR_A_Odp_XO)   ,C_LABEL(SPC_OR_A_Oabs_XO)
dd  C_LABEL(SPC_OR_A_Oabs_YO)  ,C_LABEL(SPC_OR_A_OOdpO_YO)
dd  C_LABEL(SPC_OR_dp_IM)      ,C_LABEL(SPC_OR_OXO_OYO)
dd  C_LABEL(SPC_DECW_dp)       ,C_LABEL(SPC_ASL_Odp_XO)
dd  C_LABEL(SPC_ASL_A)         ,C_LABEL(SPC_DEC_X)
dd  C_LABEL(SPC_CMP_X_abs)     ,C_LABEL(SPC_JMP_Oabs_XO)
dd  C_LABEL(SPC_CLRP)          ,C_LABEL(SPC_TCALL_2)    ; 20
dd  C_LABEL(SPC_SET1)          ,C_LABEL(SPC_BBS)
dd  C_LABEL(SPC_AND_A_dp)      ,C_LABEL(SPC_AND_A_abs)
dd  C_LABEL(SPC_AND_A_OXO)     ,C_LABEL(SPC_AND_A_OOdp_XOO)
dd  C_LABEL(SPC_AND_A_IM)      ,C_LABEL(SPC_AND_dp_dp)
dd  C_LABEL(SPC_OR1C)          ,C_LABEL(SPC_ROL_dp)
dd  C_LABEL(SPC_ROL_abs)       ,C_LABEL(SPC_PUSH_A)
dd  C_LABEL(SPC_CBNE_dp)       ,C_LABEL(SPC_BRA)
dd  C_LABEL(SPC_BMI)           ,C_LABEL(SPC_TCALL_3)    ; 30
dd  C_LABEL(SPC_CLR1)          ,C_LABEL(SPC_BBC)
dd  C_LABEL(SPC_AND_A_Odp_XO)  ,C_LABEL(SPC_AND_A_Oabs_XO)
dd  C_LABEL(SPC_AND_A_Oabs_YO) ,C_LABEL(SPC_AND_A_OOdpO_YO)
dd  C_LABEL(SPC_AND_dp_IM)     ,C_LABEL(SPC_AND_OXO_OYO)
dd  C_LABEL(SPC_INCW_dp)       ,C_LABEL(SPC_ROL_Odp_XO)
dd  C_LABEL(SPC_ROL_A)         ,C_LABEL(SPC_INC_X)
dd  C_LABEL(SPC_CMP_X_dp)      ,C_LABEL(SPC_CALL)
dd  C_LABEL(SPC_SETP)          ,C_LABEL(SPC_TCALL_4)    ; 40
dd  C_LABEL(SPC_SET1)          ,C_LABEL(SPC_BBS)
dd  C_LABEL(SPC_EOR_A_dp)      ,C_LABEL(SPC_EOR_A_abs)
dd  C_LABEL(SPC_EOR_A_OXO)     ,C_LABEL(SPC_EOR_A_OOdp_XOO)
dd  C_LABEL(SPC_EOR_A_IM)      ,C_LABEL(SPC_EOR_dp_dp)
dd  C_LABEL(SPC_AND1)          ,C_LABEL(SPC_LSR_dp)
dd  C_LABEL(SPC_LSR_abs)       ,C_LABEL(SPC_PUSH_X)
dd  C_LABEL(SPC_TCLR1)         ,C_LABEL(SPC_PCALL)
dd  C_LABEL(SPC_BVC)           ,C_LABEL(SPC_TCALL_5)    ; 50
dd  C_LABEL(SPC_CLR1)          ,C_LABEL(SPC_BBC)
dd  C_LABEL(SPC_EOR_A_Odp_XO)  ,C_LABEL(SPC_EOR_A_Oabs_XO)
dd  C_LABEL(SPC_EOR_A_Oabs_YO) ,C_LABEL(SPC_EOR_A_OOdpO_YO)
dd  C_LABEL(SPC_EOR_dp_IM)     ,C_LABEL(SPC_EOR_OXO_OYO)
dd  C_LABEL(SPC_CMPW_YA_dp)    ,C_LABEL(SPC_LSR_Odp_XO)
dd  C_LABEL(SPC_LSR_A)         ,C_LABEL(SPC_MOV_X__A)
dd  C_LABEL(SPC_CMP_Y_abs)     ,C_LABEL(SPC_JMP_abs)
dd  C_LABEL(SPC_CLRC)          ,C_LABEL(SPC_TCALL_6)    ; 60
dd  C_LABEL(SPC_SET1)          ,C_LABEL(SPC_BBS)
dd  C_LABEL(SPC_CMP_A_dp)      ,C_LABEL(SPC_CMP_A_abs)
dd  C_LABEL(SPC_CMP_A_OXO)     ,C_LABEL(SPC_CMP_A_OOdp_XOO)
dd  C_LABEL(SPC_CMP_A_IM)      ,C_LABEL(SPC_CMP_dp_dp)
dd  C_LABEL(SPC_AND1C)         ,C_LABEL(SPC_ROR_dp)
dd  C_LABEL(SPC_ROR_abs)       ,C_LABEL(SPC_PUSH_Y)
dd  C_LABEL(SPC_DBNZ_dp)       ,C_LABEL(SPC_RET)
dd  C_LABEL(SPC_BVS)           ,C_LABEL(SPC_TCALL_7)    ; 70
dd  C_LABEL(SPC_CLR1)          ,C_LABEL(SPC_BBC)
dd  C_LABEL(SPC_CMP_A_Odp_XO)  ,C_LABEL(SPC_CMP_A_Oabs_XO)
dd  C_LABEL(SPC_CMP_A_Oabs_YO) ,C_LABEL(SPC_CMP_A_OOdpO_YO)
dd  C_LABEL(SPC_CMP_dp_IM)     ,C_LABEL(SPC_CMP_OXO_OYO)
dd  C_LABEL(SPC_ADDW_YA_dp)    ,C_LABEL(SPC_ROR_Odp_XO)
dd  C_LABEL(SPC_ROR_A)         ,C_LABEL(SPC_MOV_A__X)
dd  C_LABEL(SPC_CMP_Y_dp)      ,C_LABEL(SPC_INVALID)
dd  C_LABEL(SPC_SETC)          ,C_LABEL(SPC_TCALL_8)    ; 80
dd  C_LABEL(SPC_SET1)          ,C_LABEL(SPC_BBS)
dd  C_LABEL(SPC_ADC_A_dp)      ,C_LABEL(SPC_ADC_A_abs)
dd  C_LABEL(SPC_ADC_A_OXO)     ,C_LABEL(SPC_ADC_A_OOdp_XOO)
dd  C_LABEL(SPC_ADC_A_IM)      ,C_LABEL(SPC_ADC_dp_dp)
dd  C_LABEL(SPC_EOR1)          ,C_LABEL(SPC_DEC_dp)
dd  C_LABEL(SPC_DEC_abs)       ,C_LABEL(SPC_MOV_Y_IM)
dd  C_LABEL(SPC_POP_PSW)       ,C_LABEL(SPC_MOV_dp_IM)
dd  C_LABEL(SPC_BCC)           ,C_LABEL(SPC_TCALL_9)    ; 90
dd  C_LABEL(SPC_CLR1)          ,C_LABEL(SPC_BBC)
dd  C_LABEL(SPC_ADC_A_Odp_XO)  ,C_LABEL(SPC_ADC_A_Oabs_XO)
dd  C_LABEL(SPC_ADC_A_Oabs_YO) ,C_LABEL(SPC_ADC_A_OOdpO_YO)
dd  C_LABEL(SPC_ADC_dp_IM)     ,C_LABEL(SPC_ADC_OXO_OYO)
dd  C_LABEL(SPC_SUBW_YA_dp)    ,C_LABEL(SPC_DEC_Odp_XO)
dd  C_LABEL(SPC_DEC_A)         ,C_LABEL(SPC_MOV_X__SP)
dd  C_LABEL(SPC_DIV)           ,C_LABEL(SPC_XCN)
dd  C_LABEL(SPC_EI)            ,C_LABEL(SPC_TCALL_10)   ; A0
dd  C_LABEL(SPC_SET1)          ,C_LABEL(SPC_BBS)
dd  C_LABEL(SPC_SBC_A_dp)      ,C_LABEL(SPC_SBC_A_abs)
dd  C_LABEL(SPC_SBC_A_OXO)     ,C_LABEL(SPC_SBC_A_OOdp_XOO)
dd  C_LABEL(SPC_SBC_A_IM)      ,C_LABEL(SPC_SBC_dp_dp)
dd  C_LABEL(SPC_MOV1_C_)       ,C_LABEL(SPC_INC_dp)
dd  C_LABEL(SPC_INC_abs)       ,C_LABEL(SPC_CMP_Y_IM)
dd  C_LABEL(SPC_POP_A)         ,C_LABEL(SPC_MOV_OXOInc_A)
dd  C_LABEL(SPC_BCS)           ,C_LABEL(SPC_TCALL_11)   ; B0
dd  C_LABEL(SPC_CLR1)          ,C_LABEL(SPC_BBC)
dd  C_LABEL(SPC_SBC_A_Odp_XO)  ,C_LABEL(SPC_SBC_A_Oabs_XO)
dd  C_LABEL(SPC_SBC_A_Oabs_YO) ,C_LABEL(SPC_SBC_A_OOdpO_YO)
dd  C_LABEL(SPC_SBC_dp_IM)     ,C_LABEL(SPC_SBC_OXO_OYO)
dd  C_LABEL(SPC_MOVW_YA_dp)    ,C_LABEL(SPC_INC_Odp_XO)
dd  C_LABEL(SPC_INC_A)         ,C_LABEL(SPC_MOV_SP_X)
dd  C_LABEL(SPC_INVALID)       ,C_LABEL(SPC_MOV_A_OXOInc)
dd  C_LABEL(SPC_DI)            ,C_LABEL(SPC_TCALL_12)   ; C0
dd  C_LABEL(SPC_SET1)          ,C_LABEL(SPC_BBS)
dd  C_LABEL(SPC_MOV_dp__A)     ,C_LABEL(SPC_MOV_abs__A)
dd  C_LABEL(SPC_MOV_OXO__A)    ,C_LABEL(SPC_MOV_OOdp_XOO__A)
dd  C_LABEL(SPC_CMP_X_IM)      ,C_LABEL(SPC_MOV_abs__X)
dd  C_LABEL(SPC_MOV1__C)       ,C_LABEL(SPC_MOV_dp__Y)
dd  C_LABEL(SPC_MOV_abs__Y)    ,C_LABEL(SPC_MOV_X_IM)
dd  C_LABEL(SPC_POP_X)         ,C_LABEL(SPC_MUL)
dd  C_LABEL(SPC_BNE)           ,C_LABEL(SPC_TCALL_13)   ; D0
dd  C_LABEL(SPC_CLR1)          ,C_LABEL(SPC_BBC)
dd  C_LABEL(SPC_MOV_Odp_XO__A) ,C_LABEL(SPC_MOV_Oabs_XO__A)
dd  C_LABEL(SPC_MOV_Oabs_YO__A),C_LABEL(SPC_MOV_OOdpO_YO__A)
dd  C_LABEL(SPC_MOV_dp__X)     ,C_LABEL(SPC_MOV_Odp_YO__X)
dd  C_LABEL(SPC_MOVW_dp_YA)    ,C_LABEL(SPC_MOV_Odp_XO__Y)
dd  C_LABEL(SPC_DEC_Y)         ,C_LABEL(SPC_MOV_A__Y)
dd  C_LABEL(SPC_CBNE_Odp_XO)   ,C_LABEL(SPC_INVALID)
dd  C_LABEL(SPC_CLRV)          ,C_LABEL(SPC_TCALL_14)   ; E0
dd  C_LABEL(SPC_SET1)          ,C_LABEL(SPC_BBS)
dd  C_LABEL(SPC_MOV_A_dp)      ,C_LABEL(SPC_MOV_A_abs)
dd  C_LABEL(SPC_MOV_A_OXO)     ,C_LABEL(SPC_MOV_A_OOdp_XOO)
dd  C_LABEL(SPC_MOV_A_IM)      ,C_LABEL(SPC_MOV_X_abs)
dd  C_LABEL(SPC_NOT1)          ,C_LABEL(SPC_MOV_Y_dp)
dd  C_LABEL(SPC_MOV_Y_abs)     ,C_LABEL(SPC_NOTC)
dd  C_LABEL(SPC_POP_Y)         ,C_LABEL(SPC_INVALID) ; SPC_SLEEP
dd  C_LABEL(SPC_BEQ)           ,C_LABEL(SPC_TCALL_15)   ; F0
dd  C_LABEL(SPC_CLR1)          ,C_LABEL(SPC_BBC)
dd  C_LABEL(SPC_MOV_A_Odp_XO)  ,C_LABEL(SPC_MOV_A_Oabs_XO)
dd  C_LABEL(SPC_MOV_A_Oabs_YO) ,C_LABEL(SPC_MOV_A_OOdpO_YO)
dd  C_LABEL(SPC_MOV_X_dp)      ,C_LABEL(SPC_MOV_X_Odp_YO)
dd  C_LABEL(SPC_MOV_dp_dp)     ,C_LABEL(SPC_MOV_Y_Odp_XO)
dd  C_LABEL(SPC_INC_Y)         ,C_LABEL(SPC_MOV_Y__A)
dd  C_LABEL(SPC_DBNZ_Y)        ,C_LABEL(SPC_INVALID) ;SPC_STOP

; This holds the base instruction timings in cycles
ALIGND
SPCCycleTable:
db 2,8,4,5,3,4,3,6,2,6,5,4,5,4,6,8  ; 00
db 2,8,4,5,4,5,5,6,5,5,6,5,2,2,4,6  ; 10
db 2,8,4,5,3,4,3,6,2,6,5,4,5,4,5,2  ; 20
db 2,8,4,5,4,5,5,6,5,5,6,5,2,2,3,8  ; 30
db 2,8,4,5,3,4,3,6,2,6,4,4,5,4,6,6  ; 40
db 2,8,4,5,4,5,5,6,5,5,4,5,2,2,4,3  ; 50
db 2,8,4,5,3,4,3,6,2,6,4,4,5,4,5,5  ; 60
db 2,8,4,5,4,5,5,6,5,5,5,5,2,2,3,6  ; 70
db 2,8,4,5,3,4,3,6,2,6,5,4,5,2,4,5  ; 80
db 2,8,4,5,4,5,5,6,5,5,5,5,2,2,12,5 ; 90
db 3,8,4,5,3,4,3,6,2,6,4,4,5,2,4,4  ; A0
db 2,8,4,5,4,5,5,6,5,5,5,5,2,2,3,4  ; B0
db 3,8,4,5,4,5,4,7,2,5,6,4,5,2,4,9  ; C0
db 2,8,4,5,5,6,6,7,4,5,4,5,2,2,6,3  ; D0
db 2,8,4,5,3,4,3,6,2,4,5,3,4,3,4,3  ; E0
db 2,8,4,5,4,5,5,6,3,4,5,4,2,2,4,3  ; F0

; This code should be copied into the top of the address space
ALIGND
EXPORT_C SPC_ROM_CODE
 db 0xCD,0xEF,0xBD,0xE8,0x00,0xC6,0x1D,0xD0
 db 0xFC,0x8F,0xAA,0xF4,0x8F,0xBB,0xF5,0x78
 db 0xCC,0xF4,0xD0,0xFB,0x2F,0x19,0xEB,0xF4
 db 0xD0,0xFC,0x7E,0xF4,0xD0,0x0B,0xE4,0xF5
 db 0xCB,0xF4,0xD7,0x00,0xFC,0xD0,0xF3,0xAB
 db 0x01,0x10,0xEF,0x7E,0xF4,0x10,0xEB,0xBA
 db 0xF6,0xDA,0x00,0xBA,0xF4,0xC4,0xF4,0xDD
 db 0x5D,0xD0,0xDB,0x1F,0x00,0x00,0xC0,0xFF

ALIGND
Read_Func_Map:              ; Mappings for SPC Registers
 dd C_LABEL(SPC_READ_INVALID)
 dd C_LABEL(SPC_READ_CTRL)
 dd C_LABEL(SPC_READ_DSP_ADDR)
 dd C_LABEL(SPC_READ_DSP_DATA)
 dd C_LABEL(SPC_READ_PORT0R)
 dd C_LABEL(SPC_READ_PORT1R)
 dd C_LABEL(SPC_READ_PORT2R)
 dd C_LABEL(SPC_READ_PORT3R)
 dd C_LABEL(SPC_READ_INVALID)
 dd C_LABEL(SPC_READ_INVALID)
 dd C_LABEL(SPC_READ_INVALID)
 dd C_LABEL(SPC_READ_INVALID)
 dd C_LABEL(SPC_READ_INVALID)
 dd C_LABEL(SPC_READ_COUNTER_0)
 dd C_LABEL(SPC_READ_COUNTER_1)
 dd C_LABEL(SPC_READ_COUNTER_2)

ALIGND
Write_Func_Map:             ; Mappings for SPC Registers
 dd C_LABEL(SPC_WRITE_INVALID)
 dd C_LABEL(SPC_WRITE_CTRL)
 dd C_LABEL(SPC_WRITE_DSP_ADDR)
 dd C_LABEL(SPC_WRITE_DSP_DATA)
 dd C_LABEL(SPC_WRITE_PORT0W)
 dd C_LABEL(SPC_WRITE_PORT1W)
 dd C_LABEL(SPC_WRITE_PORT2W)
 dd C_LABEL(SPC_WRITE_PORT3W)
 dd C_LABEL(SPC_WRITE_INVALID)
 dd C_LABEL(SPC_WRITE_INVALID)
 dd C_LABEL(SPC_WRITE_TIMER_0)
 dd C_LABEL(SPC_WRITE_TIMER_1)
 dd C_LABEL(SPC_WRITE_TIMER_2)
 dd C_LABEL(SPC_WRITE_INVALID)
 dd C_LABEL(SPC_WRITE_INVALID)
 dd C_LABEL(SPC_WRITE_INVALID)

offset_to_bit:  db 0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80
offset_to_not:  db 0xFE,0xFD,0xFB,0xF7,0xEF,0xDF,0xBF,0x7F

section .bss
ALIGNB
EXPORT_C TotalCycles,skipl

EXPORT_C SPC_T0_cycle_latch,skipl
EXPORT_C SPC_T0_position,skipw
EXPORT_C SPC_T0_target,skipw

EXPORT_C SPC_T1_cycle_latch,skipl
EXPORT_C SPC_T1_position,skipw
EXPORT_C SPC_T1_target,skipw

EXPORT_C SPC_T2_cycle_latch,skipl
EXPORT_C SPC_T2_position,skipw
EXPORT_C SPC_T2_target,skipw

SPC_FFC0_Address:   skipl

EXPORT_C SPC_T0_counter,skipb
EXPORT_C SPC_T1_counter,skipb
EXPORT_C SPC_T2_counter,skipb

ALIGNB
SPC_Register_Base:

SPC_Code_Base:  skipl
EXPORT _PC ,skipl
EXPORT _YA
EXPORT _A  ,skipb
EXPORT _Y  ,skipb
            skipw
SPC_PAGE:   skipl
SPC_PAGE_H equ SPC_PAGE+1
EXPORT _N_flag,skipb
EXPORT _H_flag,skipb
EXPORT _I_flag,skipb
EXPORT _B_flag,skipb
EXPORT _SP,skipl

EXPORT C_LABEL(SPC_Cycles),skipl    ; Number of cycles to execute for SPC

EXPORT _PSW,skipb   ; Processor status word
EXPORT _X  ,skipb
EXPORT _Z_flag,skipb
EXPORT _P_flag,skipb

EXPORT _V_flag,skipb
EXPORT _C_flag,skipb

EXPORT_C SPC_PORT0R,skipb
EXPORT_C SPC_PORT1R,skipb
EXPORT_C SPC_PORT2R,skipb
EXPORT_C SPC_PORT3R,skipb

EXPORT_C SPC_PORT0W,skipb
EXPORT_C SPC_PORT1W,skipb
EXPORT_C SPC_PORT2W,skipb
EXPORT_C SPC_PORT3W,skipb

ALIGNB
%ifdef DEBUG
SPC_TEMP_ADD:   skipl
%endif

section .text
ALIGNC
SNES_R2140_SPC: ; APUI00
 Execute_SPC SaveCycles
 mov al,[C_LABEL(SPC_PORT0W)]
 ret

ALIGNC
SNES_R2141_SPC: ; APUI01
 Execute_SPC SaveCycles
 mov al,[C_LABEL(SPC_PORT1W)]
 ret

ALIGNC
SNES_R2142_SPC: ; APUI02
 Execute_SPC SaveCycles
 mov al,[C_LABEL(SPC_PORT2W)]
 ret

ALIGNC
SNES_R2143_SPC: ; APUI03
 Execute_SPC SaveCycles
 mov al,[C_LABEL(SPC_PORT3W)]
 ret

ALIGNC
SNES_W2140_SPC: ; APUI00
 cmp [C_LABEL(SPC_PORT0R)],al
 jne .change
 test al,al
 jz .no_change
.change:
 Execute_SPC SaveCycles
 mov [C_LABEL(SPC_PORT0R)],al
.no_change:
 ret

ALIGNC
SNES_W2141_SPC: ; APUI01
 cmp [C_LABEL(SPC_PORT1R)],al
 jne .change
 test al,al
 jz .no_change
.change:
 Execute_SPC SaveCycles
 mov [C_LABEL(SPC_PORT1R)],al
.no_change:
 ret

ALIGNC
SNES_W2142_SPC: ; APUI02
 cmp [C_LABEL(SPC_PORT2R)],al
 jne .change
 test al,al
 jz .no_change
.change:
 Execute_SPC SaveCycles
 mov [C_LABEL(SPC_PORT2R)],al
.no_change:
 ret

ALIGNC
SNES_W2143_SPC: ; APUI03
 cmp [C_LABEL(SPC_PORT3R)],al
 jne .change
 test al,al
 jz .no_change
.change:
 Execute_SPC SaveCycles
 mov [C_LABEL(SPC_PORT3R)],al
.no_change:
 ret

ALIGNC
EXPORT_C Make_SPC
 pusha
 mov eax,SNES_R2140_SPC
 mov edx,SNES_R2141_SPC
 mov esi,SNES_R2142_SPC
 mov edi,SNES_R2143_SPC

 mov ebx,Read_21_Address(0x40)
 mov cl,0x40 / 4

.set_read_loop:
 mov [ebx],eax
 mov [ebx+1*4],edx
 mov [ebx+2*4],esi
 mov [ebx+3*4],edi
 add ebx,byte 4*4
 dec cl
 jnz .set_read_loop

 mov eax,SNES_W2140_SPC
 mov edx,SNES_W2141_SPC
 mov esi,SNES_W2142_SPC
 mov edi,SNES_W2143_SPC

 mov ebx,Write_21_Address(0x40)
 mov cl,0x40 / 4

⌨️ 快捷键说明

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