.686 ; create 32 bit code
.mmx
.xmm
.model flat, stdcall ; 32 bit memory model
option casemap :none ; case sensitive
; ===========================================================================
;
;
;
; this source is based on VirtuaNES && (\virtuanessrc097\NES\Cpu.cpp)
; nesterJ && (nesterj_0_51_05_src\gui\SRC\NES\CPU\Nes6502.c)
; C/CPP into ASM by xuling
;
;
; 2A03 Instruction comment from nesdev.com (nesdev_weekly\www\6502.txt)
;
;
;
; ===========================================================================
;=======================
; Interrupt
;=======================
NMI_VECTOR equ FFFAh ; nmi
RES_VECTOR equ FFFCh ; reset
IRQ_VECTOR equ FFFEh ; irq
NMI_FLAG equ 2 ; nmi interrupt pending flag
IRQ_FLAG equ 1 ; irq interrupt pending flag
;=======================
; Pro Status
;=======================
C_FLAG equ 01h ; 1: carry
Z_FLAG equ 02h ; 1: zero
I_FLAG equ 04h ; 1: intterrupt enable
D_FLAG equ 08h ; 1: dec mode nes did not use this mode
B_FLAG equ 10h ; 1: software intterrupt flag
R_FLAG equ 20h ; 1: this flag is reserved
V_FLAG equ 40h ; 1: overflow flag
N_FLAG equ 80h ; 1: negative flag
INT_C equ 7
DUMMY_SBC_V_TEST equ 0
byt equ byte ptr
wot equ word ptr
dwot equ dword ptr
$a equ dword ptr[edi] ; 0
$x equ dword ptr[edi+4] ; 1
$y equ dword ptr[edi+8] ; 2
$s equ dword ptr[edi+12] ; 3
$p equ dword ptr[edi+16] ; 4
$pc equ dword ptr[edi+20] ; 5
$dma equ dword ptr[edi+24] ; 6
$dis equ dword ptr[edi+28] ; 7
$t1 equ dword ptr[edi+32] ; 8
ALIGNXMM equ align 16
;=======================
; extern symbols
;=======================
extrn nes_Read@4:proc
extrn nes_Write@8:proc
extrn nes_Readw@4:proc
extrn ram:far
extrn regs:far
extrn zn_Table:far
extrn dma_Cycles:far
extrn cpu_banks:far
extrn int_Pending:far
;===================
; Function
;===================
.code
exec2a03 proc C
option prologue:none, epilogue:none
push ebx ;U - save old frame
push esi ;V - save old frame
push edi ;U - save old frame
push ebp ;V - save old frame
; esi edi ebx ebp unscratch regs we can use this to do useful things
; eax ecx edx scratch regs to do logic opr use completion can be discarded
; ebx <- save now P (nes's PSW reg)
; ebp <- save exec Cycles counter
; esi <- save now PC (nes's EIP reg)
; edi <- save regs root
lea edi, regs ;U - ebx <- save regs root
mov eax, dwot[esp+20];V - /N load dispatch Cycles-> arg1
xor ebp, ebp ;U - reset Cycles counter
mov $dis, eax ;V - write back adjacent mem reduce cache pollute
mov esi, $pc ;U - load PC
mov ebx, $p ;V - load P
ALIGNXMM ; align
main_Loop:
mov eax, $dis ;U - load dispatch Cycles
mov edx, ebp ;V - copy Now Cycles counter
mov ecx, $dma ;U - /N load now DMA Cycles
mov ebp, edx ;V -
cmp eax, edx ;U - dispatch Cycles > Cycles counter ?
jg do_DMA_test ;V - TRUE:remain Cycles alive do DMA test FALSE:remain burning out
mov eax, ebp ;U - return now Cycles counter
mov ecx, edx ;V -
mov $pc, esi ;U - write back PC
mov $p, ebx ;V - write back P
pop ebp ;U - thaw old frame
pop edi ;V - thaw old frame
pop esi ;U - thaw old frame
pop ebx ;V - thaw old frame
ret ;N - proc ret ...
ALIGNXMM
do_DMA_test:
test ecx, ecx ;U - DMA Cycles active ?
je dec_Begin ;V - TRUE calc Cycles FALSE:immed decode
sub eax, edx ;U - remain Cycles
lea edi, [edi] ;V -
cmp ecx, eax ;U - cmp DMA Cycles/remain Cycles
jge remain_Out ;V - TRUE:remain Cycles burning out FALSE: DMA Cycles burning out
add ebp, ecx ;U - dma buring out
mov $dma, 0 ;V - reset DMA Cycles
lea eax, [eax] ;U -
jmp dec_Begin ;V - jmp decode ... short jmp
ALIGNXMM
remain_Out:
sub ecx, eax ;U - remain cycles buring out
mov eax, $dis;V - Cycles just enough
mov $dma, ecx ;U - write back DMA Cycles
mov $pc, esi ;U - write back PC
mov $p, ebx ;V - write back P
pop ebp ;U - thaw old frame
pop edi ;V - thaw old frame
pop esi ;U - thaw old frame
pop ebx ;V - thaw old frame
ret ;N - proc ret ...
ALIGNXMM
dec_Begin:
mov eax, esi ;U - load PC
inc esi ;V - ++ PC
mov edx, eax ;U - copy PC
and eax, 0FFFFh ;V - limit bits
shr eax, 13 ;U - get Bank ID
and edx, 01FFFh ;V - Bank's interval
mov ecx, dwot[cpu_banks+eax*4] ;U - get Bank ID
lea edx, [edx] ;V -
movzx eax, byt[ecx+edx] ;N - get PC's val
lea edx, [edx+ecx+1] ;U - next addr index
jmp [OPTAB+eax*4] ;V - /N short/far jmp
;***
; ADC
; 69: #$ 2 cycles
; 65: ZERO PAGE 3 cycles
; 75: ZERO PAGE X 4 cycles
; 6D: ABS 4 cycles
; 07Dh: ABS X 4 cycles (crossing page ++ cycles)
; 79: ABS Y 4 cycles (crossing page ++ cycles)
; 61: X INDIRECT 6 cycles
; 71: INDIRECT Y 4 cycles (crossing page ++ cycles)
; Algorithm:
;
; unsigned int temp = src + AC + (IF_CARRY() ? 1 : 0);
; SET_ZERO(temp & 0xff); /* This is not valid in decimal mode */
; if (IF_DECIMAL()) {
; if (((AC & 0xf) + (src & 0xf) + (IF_CARRY() ? 1 : 0)) > 9) {
; temp += 6;
; }
; SET_SIGN(temp);
; SET_OVERFLOW(!((AC ^ src) & 0x80) && ((AC ^ temp) & 0x80));
; if (temp > 0x99) {
; temp += 96;
; }
; SET_CARRY(temp > 0x99);
; } else {
; SET_SIGN(temp);
; SET_OVERFLOW(!((AC ^ src) & 0x80) && ((AC ^ temp) & 0x80));
; SET_CARRY(temp > 0xff);
; }
; AC = ((BYTE) temp);
;*************************************************
OP69: ; ADC #$ 2 cycles
movzx ecx, byt[edx] ;N - load #$
movzx eax, byt[edi] ;N - load REG A
and ebx, 00111101b ;U - clr N-V-Z Flags
lea esi, [esi+1] ;V - ++ PC
shr ebx, 1 ;U - with C
lea ebp, [ebp+2] ;V - 2 Cycles
adc al, cl ;U - ADC
mov dl, dl ;V -
seto cl ;N - SETcc set O flag
rcl ebx, 1 ;N - C Flag into NES's Flag REG
shl ecx, 6 ;U - reset pos (ready to NES's V Flag)
or ebx, dwot[zn_Table+eax*4] ;V - reset Z-N Flags
or ebx, ecx ;U - reset V Flag
mov $a, eax ;V - write Back REG A
jmp PollInt ;N - ...
OP65: ; ADC ZERO PAGE 3 cycles
movzx eax, byt[edx] ;N - load addr8Real
movzx ecx, byt[ram+eax];N - load addr8Real's VAL
movzx eax, byt[edi] ;N - load REG A
and ebx, 00111101b ;U - clr N-V-Z Flags
lea esi, [esi+1] ;V - ++ PC
shr ebx, 1 ;U - with C
lea ebp, [ebp+3] ;V - 3 Cycles
adc al, cl ;U - ADC
mov dl, dl ;V -
seto cl ;N - SETcc set O flag
rcl ebx, 1 ;N - C Flag into NES's Flag REG
shl ecx, 6 ;U - reset pos (ready to NES's V Flag)
or ebx, dwot[zn_Table+eax*4] ;V - reset Z-N Flags
or ebx, ecx ;U - reset V Flag
mov $a, eax ;V - write Back REG A
jmp PollInt ;N - ...
OP75: ; ADC ZERO PAGE X 4 cycles
movzx eax, byt[edx] ;N - load addr8Temp
add al, byt[edi+4] ;U - get addr8Real
mov bl, bl ;V -
movzx ecx, byt[ram+eax];N - load addr8Real's VAL
movzx eax, byt[edi] ;N - load REG A
and ebx, 00111101b ;U - clr N-V-Z Flags
lea esi, [esi+1] ;V - ++ PC
shr ebx, 1 ;U - with C
lea ebp, [ebp+4] ;V - 4 Cycles
adc al, cl ;U - ADC
mov dl, dl ;V -
seto cl ;N - SETcc set O flag
rcl ebx, 1 ;N - C Flag into NES's Flag REG
shl ecx, 6 ;U - reset pos (ready to NES's V Flag)
or ebx, dwot[zn_Table+eax*4] ;V - reset Z-N Flags
or ebx, ecx ;U - reset V Flag
mov $a, eax ;V - write Back REG A
jmp PollInt ;N - ...
OP6D: ; ADC ABS 4 cycles
mov ax, wot[edx] ;U - load addr16Real
add si, 2 ;V - ++ PC
push eax ;U - PUSH addr16Real
lea ebp, [ebp+4] ;V - 4 Cycles
call nes_Read@4 ;N - call PROC
movzx ecx, byt[edi] ;N - load REG A
and ebx, 00111101b ;U - clr N-V-Z Flags
and eax, 0FFh ;V - limit Bits
shr ebx, 1 ;U - with C
mov ebp, ebp ;V -
adc cl, al ;U - ADC
mov dl, dl ;V -
seto al ;N - SETcc set O flag
rcl ebx, 1 ;N - C Flag into NES's Flag REG
shl eax, 6 ;U - reset pos (ready to NES's V Flag)
or ebx, dwot[zn_Table+ecx*4] ;V - reset Z-N Flags
or ebx, eax ;U - reset V Flag
mov $a, ecx ;V - write Back REG A
jmp PollInt ;N - ...
OP7D: ; ADC ABS X 4 cycles (corssing page)
movzx eax, wot[edx] ;N - load addr16Temp
movzx ecx, byt[edi+4] ;N - load REG X
add ecx, eax ;U - ABS X
lea esi, [esi+2] ;V - ++ PC
and bl, 00111101b ;U - clr N-V-Z Flags
sub ah, ch ;V - test CrossPage
adc ebp, 4 ;U - 4/5 Cycles
push ecx ;V - PUSH addr16Real
call nes_Read@4 ;N - call PROC
movzx ecx, byt[edi] ;N - load REG A
and eax, 0FFh ;U - limit Bits
mov edx, edx ;V -
shr ebx, 1 ;U - with C
mov ebx, ebx ;V -
adc cl, al ;U - ADC
mov dl, dl ;V -
seto al ;N - SETcc set O flag
rcl ebx, 1 ;N - C Flag into NES's Flag REG
shl eax, 6 ;U - reset pos (ready to NES's V Flag)
or ebx, dwot[zn_Table+ecx*4] ;V - reset Z-N Flags
or ebx, eax ;U - reset V Flag
mov $a, ecx ;V - write Back REG A
jmp PollInt ;N - ...
OP79: ; ADC ABS Y 4 cycles (corssing page)
movzx eax, wot[edx] ;N - load addr16Temp
movzx ecx, byt[edi+8] ;N - load REG Y
add ecx, eax ;U - ABS Y
lea esi, [esi+2] ;V - ++ PC
and bl, 00111101b ;U - clr N-V-Z Flags
sub ah, ch ;V - test CrossPage
adc ebp, 4 ;U - 4/5 Cycles
push ecx ;V - PUSH addr16Real
call nes_Read@4 ;N - call PROC
movzx ecx, byt[edi] ;N - load REG A
and eax, 0FFh ;U - limit Bits
mov edx, edx ;V -
shr ebx, 1 ;U - with C
mov ebx, ebx ;V -
adc cl, al ;U - ADC
mov dl, dl ;V -
seto al ;N - SETcc set O flag
rcl ebx, 1 ;N - C Flag into NES's Flag REG
shl eax, 6 ;U - reset pos (ready to NES's V Flag)
or ebx, dwot[zn_Table+ecx*4] ;V - reset Z-N Flags
or ebx, eax ;U - reset V Flag
mov $a, ecx ;V - write Back REG A
jmp PollInt ;N - ...
OP61: ; ADC X INDIRECT 6 cycles
movzx eax, byt[edx] ;N - load addr8Temp
add al, byt[edi+4] ;U - X INDIRECT
and bl, 00111101b ;V - clr N-V-Z Flags
mov cx, wot[eax+ram];U - get addr16Real
add bp, 6 ;V - 6 Cycles
push ecx ;U - PUSH addr16Real
lea esi, [esi+1] ;V - ++ PC
call nes_Read@4 ;N - call PROC
movzx ecx, byt[edi] ;N - load REG A
and eax, 0FFh ;U - limit Bits
mov edx, edx ;V -
shr ebx, 1 ;U - with C
mov ebx, ebx ;V -
adc cl, al ;U - ADC
mov dl, dl ;V -
seto al ;N - SETcc set O flag
rcl ebx, 1 ;N - C Flag into NES's Flag REG
shl eax, 6 ;U - reset pos (ready to NES's V Flag)
or ebx, dwot[zn_Table+ecx*4] ;V - reset Z-N Flags
or ebx, eax ;U - reset V Flag
mov $a, ecx ;V - write Back REG A
jmp PollInt ;N - ...
OP71: ; ADC INDIRECT Y
movzx edx, byt[edx] ;N - load addr8Real
movzx eax, wot[edx+ram];N - load addr16Temp
movzx ecx, byt[edi+8] ;N - load REG Y
add ecx, eax ;U - ABS Y
lea esi, [esi+1] ;V - ++ PC
and bl, 00111101b ;U - clr N-V-Z Flags
sub ah, ch ;V - test CrossPage
adc ebp, 4 ;U - 4/5 Cycles
push ecx ;V - PUSH addr16Real
call nes_Read@4 ;N - call PROC
movzx ecx, byt[edi] ;N - load REG A
and eax, 0FFh ;U - limit Bits
mov edx, edx ;V -
shr ebx, 1 ;U - with C
mov ebx, ebx ;V -
adc cl, al ;U - ADC
mov dl, dl ;V -
seto al ;N - SETcc set O flag
rcl ebx, 1 ;N - C Flag into NES's Flag REG
shl eax, 6 ;U - reset pos (ready to NES's V Flag)
or ebx, dwot[zn_Table+ecx*4] ;V - reset Z-N Flags
or ebx, eax ;U - reset V Flag
mov $a, ecx ;V - write Back REG A
jmp PollInt ;N - ...
;***
; SBC
; EB: #$ 2 cycles (unofficial)
; E9: #$ 2 cycles
; E5: ZERO PAGE 3 cycles
; F5: ZERO PAGE X 4 cycles
; ED: ABS 4 cycles
; FD: ABS X 4 cycles (crossing page ++ cycles)
; F9: ABS Y 4 cycles (crossing page ++ cycles)
; E1: X INDIRECT 6 cycles
; F1: INDIRECT Y 4 cycles (crossing page ++ cycles)
; Algorithm:
;
; unsigned int temp = AC - src - (IF_CARRY() ? 0 : 1);
; SET_SIGN(temp);
; SET_ZERO(temp & 0xff); /* Sign and Zero are invalid in decimal mode */
; SET_OVERFLOW(((AC ^ temp) & 0x80) && ((AC ^ src) & 0x80));
; if (IF_DECIMAL()) {
; if ( ((AC & 0xf) - (IF_CARRY() ? 0 : 1)) < (src & 0xf)) /* EP */ {
; temp -= 6;
; }
; if (temp > 0x99) {
; temp -= 0x60;
; }
; }
; SET_CARRY(temp < 0x100);
; AC = (temp & 0xff);
;*************************************************
OPE9: ; SBC #$ 2 cycles
movzx ecx, byt[edx] ;N - load #$
movzx eax, byt[edi] ;N - load REG A
and ebx, 00111101b ;U - clr N-V-Z Flags
lea esi, [esi+1] ;V - ++ PC
xor ebx, 1 ;U - NEG C
mov eax, eax ;V -
shr ebx, 1 ;U - with C
lea ebp, [ebp+2] ;V - 2 Cycles
sbb al, cl ;U - SBC
mov dl, dl ;V -
IFDEF DUMMY_SBC_V_TEST
seto cl ;N - SETcc set O flag
ELSE
setno cl ;N - SETcc set O flag
ENDIF
rcl ebx, 1 ;N - C Flag into NES's Flag REG
xor ebx, 1 ;U - NEG C
mov eax, eax ;V -
shl ecx, 6 ;U - reset pos (ready to NES's V Flag)
or ebx, dwot[zn_Table+eax*4] ;V - reset Z-N Flags
or ebx, ecx ;U - reset V Flag
mov $a, eax ;V - write Back REG A
jmp PollInt ;N - ...
OPE5: ; SBC ZERO PAGE 3 cycles
movzx ecx, byt[edx] ;N - load addr8Real
movzx ecx, byt[ram+ecx];N - load VAL
movzx eax, byt[edi] ;N - load REG A
and ebx, 00111101b ;U - clr N-V-Z Flags
lea esi, [esi+1] ;V - ++ PC
xor ebx, 1 ;U - NEG C
mov eax, eax ;V -
shr ebx, 1 ;U - with C
lea ebp, [ebp+3] ;V - 3 Cycles
sbb al, cl ;U - SBC
mov dl, dl ;V -
IFDEF DUMMY_SBC_V_TEST
seto cl ;N - SETcc set O flag
ELSE
setno cl ;N - SETcc set O flag
ENDIF
rcl ebx, 1 ;N - C Flag into NES's Flag REG
xor ebx, 1 ;U - NEG C
mov eax, eax ;V -
shl ecx, 6 ;U - reset pos (ready to NES's V Flag)
or ebx, dwot[zn_Table+eax*4] ;V - reset Z-N Flags
or ebx, ecx ;U - reset V Flag
mov $a, eax ;V - write Back REG A
jmp PollInt ;N - ...
OPF5: ; SBC ZERO PAGE X 4 cycles
movzx ecx, byt[edx] ;N - load addr8Real
add cl, byt[edi+4] ;U - ZERO PAGE X
mov dl, dl ;V -
movzx ecx, byt[ram+ecx];N - load VAL
movzx eax, byt[edi] ;N - load REG A
and ebx, 00111101b ;U - clr N-V-Z Flags
lea esi, [esi+1] ;V - ++ PC
xor ebx, 1 ;U - NEG C
mov eax, eax ;V -
shr ebx, 1 ;U - with C
lea ebp, [ebp+4] ;V - 4 Cycles
sbb al, cl ;U - SBC
mov dl, dl ;V -
IFDEF DUMMY_SBC_V_TEST
seto cl ;N - SETcc set O flag
ELSE
setno cl ;N - SETcc set O flag
ENDIF
rcl ebx, 1 ;N - C Flag into NES's Flag REG
xor ebx, 1 ;U - NEG C
mov eax, eax ;V -
shl ecx, 6 ;U - reset pos (ready to NES's V Flag)
or ebx, dwot[zn_Table+eax*4] ;V - reset Z-N Flags
or ebx, ecx ;U - reset V Flag
mov $a, eax ;V - write Back REG A
jmp PollInt ;N - ...
OPED: ; SBC ABS 4 cycles
mov ax, wot[edx] ;U - load addr16Real
add si, 2 ;V - ++ PC
push eax ;U - PUSH addr16Real
lea ebp, [ebp+4] ;V - 4 Cycles
call nes_Read@4 ;N - call PROC
movzx ecx, byt[edi] ;N - load REG A
and ebx, 00111101b ;U - clr N-V-Z Flags
and eax, 0FFh ;V - limit Bits
xor ebx, 1 ;U - NEG C
mov eax, eax ;V -
shr ebx, 1 ;U - with C
mov ebp, ebp ;V -
sbb cl, al ;U - SBC
mov dl, dl ;V -
IFDEF DUMMY_SBC_V_TEST
seto al ;N - SETcc set O flag
ELSE
setno al ;N - SETcc set O flag
ENDIF
rcl ebx, 1 ;N - C Flag into NES's Flag REG
xor ebx, 1 ;U - NEG C
mov eax, eax ;V -
shl eax, 6 ;U - reset pos (ready to NES's V Flag)
or ebx, dwot[zn_Table+ecx*4] ;V - reset Z-N Flags
or ebx, eax ;U - reset V Flag
mov $a, ecx ;V - write Back REG A
jmp PollInt ;N - ...
OPFD: ; SBC ABS X 4 cycles (corssing page)
movzx eax, wot[edx] ;N - load addr16Temp
movzx ecx, byt[edi+4] ;N - load REG X
add ecx, eax ;U - ABS X
lea esi, [esi+2] ;V - ++ PC
and bl, 00111101b ;U - clr N-V-Z Flags
sub ah, ch ;V - test CrossPage
adc ebp, 4 ;U - 4/5 Cycles
push ecx ;V - PUSH addr16Real
call nes_Read@4 ;N - call PROC
movzx ecx, byt[edi] ;N - load REG A
and eax, 0FFh ;U - limit Bits
xor ebx, 1 ;V - NEG C
shr ebx, 1 ;U - with C
mov ebx, ebx ;V -
sbb cl, al ;U - SBC
mov dl, dl ;V -
IFDEF DUMMY_SBC_V_TEST
seto al ;N - SETcc set O flag
ELSE
setno al ;N - SETcc set O flag
ENDIF
rcl ebx, 1 ;N - C Flag into NES's Flag REG
xor ebx, 1 ;U - NEG C
mov eax, eax ;V -
shl eax, 6 ;U - reset pos (ready to NES's V Flag)
or ebx, dwot[zn_Table+ecx*4] ;V - reset Z-N Flags
or ebx, eax ;U - reset V Flag
mov $a, ecx ;V - write Back REG A
jmp PollInt ;N - ...
OPF9: ; SBC ABS Y 4 cycles (corssing page)
movzx eax, wot[edx] ;N - load addr16Temp
movzx ecx, byt[edi+8] ;N - load REG Y
add ecx, eax ;U - ABS Y
lea esi, [esi+2] ;V - ++ PC
and bl, 00111101b ;U - clr N-V-Z Flags
sub ah, ch ;V - test CrossPage
adc ebp, 4 ;U - 4/5 Cycles
push ecx ;V - PUSH addr16Real
call nes_Read@4 ;N - call PROC
movzx ecx, byt[edi] ;N - load REG A
and eax, 0FFh ;U - limit Bits
xor ebx, 1 ;V - NEG C
shr ebx, 1 ;U - with C
mov ebx, ebx ;V -
sbb cl, al ;U - SBC
mov dl, dl ;V -
IFDEF DUMMY_SBC_V_TEST
seto al ;N - SETcc set O flag
ELSE
setno al ;N - SETcc set O flag
ENDIF
rcl ebx, 1 ;N - C Flag into NES's Flag REG
xor ebx, 1 ;U - NEG C
mov eax, eax ;V -
shl eax, 6 ;U - reset pos (ready to NES's V Flag)
or ebx, dwot[zn_Table+ecx*4] ;V - reset Z-N Flags
or ebx, eax ;U - reset V Flag
mov $a, ecx ;V - write Back REG A
jmp PollInt ;N - ...
OPE1: ; SBC X INDIRECT
movzx eax, byt[edx] ;N - load addr8Temp
add al, byt[edi+4] ;U - X INDIRECT
and bl, 00111101b ;V - clr N-V-Z Flags
mov cx, wot[eax+ram];U - get addr16Real
add bp, 6 ;V - 6 Cycles
push ecx ;U - PUSH addr16Real
lea esi, [esi+1] ;V - ++ PC
call nes_Read@4 ;N - call PROC
movzx ecx, byt[edi] ;N - load REG A
and eax, 0FFh ;U - limit Bits
xor ebx, 1 ;V - NEG C
shr ebx, 1 ;U - with C
mov ebx, ebx ;V -
sbb cl, al ;U - SBC
mov dl, dl ;V -
IFDEF DUMMY_SBC_V_TEST
seto al ;N - SETcc set O flag
ELSE
setno al ;N - SETcc set O flag
ENDIF
rcl ebx, 1 ;N - C Flag into NES's Flag REG
xor ebx, 1 ;U - NEG C
mov eax, eax ;V -
shl eax, 6 ;U - reset pos (ready to NES's V Flag)
or ebx, dwot[zn_Table+ecx*4] ;V - reset Z-N Flags
or ebx, eax ;U - reset V Flag
mov $a, ecx ;V - write Back REG A
jmp PollInt ;N - ...
OPF1: ; SBC INDIRECT Y
movzx edx, byt[edx] ;N - load addr8Real
movzx eax, wot[edx+ram];N - load addr16Temp
movzx ecx, byt[edi+8] ;N - load REG Y
add ecx, eax ;U - ABS Y
lea esi, [esi+1] ;V - ++ PC
and bl, 00111101b ;U - clr N-V-Z Flags
sub ah, ch ;V - test CrossPage
adc ebp, 4 ;U - 4/5 Cycles
push ecx ;V - PUSH addr16Real
call nes_Read@4 ;N - call PROC
movzx ecx, byt[edi] ;N - load REG A
and eax, 0FFh ;U - limit Bits
xor ebx, 1 ;V - NEG C
shr ebx, 1 ;U - with C
mov ebx, ebx ;V -
sbb cl, al ;U - SBC
mov dl, dl ;V -
IFDEF DUMMY_SBC_V_TEST
seto al ;N - SETcc set O flag
ELSE
setno al ;N - SETcc set O flag
ENDIF
rcl ebx, 1 ;N - C Flag into NES's Flag REG
xor ebx, 1 ;U - NEG C
mov eax, eax ;V -
shl eax, 6 ;U - reset pos (ready to NES's V Flag)
or ebx, dwot[zn_Table+ecx*4] ;V - reset Z-N Flags
or ebx, eax ;U - reset V Flag
mov $a, ecx ;V - write Back REG A
jmp PollInt ;N - ...
;***
; DEC
; C6: ZERO PAGE 5 cycles
; D6: ZERO PAGE X 6 cycles
; CE: ABS 6 cycles
; DE: ABS X 7 cycles
; X CA: REG 2 cycles
; Y 88: REG 2 cycles
; Algorithm:
;
; src = (src - 1) & 0xff;
; SET_SIGN(src);
; SET_ZERO(src);
; STORE(address, (src));
;*************************************************
OPC6: ; DEC ZERO PAGE 5 Cycles
movzx eax, byt[edx] ;N - eax <- a8Real
movzx ecx, byt[ram+eax] ;N - ecx <- MEM
dec ecx ;U - DEC
lea esi, [esi+1] ;V - ++ PC
and ecx, 0FFh ;U -
lea ebp, [ebp+5] ;V - 5 Cycles
mov byt[ram+eax], cl ;U - MEM <- ecx
and bl, 07Dh ;V - clr Z-N
or ebx, dwot[zn_Table+ecx*4] ;U - set Z-N
jmp PollInt ;N -
OPD6: ; DEC ZERO PAGE X 6 cycles
movzx eax, byt[edx] ;N - eax <- a8Temp
add al, byt[edi+4] ;U - eax <- a8Real
mov dl, dl ;V -
movzx ecx, byt[ram+eax] ;N - ecx <- MEM
dec ecx ;U - DEC
lea esi, [esi+1] ;V - ++ PC
and ecx, 0FFh ;U -
lea ebp, [ebp+6] ;V - 6 Cycles
mov byt[ram+eax], cl ;U - MEM <- ecx
and bl, 07Dh ;V - clr Z-N
or ebx, dwot[zn_Table+ecx*4] ;U - set Z-N
jmp PollInt ;N -
OPCE: ; DEC ABS 6 cycles
movzx ecx, wot[edx] ;N - load addr16Real
push ecx ;U - ready addr16Real<-nes_Read's arg
mov $t1, ecx ;V - save old frame
call nes_Read@4 ;N - call nes_Read@4
dec eax ;U - DEC OPR
and ebx, 07Dh ;V - clr Z-N Flags
push eax ;U - arg2
push $t1 ;V - arg1
and eax, 0FFh ;U - limit Bits
lea esi, [esi+2] ;V - ++ PC
or ebx, dwot[zn_Table+eax*4] ;U - reset Z-N Flags
lea ebp, [ebp+6] ;V - 6 Cycles
call nes_Write@8 ;N - call nes_Write@8
jmp PollInt ;N - ...
OPDE: ; DEC ABS X 7 cycles
movzx ecx, wot[edx] ;N - load addr16Temp
movzx eax, byt[edi+4] ;N - load REG X
mov ebx, ebx ;U -
add ecx, eax ;V - ABS X get addr16Real
push ecx ;U - ready addr16Real<-nes_Read's arg
mov $t1, ecx ;V - save old frame
call nes_Read@4 ;N - call nes_Read@4
dec eax ;U - DEC OPR
and ebx, 07Dh ;V - clr Z-N Flags
push eax ;U - arg2
push $t1 ;V - arg1
and eax, 0FFh ;U - limit Bits
lea esi, [esi+2] ;V - ++ PC
or ebx, dwot[zn_Table+eax*4] ;U - reset Z-N Flags
lea ebp, [ebp+7] ;V - 7 Cycles
call nes_Write@8 ;N - call nes_Write@8
jmp PollInt ;N - ...
OPCA: ; DEX 2 cycles
mov eax, $x ;U - load REG X
lea ebp, [ebp+2] ;V - 2 Cycles
dec eax ;U - DEC OPR
and ebx, 07Dh ;V - clr Z-N Flags
mov $x, eax ;U - write REG X
and eax, 0FFh ;V - limit Bits
or ebx, dwot[zn_Table+eax*4] ;U - reset Z-N Flags
jmp PollInt ;V - /N ...
OP88: ; DEY
mov eax, $y ;U - load REG Y
lea ebp, [ebp+2] ;V - 2 Cycles
dec eax ;U - DEC OPR
and ebx, 07Dh ;V - clr Z-N Flags
mov $y, eax ;U - write REG Y
and eax, 0FFh ;V - limit Bits
or ebx, dwot[zn_Table+eax*4] ;U - reset Z-N Flags
jmp PollInt ;V - /N ...
;***
; INC
; E6: ZERO PAGE 5 cycles
; F6: ZERO PAGE X 6 cycles
; EE: ABS 6 cycles
; FE: ABS X 7 cycles
; X E8: REG 2 cycles
; Y C8: REG 2 cycles
; Algorithm:
;
; src = (src + 1) & 0xff;
; SET_SIGN(src);
; SET_ZERO(src);
; STORE(address, (src));
;*************************************************
OPE6: ; INC ZERO PAGE 5 cycles
movzx eax, byt[edx] ;N - load ZeroPage Index
movzx ecx, byt[ram+eax] ;N - load From MEM ->
inc cl ;U - INC OPR
mov ebx, ebx ;V -
mov ecx, ecx ;U -
lea esi, [esi+1] ;V - ++ PC
mov byt[ram+eax], cl ;U - write Back MEM <-
and bl, 07Dh ;V - clr Z-N Flags
lea ebp, [ebp+5] ;U - 5 Cycles
or ebx, dwot[zn_Table+ecx*4] ;V - reset Z-N Flags
jmp PollInt ;N - ...
OPF6: ; INC ZERO PAGE X 6 cycles
movzx eax, byt[edx] ;N - load ZeroPage Index
add al, byt[edi+4] ;U - ZERO PAGE X
mov bl, bl ;V -
movzx ecx, byt[ram+eax] ;N - load From MEM ->
inc cl ;U - INC OPR
mov ebx, ebx ;V -
mov ecx, ecx ;U -
lea esi, [esi+1] ;V - ++ PC
mov byt[ram+eax], cl ;U - write Back MEM <-
and bl, 07Dh ;V - clr Z-N Flags
lea ebp, [ebp+6] ;U - 6 Cycles
or ebx, dwot[zn_Table+ecx*4] ;V - reset Z-N Flags
jmp PollInt ;N - ...
OPEE: ; INC ABS 6 cycles
movzx ecx, wot[edx] ;N - load addr16Real
push ecx ;U - ready addr16Real<-nes_Read's arg
mov $t1, ecx ;V - save old frame
call nes_Read@4 ;N - call nes_Read@4
inc eax ;U - INC OPR
and ebx, 07Dh ;V - clr Z-N Flags
push eax ;U - arg2
push $t1 ;V - arg1
and eax, 0FFh ;U - limit Bits
lea esi, [esi+2] ;V - ++ PC
or ebx, dwot[zn_Table+eax*4] ;U - reset Z-N Flags
lea ebp, [ebp+6] ;V - 6 Cycles
call nes_Write@8 ;N - call nes_Write@8
jmp PollInt ;N - ...
OPFE: ; INC ABS X 7 cycles
movzx ecx, wot[edx] ;N - load addr16Temp
movzx eax, byt[edi+4] ;N - load REG X
mov ebx, ebx ;U -
add ecx, eax ;V - ABS X get addr16Real
push ecx ;U - ready addr16Real<-nes_Read's arg
mov $t1, ecx ;V - save old frame
call nes_Read@4 ;N - call nes_Read@4
inc eax ;U - INC OPR
and ebx, 07Dh ;V - clr Z-N Flags
push eax ;U - arg2
push $t1 ;V - arg1
and eax, 0FFh ;U - limit Bits
lea esi, [esi+2] ;V - ++ PC
or ebx, dwot[zn_Table+eax*4] ;U - reset Z-N Flags
lea ebp, [ebp+7] ;V - 7 Cycles
call nes_Write@8 ;N - call nes_Write@8
jmp PollInt ;N - ...
OPE8: ; INX
mov eax, $x ;U - load REG X
lea ebp, [ebp+2] ;V - 2 Cycles
inc eax ;U - INC OPR
and ebx, 07Dh ;V - clr Z-N Flags
mov $x, eax ;U - write REG X
and eax, 0FFh ;V - limit Bits
or ebx, dwot[zn_Table+eax*4] ;U - reset Z-N Flags
jmp PollInt ;V - /N ...
OPC8: ; INY
mov eax, $y ;U - load REG Y
lea ebp, [ebp+2] ;V - 2 Cycles
inc eax ;U - INC OPR
and ebx, 07Dh ;V - clr Z-N Flags
mov $y, eax ;U - write REG Y
and eax, 0FFh ;V - limit Bits
or ebx, dwot[zn_Table+eax*4] ;U - reset Z-N Flags
jmp PollInt ;V - /N ...
;***
; CMP
; C9: #$ 2 cycles
; C5: ZERO PAGE 3 cycles
; D5: ZERO PAGE X 4 cycles
; CD: ABS 4 cycles
; DD: ABS X 4 cycles (crossing page ++ cycles)
; D9: ABS Y 4 cycles (crossing page ++ cycles)
; C1: X INDIRECT 6 cycles
; D1: INDIRECT Y 5 cycles (crossing page ++ cycles)
; X E0: #$ 2 cycles
; X E4: ZERO PAGE 3 cycles
; X EC: ABS 4 cycles
; Y C0: #$ 2 cycles
; Y C4: ZERO PAGE 3 cycles
; Y CC: ABS 4 cycles
;
; Algorithm:
;
; src = AC - src;
; SET_CARRY(src < 0x100);
; SET_SIGN(src);
; SET_ZERO(src &= 0xff);
;*************************************************
; =====
; A
; =====
OPC9: ; CMP #$ 2 cycles
mov cl, byt[edx] ;U - ecx <- MEM
mov al, byt[edi] ;V - eax <- A
and bl, 01111100b ;U - clr Z-N-C
sub al, cl ;V - CMP
setnc cl ;N - get C
lea ebp, [ebp+2] ;U - 2 Cycles
and eax, 0FFh ;V -
or ebx, dwot[zn_Table+eax*4] ;U - set Z-N
lea esi, [esi+1] ;V - ++ PC
or ebx, ecx ;U - set C
jmp PollInt ;V - /N ...
OPC5: ; CMP ZERO PAGE 3 cycles
movzx ecx, byt[edx] ;N - ecx <- a8Real
mov cl, byt[ram+ecx];U - ecx <- MEM
mov al, byt[edi] ;V - eax <- A
and bl, 01111100b ;U - clr Z-N-C
sub al, cl ;V - CMP
setnc cl ;N - get C
lea ebp, [ebp+3] ;U - 3 Cycles
and eax, 0FFh ;V -
or ebx, dwot[zn_Table+eax*4] ;U - set Z-N
lea esi, [esi+1] ;V - ++ PC
or ebx, ecx ;U - set C
jmp PollInt ;V - /N ...
OPD5: ; CMP ZERO PAGE X 4 cycles
movzx ecx, byt[edx] ;N - ecx <- a8Temp
add cl, byt[edi+4] ;U - ecx <- a8Real
mov al, al ;V -
mov dl, byt[ram+ecx];U - edx <- MEM
mov al, byt[edi] ;V - eax <- A
and bl, 01111100b ;U - clr Z-N-C
sub al, dl ;V - CMP
setnc dl ;N -
lea ebp, [ebp+4] ;U - 4 Cycles
and eax, 0FFh ;V -
or ebx, dwot[zn_Table+eax*4] ;U - set Z-N
lea esi, [esi+1] ;V - ++ PC
or ebx, edx ;U - set C
jmp PollInt ;V - /N ...
OPCD: ; CMP ABS 4 cycles
mov ax, wot[edx] ;U - eax <- a16Real
add si, 2 ;V - ++ PC
push eax ;U -
lea ebp, [ebp+4] ;V - 4 Cycles
call nes_Read@4 ;N -
and bl, 01111100b ;U - clr Z-N-C
mov cl, byt[edi] ;V - ecx <- A
sub cl, al ;U - CMP
mov dl, dl ;V -
setnc al ;N - SETcc
or ebx, eax ;U - set C
and ecx, 0FFh ;V -
or ebx, dwot[zn_Table+ecx*4] ;U - set Z-N
jmp PollInt ;V - /N ...
OPDD: ; CMP ABS X (test cross page)
movzx ecx, byt[edi+4] ;N - ecx <- X
movzx eax, wot[edx] ;U - eax <- a16Temp
add ecx, eax ;U -
lea esi, [esi+2] ;V - ++ PC
push ecx ;U -
mov esi, esi ;V -
sub ah, ch ;U -
mov dh, dh ;V -
adc ebp, 4 ;U - 4/5 Cycles
mov eax, eax ;V -
call nes_Read@4 ;N -
and bl, 01111100b ;U - clr Z-N-C
mov cl, byt[edi] ;V - ecx <- A
sub cl, al ;U - CMP
mov dl, dl ;V -
setnc al ;N - SETcc
or ebx, eax ;U - set C
and ecx, 0FFh ;V -
or ebx, dwot[zn_Table+ecx*4] ;U - set Z-N
jmp PollInt ;V - /N ...
OPD9: ; CMP ABS Y (test cross page)
movzx ecx, byt[edi+8] ;N - ecx <- Y
movzx eax, wot[edx] ;U - eax <- a16Temp
add ecx, eax ;U -
lea esi, [esi+2] ;V - ++ PC
push ecx ;U -
mov esi, esi ;V -
sub ah, ch ;U -
mov dh, dh ;V -
adc ebp, 4 ;U - 4/5 Cycles
mov eax, eax ;V -
call nes_Read@4 ;N -
and bl, 01111100b ;U - clr Z-N-C
mov cl, byt[edi] ;V - ecx <- A
sub cl, al ;U - CMP
mov dl, dl ;V -
setnc al ;N - SETcc
or ebx, eax ;U - set C
and ecx, 0FFh ;V -
or ebx, dwot[zn_Table+ecx*4] ;U - set Z-N
jmp PollInt ;V - /N ...
OPC1: ; CMP X INDIRECT 6 cycles
movzx eax, byt[edx] ;N - eax <- a8Temp
add al, byt[edi+4] ;U - eax <- a8Real
mov bl, bl ;V -
movzx eax, wot[ram+eax];N -
lea esi, [esi+1] ;U - ++ PC
mov ebx, ebx ;V -
push eax ;U -
lea ebp, [ebp+6] ;V - 6 Cycles
call nes_Read@4 ;N -
and bl, 01111100b ;U - clr Z-N-C
mov cl, byt[edi] ;V - ecx <- A
sub cl, al ;U - CMP
mov dl, dl ;V -
setnc al ;N - SETcc
or ebx, eax ;U - set C
and ecx, 0FFh ;V -
or ebx, dwot[zn_Table+ecx*4] ;U - set Z-N
jmp PollInt ;V - /N ...
OPD1: ; CMP INDIRECT Y (test cross page)
movzx ecx, byt[edi+8] ;N - ecx <- Y
movzx eax, byt[edx] ;N - eax <- a8Real
movzx eax, wot[ram+eax];N - eax <- a16Real
add ecx, eax ;U -
lea esi, [esi+1] ;V - ++ PC
push ecx ;U -
mov esi, esi ;V -
sub ah, ch ;U -
mov dh, dh ;V -
adc ebp, 5 ;U - 5/6 Cycles
mov eax, eax ;V -
call nes_Read@4 ;N -
and bl, 01111100b ;U - clr Z-N-C
mov cl, byt[edi] ;V - ecx <- A
sub cl, al ;U - CMP
mov dl, dl ;V -
setnc al ;N - SETcc
or ebx, eax ;U - set C
and ecx, 0FFh ;V -
or ebx, dwot[zn_Table+ecx*4] ;U - set Z-N
jmp PollInt ;V - /N ...
; =====
; X
; =====
OPE0: ; CPX #$
mov cl, byt[edx] ;U - ecx <- MEM
mov al, byt[edi+4] ;V - eax <- X
and bl, 01111100b ;U - clr Z-N-C
sub al, cl ;V - CMP
setnc cl ;N - get C
lea ebp, [ebp+2] ;U - 2 Cycles
and eax, 0FFh ;V -
or ebx, dwot[zn_Table+eax*4] ;U - set Z-N
lea esi, [esi+1] ;V - ++ PC
or ebx, ecx ;U - set C
jmp PollInt ;V - /N ...
OPE4: ; CPX ZERO PAGE
movzx ecx, byt[edx] ;N - ecx <- a8Real
mov cl, byt[ram+ecx];U - ecx <- MEM
mov al, byt[edi+4] ;V - eax <- X
and bl, 01111100b ;U - clr Z-N-C
sub al, cl ;V - CMP
setnc cl ;N - get C
lea ebp, [ebp+3] ;U - 3 Cycles
and eax, 0FFh ;V -
or ebx, dwot[zn_Table+eax*4] ;U - set Z-N
lea esi, [esi+1] ;V - ++ PC
or ebx, ecx ;U - set C
jmp PollInt ;V - /N ...
OPEC: ; CPX ABS
mov ax, wot[edx] ;U - eax <- a16Real
add si, 2 ;V - ++ PC
push eax ;U -
lea ebp, [ebp+4] ;V - 4 Cycles
call nes_Read@4 ;N -
and bl, 01111100b ;U - clr Z-N-C
mov cl, byt[edi+4] ;V - ecx <- X
sub cl, al ;U - CMP
mov dl, dl ;V -
setnc al ;N - SETcc
or ebx, eax ;U - set C
and ecx, 0FFh ;V -
or ebx, dwot[zn_Table+ecx*4] ;U - set Z-N
jmp PollInt ;V - /N ...
; =====
; y
; =====
OPC0: ; CPY #$
mov cl, byt[edx] ;U - ecx <- MEM
mov al, byt[edi+8] ;V - eax <- Y
and bl, 01111100b ;U - clr Z-N-C
sub al, cl ;V - CMP
setnc cl ;N - get C
lea ebp, [ebp+2] ;U - 2 Cycles
and eax, 0FFh ;V -
or ebx, dwot[zn_Table+eax*4] ;U - set Z-N
lea esi, [esi+1] ;V - ++ PC
or ebx, ecx ;U - set C
jmp PollInt ;V - /N ...
OPC4: ; CPY ZERO PAGE
movzx ecx, byt[edx] ;N - ecx <- a8Real
mov cl, byt[ram+ecx];U - ecx <- MEM
mov al, byt[edi+8] ;V - eax <- Y
and bl, 01111100b ;U - clr Z-N-C
sub al, cl ;V - CMP
setnc cl ;N - get C
lea ebp, [ebp+3] ;U - 3 Cycles
and eax, 0FFh ;V -
or ebx, dwot[zn_Table+eax*4] ;U - set Z-N
lea esi, [esi+1] ;V - ++ PC
or ebx, ecx ;U - set C
jmp PollInt ;V - /N ...
OPCC: ; CPY ABS
mov ax, wot[edx] ;U - eax <- a16Real
add si, 2 ;V - ++ PC
push eax ;U -
lea ebp, [ebp+4] ;V - 4 Cycles
call nes_Read@4 ;N -
and bl, 01111100b ;U - clr Z-N-C
mov cl, byt[edi+8] ;V - ecx <- Y
sub cl, al ;U - CMP
mov dl, dl ;V -
setnc al ;N - SETcc
or ebx, eax ;U - set C
and ecx, 0FFh ;V -
or ebx, dwot[zn_Table+ecx*4] ;U - set Z-N
jmp PollInt ;V - /N ...
OP90: ; BCC C clr JMP
test ebx, 00000001b
je Fhit
jmp Fnhit
OPD0: ; BNE Z clr JMP
test ebx, 00000010b
je Fhit
jmp Fnhit
OP10: ; BPL N clr JMP
test ebx, 10000000b
je Fhit
jmp Fnhit
OP50: ; BVC V clr JMP
test ebx, 01000000b
je Fhit
jmp Fnhit
OPB0: ; BCS C set JMP
test ebx, 00000001b
jne Fhit
jmp Fnhit
OPF0: ; BEQ Z set JMP
test ebx, 00000010b
jne Fhit
jmp Fnhit
OP30: ; BMI N set JMP
test ebx, 10000000b
jne Fhit
jmp Fnhit
OP70: ; BVS V set JMP
test ebx, 01000000b
jne Fhit
jmp Fnhit
ALIGNXMM
Fhit:
add ebp, 3 ; hit 3 Cycles
movsx ecx, byt[edx]
lea esi, [ecx+esi+1]
jmp PollInt
ALIGNXMM
Fnhit:
add ebp, 2 ; miss 2 Cycles
add esi, 1
jmp PollInt
;***
; ORA
; 09: #$ 2 cycles
; 05: ZERO PAGE 3 cycles
; 15: ZERO PAGE X 4 cycles
; 0D: ABS 4 cycles
; 1D: ABS X 4 cycles (crossing page ++ cycles)
; 19: ABS Y 4 cycles (crossing page ++ cycles)
; 01: X INDIRECT 6 cycles
; 11: INDIRECT Y 4 cycles (crossing page ++ cycles)
; Algorithm:
;
; src |= AC;
; SET_SIGN(src);
; SET_ZERO(src);
; AC = src;
;*************************************************
OP09: ; ORA #$
movzx eax, byt[edx] ;N - load #$
movzx ecx, byt[edi] ;N - load REG A
or ecx, eax ;U - ORA OPR
and ebx, 07Dh ;V - clr Z-N Flags
lea ebp, [ebp+2] ;U - 2 Cycles
or ebx, dwot[zn_Table+ecx*4] ;V - reset Z-N Flags
lea esi, [esi+1] ;U - ++ PC
mov $a, ecx ;V - write Back REG A
jmp PollInt ;N - ...
OP05: ; ORA ZERO PAGE
movzx ecx, byt[edx] ;N - load addr8Real
movzx eax, byt[ram+ecx];N - load VAL
movzx ecx, byt[edi] ;N - load REG A
or ecx, eax ;U - ORA OPR
and ebx, 07Dh ;V - clr Z-N Flags
lea ebp, [ebp+3] ;U - 3 Cycles
or ebx, dwot[zn_Table+ecx*4] ;V - reset Z-N Flags
lea esi, [esi+1] ;U - ++ PC
mov $a, ecx ;V - write Back REG A
jmp PollInt ;N - ...
OP15: ; ORA ZERO PAGE X
movzx ecx, byt[edx] ;N - load addr8Real
add cl, byt[edi+4] ;U - ZERO PAGE X
mov dl, dl ;V -
movzx eax, byt[ram+ecx];N - load VAL
movzx ecx, byt[edi] ;N - load REG A
or ecx, eax ;U - ORA OPR
and ebx, 07Dh ;V - clr Z-N Flags
lea ebp, [ebp+4] ;U - 4 Cycles
or ebx, dwot[zn_Table+ecx*4] ;V - reset Z-N Flags
lea esi, [esi+1] ;U - ++ PC
mov $a, ecx ;V - write Back REG A
jmp PollInt ;N - ...
OP0D: ; ORA ABS
movzx ecx, wot[edx] ;N - load addr16Real
push ecx ;U -
lea ebp, [ebp+4] ;V - 4 Cycles
call nes_Read@4 ;N -
movzx ecx, byt[edi] ;N - load REG A
or cl, al ;U - ORA OPR
and bl, 07Dh ;V - clr Z-N Flags
mov $a, ecx ;U - write Back REG A
lea esi, [esi+2] ;V - ++ PC
or ebx, dwot[zn_Table+ecx*4] ;V - reset Z-N Flags
jmp PollInt ;V - /N ...
OP1D: ; ORA ABS X
movzx eax, wot[edx] ;N - load addr16Temp
movzx edx, byt[edi+4] ;N - load REG X
add dx, ax ;U - ABS X
add si, 2 ;V - ++ PC
push edx ;U - PUSH arg wait call PROC
lea ebp, [ebp+4] ;V - 4 Cycles
and bl, 07Dh ;U - clr Z-N Flags
sub ah, dh ;V - test CrossPage
adc ebp, 0 ;U -
mov eax, eax ;V -
call nes_Read@4 ;N - call PROC
movzx ecx, byt[edi] ;N - load REG A
or cl, al ;U - ORA OPR
mov dl, dl ;V -
mov $a, ecx ;U - write Back REG A
mov eax, eax ;V -
or ebx, dwot[zn_Table+ecx*4] ;V - reset Z-N Flags
jmp PollInt ;V - /N ...
OP19: ; ORA ABS Y
movzx eax, wot[edx] ;N - load addr16Temp
movzx edx, byt[edi+8] ;N - load REG Y
add dx, ax ;U - ABS Y
add si, 2 ;V - ++ PC
push edx ;U - PUSH arg wait call PROC
lea ebp, [ebp+4] ;V - 4 Cycles
and bl, 07Dh ;U - clr Z-N Flags
sub ah, dh ;V - test CrossPage
adc ebp, 0 ;U -
mov eax, eax ;V -
call nes_Read@4 ;N - call PROC
movzx ecx, byt[edi] ;N - load REG A
or cl, al ;U - ORA OPR
mov dl, dl ;V -
mov $a, ecx ;U - write Back REG A
mov eax, eax ;V -
or ebx, dwot[zn_Table+ecx*4] ;V - reset Z-N Flags
jmp PollInt ;V - /N ...
OP01: ; ORA X INDIRECT
movzx eax, byt[edx] ;N - load addr8Real
add al, byt[edi+4] ;U - X INDIRECT
and bl, 07Dh ;V - clr Z-N Flags
mov dx, wot[ram+eax];U - load addr16Real
add si, 1 ;V - ++ PC
push edx ;U -
lea ebp, [ebp+6] ;V - 6 Cycles
call nes_Read@4 ;N - call PROC
movzx ecx, byt[edi] ;N - load REG A
or cl, al ;U - ORA OPR
mov dl, dl ;V -
mov $a, ecx ;U - write Back REG A
mov eax, eax ;V -
or ebx, dwot[zn_Table+ecx*4] ;V - reset Z-N Flags
jmp PollInt ;V - /N ...
OP11: ; ORA INDIRECT Y
movzx ecx, byt[edx] ;N - load addr8Real
movzx eax, wot[ram+ecx];N - load addr16Temp
movzx edx, byt[edi+8] ;N - load REG Y
add dx, ax ;U - ABS Y
add si, 1 ;V - ++ PC
push edx ;U - PUSH arg wait call PROC
lea ebp, [ebp+4] ;V - 4 Cycles
and bl, 07Dh ;U - clr Z-N Flags
sub ah, dh ;V - test CrossPage
adc ebp, 0 ;U -
mov eax, eax ;V -
call nes_Read@4 ;N - call PROC
movzx ecx, byt[edi] ;N - load REG A
or cl, al ;U - ORA OPR
mov dl, dl ;V -
mov $a, ecx ;U - write Back REG A
mov eax, eax ;V -
or ebx, dwot[zn_Table+ecx*4] ;V - reset Z-N Flags
jmp PollInt ;V - /N ...
;***
; EOR
; 49: #$ 2 cycles
; 45: ZERO PAGE 3 cycles
; 55: ZERO PAGE X 4 cycles
; 4D: ABS 4 cycles
; 5D: ABS X 4 cycles (crossing page ++ cycles)
; 59: ABS Y 4 cycles (crossing page ++ cycles)
; 41: X INDIRECT 6 cycles
; 51: INDIRECT Y 4 cycles (crossing page ++ cycles)
; Algorithm:
;
; src ^= AC;
; SET_SIGN(src);
; SET_ZERO(src);
; AC = src;
;*************************************************
OP49: ; EOR #$
movzx eax, byt[edx] ;N - load #$
movzx ecx, byt[edi] ;N - load REG A
xor ecx, eax ;U - EOR OPR
and ebx, 07Dh ;V - clr Z-N Flags
lea ebp, [ebp+2] ;U - 2 Cycles
or ebx, dwot[zn_Table+ecx*4] ;V - reset Z-N Flags
lea esi, [esi+1] ;U - ++ PC
mov $a, ecx ;V - write Back REG A
jmp PollInt ;N - ...
OP45: ; EOR ZERO PAGE
movzx ecx, byt[edx] ;N - load addr8Real
movzx eax, byt[ram+ecx];N - load VAL
movzx ecx, byt[edi] ;N - load REG A
xor ecx, eax ;U - EOR OPR
and ebx, 07Dh ;V - clr Z-N Flags
lea ebp, [ebp+3] ;U - 3 Cycles
or ebx, dwot[zn_Table+ecx*4] ;V - reset Z-N Flags
lea esi, [esi+1] ;U - ++ PC
mov $a, ecx ;V - write Back REG A
jmp PollInt ;N - ...
OP55: ; EOR ZERO PAGE X
movzx ecx, byt[edx] ;N - load addr8Real
add cl, byt[edi+4] ;U - ZERO PAGE X
mov dl, dl ;V -
movzx eax, byt[ram+ecx];N - load VAL
movzx ecx, byt[edi] ;N - load REG A
xor ecx, eax ;U - EOR OPR
and ebx, 07Dh ;V - clr Z-N Flags
lea ebp, [ebp+4] ;U - 4 Cycles
or ebx, dwot[zn_Table+ecx*4] ;V - reset Z-N Flags
lea esi, [esi+1] ;U - ++ PC
mov $a, ecx ;V - write Back REG A
jmp PollInt ;N - ...
OP4D: ; EOR ABS
movzx ecx, wot[edx] ;N - load addr16Real
push ecx ;U -
lea ebp, [ebp+4] ;V - 4 Cycles
call nes_Read@4 ;N -
movzx ecx, byt[edi] ;N - load REG A
xor cl, al ;U - EOR OPR
and bl, 07Dh ;V - clr Z-N Flags
mov $a, ecx ;U - write Back REG A
lea esi, [esi+2] ;V - ++ PC
or ebx, dwot[zn_Table+ecx*4] ;V - reset Z-N Flags
jmp PollInt ;V - /N ...
OP5D: ; EOR ABS X
movzx eax, wot[edx] ;N - load addr16Temp
movzx edx, byt[edi+4] ;N - load REG X
add dx, ax ;U - ABS X
add si, 2 ;V - ++ PC
push edx ;U - PUSH arg wait call PROC
lea ebp, [ebp+4] ;V - 4 Cycles
and bl, 07Dh ;U - clr Z-N Flags
sub ah, dh ;V - test CrossPage
adc ebp, 0 ;U -
mov eax, eax ;V -
call nes_Read@4 ;N - call PROC
movzx ecx, byt[edi] ;N - load REG A
xor cl, al ;U - EOR OPR
mov dl, dl ;V -
mov $a, ecx ;U - write Back REG A
mov eax, eax ;V -
or ebx, dwot[zn_Table+ecx*4] ;V - reset Z-N Flags
jmp PollInt ;V - /N ...
OP59: ; EOR ABS Y
movzx eax, wot[edx] ;N - load addr16Temp
movzx edx, byt[edi+8] ;N - load REG Y
add dx, ax ;U - ABS Y
add si, 2 ;V - ++ PC
push edx ;U - PUSH arg wait call PROC
lea ebp, [ebp+4] ;V - 4 Cycles
and bl, 07Dh ;U - clr Z-N Flags
sub ah, dh ;V - test CrossPage
adc ebp, 0 ;U -
mov eax, eax ;V -
call nes_Read@4 ;N - call PROC
movzx ecx, byt[edi] ;N - load REG A
xor cl, al ;U - EOR OPR
mov dl, dl ;V -
mov $a, ecx ;U - write Back REG A
mov eax, eax ;V -
or ebx, dwot[zn_Table+ecx*4] ;V - reset Z-N Flags
jmp PollInt ;V - /N ...
OP41: ; EOR X INDIRECT
movzx eax, byt[edx] ;N - load addr8Real
add al, byt[edi+4] ;U - X INDIRECT
and bl, 07Dh ;V - clr Z-N Flags
mov dx, wot[ram+eax];U - load addr16Real
add si, 1 ;V - ++ PC
push edx ;U -
lea ebp, [ebp+6] ;V - 6 Cycles
call nes_Read@4 ;N - call PROC
movzx ecx, byt[edi] ;N - load REG A
xor cl, al ;U - EOR OPR
mov dl, dl ;V -
mov $a, ecx ;U - write Back REG A
mov eax, eax ;V -
or ebx, dwot[zn_Table+ecx*4] ;V - reset Z-N Flags
jmp PollInt ;V - /N ...
OP51: ; EOR INDIRECT Y
movzx ecx, byt[edx] ;N - load addr8Real
movzx eax, wot[ram+ecx];N - load addr16Temp
movzx edx, byt[edi+8] ;N - load REG Y
add dx, ax ;U - ABS Y
add si, 1 ;V - ++ PC
push edx ;U - PUSH arg wait call PROC
lea ebp, [ebp+4] ;V - 4 Cycles
and bl, 07Dh ;U - clr Z-N Flags
sub ah, dh ;V - test CrossPage
adc ebp, 0 ;U -
mov eax, eax ;V -
call nes_Read@4 ;N - call PROC
movzx ecx, byt[edi] ;N - load REG A
xor cl, al ;U - EOR OPR
mov dl, dl ;V -
mov $a, ecx ;U - write Back REG A
mov eax, eax ;V -
or ebx, dwot[zn_Table+ecx*4] ;V - reset Z-N Flags
jmp PollInt ;V - /N ...
;***
; AND
; 29: #$ 2 cycles
; 25: ZERO PAGE 3 cycles
; 35: ZERO PAGE X 4 cycles
; 2D: ABS 4 cycles
; 3D: ABS X 4 cycles (crossing page ++ cycles)
; 39: ABS Y 4 cycles (crossing page ++ cycles)
; 21: X INDIRECT 6 cycles
; 31: INDIRECT Y 4 cycles (crossing page ++ cycles)
; Algorithm:
;
; src &= AC;
; SET_SIGN(src);
; SET_ZERO(src);
; AC = src;
;*************************************************
OP29: ; AND #$
movzx eax, byt[edx] ;N - load #$
movzx ecx, byt[edi] ;N - load REG A
and ecx, eax ;U - AND OPR
and ebx, 07Dh ;V - clr Z-N Flags
lea ebp, [ebp+2] ;U - 2 Cycles
or ebx, dwot[zn_Table+ecx*4] ;V - reset Z-N Flags
lea esi, [esi+1] ;U - ++ PC
mov $a, ecx ;V - write Back REG A
jmp PollInt ;N - ...
OP25: ; AND ZERO PAGE
movzx ecx, byt[edx] ;N - load addr8Real
movzx eax, byt[ram+ecx];N - load VAL
movzx ecx, byt[edi] ;N - load REG A
and ecx, eax ;U - AND OPR
and ebx, 07Dh ;V - clr Z-N Flags
lea ebp, [ebp+3] ;U - 3 Cycles
or ebx, dwot[zn_Table+ecx*4] ;V - reset Z-N Flags
lea esi, [esi+1] ;U - ++ PC
mov $a, ecx ;V - write Back REG A
jmp PollInt ;N - ...
OP35: ; AND ZERO PAGE X
movzx ecx, byt[edx] ;N - load addr8Real
add cl, byt[edi+4] ;U - ZERO PAGE X
mov dl, dl ;V -
movzx eax, byt[ram+ecx];N - load VAL
movzx ecx, byt[edi] ;N - load REG A
and ecx, eax ;U - AND OPR
and ebx, 07Dh ;V - clr Z-N Flags
lea ebp, [ebp+4] ;U - 4 Cycles
or ebx, dwot[zn_Table+ecx*4] ;V - reset Z-N Flags
lea esi, [esi+1] ;U - ++ PC
mov $a, ecx ;V - write Back REG A
jmp PollInt ;N - ...
OP2D: ; AND ABS
movzx ecx, wot[edx] ;N - load addr16Real
push ecx ;U -
lea ebp, [ebp+4] ;V - 4 Cycles
call nes_Read@4 ;N -
movzx ecx, byt[edi] ;N - load REG A
and cl, al ;U - AND OPR
and bl, 07Dh ;V - clr Z-N Flags
mov $a, ecx ;U - write Back REG A
lea esi, [esi+2] ;V - ++ PC
or ebx, dwot[zn_Table+ecx*4] ;V - reset Z-N Flags
jmp PollInt ;V - /N ...
OP3D: ; AND ABS X
movzx eax, wot[edx] ;N - load addr16Temp
movzx edx, byt[edi+4] ;N - load REG X
add dx, ax ;U - ABS X
add si, 2 ;V - ++ PC
push edx ;U - PUSH arg wait call PROC
lea ebp, [ebp+4] ;V - 4 Cycles
and bl, 07Dh ;U - clr Z-N Flags
sub ah, dh ;V - test CrossPage
adc ebp, 0 ;U -
mov eax, eax ;V -
call nes_Read@4 ;N - call PROC
movzx ecx, byt[edi] ;N - load REG A
and cl, al ;U - AND OPR
mov dl, dl ;V -
mov $a, ecx ;U - write Back REG A
mov eax, eax ;V -
or ebx, dwot[zn_Table+ecx*4] ;V - reset Z-N Flags
jmp PollInt ;V - /N ...
OP39: ; AND ABS Y
movzx eax, wot[edx] ;N - load addr16Temp
movzx edx, byt[edi+8] ;N - load REG Y
add dx, ax ;U - ABS Y
add si, 2 ;V - ++ PC
push edx ;U - PUSH arg wait call PROC
lea ebp, [ebp+4] ;V - 4 Cycles
and bl, 07Dh ;U - clr Z-N Flags
sub ah, dh ;V - test CrossPage
adc ebp, 0 ;U -
mov eax, eax ;V -
call nes_Read@4 ;N - call PROC
movzx ecx, byt[edi] ;N - load REG A
and cl, al ;U - AND OPR
mov dl, dl ;V -
mov $a, ecx ;U - write Back REG A
mov eax, eax ;V -
or ebx, dwot[zn_Table+ecx*4] ;V - reset Z-N Flags
jmp PollInt ;V - /N ...
OP21: ; AND X INDIRECT
movzx eax, byt[edx] ;N - load addr8Real
add al, byt[edi+4] ;U - X INDIRECT
and bl, 07Dh ;V - clr Z-N Flags
mov dx, wot[ram+eax];U - load addr16Real
add si, 1 ;V - ++ PC
push edx ;U -
lea ebp, [ebp+6] ;V - 6 Cycles
call nes_Read@4 ;N - call PROC
movzx ecx, byt[edi] ;N - load REG A
and cl, al ;U - AND OPR
mov dl, dl ;V -
mov $a, ecx ;U - write Back REG A
mov eax, eax ;V -
or ebx, dwot[zn_Table+ecx*4] ;V - reset Z-N Flags
jmp PollInt ;V - /N ...
OP31: ; AND INDIRECT Y
movzx ecx, byt[edx] ;N - load addr8Real
movzx eax, wot[ram+ecx];N - load addr16Temp
movzx edx, byt[edi+8] ;N - load REG Y
add dx, ax ;U - ABS Y
add si, 1 ;V - ++ PC
push edx ;U - PUSH arg wait call PROC
lea ebp, [ebp+4] ;V - 4 Cycles
and bl, 07Dh ;U - clr Z-N Flags
sub ah, dh ;V - test CrossPage
adc ebp, 0 ;U -
mov eax, eax ;V -
call nes_Read@4 ;N - call PROC
movzx ecx, byt[edi] ;N - load REG A
and cl, al ;U - AND OPR
mov dl, dl ;V -
mov $a, ecx ;U - write Back REG A
mov eax, eax ;V -
or ebx, dwot[zn_Table+ecx*4] ;V - reset Z-N Flags
jmp PollInt ;V - /N ...
;***
; JMP
; 4C: ABS 3 cycles
; 6C: inDirect 5 cycles
; Algorithm:
;
; PC = (src);
;
;*************************************************
OP4C: ; JMP ABS
mov si, wot[edx] ;U - get PC
add bp, 3 ;V - 3 Cycles
jmp PollInt ;N -
OP6C:
; in-direct JMP expection crossing page boundaries in 6C
; NES JMP(only 6C)'s BUG: if addr is 0x--FF(Crossing Page) IP's High Bit Will Not Add
;
; $2500: 33
; $25FF: 76
; $2600: 89
; $7574: 6C FF 25
; PC <- $7574
;
; Step1-> Get PC's Low Bit FF
; Step2-> Get PC's High Bit 25
; $(25FF-2600) will crossing page so low bit is $25FF high Bit is $2500
; jmp to $3376 ...
movzx eax, wot[edx] ;N - load indirect addr ...
push eax ;U - push arg wait call nes_Read@4/nes_Readw@4
add ebp, 5 ;V - 5 Cycles
cmp al, 0FFh ;U - low addr is FF ?
jne noCrossPageBUG ;V - FF:no jmp else immed read word no CrossPage
mov $t1, eax ;U - save addr
mov ebp, ebp ;V -
call nes_Read@4 ;N - call read PROC - BYTE
mov esi, eax ;U - addr - low bit
mov eax, $t1 ;V - load org addr
sub eax, 0FFh ;U - crossPage BUG deal
and esi, 0FFh ;V - limit byte
push eax ;U - push arg wait call nes_Read@4
mov eax, eax ;V -
call nes_Read@4 ;N - call read PROC - BYTE
shl eax, 8 ;U - shift to high 8 bits
mov ecx, ecx ;V -
or esi, eax ;U - get PC over
jmp PollInt ;V - /N
ALIGNXMM
noCrossPageBUG:
call nes_Readw@4 ; - N call read PROC - WORD
mov esi, eax ; - U PC <- EAX
jmp PollInt ; - V/N
;***
; JSR 20: ABS 6 cycles
;
;
; Algorithm:
;
; PC--;
; PUSH((PC >> 8) & 0xff); /* Push return address onto the stack. */
; PUSH(PC & 0xff);
; PC = (src);
;
;*************************************************
OP20: ; JSR
movzx eax, wot[edx] ;N - load future PC
mov ecx, $s ;U - load REG S
add ebp, 6 ;V - 6 Cycles
and ecx, 0FFh ;U - limits bits
lea edx, [esi+1] ;V - ++ PC
mov esi, eax ;U - write back PC
mov eax, eax ;V -
mov wot[ram+0100h+ecx-1], dx ;U - wrte back STACK PC
sub cx, 2 ;V - /N STACK --
mov $s, ecx ;U - write back STACK
jmp PollInt ;V - /N continue deal interrupt
;***
; RTI 40
;
;
; Algorithm:
;
; src = PULL();
; SET_SR(src);
; src = PULL();
; src |= (PULL() << 8); /* Load return address from stack. */
; PC = (src);
;
;*************************************************
OP40: ; RTI
mov ecx, $s ;U - load REG S
add ebp, 6 ;V - 6 Cycles
and ecx, 0FFh ;U -
mov eax, eax ;V -
lea ecx, [ecx+3] ;U - ++ STACK
mov ebx, ebx ;V -
mov bl, byt[ram+0100h+ecx-2] ;U - write back REG P
mov al, al ;V -
mov si, wot[ram+0100h+ecx-1] ;U - write back REG PC
mov bx, bx ;V -
mov $s, ecx ;U - write back REG S
jmp PollInt ;V - /N continue deal interrupt
;***
; RTS 60
;
;
; Algorithm:
;
; src = PULL();
; src += ((PULL()) << 8) + 1; /* Load return address from stack and add 1. */
; PC = (src);
;
;*************************************************
OP60: ; RTS
mov ecx, $s ;U - load REG S
add ebp, 6 ;V - 6 Cycles
and ecx, 255 ;U - limit Bits
mov eax, eax ;V -
add ecx, 2 ;U - ++STACK
mov eax, eax ;V -
mov si, wot[ram+0100h+ecx-1] ;U - load PC
mov ax, ax ;V -
mov $s, ecx ;U - write back S
lea esi, [esi+1] ;V - ++ PC
jmp PollInt ;V - /N continue deal interrupt
OP18: ; CLC
add ebp, 2
and ebx, 11111110b
jmp PollInt
OPD8: ; CLD
add ebp, 2
and ebx, 11110111b
jmp PollInt
OP58: ; CLI
add ebp, 2
and ebx, 11111011b
jmp PollInt
OPB8: ; CLV
add ebp, 2
and ebx, 10111111b
jmp PollInt
OP38: ; SEC
add ebp, 2
or ebx, 00000001b
jmp PollInt
OPF8: ; SED
add ebp, 2
or ebx, 00001000b
jmp PollInt
OP78: ; SEI
add ebp, 2
or ebx, 00000100b
jmp PollInt
;***
; LDA
; A9: ACC 2 cycles
; A5: ZERO PAGE 3 cycles
; B5: ZERO PAGE X 4 cycles
; AD: ABS 4 cycles
; BD: ABS X 4 cycles (test cross page)
; B9: ABS Y 4 cycles (test cross page)
; A1: X INDIRECT 6 cycles
; B1: INDIRECT Y 5 cycles (test cross page)
; X A5: X REG 2 cycles
; X A6: ZERO PAGE 3 cycles
; X B6: ZERO PAGE Y 4 cycles
; X AE: ABS 4 cycles
; X BE: ABS Y 4 cycles (test cross page)
; Y A0: Y REG 2 cycles
; Y A4: ZERO PAGE 3 cycles
; Y B4: ZERO PAGE X 4 cycles
; Y AC: ABS 4 cycles
; Y BC: ABS X 4 cycles (test cross page)
;
; Algorithm:
;
; SET_SIGN(src);
; SET_ZERO(src);
; AC = (src);
;
;*************************************************
; =====
; A
; =====
OPA9: ; LDA #$
movzx eax, byt[edx] ;N - eax <- #$
mov $a, eax ;U - A <- eax
and ebx, 07Dh ;V - clr Z-N
lea ebp, [ebp+2] ;U - 2 Cycles
lea esi, [esi+1] ;V - ++ PC
or ebx, dwot[zn_Table+eax*4] ;U - set Z-N
jmp PollInt ;V -
OPA5: ; LDA ZERO PAGE
movzx eax, byt[edx] ;N - eax <- a8Real
mov al, byt[ram+eax] ;U - eax <- MEM
and bl, 07Dh ;V - clr Z-N
mov $a, eax ;U - A <- MEM
lea ebp, [ebp+3] ;V - 3 Cycles
lea esi, [esi+1] ;U - ++ PC
or ebx, dwot[zn_Table+eax*4] ;V - set Z-N
jmp PollInt ;N -
OPB5: ; LDA ZERO PAGE X
movzx eax, byt[edx] ;N - eax <- a8Temp
add al, byt[edi+4] ;U - eax <- a8Real
mov dl, dl ;V -
mov al, byt[ram+eax] ;U - eax <- MEM
and bl, 07Dh ;V - clr Z-N
mov $a, eax ;U - A <- MEM
lea ebp, [ebp+4] ;V - 4 Cycles
lea esi, [esi+1] ;U - ++ PC
or ebx, dwot[zn_Table+eax*4] ;V - set Z-N
jmp PollInt ;N -
OPAD: ; LDA ABS --
movzx eax, wot[edx] ;N - eax <- a16Real
push eax ;U -
lea ebp, [ebp+4] ;V - 4 Cycles
call nes_Read@4 ;N -
and eax, 0FFh ;U -
mov edx, edx ;V -
and ebx, 07Dh ;U - clr Z-N
mov $a, eax ;V - A <- MEM
or ebx, dwot[zn_Table+eax*4] ;U - set Z-N
lea esi, [esi+2] ;V - ++ PC
jmp PollInt ;N -
OPBD: ; LDA ABS X
movzx eax, wot[edx] ;N - eax <- a16Temp
movzx ecx, byt[edi+4] ;N - ecx <- X
add ecx, eax ;U -
lea esi, [esi+2] ;V - ++ PC
push ecx ;U -
mov eax, eax ;V -
and bl, 07Dh ;U - clr Z-N
sub ah, ch ;V - test CrossPage
adc ebp, 4 ;U -
mov ebx, ebx ;V -
call nes_Read@4 ;N -
mov $a, eax ;U - A <- MEM
and eax, 0FFh ;V -
or ebx, dwot[zn_Table+eax*4] ;U - set Z-N
jmp PollInt ;V/N -
OPB9: ; LDA ABS Y
movzx eax, wot[edx] ;N - eax <- a16Temp
movzx ecx, byt[edi+8] ;N - ecx <- Y
add ecx, eax ;U -
lea esi, [esi+2] ;V - ++ PC
push ecx ;U -
mov eax, eax ;V -
and bl, 07Dh ;U - clr Z-N
sub ah, ch ;V - test CrossPage
adc ebp, 4 ;U -
mov ebx, ebx ;V -
call nes_Read@4 ;N -
mov $a, eax ;U - A <- MEM
and eax, 0FFh ;V -
or ebx, dwot[zn_Table+eax*4] ;U - set Z-N
jmp PollInt ;V/N -
OPA1: ; LDA X INDIRECT
movzx eax, byt[edx] ;N - eax <- a8Temp
add al, byt[edi+4] ;U - eax <- a8Real
and bl, 07Dh ;V - clr Z-N
mov cx, wot[ram+eax] ;U - ecx <- a16Real
add bp, 6 ;V - 6 Cycles
push ecx ;U -
lea esi, [esi+1] ;V - ++ PC
call nes_Read@4 ;N -
mov $a, eax ;U - A <- MEM
and eax, 0FFh ;V -
or ebx, dwot[zn_Table+eax*4] ;U - set Z-N
jmp PollInt ;V - /N ...
OPB1: ; LDA INDIRECT Y
movzx eax, byt[edx] ;N - eax <- a8Real
movzx eax, wot[ram+eax] ;N - eax <- a16Temp
movzx ecx, byt[edi+8] ;N - ecx <- Y
add ecx, eax ;U -
lea esi, [esi+1] ;V - ++ PC
push ecx ;U -
mov eax, eax ;V -
and bl, 07Dh ;U - clr Z-N
sub ah, ch ;V - test CrossPage
adc ebp, 5 ;U -
mov ebx, ebx ;V -
call nes_Read@4 ;N -
mov $a, eax ;U - A <- MEM
and eax, 0FFh ;V -
or ebx, dwot[zn_Table+eax*4] ;U - set Z-N
jmp PollInt ;V/N -
; =====
; X
; =====
OPA2: ; LDX #$
movzx eax, byt[edx] ;N - eax <- #$
mov $x, eax ;U - X <- eax
and ebx, 07Dh ;V - clr Z-N
lea ebp, [ebp+2] ;U - 2 Cycles
lea esi, [esi+1] ;V - ++ PC
or ebx, dwot[zn_Table+eax*4] ;U - set Z-N
jmp PollInt ;V -
OPA6: ; LDX ZERO PAGE
movzx eax, byt[edx] ;N - eax <- a8Real
mov al, byt[ram+eax] ;U - eax <- MEM
and bl, 07Dh ;V - clr Z-N
mov $x, eax ;U - X <- MEM
lea ebp, [ebp+3] ;V - 3 Cycles
lea esi, [esi+1] ;U - ++ PC
or ebx, dwot[zn_Table+eax*4] ;V - set Z-N
jmp PollInt ;N -
OPB6: ; LDX ZERO PAGE Y
movzx eax, byt[edx] ;N - eax <- a8Temp
add al, byt[edi+8] ;U - eax <- a8Real
mov dl, dl ;V -
mov al, byt[ram+eax] ;U - eax <- MEM
and bl, 07Dh ;V - clr Z-N
mov $x, eax ;U - X <- MEM
lea ebp, [ebp+4] ;V - 4 Cycles
lea esi, [esi+1] ;U - ++ PC
or ebx, dwot[zn_Table+eax*4] ;V - set Z-N
jmp PollInt ;N -
OPAE: ; LDX ABS
movzx eax, wot[edx] ;N - eax <- a16Real
push eax ;U -
lea ebp, [ebp+4] ;V - 4 Cycles
call nes_Read@4 ;N -
and eax, 0FFh ;U -
mov edx, edx ;V -
and ebx, 07Dh ;U - clr Z-N
mov $x, eax ;V - X <- MEM
or ebx, dwot[zn_Table+eax*4] ;U - set Z-N
lea esi, [esi+2] ;V - ++ PC
jmp PollInt ;N -
OPBE: ; LDX ABS Y
movzx eax, wot[edx] ;N - eax <- a16Temp
movzx ecx, byt[edi+8] ;N - ecx <- Y
add ecx, eax ;U -
lea esi, [esi+2] ;V - ++ PC
push ecx ;U -
mov eax, eax ;V -
and bl, 07Dh ;U - clr Z-N
sub ah, ch ;V - test CrossPage
adc ebp, 4 ;U -
mov ebx, ebx ;V -
call nes_Read@4 ;N -
mov $x, eax ;U - X <- MEM
and eax, 0FFh ;V -
or ebx, dwot[zn_Table+eax*4] ;U - set Z-N
jmp PollInt ;V/N -
; =====
; y
; =====
OPA0: ; LDY #$
movzx eax, byt[edx] ;N - eax <- #$
mov $y, eax ;U - Y <- eax
and ebx, 07Dh ;V - clr Z-N
lea ebp, [ebp+2] ;U - 2 Cycles
lea esi, [esi+1] ;V - ++ PC
or ebx, dwot[zn_Table+eax*4] ;U - set Z-N
jmp PollInt ;V -
OPA4: ; LDY ZERO PAGE
movzx eax, byt[edx] ;N - eax <- a8Real
mov al, byt[ram+eax] ;U - eax <- MEM
and bl, 07Dh ;V - clr Z-N
mov $y, eax ;U - Y <- MEM
lea ebp, [ebp+3] ;V - 3 Cycles
lea esi, [esi+1] ;U - ++ PC
or ebx, dwot[zn_Table+eax*4] ;V - set Z-N
jmp PollInt ;N -
OPB4: ; LDY ZERO PAGE X
movzx eax, byt[edx] ;N - eax <- a8Temp
add al, byt[edi+4] ;U - eax <- a8Real
mov dl, dl ;V -
mov al, byt[ram+eax] ;U - eax <- MEM
and bl, 07Dh ;V - clr Z-N
mov $y, eax ;U - Y <- MEM
lea ebp, [ebp+4] ;V - 4 Cycles
lea esi, [esi+1] ;U - ++ PC
or ebx, dwot[zn_Table+eax*4] ;V - set Z-N
jmp PollInt ;N -
OPAC: ; LDY ABS
movzx eax, wot[edx] ;N - eax <- a16Real
push eax ;U -
lea ebp, [ebp+4] ;V - 4 Cycles
call nes_Read@4 ;N -
and eax, 0FFh ;U -
mov edx, edx ;V -
and ebx, 07Dh ;U - clr Z-N
mov $y, eax ;V - Y <- MEM
or ebx, dwot[zn_Table+eax*4] ;U - set Z-N
lea esi, [esi+2] ;V - ++ PC
jmp PollInt ;N -
OPBC: ; LDY ABS X
movzx eax, wot[edx] ;N - eax <- a16Temp
movzx ecx, byt[edi+4] ;N - ecx <- X
add ecx, eax ;U -
lea esi, [esi+2] ;V - ++ PC
push ecx ;U -
mov eax, eax ;V -
and bl, 07Dh ;U - clr Z-N
sub ah, ch ;V - test CrossPage
adc ebp, 4 ;U -
mov ebx, ebx ;V -
call nes_Read@4 ;N -
mov $y, eax ;U - Y <- MEM
and eax, 0FFh ;V -
or ebx, dwot[zn_Table+eax*4] ;U - set Z-N
jmp PollInt ;V/N -
; trans REG to REG
; tXN
; X source REG
; N target REG
; TXS not set Z-N flag (only this.. other must set Z-N flag)...
; cycles all 2 cycles ...
OPAA: ; TAX
and ebx, 07Dh ;U -
mov eax, $a ;V - eax <- A
mov $x, eax ;U - X <- eax
and eax, 0FFh ;V -
add ebp, 2 ;U -
or ebx, dwot[zn_Table+eax*4];V -
jmp PollInt ;N -
OP8A: ; TXA
and ebx, 07Dh ;U -
mov eax, $x ;V - eax <- X
mov $a, eax ;U - A <- eax
and eax, 0FFh ;V -
add ebp, 2 ;U -
or ebx, dwot[zn_Table+eax*4];V -
jmp PollInt ;N -
OPA8: ; TAY
and ebx, 07Dh ;U -
mov eax, $a ;V - eax <- A
mov $y, eax ;U - Y <- eax
and eax, 0FFh ;V -
add ebp, 2 ;U -
or ebx, dwot[zn_Table+eax*4];V -
jmp PollInt ;N -
OP98: ; TYA
and ebx, 07Dh ;U -
mov eax, $y ;V - eax <- Y
mov $a, eax ;U - A <- eax
and eax, 0FFh ;V -
add ebp, 2 ;U -
or ebx, dwot[zn_Table+eax*4];V -
jmp PollInt ;N -
OPBA: ; TSX
and ebx, 07Dh ;U -
mov eax, $s ;V - eax <- S
mov $x, eax ;U - X <- eax
and eax, 0FFh ;V -
add ebp, 2 ;U -
or ebx, dwot[zn_Table+eax*4];V -
jmp PollInt ;N -
OP9A: ; TXS (RTOR only this not set flag)
mov eax, $x ;U - eax <- X
add ebp, 2 ;V -
mov $s, eax ;U - S <- eax
jmp PollInt ;N -
;***
; ASL
; 0A: ACC 2 cycles
; 06: ZERO PAGE 5 cycles
; 16: ZERO PAGE X 6 cycles
; 0E: ABS 6 cycles
; 1E: ABS X 7 cycles
; Algorithm:
;
; SET_CARRY(src & 0x80);
; src <<= 1;
; src &= 0xff;
; SET_SIGN(src);
; SET_ZERO(src);
; STORE src in memory or accumulator depending on addressing mode.
;
;*************************************************
OP0A: ; ASL A - 2 cycles
movzx eax, byt[edi] ;N - eax <- A
and ebx, 01111100b ;U - clr N-Z-C
lea ebp, [ebp+2] ;V - 2 Cycles
shl al, 1 ;U - ASL A
mov dl, dl ;V -
adc ebx, 0 ;U - set C
mov $a, eax ;V - A <- eax
or ebx, dwot[zn_Table+eax*4] ;U - set Z-N
jmp PollInt ;V - /N
OP06: ; ASL ZERO PAGE 5 cycles
movzx edx, byt[edx] ;N - edx <- a8Real
movzx eax, byt[ram+edx];N - eax <- MEM
and ebx, 01111100b ;U - clr N-Z-C
lea ebp, [ebp+5] ;V - 5 Cycles
shl al, 1 ;U - ASL
mov dl, dl ;V -
adc ebx, 0 ;U - set C
lea esi, [esi+1] ;V - ++ PC
mov byt[ram+edx], al ;U - MEM <- eax
or bl, byt[zn_Table+eax*4] ;V - set Z-N
jmp PollInt ;N -
OP16: ; ASL ZERO PAGE X
movzx edx, byt[edx] ;N - edx <- a8Temp
add dl, byt[edi+4] ;U - edx <- a8Real
mov al, al ;V -
movzx eax, byt[ram+edx];N - eax <- MEM
and ebx, 01111100b ;U - clr N-Z-C
lea ebp, [ebp+6] ;V - 6 Cycles
shl al, 1 ;U - ASL
mov dl, dl ;V -
adc ebx, 0 ;U - set C
lea esi, [esi+1] ;V - ++ PC
mov byt[ram+edx], al ;U - MEM <- eax
or bl, byt[zn_Table+eax*4] ;V - set Z-N
jmp PollInt ;N -
OP0E: ; ASL ABS
mov ax, wot[edx] ;U - eax <- a16Real
add si, 2 ;V - ++ PC
mov $t1, eax ;U - t1 <- a16Real
push eax ;V -
call nes_Read@4 ;N -
and eax, 0FFh ;U - purify
and ebx, 01111100b ;V - clr Z-N-C
shl al, 1 ;U - ASL
mov dl, dl ;V -
adc ebx, 0 ;U - set C
lea ebp, [ebp+6] ;V - 6 Cycles
or ebx, dwot[zn_Table+eax*4] ;U - set Z-N
push eax ;V - push MEM
push $t1 ;U - push a16Real
mov eax, eax ;V -
call nes_Write@8 ;N -
jmp PollInt ;N -
OP1E: ; ASL ABS X
movzx ecx, byt[edi+4] ;N - ecx <- X
mov ax, wot[edx] ;U - eax <- a16Temp
mov bx, bx ;V -
add ax, cx ;U - eax <- a16Real
add si, 2 ;V - ++ PC
mov $t1, eax ;U - t1 <- a16Real
push eax ;V -
call nes_Read@4 ;N -
and eax, 0FFh ;U - purify
and ebx, 01111100b ;V - clr Z-N-C
shl al, 1 ;U - ASL
mov dl, dl ;V -
adc ebx, 0 ;U - set C
lea ebp, [ebp+7] ;V - 7 Cycles
or ebx, dwot[zn_Table+eax*4] ;U - set Z-N
push eax ;V - push MEM
push $t1 ;U - push a16Real
mov eax, eax ;V -
call nes_Write@8 ;N -
jmp PollInt ;N -
;***
; LSR
; 4A: ACC 2 cycles
; 46: ZERO PAGE 5 cycles
; 56: ZERO PAGE X 6 cycles
; 4E: ABS 6 cycles
; 5E: ABS X 7 cycles
; Algorithm:
;
; SET_CARRY(src & 0x01);
; src >>= 1;
; SET_SIGN(src);
; SET_ZERO(src);
; STORE src in memory or accumulator depending on addressing mode.
;
;*************************************************
OP4A: ; LSR A
movzx eax, byt[edi] ;N - eax <- A
and ebx, 01111100b ;U - clr N-Z-C
lea ebp, [ebp+2] ;V - 2 Cycles
shr al, 1 ;U - LSR A
mov dl, dl ;V -
adc ebx, 0 ;U - set C
mov $a, eax ;V - A <- eax
or ebx, dwot[zn_Table+eax*4] ;U - set Z-N
jmp PollInt ;V - /N
OP46: ; LSR ZERO PAGE
movzx edx, byt[edx] ;N - edx <- a8Real
movzx eax, byt[ram+edx];N - eax <- MEM
and ebx, 01111100b ;U - clr N-Z-C
lea ebp, [ebp+5] ;V - 5 Cycles
shr al, 1 ;U - LSR
mov dl, dl ;V -
adc ebx, 0 ;U - set C
lea esi, [esi+1] ;V - ++ PC
mov byt[ram+edx], al ;U - MEM <- eax
or bl, byt[zn_Table+eax*4] ;V - set Z-N
jmp PollInt ;N -
OP56: ; LSR ZERO PAGE X
movzx edx, byt[edx] ;N - edx <- a8Temp
add dl, byt[edi+4] ;U - edx <- a8Real
mov al, al ;V -
movzx eax, byt[ram+edx];N - eax <- MEM
and ebx, 01111100b ;U - clr N-Z-C
lea ebp, [ebp+6] ;V - 6 Cycles
shr al, 1 ;U - LSR
mov dl, dl ;V -
adc ebx, 0 ;U - set C
lea esi, [esi+1] ;V - ++ PC
mov byt[ram+edx], al ;U - MEM <- eax
or bl, byt[zn_Table+eax*4] ;V - set Z-N
jmp PollInt ;N -
OP4E: ; LSR ABS
mov ax, wot[edx] ;U - eax <- a16Real
add si, 2 ;V - ++ PC
mov $t1, eax ;U - t1 <- a16Real
push eax ;V -
call nes_Read@4 ;N -
and eax, 0FFh ;U - purify
and ebx, 01111100b ;V - clr Z-N-C
shr al, 1 ;U - LSR
mov dl, dl ;V -
adc ebx, 0 ;U - set C
lea ebp, [ebp+6] ;V - 6 Cycles
or ebx, dwot[zn_Table+eax*4] ;U - set Z-N
push eax ;V - push MEM
push $t1 ;U - push a16Real
mov eax, eax ;V -
call nes_Write@8 ;N -
jmp PollInt ;N -
OP5E: ; LSR ABS X
movzx ecx, byt[edi+4] ;N - ecx <- X
mov ax, wot[edx] ;U - eax <- a16Temp
mov bx, bx ;V -
add ax, cx ;U - eax <- a16Real
add si, 2 ;V - ++ PC
mov $t1, eax ;U - t1 <- a16Real
push eax ;V -
call nes_Read@4 ;N -
and eax, 0FFh ;U - purify
and ebx, 01111100b ;V - clr Z-N-C
shr al, 1 ;U - LSR
mov dl, dl ;V -
adc ebx, 0 ;U - set C
lea ebp, [ebp+7] ;V - 7 Cycles
or ebx, dwot[zn_Table+eax*4] ;U - set Z-N
push eax ;V - push MEM
push $t1 ;U - push a16Real
mov eax, eax ;V -
call nes_Write@8 ;N -
jmp PollInt ;N -
;***
; ROL
; 2A: ACC 2 cycles
; 26: ZERO PAGE 5 cycles
; 36: ZERO PAGE X 6 cycles
; 2E: ABS 6 cycles
; 3E: ABS X 7 cycles
; Algorithm:
;
; src <<= 1;
; if (IF_CARRY()) {
; src |= 0x1;
; }
; SET_CARRY(src > 0xff);
; src &= 0xff;
; SET_SIGN(src);
; SET_ZERO(src);
; STORE src in memory or accumulator depending on addressing mode.
;
;*************************************************
OP2A: ; ROL A
movzx eax, byt[edi] ;N - eax <- A
and ebx, 01111101b ;U - set C
lea ebp, [ebp+2] ;V - 2 Cycles
shr ebx, 1 ;U - throw C
mov eax, eax ;V -
rcl al, 1 ;N - ROL A
rcl bl, 1 ;N - receive C
mov $a, eax ;U - A <- eax
or ebx, dwot[zn_Table+eax*4] ;V - set Z-N
jmp PollInt ;N -
OP26: ; ROL ZERO PAGE
movzx edx, byt[edx] ;N - edx <- a8Real
movzx eax, byt[ram+edx];N - eax <- MEM
and ebx, 01111101b ;U - set C
lea ebp, [ebp+5] ;V - 5 Cycles
shr ebx, 1 ;U - throw C
lea esi, [esi+1] ;V - ++ PC
rcl al, 1 ;N - ROL
rcl bl, 1 ;N - receive C
mov byt[ram+edx], al ;U - MEM <- eax
or bl, byt[zn_Table+eax*4] ;V - set Z-N
jmp PollInt ;N -
OP36: ; ROL ZERO PAGE X
movzx edx, byt[edx] ;N - edx <- a8Temp
add dl, byt[edi+4] ;U - edx <- a8Real
mov bl, bl ;V -
movzx eax, byt[ram+edx];N - eax <- MEM
and ebx, 01111101b ;U - set C
lea ebp, [ebp+6] ;V - 6 Cycles
shr ebx, 1 ;U - throw C
lea esi, [esi+1] ;V - ++ PC
rcl al, 1 ;N - ROL
rcl bl, 1 ;N - receive C
mov byt[ram+edx], al ;U - MEM <- eax
or bl, byt[zn_Table+eax*4] ;V - set Z-N
jmp PollInt ;N -
OP2E: ; ROL ABS
mov ax, wot[edx] ;U - eax <- a16Real
add si, 2 ;V - ++ PC
mov $t1, eax ;U - t1 <- a16Real
push eax ;V -
call nes_Read@4 ;N -
and eax, 0FFh ;U - purify
and ebx, 01111101b ;V - clr Z-N-C
shr ebx, 1 ;U - throw C
lea ebp, [ebp+6] ;V - 6 Cycles
rcl al, 1 ;N - ROL
rcl bl, 1 ;N - receive C
push eax ;U -
push $t1 ;V -
mov edx, edx ;U -
or ebx, dwot[zn_Table+eax*4] ;V - reset Z-N Flags
call nes_Write@8 ;N -
jmp PollInt ;N -
OP3E: ; ROL ABS X
movzx ecx, byt[edi+4] ;N - ecx <- X
mov ax, wot[edx] ;U - eax <- a16Temp
add si, 2 ;V - ++ PC
add ax, cx ;U - eax <- a16Real
mov dx, dx ;V -
mov $t1, eax ;U - t1 <- a16Real
push eax ;V -
call nes_Read@4 ;N -
and eax, 0FFh ;U - purify
and ebx, 01111101b ;V - clr Z-N-C
shr ebx, 1 ;U - throw C
lea ebp, [ebp+7] ;V - 7 Cycles
rcl al, 1 ;N - ROL
rcl bl, 1 ;N - receive C
push eax ;U -
push $t1 ;V -
mov edx, edx ;U -
or ebx, dwot[zn_Table+eax*4] ;V - reset Z-N Flags
call nes_Write@8 ;N -
jmp PollInt ;N -
;***
; ROR
; 6A: ACC 2 cycles
; 66: ZERO PAGE 5 cycles
; 76: ZERO PAGE X 6 cycles
; 6E: ABS 6 cycles
; 7E: ABS X 7 cycles
; Algorithm:
;
; if (IF_CARRY()) {
; src |= 0x100;
; }
; SET_CARRY(src & 0x01);
; src >>= 1;
; SET_SIGN(src);
; SET_ZERO(src);
; STORE src in memory or accumulator depending on addressing mode.
;
;*************************************************
OP6A: ; ROR A
movzx eax, byt[edi] ;N - eax <- A
and ebx, 01111101b ;U - set C
lea ebp, [ebp+2] ;V - 2 Cycles
shr ebx, 1 ;U - throw C
mov eax, eax ;V -
rcr al, 1 ;N - ROR A
rcl bl, 1 ;N - receive C
mov $a, eax ;U - A <- eax
or ebx, dwot[zn_Table+eax*4] ;V - set Z-N
jmp PollInt ;N -
OP66: ; ROR ZERO PAGE
movzx edx, byt[edx] ;N - edx <- a8Real
movzx eax, byt[ram+edx];N - eax <- MEM
and ebx, 01111101b ;U - set C
lea ebp, [ebp+5] ;V - 5 Cycles
shr ebx, 1 ;U - throw C
lea esi, [esi+1] ;V - ++ PC
rcr al, 1 ;N - ROR
rcl bl, 1 ;N - receive C
mov byt[ram+edx], al ;U - MEM <- eax
or bl, byt[zn_Table+eax*4] ;V - set Z-N
jmp PollInt ;N -
OP76: ; ROR ZERO PAGE X
movzx edx, byt[edx] ;N - edx <- a8Temp
add dl, byt[edi+4] ;U - edx <- a8Real
mov bl, bl ;V -
movzx eax, byt[ram+edx];N - eax <- MEM
and ebx, 01111101b ;U - set C
lea ebp, [ebp+6] ;V - 6 Cycles
shr ebx, 1 ;U - throw C
lea esi, [esi+1] ;V - ++ PC
rcr al, 1 ;N - ROR
rcl bl, 1 ;N - receive C
mov byt[ram+edx], al ;U - MEM <- eax
or bl, byt[zn_Table+eax*4] ;V - set Z-N
jmp PollInt ;N -
OP6E: ; ROR ABS
mov ax, wot[edx] ;U - eax <- a16Real
add si, 2 ;V - ++ PC
mov $t1, eax ;U - t1 <- a16Real
push eax ;V -
call nes_Read@4 ;N -
and eax, 0FFh ;U - purify
and ebx, 01111101b ;V - clr Z-N-C
shr ebx, 1 ;U - throw C
lea ebp, [ebp+6] ;V - 6 Cycles
rcr al, 1 ;N - ROR
rcl bl, 1 ;N - receive C
push eax ;U -
push $t1 ;V -
mov edx, edx ;U -
or ebx, dwot[zn_Table+eax*4] ;V - reset Z-N Flags
call nes_Write@8 ;N -
jmp PollInt ;N -
OP7E: ; ROR ABS X
movzx ecx, byt[edi+4] ;N - ecx <- X
mov ax, wot[edx] ;U - eax <- a16Temp
add si, 2 ;V - ++ PC
add si, 2 ;V - ++ PC
add ax, cx ;U - eax <- a16Real
mov dx, dx ;V -
mov $t1, eax ;U - t1 <- a16Real
push eax ;V -
call nes_Read@4 ;N -
and eax, 0FFh ;U - purify
and ebx, 01111101b ;V - clr Z-N-C
shr ebx, 1 ;U - throw C
lea ebp, [ebp+7] ;V - 7 Cycles
rcr al, 1 ;N - ROR
rcl bl, 1 ;N - receive C
push eax ;U -
push $t1 ;V -
mov edx, edx ;U -
or ebx, dwot[zn_Table+eax*4] ;V - reset Z-N Flags
call nes_Write@8 ;N -
jmp PollInt ;N -
OP48: ; PHA
mov eax, $a ;U - eax <- A
mov edx, $s ;V - edx <- S
and edx, 0FFh ;U - purify
add ebp, 3 ;V - 3 Cycles
mov byt[ram+0100h+edx], al ;U - STACK <- A
dec dl ;V - STACK --
mov $s, edx ;U -
jmp PollInt ;V -
OP08: ; PHP
mov edx, $s ;U - edx <- S
add ebp, 3 ;V - 3 Cycles
and edx, 0FFh ;U - purify
or ebx, B_FLAG ;V - set B Flag
mov byt[ram+0100h+edx], bl ;U - STACK <- P
dec dl ;V - STACK --
mov $s, edx ;U -
jmp PollInt ;V -
OP68: ; PLA
mov edx, $s ;U - edx <- S
and ebx, 07Dh ;V - clr Z-N
and edx, 0FFh ;U - purify
add ebp, 4 ;V - 4 Cycles
mov al, byt[ram+0101h+edx] ;U - A <- STACK
add dl, 1 ;V - ++ STACK
and eax, 0FFh ;U - purify
mov $s, edx ;V -
mov $a, eax ;U -
or ebx, dwot[zn_Table+eax*4] ;V - set Z-N
jmp PollInt ;N -
OP28: ; PLP
mov edx, $s ;U - edx <- S
add ebp, 4 ;V - 4 Cycles
and edx, 0FFh ;U - purify
mov ecx, ecx ;V -
mov bl, byt[ram+0101h+edx] ;U - P <- STACK
add dl, 1 ;V - ++ STACK
mov $s, edx ;U -
jmp PollInt ;V -
;***
; BIT
; 24: ZERO PAGE 3 cycles
; 2C: ABS 4 cycles
; Algorithm:
;
; SET_SIGN(src);
; SET_OVERFLOW(0x40 & src);
; SET_ZERO(src & AC);
;*************************************************
OP24: ; BIT ZERO PAGE 3 cycles
movzx eax, byt[edx] ;N - eax <- a8Real
mov al, byt[ram+eax];U - eax <- MEM
and bl, 00111101b ;V - clr N-Z-V
mov ecx, $a ;U - ecx <- A
lea esi, [esi+1] ;V - ++ PC
test al, cl ;U -
mov bl, bl ;V -
setz cl ;N - set Z
and eax, 0C0h ;U - get N-V
and ecx, 001h ;V - get Z
lea edx, [eax+ecx*2] ;U - mix N-V-Z
lea ebp, [ebp+3] ;V - 3 Cycles
or ebx, edx ;U - set N-V-Z
jmp PollInt ;V -
OP2C: ; BIT ABS 4 cycles
mov ax, wot[edx] ;U - eax <- a16Real
and bx, 00111101b ;V - clr N-Z-V
push eax ;U -
lea esi, [esi+2] ;V - ++ PC
call nes_Read@4 ;N -
mov ecx, $a ;U - ecx <- A
lea ebx, [ebx] ;V -
test al, cl ;U -
mov bl, bl ;V -
setz cl ;N - set Z
and eax, 0C0h ;U - get N-V
and ecx, 001h ;V - get Z
lea edx, [eax+ecx*2] ;U - mix N-V-Z
lea ebp, [ebp+4] ;V - 4 Cycles
or ebx, edx ;U - set N-V-Z
jmp PollInt ;V -
;***
; STA
; 85: ZERO PAGE 3 cycles
; 95: ZERO PAGE X 4 cycles
; 80: ABS 4 cycles
; 90: ABS X 5 cycles
; 99: ABS Y 5 cycles
; 81: X INDIRECT 6 cycles
; 91: INDIRECT Y 6 cycles (no test cross page)
; X 86: ZERO PAGE 3 cycles
; X 96: ZERO PAGE Y 4 cycles
; X 8E: ABS 4 cycles
; Y 84: ZERO PAGE 3 cycles
; Y 94: ZERO PAGE X 4 cycles
; Y 8C: ABS 4 cycles
;
; Algorithm:
;
; STORE(address, A);
;
;*************************************************
; =====
; A
; =====
OP85: ; STA ZERO PAGE
movzx eax, byt[edx] ;N - eax <- a8Real
mov ecx, $a ;U - ecx <- A
lea ebp, [ebp+3] ;V - 3 Cycles
mov byt[ram+eax], cl ;U - MEM <- ecx
mov bl, bl ;V -
lea esi, [esi+1] ;U - ++ PC
jmp PollInt ;V -
OP95: ; STA ZERO PAGE X
movzx eax, byt[edx] ;N - eax <- a8Temp
add al, byt[edi+4] ;U -
mov dl, dl ;V -
mov ecx, $a ;U - ecx <- A
lea ebp, [ebp+4] ;V - 4 Cycles
mov byt[ram+eax], cl ;U - MEM <- ecx
mov bl, bl ;V -
lea esi, [esi+1] ;U - ++ PC
jmp PollInt ;V -
OP8D: ; STA ABS
movzx eax, wot[edx] ;N - eax <- a16Real
push $a ;U -
push eax ;V -
call nes_Write@8 ;N -
lea esi, [esi+2] ;U - ++ PC
lea ebp, [ebp+4] ;V - 4 Cycles
jmp PollInt ;V -
OP9D: ; STA ABS X
movzx eax, wot[edx] ;N - eax <- a16Temp
movzx ecx, byt[edi+4] ;N - ecx <- X
push $a ;U -
add eax, ecx ;V - eax <- a16Real
push eax ;U -
lea ebp, [ebp+5] ;V - 5 Cycles
call nes_Write@8 ;N -
lea esi, [esi+2] ;U - ++ PC
jmp PollInt ;V - /N ...
OP99: ; STA ABS Y
movzx eax, wot[edx] ;N - eax <- a16Temp
movzx ecx, byt[edi+8] ;N - ecx <- Y
push $a ;U -
add eax, ecx ;V - eax <- a16Real
push eax ;U -
lea ebp, [ebp+5] ;V - 5 Cycles
call nes_Write@8 ;N -
lea esi, [esi+2] ;U - ++ PC
jmp PollInt ;V - /N ...
OP81: ; STA X INDIRECT
movzx eax, byt[edx] ;N - eax <- a8Temp
add al, byt[edi+4] ;U - eax <- a8Real
mov cl, cl ;V -
mov dx, wot[eax+ram] ;U - edx <- a16Real
add bp, 6 ;V - 6 Cycles
push $a ;U -
push edx ;V -
call nes_Write@8 ;N - call nes_Write@8
add esi, 1 ;U - ++ PC
jmp PollInt ;V -
OP91: ; STA INDIRECT Y
movzx eax, byt[edx] ;N - eax <- a8Real
movzx edx, byt[edi+8] ;N - edx <- Y
mov cx, wot[ram+eax] ;U - ecx <- a16Temp
add si, 1 ;V - ++ PC
add cx, dx ;U - ecx <- a16Real
add bp, 6 ;V - 6 Cycles
push $a ;U -
push ecx ;V -
call nes_Write@8 ;N -
jmp PollInt ;V -
; =====
; X
; =====
OP86: ; STX ZERO PAGE
movzx eax, byt[edx] ;N - eax <- a8Real
mov ecx, $x ;U - ecx <- X
lea ebp, [ebp+3] ;V - 3 Cycles
mov byt[ram+eax], cl ;U - MEM <- ecx
mov bl, bl ;V -
lea esi, [esi+1] ;U - ++ PC
jmp PollInt ;V -
OP96: ; STX ZERO PAGE Y
movzx eax, byt[edx] ;N - eax <- a8Temp
add al, byt[edi+8] ;U -
mov dl, dl ;V -
mov ecx, $x ;U - ecx <- X
lea ebp, [ebp+4] ;V - 4 Cycles
mov byt[ram+eax], cl ;U - MEM <- ecx
mov bl, bl ;V -
lea esi, [esi+1] ;U - ++ PC
jmp PollInt ;V -
OP8E: ; STX ABS
movzx eax, wot[edx] ;N - eax <- a16Real
push $x ;U -
push eax ;V -
call nes_Write@8 ;N -
lea esi, [esi+2] ;U - ++ PC
lea ebp, [ebp+4] ;V - 4 Cycles
jmp PollInt ;V -
; =====
; y
; =====
OP84: ; STY ZERO PAGE
movzx eax, byt[edx] ;N - eax <- a8Real
mov ecx, $y ;U - ecx <- Y
lea ebp, [ebp+3] ;V - 3 Cycles
mov byt[ram+eax], cl ;U - MEM <- ecx
mov bl, bl ;V -
lea esi, [esi+1] ;U - ++ PC
jmp PollInt ;V -
OP94: ; STY ZERO PAGE X
movzx eax, byt[edx] ;N - eax <- a8Temp
add al, byt[edi+4] ;U -
mov dl, dl ;V -
mov ecx, $y ;U - ecx <- Y
lea ebp, [ebp+4] ;V - 4 Cycles
mov byt[ram+eax], cl ;U - MEM <- ecx
mov bl, bl ;V -
lea esi, [esi+1] ;U - ++ PC
jmp PollInt ;V -
OP8C: ; STY ABS
movzx eax, wot[edx] ;N - eax <- a16Real
push $y ;U -
push eax ;V -
call nes_Write@8 ;N -
lea esi, [esi+2] ;U - ++ PC
lea ebp, [ebp+4] ;V - 4 Cycles
jmp PollInt ;V -
OP00:
OPEA:
; When the MOS 6502 processor was modified into the Ricoh 2A03 chip for the NES,\
; the BRK (Force Break) opcode was eliminated.
; Thus, the BRK command doesn't actually do anything on the NES and is effectively identical to NOP.
; Because of this, when you see a BRK in decompiled NES code,\
; you can be fairly certain that the #00 value is either game data or unused.
; Having a BRK execute on the NES won't harm anything, it will only eat up a clock cycle to process.
; You can take advantage of this feature when making game cheats.
; For example, if you want to change an opcode that takes a two-byte operand into an opcode that uses a one-byte operand,\
; you can ignore the second byte of the operand if it is a #00 because the NES will simply treat it as a BRK, which is ignored.
; On an original MOS 6502 processor,\
; BRK would set the Interrupt Flag to prevent further interrupts and then move the Program Counter Register to the new location.
; Addressing Modes
; ==================================================================
; Addressing Mode Assembly Language Form Opcode # Bytes # Cycles
; =============== ====================== ====== ====== =====
; Implied BRK 00 1 2
; ========================================================================
; ref link: www.thealmightyguru.com/Games/Hacking/Wiki/index.php?title=BRK
; ========================================================================
add ebp, 2
jmp PollInt
OP02:
OP03:
OP04:
OP07:
OP0B:
OP0C:
OP0F:
OP12:
OP13:
OP14:
OP17:
OP1A:
OP1B:
OP1C:
OP1F:
OP22:
OP23:
OP27:
OP2B:
OP2F:
OP32:
OP33:
OP34:
OP37:
OP3A:
OP3B:
OP3C:
OP3F:
OP42:
OP43:
OP44:
OP47:
OP4B:
OP4F:
OP52:
OP53:
OP54:
OP57:
OP5A:
OP5B:
OP5C:
OP5F:
OP62:
OP63:
OP64:
OP67:
OP6B:
OP6F:
OP72:
OP73:
OP74:
OP77:
OP7A:
OP7B:
OP7C:
OP7F:
OP80:
OP82:
OP83:
OP87:
OP89:
OP8B:
OP8F:
OP92:
OP93:
OP97:
OP9B:
OP9C:
OP9E:
OP9F:
OPA3:
OPA7:
OPAB:
OPAF:
OPB2:
OPB3:
OPB7:
OPBB:
OPBF:
OPC2:
OPC3:
OPC7:
OPCB:
OPCF:
OPD2:
OPD3:
OPD4:
OPD7:
OPDA:
OPDB:
OPDC:
OPDF:
OPE2:
OPE3:
OPE7:
OPEB:
OPEF:
OPF2:
OPF3:
OPF4:
OPF7:
OPFA:
OPFB:
OPFC:
OPFF:
int 3
ALIGNXMM
OPTAB dd OP00, OP01, OP02, OP03, OP04, OP05, OP06, OP07, OP08, OP09, OP0A, OP0B, OP0C, OP0D, OP0E, OP0F
dd OP10, OP11, OP12, OP13, OP14, OP15, OP16, OP17, OP18, OP19, OP1A, OP1B, OP1C, OP1D, OP1E, OP1F
dd OP20, OP21, OP22, OP23, OP24, OP25, OP26, OP27, OP28, OP29, OP2A, OP2B, OP2C, OP2D, OP2E, OP2F
dd OP30, OP31, OP32, OP33, OP34, OP35, OP36, OP37, OP38, OP39, OP3A, OP3B, OP3C, OP3D, OP3E, OP3F
dd OP40, OP41, OP42, OP43, OP44, OP45, OP46, OP47, OP48, OP49, OP4A, OP4B, OP4C, OP4D, OP4E, OP4F
dd OP50, OP51, OP52, OP53, OP54, OP55, OP56, OP57, OP58, OP59, OP5A, OP5B, OP5C, OP5D, OP5E, OP5F
dd OP60, OP61, OP62, OP63, OP64, OP65, OP66, OP67, OP68, OP69, OP6A, OP6B, OP6C, OP6D, OP6E, OP6F
dd OP70, OP71, OP72, OP73, OP74, OP75, OP76, OP77, OP78, OP79, OP7A, OP7B, OP7C, OP7D, OP7E, OP7F
dd OP80, OP81, OP82, OP83, OP84, OP85, OP86, OP87, OP88, OP89, OP8A, OP8B, OP8C, OP8D, OP8E, OP8F
dd OP90, OP91, OP92, OP93, OP94, OP95, OP96, OP97, OP98, OP99, OP9A, OP9B, OP9C, OP9D, OP9E, OP9F
dd OPA0, OPA1, OPA2, OPA3, OPA4, OPA5, OPA6, OPA7, OPA8, OPA9, OPAA, OPAB, OPAC, OPAD, OPAE, OPAF
dd OPB0, OPB1, OPB2, OPB3, OPB4, OPB5, OPB6, OPB7, OPB8, OPB9, OPBA, OPBB, OPBC, OPBD, OPBE, OPBF
dd OPC0, OPC1, OPC2, OPC3, OPC4, OPC5, OPC6, OPC7, OPC8, OPC9, OPCA, OPCB, OPCC, OPCD, OPCE, OPCF
dd OPD0, OPD1, OPD2, OPD3, OPD4, OPD5, OPD6, OPD7, OPD8, OPD9, OPDA, OPDB, OPDC, OPDD, OPDE, OPDF
dd OPE0, OPE1, OPE2, OPE3, OPE4, OPE5, OPE6, OPE7, OPE8, OPE9, OPEA, OPEB, OPEC, OPED, OPEE, OPEF
dd OPF0, OPF1, OPF2, OPF3, OPF4, OPF5, OPF6, OPF7, OPF8, OPF9, OPFA, OPFB, OPFC, OPFD, OPFE, OPFF
ALIGNXMM
PollInt:
mov eax, dwot[int_Pending] ;U - load Pending signal
and eax, 3 ;V - clr bits
lea ecx, [ecx] ;U -
jmp dwot[INT_TAB+eax*4] ;V - decode interrupt
ALIGNXMM
IRQ_:
and eax, 1 ;U - clr NMI flag ...
mov ecx, $s ;V - load S stack
and ecx, 0FFh ;U - clr bits
lea edx, [edx] ;V -
mov dwot[int_Pending], eax ;U - write back Pending_int
mov wot[ecx+ram+0100h-1], si;V - push now PC
and ebx, 0EFh ;U - clr B flag ...
add ebp, INT_C ;V - add INT Cycles
mov byt[ecx+ram+0100h-2], bl;U - push Flags
sub cl, 3 ;V - sub Stack
or ebx, I_FLAG ;U - set Interrupt Disable Flags
mov eax, dwot[cpu_banks+28];V - get last Bank
mov $s, ecx ;U - write back Stack
mov si, wot[eax+01FFEh] ;V - /N set IRQ addr
jmp main_Loop ;N -
ALIGNXMM
NMI_:
and eax, 1 ;U - clr NMI flag ...
mov ecx, $s ;V - load S stack
and ecx, 0FFh ;U - clr bits
lea edx, [edx] ;V -
mov dwot[int_Pending], eax ;U - write back Pending_int
mov wot[ecx+ram+0100h-1], si;V - push now PC
and ebx, 0EFh ;U - clr B flag ...
add ebp, INT_C ;V - add INT Cycles
mov byt[ecx+ram+0100h-2], bl;U - push Flags
sub cl, 3 ;V - sub Stack
or ebx, I_FLAG ;U - set Interrupt Disable Flags
mov eax, dwot[cpu_banks+28];V - get last Bank
mov $s, ecx ;U - write back Stack
mov si, wot[eax+01FFAh] ;V - /N set NMI addr
jmp main_Loop ;N -
ALIGNXMM
NO_DEAL:
jmp main_Loop
INT_TAB dd NO_DEAL, IRQ_, NMI_, NMI_
exec2a03 endp
set_NMI proc C
option prologue:none, epilogue:none
or dwot[int_Pending], NMI_FLAG
ret
set_NMI endp
setIRQ proc C
option prologue:none, epilogue:none
or dwot[int_Pending], IRQ_FLAG
ret
setIRQ endp
fastNMI proc C
option prologue:none, epilogue:none
fastNMI endp
fastIRQ proc C
option prologue:none, epilogue:none
fastIRQ endp
cpu_Reset proc C
option prologue:none, epilogue:none
push ebx
lea edi, regs
xor ecx, ecx
or $p, 022h
mov $a, ecx
mov $x, ecx
mov $y, ecx
mov $s, 0FFh
mov eax, dwot[cpu_banks+28]
mov ecx, dwot[eax+01FFCh] ; set RESET addr
mov $pc, ecx
pop ebx
ret
cpu_Reset endp
set_DMA_Cycles proc C
option prologue:none, epilogue:none
test dword ptr[esp+4], -1
je __No_Force
mov dwot[regs+024], 514
__No_Force:
add dwot[regs+024], 514
ret
set_DMA_Cycles endp
end
NES 6502
最新推荐文章于 2024-10-10 09:03:38 发布