From 8fa5eb3371d902b8d58dba6e6bf62726d7ed8dbc Mon Sep 17 00:00:00 2001
From: notaz <notasas@gmail.com>
Date: Fri, 27 Apr 2007 21:07:14 +0000
Subject: [PATCH] Blaster Master + other fixes

git-svn-id: file:///home/notaz/opt/svn/fceu@112 be3aeb3a-fb24-0410-a615-afba39da0efa
---
 fce.c        |  6 ++---
 ncpu.S       | 74 +++++++++++++++++++++++++++++++---------------------
 ncpu_debug.c | 14 +++++++---
 ops.h        |  3 ++-
 x6502.h      |  8 +++---
 5 files changed, 64 insertions(+), 41 deletions(-)

diff --git a/fce.c b/fce.c
index abcf10f..3cb0632 100644
--- a/fce.c
+++ b/fce.c
@@ -104,7 +104,7 @@ static int RWWrap=0;
 static void asmcpu_update(int32 cycles)
 {
  // timestamp..
- timestamp += ((cycles >> 4) * 43) >> 7; // aproximating /= 48
+ //timestamp += ((cycles >> 4) * 43) >> 7; // aproximating /= 48
 
  // some code from x6502.c
  fhcnt-=cycles;
@@ -140,7 +140,7 @@ void asmcpu_unpack(void)
 	X6502_Rebase_a();
 	nes_registers[4] = X.S << 24;
 	nes_registers[4]|= X.IRQlow << 8;
-	nes_registers[7] = (uint32)X.count;
+	nes_registers[7] = (uint32)X.count << 16;
 
 	// NVUB DIZC
 	nes_registers[4]|= X.P & 0x5d;
@@ -156,7 +156,7 @@ void asmcpu_pack(void)
 	X.PC= nes_registers[3] - pc_base;
 	X.S = nes_registers[4] >> 24;
 	X.IRQlow = nes_registers[4] >> 8;
-	X.count = (int32) nes_registers[7];
+	X.count = (int32) nes_registers[7] >> 16;
 
 	// NVUB DIZC
 	X.P = nes_registers[4] & 0x5d;
diff --git a/ncpu.S b/ncpu.S
index 0b79afb..6b68fe7 100644
--- a/ncpu.S
+++ b/ncpu.S
@@ -16,7 +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_TIMESTAMP (timestamp        - cpu_exec_table)
 #define OTOFFS_X         (X_               - cpu_exec_table)
 
 @ fceu
@@ -33,9 +33,14 @@
 
 /*
 bbbb:
-.ascii "rebase: %04x"
+.ascii "lsr_a: %02x"
 .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}
 */
 
 @@@
@@ -62,6 +67,16 @@ bbbb:
 .endm
 
 
+@ updates fceu "timestamp" variable
+@ loads cycles to reg, reg!=r1, trashes r1
+.macro	FLUSH_TIMESTAMP reg
+	ldr	r1, [REG_OP_TABLE, #OTOFFS_TIMESTAMP]
+	and	\reg, REG_CYCLE, #0xff
+	add	r1, r1, \reg
+	bic	REG_CYCLE, REG_CYCLE, #0xff
+	str	r1, [REG_OP_TABLE, #OTOFFS_TIMESTAMP]
+.endm
+
 
 @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
 @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@@ -76,7 +91,8 @@ bbbb:
 .macro	CYCLE_NEXT	n, hook_check=1
 	@@DEBUG_INFO
 
-	subs	REG_CYCLE, REG_CYCLE, #\n*48
+	add	REG_CYCLE, REG_CYCLE, #\n
+	subs	REG_CYCLE, REG_CYCLE, #\n*48<<16
 	ble	cpu_exec_end
 .if \hook_check
 	tst	REG_P_REST, #1<<16
@@ -107,11 +123,6 @@ bbbb:
 @@@ 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
 
@@ -445,7 +456,8 @@ bbbb:
 	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)
@@ -482,7 +494,8 @@ bbbb:
 	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)
@@ -500,7 +513,8 @@ bbbb:
 	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)
@@ -1906,14 +1920,16 @@ op7E:	@ ROR $nnnn, X
 	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:
@@ -1923,7 +1939,8 @@ op7E:	@ ROR $nnnn, X
 	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:
@@ -2771,7 +2788,8 @@ do_int:
 	REBASE_PC
 @	CYCLE_NEXT	7
 
-	subs	REG_CYCLE, REG_CYCLE, #7*48
+	add	REG_CYCLE, REG_CYCLE, #7
+	subs	REG_CYCLE, REG_CYCLE, #7*48<<16
 	ble	cpu_exec_end
 	ldrb	r0, [REG_PC], #1
 	tst	REG_P_REST, #0xff<<8
@@ -2881,6 +2899,7 @@ write_ppu_reg:
 write_high_reg:
 write_save_ram:
 write_rom_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
@@ -2913,6 +2932,7 @@ write_rom_byte:
 	ldr	r2, =dwrite_count_a
 	add	r1, r1, #1
 	str	r1, [r2]
+	and	r0, r0, #0xff
 #endif
 	bx	lr
 
