diff options
| author | SND\weimingzhi_cp <SND\weimingzhi_cp@e17a0e51-4ae3-4d35-97c3-1a29b211df97> | 2011-03-13 08:26:16 +0000 |
|---|---|---|
| committer | SND\weimingzhi_cp <SND\weimingzhi_cp@e17a0e51-4ae3-4d35-97c3-1a29b211df97> | 2011-03-13 08:26:16 +0000 |
| commit | 379a8879f7dae1a9074317c0270e12dd203b32c0 (patch) | |
| tree | 348efb7ecd4f7cbc030f4b5db6683a857f2ae6cf /libpcsxcore/debug.c | |
| parent | d34b4220bde29d7937d927e9d17a50470a36c500 (diff) | |
| download | pcsxr-379a8879f7dae1a9074317c0270e12dd203b32c0.tar.gz | |
Temporarily reverted r64524 until I (or someone else) find the time to sort out the stuff.
git-svn-id: https://pcsxr.svn.codeplex.com/svn/pcsxr@64536 e17a0e51-4ae3-4d35-97c3-1a29b211df97
Diffstat (limited to 'libpcsxcore/debug.c')
| -rw-r--r-- | libpcsxcore/debug.c | 2290 |
1 files changed, 1145 insertions, 1145 deletions
diff --git a/libpcsxcore/debug.c b/libpcsxcore/debug.c index 5455e305..179e3340 100644 --- a/libpcsxcore/debug.c +++ b/libpcsxcore/debug.c @@ -1,1145 +1,1145 @@ -/* Pcsx - Pc Psx Emulator - * Copyright (C) 1999-2003 Pcsx Team - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, see <http://www.gnu.org/licenses>. - */ - -#include "psxcommon.h" -#include "r3000a.h" -#include "debug.h" -#include "socket.h" - -/* -PCSX Debug console protocol description, version 1.0 -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -Commands number are formatted using %03X (yes) -Registers number are formatted using %02X. -Breakpoints numbers are formatted using %X -All other values are formatted using %08X, unless specified. - - -Client inputs: -~~~~~~~~~~~~~ -Basic commands (1xx): --------------------- -100 <message> - Sends a dumb message. Will be replied with a 200 reply, followed by the message. -101 - Gets PCSX version. -102 - Gets protocol version. -103 - Gets status -110 - Gets PC. -111 [reg] - Gets GP register, or all, if no argument. -112 - Gets LO/HI registers. -113 [reg] - Gets COP0 register, or all, if no argument. -114 [reg] - Gets COP2 control register, or all, if no argument. -115 [reg] - Gets COP2 data register, or all, if no argument. -119 [pc] - Disassemble current PC, or given PC. -121 <reg>=<value> - Sets a GP register. Will return a 221 message. -122 <LO|HI>=<value> - Sets LO or HI register. Will return a 222 message. -123 <reg>=<value> - Sets a COP0 register. Will return a 223 message. -124 <reg>=<value> - Sets a COP2 control register. Will return a 224 message. -125 <reg>=<value> - Sets a COP2 data register. Will return a 225 message. -130 <size>@<addr> - Dumps a range of memory, of size bytes starting at addr. -140 <size>@<addr> - Sets a range of memory, of size bytes starting at addr. - Will have to send immediately exactly size bytes afterward. -150 [number] - Starts/reset mapping execution flow, or stop it if number = 0 -151 [number] - Starts/reset mapping read8 flow, or stop it if number = 0 -152 [number] - Starts/reset mapping read16 flow, or stop it if number = 0 -153 [number] - Starts/reset mapping read32 flow, or stop it if number = 0 -154 [number] - Starts/reset mapping write8 flow, or stop it if number = 0 -155 [number] - Starts/reset mapping write16 flow, or stop it if number = 0 -156 [number] - Starts/reset mapping write32 flow, or stop it if number = 0 -160 [number] - Breaks on map exec flow, or stop it if number = 0 -161 [number] - Breaks on map read8 flow, or stop it if number = 0 -162 [number] - Breaks on map read16 flow, or stop it if number = 0 -163 [number] - Breaks on map read32 flow, or stop it if number = 0 -164 [number] - Breaks on map write8 flow, or stop it if number = 0 -165 [number] - Breaks on map write16 flow, or stop it if number = 0 -166 [number] - Breaks on map write32 flow, or stop it if number = 0 -170 - Dumps the execution flow map in an IDC file - -Execution flow control commands (3xx): -------------------------------------- -300 [number] - Get a list of the actual breakpoints. Will get '400' answers. -301 [number] - Deletes a breakpoint, or all, if no arguments. -310 <address> - Sets an exec breakpoint. -320 <address> - Sets a read breakpoint, 1 byte / 8 bits. -321 <address> - Sets a read breakpoint, 2 bytes / 16 bits, has to be on an even address. -322 <address> - Sets a read breakpoint, 4 bytes / 32 bits, address has to be 4-bytes aligned. -330 <address> - Sets a write breakpoint, 1 byte / 8 bits. -331 <address> - Sets a write breakpoint, 2 bytes / 16 bits, has to be on an even address. -332 <address> - Sets a write breakpoint, 4 bytes / 32 bits, address has to be 4-bytes aligned. -390 - Pauses execution. Equivalents to a breakpoint. -391 - Restarts execution. -395 [number] - Traces execution, 1 instruction by default. Formatted using %i -398 - Soft (quick) resets. -399 - Resets. - - -Server outputs: -~~~~~~~~~~~~~~ -Spontaneous messages (0xx): --------------------------- -000 <message> - Greeting banner. -010 / 011 / 012 / 013 / 014 / 015 / 016 - Execution hit mapping flow automatic breakpoint. -030 <number>@<PC> - Execution hit breakpoint, PCSX is paused. Displays PC's value. - -Basic commands acknowledge (2xx): --------------------------------- -200 <message> - Sends a dumb message. -201 <message> - Returns PCSX version. -202 <message> - Returns protocol version. -203 <status> - status = 0: running; = 1: paused; = 2: trace -210 PC=<value> - Displays current PC value. -211 <reg>=<value> - Displays one GP register value. -212 LO=<value> HI=<value> - Displays LO/HI registers. -213 <reg>=<value> - Displays one COP0 register value. -214 <reg>=<value> - Displays one COP2 control register value. -215 <reg>=<value> - Displays one COP2 data register value. -219 <message> - Displays one line of disassembled code. -221 <reg>=<value> - Displays one GP register value, ack for modification. -222 LO=<value> HI=<value> - Displays LO/HI registers, ack for modification. -223 <reg>=<value> - Displays one COP0 register value, ack for modification. -224 <reg>=<value> - Displays one COP2 control register value, ack for modification. -225 <reg>=<value> - Displays one COP2 data register value, ack for modification. -230 <size>@<addr> - Dumping memory. Will then raw outputs size bytes. -240 <size>@<addr> - Memory set acknowledge. -250 / 251 / 252 / 253 / 254 / 255 / 256 - Acknolwedge of 15x commands. -260 / 261 / 262 / 263 / 264 / 265 / 266 - Acknolwedge of 16x commands. -270 - Acknolwedge of 170 command. - -Execution flow control commands acknowledge (4xx): -------------------------------------------------- -400 <number>@<address>-<type> - Displays a breakpoint, where 'type' can be of E, R1, R2, R4, W1, W2 or W4. -401 <message> - Breakpoint deleting acknowledge. -410, 420, 421, 422, 430, 431, 432 <number> - Breakpoint adding acknowledge. Returns the number of the added breakpoint. -490 <message> - Pausing. -491 <message> - Resuming. -495 <message> - Tracing. -498 <message> - Soft resetting. -499 <message> - Resetting. - -Error messages (5xx): --------------------- -500 <message> - Command not understood. -511 <message> - Invalid GPR register. -512 <message> - Invalid LO/HI register. -513, 514 <message> - Invalid range or address. -530 <message> - Non existant breakpoint. -531, 532, 533 <message> - Invalid breakpoint address. -*/ - -static int debugger_active = 0, paused = 0, trace = 0, reset = 0, resetting = 0; -static int mapping_e = 0, mapping_r8 = 0, mapping_r16 = 0, mapping_r32 = 0, mapping_w8 = 0, mapping_w16 = 0, mapping_w32 = 0; -static int breakmp_e = 0, breakmp_r8 = 0, breakmp_r16 = 0, breakmp_r32 = 0, breakmp_w8 = 0, breakmp_w16 = 0, breakmp_w32 = 0; - -static void ProcessCommands(); - -static u8 *MemoryMap = NULL; - -enum { - MAP_EXEC = 1, - MAP_R8 = 2, - MAP_R16 = 4, - MAP_R32 = 8, - MAP_W8 = 16, - MAP_W16 = 32, - MAP_W32 = 64, - MAP_EXEC_JAL = 128, -}; - -char *breakpoint_type_names[] = { - "E", "R1", "R2", "R4", "W1", "W2", "W4" -}; - -typedef struct breakpoint_s { - struct breakpoint_s *next, *prev; - int number, type; - u32 address; -} breakpoint_t; - -static breakpoint_t *first = NULL; - -static int add_breakpoint(int type, u32 address) { - breakpoint_t *bp = (breakpoint_t *)malloc(sizeof(breakpoint_t)); - - bp->type = type; - bp->address = address; - - if (first) { - bp->number = first->prev->number + 1; - bp->next = first; - bp->prev = first->prev; - first->prev = bp; - bp->prev->next = bp; - } else { - first = bp; - bp->number = 1; - bp->next = bp; - bp->prev = bp; - } - - return bp->number; -} - -static void delete_breakpoint(breakpoint_t * bp) { - if (bp == first) { - if (bp->next == bp) { - first = NULL; - } else { - first = bp->next; - } - } - - bp->next->prev = bp->prev; - bp->prev->next = bp->next; - - free(bp); -} - -static breakpoint_t *next_breakpoint(breakpoint_t *bp) { - return bp->next != first ? bp->next : 0; -} - -static breakpoint_t *find_breakpoint(int number) { - breakpoint_t *p; - - for (p = first; p; p = next_breakpoint(p)) { - if (p->number == number) - return p; - } - - return 0; -} - -void StartDebugger() { - if (debugger_active) - return; - - MemoryMap = (u8 *)malloc(0x200000); - if (MemoryMap == NULL) { - SysMessage(_("Error allocating memory")); - return; - } - - if (StartServer() == -1) { - SysPrintf(_("Unable to start debug server.\n")); - return; - } - - SysPrintf(_("Debugger started.\n")); - debugger_active = 1; -} - -void StopDebugger() { - if (debugger_active) { - StopServer(); - SysPrintf(_("Debugger stopped.\n")); - } - - if (MemoryMap != NULL) { - free(MemoryMap); - MemoryMap = NULL; - } - - while (first != NULL) delete_breakpoint(first); - - debugger_active = 0; -} - -void PauseDebugger() { - trace = 0; - paused = 1; -} - -void ResumeDebugger() { - trace = 0; - paused = 0; -} - -void DebugVSync() { - if (!debugger_active || resetting) - return; - - if (reset) { - resetting = 1; - CheckCdrom(); - SysReset(); - if (reset == 2) - LoadCdrom(); - reset = resetting = 0; - return; - } - - GetClient(); - ProcessCommands(); -} - -static void MarkMap(u32 address, int mask) { - if ((address & 0xff000000) != 0x80000000) return; - MemoryMap[address & 0x001fffff] |= mask; -} - -static int IsMapMarked(u32 address, int mask) { - return (MemoryMap[address & 0x001fffff] & mask) != 0; -} - -void ProcessDebug() { - if (!debugger_active || reset || resetting) - return; - if (trace) { - if (!(--trace)) { - paused = 1; - } - } - if (!paused) { - DebugCheckBP(psxRegs.pc, E); - } - if (mapping_e) { - MarkMap(psxRegs.pc, MAP_EXEC); - if ((psxRegs.code >> 26) == 3) { - MarkMap(_JumpTarget_, MAP_EXEC_JAL); - } - if (((psxRegs.code >> 26) == 0) && ((psxRegs.code && 0x3F) == 9)) { - MarkMap(_Rd_, MAP_EXEC_JAL); - } - } - while (paused) { - GetClient(); - ProcessCommands(); - GPU_updateLace(); - SysUpdate(); - } -} - -static void ProcessCommands() { - int code, i, dumping; - FILE *sfile; - char cmd[257], *arguments, *p, reply[10240], *save, *dump; - u32 reg, value, size, address; - breakpoint_t *bp; - - if (!HasClient()) - return; - if (ReadSocket(cmd, 256) > 0) { - arguments = NULL; - if (strlen(cmd) <= 2) { - code = 0; - } else if (strlen(cmd) == 3) { - code = strtol(cmd, 0, 16); - } else if (!(isxdigit(cmd[0]) && isxdigit(cmd[1]) && isxdigit(cmd[2]) && (cmd[3] == 0x20))) { - code = 0; - } else if (sscanf(cmd, "%3X ", &code) != 1) { - code = 0; - } else { - arguments = cmd + 4; - } - code = strtol(cmd, &arguments, 16); - while (arguments && *arguments && *arguments == 0x20) - arguments++; - - if (*arguments == '\0') - arguments = NULL; - - dumping = 0; - save = NULL; - - switch (code) { - case 0x100: - sprintf(reply, "200 %s\r\n", arguments == NULL ? "OK" : arguments); - break; - case 0x101: - sprintf(reply, "201 %s\r\n", PACKAGE_VERSION); - break; - case 0x102: - sprintf(reply, "202 1.0\r\n"); - break; - case 0x103: - sprintf(reply, "203 %i\r\n", paused ? 1 : trace ? 2 : 0); - break; - case 0x110: - sprintf(reply, "210 PC=%08X\r\n", psxRegs.pc); - break; - case 0x111: - if (arguments) { - if (sscanf(arguments, "%02X", &code) != 1) { - sprintf(reply, "511 Malformed 111 command '%s'\r\n", cmd); - break; - } - } - if (!arguments) { - reply[0] = 0; - for (i = 0; i < 32; i++) { - sprintf(reply, "%s211 %02X=%08X\r\n", reply, i, psxRegs.GPR.r[i]); - } - } else { - if ((code >= 0) && (code < 32)) { - sprintf(reply, "211 %02X=%08X\r\n", code, psxRegs.GPR.r[code]); - } else { - sprintf(reply, "511 Invalid GPR register: %X\r\n", code); - } - } - break; - case 0x112: - sprintf(reply, "212 LO=%08X HI=%08X\r\n", psxRegs.GPR.n.lo, psxRegs.GPR.n.hi); - break; - case 0x113: - if (arguments) { - if (sscanf(arguments, "%02X", &code) != 1) { - sprintf(reply, "511 Malformed 113 command '%s'\r\n", cmd); - break; - } - } - if (!arguments) { - reply[0] = 0; - for (i = 0; i < 32; i++) { - sprintf(reply, "%s213 %02X=%08X\r\n", reply, i, psxRegs.CP0.r[i]); - } - } else { - if ((code >= 0) && (code < 32)) { - sprintf(reply, "213 %02X=%08X\r\n", code, psxRegs.CP0.r[code]); - } else { - sprintf(reply, "511 Invalid COP0 register: %X\r\n", code); - } - } - break; - case 0x114: - if (arguments) { - if (sscanf(arguments, "%02X", &code) != 1) { - sprintf(reply, "511 Malformed 114 command '%s'\r\n", cmd); - break; - } - } - if (!arguments) { - reply[0] = 0; - for (i = 0; i < 32; i++) { - sprintf(reply, "%s214 %02X=%08X\r\n", reply, i, psxRegs.CP2C.r[i]); - } - } else { - if ((code >= 0) && (code < 32)) { - sprintf(reply, "214 %02X=%08X\r\n", code, psxRegs.CP2C.r[code]); - } else { - sprintf(reply, "511 Invalid COP2C register: %X\r\n", code); - } - } - break; - case 0x115: - if (arguments) { - if (sscanf(arguments, "%02X", &code) != 1) { - sprintf(reply, "511 Malformed 111 command '%s'\r\n", cmd); - break; - } - } - if (!arguments) { - reply[0] = 0; - for (i = 0; i < 32; i++) { - sprintf(reply, "%s215 %02X=%08X\r\n", reply, i, psxRegs.CP2D.r[i]); - } - } else { - if ((code >= 0) && (code < 32)) { - sprintf(reply, "215 %02X=%08X\r\n", code, psxRegs.CP2D.r[code]); - } else { - sprintf(reply, "511 Invalid COP2D register: %X\r\n", code); - } - } - break; - case 0x119: - if (arguments) { - if (sscanf(arguments, "%08X", &code) != 1) { - sprintf(reply, "511 Malformed 119 command '%s'\r\n", cmd); - break; - } - } - if (!arguments) - code = psxRegs.pc; - - sprintf(reply, "219 %s\r\n", disR3000AF(psxMemRead32(code), code)); - break; - case 0x121: - if (!arguments || sscanf(arguments, "%02X=%08X", ®, &value) != 2) { - sprintf(reply, "500 Malformed 121 command '%s'\r\n", arguments); - break; - } - - if (reg < 32) { - psxRegs.GPR.r[reg] = value; - sprintf(reply, "221 %02X=%08X\r\n", reg, value); - } else { - sprintf(reply, "512 Invalid GPR register: %02X\r\n", reg); - } - break; - case 0x122: - if (!arguments || strncmp(arguments, "HI=", 3) == 0) { - reg = 33; - } else if (arguments && strncmp(arguments, "LO=", 3) == 0) { - reg = 32; - } else { - arguments[2] = 0; - sprintf(reply, "512 Invalid LO/HI register: '%s'\r\n", arguments); - break; - } - - if (sscanf(arguments + 3, "%08X", &value) != 1) { - sprintf(reply, "500 Malformed 122 command '%s'\r\n", arguments); - } else { - psxRegs.GPR.r[reg] = value; - sprintf(reply, "222 LO=%08X HI=%08X\r\n", psxRegs.GPR.n.lo, psxRegs.GPR.n.hi); - } - break; - case 0x123: - if (!arguments || sscanf(arguments, "%02X=%08X", ®, &value) != 2) { - sprintf(reply, "500 Malformed 123 command '%s'\r\n", arguments); - break; - } - - if (reg < 32) { - psxRegs.CP0.r[reg] = value; - sprintf(reply, "223 %02X=%08X\r\n", reg, value); - } else { - sprintf(reply, "512 Invalid COP0 register: %02X\r\n", reg); - } - break; - case 0x124: - if (!arguments || sscanf(arguments, "%02X=%08X", ®, &value) != 2) { - sprintf(reply, "500 Malformed 124 command '%s'\r\n", arguments); - break; - } - - if (reg < 32) { - psxRegs.CP2C.r[reg] = value; - sprintf(reply, "224 %02X=%08X\r\n", reg, value); - } else { - sprintf(reply, "512 Invalid COP2C register: %02X\r\n", reg); - } - break; - case 0x125: - if (!arguments || sscanf(arguments, "%02X=%08X", ®, &value) != 2) { - sprintf(reply, "500 Malformed 121 command '%s'\r\n", arguments); - break; - } - - if (reg < 32) { - psxRegs.CP2D.r[reg] = value; - sprintf(reply, "225 %02X=%08X\r\n", reg, value); - } else { - sprintf(reply, "512 Invalid COP2D register: %02X\r\n", reg); - } - break; - case 0x130: - if (!arguments || sscanf(arguments, "%08X@%08X", &size, &address) != 2) { - sprintf(reply, "500 Malformed 130 command '%s'\r\n", arguments); - break; - } - - if ((address >= 0x80000000) && ((address + size) <= 0x80200000)) { - sprintf(reply, "230 %08X@%08X\r\n", size, address); - dump = (char *) PSXM(address); - dumping = 1; - } else { - sprintf(reply, "513 Invalid address or range: '%s'\r\n", arguments); - } - break; - case 0x140: - if (!arguments || sscanf(arguments, "%08X@%08X", &size, &address) != 2) { - sprintf(reply, "500 Malformed 140 command '%s'\r\n", arguments); - break; - } - - if ((address >= 0x80000000) && ((address + size) <= 0x80200000)) { - sprintf(reply, "240 %08X@%08X\r\n", size, address); - RawReadSocket((char *)PSXM(address), size); - } else { - sprintf(reply, "514 Invalid address or range: '%s'\r\n", arguments); - } - break; - case 0x150: - code = 1; - if (arguments) { - if (sscanf(arguments, "%02X", &code) != 1) { - sprintf(reply, "500 Malformed 150 command '%s'\r\n", cmd); - break; - } - } - if (code) { - mapping_e = 1; - for (i = 0; i < 0x00200000; i++) { - MemoryMap[i] &= ~MAP_EXEC; - MemoryMap[i] &= ~MAP_EXEC_JAL; - } - } else { - mapping_e = 0; - } - sprintf(reply, "250 Mapping of exec flow %s\r\n", code ? "started" : "stopped"); - break; - case 0x151: - code = 1; - if (arguments) { - if (sscanf(arguments, "%02X", &code) != 1) { - sprintf(reply, "500 Malformed 151 command '%s'\r\n", cmd); - break; - } - } - if (code) { - mapping_r8 = 1; - for (i = 0; i < 0x00200000; i++) { - MemoryMap[i] &= ~MAP_R8; - } - } else { - mapping_r8 = 0; - } - sprintf(reply, "251 Mapping of read8 flow %s\r\n", code ? "started" : "stopped"); - break; - case 0x152: - code = 1; - if (arguments) { - if (sscanf(arguments, "%02X", &code) != 1) { - sprintf(reply, "500 Malformed 152 command '%s'\r\n", cmd); - break; - } - } - if (code) { - mapping_r16 = 1; - for (i = 0; i < 0x00200000; i++) { - MemoryMap[i] &= ~MAP_R16; - } - } else { - mapping_r16 = 0; - } - sprintf(reply, "252 Mapping of read16 flow %s\r\n", code ? "started" : "stopped"); - break; - case 0x153: - code = 1; - if (arguments) { - if (sscanf(arguments, "%02X", &code) != 1) { - sprintf(reply, "500 Malformed 153 command '%s'\r\n", cmd); - break; - } - } - if (code) { - mapping_r32 = 1; - for (i = 0; i < 0x00200000; i++) { - MemoryMap[i] &= ~MAP_R32; - } - } else { - mapping_r32 = 0; - } - sprintf(reply, "253 Mapping of read32 flow %s\r\n", code ? "started" : "stopped"); - break; - case 0x154: - code = 1; - if (arguments) { - if (sscanf(arguments, "%02X", &code) != 1) { - sprintf(reply, "500 Malformed 154 command '%s'\r\n", cmd); - break; - } - } - if (code) { - mapping_w8 = 1; - for (i = 0; i < 0x00200000; i++) { - MemoryMap[i] &= ~MAP_W8; - } - } else { - mapping_w8 = 0; - } - sprintf(reply, "254 Mapping of write8 flow %s\r\n", code ? "started" : "stopped"); - break; - case 0x155: - code = 1; - if (arguments) { - if (sscanf(arguments, "%02X", &code) != 1) { - sprintf(reply, "500 Malformed 155 command '%s'\r\n", cmd); - break; - } - } - if (code) { - mapping_w16 = 1; - for (i = 0; i < 0x00200000; i++) { - MemoryMap[i] &= ~MAP_W16; - } - } else { - mapping_w16 = 0; - } - sprintf(reply, "255 Mapping of write16 flow %s\r\n", code ? "started" : "stopped"); - break; - case 0x156: - code = 1; - if (arguments) { - if (sscanf(arguments, "%02X", &code) != 1) { - sprintf(reply, "500 Malformed 156 command '%s'\r\n", cmd); - break; - } - } - if (code) { - mapping_w32 = 1; - for (i = 0; i < 0x00200000; i++) { - MemoryMap[i] &= ~MAP_W32; - } - } else { - mapping_w32 = 0; - } - sprintf(reply, "256 Mapping of write32 flow %s\r\n", code ? "started" : "stopped"); - break; - case 0x160: - code = 1; - if (arguments) { - if (sscanf(arguments, "%02X", &code) != 1) { - sprintf(reply, "500 Malformed 160 command '%s'\r\n", cmd); - break; - } - } - if (code) { - breakmp_e = 1; - } else { - breakmp_e = 0; - } - sprintf(reply, "260 Break on map of exec flow %s\r\n", code ? "started" : "stopped"); - break; - case 0x161: - code = 1; - if (arguments) { - if (sscanf(arguments, "%02X", &code) != 1) { - sprintf(reply, "500 Malformed 161 command '%s'\r\n", cmd); - break; - } - } - if (code) { - breakmp_r8 = 1; - } else { - breakmp_r8 = 0; - } - sprintf(reply, "261 Break on map of read8 flow %s\r\n", code ? "started" : "stopped"); - break; - case 0x162: - code = 1; - if (arguments) { - if (sscanf(arguments, "%02X", &code) != 1) { - sprintf(reply, "500 Malformed 162 command '%s'\r\n", cmd); - break; - } - } - if (code) { - breakmp_r16 = 1; - } else { - breakmp_r16 = 0; - } - sprintf(reply, "262 Break on map of read16 flow %s\r\n", code ? "started" : "stopped"); - break; - case 0x163: - code = 1; - if (arguments) { - if (sscanf(arguments, "%02X", &code) != 1) { - sprintf(reply, "500 Malformed 163 command '%s'\r\n", cmd); - break; - } - } - if (code) { - breakmp_r32 = 1; - } else { - breakmp_r32 = 0; - } - sprintf(reply, "263 Break on map of read32 flow %s\r\n", code ? "started" : "stopped"); - break; - case 0x164: - code = 1; - if (arguments) { - if (sscanf(arguments, "%02X", &code) != 1) { - sprintf(reply, "500 Malformed 164 command '%s'\r\n", cmd); - break; - } - } - if (code) { - breakmp_w8 = 1; - } else { - breakmp_w8 = 0; - } - sprintf(reply, "264 Break on map of write8 flow %s\r\n", code ? "started" : "stopped"); - break; - case 0x165: - code = 1; - if (arguments) { - if (sscanf(arguments, "%02X", &code) != 1) { - sprintf(reply, "500 Malformed 165 command '%s'\r\n", cmd); - break; - } - } - if (code) { - breakmp_w16 = 1; - } else { - breakmp_w16 = 0; - } - sprintf(reply, "265 Break on map of write16 flow %s\r\n", code ? "started" : "stopped"); - break; - case 0x166: - code = 1; - if (arguments) { - if (sscanf(arguments, "%02X", &code) != 1) { - sprintf(reply, "500 Malformed 166 command '%s'\r\n", cmd); - break; - } - } - if (code) { - breakmp_w32 = 1; - } else { - breakmp_w32 = 0; - } - sprintf(reply, "266 Break on map of write32 flow %s\r\n", code ? "started" : "stopped"); - break; - case 0x170: - sfile = fopen("flow.idc", "wb"); - fprintf(sfile, "#include <idc.idc>\r\n\r\n"); - fprintf(sfile, "static main(void) {\r\n"); - for (i = 0; i < 0x00200000; i++) { - if (IsMapMarked(i, MAP_EXEC_JAL)) { - fprintf(sfile, "\tMakeFunction(0X8%07X,BADADDR);\r\n", i); - } - } - fprintf(sfile, "}\r\n"); - fclose(sfile); - sfile = fopen("markcode.idc", "wb"); - fprintf(sfile, "#include <idc.idc>\r\n\r\n"); - fprintf(sfile, "static main(void) {\r\n"); - for (i = 0; i < 0x00200000; i++) { - if (IsMapMarked(i, MAP_EXEC)) { - fprintf(sfile, "\tMakeCode(0X8%07X);\r\n", i); - } - } - fprintf(sfile, "}\r\n"); - fclose(sfile); - sprintf(reply, "270 flow.idc and markcode.idc dumped\r\n"); - break; - case 0x300: - p = arguments; - if (arguments) { - code = strtol(arguments, &p, 16); - } - if (p == arguments) { - if (first) { - reply[0] = 0; - for (bp = first; bp; bp = next_breakpoint(bp)) { - sprintf(reply, "%s400 %X@%08X-%s\r\n", reply, bp->number, bp->address, breakpoint_type_names[bp->type]); - } - } else { - sprintf(reply, "530 No breakpoint\r\n"); - } - } else { - if ((bp = find_breakpoint(code))) { - sprintf(reply, "400 %X@%08X-%s\r\n", bp->number, bp->address, breakpoint_type_names[bp->type]); - } else { - sprintf(reply, "530 Invalid breakpoint number: %X\r\n", code); - } - } - break; - case 0x301: - p = arguments; - if (arguments) { - code = strtol(arguments, &p, 16); - } - if (p == arguments) { - while (first != NULL) delete_breakpoint(first); - sprintf(reply, "401 All breakpoints deleted.\r\n"); - } else { - if ((bp = find_breakpoint(code))) { - delete_breakpoint(bp); - sprintf(reply, "401 Breakpoint %X deleted.\r\n", code); - } else { - sprintf(reply, "530 Invalid breakpoint number: %X\r\n", code); - } - } - break; - case 0x310: - if (!arguments || sscanf(arguments, "%08X", &address) != 1) { - sprintf(reply, "500 Malformed 310 command '%s'\r\n", arguments); - break; - } -// if ((address & 3) || (address < 0x80000000) || (address >= 0x80200000)) { -// sprintf(reply, "531 Invalid address %08X\r\n", address); -// break; -// } - code = add_breakpoint(E, address); - sprintf(reply, "410 %X\r\n", code); - break; - case 0x320: - if (!arguments || sscanf(arguments, "%08X", &address) != 1) { - sprintf(reply, "500 Malformed 320 command '%s'\r\n", arguments); - break; - } - if ((address < 0x80000000) || (address >= 0x80200000)) { - sprintf(reply, "532 Invalid address %08X\r\n", address); - break; - } - code = add_breakpoint(R1, address); - sprintf(reply, "420 %X\r\n", code); - break; - case 0x321: - if (!arguments || sscanf(arguments, "%08X", &address) != 1) { - sprintf(reply, "500 Malformed 321 command '%s'\r\n", arguments); - break; - } - if ((address & 1) || (address < 0x80000000) || (address >= 0x80200000)) { - sprintf(reply, "532 Invalid address %08X\r\n", address); - break; - } - code = add_breakpoint(R2, address); - sprintf(reply, "421 %X\r\n", code); - break; - case 0x322: - if (!arguments || sscanf(arguments, "%08X", &address) != 1) { - sprintf(reply, "500 Malformed 322 command '%s'\r\n", arguments); - break; - } - if ((address & 3) || (address < 0x80000000) || (address >= 0x80200000)) { - sprintf(reply, "532 Invalid address %08X\r\n", address); - break; - } - code = add_breakpoint(R4, address); - sprintf(reply, "422 %X\r\n", code); - break; - case 0x330: - if (!arguments || sscanf(arguments, "%08X", &address) != 1) { - sprintf(reply, "500 Malformed 330 command '%s'\r\n", arguments); - break; - } - if ((address < 0x80000000) || (address >= 0x80200000)) { - sprintf(reply, "533 Invalid address %08X\r\n", address); - break; - } - code = add_breakpoint(W1, address); - sprintf(reply, "430 %X\r\n", code); - break; - case 0x331: - if (!arguments || sscanf(arguments, "%08X", &address) != 1) { - sprintf(reply, "500 Malformed 331 command '%s'\r\n", arguments); - break; - } - if ((address & 1) || (address < 0x80000000) || (address >= 0x80200000)) { - sprintf(reply, "533 Invalid address %08X\r\n", address); - break; - } - code = add_breakpoint(W2, address); - sprintf(reply, "431 %X\r\n", code); - break; - case 0x332: - if (!arguments || sscanf(arguments, "%08X", &address) != 1) { - sprintf(reply, "500 Malformed 332 command '%s'\r\n", arguments); - break; - } - if ((address & 3) || (address < 0x80000000) || (address >= 0x80200000)) { - sprintf(reply, "533 Invalid address %08X\r\n", address); - break; - } - code = add_breakpoint(W4, address); - sprintf(reply, "432 %X\r\n", code); - break; - case 0x390: - paused = 1; - sprintf(reply, "490 Paused\r\n"); - break; - case 0x391: - paused = 0; - sprintf(reply, "491 Resumed\r\n"); - break; - case 0x395: - p = arguments; - if (arguments) { - trace = strtol(arguments, &p, 10); - } - if (p == arguments) { - trace = 1; - } - paused = 0; - sprintf(reply, "495 Tracing\r\n"); - break; - case 0x398: - paused = 0; - trace = 0; - reset = 2; - sprintf(reply, "498 Soft resetting\r\n"); - break; - case 0x399: - paused = 0; - trace = 0; - reset = 1; - sprintf(reply, "499 Resetting\r\n"); - break; - default: - sprintf(reply, "500 Unknown command '%s'\r\n", cmd); - break; - } - WriteSocket(reply, strlen(reply)); - - if (dumping) { - WriteSocket(dump, size); - } - - if (save) { - free(save); - } - } -} - -void DebugCheckBP(u32 address, enum breakpoint_types type) { - breakpoint_t *bp; - char reply[512]; - - if (!debugger_active || reset) - return; - for (bp = first; bp; bp = next_breakpoint(bp)) { - if ((bp->type == type) && (bp->address == address)) { - sprintf(reply, "030 %X@%08X\r\n", bp->number, psxRegs.pc); - WriteSocket(reply, strlen(reply)); - paused = 1; - return; - } - } - if (breakmp_e && type == E) { - if (!IsMapMarked(address, MAP_EXEC)) { - sprintf(reply, "010 %08X@%08X\r\n", address, psxRegs.pc); - WriteSocket(reply, strlen(reply)); - paused = 1; - } - } - if (breakmp_r8 && type == R1) { - if (!IsMapMarked(address, MAP_R8)) { - sprintf(reply, "011 %08X@%08X\r\n", address, psxRegs.pc); - WriteSocket(reply, strlen(reply)); - paused = 1; - } - } - if (breakmp_r16 && type == R2) { - if (!IsMapMarked(address, MAP_R16)) { - sprintf(reply, "012 %08X@%08X\r\n", address, psxRegs.pc); - WriteSocket(reply, strlen(reply)); - paused = 1; - } - } - if (breakmp_r32 && type == R4) { - if (!IsMapMarked(address, MAP_R32)) { - sprintf(reply, "013 %08X@%08X\r\n", address, psxRegs.pc); - WriteSocket(reply, strlen(reply)); - paused = 1; - } - } - if (breakmp_w8 && type == W1) { - if (!IsMapMarked(address, MAP_W8)) { - sprintf(reply, "014 %08X@%08X\r\n", address, psxRegs.pc); - WriteSocket(reply, strlen(reply)); - paused = 1; - } - } - if (breakmp_w16 && type == W2) { - if (!IsMapMarked(address, MAP_W16)) { - sprintf(reply, "015 %08X@%08X\r\n", address, psxRegs.pc); - WriteSocket(reply, strlen(reply)); - paused = 1; - } - } - if (breakmp_w32 && type == W4) { - if (!IsMapMarked(address, MAP_W32)) { - sprintf(reply, "016 %08X@%08X\r\n", address, psxRegs.pc); - WriteSocket(reply, strlen(reply)); - paused = 1; - } - } - if (mapping_r8 && type == R1) MarkMap(address, MAP_R8); - if (mapping_r16 && type == R2) MarkMap(address, MAP_R16); - if (mapping_r32 && type == R4) MarkMap(address, MAP_R32); - if (mapping_w8 && type == W1) MarkMap(address, MAP_W8); - if (mapping_w16 && type == W2) MarkMap(address, MAP_W16); - if (mapping_w32 && type == W4) MarkMap(address, MAP_W32); - } +/* Pcsx - Pc Psx Emulator
+ * Copyright (C) 1999-2003 Pcsx Team
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see <http://www.gnu.org/licenses>.
+ */
+
+#include "psxcommon.h"
+#include "r3000a.h"
+#include "debug.h"
+#include "socket.h"
+
+/*
+PCSX Debug console protocol description, version 1.0
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Commands number are formatted using %03X (yes)
+Registers number are formatted using %02X.
+Breakpoints numbers are formatted using %X
+All other values are formatted using %08X, unless specified.
+
+
+Client inputs:
+~~~~~~~~~~~~~
+Basic commands (1xx):
+--------------------
+100 <message>
+ Sends a dumb message. Will be replied with a 200 reply, followed by the message.
+101
+ Gets PCSX version.
+102
+ Gets protocol version.
+103
+ Gets status
+110
+ Gets PC.
+111 [reg]
+ Gets GP register, or all, if no argument.
+112
+ Gets LO/HI registers.
+113 [reg]
+ Gets COP0 register, or all, if no argument.
+114 [reg]
+ Gets COP2 control register, or all, if no argument.
+115 [reg]
+ Gets COP2 data register, or all, if no argument.
+119 [pc]
+ Disassemble current PC, or given PC.
+121 <reg>=<value>
+ Sets a GP register. Will return a 221 message.
+122 <LO|HI>=<value>
+ Sets LO or HI register. Will return a 222 message.
+123 <reg>=<value>
+ Sets a COP0 register. Will return a 223 message.
+124 <reg>=<value>
+ Sets a COP2 control register. Will return a 224 message.
+125 <reg>=<value>
+ Sets a COP2 data register. Will return a 225 message.
+130 <size>@<addr>
+ Dumps a range of memory, of size bytes starting at addr.
+140 <size>@<addr>
+ Sets a range of memory, of size bytes starting at addr.
+ Will have to send immediately exactly size bytes afterward.
+150 [number]
+ Starts/reset mapping execution flow, or stop it if number = 0
+151 [number]
+ Starts/reset mapping read8 flow, or stop it if number = 0
+152 [number]
+ Starts/reset mapping read16 flow, or stop it if number = 0
+153 [number]
+ Starts/reset mapping read32 flow, or stop it if number = 0
+154 [number]
+ Starts/reset mapping write8 flow, or stop it if number = 0
+155 [number]
+ Starts/reset mapping write16 flow, or stop it if number = 0
+156 [number]
+ Starts/reset mapping write32 flow, or stop it if number = 0
+160 [number]
+ Breaks on map exec flow, or stop it if number = 0
+161 [number]
+ Breaks on map read8 flow, or stop it if number = 0
+162 [number]
+ Breaks on map read16 flow, or stop it if number = 0
+163 [number]
+ Breaks on map read32 flow, or stop it if number = 0
+164 [number]
+ Breaks on map write8 flow, or stop it if number = 0
+165 [number]
+ Breaks on map write16 flow, or stop it if number = 0
+166 [number]
+ Breaks on map write32 flow, or stop it if number = 0
+170
+ Dumps the execution flow map in an IDC file
+
+Execution flow control commands (3xx):
+-------------------------------------
+300 [number]
+ Get a list of the actual breakpoints. Will get '400' answers.
+301 [number]
+ Deletes a breakpoint, or all, if no arguments.
+310 <address>
+ Sets an exec breakpoint.
+320 <address>
+ Sets a read breakpoint, 1 byte / 8 bits.
+321 <address>
+ Sets a read breakpoint, 2 bytes / 16 bits, has to be on an even address.
+322 <address>
+ Sets a read breakpoint, 4 bytes / 32 bits, address has to be 4-bytes aligned.
+330 <address>
+ Sets a write breakpoint, 1 byte / 8 bits.
+331 <address>
+ Sets a write breakpoint, 2 bytes / 16 bits, has to be on an even address.
+332 <address>
+ Sets a write breakpoint, 4 bytes / 32 bits, address has to be 4-bytes aligned.
+390
+ Pauses execution. Equivalents to a breakpoint.
+391
+ Restarts execution.
+395 [number]
+ Traces execution, 1 instruction by default. Formatted using %i
+398
+ Soft (quick) resets.
+399
+ Resets.
+
+
+Server outputs:
+~~~~~~~~~~~~~~
+Spontaneous messages (0xx):
+--------------------------
+000 <message>
+ Greeting banner.
+010 / 011 / 012 / 013 / 014 / 015 / 016
+ Execution hit mapping flow automatic breakpoint.
+030 <number>@<PC>
+ Execution hit breakpoint, PCSX is paused. Displays PC's value.
+
+Basic commands acknowledge (2xx):
+--------------------------------
+200 <message>
+ Sends a dumb message.
+201 <message>
+ Returns PCSX version.
+202 <message>
+ Returns protocol version.
+203 <status>
+ status = 0: running; = 1: paused; = 2: trace
+210 PC=<value>
+ Displays current PC value.
+211 <reg>=<value>
+ Displays one GP register value.
+212 LO=<value> HI=<value>
+ Displays LO/HI registers.
+213 <reg>=<value>
+ Displays one COP0 register value.
+214 <reg>=<value>
+ Displays one COP2 control register value.
+215 <reg>=<value>
+ Displays one COP2 data register value.
+219 <message>
+ Displays one line of disassembled code.
+221 <reg>=<value>
+ Displays one GP register value, ack for modification.
+222 LO=<value> HI=<value>
+ Displays LO/HI registers, ack for modification.
+223 <reg>=<value>
+ Displays one COP0 register value, ack for modification.
+224 <reg>=<value>
+ Displays one COP2 control register value, ack for modification.
+225 <reg>=<value>
+ Displays one COP2 data register value, ack for modification.
+230 <size>@<addr>
+ Dumping memory. Will then raw outputs size bytes.
+240 <size>@<addr>
+ Memory set acknowledge.
+250 / 251 / 252 / 253 / 254 / 255 / 256
+ Acknolwedge of 15x commands.
+260 / 261 / 262 / 263 / 264 / 265 / 266
+ Acknolwedge of 16x commands.
+270
+ Acknolwedge of 170 command.
+
+Execution flow control commands acknowledge (4xx):
+-------------------------------------------------
+400 <number>@<address>-<type>
+ Displays a breakpoint, where 'type' can be of E, R1, R2, R4, W1, W2 or W4.
+401 <message>
+ Breakpoint deleting acknowledge.
+410, 420, 421, 422, 430, 431, 432 <number>
+ Breakpoint adding acknowledge. Returns the number of the added breakpoint.
+490 <message>
+ Pausing.
+491 <message>
+ Resuming.
+495 <message>
+ Tracing.
+498 <message>
+ Soft resetting.
+499 <message>
+ Resetting.
+
+Error messages (5xx):
+--------------------
+500 <message>
+ Command not understood.
+511 <message>
+ Invalid GPR register.
+512 <message>
+ Invalid LO/HI register.
+513, 514 <message>
+ Invalid range or address.
+530 <message>
+ Non existant breakpoint.
+531, 532, 533 <message>
+ Invalid breakpoint address.
+*/
+
+static int debugger_active = 0, paused = 0, trace = 0, reset = 0, resetting = 0;
+static int mapping_e = 0, mapping_r8 = 0, mapping_r16 = 0, mapping_r32 = 0, mapping_w8 = 0, mapping_w16 = 0, mapping_w32 = 0;
+static int breakmp_e = 0, breakmp_r8 = 0, breakmp_r16 = 0, breakmp_r32 = 0, breakmp_w8 = 0, breakmp_w16 = 0, breakmp_w32 = 0;
+
+static void ProcessCommands();
+
+static u8 *MemoryMap = NULL;
+
+enum {
+ MAP_EXEC = 1,
+ MAP_R8 = 2,
+ MAP_R16 = 4,
+ MAP_R32 = 8,
+ MAP_W8 = 16,
+ MAP_W16 = 32,
+ MAP_W32 = 64,
+ MAP_EXEC_JAL = 128,
+};
+
+char *breakpoint_type_names[] = {
+ "E", "R1", "R2", "R4", "W1", "W2", "W4"
+};
+
+typedef struct breakpoint_s {
+ struct breakpoint_s *next, *prev;
+ int number, type;
+ u32 address;
+} breakpoint_t;
+
+static breakpoint_t *first = NULL;
+
+int add_breakpoint(int type, u32 address) {
+ breakpoint_t *bp = (breakpoint_t *)malloc(sizeof(breakpoint_t));
+
+ bp->type = type;
+ bp->address = address;
+
+ if (first) {
+ bp->number = first->prev->number + 1;
+ bp->next = first;
+ bp->prev = first->prev;
+ first->prev = bp;
+ bp->prev->next = bp;
+ } else {
+ first = bp;
+ bp->number = 1;
+ bp->next = bp;
+ bp->prev = bp;
+ }
+
+ return bp->number;
+}
+
+void delete_breakpoint(breakpoint_t * bp) {
+ if (bp == first) {
+ if (bp->next == bp) {
+ first = NULL;
+ } else {
+ first = bp->next;
+ }
+ }
+
+ bp->next->prev = bp->prev;
+ bp->prev->next = bp->next;
+
+ free(bp);
+}
+
+breakpoint_t *next_breakpoint(breakpoint_t *bp) {
+ return bp->next != first ? bp->next : 0;
+}
+
+breakpoint_t *find_breakpoint(int number) {
+ breakpoint_t *p;
+
+ for (p = first; p; p = next_breakpoint(p)) {
+ if (p->number == number)
+ return p;
+ }
+
+ return 0;
+}
+
+void StartDebugger() {
+ if (debugger_active)
+ return;
+
+ MemoryMap = (u8 *)malloc(0x200000);
+ if (MemoryMap == NULL) {
+ SysMessage(_("Error allocating memory"));
+ return;
+ }
+
+ if (StartServer() == -1) {
+ SysPrintf(_("Unable to start debug server.\n"));
+ return;
+ }
+
+ SysPrintf(_("Debugger started.\n"));
+ debugger_active = 1;
+}
+
+void StopDebugger() {
+ if (debugger_active) {
+ StopServer();
+ SysPrintf(_("Debugger stopped.\n"));
+ }
+
+ if (MemoryMap != NULL) {
+ free(MemoryMap);
+ MemoryMap = NULL;
+ }
+
+ while (first != NULL) delete_breakpoint(first);
+
+ debugger_active = 0;
+}
+
+void PauseDebugger() {
+ trace = 0;
+ paused = 1;
+}
+
+void ResumeDebugger() {
+ trace = 0;
+ paused = 0;
+}
+
+void DebugVSync() {
+ if (!debugger_active || resetting)
+ return;
+
+ if (reset) {
+ resetting = 1;
+ CheckCdrom();
+ SysReset();
+ if (reset == 2)
+ LoadCdrom();
+ reset = resetting = 0;
+ return;
+ }
+
+ GetClient();
+ ProcessCommands();
+}
+
+void MarkMap(u32 address, int mask) {
+ if ((address & 0xff000000) != 0x80000000) return;
+ MemoryMap[address & 0x001fffff] |= mask;
+}
+
+int IsMapMarked(u32 address, int mask) {
+ return (MemoryMap[address & 0x001fffff] & mask) != 0;
+}
+
+void ProcessDebug() {
+ if (!debugger_active || reset || resetting)
+ return;
+ if (trace) {
+ if (!(--trace)) {
+ paused = 1;
+ }
+ }
+ if (!paused) {
+ DebugCheckBP(psxRegs.pc, E);
+ }
+ if (mapping_e) {
+ MarkMap(psxRegs.pc, MAP_EXEC);
+ if ((psxRegs.code >> 26) == 3) {
+ MarkMap(_JumpTarget_, MAP_EXEC_JAL);
+ }
+ if (((psxRegs.code >> 26) == 0) && ((psxRegs.code && 0x3F) == 9)) {
+ MarkMap(_Rd_, MAP_EXEC_JAL);
+ }
+ }
+ while (paused) {
+ GetClient();
+ ProcessCommands();
+ GPU_updateLace();
+ SysUpdate();
+ }
+}
+
+static void ProcessCommands() {
+ int code, i, dumping;
+ FILE *sfile;
+ char cmd[257], *arguments, *p, reply[10240], *save, *dump;
+ u32 reg, value, size, address;
+ breakpoint_t *bp;
+
+ if (!HasClient())
+ return;
+ if (ReadSocket(cmd, 256) > 0) {
+ arguments = NULL;
+ if (strlen(cmd) <= 2) {
+ code = 0;
+ } else if (strlen(cmd) == 3) {
+ code = strtol(cmd, 0, 16);
+ } else if (!(isxdigit(cmd[0]) && isxdigit(cmd[1]) && isxdigit(cmd[2]) && (cmd[3] == 0x20))) {
+ code = 0;
+ } else if (sscanf(cmd, "%3X ", &code) != 1) {
+ code = 0;
+ } else {
+ arguments = cmd + 4;
+ }
+ code = strtol(cmd, &arguments, 16);
+ while (arguments && *arguments && *arguments == 0x20)
+ arguments++;
+
+ if (*arguments == '\0')
+ arguments = NULL;
+
+ dumping = 0;
+ save = NULL;
+
+ switch (code) {
+ case 0x100:
+ sprintf(reply, "200 %s\r\n", arguments == NULL ? "OK" : arguments);
+ break;
+ case 0x101:
+ sprintf(reply, "201 %s\r\n", PACKAGE_VERSION);
+ break;
+ case 0x102:
+ sprintf(reply, "202 1.0\r\n");
+ break;
+ case 0x103:
+ sprintf(reply, "203 %i\r\n", paused ? 1 : trace ? 2 : 0);
+ break;
+ case 0x110:
+ sprintf(reply, "210 PC=%08X\r\n", psxRegs.pc);
+ break;
+ case 0x111:
+ if (arguments) {
+ if (sscanf(arguments, "%02X", &code) != 1) {
+ sprintf(reply, "511 Malformed 111 command '%s'\r\n", cmd);
+ break;
+ }
+ }
+ if (!arguments) {
+ reply[0] = 0;
+ for (i = 0; i < 32; i++) {
+ sprintf(reply, "%s211 %02X=%08X\r\n", reply, i, psxRegs.GPR.r[i]);
+ }
+ } else {
+ if ((code >= 0) && (code < 32)) {
+ sprintf(reply, "211 %02X=%08X\r\n", code, psxRegs.GPR.r[code]);
+ } else {
+ sprintf(reply, "511 Invalid GPR register: %X\r\n", code);
+ }
+ }
+ break;
+ case 0x112:
+ sprintf(reply, "212 LO=%08X HI=%08X\r\n", psxRegs.GPR.n.lo, psxRegs.GPR.n.hi);
+ break;
+ case 0x113:
+ if (arguments) {
+ if (sscanf(arguments, "%02X", &code) != 1) {
+ sprintf(reply, "511 Malformed 113 command '%s'\r\n", cmd);
+ break;
+ }
+ }
+ if (!arguments) {
+ reply[0] = 0;
+ for (i = 0; i < 32; i++) {
+ sprintf(reply, "%s213 %02X=%08X\r\n", reply, i, psxRegs.CP0.r[i]);
+ }
+ } else {
+ if ((code >= 0) && (code < 32)) {
+ sprintf(reply, "213 %02X=%08X\r\n", code, psxRegs.CP0.r[code]);
+ } else {
+ sprintf(reply, "511 Invalid COP0 register: %X\r\n", code);
+ }
+ }
+ break;
+ case 0x114:
+ if (arguments) {
+ if (sscanf(arguments, "%02X", &code) != 1) {
+ sprintf(reply, "511 Malformed 114 command '%s'\r\n", cmd);
+ break;
+ }
+ }
+ if (!arguments) {
+ reply[0] = 0;
+ for (i = 0; i < 32; i++) {
+ sprintf(reply, "%s214 %02X=%08X\r\n", reply, i, psxRegs.CP2C.r[i]);
+ }
+ } else {
+ if ((code >= 0) && (code < 32)) {
+ sprintf(reply, "214 %02X=%08X\r\n", code, psxRegs.CP2C.r[code]);
+ } else {
+ sprintf(reply, "511 Invalid COP2C register: %X\r\n", code);
+ }
+ }
+ break;
+ case 0x115:
+ if (arguments) {
+ if (sscanf(arguments, "%02X", &code) != 1) {
+ sprintf(reply, "511 Malformed 111 command '%s'\r\n", cmd);
+ break;
+ }
+ }
+ if (!arguments) {
+ reply[0] = 0;
+ for (i = 0; i < 32; i++) {
+ sprintf(reply, "%s215 %02X=%08X\r\n", reply, i, psxRegs.CP2D.r[i]);
+ }
+ } else {
+ if ((code >= 0) && (code < 32)) {
+ sprintf(reply, "215 %02X=%08X\r\n", code, psxRegs.CP2D.r[code]);
+ } else {
+ sprintf(reply, "511 Invalid COP2D register: %X\r\n", code);
+ }
+ }
+ break;
+ case 0x119:
+ if (arguments) {
+ if (sscanf(arguments, "%08X", &code) != 1) {
+ sprintf(reply, "511 Malformed 119 command '%s'\r\n", cmd);
+ break;
+ }
+ }
+ if (!arguments)
+ code = psxRegs.pc;
+
+ sprintf(reply, "219 %s\r\n", disR3000AF(psxMemRead32(code), code));
+ break;
+ case 0x121:
+ if (!arguments || sscanf(arguments, "%02X=%08X", ®, &value) != 2) {
+ sprintf(reply, "500 Malformed 121 command '%s'\r\n", arguments);
+ break;
+ }
+
+ if (reg < 32) {
+ psxRegs.GPR.r[reg] = value;
+ sprintf(reply, "221 %02X=%08X\r\n", reg, value);
+ } else {
+ sprintf(reply, "512 Invalid GPR register: %02X\r\n", reg);
+ }
+ break;
+ case 0x122:
+ if (!arguments || strncmp(arguments, "HI=", 3) == 0) {
+ reg = 33;
+ } else if (arguments && strncmp(arguments, "LO=", 3) == 0) {
+ reg = 32;
+ } else {
+ arguments[2] = 0;
+ sprintf(reply, "512 Invalid LO/HI register: '%s'\r\n", arguments);
+ break;
+ }
+
+ if (sscanf(arguments + 3, "%08X", &value) != 1) {
+ sprintf(reply, "500 Malformed 122 command '%s'\r\n", arguments);
+ } else {
+ psxRegs.GPR.r[reg] = value;
+ sprintf(reply, "222 LO=%08X HI=%08X\r\n", psxRegs.GPR.n.lo, psxRegs.GPR.n.hi);
+ }
+ break;
+ case 0x123:
+ if (!arguments || sscanf(arguments, "%02X=%08X", ®, &value) != 2) {
+ sprintf(reply, "500 Malformed 123 command '%s'\r\n", arguments);
+ break;
+ }
+
+ if (reg < 32) {
+ psxRegs.CP0.r[reg] = value;
+ sprintf(reply, "223 %02X=%08X\r\n", reg, value);
+ } else {
+ sprintf(reply, "512 Invalid COP0 register: %02X\r\n", reg);
+ }
+ break;
+ case 0x124:
+ if (!arguments || sscanf(arguments, "%02X=%08X", ®, &value) != 2) {
+ sprintf(reply, "500 Malformed 124 command '%s'\r\n", arguments);
+ break;
+ }
+
+ if (reg < 32) {
+ psxRegs.CP2C.r[reg] = value;
+ sprintf(reply, "224 %02X=%08X\r\n", reg, value);
+ } else {
+ sprintf(reply, "512 Invalid COP2C register: %02X\r\n", reg);
+ }
+ break;
+ case 0x125:
+ if (!arguments || sscanf(arguments, "%02X=%08X", ®, &value) != 2) {
+ sprintf(reply, "500 Malformed 121 command '%s'\r\n", arguments);
+ break;
+ }
+
+ if (reg < 32) {
+ psxRegs.CP2D.r[reg] = value;
+ sprintf(reply, "225 %02X=%08X\r\n", reg, value);
+ } else {
+ sprintf(reply, "512 Invalid COP2D register: %02X\r\n", reg);
+ }
+ break;
+ case 0x130:
+ if (!arguments || sscanf(arguments, "%08X@%08X", &size, &address) != 2) {
+ sprintf(reply, "500 Malformed 130 command '%s'\r\n", arguments);
+ break;
+ }
+
+ if ((address >= 0x80000000) && ((address + size) <= 0x80200000)) {
+ sprintf(reply, "230 %08X@%08X\r\n", size, address);
+ dump = (char *) PSXM(address);
+ dumping = 1;
+ } else {
+ sprintf(reply, "513 Invalid address or range: '%s'\r\n", arguments);
+ }
+ break;
+ case 0x140:
+ if (!arguments || sscanf(arguments, "%08X@%08X", &size, &address) != 2) {
+ sprintf(reply, "500 Malformed 140 command '%s'\r\n", arguments);
+ break;
+ }
+
+ if ((address >= 0x80000000) && ((address + size) <= 0x80200000)) {
+ sprintf(reply, "240 %08X@%08X\r\n", size, address);
+ RawReadSocket((char *)PSXM(address), size);
+ } else {
+ sprintf(reply, "514 Invalid address or range: '%s'\r\n", arguments);
+ }
+ break;
+ case 0x150:
+ code = 1;
+ if (arguments) {
+ if (sscanf(arguments, "%02X", &code) != 1) {
+ sprintf(reply, "500 Malformed 150 command '%s'\r\n", cmd);
+ break;
+ }
+ }
+ if (code) {
+ mapping_e = 1;
+ for (i = 0; i < 0x00200000; i++) {
+ MemoryMap[i] &= ~MAP_EXEC;
+ MemoryMap[i] &= ~MAP_EXEC_JAL;
+ }
+ } else {
+ mapping_e = 0;
+ }
+ sprintf(reply, "250 Mapping of exec flow %s\r\n", code ? "started" : "stopped");
+ break;
+ case 0x151:
+ code = 1;
+ if (arguments) {
+ if (sscanf(arguments, "%02X", &code) != 1) {
+ sprintf(reply, "500 Malformed 151 command '%s'\r\n", cmd);
+ break;
+ }
+ }
+ if (code) {
+ mapping_r8 = 1;
+ for (i = 0; i < 0x00200000; i++) {
+ MemoryMap[i] &= ~MAP_R8;
+ }
+ } else {
+ mapping_r8 = 0;
+ }
+ sprintf(reply, "251 Mapping of read8 flow %s\r\n", code ? "started" : "stopped");
+ break;
+ case 0x152:
+ code = 1;
+ if (arguments) {
+ if (sscanf(arguments, "%02X", &code) != 1) {
+ sprintf(reply, "500 Malformed 152 command '%s'\r\n", cmd);
+ break;
+ }
+ }
+ if (code) {
+ mapping_r16 = 1;
+ for (i = 0; i < 0x00200000; i++) {
+ MemoryMap[i] &= ~MAP_R16;
+ }
+ } else {
+ mapping_r16 = 0;
+ }
+ sprintf(reply, "252 Mapping of read16 flow %s\r\n", code ? "started" : "stopped");
+ break;
+ case 0x153:
+ code = 1;
+ if (arguments) {
+ if (sscanf(arguments, "%02X", &code) != 1) {
+ sprintf(reply, "500 Malformed 153 command '%s'\r\n", cmd);
+ break;
+ }
+ }
+ if (code) {
+ mapping_r32 = 1;
+ for (i = 0; i < 0x00200000; i++) {
+ MemoryMap[i] &= ~MAP_R32;
+ }
+ } else {
+ mapping_r32 = 0;
+ }
+ sprintf(reply, "253 Mapping of read32 flow %s\r\n", code ? "started" : "stopped");
+ break;
+ case 0x154:
+ code = 1;
+ if (arguments) {
+ if (sscanf(arguments, "%02X", &code) != 1) {
+ sprintf(reply, "500 Malformed 154 command '%s'\r\n", cmd);
+ break;
+ }
+ }
+ if (code) {
+ mapping_w8 = 1;
+ for (i = 0; i < 0x00200000; i++) {
+ MemoryMap[i] &= ~MAP_W8;
+ }
+ } else {
+ mapping_w8 = 0;
+ }
+ sprintf(reply, "254 Mapping of write8 flow %s\r\n", code ? "started" : "stopped");
+ break;
+ case 0x155:
+ code = 1;
+ if (arguments) {
+ if (sscanf(arguments, "%02X", &code) != 1) {
+ sprintf(reply, "500 Malformed 155 command '%s'\r\n", cmd);
+ break;
+ }
+ }
+ if (code) {
+ mapping_w16 = 1;
+ for (i = 0; i < 0x00200000; i++) {
+ MemoryMap[i] &= ~MAP_W16;
+ }
+ } else {
+ mapping_w16 = 0;
+ }
+ sprintf(reply, "255 Mapping of write16 flow %s\r\n", code ? "started" : "stopped");
+ break;
+ case 0x156:
+ code = 1;
+ if (arguments) {
+ if (sscanf(arguments, "%02X", &code) != 1) {
+ sprintf(reply, "500 Malformed 156 command '%s'\r\n", cmd);
+ break;
+ }
+ }
+ if (code) {
+ mapping_w32 = 1;
+ for (i = 0; i < 0x00200000; i++) {
+ MemoryMap[i] &= ~MAP_W32;
+ }
+ } else {
+ mapping_w32 = 0;
+ }
+ sprintf(reply, "256 Mapping of write32 flow %s\r\n", code ? "started" : "stopped");
+ break;
+ case 0x160:
+ code = 1;
+ if (arguments) {
+ if (sscanf(arguments, "%02X", &code) != 1) {
+ sprintf(reply, "500 Malformed 160 command '%s'\r\n", cmd);
+ break;
+ }
+ }
+ if (code) {
+ breakmp_e = 1;
+ } else {
+ breakmp_e = 0;
+ }
+ sprintf(reply, "260 Break on map of exec flow %s\r\n", code ? "started" : "stopped");
+ break;
+ case 0x161:
+ code = 1;
+ if (arguments) {
+ if (sscanf(arguments, "%02X", &code) != 1) {
+ sprintf(reply, "500 Malformed 161 command '%s'\r\n", cmd);
+ break;
+ }
+ }
+ if (code) {
+ breakmp_r8 = 1;
+ } else {
+ breakmp_r8 = 0;
+ }
+ sprintf(reply, "261 Break on map of read8 flow %s\r\n", code ? "started" : "stopped");
+ break;
+ case 0x162:
+ code = 1;
+ if (arguments) {
+ if (sscanf(arguments, "%02X", &code) != 1) {
+ sprintf(reply, "500 Malformed 162 command '%s'\r\n", cmd);
+ break;
+ }
+ }
+ if (code) {
+ breakmp_r16 = 1;
+ } else {
+ breakmp_r16 = 0;
+ }
+ sprintf(reply, "262 Break on map of read16 flow %s\r\n", code ? "started" : "stopped");
+ break;
+ case 0x163:
+ code = 1;
+ if (arguments) {
+ if (sscanf(arguments, "%02X", &code) != 1) {
+ sprintf(reply, "500 Malformed 163 command '%s'\r\n", cmd);
+ break;
+ }
+ }
+ if (code) {
+ breakmp_r32 = 1;
+ } else {
+ breakmp_r32 = 0;
+ }
+ sprintf(reply, "263 Break on map of read32 flow %s\r\n", code ? "started" : "stopped");
+ break;
+ case 0x164:
+ code = 1;
+ if (arguments) {
+ if (sscanf(arguments, "%02X", &code) != 1) {
+ sprintf(reply, "500 Malformed 164 command '%s'\r\n", cmd);
+ break;
+ }
+ }
+ if (code) {
+ breakmp_w8 = 1;
+ } else {
+ breakmp_w8 = 0;
+ }
+ sprintf(reply, "264 Break on map of write8 flow %s\r\n", code ? "started" : "stopped");
+ break;
+ case 0x165:
+ code = 1;
+ if (arguments) {
+ if (sscanf(arguments, "%02X", &code) != 1) {
+ sprintf(reply, "500 Malformed 165 command '%s'\r\n", cmd);
+ break;
+ }
+ }
+ if (code) {
+ breakmp_w16 = 1;
+ } else {
+ breakmp_w16 = 0;
+ }
+ sprintf(reply, "265 Break on map of write16 flow %s\r\n", code ? "started" : "stopped");
+ break;
+ case 0x166:
+ code = 1;
+ if (arguments) {
+ if (sscanf(arguments, "%02X", &code) != 1) {
+ sprintf(reply, "500 Malformed 166 command '%s'\r\n", cmd);
+ break;
+ }
+ }
+ if (code) {
+ breakmp_w32 = 1;
+ } else {
+ breakmp_w32 = 0;
+ }
+ sprintf(reply, "266 Break on map of write32 flow %s\r\n", code ? "started" : "stopped");
+ break;
+ case 0x170:
+ sfile = fopen("flow.idc", "wb");
+ fprintf(sfile, "#include <idc.idc>\r\n\r\n");
+ fprintf(sfile, "static main(void) {\r\n");
+ for (i = 0; i < 0x00200000; i++) {
+ if (IsMapMarked(i, MAP_EXEC_JAL)) {
+ fprintf(sfile, "\tMakeFunction(0X8%07X,BADADDR);\r\n", i);
+ }
+ }
+ fprintf(sfile, "}\r\n");
+ fclose(sfile);
+ sfile = fopen("markcode.idc", "wb");
+ fprintf(sfile, "#include <idc.idc>\r\n\r\n");
+ fprintf(sfile, "static main(void) {\r\n");
+ for (i = 0; i < 0x00200000; i++) {
+ if (IsMapMarked(i, MAP_EXEC)) {
+ fprintf(sfile, "\tMakeCode(0X8%07X);\r\n", i);
+ }
+ }
+ fprintf(sfile, "}\r\n");
+ fclose(sfile);
+ sprintf(reply, "270 flow.idc and markcode.idc dumped\r\n");
+ break;
+ case 0x300:
+ p = arguments;
+ if (arguments) {
+ code = strtol(arguments, &p, 16);
+ }
+ if (p == arguments) {
+ if (first) {
+ reply[0] = 0;
+ for (bp = first; bp; bp = next_breakpoint(bp)) {
+ sprintf(reply, "%s400 %X@%08X-%s\r\n", reply, bp->number, bp->address, breakpoint_type_names[bp->type]);
+ }
+ } else {
+ sprintf(reply, "530 No breakpoint\r\n");
+ }
+ } else {
+ if ((bp = find_breakpoint(code))) {
+ sprintf(reply, "400 %X@%08X-%s\r\n", bp->number, bp->address, breakpoint_type_names[bp->type]);
+ } else {
+ sprintf(reply, "530 Invalid breakpoint number: %X\r\n", code);
+ }
+ }
+ break;
+ case 0x301:
+ p = arguments;
+ if (arguments) {
+ code = strtol(arguments, &p, 16);
+ }
+ if (p == arguments) {
+ while (first != NULL) delete_breakpoint(first);
+ sprintf(reply, "401 All breakpoints deleted.\r\n");
+ } else {
+ if ((bp = find_breakpoint(code))) {
+ delete_breakpoint(bp);
+ sprintf(reply, "401 Breakpoint %X deleted.\r\n", code);
+ } else {
+ sprintf(reply, "530 Invalid breakpoint number: %X\r\n", code);
+ }
+ }
+ break;
+ case 0x310:
+ if (!arguments || sscanf(arguments, "%08X", &address) != 1) {
+ sprintf(reply, "500 Malformed 310 command '%s'\r\n", arguments);
+ break;
+ }
+// if ((address & 3) || (address < 0x80000000) || (address >= 0x80200000)) {
+// sprintf(reply, "531 Invalid address %08X\r\n", address);
+// break;
+// }
+ code = add_breakpoint(E, address);
+ sprintf(reply, "410 %X\r\n", code);
+ break;
+ case 0x320:
+ if (!arguments || sscanf(arguments, "%08X", &address) != 1) {
+ sprintf(reply, "500 Malformed 320 command '%s'\r\n", arguments);
+ break;
+ }
+ if ((address < 0x80000000) || (address >= 0x80200000)) {
+ sprintf(reply, "532 Invalid address %08X\r\n", address);
+ break;
+ }
+ code = add_breakpoint(R1, address);
+ sprintf(reply, "420 %X\r\n", code);
+ break;
+ case 0x321:
+ if (!arguments || sscanf(arguments, "%08X", &address) != 1) {
+ sprintf(reply, "500 Malformed 321 command '%s'\r\n", arguments);
+ break;
+ }
+ if ((address & 1) || (address < 0x80000000) || (address >= 0x80200000)) {
+ sprintf(reply, "532 Invalid address %08X\r\n", address);
+ break;
+ }
+ code = add_breakpoint(R2, address);
+ sprintf(reply, "421 %X\r\n", code);
+ break;
+ case 0x322:
+ if (!arguments || sscanf(arguments, "%08X", &address) != 1) {
+ sprintf(reply, "500 Malformed 322 command '%s'\r\n", arguments);
+ break;
+ }
+ if ((address & 3) || (address < 0x80000000) || (address >= 0x80200000)) {
+ sprintf(reply, "532 Invalid address %08X\r\n", address);
+ break;
+ }
+ code = add_breakpoint(R4, address);
+ sprintf(reply, "422 %X\r\n", code);
+ break;
+ case 0x330:
+ if (!arguments || sscanf(arguments, "%08X", &address) != 1) {
+ sprintf(reply, "500 Malformed 330 command '%s'\r\n", arguments);
+ break;
+ }
+ if ((address < 0x80000000) || (address >= 0x80200000)) {
+ sprintf(reply, "533 Invalid address %08X\r\n", address);
+ break;
+ }
+ code = add_breakpoint(W1, address);
+ sprintf(reply, "430 %X\r\n", code);
+ break;
+ case 0x331:
+ if (!arguments || sscanf(arguments, "%08X", &address) != 1) {
+ sprintf(reply, "500 Malformed 331 command '%s'\r\n", arguments);
+ break;
+ }
+ if ((address & 1) || (address < 0x80000000) || (address >= 0x80200000)) {
+ sprintf(reply, "533 Invalid address %08X\r\n", address);
+ break;
+ }
+ code = add_breakpoint(W2, address);
+ sprintf(reply, "431 %X\r\n", code);
+ break;
+ case 0x332:
+ if (!arguments || sscanf(arguments, "%08X", &address) != 1) {
+ sprintf(reply, "500 Malformed 332 command '%s'\r\n", arguments);
+ break;
+ }
+ if ((address & 3) || (address < 0x80000000) || (address >= 0x80200000)) {
+ sprintf(reply, "533 Invalid address %08X\r\n", address);
+ break;
+ }
+ code = add_breakpoint(W4, address);
+ sprintf(reply, "432 %X\r\n", code);
+ break;
+ case 0x390:
+ paused = 1;
+ sprintf(reply, "490 Paused\r\n");
+ break;
+ case 0x391:
+ paused = 0;
+ sprintf(reply, "491 Resumed\r\n");
+ break;
+ case 0x395:
+ p = arguments;
+ if (arguments) {
+ trace = strtol(arguments, &p, 10);
+ }
+ if (p == arguments) {
+ trace = 1;
+ }
+ paused = 0;
+ sprintf(reply, "495 Tracing\r\n");
+ break;
+ case 0x398:
+ paused = 0;
+ trace = 0;
+ reset = 2;
+ sprintf(reply, "498 Soft resetting\r\n");
+ break;
+ case 0x399:
+ paused = 0;
+ trace = 0;
+ reset = 1;
+ sprintf(reply, "499 Resetting\r\n");
+ break;
+ default:
+ sprintf(reply, "500 Unknown command '%s'\r\n", cmd);
+ break;
+ }
+ WriteSocket(reply, strlen(reply));
+
+ if (dumping) {
+ WriteSocket(dump, size);
+ }
+
+ if (save) {
+ free(save);
+ }
+ }
+}
+
+void DebugCheckBP(u32 address, enum breakpoint_types type) {
+ breakpoint_t *bp;
+ char reply[512];
+
+ if (!debugger_active || reset)
+ return;
+ for (bp = first; bp; bp = next_breakpoint(bp)) {
+ if ((bp->type == type) && (bp->address == address)) {
+ sprintf(reply, "030 %X@%08X\r\n", bp->number, psxRegs.pc);
+ WriteSocket(reply, strlen(reply));
+ paused = 1;
+ return;
+ }
+ }
+ if (breakmp_e && type == E) {
+ if (!IsMapMarked(address, MAP_EXEC)) {
+ sprintf(reply, "010 %08X@%08X\r\n", address, psxRegs.pc);
+ WriteSocket(reply, strlen(reply));
+ paused = 1;
+ }
+ }
+ if (breakmp_r8 && type == R1) {
+ if (!IsMapMarked(address, MAP_R8)) {
+ sprintf(reply, "011 %08X@%08X\r\n", address, psxRegs.pc);
+ WriteSocket(reply, strlen(reply));
+ paused = 1;
+ }
+ }
+ if (breakmp_r16 && type == R2) {
+ if (!IsMapMarked(address, MAP_R16)) {
+ sprintf(reply, "012 %08X@%08X\r\n", address, psxRegs.pc);
+ WriteSocket(reply, strlen(reply));
+ paused = 1;
+ }
+ }
+ if (breakmp_r32 && type == R4) {
+ if (!IsMapMarked(address, MAP_R32)) {
+ sprintf(reply, "013 %08X@%08X\r\n", address, psxRegs.pc);
+ WriteSocket(reply, strlen(reply));
+ paused = 1;
+ }
+ }
+ if (breakmp_w8 && type == W1) {
+ if (!IsMapMarked(address, MAP_W8)) {
+ sprintf(reply, "014 %08X@%08X\r\n", address, psxRegs.pc);
+ WriteSocket(reply, strlen(reply));
+ paused = 1;
+ }
+ }
+ if (breakmp_w16 && type == W2) {
+ if (!IsMapMarked(address, MAP_W16)) {
+ sprintf(reply, "015 %08X@%08X\r\n", address, psxRegs.pc);
+ WriteSocket(reply, strlen(reply));
+ paused = 1;
+ }
+ }
+ if (breakmp_w32 && type == W4) {
+ if (!IsMapMarked(address, MAP_W32)) {
+ sprintf(reply, "016 %08X@%08X\r\n", address, psxRegs.pc);
+ WriteSocket(reply, strlen(reply));
+ paused = 1;
+ }
+ }
+ if (mapping_r8 && type == R1) MarkMap(address, MAP_R8);
+ if (mapping_r16 && type == R2) MarkMap(address, MAP_R16);
+ if (mapping_r32 && type == R4) MarkMap(address, MAP_R32);
+ if (mapping_w8 && type == W1) MarkMap(address, MAP_W8);
+ if (mapping_w16 && type == W2) MarkMap(address, MAP_W16);
+ if (mapping_w32 && type == W4) MarkMap(address, MAP_W32);
+ }
|
