refactor out GP2X specific stuff completely
[fceu.git] / ncpu.S
diff --git a/ncpu.S b/ncpu.S
index fcf8fed..e7b07a6 100644 (file)
--- a/ncpu.S
+++ b/ncpu.S
@@ -3,11 +3,15 @@
   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
 @@@
@@ -33,7 +37,7 @@
 
 /*
 bbbb:
-.ascii "lsr_a: %02x"
+.ascii "ab_a: %04x"
 .byte 0x0a,0
 .align 4
 stmfd sp!,{r0-r3,r12,lr}
@@ -68,13 +72,16 @@ ldmfd sp!,{r0-r3,r12,lr}
 
 
 @ updates fceu "timestamp" variable
-@ loads cycles to reg, reg!=r1, trashes r1
+@ 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]
-       and     \reg, REG_CYCLE, #0xff
+       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
 
 
@@ -88,23 +95,25 @@ ldmfd sp!,{r0-r3,r12,lr}
 @@@
 @@@ ¤Ê¤ó¤«Ì¾Á°¤¬ÊѤÀ¤Ê(¤É¡¼¤Ç¤â¤¤¡¼¤±¤É¡¼
 @@@
-.macro CYCLE_NEXT      n, hook_check=1
+.macro CYCLE_NEXT      n, unused=0, do_cyc_add=1
        @@DEBUG_INFO
 
+.if \do_cyc_add
        add     REG_CYCLE, REG_CYCLE, #\n
+.endif
        subs    REG_CYCLE, REG_CYCLE, #\n*48<<16
        ble     cpu_exec_end
-.if \hook_check
        tst     REG_P_REST, #1<<16
-       blne    do_irq_hook
-.endif
+       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
@@ -113,6 +122,12 @@ ldmfd sp!,{r0-r3,r12,lr}
        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
+
 
 @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
 @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@@ -146,10 +161,13 @@ ldmfd sp!,{r0-r3,r12,lr}
 @@@
 @@@ ¥¢¥É¥ì¥¹¤òÆɤà
 @@@
-.macro ZP_READ_ADDR
+.macro ZP_READ_ADDR update_db=0
        ZP_READ
        ldrb    REG_ADDR, [REG_ADDR, #1]
        orr     REG_ADDR, r0, REG_ADDR, lsl #8
+.if \update_db
+       strb    r0, [REG_OP_TABLE, #(OTOFFS_X + 0x10)]          @ X.DB
+.endif
 .endm
 
 @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@@ -194,18 +212,13 @@ ldmfd sp!,{r0-r3,r12,lr}
 @@@ Read byte
 @@@
 
-.macro READ
-       adr     lr, 1f
-       tst     REG_ADDR, #0x8000
-       bne     read_rom_byte
+.macro READ unused_param
        tst     REG_ADDR, #0xe000
-       bne     read_byte
        @ RAM
-       bic     r0, REG_ADDR, #0x1800
-       add     r0, r0, #OTOFFS_NES_RAM
-       ldrb    r0, [r0, REG_OP_TABLE]
-       @@ ¤È¤¤¤¦¤ï¤±¤Ç¥¸¥ã¥ó¥×¤¹¤ëɬÍפϤʤ¤
-1:
+       biceq   r0, REG_ADDR, #0x1800
+       addeq   r0, r0, #OTOFFS_NES_RAM
+       ldreqb  r0, [r0, REG_OP_TABLE]
+       blne    read_byte
 .endm
 
 @@@
@@ -222,10 +235,8 @@ ldmfd sp!,{r0-r3,r12,lr}
 @@@ OP¤Ç¤Ïr3¤òÊݸ¤·¤Ê¤±¤ì¤Ð¤Ê¤é¤Ê¤¤
 
 .macro READ_WRITE_1
-       adr     lr, 9999f
-       tst     REG_ADDR, #0x8000
-       bne     read_rom_byte
        tst     REG_ADDR, #0xe000
+       adrne   lr, 9999f
        bne     read_byte
        @ RAM
        bic     REG_ADDR, REG_ADDR, #0x1800
@@ -269,10 +280,10 @@ ldmfd sp!,{r0-r3,r12,lr}
 @@@ 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
 
@@ -374,7 +385,7 @@ ldmfd sp!,{r0-r3,r12,lr}
 @@@ ($nn), Y
 .macro INDY_ADDR
        ZERO_ADDR
-       ZP_READ_ADDR
+       ZP_READ_ADDR 1                            @ SMB3 relies on open bus here
        add     REG_ADDR, REG_ADDR, REG_Y
        bic     REG_ADDR, REG_ADDR, #0x10000
        and     r0,REG_ADDR,#0xff
@@ -401,18 +412,25 @@ ldmfd sp!,{r0-r3,r12,lr}
 @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
 @@@ $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
@@ -431,7 +449,7 @@ ldmfd sp!,{r0-r3,r12,lr}
 @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
 @@@ $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
@@ -520,12 +538,12 @@ op38:     @ SEC
 
 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
@@ -669,34 +687,39 @@ opB5:     @ LDA $nn, X
        CYCLE_NEXT      4
 
 opAD:  @ LDA $nnnn
+       CYCLE_PRE       4
        ABS_ADDR
        READ
        OP_LDA
-       CYCLE_NEXT      4
+       CYCLE_NEXT      4,1,0
 
 opBD:  @ LDA $nnnn, X
+       CYCLE_PRE       4
        ABSX_ADDR
        READ
        OP_LDA
-       CYCLE_NEXT      4
+       CYCLE_NEXT      4,1,0
 
 opB9:  @ LDA $nnnn, Y
+       CYCLE_PRE       4
        ABSY_ADDR
        READ
        OP_LDA
-       CYCLE_NEXT      4
+       CYCLE_NEXT      4,1,0
 
 opA1:  @ LDA ($nn, X)
+       CYCLE_PRE       6
        INDX_ADDR
        READ
        OP_LDA
-       CYCLE_NEXT      6
+       CYCLE_NEXT      6,1,0
 
 opB1:  @ LDA ($nn), Y
+       CYCLE_PRE       5
        INDY_ADDR
        READ
        OP_LDA
-       CYCLE_NEXT      5
+       CYCLE_NEXT      5,1,0
 
 opA2:  @ LDX #$nn
        IMM_VALUE
@@ -716,16 +739,18 @@ opB6:     @ LDX $nn, Y
        CYCLE_NEXT      4
 
 opAE:  @ LDX $nnnn
+       CYCLE_PRE       4
        ABS_ADDR
        READ
        OP_LDX
-       CYCLE_NEXT      4
+       CYCLE_NEXT      4,1,0
 
 opBE:  @ LDX $nnnn, Y
+       CYCLE_PRE       4
        ABSY_ADDR
        READ
        OP_LDX
-       CYCLE_NEXT      4
+       CYCLE_NEXT      4,1,0
 
 
 
@@ -749,16 +774,18 @@ opB4:     @ LDY $nn, X
 
 
 opAC:  @ LDY $nnnn
+       CYCLE_PRE       4
        ABS_ADDR
        READ
        OP_LDY
-       CYCLE_NEXT      4
+       CYCLE_NEXT      4,1,0
 
 opBC:  @ LDY $nnnn, X
+       CYCLE_PRE       4
        ABSX_ADDR
        READ
        OP_LDY
-       CYCLE_NEXT      4
+       CYCLE_NEXT      4,1,0
 
 @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
 @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@@ -787,34 +814,39 @@ op95:     @ STA $nn, X
        CYCLE_NEXT      4
 
 op8D:  @ STA $nnnn
+       CYCLE_PRE       4
        ABS_ADDR
        OP_STA
        WRITE_1
-       CYCLE_NEXT 4
+       CYCLE_NEXT      4,1,0
 
 op9D:  @ STA $nnnn, X
+       CYCLE_PRE       5
        ABSX_ADDR_W
        OP_STA
        WRITE_1
-       CYCLE_NEXT 5
+       CYCLE_NEXT      5,1,0
 
 op99:  @ STA $nnnn, Y
+       CYCLE_PRE       5
        ABSY_ADDR_W
        OP_STA
        WRITE_1
-       CYCLE_NEXT 5
+       CYCLE_NEXT      5,1,0
 
 op81:  @ STA ($nn, X)
+       CYCLE_PRE       6
        INDX_ADDR
        OP_STA
        WRITE_1
-       CYCLE_NEXT 6
+       CYCLE_NEXT      6,1,0
 
 op91:  @ STA ($nn), Y
+       CYCLE_PRE       6
        INDY_ADDR_W
        OP_STA
        WRITE_1
-       CYCLE_NEXT 6
+       CYCLE_NEXT      6,1,0
 
 
 op86:  @ STX $nn
@@ -828,10 +860,11 @@ op96:     @ STX $nn, Y
        CYCLE_NEXT      4
 
 op8E:  @ STX $nnnn
+       CYCLE_PRE       4
        ABS_ADDR
        mov     r0, REG_X
        WRITE_1
-       CYCLE_NEXT 4
+       CYCLE_NEXT      4,1,0
 
 
 op84:  @ STY $nn
@@ -845,10 +878,11 @@ op94:     @ STY $nn, X
        CYCLE_NEXT      4
 
 op8C:  @ STY $nnnn
+       CYCLE_PRE       4
        ABS_ADDR
        mov     r0, REG_Y
        WRITE_1
-       CYCLE_NEXT 4
+       CYCLE_NEXT      4,1,0
 
 
 @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@@ -901,26 +935,28 @@ opF6:     @ INC $nn, X
        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
+       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
@@ -947,26 +983,28 @@ opD6:     @ DEC $nn, X
        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
+       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
@@ -1029,34 +1067,39 @@ op75:   @ ADC $nn, X
        CYCLE_NEXT      4
 
 op6D:  @ ADC $nnnn
+       CYCLE_PRE       4
        ABS_ADDR
        READ
        OP_ADC
-       CYCLE_NEXT      4
+       CYCLE_NEXT      4,1,0
 
 op7D:  @ ADC $nnnn, X
+       CYCLE_PRE       4
        ABSX_ADDR
        READ
        OP_ADC
-       CYCLE_NEXT      4
+       CYCLE_NEXT      4,1,0
 
 op79:  @ ADC $nnnn, Y
+       CYCLE_PRE       4
        ABSY_ADDR
        READ
        OP_ADC
-       CYCLE_NEXT      4
+       CYCLE_NEXT      4,1,0
 
 op61:  @ ADC ($nn, X)
+       CYCLE_PRE       6
        INDX_ADDR
        READ
        OP_ADC
-       CYCLE_NEXT      6
+       CYCLE_NEXT      6,1,0
 
 op71:  @ ADC ($nn), Y
+       CYCLE_PRE       5
        INDY_ADDR
        READ
        OP_ADC
-       CYCLE_NEXT      5
+       CYCLE_NEXT      5,1,0
 
 opEB:  @ USBC #$nn
 opE9:  @ SBC #$nn
@@ -1077,34 +1120,39 @@ opF5:   @ SBC $nn, X
        CYCLE_NEXT      4
 
 opED:  @ SBC $nnnn
+       CYCLE_PRE       4
        ABS_ADDR
        READ
        OP_SBC
-       CYCLE_NEXT      4
+       CYCLE_NEXT      4,1,0
 
 opFD:  @ SBC $nnnn, X
+       CYCLE_PRE       4
        ABSX_ADDR
        READ
        OP_SBC
-       CYCLE_NEXT      4
+       CYCLE_NEXT      4,1,0
 
 opF9:  @ SBC $nnnn, Y
+       CYCLE_PRE       4
        ABSY_ADDR
        READ
        OP_SBC
-       CYCLE_NEXT      4
+       CYCLE_NEXT      4,1,0
 
 opE1:  @ SBC ($nn, X)
+       CYCLE_PRE       6
        INDX_ADDR
        READ
        OP_SBC
-       CYCLE_NEXT      6
+       CYCLE_NEXT      6,1,0
 
 opF1:  @ SBC ($nn), Y
+       CYCLE_PRE       5
        INDY_ADDR
        READ
        OP_SBC
-       CYCLE_NEXT      5
+       CYCLE_NEXT      5,1,0
 
 
 @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@@ -1150,34 +1198,39 @@ op35:   @ AND $nn, X
        CYCLE_NEXT      4
 
 op2D:  @ AND $nnnn
+       CYCLE_PRE       4
        ABS_ADDR
        READ
        OP_AND
-       CYCLE_NEXT      4
+       CYCLE_NEXT      4,1,0
 
 op3D:  @ AND $nnnn, X
+       CYCLE_PRE       4
        ABSX_ADDR
        READ
        OP_AND
-       CYCLE_NEXT      4
+       CYCLE_NEXT      4,1,0
 
 op39:  @ AND $nnnn, Y
+       CYCLE_PRE       4
        ABSY_ADDR
        READ
        OP_AND
-       CYCLE_NEXT      4
+       CYCLE_NEXT      4,1,0
 
 op21:  @ AND ($nn, X)
+       CYCLE_PRE       6
        INDX_ADDR
        READ
        OP_AND
-       CYCLE_NEXT      6
+       CYCLE_NEXT      6,1,0
 
 op31:  @ AND ($nn), Y
+       CYCLE_PRE       5
        INDY_ADDR
        READ
        OP_AND
-       CYCLE_NEXT      5
+       CYCLE_NEXT      5,1,0
 
 
 op49:  @ EOR #$nn
@@ -1198,34 +1251,39 @@ op55:   @ EOR $nn, X
        CYCLE_NEXT      4
 
 op4D:  @ EOR $nnnn
+       CYCLE_PRE       4
        ABS_ADDR
        READ
        OP_EOR
-       CYCLE_NEXT      4
+       CYCLE_NEXT      4,1,0
 
 op5D:  @ EOR $nnnn, X
+       CYCLE_PRE       4
        ABSX_ADDR
        READ
        OP_EOR
-       CYCLE_NEXT      4
+       CYCLE_NEXT      4,1,0
 
 op59:  @ EOR $nnnn, Y
+       CYCLE_PRE       4
        ABSY_ADDR
        READ
        OP_EOR
-       CYCLE_NEXT      4
+       CYCLE_NEXT      4,1,0
 
 op41:  @ EOR ($nn, X)
+       CYCLE_PRE       6
        INDX_ADDR
        READ
        OP_EOR
-       CYCLE_NEXT      6
+       CYCLE_NEXT      6,1,0
 
 op51:  @ EOR ($nn), Y
+       CYCLE_PRE       5
        INDY_ADDR
        READ
        OP_EOR
-       CYCLE_NEXT      5
+       CYCLE_NEXT      5,1,0
 
 
 op09:  @ ORA #$nn
@@ -1246,34 +1304,39 @@ op15:   @ ORA $nn, X
        CYCLE_NEXT      4
 
 op0D:  @ ORA $nnnn
+       CYCLE_PRE       4
        ABS_ADDR
        READ
        OP_ORA
-       CYCLE_NEXT      4
+       CYCLE_NEXT      4,1,0
 
 op1D:  @ ORA $nnnn, X
+       CYCLE_PRE       4
        ABSX_ADDR
        READ
        OP_ORA
-       CYCLE_NEXT      4
+       CYCLE_NEXT      4,1,0
 
 op19:  @ ORA $nnnn, Y
+       CYCLE_PRE       4
        ABSY_ADDR
        READ
        OP_ORA
-       CYCLE_NEXT      4
+       CYCLE_NEXT      4,1,0
 
 op01:  @ ORA ($nn, X)
+       CYCLE_PRE       6
        INDX_ADDR
        READ
        OP_ORA
-       CYCLE_NEXT      6
+       CYCLE_NEXT      6,1,0
 
 op11:  @ ORA ($nn), Y
+       CYCLE_PRE       5
        INDY_ADDR
        READ
        OP_ORA
-       CYCLE_NEXT      5
+       CYCLE_NEXT      5,1,0
 
 
 
@@ -1328,34 +1391,39 @@ opD5:   @ CMP $nn, X
        CYCLE_NEXT      4
 
 opCD:  @ CMP $nnnn
+       CYCLE_PRE       4
        ABS_ADDR
        READ
        OP_CMP
-       CYCLE_NEXT      4
+       CYCLE_NEXT      4,1,0
 
 opDD:  @ CMP $nnnn, X
+       CYCLE_PRE       4
        ABSX_ADDR
        READ
        OP_CMP
-       CYCLE_NEXT      4
+       CYCLE_NEXT      4,1,0
 
 opD9:  @ CMP $nnnn, Y
+       CYCLE_PRE       4
        ABSY_ADDR
        READ
        OP_CMP
-       CYCLE_NEXT      4
+       CYCLE_NEXT      4,1,0
 
 opC1:  @ CMP ($nn, X)
+       CYCLE_PRE       6
        INDX_ADDR
        READ
        OP_CMP
-       CYCLE_NEXT      6
+       CYCLE_NEXT      6,1,0
 
 opD1:  @ CMP ($nn), Y
+       CYCLE_PRE       5
        INDY_ADDR
        READ
        OP_CMP
-       CYCLE_NEXT      5
+       CYCLE_NEXT      5,1,0
 
 
 opE0:  @ CPX #$nn
@@ -1370,10 +1438,11 @@ opE4:   @ CPX $nn
        CYCLE_NEXT      3
 
 opEC:  @ CPX $nnnn
+       CYCLE_PRE       4
        ABS_ADDR
        READ
        OP_CPX
-       CYCLE_NEXT      4
+       CYCLE_NEXT      4,1,0
 
 
 opC0:  @ CPY #$nn
@@ -1388,10 +1457,11 @@ opC4:   @ CPY $nn
        CYCLE_NEXT      3
 
 opCC:  @ CPY $nnnn
+       CYCLE_PRE       4
        ABS_ADDR
        READ
        OP_CPY
-       CYCLE_NEXT      4
+       CYCLE_NEXT      4,1,0
 
 
 @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@@ -1422,10 +1492,11 @@ op24:   @ BIT $nn
        CYCLE_NEXT      3
 
 op2C:  @ BIT $nnnn
+       CYCLE_PRE       4
        ABS_ADDR
        READ
        OP_BIT
-       CYCLE_NEXT      4
+       CYCLE_NEXT      4,1,0
 
 
 @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@@ -1488,26 +1559,28 @@ op16:   @ ASL $nn, X
        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
+       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
@@ -1530,26 +1603,28 @@ op56:   @ LSR $nn, X
        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
+       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
 
 
 @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@@ -1617,27 +1692,29 @@ op36:   @ ROL $nn, X
        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
+       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
@@ -1660,26 +1737,28 @@ op76:   @ ROR $nn, X
        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
+       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
 
 
 @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@@ -1806,12 +1885,6 @@ op70:    @ BVS $nn
        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
@@ -1847,13 +1920,9 @@ op70:    @ BVS $nn
        @@ ¥­¥ã¥ê¡¼¤òÊݸ
        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
 
 @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
 @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@@ -1876,67 +1945,66 @@ op57:   @ SRE $nn, X
        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
+       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_W
-       OP_SHY
-       WRITE_1
-       CYCLE_NEXT 5
-
 opE7:  @ ISB $nn
        ZERO_ADDR
        ZP_READ_W
@@ -1954,70 +2022,75 @@ opF7:   @ ISB $nn, X
        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
@@ -2032,35 +2105,40 @@ opB7:   @ LAX $nn, Y
        CYCLE_NEXT      4
 
 opAF:  @ LAX $nnnn
+       CYCLE_PRE       4
        ABS_ADDR
        READ
        OP_LAX
-       CYCLE_NEXT      4
+       CYCLE_NEXT      4,1,0
 
 opBF:  @ LAX $nnnn, Y
+       CYCLE_PRE       4
        ABSY_ADDR
        READ
        OP_LAX
-       CYCLE_NEXT      4
+       CYCLE_NEXT      4,1,0
 
 opA3:  @ LAX ($nn, X)
+       CYCLE_PRE       6
        INDX_ADDR
        READ
        OP_LAX
-       CYCLE_NEXT      6
+       CYCLE_NEXT      6,1,0
 
 opB3:  @ LAX ($nn), Y
+       CYCLE_PRE       5
        INDY_ADDR
        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
@@ -2070,59 +2148,64 @@ op17:   @ SLO $nn, X
        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
+       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
+       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
@@ -2146,70 +2229,75 @@ opD7:   @ DCP $nn, X
        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
@@ -2226,64 +2314,69 @@ op37:   @ RLA $nn, X
        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
+       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
+       CYCLE_PRE       7
        ABSY_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
 
 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
+       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
@@ -2291,75 +2384,80 @@ op67:   @ RRA $nn
 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
+       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
+       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
+       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
@@ -2369,8 +2467,14 @@ op64:
        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:
@@ -2395,17 +2499,177 @@ op5C:
 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
+
+
 
 
 @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@@ -2418,26 +2682,27 @@ opE2:
 @@@ ----
 @ 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
 
 
 @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@@ -2539,6 +2804,7 @@ op60:
 @@@ 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
@@ -2556,7 +2822,6 @@ do_int:
        REBASE_PC
 @      CYCLE_NEXT      7
 
-       add     REG_CYCLE, REG_CYCLE, #7
        subs    REG_CYCLE, REG_CYCLE, #7*48<<16
        ble     cpu_exec_end
        ldrb    r0, [REG_PC], #1
@@ -2611,8 +2876,11 @@ reset_cpu:
 @@@ low-level memhandlers
 @@@
 
+/*
+@ disabled because no improvements noticed, only causes trouble (with gg for example)
 read_rom_byte:
-#ifndef DEBUG_ASM_6502
+@ 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
@@ -2625,12 +2893,13 @@ read_rom_byte:
        ldr     r2, [r2, r1, lsl #2]
        ldrb    r0, [r2, REG_ADDR]
        bx      lr
-#endif
+*/
 
 
 read_byte:
        @ must preserve r3 for the callers too
        @ 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
