initial pandora port
[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];
8fa5eb33 12extern uint32 timestamp_a;
0b65fdb3 13extern uint32 framecount;
e7f52878 14extern X6502 X_;
0b65fdb3 15static uint32 framecount_d;
c0bf6f9f 16uint32 PC_prev = 0xcccccc, OP_prev = 0xcccccc;
17int32 g_cnt = 0;
af32b6c2 18
655f8df0 19static int pending_add_cycles = 0, pending_rebase = 0, pending_irq = 0;
af32b6c2 20
81bd66a1 21uint8 dreads[4];
22uint32 dwrites_c[2], dwrites_a[2];
23int dread_count_c, dread_count_a, dwrite_count_c, dwrite_count_a;
370cff9a 24int mapirq_cyc_c, mapirq_cyc_a;
81bd66a1 25
e7f52878 26extern void DumpEmptyCartMapping(void);
27
af32b6c2 28static void leave(void)
29{
92e249b1 30 printf("\nA: %02x, X: %02x, Y: %02x, S: %02x\n", X.A, X.X, X.Y, X.S);
0b65fdb3 31 printf("PC = %04x, OP=%02X\n", PC_prev, OP_prev);
32 printf("rest = %08x\n", nes_registers[4]);
e7f52878 33 DumpEmptyCartMapping();
af32b6c2 34 exit(1);
35}
36
37static void compare_state(void)
38{
39 uint8 nes_flags;
81bd66a1 40 int i, fail = 0;
af32b6c2 41
42 if ((nes_registers[0] >> 24) != X.A) {
0b65fdb3 43 printf("A: %02x vs %02x\n", nes_registers[0] >> 24, X.A);
92e249b1 44 fail = 1;
af32b6c2 45 }
46
47 if ((nes_registers[1] & 0xff) != X.X) {
0b65fdb3 48 printf("X: %02x vs %02x\n", nes_registers[1] & 0xff, X.X);
92e249b1 49 fail = 1;
af32b6c2 50 }
51
52 if ((nes_registers[2] & 0xff) != X.Y) {
0b65fdb3 53 printf("Y: %02x vs %02x\n", nes_registers[2] & 0xff, X.Y);
92e249b1 54 fail = 1;
af32b6c2 55 }
56
57 if (nes_registers[3] - pc_base != X.PC) {
0b65fdb3 58 printf("PC: %04x vs %04x\n", nes_registers[3] - pc_base, X.PC);
92e249b1 59 fail = 1;
af32b6c2 60 }
61
62 if ((nes_registers[4] >> 24) != X.S) {
0b65fdb3 63 printf("S: %02x vs %02x\n", nes_registers[4] >> 24, X.S);
92e249b1 64 fail = 1;
af32b6c2 65 }
66
67 if (((nes_registers[4]>>8)&0xff) != X.IRQlow) {
0b65fdb3 68 printf("IRQlow: %02x vs %02x\n", ((nes_registers[4]>>8)&0xff), X.IRQlow);
92e249b1 69 fail = 1;
af32b6c2 70 }
71
72 // NVUB DIZC
73 nes_flags = nes_registers[4] & 0x5d;
74 if ( nes_registers[5]&0x80000000) nes_flags |= 0x80; // N
75 if (!(nes_registers[5]&0x000000ff)) nes_flags |= 0x02; // Z
76 // nes_flags |= 0x20; // U, not set in C core (set only when pushing)
77
92e249b1 78 if (nes_flags != (X.P&~0x20)) {
79 printf("flags: %02x vs %02x\n", nes_flags, (X.P&~0x20));
80 fail = 1;
af32b6c2 81 }
82
8fa5eb33 83 if (((int32)nes_registers[7] >> 16) != X.count) {
0b65fdb3 84 printf("cycles: %i vs %i\n", (int32)nes_registers[7] >> 16, X.count);
92e249b1 85 fail = 1;
af32b6c2 86 }
92e249b1 87
81bd66a1 88 if (dread_count_a != dread_count_c) {
89 printf("dread_count: %i vs %i\n", dread_count_a, dread_count_c);
90 fail = 1;
91 }
92
93 if (dwrite_count_a != dwrite_count_c) {
94 printf("dwrite_count: %i vs %i\n", dwrite_count_a, dwrite_count_c);
95 fail = 1;
96 }
97
98 for (i = dwrite_count_a - 1; !fail && i >= 0; i--)
99 if (dwrites_a[i] != dwrites_c[i]) {
0b65fdb3 100 printf("dwrites[%i]: %06x vs %06x\n", dwrite_count_a, dwrites_a[i], dwrites_c[i]);
81bd66a1 101 fail = 1;
102 }
103
370cff9a 104 if (mapirq_cyc_a != mapirq_cyc_c) {
105 printf("mapirq_cyc: %i vs %i\n", mapirq_cyc_a, mapirq_cyc_c);
106 fail = 1;
107 }
108
8fa5eb33 109 if (timestamp_a != timestamp) {
0b65fdb3 110 printf("timestamp: %u vs %u\n", timestamp_a, timestamp);
8fa5eb33 111 fail = 1;
112 }
113
e7f52878 114/*
115 if (X_.DB != X.DB) {
116 printf("DB: %02x vs %02x\n", X_.DB, X.DB);
117 fail = 1;
118 }
119*/
92e249b1 120 if (fail) leave();
af32b6c2 121}
122
c0bf6f9f 123static void compare_ram(void)
124{
282becab 125#if 1
c0bf6f9f 126 int i, fail = 0;
127 for (i = 0; i < 0x800/4; i++)
128 {
129 if (((int *)nes_internal_ram)[i] != ((int32 *)RAM)[i]) {
130 int u;
131 fail = 1;
132 for (u = i*4; u < i*4+4; u++)
133 if (nes_internal_ram[u] != RAM[u])
134 printf("RAM[%03x]: %02x vs %02x\n", u, nes_internal_ram[u], RAM[u]);
135 }
136 }
137
138 if (fail) leave();
c0bf6f9f 139#endif
282becab 140}
af32b6c2 141
142void TriggerIRQ_d(void)
143{
144 printf("-- irq\n");
655f8df0 145 pending_irq |= 0x100;
af32b6c2 146}
147
148void TriggerNMI_d(void)
149{
150 printf("-- nmi\n");
151 TriggerNMI_c();
152 TriggerNMI_a();
153 compare_state();
154}
155
af32b6c2 156void X6502_Run_d(int32 c)
157{
c0bf6f9f 158 int32 cycles = c << 4; /* *16 */
159 if (PAL) cycles -= c; /* *15 */
af32b6c2 160
92e249b1 161 //printf("-- %06i: run(%i)\n", (int)g_cnt, (int)c);
c0bf6f9f 162 g_cnt += cycles;
af32b6c2 163
0b65fdb3 164 if (framecount != framecount_d) {
c0bf6f9f 165 compare_ram();
0b65fdb3 166 framecount_d = framecount;
167 }
168
169 timestamp_a = timestamp;
c0bf6f9f 170
171 while (g_cnt > 0)
af32b6c2 172 {
655f8df0 173 if (pending_irq) {
174 if (pending_irq & 0x100) {
175 TriggerIRQ_c();
176 TriggerIRQ_a();
177 }
178 if (pending_irq & 0xff) {
655f8df0 179 X6502_IRQBegin_c(pending_irq & 0xff);
180 X6502_IRQBegin_a(pending_irq & 0xff);
181 }
182 pending_irq = 0;
183 }
184
e5f8a1a9 185 //printf("%04x: %02x\n", nes_registers[3] - pc_base, *(unsigned char *)nes_registers[3]);
186
8fa5eb33 187 nes_registers[7]=1<<16;
af32b6c2 188 X.count=1;
92e249b1 189
81bd66a1 190 dread_count_c = dread_count_a = dwrite_count_c = dwrite_count_a = 0;
370cff9a 191 mapirq_cyc_a = mapirq_cyc_c = 0;
0b65fdb3 192 //timestamp_a = timestamp;
8fa5eb33 193
af32b6c2 194 X6502_Run_c();
92e249b1 195
af32b6c2 196 X6502_Run_a();
92e249b1 197
af32b6c2 198 compare_state();
c0bf6f9f 199 g_cnt -= 1 - X.count;
200 if (pending_add_cycles) {
c0bf6f9f 201 g_cnt -= pending_add_cycles*48;
0b65fdb3 202 //X6502_AddCycles_c(pending_add_cycles);
203 //X6502_AddCycles_a(pending_add_cycles);
204 timestamp += pending_add_cycles;
205 timestamp_a += pending_add_cycles;
c0bf6f9f 206 pending_add_cycles = 0;
207 }
208 if (pending_rebase) {
209 X6502_Rebase_a();
210 pending_rebase = 0;
211 }
af32b6c2 212 }
92e249b1 213
214 //printf("-- run_end\n");
af32b6c2 215}
216
217void X6502_Reset_d(void)
218{
219 printf("-- reset\n");
220
221 X6502_Reset_c();
222 X6502_Reset_a();
223 compare_state();
224}
225
226void X6502_Power_d(void)
227{
228 printf("-- power\n");
c0bf6f9f 229 if (nes_internal_ram == RAM) printf("nes_internal_ram == RAM!!\n");
81bd66a1 230 dread_count_c = dread_count_a = dwrite_count_c = dwrite_count_a = 0;
370cff9a 231 mapirq_cyc_c = mapirq_cyc_a = 0;
af32b6c2 232
233 X6502_Power_c();
234 X6502_Power_a();
235 compare_state();
e5f8a1a9 236
237#if 0
238 {
239 unsigned char *p = (void *) nes_registers[3];
240 int i, u, nop = 0xea;
241
242 for (i = 0; i < 256; i++)
243 {
244 if (i == 0 || i == 0x20 || i == 0x40 || i == 0x60 || i == 0x4c || i == 0x6c) continue; /* BRK, JSR, RET, etc. */
245 if ((i & 0x1f) == 0x10) continue; /* Bxx */
246 switch (i)
247 {
248 case 0x02: /* JAM */
249 case 0x12:
250 case 0x22:
251 case 0x32:
252 case 0x42:
253 case 0x52:
254 case 0x62:
255 case 0x72:
256 case 0x92:
257 case 0xB2:
258 case 0xD2:
259 case 0xF2: continue;
260 }
261
262 *p++ = i;
263 for (u = 0; u < 3; u++)
264 *p++ = nop;
265 }
266 }
267#endif
af32b6c2 268}
269
270void X6502_AddCycles_d(int x)
271{
92e249b1 272 printf("-- AddCycles(%i|%i)\n", x, x*48);
af32b6c2 273
c0bf6f9f 274 pending_add_cycles = x; // *48;
275// printf("can't use this in debug\n");
276// exit(1);
92e249b1 277 //X6502_AddCycles_c(x);
278 //X6502_AddCycles_a(x);
af32b6c2 279 //compare_state();
280}
281
282void X6502_IRQBegin_d(int w)
283{
284 printf("-- IRQBegin(%02x)\n", w);
285
655f8df0 286 // X6502_IRQBegin_c(w);
287 // X6502_IRQBegin_a(w);
288 pending_irq |= w;
af32b6c2 289}
290
291void X6502_IRQEnd_d(int w)
292{
293 printf("-- IRQEnd(%02x)\n", w);
294
295 X6502_IRQEnd_c(w);
296 X6502_IRQEnd_a(w);
297}
298
299
c0bf6f9f 300void X6502_Rebase_d(void)
301{
302 pending_rebase = 1;
303}
304
af32b6c2 305