📄 debug.cpp
字号:
/**********************************************************************************************/void ProcessDebugCommand (char *Line){ uint8 Bank = Registers.PB; uint32 Address = CPU.PC - CPU.PCBase; uint16 Hold; uint16 Number; char String [512]; short ErrorCode; if (strcasecmp (Line, "cheat") == 0) { S9xStartCheatSearch (&Cheat); printf ("Cheat Search Started\n"); return; } if (strcasecmp (Line, "less") == 0) { S9xSearchForChange (&Cheat, S9X_LESS_THAN, S9X_8_BITS, FALSE, TRUE); printf ("Recorded all values that have decreased\n"); return; } if (strcasecmp (Line, "print") == 0) { printf ("Cheat search results:\n"); S9xOutputCheatSearchResults (&Cheat); return; } if (strncasecmp (Line, "constant", 8) == 0) { uint32 Byte; if (sscanf (&Line [8], "%x %x", &Address, &Byte) == 2) S9xAddCheat (TRUE, TRUE, Address, Byte); return; } if (strncasecmp (Line, "dump", 4) == 0) { int Count; if (sscanf (&Line [4], "%x %d", &Address, &Count) == 2) { sprintf (String, "%06x%05d.sd2", Address, Count); FILE *fs = fopen (String, "wb"); if (fs) { int i; for (i = 0; i < Count; i++) putc (S9xGetByte (Address + i), fs); fclose (fs); } else printf ("Can't open %s for writing\n", String); } else printf ("Usage: dump start_address_in_hex count_in_decimal\n"); return; } if (Line[0] == 'i') { printf ("Vectors:\n"); sprintf (String, " 8 Bit 16 Bit "); DPrint (String); sprintf (String, "ABT $00:%04X|$00:%04X", S9xGetWord (0xFFF8), S9xGetWord (0xFFE8)); DPrint (String); sprintf (String, "BRK $00:%04X|$00:%04X", S9xGetWord (0xFFFE), S9xGetWord (0xFFE6)); DPrint (String); sprintf (String, "COP $00:%04X|$00:%04X", S9xGetWord (0xFFF4), S9xGetWord (0xFFE4)); DPrint (String); sprintf (String, "IRQ $00:%04X|$00:%04X", S9xGetWord (0xFFFE), S9xGetWord (0xFFEE)); DPrint (String); sprintf (String, "NMI $00:%04X|$00:%04X", S9xGetWord (0xFFFA), S9xGetWord (0xFFEA)); DPrint (String); sprintf (String, "RES $00:%04X", S9xGetWord (0xFFFC)); DPrint (String); } if (strncmp (Line, "ai", 2) == 0) { printf ("APU vectors:"); for (int i = 0; i < 0x40; i += 2) { if (i % 16 == 0) printf ("\n%04x ", 0xffc0 + i); printf ("%04x ", APU.ExtraRAM [i]); } printf ("\n"); } if (Line[0] == 's') { CPU.PC += S9xOPrint (String, Bank, Address); Bank = Registers.PB; Address = CPU.PC - CPU.PCBase; Line[0] = 'r'; } if (Line[0] == 'z') { uint16 *p = (uint16 *) &Memory.VRAM [PPU.BG[2].SCBase << 1]; for (int l = 0; l < 32; l++) { for (int c = 0; c < 32; c++, p++) { printf ("%04x,", *p++); } printf ("\n"); } } if (*Line == 'c') { printf ("Colours:\n"); for (int i = 0; i < 256; i++) { printf ("%02x%02x%02x ", PPU.CGDATA[i] & 0x1f, (PPU.CGDATA[i] >> 5) & 0x1f, (PPU.CGDATA[i] >> 10) & 0x1f); } printf ("\n"); } if (*Line == 'S') { int SmallWidth, LargeWidth; int SmallHeight, LargeHeight; switch ((Memory.FillRAM[0x2101] >> 5) & 7) { case 0: SmallWidth = SmallHeight = 8; LargeWidth = LargeHeight = 16; break; case 1: SmallWidth = SmallHeight = 8; LargeWidth = LargeHeight = 32; break; case 2: SmallWidth = SmallHeight = 8; LargeWidth = LargeHeight = 64; break; case 3: SmallWidth = SmallHeight = 16; LargeWidth = LargeHeight = 32; break; case 4: SmallWidth = SmallHeight = 16; LargeWidth = LargeHeight = 64; break; default: case 5: SmallWidth = SmallHeight = 32; LargeWidth = LargeHeight = 64; break; case 6: SmallWidth = 16; SmallHeight = 32; LargeWidth = 32; LargeHeight = 64; break; case 7: SmallWidth = 16; SmallHeight = 32; LargeWidth = LargeHeight = 32; break; } printf ("Sprites: Small: %dx%d, Large: %dx%d, OAMAddr: 0x%04x, OBJNameBase: 0x%04x, OBJNameSelect: 0x%04x, First: %d\n", SmallWidth,SmallHeight, LargeWidth,LargeHeight, PPU.OAMAddr, PPU.OBJNameBase, PPU.OBJNameSelect, PPU.FirstSprite);// for (int p = 0; p < 4; p++)// {// int c = 0;// int i;// for (i = 0; GFX.OBJList [i] >= 0; i++)// {// if (PPU.OBJ[GFX.OBJList [i]].Priority == p)// c++;// }// printf ("Priority %d: %03d, ", p, c);// }// printf ("\n"); for (int i = 0; i < 128; i++) { printf ("X:%3d Y:%3d %c%c%d%c ", PPU.OBJ[i].HPos, PPU.OBJ[i].VPos, PPU.OBJ[i].VFlip ? 'V' : 'v', PPU.OBJ[i].HFlip ? 'H' : 'h', PPU.OBJ[i].Priority, PPU.OBJ[i].Size ? 'S' : 's'); if (i % 4 == 3) printf ("\n"); } } if (*Line == 'T') { if (Line [1] == 'S') { SA1.Flags ^= TRACE_FLAG; if (SA1.Flags & TRACE_FLAG) { printf ("SA1 CPU instruction tracing enabled.\n"); if (trace2 == NULL) trace2 = fopen ("trace_sa1.log", "wb"); } else { printf ("SA1 CPU instruction tracing disabled.\n"); fclose (trace2); trace2 = NULL; } } else { CPU.Flags ^= TRACE_FLAG; if (CPU.Flags & TRACE_FLAG) { printf ("CPU instruction tracing enabled.\n"); if (trace == NULL) trace = fopen ("trace.log", "wb"); } else { printf ("CPU instruction tracing disabled.\n"); fclose (trace); trace = NULL; } } } if (*Line == 'A') { APU.Flags ^= TRACE_FLAG; extern FILE *apu_trace; if (APU.Flags & TRACE_FLAG) {#ifdef SPCTOOL printf ("ENABLED\n"); _SetSPCDbg (TraceSPC); //Install debug handler#endif if (apu_trace == NULL) apu_trace = fopen ("aputrace.log", "wb"); } else {#ifdef SPCTOOL _SetSPCDbg (NULL);#endif if (apu_trace) { fclose (apu_trace); apu_trace = NULL; } } printf ("APU tracing %s\n", APU.Flags & TRACE_FLAG ? "enabled" : "disabled"); } if (*Line == 'B') { Settings.TraceSoundDSP ^= 1; printf ("Sound DSP register tracing %s\n", Settings.TraceSoundDSP ? "enabled" : "disabled"); S9xOpenCloseSoundTracingFile (Settings.TraceSoundDSP); } if (*Line == 'b') S9xPrintAPUState (); if (*Line == 'C') { printf ("SPC700 sample addresses at 0x%04x:\n", APU.DSP [APU_DIR] << 8); for (int i = 0; i < 256; i++) { uint8 *dir = IAPU.RAM + (((APU.DSP [APU_DIR] << 8) + i * 4) & 0xffff); int addr = *dir + (*(dir + 1) << 8); int addr2 = *(dir + 2) + (*(dir + 3) << 8); printf ("%04X %04X;", addr, addr2); if (i % 8 == 7) printf ("\n"); } } if (*Line == 'R') { S9xReset (); printf ("SNES reset.\n"); CPU.Flags |= DEBUG_MODE_FLAG; } if (strncmp (Line, "ad", 2) == 0) { int Count = 16; Address = 0; if (sscanf (Line+2, "%x,%x", &Address, &Count) != 2) { if (sscanf (Line + 2, "%x", &Address) == 1) Count = 16; } printf ("APU RAM dump:\n"); for (int l = 0; l < Count; l += 16) { printf ("%04X ", Address); for (int i = 0; i < 16; i++) printf ("%02X ", IAPU.RAM [Address++]); printf ("\n"); } *Line = 0; } if (*Line == 'a') { printf ("APU in-ports: %02X %02X %02X %02X\n", IAPU.RAM [0xF4], IAPU.RAM [0xF5], IAPU.RAM [0xF6], IAPU.RAM [0xF7]);#ifdef SPCTOOL printf ("APU out-ports: %02X %02X %02X %02X\n", _SPCOutP [0], _SPCOutP [1], _SPCOutP [2], _SPCOutP [3]);#else printf ("APU out-ports: %02X %02X %02X %02X\n", APU.OutPorts [0], APU.OutPorts [1], APU.OutPorts [2], APU.OutPorts [3]);#endif printf ("ROM/RAM switch: %s\n", (IAPU.RAM [0xf1] & 0x80) ? "ROM" : "RAM"); for (int i = 0; i < 3; i++) if (APU.TimerEnabled [i]) printf ("Timer%d enabled, Value: 0x%03X, 4-bit: 0x%02X, Target: 0x%03X\n", i, APU.Timer [i], IAPU.RAM [0xfd + i], APU.TimerTarget [i]); } if (*Line == 'P') { Settings.TraceDSP = !Settings.TraceDSP; printf ("DSP tracing %s\n", Settings.TraceDSP ? "enabled" : "disabled"); } if (Line[0] == 'p') { S9xBreakpoint[5].Enabled = FALSE; Address += S9xOPrint (String, Bank, Address); if (strncmp (&String[18], "JMP", 3) != 0 && strncmp (&String[18], "JML", 3) != 0 && strncmp (&String[18], "RT", 2) != 0 && strncmp (&String[18], "BRA", 3)) { S9xBreakpoint[5].Enabled = TRUE; S9xBreakpoint[5].Bank = Bank; S9xBreakpoint[5].Address = Address; } else { CPU.Flags |= SINGLE_STEP_FLAG; CPU.Flags &= ~DEBUG_MODE_FLAG; } } if (Line[0] == 'b') { if (Line[1] == 's') { GetNumber (Line + 2, &Hold); if (Hold > 4) Hold = 0; if (Hold < 5) if (GetStartAddress (Line + 5, &Bank, &Address) == -1) { //Clear S9xBreakpoint S9xBreakpoint[Hold].Enabled = FALSE; } else { //Set S9xBreakpoint S9xBreakpoint[Hold].Enabled = TRUE; S9xBreakpoint[Hold].Bank = Bank; S9xBreakpoint[Hold].Address = Address; CPU.Flags |= BREAK_FLAG; } Line = "bv"; } if (Line[1] == 'v') { Number = 0; if (GetNumber (Line + 2, &Number) == -1 && Number < 5) { //Show All Breakpoints DPrint ("Breakpoints:"); for (Number = 0; Number != 5; Number++) { if (S9xBreakpoint[Number].Enabled) sprintf (String, "%i @ $%02X:%04X", Number, S9xBreakpoint[Number].Bank, S9xBreakpoint[Number].Address); else sprintf (String, "%i @ Disabled", Number); DPrint (String); } } else { //Show selected S9xBreakpoint DPrint ("Breakpoint:"); if (S9xBreakpoint[Number].Enabled) sprintf (String, "%i @ $%02X:%04X", Number, S9xBreakpoint[Number].Bank, S9xBreakpoint[Number].Address); else sprintf (String, "%i @ Disabled", Number); DPrint (String); } } } if (Line[0] == '?' || strcasecmp (Line, "help") == 0) { for (short Counter = 0; HelpMessage[Counter] != NULL; Counter++) DPrint (HelpMessage[Counter]); } if (Line[0] == 't') { CPU.Flags |= SINGLE_STEP_FLAG; CPU.Flags &= ~DEBUG_MODE_FLAG; } if (Line[0] == 'f') { CPU.Flags |= FRAME_ADVANCE_FLAG; CPU.Flags &= ~DEBUG_MODE_FLAG; // Render this frame IPPU.RenderThisFrame = TRUE; IPPU.FrameSkip = 0; if (sscanf (&Line [1], "%d", &ICPU.FrameAdvanceCount) != 1) ICPU.Frame = 0; } if (Line[0] == 'g') { S9xBreakpoint[5].Enabled = FALSE; int i; bool8 found = FALSE; for (i = 0; i < 5; i++) { if (S9xBreakpoint[i].Enabled) { found = TRUE; if (S9xBreakpoint[i].Bank == Registers.PB && S9xBreakpoint[i].Address == CPU.PC - CPU.PCBase) { S9xBreakpoint[i].Enabled = 2; break; } } } if (!found) CPU.Flags &= ~BREAK_FLAG; ErrorCode = GetStartAddress (Line, &Bank, &Address); if (ErrorCode == 1) { S9xBreakpoint[5].Enabled = TRUE; S9xBreakpoint[5].Bank = Bank; S9xBreakpoint[5].Address = Address; CPU.Flags |= BREAK_FLAG; } CPU.Flags &= ~DEBUG_MODE_FLAG; } if (*Line == 'D') { Settings.TraceDMA = !Settings.TraceDMA; printf ("DMA tracing %s\n", Settings.TraceDMA ? "enabled" : "disabled"); } if (*Line == 'V') { Settings.TraceVRAM = !Settings.TraceVRAM; printf ("Non-DMA VRAM write tracing %s\n", Settings.TraceVRAM ? "enabled" : "disabled"); } if (*Line == 'H') { Settings.TraceHDMA = !Settings.TraceHDMA; printf ("H-DMA tracing %s\n", Settings.TraceHDMA ? "enabled" : "disabled"); } if (*Line == 'U') { Settings.TraceUnknownRegisters = !Settings.TraceUnknownRegisters; printf ("Unknown registers read/write tracing %s\n", Settings.TraceUnknownRegisters ? "enabled" : "disabled"); } if (Line[0] == 'd') { int CLine; int CByte; uint32 Cycles = CPU.Cycles; uint8 MemoryByte; if (Debug.Dump.Bank != 0 || Debug.Dump.Address != 0) { Bank = Debug.Dump.Bank; Address = Debug.Dump.Address; } ErrorCode = GetStartAddress (Line, &Bank, &Address); for (CLine = 0; CLine != 10; CLine++) { sprintf (String, "$%02X:%04X", Bank, Address); for (CByte = 0; CByte != 16; CByte++) { if (Address + CByte == 0x2140 || Address + CByte == 0x2141 || Address + CByte == 0x2142 || Address + CByte == 0x2143 || Address + CByte == 0x4210) { MemoryByte = 0; } else { MemoryByte = S9xGetByte ((Bank << 16) + Address + CByte); } sprintf (String, "%s %02X", String, MemoryByte); } sprintf (String, "%s-", String); for (CByte = 0; CByte != 16; CByte++) { if (Address + CByte == 0x2140 || Address + CByte == 0x2141 || Address + CByte == 0x2142 || Address + CByte == 0x2143 || Address + CByte == 0x4210) { MemoryByte = 0; } else { MemoryByte = S9xGetByte ((Bank << 16) + Address + CByte); } if (MemoryByte < 32 || MemoryByte >= 127) MemoryByte = '?'; sprintf (String, "%s%c", String, MemoryByte); } Address += 16; DPrint (String); } Debug.Dump.Bank = Bank; Debug.Dump.Address = Address; CPU.Cycles = Cycles; } if (*Line == 'q') S9xExit (); if (*Line == 'W') WhatsMissing (); if (*Line == 'w') WhatsUsed (); if (Line[0] == 'r') {#if 0 sprintf (String, "A[%04X] X[%04X] Y[%04X] S[%04X] D[%04X] DB[%02X] P[%02X] F[%s %s %s %s %s %s %s %s / %s]", Registers.A.W, Registers.X.W, Registers.Y.W, Registers.S.W, Registers.D.W, Registers.DB, Registers.PL, (Registers.P.W & 128) != 0 ? "N" : "n", (Registers.P.W & 64) != 0 ? "V" : "v", (Registers.P.W & 32) != 0 ? "M" : "m", (Registers.P.W & 16) != 0 ? "X" : "x", (Registers.P.W & 8) != 0 ? "D" : "d", (Registers.P.W & 4) != 0 ? "I" : "i", (Registers.P.W & 2) != 0 ? "Z" : "z", (Registers.P.W & 1) != 0 ? "C" : "c", (Registers.P.W & 256) != 0 ? "E" : "e"); DPrint (String);#endif S9xOPrint (String, Bank, Address);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -