/[VRac]/M6502/Debug.c
This is repository of my old source code which isn't updated any more. Go to git.rot13.org for current projects!
ViewVC logotype

Annotation of /M6502/Debug.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 23 - (hide annotations)
Mon Jul 30 10:49:26 2007 UTC (16 years, 10 months ago) by dpavlin
File MIME type: text/plain
File size: 10729 byte(s)
import upstream M6502-010807.zip from http://fms.komkon.org/EMUL8/
1 dpavlin 23 /** M6502: portable 6502 emulator ****************************/
2     /** **/
3     /** Debug.c **/
4     /** **/
5     /** This file contains the built-in debugging routine for **/
6     /** the 6502 emulator which is called on each 6502 step **/
7     /** when Trap!=0. Some NES-dependent features are also **/
8     /** included under #ifdef INES. **/
9     /** **/
10     /** Copyright (C) Marat Fayzullin 1996-2007 **/
11     /** You are not allowed to distribute this software **/
12     /** commercially. Please, notify me, if you make any **/
13     /** changes to this file. **/
14     /*************************************************************/
15     #ifdef DEBUG
16    
17     #include <stdio.h>
18     #include <string.h>
19     #include <ctype.h>
20    
21     #ifdef INES
22     #include "NES.h"
23     extern word VAddr;
24     extern byte CURLINE;
25     #endif
26    
27     #define RDWORD(A) (Rd6502(A+1)*256+Rd6502(A))
28    
29     enum AddressingModes { Ac=0,Il,Im,Ab,Zp,Zx,Zy,Ax,Ay,Rl,Ix,Iy,In,No };
30    
31     static const byte *Ops[]=
32     {
33     "adc","and","asl","bcc","bcs","beq","bit","bmi",
34     "bne","bpl","brk","bvc","bvs","clc","cld","cli",
35     "clv","cmp","cpx","cpy","dec","dex","dey","inx",
36     "iny","eor","inc","jmp","jsr","lda","nop","ldx",
37     "ldy","lsr","ora","pha","php","pla","plp","rol",
38     "ror","rti","rts","sbc","sta","stx","sty","sec",
39     "sed","sei","tax","tay","txa","tya","tsx","txs"
40     };
41    
42     static const byte Ads[512]=
43     {
44     10,Il, 34,Ix, No,No, No,No, No,No, 34,Zp, 2,Zp, No,No,
45     36,Il, 34,Im, 2,Ac, No,No, No,No, 34,Ab, 2,Ab, No,No,
46     9,Rl, 34,Iy, No,No, No,No, No,No, 34,Zx, 2,Zx, No,No,
47     13,Il, 34,Ay, No,No, No,No, No,No, 34,Ax, 2,Ax, No,No,
48     28,Ab, 1,Ix, No,No, No,No, 6,Zp, 1,Zp, 39,Zp, No,No,
49     38,Il, 1,Im, 39,Ac, No,No, 6,Ab, 1,Ab, 39,Ab, No,No,
50     7,Rl, 1,Iy, No,No, No,No, No,No, 1,Zx, 39,Zx, No,No,
51     47,Il, 1,Ay, No,No, No,No, No,No, 1,Ax, 39,Ax, No,No,
52     41,Il, 25,Ix, No,No, No,No, No,No, 25,Zp, 33,Zp, No,No,
53     35,Il, 25,Im, 33,Ac, No,No, 27,Ab, 25,Ab, 33,Ab, No,No,
54     11,Rl, 25,Iy, No,No, No,No, No,No, 25,Zx, 33,Zx, No,No,
55     15,Il, 25,Ay, No,No, No,No, No,No, 25,Ax, 33,Ax, No,No,
56     42,Il, 0,Ix, No,No, No,No, No,No, 0,Zp, 40,Zp, No,No,
57     37,Il, 0,Im, 40,Ac, No,No, 27,In, 0,Ab, 40,Ab, No,No,
58     12,Rl, 0,Iy, No,No, No,No, No,No, 0,Zx, 40,Zx, No,No,
59     49,Il, 0,Ay, No,No, No,No, No,No, 0,Ax, 40,Ax, No,No,
60     No,No, 44,Ix, No,No, No,No, 46,Zp, 44,Zp, 45,Zp, No,No,
61     22,Il, No,No, 52,Il, No,No, 46,Ab, 44,Ab, 45,Ab, No,No,
62     3,Rl, 44,Iy, No,No, No,No, 46,Zx, 44,Zx, 45,Zy, No,No,
63     53,Il, 44,Ay, 55,Il, No,No, No,No, 44,Ax, No,No, No,No,
64     32,Im, 29,Ix, 31,Im, No,No, 32,Zp, 29,Zp, 31,Zp, No,No,
65     51,Il, 29,Im, 50,Il, No,No, 32,Ab, 29,Ab, 31,Ab, No,No,
66     4,Rl, 29,Iy, No,No, No,No, 32,Zx, 29,Zx, 31,Zy, No,No,
67     16,Il, 29,Ay, 54,Il, No,No, 32,Ax, 29,Ax, 31,Ay, No,No,
68     19,Im, 17,Ix, No,No, No,No, 19,Zp, 17,Zp, 20,Zp, No,No,
69     24,Il, 17,Im, 21,Il, No,No, 19,Ab, 17,Ab, 20,Ab, No,No,
70     8,Rl, 17,Iy, No,No, No,No, No,No, 17,Zx, 20,Zx, No,No,
71     14,Il, 17,Ay, No,No, No,No, No,No, 17,Ax, 20,Ax, No,No,
72     18,Im, 43,Ix, No,No, No,No, 18,Zp, 43,Zp, 26,Zp, No,No,
73     23,Il, 43,Im, 30,Il, No,No, 18,Ab, 43,Ab, 26,Ab, No,No,
74     5,Rl, 43,Iy, No,No, No,No, No,No, 43,Zx, 26,Zx, No,No,
75     48,Il, 43,Ay, No,No, No,No, No,No, 43,Ax, 26,Ax, No,No
76     };
77    
78     /** DAsm() ****************************************************/
79     /** This function will disassemble a single command and **/
80     /** return the number of bytes disassembled. **/
81     /**************************************************************/
82     static int DAsm(char *S,word A)
83     {
84     byte J;
85     word B,OP,TO;
86    
87     B=A;OP=Rd6502(B++)*2;
88    
89     switch(Ads[OP+1])
90     {
91     case Ac: sprintf(S,"%s a",Ops[Ads[OP]]);break;
92     case Il: sprintf(S,"%s",Ops[Ads[OP]]);break;
93    
94     case Rl: J=Rd6502(B++);TO=A+2+((J<0x80)? J:(J-256));
95     sprintf(S,"%s $%04X",Ops[Ads[OP]],TO);break;
96    
97     case Im: sprintf(S,"%s #$%02X",Ops[Ads[OP]],Rd6502(B++));break;
98     case Zp: sprintf(S,"%s $%02X",Ops[Ads[OP]],Rd6502(B++));break;
99     case Zx: sprintf(S,"%s $%02X,x",Ops[Ads[OP]],Rd6502(B++));break;
100     case Zy: sprintf(S,"%s $%02X,y",Ops[Ads[OP]],Rd6502(B++));break;
101     case Ix: sprintf(S,"%s ($%02X,x)",Ops[Ads[OP]],Rd6502(B++));break;
102     case Iy: sprintf(S,"%s ($%02X),y",Ops[Ads[OP]],Rd6502(B++));break;
103    
104     case Ab: sprintf(S,"%s $%04X",Ops[Ads[OP]],RDWORD(B));B+=2;break;
105     case Ax: sprintf(S,"%s $%04X,x",Ops[Ads[OP]],RDWORD(B));B+=2;break;
106     case Ay: sprintf(S,"%s $%04X,y",Ops[Ads[OP]],RDWORD(B));B+=2;break;
107     case In: sprintf(S,"%s ($%04X)",Ops[Ads[OP]],RDWORD(B));B+=2;break;
108    
109     default: sprintf(S,".db $%02X",OP/2);
110     }
111     return(B-A);
112     }
113    
114     /** Debug6502() **********************************************/
115     /** This function should exist if DEBUG is #defined. When **/
116     /** Trace!=0, it is called after each command executed by **/
117     /** the CPU, and given the 6502 registers. Emulation exits **/
118     /** if Debug6502() returns 0. **/
119     /*************************************************************/
120     byte Debug6502(M6502 *R)
121     {
122     static char FA[9]="NVRBDIZC";
123     char S[128];
124     byte *P,F;
125     int J,I,K;
126    
127     DAsm(S,R->PC.W);
128    
129     printf
130     (
131     "A:%02X P:%02X X:%02X Y:%02X S:%04X PC:%04X Flags:[",
132     R->A,R->P,R->X,R->Y,R->S+0x0100,R->PC.W
133     );
134    
135     for(J=0,F=R->P;J<8;J++,F<<=1)
136     printf("%c",F&0x80? FA[J]:'.');
137     printf("]\n");
138    
139     printf
140     (
141     "AT PC: [%02X - %s] AT SP: [%02X %02X %02X]\n",
142     Rd6502(R->PC.W),S,
143     Rd6502(0x0100+(byte)(R->S+1)),
144     Rd6502(0x0100+(byte)(R->S+2)),
145     Rd6502(0x0100+(byte)(R->S+3))
146     );
147    
148     while(1)
149     {
150     printf("\n[Command,'?']-> ");
151     fflush(stdout);fflush(stdin);
152    
153     fgets(S,50,stdin);
154     for(J=0;S[J]>=' ';J++)
155     S[J]=toupper(S[J]);
156     S[J]='\0';
157    
158     switch(S[0])
159     {
160     case 'H':
161     case '?':
162     printf("\n***** Built-in 6502 Debugger Commands *****\n");
163     printf("<CR> : Break at the next instruction\n");
164     printf("= <addr> : Break at addr\n");
165     printf("+ <offset> : Break at PC + offset\n");
166     printf("c : Continue without break\n");
167     printf("j <addr> : Continue from addr\n");
168     printf("m <addr> : Memory dump at addr\n");
169     printf("d <addr> : Disassembly at addr\n");
170     printf("v : Show interrupt vectors\n");
171     #ifdef INES
172     printf("p : Show NES palette\n");
173     printf("r : Show NES hardware registers\n");
174     printf("s : Show sprite attributes\n");
175     printf("s <number> : Show sprite pattern\n");
176     #endif /* INES */
177     printf("?,h : Show this help text\n");
178     printf("q : Exit emulation\n");
179     break;
180    
181     case '\0': return(1);
182     case '=': if(strlen(S)>=2)
183     { sscanf(S+1,"%hX",&(R->Trap));R->Trace=0;return(1); }
184     break;
185     case '+': if(strlen(S)>=2)
186     {
187     sscanf(S+1,"%hX",&(R->Trap));
188     R->Trap+=R->PC.W;R->Trace=0;
189     return(1);
190     }
191     break;
192     case 'J': if(strlen(S)>=2)
193     { sscanf(S+1,"%hX",&(R->PC.W));R->Trace=0;return(1); }
194     break;
195     case 'C': R->Trap=0xFFFF;R->Trace=0;return(1);
196     case 'Q': return(0);
197    
198     case 'V':
199     printf("\n6502 Interrupt Vectors:\n");
200     printf("[$FFFC] INIT: $%04X\n",Rd6502(0xFFFC)+256*Rd6502(0xFFFD));
201     printf("[$FFFE] IRQ: $%04X\n",Rd6502(0xFFFE)+256*Rd6502(0xFFFF));
202     printf("[$FFFA] NMI: $%04X\n",Rd6502(0xFFFA)+256*Rd6502(0xFFFB));
203     break;
204    
205     case 'M':
206     {
207     word Addr;
208    
209     if(sscanf(S+1,"%hX",&Addr)!=1) Addr=R->PC.W;
210     printf("\n");
211     for(J=0;J<16;J++)
212     {
213     printf("%04X: ",Addr);
214     for(I=0;I<16;I++,Addr++)
215     printf("%02X ",Rd6502(Addr));
216     printf(" | ");Addr-=16;
217     for(I=0;I<16;I++,Addr++)
218     printf("%c",isprint(Rd6502(Addr))? Rd6502(Addr):'.');
219     printf("\n");
220     }
221     }
222     break;
223    
224     case 'D':
225     {
226     word Addr;
227    
228     if(sscanf(S+1,"%hX",&Addr)!=1) Addr=R->PC.W;
229     printf("\n");
230     for(J=0;J<16;J++)
231     {
232     printf("%04X: ",Addr);
233     Addr+=DAsm(S,Addr);
234     printf("%s\n",S);
235     }
236     }
237     break;
238    
239     #ifdef INES
240     case 'P':
241     printf("\nNo | Picture | Sprites\n");
242     for(J=0;J<16;J++)
243     {
244     byte B1,B2;
245     B1=*(VRAM+0x3F00+J);B2=*(VRAM+0x3F10+J);
246     printf
247     (
248     "%2d | %02X (%02X,%02X,%02X) | %02X (%02X,%02X,%02X)\n",J,
249     B1,Palette[B1][0],Palette[B1][1],Palette[B1][2],
250     B2,Palette[B2][0],Palette[B2][1],Palette[B2][2]
251     );
252     }
253     break;
254    
255     case 'R':
256     printf
257     (
258     "\n[$2000] PPUCONT1 = $%02X\n[$2001] PPUCONT2 = $%02X\n[$2002] PPUSTAT = $%02X\n",
259     PPU[0],PPU[1],PPU[2]
260     );
261     printf
262     (
263     "POSITION = %d,%d\nVADDR = $%04X\nSCANLINE = %d\n",
264     SCROLLX,SCROLLY,VAddr,CURLINE
265     );
266     break;
267    
268     case 'S':
269     if(sscanf(S+1,"%d",&J)==1)
270     {
271     K=SRAM[J*4+1];
272     P=SPRITES16?
273     VPage[(K&0x01? 4:0)+(K>>6)]+((K&0x3E)<<4)
274     :SprGen[K>>6]+((K&0x3F)<<4);
275     printf("Sprite #%d (pattern $%02X)\n--------\n",J,K);
276     for(I=SPRITES16? 16:8;I>0;I--,P++)
277     {
278     for(K=0x80;K;K>>=1)
279     printf("%c",P[0]&K? (P[8]&K? '#':'o'):(P[8]&K? 'O':'.'));
280     printf("\n");
281     if(I==9) P+=8;
282     }
283     printf("--------\n");
284     }
285     else
286     {
287     printf("\nNo| Position | Pat | Att |No| Position | Pat | Att |No| Position | Pat | Att\n");
288     for(J=I=0;J<64*4;J+=4)
289     if(!J||(SRAM[J]&&SRAM[J+3]&&(SRAM[J]<240)))
290     {
291     printf
292     (
293     "%2d| %3d,%3d | $%02X | $%02X %s",
294     J/4,SRAM[J+3],SRAM[J],SRAM[J+1],SRAM[J+2],
295     I%3==2? "\n":"|"
296     );
297     I++;
298     }
299     }
300     break;
301     #endif /* INES */
302     }
303     }
304    
305     /* Continue with emulation */
306     return(1);
307     }
308    
309     #endif /* DEBUG */

  ViewVC Help
Powered by ViewVC 1.1.26