📄 65c816.asm
字号:
movzx dword %1,word R_PC
%endmacro
; Get PB:PC from register R_PBPC
;%1 = with
%macro GET_PBPC 1
%ifnidn %1,R_PBPC
mov dword %1,R_PBPC
%endif
%endmacro
;%1 = with
%macro SAVE_PC 1
GET_PC %1
mov dword [CPU_LABEL(PC)],%1
%endmacro
; Set up the flags from PC flag format to 65816 flag format
; Corrupts arg 1, returns value in arg 2 (default to cl, al)
;|E|N|V|M|X|D|I|Z|C|
;%1 = scratchpad, %2 = output
%macro E0_SETUPFLAGS 0-2 cl,al
;%macro Flags_Native_to_65c816_E0 0-2 cl,al
%ifdef WATCH_FLAG_BREAKS
inc dword [C_LABEL(BreaksLast)]
%endif
mov byte %2,B_N_flag
shr byte %2,7
mov byte %1,B_V_flag
add byte %1,-1
adc byte %2,%2
mov byte %1,B_M1_flag
add byte %1,-1
adc byte %2,%2
mov byte %1,B_XB_flag
add byte %1,-1
adc byte %2,%2
mov byte %1,B_D_flag
add byte %1,-1
adc byte %2,%2
mov byte %1,B_I_flag
add byte %1,-1
adc byte %2,%2
mov byte %1,B_Z_flag
cmp byte %1,1
adc byte %2,%2
mov byte %1,B_C_flag
add byte %1,-1
adc byte %2,%2
%endmacro
; Set up the flags from PC flag format to 65816 flag format
; Corrupts arg 2, returns value in arg 3 (default to cl, al)
;|E|N|V|1|B|D|I|Z|C|
;%1 = break flag, %2 = scratchpad, %3 = output
%macro E1_SETUPFLAGS 0-3 1,cl,al
;%macro Flags_Native_to_65c816_E0 0-3 1,cl,al
%ifdef WATCH_FLAG_BREAKS
inc dword [C_LABEL(BreaksLast)]
%endif
mov byte %3,B_N_flag
shr byte %3,7
mov byte %2,B_V_flag
add byte %2,-1
adc byte %3,%3
mov byte %2,B_D_flag
shl byte %3,byte 2
%if %1
or byte %3,3
%else
or byte %3,2
%endif
add byte %2,-1
adc byte %3,%3
mov byte %2,B_I_flag
add byte %2,-1
adc byte %3,%3
mov byte %2,B_Z_flag
cmp byte %2,1
adc byte %3,%3
mov byte %2,B_C_flag
add byte %2,-1
adc byte %3,%3
%endmacro
%macro SETUPFLAGS 0-3 1,cl,al
%if S_8bit
E1_SETUPFLAGS %1,%2,%3
%else
E0_SETUPFLAGS %2,%3
%endif
%endmacro
;%macro Flags_65c816_to_Native_E0 0-1 R_P_B
; Restore the flags from 65c816 flag format to PC format
; Corrupts arg 1, uses value in arg 2 (default to cl, al)
;%1 = scratchpad, %2 = input
%macro E0_RESTOREFLAGS 0-2 cl,al
;%macro Flags_65c816_to_Native 0-2 cl,al
%ifdef WATCH_FLAG_BREAKS
inc dword [C_LABEL(BreaksLast)]
%endif
mov byte B_N_flag,%2 ;negative
shl byte %2,2 ;start next (overflow)
sbb byte %1,%1
add byte %2,%2 ;start next (memory/accumulator size)
mov byte B_V_flag,%1
sbb byte %1,%1
add byte %2,%2 ;start next (index size)
mov byte B_M1_flag,%1
sbb byte %1,%1
add byte %2,%2 ;start next (decimal mode)
mov byte B_XB_flag,%1
sbb byte %1,%1
add byte %2,%2 ;start next (interrupt disable)
mov byte B_D_flag,%1
sbb byte %1,%1
add byte %2,%2 ;start next (zero)
mov byte B_I_flag,%1
sbb byte %1,%1
xor byte %1,0xFF
add byte %2,%2 ;start next (carry)
mov byte B_Z_flag,%1
sbb byte %1,%1
mov byte B_C_flag,%1
%endmacro
;%macro Flags_65c816_to_Native_E1 0-1 R_P_B
; Restore the flags from 65c816 flag format to PC format
; Corrupts arg 1, uses value in arg 2 (default to cl, al)
;%1 = scratchpad, %2 = input
%macro E1_RESTOREFLAGS 0-2 cl,al
;%macro Flags_65c816_to_Native 0-2 cl,al
%ifdef WATCH_FLAG_BREAKS
inc dword [C_LABEL(BreaksLast)]
%endif
mov byte B_N_flag,%2 ;negative
shl byte %2,2 ;start next (overflow)
sbb byte %1,%1
shl byte %2,3 ;start next (decimal mode)
mov byte B_V_flag,%1
;mov byte B_M1_flag,1
;mov byte B_XB_flag,1
sbb byte %1,%1
add byte %2,%2 ;start next (interrupt disable)
mov byte B_D_flag,%1
sbb byte %1,%1
add byte %2,%2 ;start next (zero)
mov byte B_I_flag,%1
sbb byte %1,%1
xor byte %1,0xFF
add byte %2,%2 ;start next (carry)
mov byte B_Z_flag,%1
sbb byte %1,%1
mov byte B_C_flag,%1
%endmacro
%macro RESTOREFLAGS 0-2 cl,al
%if S_8bit
E1_RESTOREFLAGS %1,%2
%else
E0_RESTOREFLAGS %1,%2
%endif
%endmacro
; Set the current opcode execution and timing table pointers based
; on the M and X bits of flag register. This returns control to the
; execution loop, so it must be the last instruction
; Corrupts eax,ecx
%macro SET_TABLE_MX 0
mov al,B_XB_flag
mov cl,B_M1_flag
add al,255
sbb eax,eax
add cl,255
adc eax,eax
and eax,byte 3
JUMP_NOT_FLAG SNES_FLAG_X,%%index_16
mov [CPU_LABEL(XH)],ah ; Clear XH/YH if X flag set
mov [CPU_LABEL(YH)],ah
%%index_16:
mov eax,[CPU_OpTables+eax*4]
mov [OpTable],eax
OPCODE_EPILOG
%endmacro
; Push/Pull macros assume eax contains value - corrupt ebx
%macro FAST_SET_BYTE_STACK_NATIVE_MODE 1
cmp bh,0x20
jnb %%not_within_wram
mov byte [C_LABEL(WRAM)+ebx],%1
%%not_within_wram:
add R_Cycles,_5A22_SLOW_CYCLE
%endmacro
%macro FAST_GET_BYTE_STACK_NATIVE_MODE 1
cmp bh,0x20
jnb %%not_within_wram
mov %1,byte [C_LABEL(WRAM)+ebx]
%%not_within_wram:
add R_Cycles,_5A22_SLOW_CYCLE
%endmacro
%macro FAST_SET_BYTE_STACK_EMULATION_MODE 1
mov byte [C_LABEL(WRAM)+ebx],%1
add R_Cycles,_5A22_SLOW_CYCLE
%endmacro
%macro FAST_GET_BYTE_STACK_EMULATION_MODE 1
mov %1,byte [C_LABEL(WRAM)+ebx]
add R_Cycles,_5A22_SLOW_CYCLE
%endmacro
; Native mode - push byte (S--)
%macro E0_PUSH_B 0
mov ebx,[CPU_LABEL(S)] ; S only - bank always 0!
%ifdef FAST_STACK_ACCESS_NATIVE_MODE
FAST_SET_BYTE_STACK_NATIVE_MODE al
%else
SET_BYTE
%endif
dec ebx ; Postdecrement S
mov [CPU_LABEL(S)],bx ; Set stack pointer
%endmacro
; Emulation mode - push byte (SL--)
%macro E1_PUSH_B 0
mov ebx,[CPU_LABEL(S)] ; S only - bank always 0!
dec byte [CPU_LABEL(S)] ; Postdecrement SL
%ifdef FAST_STACK_ACCESS_EMULATION_MODE
FAST_SET_BYTE_STACK_EMULATION_MODE al
%else
SET_BYTE
%endif
%endmacro
%macro PUSH_B 0
%if S_8bit
E1_PUSH_B
%else
E0_PUSH_B
%endif
%endmacro
; Native mode - pull byte (++S)
%macro E0_PULL_B 0
mov ebx,[CPU_LABEL(S)] ; S only - bank always 0!
inc bx ; Preincrement S
mov [CPU_LABEL(S)],ebx ; Set stack pointer
%ifdef FAST_STACK_ACCESS_NATIVE_MODE
FAST_GET_BYTE_STACK_NATIVE_MODE al
%else
GET_BYTE
%endif
%endmacro
; Emulation mode - pull byte (++SL)
%macro E1_PULL_B 0
inc byte [CPU_LABEL(S)] ; Preincrement SL
mov ebx,[CPU_LABEL(S)] ; S only - bank always 0!
%ifdef FAST_STACK_ACCESS_EMULATION_MODE
FAST_GET_BYTE_STACK_EMULATION_MODE al
%else
GET_BYTE
%endif
%endmacro
%macro PULL_B 0
%if S_8bit
E1_PULL_B
%else
E0_PULL_B
%endif
%endmacro
; Native mode - push word (S--)
%macro E0_PUSH_W 0
mov ebx,[CPU_LABEL(S)] ; S only - bank always 0!
%ifdef FAST_STACK_ACCESS_NATIVE_MODE
cmp bh,0x20
jnb %%not_within_wram_hi
mov byte [C_LABEL(WRAM)+ebx],ah
%%not_within_wram_hi:
%else
push eax
mov al,ah
SET_BYTE
%endif
dec bx ; Postdecrement S
%ifdef FAST_STACK_ACCESS_NATIVE_MODE
cmp bh,0x20
jnb %%not_within_wram_lo
mov byte [C_LABEL(WRAM)+ebx],al
%%not_within_wram_lo:
%else
pop eax
SET_BYTE
%endif
dec bx ; Postdecrement S
mov [CPU_LABEL(S)],ebx ; Set stack pointer
%endmacro
;Emulation mode - push word (SL--)
; pass argument of 'New' for opcodes new to 16-bit 65xx
; (temporary address is 16-bit, but SH not changed after opcode)
%macro E1_PUSH_W 0-1 0
mov ebx,[CPU_LABEL(S)] ; S only - bank always 0!
%ifdef FAST_STACK_ACCESS_EMULATION_MODE
FAST_SET_BYTE_STACK_EMULATION_MODE ah
%else
push eax
mov al,ah
SET_BYTE
%endif
%ifnidni %1,New
dec bl ; Postdecrement SL
%else
dec bx ; Postdecrement S
%endif
%ifdef FAST_STACK_ACCESS_EMULATION_MODE
FAST_SET_BYTE_STACK_EMULATION_MODE al
%else
pop eax
SET_BYTE
%endif
dec bl ; Postdecrement SL
mov [CPU_LABEL(S)],bl ; Set stack pointer
%endmacro
%macro PUSH_W 0-1 0
%if S_8bit
E1_PUSH_W %1
%else
E0_PUSH_W
%endif
%endmacro
;Native mode - push word (S--)
%macro E0_PULL_W 0
mov ebx,[CPU_LABEL(S)] ; S only - bank always 0!
inc bx ; Preincrement S
%ifdef FAST_STACK_ACCESS_NATIVE_MODE
cmp bh,0x20
jnb %%not_within_wram_lo
mov al,byte [C_LABEL(WRAM)+ebx]
%%not_within_wram_lo:
%else
GET_BYTE
mov ah,al
%endif
inc bx ; Preincrement S
%ifdef FAST_STACK_ACCESS_NATIVE_MODE
cmp bh,0x20
jnb %%not_within_wram_hi
mov ah,byte [C_LABEL(WRAM)+ebx]
%%not_within_wram_hi:
%else
GET_BYTE
ror ax,8
%endif
mov [CPU_LABEL(S)],ebx ; Set stack pointer
%endmacro
;Emulation mode - pull word (++SL)
; pass argument of 'New' for opcodes new to 16-bit 65xx
; (temporary address is 16-bit, but SH not changed after opcode)
%macro E1_PULL_W 0-1 0
%ifnidni %1,New
inc byte [CPU_LABEL(S)] ; Preincrement SL
mov ebx,[CPU_LABEL(S)] ; S only - bank always 0!
%else
mov ebx,[CPU_LABEL(S)] ; S only - bank always 0!
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -