Gradius fixed
authornotaz <notasas@gmail.com>
Wed, 25 Apr 2007 19:44:33 +0000 (19:44 +0000)
committernotaz <notasas@gmail.com>
Wed, 25 Apr 2007 19:44:33 +0000 (19:44 +0000)
git-svn-id: file:///home/notaz/opt/svn/fceu@110 be3aeb3a-fb24-0410-a615-afba39da0efa

Makefile.gp2x
ncpu.S
ncpu_debug.c
x6502.c

index 94693c2..95398d6 100644 (file)
@@ -16,7 +16,7 @@ LDRIVER       += -O3 # -pg
 endif
 
 asm_6502=1
-debug_asm_6502=1
+#debug_asm_6502=1
 
 all:           fceu
 
diff --git a/ncpu.S b/ncpu.S
index ea9cb61..d649f9a 100644 (file)
--- a/ncpu.S
+++ b/ncpu.S
@@ -16,6 +16,7 @@
 #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_IRQH_CYC  (MapIRQHookCyc    - cpu_exec_table)
 #define OTOFFS_X         (X_               - cpu_exec_table)
 
 @ fceu
        SECTION_TEXT
        ALIGN
 
+/*
 bbbb:
 .ascii "rebase: %04x"
 .byte 0x0a,0
 .align 4
-
+*/
 
 @@@
 @@@ r0 =  Address (unbased)
