debug.c
来自「GAMEBOY模拟器virtual_gameb DOS版(C语言)」· C语言 代码 · 共 317 行
C
317 行
/** VGB: portable GameBoy emulator ***************************//** **//** Debug.c **//** **//** This file contains the built-in debugging routine for **//** the GameBoy emulator which is called on each CPU step **//** when Trap==TRUE. **//** **//** Copyright (C) Marat Fayzullin 1995,1996 **//** Pascal Felber 1996 **//** You are not allowed to distribute this software **//** commercially. Please, notify me, if you make any **//** changes to this file. **//*************************************************************/#ifdef DEBUG#include "Z80.h"#include <stdio.h>#include <string.h>int DAsm(char *S,word A);char *Mnemonics[256] ={ "NOP","LD BC,#h","LD (BC),A","INC BC","INC B","DEC B","LD B,*h","RLCA", "LD (#h),SP","ADD HL,BC","LD A,(BC)","DEC BC","INC C","DEC C","LD C,*h","RRCA", "STOP","LD DE,#h","LD (DE),A","INC DE","INC D","DEC D","LD D,*h","RLA", "JR @h","ADD HL,DE","LD A,(DE)","DEC DE","INC E","DEC E","LD E,*h","RRA", "JR NZ,@h","LD HL,#h","LD (HL+),A","INC HL","INC H","DEC H","LD H,*h","DAA", "JR Z,@h","ADD HL,HL","LD A,(HL+)","DEC HL","INC L","DEC L","LD L,*h","CPL", "JR NC,@h","LD SP,#h","LD (HL-),A","INC SP","INC (HL)","DEC (HL)","LD (HL),*h","SCF", "JR C,@h","ADD HL,SP","LD A,(HL-)","DEC SP","INC A","DEC A","LD A,*h","CCF", "LD B,B","LD B,C","LD B,D","LD B,E","LD B,H","LD B,L","LD B,(HL)","LD B,A", "LD C,B","LD C,C","LD C,D","LD C,E","LD C,H","LD C,L","LD C,(HL)","LD C,A", "LD D,B","LD D,C","LD D,D","LD D,E","LD D,H","LD D,L","LD D,(HL)","LD D,A", "LD E,B","LD E,C","LD E,D","LD E,E","LD E,H","LD E,L","LD E,(HL)","LD E,A", "LD H,B","LD H,C","LD H,D","LD H,E","LD H,H","LD H,L","LD H,(HL)","LD H,A", "LD L,B","LD L,C","LD L,D","LD L,E","LD L,H","LD L,L","LD L,(HL)","LD L,A", "LD (HL),B","LD (HL),C","LD (HL),D","LD (HL),E","LD (HL),H","LD (HL),L","HALT","LD (HL),A", "LD A,B","LD A,C","LD A,D","LD A,E","LD A,H","LD A,L","LD A,(HL)","LD A,A", "ADD B","ADD C","ADD D","ADD E","ADD H","ADD L","ADD (HL)","ADD A", "ADC B","ADC C","ADC D","ADC E","ADC H","ADC L","ADC (HL)","ADC A", "SUB B","SUB C","SUB D","SUB E","SUB H","SUB L","SUB (HL)","SUB A", "SBC B","SBC C","SBC D","SBC E","SBC H","SBC L","SBC (HL)","SBC A", "AND B","AND C","AND D","AND E","AND H","AND L","AND (HL)","AND A", "XOR B","XOR C","XOR D","XOR E","XOR H","XOR L","XOR (HL)","XOR A", "OR B","OR C","OR D","OR E","OR H","OR L","OR (HL)","OR A", "CP B","CP C","CP D","CP E","CP H","CP L","CP (HL)","CP A", "RET NZ","POP BC","JP NZ,#h","JP #h","CALL NZ,#h","PUSH BC","ADD *h","RST 00h", "RET Z","RET","JP Z,#h","PREFIX CBh","CALL Z,#h","CALL #h","ADC *h","RST 08h", "RET NC","POP DE","JP NC,#h","DB D3h","CALL NC,#h","PUSH DE","SUB *h","RST 10h", "RET C","RETI","JP C,#h","DB DBh","CALL C,#h","DB DDh","SBC *h","RST 18h", "LD (FF*h),A","POP HL","LD (FF00h+C),A","EX HL,(SP)","DB E4h","PUSH HL","AND *h","RST 20h", "ADD SP,@h","LD PC,HL","LD (#h),A","DB EBh","DB ECh","PREFIX EDh","XOR *h","RST 28h", "LD A,(FF*h)","POP AF","LD A,(FF00h+C)","DI","DB F4h","PUSH AF","OR *h","RST 30h", "LDHL SP,@h","LD SP,HL","LD A,(#h)","EI","DB FCh","DB FDh","CP *h","RST 38h"};char *MnemonicsCB[256] ={ "RLC B","RLC C","RLC D","RLC E","RLC H","RLC L","RLC (HL)","RLC A", "RRC B","RRC C","RRC D","RRC E","RRC H","RRC L","RRC (HL)","RRC A", "RL B","RL C","RL D","RL E","RL H","RL L","RL (HL)","RL A", "RR B","RR C","RR D","RR E","RR H","RR L","RR (HL)","RR A", "SLA B","SLA C","SLA D","SLA E","SLA H","SLA L","SLA (HL)","SLA A", "SRA B","SRA C","SRA D","SRA E","SRA H","SRA L","SRA (HL)","SRA A", "SWAP B","SWAP C","SWAP D","SWAP E","SWAP H","SWAP L","SWAP (HL)","SWAP A", "SRL B","SRL C","SRL D","SRL E","SRL H","SRL L","SRL (HL)","SRL A", "BIT 0,B","BIT 0,C","BIT 0,D","BIT 0,E","BIT 0,H","BIT 0,L","BIT 0,(HL)","BIT 0,A", "BIT 1,B","BIT 1,C","BIT 1,D","BIT 1,E","BIT 1,H","BIT 1,L","BIT 1,(HL)","BIT 1,A", "BIT 2,B","BIT 2,C","BIT 2,D","BIT 2,E","BIT 2,H","BIT 2,L","BIT 2,(HL)","BIT 2,A", "BIT 3,B","BIT 3,C","BIT 3,D","BIT 3,E","BIT 3,H","BIT 3,L","BIT 3,(HL)","BIT 3,A", "BIT 4,B","BIT 4,C","BIT 4,D","BIT 4,E","BIT 4,H","BIT 4,L","BIT 4,(HL)","BIT 4,A", "BIT 5,B","BIT 5,C","BIT 5,D","BIT 5,E","BIT 5,H","BIT 5,L","BIT 5,(HL)","BIT 5,A", "BIT 6,B","BIT 6,C","BIT 6,D","BIT 6,E","BIT 6,H","BIT 6,L","BIT 6,(HL)","BIT 6,A", "BIT 7,B","BIT 7,C","BIT 7,D","BIT 7,E","BIT 7,H","BIT 7,L","BIT 7,(HL)","BIT 7,A", "RES 0,B","RES 0,C","RES 0,D","RES 0,E","RES 0,H","RES 0,L","RES 0,(HL)","RES 0,A", "RES 1,B","RES 1,C","RES 1,D","RES 1,E","RES 1,H","RES 1,L","RES 1,(HL)","RES 1,A", "RES 2,B","RES 2,C","RES 2,D","RES 2,E","RES 2,H","RES 2,L","RES 2,(HL)","RES 2,A", "RES 3,B","RES 3,C","RES 3,D","RES 3,E","RES 3,H","RES 3,L","RES 3,(HL)","RES 3,A", "RES 4,B","RES 4,C","RES 4,D","RES 4,E","RES 4,H","RES 4,L","RES 4,(HL)","RES 4,A", "RES 5,B","RES 5,C","RES 5,D","RES 5,E","RES 5,H","RES 5,L","RES 5,(HL)","RES 5,A", "RES 6,B","RES 6,C","RES 6,D","RES 6,E","RES 6,H","RES 6,L","RES 6,(HL)","RES 6,A", "RES 7,B","RES 7,C","RES 7,D","RES 7,E","RES 7,H","RES 7,L","RES 7,(HL)","RES 7,A", "SET 0,B","SET 0,C","SET 0,D","SET 0,E","SET 0,H","SET 0,L","SET 0,(HL)","SET 0,A", "SET 1,B","SET 1,C","SET 1,D","SET 1,E","SET 1,H","SET 1,L","SET 1,(HL)","SET 1,A", "SET 2,B","SET 2,C","SET 2,D","SET 2,E","SET 2,H","SET 2,L","SET 2,(HL)","SET 2,A", "SET 3,B","SET 3,C","SET 3,D","SET 3,E","SET 3,H","SET 3,L","SET 3,(HL)","SET 3,A", "SET 4,B","SET 4,C","SET 4,D","SET 4,E","SET 4,H","SET 4,L","SET 4,(HL)","SET 4,A", "SET 5,B","SET 5,C","SET 5,D","SET 5,E","SET 5,H","SET 5,L","SET 5,(HL)","SET 5,A", "SET 6,B","SET 6,C","SET 6,D","SET 6,E","SET 6,H","SET 6,L","SET 6,(HL)","SET 6,A", "SET 7,B","SET 7,C","SET 7,D","SET 7,E","SET 7,H","SET 7,L","SET 7,(HL)","SET 7,A"};char *MnemonicsED[256] ={ "DB EDh,00h","DB EDh,01h","DB EDh,02h","DB EDh,03h", "DB EDh,04h","DB EDh,05h","DB EDh,06h","DB EDh,07h", "DB EDh,08h","DB EDh,09h","DB EDh,0Ah","DB EDh,0Bh", "DB EDh,0Ch","DB EDh,0Dh","DB EDh,0Eh","DB EDh,0Fh", "DB EDh,10h","DB EDh,11h","DB EDh,12h","DB EDh,13h", "DB EDh,14h","DB EDh,15h","DB EDh,16h","DB EDh,17h", "DB EDh,18h","DB EDh,19h","DB EDh,1Ah","DB EDh,1Bh", "DB EDh,1Ch","DB EDh,1Dh","DB EDh,1Eh","DB EDh,1Fh", "DB EDh,20h","DB EDh,21h","DB EDh,22h","DB EDh,23h", "DB EDh,24h","DB EDh,25h","DB EDh,26h","DB EDh,27h", "DB EDh,28h","DB EDh,29h","DB EDh,2Ah","DB EDh,2Bh", "DB EDh,2Ch","DB EDh,2Dh","DB EDh,2Eh","DB EDh,2Fh", "DB EDh,30h","DB EDh,31h","DB EDh,32h","DB EDh,33h", "DB EDh,34h","DB EDh,35h","DB EDh,36h","DB EDh,37h", "DB EDh,38h","DB EDh,39h","DB EDh,3Ah","DB EDh,3Bh", "DB EDh,3Ch","DB EDh,3Dh","DB EDh,3Eh","DB EDh,3Fh", "DB EDh,40h","DB EDh,41h","SBC HL,BC","LD (#h),BC", "DB EDh,44h","RETN","IM 0","LD I,A", "DB EDh,48h","DB EDh,49h","ADC HL,BC","LD BC,(#h)", "DB EDh,4Ch","RETI","DB EDh,4Eh","LD R,A", "DB EDh,50h","DB EDh,51h","SBC HL,DE","LD (#h),DE", "DB EDh,54h","DB EDh,55h","IM 1","LD A,I", "DB EDh,58h","DB EDh,59h","ADC HL,DE","LD DE,(#h)", "DB EDh,5Ch","DB EDh,5Dh","IM 2","LD A,R", "DB EDh,60h","DB EDh,61h","SBC HL,HL","LD (#h),HL", "DB EDh,64h","DB EDh,65h","DB EDh,66h","RRD", "DB EDh,68h","DB EDh,69h","ADC HL,HL","LD HL,(#h)", "DB EDh,6Ch","DB EDh,6Dh","DB EDh,6Eh","RLD", "DB EDh,70h","DB EDh,71h","SBC HL,SP","LD (#h),SP", "DB EDh,74h","DB EDh,75h","DB EDh,76h","DB EDh,77h", "DB EDh,78h","DB EDh,79h","ADC HL,SP","LD SP,(#h)", "DB EDh,7Ch","DB EDh,7Dh","DB EDh,7Eh","DB EDh,7Fh", "DB EDh,80h","DB EDh,81h","DB EDh,82h","DB EDh,83h", "DB EDh,84h","DB EDh,85h","DB EDh,86h","DB EDh,87h", "DB EDh,88h","DB EDh,89h","DB EDh,8Ah","DB EDh,8Bh", "DB EDh,8Ch","DB EDh,8Dh","DB EDh,8Eh","DB EDh,8Fh", "DB EDh,90h","DB EDh,91h","DB EDh,92h","DB EDh,93h", "DB EDh,94h","DB EDh,95h","DB EDh,96h","DB EDh,97h", "DB EDh,98h","DB EDh,99h","DB EDh,9Ah","DB EDh,9Bh", "DB EDh,9Ch","DB EDh,9Dh","DB EDh,9Eh","DB EDh,9Fh", "LDI","CPI","DB EDh,A2h","DB EDh,A3h", "DB EDh,A4h","DB EDh,A5h","DB EDh,A6h","DB EDh,A7h", "LDD","CPD","DB EDh,AAh","DB EDh,ABh", "DB EDh,ACh","DB EDh,ADh","DB EDh,AEh","DB EDh,AFh", "LDIR","CPIR","DB EDh,B2h","DB EDh,B3h", "DB EDh,B4h","DB EDh,B5h","DB EDh,B6h","DB EDh,B7h", "LDDR","CPDR","DB EDh,BAh","DB EDh,BBh", "DB EDh,BCh","DB EDh,BDh","DB EDh,BEh","DB EDh,BFh", "DB EDh,C0h","DB EDh,C1h","DB EDh,C2h","DB EDh,C3h", "DB EDh,C4h","DB EDh,C5h","DB EDh,C6h","DB EDh,C7h", "DB EDh,C8h","DB EDh,C9h","DB EDh,CAh","DB EDh,CBh", "DB EDh,CCh","DB EDh,CDh","DB EDh,CEh","DB EDh,CFh", "DB EDh,D0h","DB EDh,D1h","DB EDh,D2h","DB EDh,D3h", "DB EDh,D4h","DB EDh,D5h","DB EDh,D6h","DB EDh,D7h", "DB EDh,D8h","DB EDh,D9h","DB EDh,DAh","DB EDh,DBh", "DB EDh,DCh","DB EDh,DDh","DB EDh,DEh","DB EDh,DFh", "DB EDh,E0h","DB EDh,E1h","DB EDh,E2h","DB EDh,E3h", "DB EDh,E4h","DB EDh,E5h","DB EDh,E6h","DB EDh,E7h", "DB EDh,E8h","DB EDh,E9h","DB EDh,EAh","DB EDh,EBh", "DB EDh,ECh","DB EDh,EDh","DB EDh,EEh","DB EDh,EFh", "DB EDh,F0h","DB EDh,F1h","DB EDh,F2h","DB EDh,F3h", "DB EDh,F4h","DB EDh,F5h","DB EDh,F6h","DB EDh,F7h", "DB EDh,F8h","DB EDh,F9h","DB EDh,FAh","DB EDh,FBh", "DB EDh,FCh","DB EDh,FDh","DB EDh,FEh","DB EDh,FFh"};int DAsm(char *S,word A){ char R[128],H[10],C,*T,*P; byte J,Offset; word B; B=A;C='\0';J=0; switch(M_RDMEM(B)) { case 0xCB: B++;T=MnemonicsCB[M_RDMEM(B++)];break; case 0xED: B++;T=MnemonicsED[M_RDMEM(B++)];break; default: T=Mnemonics[M_RDMEM(B++)]; } if(P=strchr(T,'^')) { strncpy(R,T,P-T);R[P-T]='\0'; sprintf(H,"%02X",M_RDMEM(B++)); strcat(R,H);strcat(R,P+1); } else strcpy(R,T); if(P=strchr(R,'%')) *P=C; if(P=strchr(R,'*')) { strncpy(S,R,P-R);S[P-R]='\0'; sprintf(H,"%02X",M_RDMEM(B++)); strcat(S,H);strcat(S,P+1); } else if(P=strchr(R,'@')) { strncpy(S,R,P-R);S[P-R]='\0'; if(!J) Offset=M_RDMEM(B++); strcat(S,Offset&0x80? "-":"+"); J=Offset&0x80? 256-Offset:Offset; sprintf(H,"%02X",J); strcat(S,H);strcat(S,P+1); } else if(P=strchr(R,'#')) { strncpy(S,R,P-R);S[P-R]='\0'; sprintf(H,"%04X",M_RDMEM(B)+256*M_RDMEM(B+1)); strcat(S,H);strcat(S,P+1); B+=2; } else strcpy(S,R); return(B-A);}/*** Single-step debugger ****************************//*** This function should exist if DEBUG is ***//*** #defined. When Trace=TRUE, it is called after ***//*** each command executed by the CPU and given ***//*** address of the address space and the register ***//*** file. ***//*****************************************************/void Debug(reg *R){ static char Flags[8] = "SZ.H.PNC"; char S[128],T[10]; byte J,I; DAsm(S,R->PC.W); for(J=0,I=R->AF.B.l;J<8;J++,I<<=1) T[J]=I&0x80? Flags[J]:'.'; T[8]='\0'; printf ( "AF:%04X HL:%04X DE:%04X BC:%04X PC:%04X SP:%04X\n", R->AF.W,R->HL.W,R->DE.W,R->BC.W,R->PC.W,R->SP.W ); printf ( "AT PC: [%02X - %s] AT SP: [%04X] FLAGS: [%s]\n", M_RDMEM(R->PC.W),S,M_RDMEM(R->SP.W)+256*M_RDMEM(R->SP.W+1),T ); while(1) { printf("\n[Command,'?']-> "); fflush(stdout);fflush(stdin); fgets(S,50,stdin); for(J=0;S[J]>=' ';J++) S[J]=toupper(S[J]); S[J]='\0'; switch(S[0]) { case 'H': case '?': puts("\n<CR> : break at next instruction"); puts("=<addr> : break at addr"); puts("+<offset> : break at PC + offset"); puts("c : continue without break"); puts("m<addr> : memory dump at addr"); puts("d<addr> : disassembly at addr"); puts("?,h : show this help text"); puts("q : exit VGB"); break; case '\0': return; case '=': if(strlen(S)<2) break; else { sscanf(S+1,"%hX",&Trap);Trace=0;return; } case '+': if(strlen(S)<2) break; else { sscanf(S+1,"%hX",&Trap);Trap+=R->PC.W;Trace=0;return; } case 'C': Trap=0xFFFF;Trace=0;return; case 'Q': CPURunning=Trace=0;return; case 'M': { word Addr; if(strlen(S)>1) sscanf(S+1,"%hX",&Addr); else Addr=R->PC.W; puts(""); for(J=0;J<16;J++) { printf("%04X: ",Addr); for(I=0;I<16;I++,Addr++) printf("%02X ",M_RDMEM(Addr)); printf(" | ");Addr-=16; for(I=0;I<16;I++,Addr++) putchar(isprint(M_RDMEM(Addr))? M_RDMEM(Addr):'.'); puts(""); } } break; case 'D': { word Addr; if(strlen(S)>1) sscanf(S+1,"%hX",&Addr); else Addr=R->PC.W; puts(""); for(J=0;J<16;J++) { printf("%04X: ",Addr); Addr+=DAsm(S,Addr); puts(S); } } break; } }}#endif
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?