Gradius fixed
[fceu.git] / ncpu_debug.c
CommitLineData
af32b6c2 1#include <stdio.h>
2#include <stdlib.h>
3
4#include "types.h"
5#include "x6502.h"
6#include "fce.h"
7
8// asm core state
9extern uint32 nes_registers[0x10];
10extern uint32 pc_base;
c0bf6f9f 11extern uint8 nes_internal_ram[0x800];
12uint32 PC_prev = 0xcccccc, OP_prev = 0xcccccc;
13int32 g_cnt = 0;
af32b6c2 14
655f8df0 15static int pending_add_cycles = 0, pending_rebase = 0, pending_irq = 0;
af32b6c2 16
81bd66a1 17uint8 dreads[4];
18uint32 dwrites_c[2], dwrites_a[2];
19int dread_count_c, dread_count_a, dwrite_count_c, dwrite_count_a;
370cff9a 20int mapirq_cyc_c, mapirq_cyc_a;
81bd66a1 21
af32b6c2 22static void leave(void)
23{
92e249b1 24 printf("\nA: %02x, X: %02x, Y: %02x, S: %02x\n", X.A, X.X, X.Y, X.S);
c0bf6f9f 25 printf("PC = %04lx, OP=%02lX\n", PC_prev, OP_prev);
370cff9a 26 printf("rest = %08lx\n", nes_registers[4]);
af32b6c2 27 exit(1);
28}
29
30static void compare_state(void)
31{
32 uint8 nes_flags;
81bd66a1 33 int i, fail = 0;
af32b6c2 34
35 if ((nes_registers[0] >> 24) != X.A) {
36 printf("A: %02lx vs %02x\n", nes_registers[0] >> 24, X.A);
92e249b1 37 fail = 1;
af32b6c2 38 }
39
40 if ((nes_registers[1] & 0xff) != X.X) {
41 printf("X: %02lx vs %02x\n", nes_registers[1] & 0xff, X.X);
92e249b1 42 fail = 1;
af32b6c2 43 }
44
45 if ((nes_registers[2] & 0xff) != X.Y) {
46 printf("Y: %02lx vs %02x\n", nes_registers[2] & 0xff, X.Y);
92e249b1 47 fail = 1;
af32b6c2 48 }
49
50 if (nes_registers[3] - pc_base != X.PC) {
51 printf("PC: %04lx vs %04x\n", nes_registers[3] - pc_base, X.PC);
92e249b1 52 fail = 1;
af32b6c2 53 }
54
55 if ((nes_registers[4] >> 24) != X.S) {
56 printf("S: %02lx vs %02x\n", nes_registers[4] >> 24, X.S);
92e249b1 57 fail = 1;
af32b6c2 58 }
59
60 if (((nes_registers[4]>>8)&0xff) != X.IRQlow) {
61 printf("IRQlow: %02lx vs %02x\n", ((nes_registers[4]>>8)&0xff), X.IRQlow);
92e249b1 62 fail = 1;
af32b6c2 63 }
64
65 // NVUB DIZC
66 nes_flags = nes_registers[4] & 0x5d;
67 if ( nes_registers[5]&0x80000000) nes_flags |= 0x80; // N
68 if (!(nes_registers[5]&0x000000ff)) nes_flags |= 0x02; // Z
69 // nes_flags |= 0x20; // U, not set in C core (set only when pushing)
70
92e249b1 71 if (nes_flags != (X.P&~0x20)) {
72 printf("flags: %02x vs %02x\n", nes_flags, (X.P&~0x20));
73 fail = 1;
af32b6c2 74 }
75
76 if ((int32)nes_registers[7] != X.count) {
77 printf("cycles: %li vs %li\n", (int32)nes_registers[7], X.count);
92e249b1 78 fail = 1;
af32b6c2 79 }
92e249b1 80
81bd66a1 81 if (dread_count_a != dread_count_c) {
82 printf("dread_count: %i vs %i\n", dread_count_a, dread_count_c);
83 fail = 1;
84 }
85
86 if (dwrite_count_a != dwrite_count_c) {
87 printf("dwrite_count: %i vs %i\n", dwrite_count_a, dwrite_count_c);
88 fail = 1;
89 }
90
91 for (i = dwrite_count_a - 1; !fail && i >= 0; i--)
92 if (dwrites_a[i] != dwrites_c[i]) {
93 printf("dwrites[%i]: %06lx vs %06lx\n", dwrite_count_a, dwrites_a[i], dwrites_c[i]);
94 fail = 1;
95 }
96
370cff9a 97 if (mapirq_cyc_a != mapirq_cyc_c) {
98 printf("mapirq_cyc: %i vs %i\n", mapirq_cyc_a, mapirq_cyc_c);
99 fail = 1;
100 }
101
92e249b1 102 if (fail) leave();
af32b6c2 103}
104
c0bf6f9f 105#if 1
106static void compare_ram(void)
107{
108 int i, fail = 0;
109 for (i = 0; i < 0x800/4; i++)
110 {
111 if (((int *)nes_internal_ram)[i] != ((int32 *)RAM)[i]) {
112 int u;
113 fail = 1;
114 for (u = i*4; u < i*4+4; u++)
115 if (nes_internal_ram[u] != RAM[u])
116 printf("RAM[%03x]: %02x vs %02x\n", u, nes_internal_ram[u], RAM[u]);
117 }
118 }
119
120 if (fail) leave();
121}
122#endif
af32b6c2 123
124void TriggerIRQ_d(void)
125{
126 printf("-- irq\n");
655f8df0 127 pending_irq |= 0x100;
af32b6c2 128}
129
130void TriggerNMI_d(void)
131{
132 printf("-- nmi\n");
133 TriggerNMI_c();
134 TriggerNMI_a();
135 compare_state();
136}
137
138void TriggerNMINSF_d(void)
139{
140}
141
142void X6502_Run_d(int32 c)
143{
c0bf6f9f 144 int32 cycles = c << 4; /* *16 */
145 if (PAL) cycles -= c; /* *15 */
af32b6c2 146
92e249b1 147 //printf("-- %06i: run(%i)\n", (int)g_cnt, (int)c);
c0bf6f9f 148 g_cnt += cycles;
af32b6c2 149
c0bf6f9f 150 if (c > 200)
151 compare_ram();
152
153 while (g_cnt > 0)
af32b6c2 154 {
655f8df0 155 if (pending_irq) {
156 if (pending_irq & 0x100) {
157 TriggerIRQ_c();
158 TriggerIRQ_a();
159 }
160 if (pending_irq & 0xff) {
161 TriggerIRQ_c();
162 TriggerIRQ_a();
163 X6502_IRQBegin_c(pending_irq & 0xff);
164 X6502_IRQBegin_a(pending_irq & 0xff);
165 }
166 pending_irq = 0;
167 }
168
af32b6c2 169 nes_registers[7]=1;
170 X.count=1;
92e249b1 171
81bd66a1 172 dread_count_c = dread_count_a = dwrite_count_c = dwrite_count_a = 0;
370cff9a 173 mapirq_cyc_a = mapirq_cyc_c = 0;
af32b6c2 174 X6502_Run_c();
92e249b1 175
af32b6c2 176 X6502_Run_a();
92e249b1 177
af32b6c2 178 compare_state();
c0bf6f9f 179 g_cnt -= 1 - X.count;
180 if (pending_add_cycles) {
c0bf6f9f 181 g_cnt -= pending_add_cycles*48;
182 pending_add_cycles = 0;
183 }
184 if (pending_rebase) {
185 X6502_Rebase_a();
186 pending_rebase = 0;
187 }
af32b6c2 188 }
92e249b1 189
190 //printf("-- run_end\n");
af32b6c2 191}
192
193void X6502_Reset_d(void)
194{
195 printf("-- reset\n");
196
197 X6502_Reset_c();
198 X6502_Reset_a();
199 compare_state();
200}
201
202void X6502_Power_d(void)
203{
204 printf("-- power\n");
c0bf6f9f 205 if (nes_internal_ram == RAM) printf("nes_internal_ram == RAM!!\n");
81bd66a1 206 dread_count_c = dread_count_a = dwrite_count_c = dwrite_count_a = 0;
370cff9a 207 mapirq_cyc_c = mapirq_cyc_a = 0;
af32b6c2 208
209 X6502_Power_c();
210 X6502_Power_a();
211 compare_state();
212}
213
214void X6502_AddCycles_d(int x)
215{
92e249b1 216 printf("-- AddCycles(%i|%i)\n", x, x*48);
af32b6c2 217
c0bf6f9f 218 pending_add_cycles = x; // *48;
219// printf("can't use this in debug\n");
220// exit(1);
92e249b1 221 //X6502_AddCycles_c(x);
222 //X6502_AddCycles_a(x);
af32b6c2 223 //compare_state();
224}
225
226void X6502_IRQBegin_d(int w)
227{
228 printf("-- IRQBegin(%02x)\n", w);
229
655f8df0 230 // X6502_IRQBegin_c(w);
231 // X6502_IRQBegin_a(w);
232 pending_irq |= w;
af32b6c2 233}
234
235void X6502_IRQEnd_d(int w)
236{
237 printf("-- IRQEnd(%02x)\n", w);
238
239 X6502_IRQEnd_c(w);
240 X6502_IRQEnd_a(w);
241}
242
243
c0bf6f9f 244void X6502_Rebase_d(void)
245{
246 pending_rebase = 1;
247}
248
af32b6c2 249