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