@@ -2720,13 +2989,26 @@ cpu_exec:
 
 @      ldr   REG_OP_TABLE, = cpu_exec_table @ set on init
 
-       CYCLE_NEXT      0, 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
-       blne    do_irq_hook_noflushts
+       bne     do_irq_hook_final
 
        ldr     r0, =nes_registers
        stmia   r0, {r4-r12}
@@ -2805,7 +3087,6 @@ nes_internal_ram:
        .fill   0x100, 1, 0
 nes_stack:
        .fill   0x700, 1, 0
-@ TODO: write code which keeps it up-to-date
 pc_base:
        .long   0
 MapIRQHook:
@@ -2825,92 +3106,6 @@ X_:      .fill   0x20, 1, 0
        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
-@op23: @ RLA ($nn, X)
-@op67: @ RRA $nn
-@op77: @ RRA $nn, X
-@op6F: @ RRA $nnnn
-@op7F: @ RRA $nnnn, X
-@op63: @ RRA ($nn, X)
-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
-@op03:   @ SLO ($nn, X)
-@op07: @ SLO $nn
-@op17: @ SLO $nn, X
-@op0F: @ SLO $nnnn
-@op1F: @ SLO $nnnn, X
-@op47: @ SRE $nn
-@op57: @ SRE $nn, X
-@op4F: @ SRE $nnnn
-@op5F: @ SRE $nnnn, X
-@op5B: @ SRE $nnnn, Y
-@op43: @ SRE ($nn, X)
-       CYCLE_NEXT   1
-@ emu_panic?
-
-
 
 @@@@@@@@@@@@@@@@@@@@@@@@@@
 @ fceu stuff...