@@ -71,14 +73,15 @@ bbbb:
 @@@
 @@@ ¤Ê¤ó¤«Ì¾Á°¤¬ÊѤÀ¤Ê(¤É¡¼¤Ç¤â¤¤¡¼¤±¤É¡¼
 @@@
-.macro CYCLE_NEXT      n
+.macro CYCLE_NEXT      n, hook_check=1
        @@DEBUG_INFO
 
        subs    REG_CYCLE, REG_CYCLE, #\n*48
        ble     cpu_exec_end
+.if \hook_check
        tst     REG_P_REST, #1<<16
-       movne   r0, #\n
        blne    do_irq_hook
+.endif
        ldrb    r0, [REG_PC], #1
        tst     REG_P_REST, #0xff<<8
        ldreq   pc, [REG_OP_TABLE, r0, lsl #2]
@@ -2761,7 +2764,18 @@ do_int:
        subne   REG_ADDR, REG_ADDR, #NMI_VECTOR
        READ_WORD
        REBASE_PC
-       CYCLE_NEXT      7
+@      CYCLE_NEXT      7
+
+       subs    REG_CYCLE, REG_CYCLE, #7*48
+       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
+
 
 @@@
 @@@ ¥ê¥»¥Ã¥È¤Î½èÍý
@@ -2916,9 +2930,15 @@ cpu_exec:
 
 @      ldr   REG_OP_TABLE, = cpu_exec_table @ set on init
 
-       CYCLE_NEXT      0
+       tst     REG_P_REST, #1<<16
+       strne   REG_CYCLE, [REG_OP_TABLE, #OTOFFS_IRQH_CYC]
+
+       CYCLE_NEXT      0, 0
 
 cpu_exec_end:
+       tst     REG_P_REST, #1<<16
+       blne    do_irq_hook
+
        ldr     r0, =nes_registers
        stmia   r0, {r4-r12}
 
@@ -3001,6 +3021,8 @@ pc_base:
        .long   0
 MapIRQHook:
        .long   0
+MapIRQHookCyc:
+       .long   0
 timestamp:
        .long   0
 #ifndef DEBUG_ASM_6502
@@ -3117,11 +3139,11 @@ op9E:   @ SHX $nnnn, Y
        ALIGN
        .globl  nes_registers @ TODO: hide?
        .globl  pc_base
+       .globl  MapIRQHook @ (int a)
 #ifndef DEBUG_ASM_6502
        .globl  X
        .globl  RAM
        .globl  timestamp
-       .globl  MapIRQHook @ (int a)
 #else
        .globl  nes_internal_ram
 #endif
@@ -3214,7 +3236,17 @@ X6502_Rebase_a:
 
 
 @ the nasty MapIRQHook thing from FCE..
+@ test Gradius 2 (J) if you change this
 do_irq_hook:
+       @ ((cycles >> 4) * 43) >> 7; // aproximating /= 48
+       ldr     r1,        [REG_OP_TABLE, #OTOFFS_IRQH_CYC]
+       str     REG_CYCLE, [REG_OP_TABLE, #OTOFFS_IRQH_CYC]
+       mov     r0, #43
+       sub     r1, r1, REG_CYCLE
+       mul     r0, r1, r0
+       mov     r0, r0, lsr #11
+
+#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
@@ -3226,6 +3258,11 @@ do_irq_hook:
        ldr     REG_OP_TABLE, =cpu_exec_table   @ got trashed because was in r12
        mov     lr, REG_P_REST
        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
        bx      lr
 
 
index 63eef3f..aed7afb 100644 (file)
@@ -17,11 +17,13 @@ static int pending_add_cycles = 0, pending_rebase = 0, pending_irq = 0;
 uint8  dreads[4];
 uint32 dwrites_c[2], dwrites_a[2];
 int dread_count_c, dread_count_a, dwrite_count_c, dwrite_count_a;
+int mapirq_cyc_c, mapirq_cyc_a;
 
 static void leave(void)
 {
        printf("\nA: %02x, X: %02x, Y: %02x, S: %02x\n", X.A, X.X, X.Y, X.S);
        printf("PC = %04lx, OP=%02lX\n", PC_prev, OP_prev);
+       printf("rest = %08lx\n", nes_registers[4]);
        exit(1);
 }
 
@@ -92,6 +94,11 @@ static void compare_state(void)
                        fail = 1;
                }
 
+       if (mapirq_cyc_a != mapirq_cyc_c) {
+               printf("mapirq_cyc: %i vs %i\n", mapirq_cyc_a, mapirq_cyc_c);
+               fail = 1;
+       }
+
        if (fail) leave();
 }
 
@@ -163,6 +170,7 @@ void X6502_Run_d(int32 c)
                X.count=1;
 
                dread_count_c = dread_count_a = dwrite_count_c = dwrite_count_a = 0;
+               mapirq_cyc_a = mapirq_cyc_c = 0;
                X6502_Run_c();
 
                X6502_Run_a();
@@ -196,6 +204,7 @@ void X6502_Power_d(void)
        printf("-- power\n");
        if (nes_internal_ram == RAM) printf("nes_internal_ram == RAM!!\n");
        dread_count_c = dread_count_a = dwrite_count_c = dwrite_count_a = 0;
+       mapirq_cyc_c = mapirq_cyc_a = 0;
 
        X6502_Power_c();
        X6502_Power_a();
diff --git a/x6502.c b/x6502.c
index b428056..c8c0032 100644 (file)
--- a/x6502.c
+++ b/x6502.c
@@ -33,14 +33,16 @@ extern uint32 PC_prev, OP_prev;
 extern uint8  dreads[4];
 extern uint32 dwrites_c[2];
 extern int dread_count_c, dwrite_count_c;
+extern int mapirq_cyc_c;
+extern void (*MapIRQHook)(int a);
 #define DummyRdMem(...)
 #else
 #define DummyRdMem RdMem
+void FP_FASTAPASS(1) (*MapIRQHook)(int a);
 #endif
 
 X6502 X;
 uint32 timestamp;
-void FP_FASTAPASS(1) (*MapIRQHook)(int a);
 
 #define _PC              X.PC
 #define _A               X.A
@@ -107,7 +109,7 @@ static INLINE void WrRAM(unsigned int A, uint8 V)
 
 static INLINE void ADDCYC(int x)
 {
//_tcount+=x;
+ _tcount+=x;
  _count-=x*48;
  timestamp+=x;
 }
@@ -499,17 +501,20 @@ void X6502_Run_c(void/*int32 cycles*/)
           TriggerIRQReal();
 
          _IRQlow&=~(FCEU_IQTEMP|FCEU_IQNMI);
-         if(_count<=0) {_PI=_P;return;} /* Should increase accuracy without a */
-                                          /* major speed hit. */
+         if(_count<=0)
+         {
+#ifdef DEBUG_ASM_6502
+          if(MapIRQHook) mapirq_cyc_c = _tcount;
+          _tcount=0;
+#endif
+          _PI=_P;
+          return; /* Should increase accuracy without a major speed hit. */
+         }
         }
         _PI=_P;
         b1=RdMem(_PC);
-        temp=CycTable[b1];
-        ADDCYC(temp);
-        //temp=_tcount;
-        //_tcount=0;
-
-        if(MapIRQHook) MapIRQHook(temp);
+        ADDCYC(CycTable[b1]);
+        temp=_tcount;
 
         temp*=48;
 
@@ -548,6 +553,16 @@ void X6502_Run_c(void/*int32 cycles*/)
           #include "ops.h"
          }
 
+        temp=_tcount; /* Gradius II (J) glitches if _tcount is not used */
+        _tcount=0;
+
+        if(MapIRQHook) {
+#ifdef DEBUG_ASM_6502
+         mapirq_cyc_c = temp;
+#endif
+         MapIRQHook(temp);
+        }
+
 #ifdef DEBUG_ASM_6502
         _PI=_P;
 #endif