File : ncpu.S
Authors : FCA author
modified and adapted by Yoyo.
- adapted for fceu by notaz, 2007.
+ timing fixed, missing opcodes added
+ and adapted for fceu by notaz, 2007.
**************************************/
#include "ncpu.h"
+/* emulate (some) dummy reads (may need that because they affect open bus) */
+#define DO_DUMMY_READS 1
+
@@@
@@@ Offets from REG_OP_TABLE
@@@
#define OTOFFS_NES_STACK (nes_stack - cpu_exec_table)
#define OTOFFS_NES_REGS (nes_registers - cpu_exec_table)
#define OTOFFS_PC_BASE (pc_base - cpu_exec_table)
+#define OTOFFS_IRQ_HOOK (MapIRQHook - cpu_exec_table)
+#define OTOFFS_TIMESTAMP (timestamp - cpu_exec_table)
+#define OTOFFS_X (X_ - cpu_exec_table)
@ fceu
#define FCEU_IQNMI 0x08
SECTION_TEXT
ALIGN
-
+/*
+bbbb:
+.ascii "ab_a: %04x"
+.byte 0x0a,0
+.align 4
+stmfd sp!,{r0-r3,r12,lr}
+mov r1,r0
+ldr r0,=bbbb
+bl printf
+ldmfd sp!,{r0-r3,r12,lr}
+*/
@@@
@@@ r0 = Address (unbased)
@@@
.macro REBASE_PC
@ FIXME: do something with mem not in Page[].
+@ stmfd sp!, {r0-r3,r12,lr}
+@ mov r1, r0
+@ ldr r0, =bbbb
+@ bl printf
+@ ldmfd sp!, {r0-r3,r12,lr}
+
cmp r0, #0x2000
ldrge r1, =Page
movge r2, r0, lsr #11
.endm
-.macro RETURN_FROM_CPU_EXEC
- b cpu_exec_end
+@ updates fceu "timestamp" variable
+@ loads cycles to reg, reg!=r1, trashes r1, kills flags
+.macro FLUSH_TIMESTAMP reg
+ ands \reg, REG_CYCLE, #0xff
+ beq 1f
+ ldr r1, [REG_OP_TABLE, #OTOFFS_TIMESTAMP]
+ orr REG_CYCLE, REG_CYCLE, \reg, lsl #8 @ put cycles for do_irq_hook
+ add r1, r1, \reg
+ bic REG_CYCLE, REG_CYCLE, #0xff
+ str r1, [REG_OP_TABLE, #OTOFFS_TIMESTAMP]
+1:
.endm
@@@
@@@ ¤Ê¤ó¤«Ì¾Á°¤¬ÊѤÀ¤Ê(¤É¡¼¤Ç¤â¤¤¡¼¤±¤É¡¼
@@@
-.macro CYCLE_NEXT n
+.macro CYCLE_NEXT n, unused=0, do_cyc_add=1
@@DEBUG_INFO
- subs REG_CYCLE, REG_CYCLE, #\n*48
+.if \do_cyc_add
+ add REG_CYCLE, REG_CYCLE, #\n
+.endif
+ subs REG_CYCLE, REG_CYCLE, #\n*48<<16
ble cpu_exec_end
+ tst REG_P_REST, #1<<16
+ bne do_irq_hook
+
ldrb r0, [REG_PC], #1
tst REG_P_REST, #0xff<<8
ldreq pc, [REG_OP_TABLE, r0, lsl #2]
@ do some messing to find out which IRQ is pending..
- tst REG_P_REST, #FCEU_IQNMI<<8
- bne do_int
+ @ assumption: NMI can be set only on very first run, because it is only set once before vblank..
+@ tst REG_P_REST, #FCEU_IQNMI<<8
+@ bne do_int
tst REG_P_REST, #P_REST_I_FLAG
@@ if I_FLAG=1, continue execution, don't trigger IRQ
bicne REG_P_REST, REG_P_REST, #FCEU_IQTEMP<<8
b do_int
.endm
+@ fceu needs timestamp cycles to be inremented before doing actual opcode.
+@ this is only needed for ops which do memory i/o
+.macro CYCLE_PRE n
+ add REG_CYCLE, REG_CYCLE, #\n
+.endm
+
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@@@ CLI¡¦PHP¤Ê¤É¥Õ¥é¥°¤òÊѹ¹¤·¤¿¾ì¹ç¤Ï¤³¤ì
@@@
.macro CYCLE_NEXT_INT n
-@ @@DEBUG_INFO
-@
-@ subs REG_CYCLE, REG_CYCLE, #\n*48
-@ bgt cpu_exec_check_int
-@ RETURN_FROM_CPU_EXEC
CYCLE_NEXT \n
.endm
@@@ ¥¹¥È¥¢¤¹¤ë¤À¤±¤ÎÌ¿Îá
@@@
-@@@ 16¥Ó¥Ã¥È¥¢¥É¥ì¥¹¤«¤é¥í¡¼¥É¤Î¤ß
-@@@
-@@@ RAM¤«¤é¤Î¥í¡¼¥É¤¬°ìÈÖ¿¤¤¤Î¤ÇÍ¥À褹¤ë
-@@@
-@@@ READ_1
-@@@ OP
-@@@ READ_2
-@@@ OP
+@@@ Read byte
@@@
-@@@ ¤Î¤è¤¦¤Ë»È¤¦
-
-.macro READ_1
- movs r1, REG_ADDR, lsr #13
- adr lr, 9999f
- @@ 0¤Ç¤Ê¤¤»þ¤Ï¥¸¥ã¥ó¥×¤¹¤ë¡£
- @@ ¤Á¤ç¤Ã¤È¹©Éפ·¤Æ1¥¯¥í¥Ã¥¯¸º¤é¤¹
- ldrne pc, [lr, -r1, lsl #2]
- @@ RAM¤«¤é¥í¡¼¥É
- bic r0, REG_ADDR, #0x1800
- add r0, r0, #OTOFFS_NES_RAM
- ldrb r0, [r0, REG_OP_TABLE]
-.endm
-
-.macro READ_2
- .long read_rom_byte
- .long read_rom_byte
- .long read_rom_byte
- .long read_rom_byte
- .long read_save_ram
- .long read_high_reg
- .long read_ppu_reg
-9999:
-.endm
-.macro READ
- mov r1, REG_ADDR, lsr #13
- adr lr, 1f
- ldr pc, [pc, r1, lsl #2]
- nop
- .long 2f @ fast path
- .long read_ppu_reg
- .long read_high_reg
- .long read_save_ram
- .long read_rom_byte
- .long read_rom_byte
- .long read_rom_byte
- .long read_rom_byte
-2:
- bic r0, REG_ADDR, #0x1800
- add r0, r0, #OTOFFS_NES_RAM
- ldrb r0, [r0, REG_OP_TABLE]
- @@ ¤È¤¤¤¦¤ï¤±¤Ç¥¸¥ã¥ó¥×¤¹¤ëɬÍפϤʤ¤
-1:
+.macro READ unused_param
+ tst REG_ADDR, #0xe000
+ @ RAM
+ biceq r0, REG_ADDR, #0x1800
+ addeq r0, r0, #OTOFFS_NES_RAM
+ ldreqb r0, [r0, REG_OP_TABLE]
+ blne read_byte
.endm
@@@
@@@ OP¤Ç¤Ïr3¤òÊݸ¤·¤Ê¤±¤ì¤Ð¤Ê¤é¤Ê¤¤
.macro READ_WRITE_1
- movs r3, REG_ADDR, lsr #13
- adr lr, 9999f
- @@ 0¤Ç¤Ê¤¤»þ¤Ï¥¸¥ã¥ó¥×¤¹¤ë¡£
- @@ ¤Á¤ç¤Ã¤È¹©Éפ·¤Æ1¥¯¥í¥Ã¥¯¸º¤é¤¹
- ldrne pc, [lr, -r3, lsl #2]
- @@ RAM¤«¤é¥í¡¼¥É
+ tst REG_ADDR, #0xe000
+ adrne lr, 9999f
+ bne read_byte
+ @ RAM
bic REG_ADDR, REG_ADDR, #0x1800
add REG_ADDR, REG_ADDR, #OTOFFS_NES_RAM
ldrb r0, [REG_ADDR, REG_OP_TABLE]!
.endm
.macro READ_WRITE_3
- .long read_rom_byte
- .long read_rom_byte
- .long read_rom_byte
- .long read_rom_byte
- .long read_save_ram
- .long read_high_reg
- .long read_ppu_reg
9999:
+ bl write_byte @ rmw first writes unmodified data
.endm
.macro READ_WRITE_4
- adr lr, 1f
- ldr pc, [pc, r3, lsl #2]
- nop
- nop
- .long write_ppu_reg
- .long write_high_reg
- .long write_save_ram
- .long write_rom_byte
- .long write_rom_byte
- .long write_rom_byte
- .long write_rom_byte
-1:
+ bl write_byte @ and only then modified (Blaster Master)
.endm
@@@
-@@@ ½ñ¤¹þ¤ß¤À¤±¤Î¾ì¹ç
+@@@ Write r0 to [addr]
@@@
-@@@ WRITE_1
-@@@ TAIL
-@@@ WRITE_2
-@@@ TAIL
-@@@ ¤È¤¹¤ë
.macro WRITE_1
@@DEBUG_INFO
- movs r1, REG_ADDR, lsr #13
- adr lr, 9999f
- ldrne pc, [lr, -r1, lsl #2]
- bic REG_ADDR, REG_ADDR, #0x1800
- add REG_ADDR, REG_ADDR, #OTOFFS_NES_RAM
-
- strb r0, [REG_ADDR, REG_OP_TABLE]
-.endm
+ tst REG_ADDR, #0xe000
+ biceq REG_ADDR, REG_ADDR, #0x1800
+ addeq REG_ADDR, REG_ADDR, #OTOFFS_NES_RAM
-.macro WRITE_2
- .long write_rom_byte
- .long write_rom_byte
- .long write_rom_byte
- .long write_rom_byte
- .long write_save_ram
- .long write_high_reg
- .long write_ppu_reg
-9999:
+ streqb r0, [REG_ADDR, REG_OP_TABLE]
+ blne write_byte
.endm
@@@
@@@ REG_ADDR¤òÊѹ¹¤¹¤ë¤¬µ¤¤Ë¤¹¤ë¤Ê
@@@
.macro READ_WORD
- READ
+ READ 0
mov REG_PC, r0
add REG_ADDR, REG_ADDR, #1
- READ
+ READ 0
orr r0, REG_PC, r0, lsl #8
.endm
bic REG_ADDR, REG_ADDR, #0x10000
and r0,REG_ADDR,#0xff
cmp REG_Y,r0
- subgt REG_CYCLE,REG_CYCLE,#1*48
+ addgt REG_CYCLE, REG_CYCLE, #1
+ subgt REG_CYCLE, REG_CYCLE, #1*48<<16
+.endm
+
+@ Indirect Indexed (for writes and rmws)
+.macro INDY_ADDR_W
+ ZERO_ADDR
+ ZP_READ_ADDR
+ add REG_ADDR, REG_ADDR, REG_Y
+ bic REG_ADDR, REG_ADDR, #0x10000
.endm
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@@@ $nnnn
-.macro ABS_ADDR
+.macro ABS_ADDR update_db=0
+.if \update_db
+ ldrb r0, [REG_PC, #1]
+ ldrb REG_ADDR, [REG_PC], #2
+ strb r0, [REG_OP_TABLE, #(OTOFFS_X + 0x10)] @ X.DB
+ orr REG_ADDR, REG_ADDR, r0, lsl #8
+.else
tst REG_PC, #1
ldrneb REG_ADDR, [REG_PC], #1
ldrneb r0, [REG_PC], #1
ldreqh REG_ADDR, [REG_PC], #2
orrne REG_ADDR, REG_ADDR, r0, lsl #8
+.endif
.endm
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@@@ $nnnn, X
.macro ABSX_ADDR
- ABS_ADDR
+ ABS_ADDR DO_DUMMY_READS
add REG_ADDR, REG_ADDR, REG_X
bic REG_ADDR, REG_ADDR, #0x10000
and r0,REG_ADDR,#0xff
cmp REG_X,r0
- subgt REG_CYCLE,REG_CYCLE,#1*48
+ addgt REG_CYCLE, REG_CYCLE, #1
+ subgt REG_CYCLE, REG_CYCLE, #1*48<<16
+.endm
+
+@ Absolute Indexed (for writes and rmws)
+.macro ABSX_ADDR_W
+ ABS_ADDR
+ add REG_ADDR, REG_ADDR, REG_X
+ bic REG_ADDR, REG_ADDR, #0x10000
.endm
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@@@ $nnnn, Y
.macro ABSY_ADDR
- ABS_ADDR
+ ABS_ADDR DO_DUMMY_READS @ a hack needed for Paperboy, Dirty Harry controls to work
add REG_ADDR, REG_ADDR, REG_Y
bic REG_ADDR, REG_ADDR, #0x10000
and r0,REG_ADDR,#0xff
cmp REG_Y,r0
- subgt REG_CYCLE,REG_CYCLE,#1*48
+ addgt REG_CYCLE, REG_CYCLE, #1
+ subgt REG_CYCLE, REG_CYCLE, #1*48<<16
.endm
+@ Absolute Indexed (for writes and rmws)
+.macro ABSY_ADDR_W
+ ABS_ADDR
+ add REG_ADDR, REG_ADDR, REG_Y
+ bic REG_ADDR, REG_ADDR, #0x10000
+.endm
+
+@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
+
@@@ P ¤òÉü¸µ¤¹¤ë
@@@ r0 => 6502 ¤Î P ¥ì¥¸¥¹¥¿
@@@ REG_NZ <= Éü¸µ¤µ¤ì¤¿ REG_NZ
opD8: @ CLD
IMPLIED
- @@bic REG_P_REST, REG_P_REST, #P_REST_D_FLAG
+ bic REG_P_REST, REG_P_REST, #P_REST_D_FLAG
CYCLE_NEXT 2
opF8: @ SED
IMPLIED
- @@orr REG_P_REST, REG_P_REST, #P_REST_D_FLAG
+ orr REG_P_REST, REG_P_REST, #P_REST_D_FLAG
CYCLE_NEXT 2
op58: @ CLI
CYCLE_NEXT 4
opAD: @ LDA $nnnn
+ CYCLE_PRE 4
ABS_ADDR
- READ_1
- OP_LDA
- CYCLE_NEXT 4
- READ_2
+ READ
OP_LDA
- CYCLE_NEXT 4
+ CYCLE_NEXT 4,1,0
opBD: @ LDA $nnnn, X
+ CYCLE_PRE 4
ABSX_ADDR
- READ_1
- OP_LDA
- CYCLE_NEXT 4
- READ_2
+ READ
OP_LDA
- CYCLE_NEXT 4
+ CYCLE_NEXT 4,1,0
opB9: @ LDA $nnnn, Y
+ CYCLE_PRE 4
ABSY_ADDR
- READ_1
- OP_LDA
- CYCLE_NEXT 4
- READ_2
+ READ
OP_LDA
- CYCLE_NEXT 4
+ CYCLE_NEXT 4,1,0
opA1: @ LDA ($nn, X)
+ CYCLE_PRE 6
INDX_ADDR
- READ_1
- OP_LDA
- CYCLE_NEXT 6
- READ_2
+ READ
OP_LDA
- CYCLE_NEXT 6
+ CYCLE_NEXT 6,1,0
opB1: @ LDA ($nn), Y
+ CYCLE_PRE 5
INDY_ADDR
- READ_1
- OP_LDA
- CYCLE_NEXT 5
- READ_2
+ READ
OP_LDA
- CYCLE_NEXT 5
-
+ CYCLE_NEXT 5,1,0
opA2: @ LDX #$nn
IMM_VALUE
CYCLE_NEXT 4
opAE: @ LDX $nnnn
+ CYCLE_PRE 4
ABS_ADDR
- READ_1
- OP_LDX
- CYCLE_NEXT 4
- READ_2
+ READ
OP_LDX
- CYCLE_NEXT 4
+ CYCLE_NEXT 4,1,0
opBE: @ LDX $nnnn, Y
+ CYCLE_PRE 4
ABSY_ADDR
- READ_1
- OP_LDX
- CYCLE_NEXT 4
- READ_2
+ READ
OP_LDX
- CYCLE_NEXT 4
+ CYCLE_NEXT 4,1,0
opAC: @ LDY $nnnn
+ CYCLE_PRE 4
ABS_ADDR
- READ_1
- OP_LDY
- CYCLE_NEXT 4
- READ_2
+ READ
OP_LDY
- CYCLE_NEXT 4
+ CYCLE_NEXT 4,1,0
opBC: @ LDY $nnnn, X
+ CYCLE_PRE 4
ABSX_ADDR
- READ_1
- OP_LDY
- CYCLE_NEXT 4
- READ_2
+ READ
OP_LDY
- CYCLE_NEXT 4
+ CYCLE_NEXT 4,1,0
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
CYCLE_NEXT 4
op8D: @ STA $nnnn
+ CYCLE_PRE 4
ABS_ADDR
OP_STA
WRITE_1
- CYCLE_NEXT 4
- WRITE_2
- CYCLE_NEXT 4
+ CYCLE_NEXT 4,1,0
op9D: @ STA $nnnn, X
- ABSX_ADDR
+ CYCLE_PRE 5
+ ABSX_ADDR_W
OP_STA
WRITE_1
- CYCLE_NEXT 5
- WRITE_2
- CYCLE_NEXT 5
+ CYCLE_NEXT 5,1,0
op99: @ STA $nnnn, Y
- ABSY_ADDR
+ CYCLE_PRE 5
+ ABSY_ADDR_W
OP_STA
WRITE_1
- CYCLE_NEXT 5
- WRITE_2
- CYCLE_NEXT 5
+ CYCLE_NEXT 5,1,0
op81: @ STA ($nn, X)
+ CYCLE_PRE 6
INDX_ADDR
OP_STA
WRITE_1
- CYCLE_NEXT 6
- WRITE_2
- CYCLE_NEXT 6
+ CYCLE_NEXT 6,1,0
op91: @ STA ($nn), Y
- INDY_ADDR
+ CYCLE_PRE 6
+ INDY_ADDR_W
OP_STA
WRITE_1
- CYCLE_NEXT 6
- WRITE_2
- CYCLE_NEXT 6
+ CYCLE_NEXT 6,1,0
op86: @ STX $nn
CYCLE_NEXT 4
op8E: @ STX $nnnn
+ CYCLE_PRE 4
ABS_ADDR
mov r0, REG_X
WRITE_1
- CYCLE_NEXT 4
- WRITE_2
- CYCLE_NEXT 4
+ CYCLE_NEXT 4,1,0
op84: @ STY $nn
CYCLE_NEXT 4
op8C: @ STY $nnnn
+ CYCLE_PRE 4
ABS_ADDR
mov r0, REG_Y
WRITE_1
- CYCLE_NEXT 4
- WRITE_2
- CYCLE_NEXT 4
+ CYCLE_NEXT 4,1,0
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
CYCLE_NEXT 6
opEE: @ INC $nnnn
+ CYCLE_PRE 6
ABS_ADDR
READ_WRITE_1
OP_INC
READ_WRITE_2
- CYCLE_NEXT 6
+ CYCLE_NEXT 6,1,0
READ_WRITE_3
OP_INC
READ_WRITE_4
- CYCLE_NEXT 6
+ CYCLE_NEXT 6,1,0
opFE: @ INC $nnnn, X
- ABSX_ADDR
+ CYCLE_PRE 7
+ ABSX_ADDR_W
READ_WRITE_1
OP_INC
READ_WRITE_2
- CYCLE_NEXT 7
+ CYCLE_NEXT 7,1,0
READ_WRITE_3
OP_INC
READ_WRITE_4
- CYCLE_NEXT 7
+ CYCLE_NEXT 7,1,0
opE8: @ INX
IMPLIED
CYCLE_NEXT 6
opCE: @ DEC $nnnn
+ CYCLE_PRE 6
ABS_ADDR
READ_WRITE_1
OP_DEC
READ_WRITE_2
- CYCLE_NEXT 6
+ CYCLE_NEXT 6,1,0
READ_WRITE_3
OP_DEC
READ_WRITE_4
- CYCLE_NEXT 6
+ CYCLE_NEXT 6,1,0
opDE: @ DEC $nnnn, X
- ABSX_ADDR
+ CYCLE_PRE 7
+ ABSX_ADDR_W
READ_WRITE_1
OP_DEC
READ_WRITE_2
- CYCLE_NEXT 7
+ CYCLE_NEXT 7,1,0
READ_WRITE_3
OP_DEC
READ_WRITE_4
- CYCLE_NEXT 7
+ CYCLE_NEXT 7,1,0
opCA: @ DEX
IMPLIED
CYCLE_NEXT 4
op6D: @ ADC $nnnn
+ CYCLE_PRE 4
ABS_ADDR
- READ_1
- OP_ADC
- CYCLE_NEXT 4
- READ_2
+ READ
OP_ADC
- CYCLE_NEXT 4
+ CYCLE_NEXT 4,1,0
op7D: @ ADC $nnnn, X
+ CYCLE_PRE 4
ABSX_ADDR
- READ_1
- OP_ADC
- CYCLE_NEXT 4
- READ_2
+ READ
OP_ADC
- CYCLE_NEXT 4
+ CYCLE_NEXT 4,1,0
op79: @ ADC $nnnn, Y
+ CYCLE_PRE 4
ABSY_ADDR
- READ_1
- OP_ADC
- CYCLE_NEXT 4
- READ_2
+ READ
OP_ADC
- CYCLE_NEXT 4
+ CYCLE_NEXT 4,1,0
op61: @ ADC ($nn, X)
+ CYCLE_PRE 6
INDX_ADDR
- READ_1
- OP_ADC
- CYCLE_NEXT 6
- READ_2
+ READ
OP_ADC
- CYCLE_NEXT 6
+ CYCLE_NEXT 6,1,0
op71: @ ADC ($nn), Y
+ CYCLE_PRE 5
INDY_ADDR
- READ_1
- OP_ADC
- CYCLE_NEXT 5
- READ_2
+ READ
OP_ADC
- CYCLE_NEXT 5
+ CYCLE_NEXT 5,1,0
opEB: @ USBC #$nn
opE9: @ SBC #$nn
CYCLE_NEXT 4
opED: @ SBC $nnnn
+ CYCLE_PRE 4
ABS_ADDR
- READ_1
- OP_SBC
- CYCLE_NEXT 4
- READ_2
+ READ
OP_SBC
- CYCLE_NEXT 4
+ CYCLE_NEXT 4,1,0
opFD: @ SBC $nnnn, X
+ CYCLE_PRE 4
ABSX_ADDR
- READ_1
- OP_SBC
- CYCLE_NEXT 4
- READ_2
+ READ
OP_SBC
- CYCLE_NEXT 4
+ CYCLE_NEXT 4,1,0
opF9: @ SBC $nnnn, Y
+ CYCLE_PRE 4
ABSY_ADDR
- READ_1
- OP_SBC
- CYCLE_NEXT 4
- READ_2
+ READ
OP_SBC
- CYCLE_NEXT 4
+ CYCLE_NEXT 4,1,0
opE1: @ SBC ($nn, X)
+ CYCLE_PRE 6
INDX_ADDR
- READ_1
- OP_SBC
- CYCLE_NEXT 6
- READ_2
+ READ
OP_SBC
- CYCLE_NEXT 6
+ CYCLE_NEXT 6,1,0
opF1: @ SBC ($nn), Y
+ CYCLE_PRE 5
INDY_ADDR
- READ_1
- OP_SBC
- CYCLE_NEXT 5
- READ_2
+ READ
OP_SBC
- CYCLE_NEXT 5
+ CYCLE_NEXT 5,1,0
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
CYCLE_NEXT 4
op2D: @ AND $nnnn
+ CYCLE_PRE 4
ABS_ADDR
- READ_1
- OP_AND
- CYCLE_NEXT 4
- READ_2
+ READ
OP_AND
- CYCLE_NEXT 4
+ CYCLE_NEXT 4,1,0
op3D: @ AND $nnnn, X
+ CYCLE_PRE 4
ABSX_ADDR
- READ_1
- OP_AND
- CYCLE_NEXT 4
- READ_2
+ READ
OP_AND
- CYCLE_NEXT 4
+ CYCLE_NEXT 4,1,0
op39: @ AND $nnnn, Y
+ CYCLE_PRE 4
ABSY_ADDR
- READ_1
- OP_AND
- CYCLE_NEXT 4
- READ_2
+ READ
OP_AND
- CYCLE_NEXT 4
+ CYCLE_NEXT 4,1,0
op21: @ AND ($nn, X)
+ CYCLE_PRE 6
INDX_ADDR
- READ_1
- OP_AND
- CYCLE_NEXT 6
- READ_2
+ READ
OP_AND
- CYCLE_NEXT 6
+ CYCLE_NEXT 6,1,0
op31: @ AND ($nn), Y
+ CYCLE_PRE 5
INDY_ADDR
- READ_1
- OP_AND
- CYCLE_NEXT 5
- READ_2
+ READ
OP_AND
- CYCLE_NEXT 5
+ CYCLE_NEXT 5,1,0
op49: @ EOR #$nn
CYCLE_NEXT 4
op4D: @ EOR $nnnn
+ CYCLE_PRE 4
ABS_ADDR
- READ_1
- OP_EOR
- CYCLE_NEXT 4
- READ_2
+ READ
OP_EOR
- CYCLE_NEXT 4
+ CYCLE_NEXT 4,1,0
op5D: @ EOR $nnnn, X
+ CYCLE_PRE 4
ABSX_ADDR
- READ_1
- OP_EOR
- CYCLE_NEXT 4
- READ_2
+ READ
OP_EOR
- CYCLE_NEXT 4
+ CYCLE_NEXT 4,1,0
op59: @ EOR $nnnn, Y
+ CYCLE_PRE 4
ABSY_ADDR
- READ_1
- OP_EOR
- CYCLE_NEXT 4
- READ_2
+ READ
OP_EOR
- CYCLE_NEXT 4
+ CYCLE_NEXT 4,1,0
op41: @ EOR ($nn, X)
+ CYCLE_PRE 6
INDX_ADDR
- READ_1
- OP_EOR
- CYCLE_NEXT 6
- READ_2
+ READ
OP_EOR
- CYCLE_NEXT 6
+ CYCLE_NEXT 6,1,0
op51: @ EOR ($nn), Y
+ CYCLE_PRE 5
INDY_ADDR
- READ_1
- OP_EOR
- CYCLE_NEXT 5
- READ_2
+ READ
OP_EOR
- CYCLE_NEXT 5
+ CYCLE_NEXT 5,1,0
op09: @ ORA #$nn
CYCLE_NEXT 4
op0D: @ ORA $nnnn
+ CYCLE_PRE 4
ABS_ADDR
- READ_1
- OP_ORA
- CYCLE_NEXT 4
- READ_2
+ READ
OP_ORA
- CYCLE_NEXT 4
+ CYCLE_NEXT 4,1,0
op1D: @ ORA $nnnn, X
+ CYCLE_PRE 4
ABSX_ADDR
- READ_1
- OP_ORA
- CYCLE_NEXT 4
- READ_2
+ READ
OP_ORA
- CYCLE_NEXT 4
+ CYCLE_NEXT 4,1,0
op19: @ ORA $nnnn, Y
+ CYCLE_PRE 4
ABSY_ADDR
- READ_1
- OP_ORA
- CYCLE_NEXT 4
- READ_2
+ READ
OP_ORA
- CYCLE_NEXT 4
+ CYCLE_NEXT 4,1,0
op01: @ ORA ($nn, X)
+ CYCLE_PRE 6
INDX_ADDR
- READ_1
- OP_ORA
- CYCLE_NEXT 6
- READ_2
+ READ
OP_ORA
- CYCLE_NEXT 6
+ CYCLE_NEXT 6,1,0
op11: @ ORA ($nn), Y
+ CYCLE_PRE 5
INDY_ADDR
- READ_1
- OP_ORA
- CYCLE_NEXT 5
- READ_2
+ READ
OP_ORA
- CYCLE_NEXT 5
+ CYCLE_NEXT 5,1,0
CYCLE_NEXT 4
opCD: @ CMP $nnnn
+ CYCLE_PRE 4
ABS_ADDR
- READ_1
- OP_CMP
- CYCLE_NEXT 4
- READ_2
+ READ
OP_CMP
- CYCLE_NEXT 4
+ CYCLE_NEXT 4,1,0
opDD: @ CMP $nnnn, X
+ CYCLE_PRE 4
ABSX_ADDR
- READ_1
- OP_CMP
- CYCLE_NEXT 4
- READ_2
+ READ
OP_CMP
- CYCLE_NEXT 4
+ CYCLE_NEXT 4,1,0
opD9: @ CMP $nnnn, Y
+ CYCLE_PRE 4
ABSY_ADDR
- READ_1
- OP_CMP
- CYCLE_NEXT 4
- READ_2
+ READ
OP_CMP
- CYCLE_NEXT 4
+ CYCLE_NEXT 4,1,0
opC1: @ CMP ($nn, X)
+ CYCLE_PRE 6
INDX_ADDR
- READ_1
- OP_CMP
- CYCLE_NEXT 6
- READ_2
+ READ
OP_CMP
- CYCLE_NEXT 6
+ CYCLE_NEXT 6,1,0
opD1: @ CMP ($nn), Y
+ CYCLE_PRE 5
INDY_ADDR
- READ_1
- OP_CMP
- CYCLE_NEXT 5
- READ_2
+ READ
OP_CMP
- CYCLE_NEXT 5
+ CYCLE_NEXT 5,1,0
opE0: @ CPX #$nn
CYCLE_NEXT 3
opEC: @ CPX $nnnn
+ CYCLE_PRE 4
ABS_ADDR
- READ_1
- OP_CPX
- CYCLE_NEXT 4
- READ_2
+ READ
OP_CPX
- CYCLE_NEXT 4
+ CYCLE_NEXT 4,1,0
opC0: @ CPY #$nn
CYCLE_NEXT 3
opCC: @ CPY $nnnn
+ CYCLE_PRE 4
ABS_ADDR
- READ_1
- OP_CPY
- CYCLE_NEXT 4
- READ_2
+ READ
OP_CPY
- CYCLE_NEXT 4
+ CYCLE_NEXT 4,1,0
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
CYCLE_NEXT 3
op2C: @ BIT $nnnn
+ CYCLE_PRE 4
ABS_ADDR
- READ_1
- OP_BIT
- CYCLE_NEXT 4
- READ_2
+ READ
OP_BIT
- CYCLE_NEXT 4
+ CYCLE_NEXT 4,1,0
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
CYCLE_NEXT 6
op0E: @ ASL $nnnn
+ CYCLE_PRE 6
ABS_ADDR
READ_WRITE_1
OP_ASL
READ_WRITE_2
- CYCLE_NEXT 6
+ CYCLE_NEXT 6,1,0
READ_WRITE_3
OP_ASL
READ_WRITE_4
- CYCLE_NEXT 6
+ CYCLE_NEXT 6,1,0
op1E: @ ASL $nnnn, X
- ABSX_ADDR
+ CYCLE_PRE 7
+ ABSX_ADDR_W
READ_WRITE_1
OP_ASL
READ_WRITE_2
- CYCLE_NEXT 7
+ CYCLE_NEXT 7,1,0
READ_WRITE_3
OP_ASL
READ_WRITE_4
- CYCLE_NEXT 7
+ CYCLE_NEXT 7,1,0
op4A: @ LSR A
CYCLE_NEXT 6
op4E: @ LSR $nnnn
+ CYCLE_PRE 6
ABS_ADDR
READ_WRITE_1
OP_LSR
READ_WRITE_2
- CYCLE_NEXT 6
+ CYCLE_NEXT 6,1,0
READ_WRITE_3
OP_LSR
READ_WRITE_4
- CYCLE_NEXT 6
+ CYCLE_NEXT 6,1,0
op5E: @ LSR $nnnn, X
- ABSX_ADDR
+ CYCLE_PRE 7
+ ABSX_ADDR_W
READ_WRITE_1
OP_LSR
READ_WRITE_2
- CYCLE_NEXT 7
+ CYCLE_NEXT 7,1,0
READ_WRITE_3
OP_LSR
READ_WRITE_4
- CYCLE_NEXT 7
+ CYCLE_NEXT 7,1,0
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
CYCLE_NEXT 6
op2E: @ ROL $nnnn
+ CYCLE_PRE 6
ABS_ADDR
READ_WRITE_1
OP_ROL
READ_WRITE_2
- CYCLE_NEXT 6
+ CYCLE_NEXT 6,1,0
READ_WRITE_3
OP_ROL
READ_WRITE_4
- CYCLE_NEXT 6
+ CYCLE_NEXT 6,1,0
op3E: @ ROL $nnnn, X
- ABSX_ADDR
+ CYCLE_PRE 7
+ ABSX_ADDR_W
READ_WRITE_1
OP_ROL
READ_WRITE_2
- CYCLE_NEXT 7
+ CYCLE_NEXT 7,1,0
READ_WRITE_3
OP_ROL
READ_WRITE_4
- CYCLE_NEXT 7
+ CYCLE_NEXT 7,1,0
op6A: @ ROR A
CYCLE_NEXT 6
op6E: @ ROR $nnnn
+ CYCLE_PRE 6
ABS_ADDR
READ_WRITE_1
OP_ROR
READ_WRITE_2
- CYCLE_NEXT 6
+ CYCLE_NEXT 6,1,0
READ_WRITE_3
OP_ROR
READ_WRITE_4
- CYCLE_NEXT 6
+ CYCLE_NEXT 6,1,0
op7E: @ ROR $nnnn, X
- ABSX_ADDR
+ CYCLE_PRE 7
+ ABSX_ADDR_W
READ_WRITE_1
OP_ROR
READ_WRITE_2
- CYCLE_NEXT 7
+ CYCLE_NEXT 7,1,0
READ_WRITE_3
OP_ROR
READ_WRITE_4
- CYCLE_NEXT 7
+ CYCLE_NEXT 7,1,0
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
and r1,r1,#0xff
add r1,r3,r1
tst r1,#0x100
- subne REG_CYCLE,REG_CYCLE, #1*48
+ addne REG_CYCLE, REG_CYCLE, #1
+ subne REG_CYCLE, REG_CYCLE, #1*48<<16
.endm
.macro BRANCH_EQ
ldreqsb r1, [REG_PC], #1
movne r1, #1
add REG_PC, REG_PC, r1
- subeq REG_CYCLE, REG_CYCLE, #1*48
+ addeq REG_CYCLE, REG_CYCLE, #1
+ subeq REG_CYCLE, REG_CYCLE, #1*48<<16
bne 1f
HAD_BRANCH
1:
ldrnesb r1, [REG_PC], #1
moveq r1, #1
add REG_PC, REG_PC, r1
- subne REG_CYCLE, REG_CYCLE, #1*48
+ addne REG_CYCLE, REG_CYCLE, #1
+ subne REG_CYCLE, REG_CYCLE, #1*48<<16
beq 1f
HAD_BRANCH
1:
and r0, r0, #0xFF
.endm
-.macro OP_SHY
- mov r0,REG_ADDR, lsr #8
- add r0,r0,#1
- and r0,r0,REG_Y
-.endm
-
.macro OP_SRE
movs r0, r0, lsr #1
@@set C flag
@@ ¥¥ã¥ê¡¼¤òÊݸ
adc REG_P_REST, r1, r1
and REG_A,REG_A,r0,lsl #24
+ orr REG_NZ, REG_A, REG_A, lsr #24 @ according to fceu
.endm
-.macro OP_RRA
- movs r1, REG_P_REST, lsr #1
- orrcs r0, r0, #0x100
- movs r0, r0, lsr #1
-.endm
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
CYCLE_NEXT 6
op4F: @ SRE $nnnn
+ CYCLE_PRE 6
ABS_ADDR
READ_WRITE_1
OP_SRE
READ_WRITE_2
- CYCLE_NEXT 6
+ CYCLE_NEXT 6,1,0
READ_WRITE_3
OP_SRE
READ_WRITE_4
- CYCLE_NEXT 6
+ CYCLE_NEXT 6,1,0
op5F: @ SRE $nnnn, X
- ABSX_ADDR
+ CYCLE_PRE 7
+ ABSX_ADDR_W
READ_WRITE_1
OP_SRE
READ_WRITE_2
- CYCLE_NEXT 7
+ CYCLE_NEXT 7,1,0
READ_WRITE_3
OP_SRE
READ_WRITE_4
- CYCLE_NEXT 7
+ CYCLE_NEXT 7,1,0
op5B: @ SRE $nnnn, Y
- ABSY_ADDR
+ CYCLE_PRE 7
+ ABSY_ADDR_W
READ_WRITE_1
OP_SRE
READ_WRITE_2
- CYCLE_NEXT 7
+ CYCLE_NEXT 7,1,0
READ_WRITE_3
OP_SRE
READ_WRITE_4
- CYCLE_NEXT 7
+ CYCLE_NEXT 7,1,0
op43: @ SRE ($nn, X)
+ CYCLE_PRE 8
INDX_ADDR
READ_WRITE_1
OP_SRE
READ_WRITE_2
- CYCLE_NEXT 8
+ CYCLE_NEXT 8,1,0
READ_WRITE_3
OP_SRE
READ_WRITE_4
- CYCLE_NEXT 8
+ CYCLE_NEXT 8,1,0
op53: @ SRE ($nn), Y
- INDY_ADDR
+ CYCLE_PRE 8
+ INDY_ADDR_W
READ_WRITE_1
OP_SRE
READ_WRITE_2
- CYCLE_NEXT 8
+ CYCLE_NEXT 8,1,0
READ_WRITE_3
OP_SRE
READ_WRITE_4
- CYCLE_NEXT 8
-
+ CYCLE_NEXT 8,1,0
-op9C: @ SHY $nnnn, X
- ABSX_ADDR
- OP_SHY
- WRITE_1
- CYCLE_NEXT 5
- WRITE_2
- CYCLE_NEXT 5
opE7: @ ISB $nn
ZERO_ADDR
CYCLE_NEXT 6
opEF: @ ISB $nnnn
+ CYCLE_PRE 6
ABS_ADDR
READ_WRITE_1
OP_ISB
READ_WRITE_2
OP_SBC
- CYCLE_NEXT 6
+ CYCLE_NEXT 6,1,0
READ_WRITE_3
OP_ISB
READ_WRITE_4
OP_SBC
- CYCLE_NEXT 6
+ CYCLE_NEXT 6,1,0
opFF: @ ISB $nnnn,X
- ABSX_ADDR
+ CYCLE_PRE 7
+ ABSX_ADDR_W
READ_WRITE_1
OP_ISB
READ_WRITE_2
OP_SBC
- CYCLE_NEXT 7
+ CYCLE_NEXT 7,1,0
READ_WRITE_3
OP_ISB
READ_WRITE_4
OP_SBC
- CYCLE_NEXT 7
+ CYCLE_NEXT 7,1,0
opFB: @ ISB $nnnn, Y
- ABSY_ADDR
+ CYCLE_PRE 7
+ ABSY_ADDR_W
READ_WRITE_1
OP_ISB
READ_WRITE_2
OP_SBC
- CYCLE_NEXT 7
+ CYCLE_NEXT 7,1,0
READ_WRITE_3
OP_ISB
READ_WRITE_4
OP_SBC
- CYCLE_NEXT 7
+ CYCLE_NEXT 7,1,0
opE3: @ ISB ($nn, X)
+ CYCLE_PRE 8
INDX_ADDR
READ_WRITE_1
OP_ISB
READ_WRITE_2
OP_SBC
- CYCLE_NEXT 7
+ CYCLE_NEXT 8,1,0
READ_WRITE_3
OP_ISB
READ_WRITE_4
OP_SBC
- CYCLE_NEXT 7
+ CYCLE_NEXT 8,1,0
opF3: @ ISB ($nn), Y
+ CYCLE_PRE 8
INDY_ADDR
READ_WRITE_1
OP_ISB
READ_WRITE_2
OP_SBC
- CYCLE_NEXT 7
+ CYCLE_NEXT 8,1,0
READ_WRITE_3
OP_ISB
READ_WRITE_4
OP_SBC
- CYCLE_NEXT 7
+ CYCLE_NEXT 8,1,0
opA7: @ LAX $nn
ZERO_ADDR
CYCLE_NEXT 4
opAF: @ LAX $nnnn
+ CYCLE_PRE 4
ABS_ADDR
- READ_1
- OP_LAX
- CYCLE_NEXT 4
- READ_2
+ READ
OP_LAX
- CYCLE_NEXT 4
+ CYCLE_NEXT 4,1,0
opBF: @ LAX $nnnn, Y
+ CYCLE_PRE 4
ABSY_ADDR
- READ_1
- OP_LAX
- CYCLE_NEXT 4
- READ_2
+ READ
OP_LAX
- CYCLE_NEXT 4
+ CYCLE_NEXT 4,1,0
opA3: @ LAX ($nn, X)
+ CYCLE_PRE 6
INDX_ADDR
- READ_1
- OP_LAX
- CYCLE_NEXT 6
- READ_2
+ READ
OP_LAX
- CYCLE_NEXT 6
+ CYCLE_NEXT 6,1,0
opB3: @ LAX ($nn), Y
+ CYCLE_PRE 5
INDY_ADDR
- READ_1
- OP_LAX
- CYCLE_NEXT 5
- READ_2
+ READ
OP_LAX
- CYCLE_NEXT 5
+ CYCLE_NEXT 5,1,0
op07: @ SLO $nn
+ CYCLE_PRE 5
ZERO_ADDR
ZP_READ_W
OP_SLO
ZP_WRITE_W
- CYCLE_NEXT 5
+ CYCLE_NEXT 5,1,0
op17: @ SLO $nn, X
ZEROX_ADDR
CYCLE_NEXT 6
op0F: @ SLO $nnnn
+ CYCLE_PRE 6
ABS_ADDR
READ_WRITE_1
OP_SLO
READ_WRITE_2
- CYCLE_NEXT 6
+ CYCLE_NEXT 6,1,0
READ_WRITE_3
OP_SLO
READ_WRITE_4
- CYCLE_NEXT 6
+ CYCLE_NEXT 6,1,0
op1F: @ SLO $nnnn, X
- ABSX_ADDR
+ CYCLE_PRE 7
+ ABSX_ADDR_W
READ_WRITE_1
OP_SLO
READ_WRITE_2
- CYCLE_NEXT 7
+ CYCLE_NEXT 7,1,0
READ_WRITE_3
OP_SLO
READ_WRITE_4
- CYCLE_NEXT 7
+ CYCLE_NEXT 7,1,0
op1B: @ SLO $nnnn, Y
- ABSY_ADDR
+ CYCLE_PRE 7
+ ABSY_ADDR_W
READ_WRITE_1
OP_SLO
READ_WRITE_2
- CYCLE_NEXT 7
+ CYCLE_NEXT 7,1,0
READ_WRITE_3
OP_SLO
READ_WRITE_4
- CYCLE_NEXT 7
+ CYCLE_NEXT 7,1,0
op03: @ SLO ($nn, X)
+ CYCLE_PRE 8
INDX_ADDR
READ_WRITE_1
OP_SLO
READ_WRITE_2
- CYCLE_NEXT 8
+ CYCLE_NEXT 8,1,0
READ_WRITE_3
OP_SLO
READ_WRITE_4
- CYCLE_NEXT 8
+ CYCLE_NEXT 8,1,0
op13: @ SLO ($nn), Y
- INDY_ADDR
+ CYCLE_PRE 8
+ INDY_ADDR_W
READ_WRITE_1
OP_SLO
READ_WRITE_2
- CYCLE_NEXT 8
+ CYCLE_NEXT 8,1,0
READ_WRITE_3
OP_SLO
READ_WRITE_4
- CYCLE_NEXT 8
+ CYCLE_NEXT 8,1,0
opCB: @ SBX #$nn
IMM_VALUE
CYCLE_NEXT 6
opCF: @ DCP $nnnn
+ CYCLE_PRE 6
ABS_ADDR
READ_WRITE_1
OP_DCP
READ_WRITE_2
OP_CMP
- CYCLE_NEXT 6
+ CYCLE_NEXT 6,1,0
READ_WRITE_3
OP_DCP
READ_WRITE_4
OP_CMP
- CYCLE_NEXT 6
+ CYCLE_NEXT 6,1,0
opDF: @ DCP $nnnn, X
- ABSX_ADDR
+ CYCLE_PRE 7
+ ABSX_ADDR_W
READ_WRITE_1
OP_DCP
READ_WRITE_2
OP_CMP
- CYCLE_NEXT 7
+ CYCLE_NEXT 7,1,0
READ_WRITE_3
OP_DCP
READ_WRITE_4
OP_CMP
- CYCLE_NEXT 7
+ CYCLE_NEXT 7,1,0
opDB: @ DCP $nnnn, Y
- ABSY_ADDR
+ CYCLE_PRE 7
+ ABSY_ADDR_W
READ_WRITE_1
OP_DCP
READ_WRITE_2
OP_CMP
- CYCLE_NEXT 7
+ CYCLE_NEXT 7,1,0
READ_WRITE_3
OP_DCP
READ_WRITE_4
OP_CMP
- CYCLE_NEXT 7
+ CYCLE_NEXT 7,1,0
opC3: @ DCP ($nn, X)
+ CYCLE_PRE 8
INDX_ADDR
READ_WRITE_1
OP_DCP
READ_WRITE_2
OP_CMP
- CYCLE_NEXT 8
+ CYCLE_NEXT 8,1,0
READ_WRITE_3
OP_DCP
READ_WRITE_4
OP_CMP
- CYCLE_NEXT 8
+ CYCLE_NEXT 8,1,0
opD3: @ DCP ($nn), Y
- INDY_ADDR
+ CYCLE_PRE 8
+ INDY_ADDR_W
READ_WRITE_1
OP_DCP
READ_WRITE_2
OP_CMP
- CYCLE_NEXT 8
+ CYCLE_NEXT 8,1,0
READ_WRITE_3
OP_DCP
READ_WRITE_4
OP_CMP
- CYCLE_NEXT 8
+ CYCLE_NEXT 8,1,0
op27: @ RLA $nn
ZERO_ADDR
CYCLE_NEXT 6
op2F: @ RLA $nnnn
+ CYCLE_PRE 6
ABS_ADDR
READ_WRITE_1
OP_RLA
READ_WRITE_2
- CYCLE_NEXT 6
+ CYCLE_NEXT 6,1,0
READ_WRITE_3
OP_RLA
READ_WRITE_4
- CYCLE_NEXT 6
+ CYCLE_NEXT 6,1,0
op3F: @ RLA $nnnn, X
- ABSX_ADDR
+ CYCLE_PRE 7
+ ABSX_ADDR_W
READ_WRITE_1
OP_RLA
READ_WRITE_2
- CYCLE_NEXT 7
+ CYCLE_NEXT 7,1,0
READ_WRITE_3
OP_RLA
READ_WRITE_4
- CYCLE_NEXT 7
+ CYCLE_NEXT 7,1,0
op3B: @ RLA $nnnn, Y
- ABSY_ADDR
+ CYCLE_PRE 7
+ ABSY_ADDR_W
READ_WRITE_1
OP_RLA
- READ_WRITE_2
- CYCLE_NEXT 7
+ READ_WRITE_2
+ CYCLE_NEXT 7,1,0
READ_WRITE_3
OP_RLA
READ_WRITE_4
- CYCLE_NEXT 7
+ CYCLE_NEXT 7,1,0
op23: @ RLA ($nn, X)
+ CYCLE_PRE 8
INDX_ADDR
READ_WRITE_1
OP_RLA
READ_WRITE_2
- CYCLE_NEXT 8
+ CYCLE_NEXT 8,1,0
READ_WRITE_3
OP_RLA
READ_WRITE_4
- CYCLE_NEXT 8
+ CYCLE_NEXT 8,1,0
op33: @ RLA ($nn), Y
- INDY_ADDR
+ CYCLE_PRE 8
+ INDY_ADDR_W
READ_WRITE_1
OP_RLA
READ_WRITE_2
- CYCLE_NEXT 8
+ CYCLE_NEXT 8,1,0
READ_WRITE_3
OP_RLA
READ_WRITE_4
- CYCLE_NEXT 8
+ CYCLE_NEXT 8,1,0
op67: @ RRA $nn
ZERO_ADDR
ZP_READ_W
- OP_RRA
+ OP_ROR
ZP_WRITE_W
OP_ADC
CYCLE_NEXT 5
op77: @ RRA $nn, X
ZEROX_ADDR
ZP_READ_W
- OP_RRA
+ OP_ROR
ZP_WRITE_W
OP_ADC
CYCLE_NEXT 6
op6F: @ RRA $nnnn
+ CYCLE_PRE 6
ABS_ADDR
READ_WRITE_1
- OP_RRA
+ OP_ROR
READ_WRITE_2
OP_ADC
- CYCLE_NEXT 6
+ CYCLE_NEXT 6,1,0
READ_WRITE_3
- OP_RRA
+ OP_ROR
READ_WRITE_4
OP_ADC
- CYCLE_NEXT 6
+ CYCLE_NEXT 6,1,0
op7F: @ RRA $nnnn, X
- ABSX_ADDR
+ CYCLE_PRE 7
+ ABSX_ADDR_W
READ_WRITE_1
- OP_RRA
+ OP_ROR
READ_WRITE_2
OP_ADC
- CYCLE_NEXT 7
+ CYCLE_NEXT 7,1,0
READ_WRITE_3
- OP_RRA
+ OP_ROR
READ_WRITE_4
OP_ADC
- CYCLE_NEXT 7
+ CYCLE_NEXT 7,1,0
op7B: @ RRA $nnnn, Y
- ABSY_ADDR
+ CYCLE_PRE 7
+ ABSY_ADDR_W
READ_WRITE_1
- OP_RRA
+ OP_ROR
READ_WRITE_2
OP_ADC
- CYCLE_NEXT 7
+ CYCLE_NEXT 7,1,0
READ_WRITE_3
- OP_RRA
+ OP_ROR
READ_WRITE_4
OP_ADC
- CYCLE_NEXT 7
+ CYCLE_NEXT 7,1,0
op63: @ RRA ($nn, X)
+ CYCLE_PRE 8
INDX_ADDR
READ_WRITE_1
- OP_RRA
+ OP_ROR
READ_WRITE_2
OP_ADC
- CYCLE_NEXT 8
+ CYCLE_NEXT 8,1,0
READ_WRITE_3
- OP_RRA
+ OP_ROR
READ_WRITE_4
OP_ADC
- CYCLE_NEXT 8
+ CYCLE_NEXT 8,1,0
op73: @ RRA ($nn), Y
- INDY_ADDR
+ CYCLE_PRE 8
+ INDY_ADDR_W
READ_WRITE_1
- OP_RRA
+ OP_ROR
READ_WRITE_2
OP_ADC
- CYCLE_NEXT 8
+ CYCLE_NEXT 8,1,0
READ_WRITE_3
- OP_RRA
+ OP_ROR
READ_WRITE_4
OP_ADC
- CYCLE_NEXT 8
+ CYCLE_NEXT 8,1,0
op04: @ NOP $nn
CYCLE_NEXT 3
op0C: @ NOP $nnnn
+ CYCLE_PRE 4
+#if DO_DUMMY_READS
+ ABS_ADDR
+ READ
+#else
add REG_PC,REG_PC,#2
- CYCLE_NEXT 4
+#endif
+ CYCLE_NEXT 4,1,0
op14: @ NOP $nn, X
op34:
op7C:
opDC:
opFC:
+ CYCLE_PRE 4
+#if DO_DUMMY_READS
+ ABSX_ADDR
+ READ
+#else
add REG_PC,REG_PC,#2
- CYCLE_NEXT 4
+#endif
+ CYCLE_NEXT 4,1,0
op80: @ NOP #$nn
op82:
op89:
opC2:
+ add REG_PC,REG_PC,#1
+ CYCLE_NEXT 2
+
opE2:
add REG_PC,REG_PC,#1
+ CYCLE_NEXT 3
+
+op02: @ JAM: try to be compatible with fceu
+op12:
+op22:
+op32:
+op42:
+op52:
+op62:
+op72:
+op92:
+opB2:
+opD2:
+opF2:
+ sub REG_PC,REG_PC,#1
+ add REG_CYCLE, REG_CYCLE, #0x10
+ FLUSH_TIMESTAMP r0
+ add REG_CYCLE, REG_CYCLE, #0xef
+ sub REG_CYCLE, REG_CYCLE, #0x00d00000 @ 0xff*48<<16
+ sub REG_CYCLE, REG_CYCLE, #0x2f000000
+ CYCLE_NEXT 2
+
+op0B: @ ANC #$nn
+op2B: @ ANC #$nn
+ IMM_VALUE
+ OP_AND
+ bic REG_P_REST, REG_P_REST, #P_REST_C_FLAG
+ orr REG_P_REST, REG_P_REST, REG_A, lsr #31
CYCLE_NEXT 2
+op4B: @ ASR #$nn
+ IMM_VALUE
+ OP_AND
+ OP_LSR_A
+ CYCLE_NEXT 2
+
+op6B: @ ARR #$nn
+ IMM_VALUE
+ OP_AND
+ bic REG_P_REST, REG_P_REST, #P_REST_C_FLAG
+ eor r0, REG_A, REG_A, lsr #1
+ and r0, r0, #0x40000000
+ orr REG_P_REST, REG_P_REST, r0, lsr #24
+ OP_ROR_A
+ CYCLE_NEXT 2
+
+op83: @ SAX/AAX ($nn, X)
+ CYCLE_PRE 6
+ INDX_ADDR
+ and r0, REG_X, REG_A, lsr #24
+ WRITE_1
+ CYCLE_NEXT 6,1,0
+
+op87: @ SAX/AAX $nn
+ ZERO_ADDR
+ and r0, REG_X, REG_A, lsr #24
+ ZP_WRITE
+ CYCLE_NEXT 3
+
+op8B: @ ANE/XAA #$nn
+ orr REG_A, REG_A, #0xee000000
+ and REG_A, REG_A, REG_X, lsl #24
+ IMM_VALUE
+ OP_AND
+ CYCLE_NEXT 2
+
+op8F: @ SAX/AAX $nnnn
+ CYCLE_PRE 4
+ ABS_ADDR
+ and r0, REG_X, REG_A, lsr #24
+ WRITE_1
+ CYCLE_NEXT 4,1,0
+
+.macro AMY_MSB
+ sub r0, REG_ADDR, REG_Y
+ mov r0, r0, lsr #8
+ add r0, r0, #1
+.endm
+
+op93: @ SHA/AXA ($nn), Y
+ CYCLE_PRE 6
+ INDY_ADDR_W
+ AMY_MSB
+ and r0, r0, REG_X
+ and r0, r0, REG_A, lsr #24
+ WRITE_1
+ CYCLE_NEXT 6,1,0
+
+op97: @ SAX,AAX $nn, Y
+ ZEROY_ADDR
+ and r0, REG_X, REG_A, lsr #24
+ ZP_WRITE
+ CYCLE_NEXT 4
+
+op9B: @ SHS/XAS $nnnn, Y
+ and r0, REG_X, REG_A, lsr #24
+ bic REG_S, REG_S, #0xFF << 24
+ orr REG_S, REG_S, r0, lsl #24
+ ABSY_ADDR_W
+ AMY_MSB
+ and r0, r0, REG_S, lsr #24
+ WRITE_1
+ CYCLE_NEXT 5
+
+op9C: @ SHY/SYA $nnnn, X
+ CYCLE_PRE 5
+ ABSX_ADDR_W
+ sub r0, REG_ADDR, REG_X
+ mov r0, r0, lsr #8
+ add r0, r0, #1
+ and r0, r0, REG_Y
+ WRITE_1
+ CYCLE_NEXT 5,1,0
+
+op9E: @ SHX/SXA $nnnn, Y
+ ABSY_ADDR_W
+ AMY_MSB
+ and r0, r0, REG_X
+ WRITE_1
+ CYCLE_NEXT 5
+
+op9F: @ SHA/AXA $nnnn, Y
+ CYCLE_PRE 5
+ ABSY_ADDR_W
+ AMY_MSB
+ and r0, r0, REG_X
+ and r0, r0, REG_A, lsr #24
+ WRITE_1
+ CYCLE_NEXT 5,1,0
+
+opAB: @ LXA/ATX/OAL #$nn
+ IMM_VALUE
+ orr REG_A, REG_A, #0xee000000
+ OP_AND
+ mov REG_X, REG_A, lsr #24
+ CYCLE_NEXT 2
+
+opBB: @ LAS/LAR $nnnn,Y
+ CYCLE_PRE 4
+ ABSY_ADDR_W
+ READ_WRITE_1
+ READ_WRITE_2
+ b opBB_
+ READ_WRITE_3
+ READ_WRITE_4
+opBB_: and REG_X, r0, REG_S, lsr #24
+ bic REG_S, REG_S, #0xff<<24
+ orr REG_S, REG_S, REG_X, lsl #24
+ mov REG_A, REG_X, lsl #24
+ orr REG_NZ, REG_A, REG_A, lsr #24
+ CYCLE_NEXT 4,1,0
+
+
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@@@ ----
@ JMP ($nnnn)
op6C:
+ CYCLE_PRE 5
ABS_ADDR
and r0, REG_ADDR, #0xFF
teq r0, #0xFF
beq jmp_indirect_bug
READ_WORD
REBASE_PC
- CYCLE_NEXT 5
+ CYCLE_NEXT 5,1,0
jmp_indirect_bug:
@@
@@ BUG is : to not read word at REG_ADDR, because it loops
@@ but read low part at REG_ADDR and high part at REG_ADDR&0xFF00 instead of REG_ADDR+1
@@
- READ
+ READ 0
mov REG_PC, r0
and REG_ADDR, REG_ADDR, #0xff00
- READ
+ READ 0
orr r0, REG_PC, r0, lsl #8
REBASE_PC
- CYCLE_NEXT 5
+ CYCLE_NEXT 5,1,0
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@@@
@@@ ³ä¤ê¹þ¤ß¤Î½èÍý
+@@@ WARNING: decrements REG_PC
@@@
do_int:
+ add REG_CYCLE, REG_CYCLE, #7
ldr r0, [REG_OP_TABLE, #OTOFFS_PC_BASE]
+ sub REG_PC, REG_PC, #1
sub r0, REG_PC, r0
PUSH_WORD
bic REG_P_REST, REG_P_REST, #P_REST_B_FLAG
subne REG_ADDR, REG_ADDR, #NMI_VECTOR
READ_WORD
REBASE_PC
- CYCLE_NEXT 7
+@ CYCLE_NEXT 7
+
+ subs REG_CYCLE, REG_CYCLE, #7*48<<16
+ ble cpu_exec_end
+ ldrb r0, [REG_PC], #1
+ tst REG_P_REST, #0xff<<8
+ ldreq pc, [REG_OP_TABLE, r0, lsl #2]
+
+ tst REG_P_REST, #P_REST_I_FLAG
+ ldrne pc, [REG_OP_TABLE, r0, lsl #2]
+ b do_int
+
@@@
@@@ ¥ê¥»¥Ã¥È¤Î½èÍý
@@REG_P_REST = 0, don't touch REG_S
bic REG_P_REST, REG_P_REST, #0xff
+ @ fceu: set MapIRQHook present flag
+ ldr r0, [REG_OP_TABLE, #OTOFFS_IRQ_HOOK]
+ tst r0, r0
+ orrne REG_P_REST, REG_P_REST, #1<<16
+ biceq REG_P_REST, REG_P_REST, #1<<16
+
@@ R bit is always 1
orr REG_NZ, REG_NZ, #P_R_FLAG
@@@ low-level memhandlers
@@@
-read_ppu_reg:
-read_high_reg:
-read_save_ram:
+/*
+@ disabled because no improvements noticed, only causes trouble (with gg for example)
read_rom_byte:
+@ try to avoid lookup of every address at least for ROM and RAM areas
+@ I've verified that if ARead[0xfff0] points to CartBR, it is always normal ROM read.
+ ldr r0, =CartBR
+ ldr r2, =ARead
+ mov r1, #0xff00
+ orr r1, r1, r1, lsr #4
+ ldr r1, [r2, r1, lsl #2] @ if (ARead[0xfff0] == CartBR)
+ cmp r0, r1
+ bne read_byte
+ ldr r2, =Page
+ mov r1, REG_ADDR, lsr #11
+ ldr r2, [r2, r1, lsl #2]
+ ldrb r0, [r2, REG_ADDR]
+ bx lr
+*/
+
+
+read_byte:
@ must preserve r3 for the callers too
- @ TODO: check if all of saves are needed, optimize read_rom_byte, _DB
+ @ TODO: check if all of saves are needed, _DB (is full needed?)
+ FLUSH_TIMESTAMP r2 @ needed for TryFixit1
str REG_PC, [REG_OP_TABLE, #(OTOFFS_NES_REGS + 0x0c)] @ might get rebased
str REG_P_REST, [REG_OP_TABLE, #(OTOFFS_NES_REGS + 0x10)] @ might set irq
str REG_CYCLE, [REG_OP_TABLE, #(OTOFFS_NES_REGS + 0x1c)] @ might get used
mov REG_PC, lr @ r7
mov REG_P_REST, r3 @ r8
+#ifndef DEBUG_ASM_6502
ldr r2, =ARead
bic r0, REG_ADDR, #0x00ff0000
mov lr, pc
ldr pc, [r2, r0, lsl #2]
+#else
+ ldr r2, =dread_count_a
+ ldr r0, =dreads
+ ldr r1, [r2]
+ ldrb r0, [r0, r1]
+ add r1, r1, #1
+ str r1, [r2]
+#endif
ldr REG_OP_TABLE, =cpu_exec_table @ got trashed because was in r12
mov lr, REG_PC
ldr REG_PC, [REG_OP_TABLE, #(OTOFFS_NES_REGS + 0x0c)] @ might get rebased
ldr REG_P_REST, [REG_OP_TABLE, #(OTOFFS_NES_REGS + 0x10)] @ might set irq
ldr REG_CYCLE, [REG_OP_TABLE, #(OTOFFS_NES_REGS + 0x1c)] @ might get used
+ strb r0, [REG_OP_TABLE, #(OTOFFS_X + 0x10)] @ X.DB
bx lr
-write_ppu_reg:
-write_high_reg:
-write_save_ram:
-write_rom_byte:
- @ must preserve r3 for the callers too
+write_byte:
+ FLUSH_TIMESTAMP r2 @ Blaster Master, more...
+#ifndef DEBUG_ASM_6502
+ @ must preserve r0 (data) and r3 for the callers
str REG_PC, [REG_OP_TABLE, #(OTOFFS_NES_REGS + 0x0c)] @ might get rebased
str REG_P_REST, [REG_OP_TABLE, #(OTOFFS_NES_REGS + 0x10)] @ might set irq
str REG_CYCLE, [REG_OP_TABLE, #(OTOFFS_NES_REGS + 0x1c)] @ might get used
mov REG_PC, lr @ r7
mov REG_P_REST, r3 @ r8
+ mov REG_CYCLE, r0 @ r11
ldr r2, =BWrite
mov r1, r0
ldr REG_OP_TABLE, =cpu_exec_table @ got trashed because was in r12
mov lr, REG_PC
mov r3, REG_P_REST
+ mov r0, REG_CYCLE
ldr REG_PC, [REG_OP_TABLE, #(OTOFFS_NES_REGS + 0x0c)] @ might get rebased
ldr REG_P_REST, [REG_OP_TABLE, #(OTOFFS_NES_REGS + 0x10)] @ might set irq
ldr REG_CYCLE, [REG_OP_TABLE, #(OTOFFS_NES_REGS + 0x1c)] @ might get used
+#else
+ ldr r1, =dwrite_count_a
+ ldr r2, =dwrites_a
+ ldr r1, [r1]
+ and r0, r0, #0xff
+ orr r0, r0, REG_ADDR, lsl #8
+ str r0, [r2, r1, lsl #2]
+ ldr r2, =dwrite_count_a
+ add r1, r1, #1
+ str r1, [r2]
+ and r0, r0, #0xff
+#endif
bx lr
@ ldr REG_OP_TABLE, = cpu_exec_table @ set on init
- CYCLE_NEXT 0
+ ldrb r0, [REG_PC], #1
+ tst REG_P_REST, #0xff<<8
+ ldreq pc, [REG_OP_TABLE, r0, lsl #2]
+
+ @ assumption: NMI can be set only on very first run, because it is only set once before vblank..
+ tst REG_P_REST, #FCEU_IQNMI<<8
+ bne do_int
+ tst REG_P_REST, #P_REST_I_FLAG
+ @@ if I_FLAG=1, continue execution, don't trigger IRQ
+ bicne REG_P_REST, REG_P_REST, #FCEU_IQTEMP<<8
+ ldrne pc, [REG_OP_TABLE, r0, lsl #2]
+ @@ I_FLAG=0 and REST is checked, we have a IRQ
+ b do_int
+
cpu_exec_end:
+ FLUSH_TIMESTAMP r0
+
+ tst REG_P_REST, #1<<16
+ bne do_irq_hook_final
+
ldr r0, =nes_registers
stmia r0, {r4-r12}
.fill 0x100, 1, 0
nes_stack:
.fill 0x700, 1, 0
-@ TODO: write code which keeps it up-to-date
pc_base:
.long 0
+MapIRQHook:
+ .long 0
+timestamp:
+timestamp_a:
+ .long 0
+#ifndef DEBUG_ASM_6502
+X:
+#endif
+X_: .fill 0x20, 1, 0
.pool
ALIGN
-@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
-@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
-@@@
-@@@ Undefined Opcodes
-@@@
-op0B: @ ANC #$nn
-op2B: @ ANC #$nn
-op8B: @ ANE #$nn
-op6B: @ ARR #$nn
-op4B: @ ASR #$nn
-@opC7: @ DCP $nn
-@opD7: @ DCP $nn, X
-@opCF: @ DCP $nnnn
-@opDF: @ DCP $nnnn, X
-@opDB: @ DCP $nnnn, Y
-@opC3: @ DCP ($nn, X)
-@opD3: @ DCP ($nn), Y
-
-
-
-@opE7: @ ISB $nn
-@opF7: @ ISB $nn, X
-@opEF: @ ISB $nnnn
-@opFF: @ ISB $nnnn, X
-@opFB: @ ISB $nnnn, Y
-@opE3: @ ISB ($nn, X)
-@opF3: @ ISB ($nn), Y
-
-
-op02: @ JAM
-op12:
-op22:
-op32:
-op42:
-op52:
-op62:
-op72:
-op92:
-opB2:
-opD2:
-opF2:
-
-
-opBB: @ LAS $nnnn,Y
-@opA3: @ LAX ($nn, X)
-@opA7: @ LAX $nn
-@opB7: @ LAX $nn, Y
-@opAF: @ LAX $nnnn
-@opBF: @ LAX $nnnn, Y
-
-@opB3: @ LAX ($nn), Y
-opAB: @ LXA #$nn
-@op27: @ RLA $nn
-@op37: @ RLA $nn, X
-@op2F: @ RLA $nnnn
-@op3F: @ RLA $nnnn, X
-@op3B: @ RLA $nnnn, Y
-@op23: @ RLA ($nn, X)
-@op33: @ RLA ($nn), Y
-@op67: @ RRA $nn
-@op77: @ RRA $nn, X
-@op6F: @ RRA $nnnn
-@op7F: @ RRA $nnnn, X
-@op7B: @ RRA $nnnn, Y
-@op63: @ RRA ($nn, X)
-@op73: @ RRA ($nn), Y
-op87: @ SAX $nn
-op97: @ SAX $nn, Y
-op8F: @ SAX $nnnn
-op83: @ SAX ($nn, X)
-@opCB: @ SBX #$nn
-op9F: @ SHA $nnnn, Y
-op93: @ SHA ($nn), Y
-op9B: @ SHS $nnnn, Y
-op9E: @ SHX $nnnn, Y
-@op9C: @ SHY $nnnn, X
-@op03: @ SLO ($nn, X)
-@op07: @ SLO $nn
-@op17: @ SLO $nn, X
-@op0F: @ SLO $nnnn
-@op1F: @ SLO $nnnn, X
-@op1B: @ SLO $nnnn, Y
-@op13: @ SLO ($nn), Y
-@op47: @ SRE $nn
-@op57: @ SRE $nn, X
-@op4F: @ SRE $nnnn
-@op5F: @ SRE $nnnn, X
-@op5B: @ SRE $nnnn, Y
-@op43: @ SRE ($nn, X)
-@op53: @ SRE ($nn), Y
- CYCLE_NEXT 1
-@ emu_panic?
-
-
@@@@@@@@@@@@@@@@@@@@@@@@@@
@ fceu stuff...
.extern Page
.extern ARead
.extern BWrite
+.extern MapIRQHook
SECTION_DATA
ALIGN
-@ .globl X
- .globl RAM
.globl nes_registers @ TODO: hide?
.globl pc_base
-@ .globl timestamp
-@ .globl MapIRQHook @ (int a)
-@ TODO... .. conversion X <-> nes_registers for savestates
-@timestamp: .long 0
-@MapIRQHook: .long 0
-@X: .fill 0x20, 1, 0
+ .globl MapIRQHook @ (int a)
+#ifndef DEBUG_ASM_6502
+ .globl X
+ .globl RAM
+ .globl timestamp
+#else
+ .globl X_
+ .globl nes_internal_ram
+ .globl timestamp_a
+#endif
.globl X6502_Reset_a @ (void);
.globl X6502_Power_a @ (void);
.globl X6502_Run_a @ (int32 cycles);
.globl TriggerIRQ_a @ (void);
.globl TriggerNMI_a @ (void);
- .globl TriggerNMINSF_a @ (void);
.globl X6502_AddCycles_a @ (int x);
.globl X6502_IRQBegin_a @ (int w);
.globl X6502_IRQEnd_a @ (int w);
- .globl X6502_rebase_a @ (void);
+ .globl X6502_Rebase_a @ (void);
SECTION_TEXT
ALIGN
TriggerNMI_a:
- mov r0, #FCEU_IQTEMP
+ mov r0, #FCEU_IQNMI
b X6502_IRQBegin_a
-TriggerNMINSF_a:
- @ not implemented
- bx lr
-
-
X6502_AddCycles_a:
+ ldr r3, =timestamp
ldr r2, =nes_registers
- ldr r1, [r2, #0x1c]
- mvn r3, #49
- mla r0, r3, r0, r1
- str r0, [r2, #0x1c]
- bx lr
+ ldr r1, [r3]
+ add r1, r1, r0
+ str r1, [r3]
+ ldrsh r1, [r2, #0x1e]
+ mvn r3, #47 @ r3=-48
+ mla r3, r0, r3, r1
+ ldr r1, =MapIRQHook @ hack..
+ strh r3, [r2, #0x1e]
+ ldr r1, [r1]
+ tst r1, r1
+ bxeq lr
+ bx r1
@ rebase PC when not executing or in memhandlers
-X6502_rebase_a:
+X6502_Rebase_a:
stmfd sp!,{REG_PC,REG_OP_TABLE}
ldr REG_OP_TABLE, =cpu_exec_table
ldr r0, [REG_OP_TABLE, #(OTOFFS_NES_REGS+0x0c)] @ PC
.pool
+@ the nasty MapIRQHook thing from FCE..
+@ test Gradius 2 (J) if you change this
+do_irq_hook:
+ FLUSH_TIMESTAMP r0
+
+ @ get irqhook cycles
+ and r0, REG_CYCLE, #0xff00
+ mov r0, r0, lsr #8
+#ifndef DEBUG_ASM_6502
+ @ I have reviewed all MapIRQHook functions, they only seem to cause IRQs, not messing cycles or something
+ str REG_P_REST, [REG_OP_TABLE, #(OTOFFS_NES_REGS + 0x10)] @ might set irq
+ mov REG_P_REST, REG_OP_TABLE @ r8
+
+ @ if somebody modifies MapIRQHook without calling reset, we are doomed
+ mov lr, pc
+ ldr pc, [REG_OP_TABLE, #OTOFFS_IRQ_HOOK]
+
+ mov REG_OP_TABLE, REG_P_REST @ got trashed because was in r12
+ ldr REG_P_REST, [REG_OP_TABLE, #(OTOFFS_NES_REGS + 0x10)] @ might set irq
+#else
+ ldr r1, =mapirq_cyc_a
+ str r0, [r1]
+ mov r1, r0
+#endif
+
+ ldrb r0, [REG_PC], #1
+ bic REG_CYCLE, REG_CYCLE, #0xff00
+ tst REG_P_REST, #0xff<<8
+ ldreq pc, [REG_OP_TABLE, r0, lsl #2]
+
+ @ do some messing to find out which IRQ is pending..
+ tst REG_P_REST, #P_REST_I_FLAG
+ @@ if I_FLAG=1, continue execution, don't trigger IRQ
+ bicne REG_P_REST, REG_P_REST, #FCEU_IQTEMP<<8
+ ldrne pc, [REG_OP_TABLE, r0, lsl #2]
+ @@ I_FLAG=0 and REST is checked, we have a IRQ
+ b do_int
+
+
+do_irq_hook_final:
+ ldr r1, =nes_registers
+
+ @ get irqhook cycles
+ and r0, REG_CYCLE, #0xff00
+ bic REG_CYCLE, REG_CYCLE, #0xff00
+ mov r0, r0, lsr #8
+
+ stmia r1, {r4-r12}
+
+ ldmfd r13!,{r4-r11,lr}
+
+#ifndef DEBUG_ASM_6502
+ ldr pc, [REG_OP_TABLE, #OTOFFS_IRQ_HOOK]
+#else
+ ldr r1, =mapirq_cyc_a
+ str r0, [r1]
+ mov r1, r0
+ bx lr
+#endif
+
+
@ vim:filetype=armasm