@@ -2933,6 +3128,7 @@ op9E:     @ SHX $nnnn, Y
        .globl  RAM
        .globl  timestamp
 #else
+       .globl  X_
        .globl  nes_internal_ram
        .globl  timestamp_a
 #endif
@@ -2941,7 +3137,6 @@ op9E:     @ SHX $nnnn, Y
        .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);
@@ -2996,11 +3191,6 @@ TriggerNMI_a:
        b       X6502_IRQBegin_a
 
 
-TriggerNMINSF_a:
-       @ not implemented
-       bx      lr
-
-
 X6502_AddCycles_a:
        ldr     r3, =timestamp
        ldr     r2, =nes_registers
@@ -3009,9 +3199,13 @@ X6502_AddCycles_a:
        str     r1, [r3]
        ldrsh   r1, [r2, #0x1e]
        mvn     r3, #47                 @ r3=-48
-       mla     r0, r3, r0, r1
-       strh    r0, [r2, #0x1e]
-       bx      lr
+       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
@@ -3033,25 +3227,60 @@ X6502_Rebase_a:
 do_irq_hook:
        FLUSH_TIMESTAMP r0
 
-do_irq_hook_noflushts:
+       @ 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, lr                  @ r8
+       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]
 
-       ldr     REG_OP_TABLE, =cpu_exec_table   @ got trashed because was in r12
-       mov     lr, REG_P_REST
+       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