📄 spc700.asm
字号:
;%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 + -