1 /* Pcsx - Pc Psx Emulator
2 * Copyright (C) 1999-2003 Pcsx Team
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, see <http://www.gnu.org/licenses>.
18 #include "psxcommon.h"
24 PCSX Debug console protocol description, version 1.0
25 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
27 Commands number are formatted using %03X (yes)
28 Registers number are formatted using %02X.
29 Breakpoints numbers are formatted using %X
30 All other values are formatted using %08X, unless specified.
38 Sends a dumb message. Will be replied with a 200 reply, followed by the message.
42 Gets protocol version.
48 Gets GP register, or all, if no argument.
52 Gets COP0 register, or all, if no argument.
54 Gets COP2 control register, or all, if no argument.
56 Gets COP2 data register, or all, if no argument.
58 Disassemble current PC, or given PC.
60 Sets a GP register. Will return a 221 message.
62 Sets LO or HI register. Will return a 222 message.
64 Sets a COP0 register. Will return a 223 message.
66 Sets a COP2 control register. Will return a 224 message.
68 Sets a COP2 data register. Will return a 225 message.
70 Dumps a range of memory, of size bytes starting at addr.
72 Sets a range of memory, of size bytes starting at addr.
73 Will have to send immediately exactly size bytes afterward.
75 Starts/reset mapping execution flow, or stop it if number = 0
77 Starts/reset mapping read8 flow, or stop it if number = 0
79 Starts/reset mapping read16 flow, or stop it if number = 0
81 Starts/reset mapping read32 flow, or stop it if number = 0
83 Starts/reset mapping write8 flow, or stop it if number = 0
85 Starts/reset mapping write16 flow, or stop it if number = 0
87 Starts/reset mapping write32 flow, or stop it if number = 0
89 Breaks on map exec flow, or stop it if number = 0
91 Breaks on map read8 flow, or stop it if number = 0
93 Breaks on map read16 flow, or stop it if number = 0
95 Breaks on map read32 flow, or stop it if number = 0
97 Breaks on map write8 flow, or stop it if number = 0
99 Breaks on map write16 flow, or stop it if number = 0
101 Breaks on map write32 flow, or stop it if number = 0
103 Dumps the execution flow map in an IDC file
105 Execution flow control commands (3xx):
106 -------------------------------------
108 Get a list of the actual breakpoints. Will get '400' answers.
110 Deletes a breakpoint, or all, if no arguments.
112 Sets an exec breakpoint.
114 Sets a read breakpoint, 1 byte / 8 bits.
116 Sets a read breakpoint, 2 bytes / 16 bits, has to be on an even address.
118 Sets a read breakpoint, 4 bytes / 32 bits, address has to be 4-bytes aligned.
120 Sets a write breakpoint, 1 byte / 8 bits.
122 Sets a write breakpoint, 2 bytes / 16 bits, has to be on an even address.
124 Sets a write breakpoint, 4 bytes / 32 bits, address has to be 4-bytes aligned.
126 Pauses execution. Equivalents to a breakpoint.
130 Traces execution, 1 instruction by default. Formatted using %i
139 Spontaneous messages (0xx):
140 --------------------------
143 010 / 011 / 012 / 013 / 014 / 015 / 016
144 Execution hit mapping flow automatic breakpoint.
146 Execution hit breakpoint, PCSX is paused. Displays PC's value.
148 Basic commands acknowledge (2xx):
149 --------------------------------
151 Sends a dumb message.
153 Returns PCSX version.
155 Returns protocol version.
157 status = 0: running; = 1: paused; = 2: trace
159 Displays current PC value.
161 Displays one GP register value.
162 212 LO=<value> HI=<value>
163 Displays LO/HI registers.
165 Displays one COP0 register value.
167 Displays one COP2 control register value.
169 Displays one COP2 data register value.
171 Displays one line of disassembled code.
173 Displays one GP register value, ack for modification.
174 222 LO=<value> HI=<value>
175 Displays LO/HI registers, ack for modification.
177 Displays one COP0 register value, ack for modification.
179 Displays one COP2 control register value, ack for modification.
181 Displays one COP2 data register value, ack for modification.
183 Dumping memory. Will then raw outputs size bytes.
185 Memory set acknowledge.
186 250 / 251 / 252 / 253 / 254 / 255 / 256
187 Acknolwedge of 15x commands.
188 260 / 261 / 262 / 263 / 264 / 265 / 266
189 Acknolwedge of 16x commands.
191 Acknolwedge of 170 command.
193 Execution flow control commands acknowledge (4xx):
194 -------------------------------------------------
195 400 <number>@<address>-<type>
196 Displays a breakpoint, where 'type' can be of E, R1, R2, R4, W1, W2 or W4.
198 Breakpoint deleting acknowledge.
199 410, 420, 421, 422, 430, 431, 432 <number>
200 Breakpoint adding acknowledge. Returns the number of the added breakpoint.
212 Error messages (5xx):
215 Command not understood.
217 Invalid GPR register.
219 Invalid LO/HI register.
221 Invalid range or address.
223 Non existant breakpoint.
224 531, 532, 533 <message>
225 Invalid breakpoint address.
228 static int debugger_active = 0, paused = 0, trace = 0, reset = 0, resetting = 0;
229 static int mapping_e = 0, mapping_r8 = 0, mapping_r16 = 0, mapping_r32 = 0, mapping_w8 = 0, mapping_w16 = 0, mapping_w32 = 0;
230 static int breakmp_e = 0, breakmp_r8 = 0, breakmp_r16 = 0, breakmp_r32 = 0, breakmp_w8 = 0, breakmp_w16 = 0, breakmp_w32 = 0;
232 static void ProcessCommands();
234 static u8 *MemoryMap = NULL;
247 char *breakpoint_type_names[] = {
248 "E", "R1", "R2", "R4", "W1", "W2", "W4"
251 typedef struct breakpoint_s {
252 struct breakpoint_s *next, *prev;
257 static breakpoint_t *first = NULL;
259 int add_breakpoint(int type, u32 address) {
260 breakpoint_t *bp = (breakpoint_t *)malloc(sizeof(breakpoint_t));
263 bp->address = address;
266 bp->number = first->prev->number + 1;
268 bp->prev = first->prev;
281 void delete_breakpoint(breakpoint_t * bp) {
283 if (bp->next == bp) {
290 bp->next->prev = bp->prev;
291 bp->prev->next = bp->next;
296 breakpoint_t *next_breakpoint(breakpoint_t *bp) {
297 return bp->next != first ? bp->next : 0;
300 breakpoint_t *find_breakpoint(int number) {
303 for (p = first; p; p = next_breakpoint(p)) {
304 if (p->number == number)
311 void StartDebugger() {
315 MemoryMap = (u8 *)malloc(0x200000);
316 if (MemoryMap == NULL) {
317 SysMessage(_("Error allocating memory"));
321 if (StartServer() == -1) {
322 SysPrintf(_("Unable to start debug server.\n"));
326 SysPrintf(_("Debugger started.\n"));
330 void StopDebugger() {
331 if (debugger_active) {
333 SysPrintf(_("Debugger stopped.\n"));
336 if (MemoryMap != NULL) {
341 while (first != NULL) delete_breakpoint(first);
346 void PauseDebugger() {
351 void ResumeDebugger() {
357 if (!debugger_active || resetting)
366 reset = resetting = 0;
374 void MarkMap(u32 address, int mask) {
375 if ((address & 0xff000000) != 0x80000000) return;
376 MemoryMap[address & 0x001fffff] |= mask;
379 int IsMapMarked(u32 address, int mask) {
380 return (MemoryMap[address & 0x001fffff] & mask) != 0;
383 void ProcessDebug() {
384 if (!debugger_active || reset || resetting)
392 DebugCheckBP(psxRegs.pc, E);
395 MarkMap(psxRegs.pc, MAP_EXEC);
396 if ((psxRegs.code >> 26) == 3) {
397 MarkMap(_JumpTarget_, MAP_EXEC_JAL);
399 if (((psxRegs.code >> 26) == 0) && ((psxRegs.code & 0x3F) == 9)) {
400 MarkMap(_Rd_, MAP_EXEC_JAL);
411 static void ProcessCommands() {
412 int code, i, dumping;
414 char cmd[257], *arguments, *p, reply[10240], *save, *dump;
415 u32 reg, value, size, address;
420 if (ReadSocket(cmd, 256) > 0) {
422 if (strlen(cmd) <= 2) {
424 } else if (strlen(cmd) == 3) {
425 code = strtol(cmd, 0, 16);
426 } else if (!(isxdigit(cmd[0]) && isxdigit(cmd[1]) && isxdigit(cmd[2]) && (cmd[3] == 0x20))) {
428 } else if (sscanf(cmd, "%3X ", &code) != 1) {
433 code = strtol(cmd, &arguments, 16);
434 while (arguments && *arguments && *arguments == 0x20)
437 if (*arguments == '\0')
445 sprintf(reply, "200 %s\r\n", arguments == NULL ? "OK" : arguments);
448 sprintf(reply, "201 %s\r\n", PCSX_VERSION);
451 sprintf(reply, "202 1.0\r\n");
454 sprintf(reply, "203 %i\r\n", paused ? 1 : trace ? 2 : 0);
457 sprintf(reply, "210 PC=%08X\r\n", psxRegs.pc);
461 if (sscanf(arguments, "%02X", &code) != 1) {
462 sprintf(reply, "511 Malformed 111 command '%s'\r\n", cmd);
468 for (i = 0; i < 32; i++) {
469 sprintf(reply, "%s211 %02X=%08X\r\n", reply, i, psxRegs.GPR.r[i]);
472 if ((code >= 0) && (code < 32)) {
473 sprintf(reply, "211 %02X=%08X\r\n", code, psxRegs.GPR.r[code]);
475 sprintf(reply, "511 Invalid GPR register: %X\r\n", code);
480 sprintf(reply, "212 LO=%08X HI=%08X\r\n", psxRegs.GPR.n.lo, psxRegs.GPR.n.hi);
484 if (sscanf(arguments, "%02X", &code) != 1) {
485 sprintf(reply, "511 Malformed 113 command '%s'\r\n", cmd);
491 for (i = 0; i < 32; i++) {
492 sprintf(reply, "%s213 %02X=%08X\r\n", reply, i, psxRegs.CP0.r[i]);
495 if ((code >= 0) && (code < 32)) {
496 sprintf(reply, "213 %02X=%08X\r\n", code, psxRegs.CP0.r[code]);
498 sprintf(reply, "511 Invalid COP0 register: %X\r\n", code);
504 if (sscanf(arguments, "%02X", &code) != 1) {
505 sprintf(reply, "511 Malformed 114 command '%s'\r\n", cmd);
511 for (i = 0; i < 32; i++) {
512 sprintf(reply, "%s214 %02X=%08X\r\n", reply, i, psxRegs.CP2C.r[i]);
515 if ((code >= 0) && (code < 32)) {
516 sprintf(reply, "214 %02X=%08X\r\n", code, psxRegs.CP2C.r[code]);
518 sprintf(reply, "511 Invalid COP2C register: %X\r\n", code);
524 if (sscanf(arguments, "%02X", &code) != 1) {
525 sprintf(reply, "511 Malformed 111 command '%s'\r\n", cmd);
531 for (i = 0; i < 32; i++) {
532 sprintf(reply, "%s215 %02X=%08X\r\n", reply, i, psxRegs.CP2D.r[i]);
535 if ((code >= 0) && (code < 32)) {
536 sprintf(reply, "215 %02X=%08X\r\n", code, psxRegs.CP2D.r[code]);
538 sprintf(reply, "511 Invalid COP2D register: %X\r\n", code);
544 if (sscanf(arguments, "%08X", &code) != 1) {
545 sprintf(reply, "511 Malformed 119 command '%s'\r\n", cmd);
552 sprintf(reply, "219 %s\r\n", disR3000AF(psxMemRead32(code), code));
555 if (!arguments || sscanf(arguments, "%02X=%08X", ®, &value) != 2) {
556 sprintf(reply, "500 Malformed 121 command '%s'\r\n", arguments);
561 psxRegs.GPR.r[reg] = value;
562 sprintf(reply, "221 %02X=%08X\r\n", reg, value);
564 sprintf(reply, "512 Invalid GPR register: %02X\r\n", reg);
568 if (!arguments || strncmp(arguments, "HI=", 3) == 0) {
570 } else if (arguments && strncmp(arguments, "LO=", 3) == 0) {
574 sprintf(reply, "512 Invalid LO/HI register: '%s'\r\n", arguments);
578 if (sscanf(arguments + 3, "%08X", &value) != 1) {
579 sprintf(reply, "500 Malformed 122 command '%s'\r\n", arguments);
581 psxRegs.GPR.r[reg] = value;
582 sprintf(reply, "222 LO=%08X HI=%08X\r\n", psxRegs.GPR.n.lo, psxRegs.GPR.n.hi);
586 if (!arguments || sscanf(arguments, "%02X=%08X", ®, &value) != 2) {
587 sprintf(reply, "500 Malformed 123 command '%s'\r\n", arguments);
592 psxRegs.CP0.r[reg] = value;
593 sprintf(reply, "223 %02X=%08X\r\n", reg, value);
595 sprintf(reply, "512 Invalid COP0 register: %02X\r\n", reg);
599 if (!arguments || sscanf(arguments, "%02X=%08X", ®, &value) != 2) {
600 sprintf(reply, "500 Malformed 124 command '%s'\r\n", arguments);
605 psxRegs.CP2C.r[reg] = value;
606 sprintf(reply, "224 %02X=%08X\r\n", reg, value);
608 sprintf(reply, "512 Invalid COP2C register: %02X\r\n", reg);
612 if (!arguments || sscanf(arguments, "%02X=%08X", ®, &value) != 2) {
613 sprintf(reply, "500 Malformed 121 command '%s'\r\n", arguments);
618 psxRegs.CP2D.r[reg] = value;
619 sprintf(reply, "225 %02X=%08X\r\n", reg, value);
621 sprintf(reply, "512 Invalid COP2D register: %02X\r\n", reg);
625 if (!arguments || sscanf(arguments, "%08X@%08X", &size, &address) != 2) {
626 sprintf(reply, "500 Malformed 130 command '%s'\r\n", arguments);
630 if ((address >= 0x80000000) && ((address + size) <= 0x80200000)) {
631 sprintf(reply, "230 %08X@%08X\r\n", size, address);
632 dump = (char *) PSXM(address);
635 sprintf(reply, "513 Invalid address or range: '%s'\r\n", arguments);
639 if (!arguments || sscanf(arguments, "%08X@%08X", &size, &address) != 2) {
640 sprintf(reply, "500 Malformed 140 command '%s'\r\n", arguments);
644 if ((address >= 0x80000000) && ((address + size) <= 0x80200000)) {
645 sprintf(reply, "240 %08X@%08X\r\n", size, address);
646 RawReadSocket((char *)PSXM(address), size);
648 sprintf(reply, "514 Invalid address or range: '%s'\r\n", arguments);
654 if (sscanf(arguments, "%02X", &code) != 1) {
655 sprintf(reply, "500 Malformed 150 command '%s'\r\n", cmd);
661 for (i = 0; i < 0x00200000; i++) {
662 MemoryMap[i] &= ~MAP_EXEC;
663 MemoryMap[i] &= ~MAP_EXEC_JAL;
668 sprintf(reply, "250 Mapping of exec flow %s\r\n", code ? "started" : "stopped");
673 if (sscanf(arguments, "%02X", &code) != 1) {
674 sprintf(reply, "500 Malformed 151 command '%s'\r\n", cmd);
680 for (i = 0; i < 0x00200000; i++) {
681 MemoryMap[i] &= ~MAP_R8;
686 sprintf(reply, "251 Mapping of read8 flow %s\r\n", code ? "started" : "stopped");
691 if (sscanf(arguments, "%02X", &code) != 1) {
692 sprintf(reply, "500 Malformed 152 command '%s'\r\n", cmd);
698 for (i = 0; i < 0x00200000; i++) {
699 MemoryMap[i] &= ~MAP_R16;
704 sprintf(reply, "252 Mapping of read16 flow %s\r\n", code ? "started" : "stopped");
709 if (sscanf(arguments, "%02X", &code) != 1) {
710 sprintf(reply, "500 Malformed 153 command '%s'\r\n", cmd);
716 for (i = 0; i < 0x00200000; i++) {
717 MemoryMap[i] &= ~MAP_R32;
722 sprintf(reply, "253 Mapping of read32 flow %s\r\n", code ? "started" : "stopped");
727 if (sscanf(arguments, "%02X", &code) != 1) {
728 sprintf(reply, "500 Malformed 154 command '%s'\r\n", cmd);
734 for (i = 0; i < 0x00200000; i++) {
735 MemoryMap[i] &= ~MAP_W8;
740 sprintf(reply, "254 Mapping of write8 flow %s\r\n", code ? "started" : "stopped");
745 if (sscanf(arguments, "%02X", &code) != 1) {
746 sprintf(reply, "500 Malformed 155 command '%s'\r\n", cmd);
752 for (i = 0; i < 0x00200000; i++) {
753 MemoryMap[i] &= ~MAP_W16;
758 sprintf(reply, "255 Mapping of write16 flow %s\r\n", code ? "started" : "stopped");
763 if (sscanf(arguments, "%02X", &code) != 1) {
764 sprintf(reply, "500 Malformed 156 command '%s'\r\n", cmd);
770 for (i = 0; i < 0x00200000; i++) {
771 MemoryMap[i] &= ~MAP_W32;
776 sprintf(reply, "256 Mapping of write32 flow %s\r\n", code ? "started" : "stopped");
781 if (sscanf(arguments, "%02X", &code) != 1) {
782 sprintf(reply, "500 Malformed 160 command '%s'\r\n", cmd);
791 sprintf(reply, "260 Break on map of exec flow %s\r\n", code ? "started" : "stopped");
796 if (sscanf(arguments, "%02X", &code) != 1) {
797 sprintf(reply, "500 Malformed 161 command '%s'\r\n", cmd);
806 sprintf(reply, "261 Break on map of read8 flow %s\r\n", code ? "started" : "stopped");
811 if (sscanf(arguments, "%02X", &code) != 1) {
812 sprintf(reply, "500 Malformed 162 command '%s'\r\n", cmd);
821 sprintf(reply, "262 Break on map of read16 flow %s\r\n", code ? "started" : "stopped");
826 if (sscanf(arguments, "%02X", &code) != 1) {
827 sprintf(reply, "500 Malformed 163 command '%s'\r\n", cmd);
836 sprintf(reply, "263 Break on map of read32 flow %s\r\n", code ? "started" : "stopped");
841 if (sscanf(arguments, "%02X", &code) != 1) {
842 sprintf(reply, "500 Malformed 164 command '%s'\r\n", cmd);
851 sprintf(reply, "264 Break on map of write8 flow %s\r\n", code ? "started" : "stopped");
856 if (sscanf(arguments, "%02X", &code) != 1) {
857 sprintf(reply, "500 Malformed 165 command '%s'\r\n", cmd);
866 sprintf(reply, "265 Break on map of write16 flow %s\r\n", code ? "started" : "stopped");
871 if (sscanf(arguments, "%02X", &code) != 1) {
872 sprintf(reply, "500 Malformed 166 command '%s'\r\n", cmd);
881 sprintf(reply, "266 Break on map of write32 flow %s\r\n", code ? "started" : "stopped");
884 sfile = fopen("flow.idc", "wb");
885 fprintf(sfile, "#include <idc.idc>\r\n\r\n");
886 fprintf(sfile, "static main(void) {\r\n");
887 for (i = 0; i < 0x00200000; i++) {
888 if (IsMapMarked(i, MAP_EXEC_JAL)) {
889 fprintf(sfile, "\tMakeFunction(0X8%07X,BADADDR);\r\n", i);
892 fprintf(sfile, "}\r\n");
894 sfile = fopen("markcode.idc", "wb");
895 fprintf(sfile, "#include <idc.idc>\r\n\r\n");
896 fprintf(sfile, "static main(void) {\r\n");
897 for (i = 0; i < 0x00200000; i++) {
898 if (IsMapMarked(i, MAP_EXEC)) {
899 fprintf(sfile, "\tMakeCode(0X8%07X);\r\n", i);
902 fprintf(sfile, "}\r\n");
904 sprintf(reply, "270 flow.idc and markcode.idc dumped\r\n");
909 code = strtol(arguments, &p, 16);
911 if (p == arguments) {
914 for (bp = first; bp; bp = next_breakpoint(bp)) {
915 sprintf(reply, "%s400 %X@%08X-%s\r\n", reply, bp->number, bp->address, breakpoint_type_names[bp->type]);
918 sprintf(reply, "530 No breakpoint\r\n");
921 if ((bp = find_breakpoint(code))) {
922 sprintf(reply, "400 %X@%08X-%s\r\n", bp->number, bp->address, breakpoint_type_names[bp->type]);
924 sprintf(reply, "530 Invalid breakpoint number: %X\r\n", code);
931 code = strtol(arguments, &p, 16);
933 if (p == arguments) {
934 while (first != NULL) delete_breakpoint(first);
935 sprintf(reply, "401 All breakpoints deleted.\r\n");
937 if ((bp = find_breakpoint(code))) {
938 delete_breakpoint(bp);
939 sprintf(reply, "401 Breakpoint %X deleted.\r\n", code);
941 sprintf(reply, "530 Invalid breakpoint number: %X\r\n", code);
946 if (!arguments || sscanf(arguments, "%08X", &address) != 1) {
947 sprintf(reply, "500 Malformed 310 command '%s'\r\n", arguments);
950 // if ((address & 3) || (address < 0x80000000) || (address >= 0x80200000)) {
951 // sprintf(reply, "531 Invalid address %08X\r\n", address);
954 code = add_breakpoint(E, address);
955 sprintf(reply, "410 %X\r\n", code);
958 if (!arguments || sscanf(arguments, "%08X", &address) != 1) {
959 sprintf(reply, "500 Malformed 320 command '%s'\r\n", arguments);
962 if ((address < 0x80000000) || (address >= 0x80200000)) {
963 sprintf(reply, "532 Invalid address %08X\r\n", address);
966 code = add_breakpoint(R1, address);
967 sprintf(reply, "420 %X\r\n", code);
970 if (!arguments || sscanf(arguments, "%08X", &address) != 1) {
971 sprintf(reply, "500 Malformed 321 command '%s'\r\n", arguments);
974 if ((address & 1) || (address < 0x80000000) || (address >= 0x80200000)) {
975 sprintf(reply, "532 Invalid address %08X\r\n", address);
978 code = add_breakpoint(R2, address);
979 sprintf(reply, "421 %X\r\n", code);
982 if (!arguments || sscanf(arguments, "%08X", &address) != 1) {
983 sprintf(reply, "500 Malformed 322 command '%s'\r\n", arguments);
986 if ((address & 3) || (address < 0x80000000) || (address >= 0x80200000)) {
987 sprintf(reply, "532 Invalid address %08X\r\n", address);
990 code = add_breakpoint(R4, address);
991 sprintf(reply, "422 %X\r\n", code);
994 if (!arguments || sscanf(arguments, "%08X", &address) != 1) {
995 sprintf(reply, "500 Malformed 330 command '%s'\r\n", arguments);
998 if ((address < 0x80000000) || (address >= 0x80200000)) {
999 sprintf(reply, "533 Invalid address %08X\r\n", address);
1002 code = add_breakpoint(W1, address);
1003 sprintf(reply, "430 %X\r\n", code);
1006 if (!arguments || sscanf(arguments, "%08X", &address) != 1) {
1007 sprintf(reply, "500 Malformed 331 command '%s'\r\n", arguments);
1010 if ((address & 1) || (address < 0x80000000) || (address >= 0x80200000)) {
1011 sprintf(reply, "533 Invalid address %08X\r\n", address);
1014 code = add_breakpoint(W2, address);
1015 sprintf(reply, "431 %X\r\n", code);
1018 if (!arguments || sscanf(arguments, "%08X", &address) != 1) {
1019 sprintf(reply, "500 Malformed 332 command '%s'\r\n", arguments);
1022 if ((address & 3) || (address < 0x80000000) || (address >= 0x80200000)) {
1023 sprintf(reply, "533 Invalid address %08X\r\n", address);
1026 code = add_breakpoint(W4, address);
1027 sprintf(reply, "432 %X\r\n", code);
1031 sprintf(reply, "490 Paused\r\n");
1035 sprintf(reply, "491 Resumed\r\n");
1040 trace = strtol(arguments, &p, 10);
1042 if (p == arguments) {
1046 sprintf(reply, "495 Tracing\r\n");
1052 sprintf(reply, "498 Soft resetting\r\n");
1058 sprintf(reply, "499 Resetting\r\n");
1061 sprintf(reply, "500 Unknown command '%s'\r\n", cmd);
1064 WriteSocket(reply, strlen(reply));
1067 WriteSocket(dump, size);
1076 void DebugCheckBP(u32 address, enum breakpoint_types type) {
1080 if (!debugger_active || reset)
1082 for (bp = first; bp; bp = next_breakpoint(bp)) {
1083 if ((bp->type == type) && (bp->address == address)) {
1084 sprintf(reply, "030 %X@%08X\r\n", bp->number, psxRegs.pc);
1085 WriteSocket(reply, strlen(reply));
1090 if (breakmp_e && type == E) {
1091 if (!IsMapMarked(address, MAP_EXEC)) {
1092 sprintf(reply, "010 %08X@%08X\r\n", address, psxRegs.pc);
1093 WriteSocket(reply, strlen(reply));
1097 if (breakmp_r8 && type == R1) {
1098 if (!IsMapMarked(address, MAP_R8)) {
1099 sprintf(reply, "011 %08X@%08X\r\n", address, psxRegs.pc);
1100 WriteSocket(reply, strlen(reply));
1104 if (breakmp_r16 && type == R2) {
1105 if (!IsMapMarked(address, MAP_R16)) {
1106 sprintf(reply, "012 %08X@%08X\r\n", address, psxRegs.pc);
1107 WriteSocket(reply, strlen(reply));
1111 if (breakmp_r32 && type == R4) {
1112 if (!IsMapMarked(address, MAP_R32)) {
1113 sprintf(reply, "013 %08X@%08X\r\n", address, psxRegs.pc);
1114 WriteSocket(reply, strlen(reply));
1118 if (breakmp_w8 && type == W1) {
1119 if (!IsMapMarked(address, MAP_W8)) {
1120 sprintf(reply, "014 %08X@%08X\r\n", address, psxRegs.pc);
1121 WriteSocket(reply, strlen(reply));
1125 if (breakmp_w16 && type == W2) {
1126 if (!IsMapMarked(address, MAP_W16)) {
1127 sprintf(reply, "015 %08X@%08X\r\n", address, psxRegs.pc);
1128 WriteSocket(reply, strlen(reply));
1132 if (breakmp_w32 && type == W4) {
1133 if (!IsMapMarked(address, MAP_W32)) {
1134 sprintf(reply, "016 %08X@%08X\r\n", address, psxRegs.pc);
1135 WriteSocket(reply, strlen(reply));
1139 if (mapping_r8 && type == R1) MarkMap(address, MAP_R8);
1140 if (mapping_r16 && type == R2) MarkMap(address, MAP_R16);
1141 if (mapping_r32 && type == R4) MarkMap(address, MAP_R32);
1142 if (mapping_w8 && type == W1) MarkMap(address, MAP_W8);
1143 if (mapping_w16 && type == W2) MarkMap(address, MAP_W16);
1144 if (mapping_w32 && type == W4) MarkMap(address, MAP_W32);