@@ -2937,14 +2957,13 @@ cpu_exec:
 
 @	ldr   REG_OP_TABLE, = cpu_exec_table @ set on init
 
-	tst	REG_P_REST, #1<<16
-	strne	REG_CYCLE, [REG_OP_TABLE, #OTOFFS_IRQH_CYC]
-
 	CYCLE_NEXT	0, 0
 
 cpu_exec_end:
+	FLUSH_TIMESTAMP r0
+
 	tst	REG_P_REST, #1<<16
-	blne	do_irq_hook
+	blne	do_irq_hook_noflushts
 
 	ldr     r0, =nes_registers
 	stmia	r0, {r4-r12}
@@ -3028,9 +3047,8 @@ pc_base:
 	.long	0
 MapIRQHook:
 	.long	0
-MapIRQHookCyc:
-	.long	0
 timestamp:
+timestamp_a:
 	.long	0
 #ifndef DEBUG_ASM_6502
 X:
@@ -3153,6 +3171,7 @@ op9E:	@ SHX $nnnn, Y
 	.globl	timestamp
 #else
 	.globl	nes_internal_ram
+	.globl	timestamp_a
 #endif
 	.globl	X6502_Reset_a @ (void);
 	.globl	X6502_Power_a @ (void);
@@ -3221,10 +3240,10 @@ TriggerNMINSF_a:
 
 X6502_AddCycles_a:
 	ldr	r2, =nes_registers
-	ldr	r1, [r2, #0x1c]
+	ldrsh	r1, [r2, #0x1e]
 	mvn	r3, #47			@ r3=-48
 	mla	r0, r3, r0, r1
-	str	r0, [r2, #0x1c]
+	strh	r0, [r2, #0x1e]
 	bx	lr
 
 
@@ -3245,14 +3264,9 @@ 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
+	FLUSH_TIMESTAMP r0
 
+do_irq_hook_noflushts:
 #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
diff --git a/ncpu_debug.c b/ncpu_debug.c
index aed7afb..ce1b3cc 100644
--- a/ncpu_debug.c
+++ b/ncpu_debug.c
@@ -9,6 +9,7 @@
 extern uint32 nes_registers[0x10];
 extern uint32 pc_base;
 extern uint8  nes_internal_ram[0x800];
+extern uint32 timestamp_a;
 uint32 PC_prev = 0xcccccc, OP_prev = 0xcccccc;
 int32  g_cnt = 0;
 
@@ -73,8 +74,8 @@ static void compare_state(void)
 		fail = 1;
 	}
 
-	if ((int32)nes_registers[7] != X.count) {
-		printf("cycles: %li vs %li\n", (int32)nes_registers[7], X.count);
+	if (((int32)nes_registers[7] >> 16) != X.count) {
+		printf("cycles: %li vs %li\n", (int32)nes_registers[7] >> 16, X.count);
 		fail = 1;
 	}
 
@@ -99,6 +100,11 @@ static void compare_state(void)
 		fail = 1;
 	}
 
+	if (timestamp_a != timestamp) {
+		printf("timestamp: %lu vs %lu\n", timestamp_a, timestamp);
+		fail = 1;
+	}
+
 	if (fail) leave();
 }
 
@@ -166,11 +172,13 @@ void X6502_Run_d(int32 c)
 			pending_irq = 0;
 		}
 
-		nes_registers[7]=1;
+		nes_registers[7]=1<<16;
 		X.count=1;
 
 		dread_count_c = dread_count_a = dwrite_count_c = dwrite_count_a = 0;
 		mapirq_cyc_a = mapirq_cyc_c = 0;
+		timestamp_a = timestamp;
+
 		X6502_Run_c();
 
 		X6502_Run_a();
diff --git a/ops.h b/ops.h
index 62b8481..cd595cd 100644
--- a/ops.h
+++ b/ops.h
@@ -22,7 +22,8 @@ case 0x00:  /* BRK */
             _PC++;
             PUSH(_PC>>8);
             PUSH(_PC);
-            PUSH(_P|U_FLAG|B_FLAG);
+	    _P|=B_FLAG;
+            PUSH(_P|U_FLAG);
 	    _P|=I_FLAG;
             _PC=RdMem(0xFFFE);
             _PC|=RdMem(0xFFFF)<<8;
diff --git a/x6502.h b/x6502.h
index 1b63a2f..3216d50 100644
--- a/x6502.h
+++ b/x6502.h
@@ -84,11 +84,11 @@ extern void FP_FASTAPASS(1) (*MapIRQHook)(int a);
 { \
  int32 cycles = (c) << 4; /* *16 */ \
  if (PAL) cycles -= (c);  /* *15 */ \
- nes_registers[7]+=cycles; \
- if (nes_registers[7] > 0) { \
-   cycles = (int32)nes_registers[7]; \
+ nes_registers[7]+=cycles<<16; \
+ cycles=(int32)nes_registers[7]>>16; \
+ if (cycles > 0) { \
    X6502_Run_a(); \
-   cycles -= (int32)nes_registers[7]; \
+   cycles -= (int32)nes_registers[7]>>16; \
    asmcpu_update(cycles); \
  } \
 }
-- 
2.39.5