#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)
@@@
@@@ ¤Ê¤ó¤«Ì¾Á°¤¬ÊѤÀ¤Ê(¤É¡¼¤Ç¤â¤¤¡¼¤±¤É¡¼
@@@
-.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]
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
+
@@@
@@@ ¥ê¥»¥Ã¥È¤Î½èÍý
@ 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}
.long 0
MapIRQHook:
.long 0
+MapIRQHookCyc:
+ .long 0
timestamp:
.long 0
#ifndef DEBUG_ASM_6502
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
@ 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
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
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);
}
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();
}
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();
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();
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
static INLINE void ADDCYC(int x)
{
- //_tcount+=x;
+ _tcount+=x;
_count-=x*48;
timestamp+=x;
}
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;
#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