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"
23 // XXX: don't care but maybe fix it someday
24 #if defined(__GNUC__) && __GNUC__ >= 7
25 #pragma GCC diagnostic ignored "-Wrestrict"
29 PCSX Debug console protocol description, version 1.0
30 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
32 Commands number are formatted using %03X (yes)
33 Registers number are formatted using %02X.
34 Breakpoints numbers are formatted using %X
35 All other values are formatted using %08X, unless specified.
43 Sends a dumb message. Will be replied with a 200 reply, followed by the message.
47 Gets protocol version.
53 Gets GP register, or all, if no argument.
57 Gets COP0 register, or all, if no argument.
59 Gets COP2 control register, or all, if no argument.
61 Gets COP2 data register, or all, if no argument.
63 Disassemble current PC, or given PC.
65 Sets a GP register. Will return a 221 message.
67 Sets LO or HI register. Will return a 222 message.
69 Sets a COP0 register. Will return a 223 message.
71 Sets a COP2 control register. Will return a 224 message.
73 Sets a COP2 data register. Will return a 225 message.
75 Dumps a range of memory, of size bytes starting at addr.
77 Sets a range of memory, of size bytes starting at addr.
78 Will have to send immediately exactly size bytes afterward.
80 Starts/reset mapping execution flow, or stop it if number = 0
82 Starts/reset mapping read8 flow, or stop it if number = 0
84 Starts/reset mapping read16 flow, or stop it if number = 0
86 Starts/reset mapping read32 flow, or stop it if number = 0
88 Starts/reset mapping write8 flow, or stop it if number = 0
90 Starts/reset mapping write16 flow, or stop it if number = 0
92 Starts/reset mapping write32 flow, or stop it if number = 0
94 Breaks on map exec flow, or stop it if number = 0
96 Breaks on map read8 flow, or stop it if number = 0
98 Breaks on map read16 flow, or stop it if number = 0
100 Breaks on map read32 flow, or stop it if number = 0
102 Breaks on map write8 flow, or stop it if number = 0
104 Breaks on map write16 flow, or stop it if number = 0
106 Breaks on map write32 flow, or stop it if number = 0
108 Dumps the execution flow map in an IDC file
110 Execution flow control commands (3xx):
111 -------------------------------------
113 Get a list of the actual breakpoints. Will get '400' answers.
115 Deletes a breakpoint, or all, if no arguments.
117 Sets an exec breakpoint.
119 Sets a read breakpoint, 1 byte / 8 bits.
121 Sets a read breakpoint, 2 bytes / 16 bits, has to be on an even address.
123 Sets a read breakpoint, 4 bytes / 32 bits, address has to be 4-bytes aligned.
125 Sets a write breakpoint, 1 byte / 8 bits.
127 Sets a write breakpoint, 2 bytes / 16 bits, has to be on an even address.
129 Sets a write breakpoint, 4 bytes / 32 bits, address has to be 4-bytes aligned.
131 Pauses execution. Equivalents to a breakpoint.
135 Traces execution, 1 instruction by default. Formatted using %i
144 Spontaneous messages (0xx):
145 --------------------------
148 010 / 011 / 012 / 013 / 014 / 015 / 016
149 Execution hit mapping flow automatic breakpoint.
151 Execution hit breakpoint, PCSX is paused. Displays PC's value.
153 Basic commands acknowledge (2xx):
154 --------------------------------
156 Sends a dumb message.
158 Returns PCSX version.
160 Returns protocol version.
162 status = 0: running; = 1: paused; = 2: trace
164 Displays current PC value.
166 Displays one GP register value.
167 212 LO=<value> HI=<value>
168 Displays LO/HI registers.
170 Displays one COP0 register value.
172 Displays one COP2 control register value.
174 Displays one COP2 data register value.
176 Displays one line of disassembled code.
178 Displays one GP register value, ack for modification.
179 222 LO=<value> HI=<value>
180 Displays LO/HI registers, ack for modification.
182 Displays one COP0 register value, ack for modification.
184 Displays one COP2 control register value, ack for modification.
186 Displays one COP2 data register value, ack for modification.
188 Dumping memory. Will then raw outputs size bytes.
190 Memory set acknowledge.
191 250 / 251 / 252 / 253 / 254 / 255 / 256
192 Acknolwedge of 15x commands.
193 260 / 261 / 262 / 263 / 264 / 265 / 266
194 Acknolwedge of 16x commands.
196 Acknolwedge of 170 command.
198 Execution flow control commands acknowledge (4xx):
199 -------------------------------------------------
200 400 <number>@<address>-<type>
201 Displays a breakpoint, where 'type' can be of E, R1, R2, R4, W1, W2 or W4.
203 Breakpoint deleting acknowledge.
204 410, 420, 421, 422, 430, 431, 432 <number>
205 Breakpoint adding acknowledge. Returns the number of the added breakpoint.
217 Error messages (5xx):
220 Command not understood.
222 Invalid GPR register.
224 Invalid LO/HI register.
226 Invalid range or address.
228 Non existant breakpoint.
229 531, 532, 533 <message>
230 Invalid breakpoint address.
233 static int debugger_active = 0, paused = 0, trace = 0, reset = 0, resetting = 0;
234 static int mapping_e = 0, mapping_r8 = 0, mapping_r16 = 0, mapping_r32 = 0, mapping_w8 = 0, mapping_w16 = 0, mapping_w32 = 0;
235 static int breakmp_e = 0, breakmp_r8 = 0, breakmp_r16 = 0, breakmp_r32 = 0, breakmp_w8 = 0, breakmp_w16 = 0, breakmp_w32 = 0;
237 static void ProcessCommands();
239 static u8 *MemoryMap = NULL;
252 char *breakpoint_type_names[] = {
253 "E", "R1", "R2", "R4", "W1", "W2", "W4"
256 typedef struct breakpoint_s {
257 struct breakpoint_s *next, *prev;
262 static breakpoint_t *first = NULL;
264 int add_breakpoint(int type, u32 address) {
265 breakpoint_t *bp = (breakpoint_t *)malloc(sizeof(breakpoint_t));
268 bp->address = address;
271 bp->number = first->prev->number + 1;
273 bp->prev = first->prev;
286 void delete_breakpoint(breakpoint_t * bp) {
288 if (bp->next == bp) {
295 bp->next->prev = bp->prev;
296 bp->prev->next = bp->next;
301 breakpoint_t *next_breakpoint(breakpoint_t *bp) {
302 return bp->next != first ? bp->next : 0;
305 breakpoint_t *find_breakpoint(int number) {
308 for (p = first; p; p = next_breakpoint(p)) {
309 if (p->number == number)
316 void StartDebugger() {
320 MemoryMap = (u8 *)malloc(0x200000);
321 if (MemoryMap == NULL) {
322 SysMessage(_("Error allocating memory"));
326 if (StartServer() == -1) {
327 SysPrintf(_("Unable to start debug server.\n"));
331 SysPrintf(_("Debugger started.\n"));
335 void StopDebugger() {
336 if (debugger_active) {
338 SysPrintf(_("Debugger stopped.\n"));
341 if (MemoryMap != NULL) {
346 while (first != NULL) delete_breakpoint(first);
351 void PauseDebugger() {
356 void ResumeDebugger() {
362 if (!debugger_active || resetting)
371 reset = resetting = 0;
379 void MarkMap(u32 address, int mask) {
380 if ((address & 0xff000000) != 0x80000000) return;
381 MemoryMap[address & 0x001fffff] |= mask;
384 int IsMapMarked(u32 address, int mask) {
385 return (MemoryMap[address & 0x001fffff] & mask) != 0;
388 void ProcessDebug() {
389 if (!debugger_active || reset || resetting)
397 DebugCheckBP(psxRegs.pc, E);
400 MarkMap(psxRegs.pc, MAP_EXEC);
401 if ((psxRegs.code >> 26) == 3) {
402 MarkMap(_JumpTarget_, MAP_EXEC_JAL);
404 if (((psxRegs.code >> 26) == 0) && ((psxRegs.code & 0x3F) == 9)) {
405 MarkMap(_Rd_, MAP_EXEC_JAL);
416 static void ProcessCommands() {
417 int code, i, dumping;
419 char cmd[257], *arguments, *p, reply[10240], *save, *dump;
420 u32 reg, value, size, address;
425 if (ReadSocket(cmd, 256) > 0) {
427 if (strlen(cmd) <= 2) {
429 } else if (strlen(cmd) == 3) {
430 code = strtol(cmd, 0, 16);
431 } else if (!(isxdigit(cmd[0]) && isxdigit(cmd[1]) && isxdigit(cmd[2]) && (cmd[3] == 0x20))) {
433 } else if (sscanf(cmd, "%3X ", &code) != 1) {
438 code = strtol(cmd, &arguments, 16);
439 while (arguments && *arguments && *arguments == 0x20)
442 if (*arguments == '\0')
450 sprintf(reply, "200 %s\r\n", arguments == NULL ? "OK" : arguments);
453 sprintf(reply, "201 %s\r\n", PACKAGE_VERSION);
456 sprintf(reply, "202 1.0\r\n");
459 sprintf(reply, "203 %i\r\n", paused ? 1 : trace ? 2 : 0);
462 sprintf(reply, "210 PC=%08X\r\n", psxRegs.pc);
466 if (sscanf(arguments, "%02X", &code) != 1) {
467 sprintf(reply, "511 Malformed 111 command '%s'\r\n", cmd);
473 for (i = 0; i < 32; i++) {
474 sprintf(reply, "%s211 %02X=%08X\r\n", reply, i, psxRegs.GPR.r[i]);
477 if ((code >= 0) && (code < 32)) {
478 sprintf(reply, "211 %02X=%08X\r\n", code, psxRegs.GPR.r[code]);
480 sprintf(reply, "511 Invalid GPR register: %X\r\n", code);
485 sprintf(reply, "212 LO=%08X HI=%08X\r\n", psxRegs.GPR.n.lo, psxRegs.GPR.n.hi);
489 if (sscanf(arguments, "%02X", &code) != 1) {
490 sprintf(reply, "511 Malformed 113 command '%s'\r\n", cmd);
496 for (i = 0; i < 32; i++) {
497 sprintf(reply, "%s213 %02X=%08X\r\n", reply, i, psxRegs.CP0.r[i]);
500 if ((code >= 0) && (code < 32)) {
501 sprintf(reply, "213 %02X=%08X\r\n", code, psxRegs.CP0.r[code]);
503 sprintf(reply, "511 Invalid COP0 register: %X\r\n", code);
509 if (sscanf(arguments, "%02X", &code) != 1) {
510 sprintf(reply, "511 Malformed 114 command '%s'\r\n", cmd);
516 for (i = 0; i < 32; i++) {
517 sprintf(reply, "%s214 %02X=%08X\r\n", reply, i, psxRegs.CP2C.r[i]);
520 if ((code >= 0) && (code < 32)) {
521 sprintf(reply, "214 %02X=%08X\r\n", code, psxRegs.CP2C.r[code]);
523 sprintf(reply, "511 Invalid COP2C register: %X\r\n", code);
529 if (sscanf(arguments, "%02X", &code) != 1) {
530 sprintf(reply, "511 Malformed 111 command '%s'\r\n", cmd);
536 for (i = 0; i < 32; i++) {
537 sprintf(reply, "%s215 %02X=%08X\r\n", reply, i, psxRegs.CP2D.r[i]);
540 if ((code >= 0) && (code < 32)) {
541 sprintf(reply, "215 %02X=%08X\r\n", code, psxRegs.CP2D.r[code]);
543 sprintf(reply, "511 Invalid COP2D register: %X\r\n", code);
549 if (sscanf(arguments, "%08X", &code) != 1) {
550 sprintf(reply, "511 Malformed 119 command '%s'\r\n", cmd);
557 sprintf(reply, "219 %s\r\n", disR3000AF(psxMemRead32(code), code));
560 if (!arguments || sscanf(arguments, "%02X=%08X", ®, &value) != 2) {
561 sprintf(reply, "500 Malformed 121 command '%s'\r\n", arguments);
566 psxRegs.GPR.r[reg] = value;
567 sprintf(reply, "221 %02X=%08X\r\n", reg, value);
569 sprintf(reply, "512 Invalid GPR register: %02X\r\n", reg);
573 if (!arguments || strncmp(arguments, "HI=", 3) == 0) {
575 } else if (arguments && strncmp(arguments, "LO=", 3) == 0) {
579 sprintf(reply, "512 Invalid LO/HI register: '%s'\r\n", arguments);
583 if (sscanf(arguments + 3, "%08X", &value) != 1) {
584 sprintf(reply, "500 Malformed 122 command '%s'\r\n", arguments);
586 psxRegs.GPR.r[reg] = value;
587 sprintf(reply, "222 LO=%08X HI=%08X\r\n", psxRegs.GPR.n.lo, psxRegs.GPR.n.hi);
591 if (!arguments || sscanf(arguments, "%02X=%08X", ®, &value) != 2) {
592 sprintf(reply, "500 Malformed 123 command '%s'\r\n", arguments);
597 psxRegs.CP0.r[reg] = value;
598 sprintf(reply, "223 %02X=%08X\r\n", reg, value);
600 sprintf(reply, "512 Invalid COP0 register: %02X\r\n", reg);
604 if (!arguments || sscanf(arguments, "%02X=%08X", ®, &value) != 2) {
605 sprintf(reply, "500 Malformed 124 command '%s'\r\n", arguments);
610 psxRegs.CP2C.r[reg] = value;
611 sprintf(reply, "224 %02X=%08X\r\n", reg, value);
613 sprintf(reply, "512 Invalid COP2C register: %02X\r\n", reg);
617 if (!arguments || sscanf(arguments, "%02X=%08X", ®, &value) != 2) {
618 sprintf(reply, "500 Malformed 121 command '%s'\r\n", arguments);
623 psxRegs.CP2D.r[reg] = value;
624 sprintf(reply, "225 %02X=%08X\r\n", reg, value);
626 sprintf(reply, "512 Invalid COP2D register: %02X\r\n", reg);
630 if (!arguments || sscanf(arguments, "%08X@%08X", &size, &address) != 2) {
631 sprintf(reply, "500 Malformed 130 command '%s'\r\n", arguments);
635 if ((address >= 0x80000000) && ((address + size) <= 0x80200000)) {
636 sprintf(reply, "230 %08X@%08X\r\n", size, address);
637 dump = (char *) PSXM(address);
640 sprintf(reply, "513 Invalid address or range: '%s'\r\n", arguments);
644 if (!arguments || sscanf(arguments, "%08X@%08X", &size, &address) != 2) {
645 sprintf(reply, "500 Malformed 140 command '%s'\r\n", arguments);
649 if ((address >= 0x80000000) && ((address + size) <= 0x80200000)) {
650 sprintf(reply, "240 %08X@%08X\r\n", size, address);
651 RawReadSocket((char *)PSXM(address), size);
653 sprintf(reply, "514 Invalid address or range: '%s'\r\n", arguments);
659 if (sscanf(arguments, "%02X", &code) != 1) {
660 sprintf(reply, "500 Malformed 150 command '%s'\r\n", cmd);
666 for (i = 0; i < 0x00200000; i++) {
667 MemoryMap[i] &= ~MAP_EXEC;
668 MemoryMap[i] &= ~MAP_EXEC_JAL;
673 sprintf(reply, "250 Mapping of exec flow %s\r\n", code ? "started" : "stopped");
678 if (sscanf(arguments, "%02X", &code) != 1) {
679 sprintf(reply, "500 Malformed 151 command '%s'\r\n", cmd);
685 for (i = 0; i < 0x00200000; i++) {
686 MemoryMap[i] &= ~MAP_R8;
691 sprintf(reply, "251 Mapping of read8 flow %s\r\n", code ? "started" : "stopped");
696 if (sscanf(arguments, "%02X", &code) != 1) {
697 sprintf(reply, "500 Malformed 152 command '%s'\r\n", cmd);
703 for (i = 0; i < 0x00200000; i++) {
704 MemoryMap[i] &= ~MAP_R16;
709 sprintf(reply, "252 Mapping of read16 flow %s\r\n", code ? "started" : "stopped");
714 if (sscanf(arguments, "%02X", &code) != 1) {
715 sprintf(reply, "500 Malformed 153 command '%s'\r\n", cmd);
721 for (i = 0; i < 0x00200000; i++) {
722 MemoryMap[i] &= ~MAP_R32;
727 sprintf(reply, "253 Mapping of read32 flow %s\r\n", code ? "started" : "stopped");
732 if (sscanf(arguments, "%02X", &code) != 1) {
733 sprintf(reply, "500 Malformed 154 command '%s'\r\n", cmd);
739 for (i = 0; i < 0x00200000; i++) {
740 MemoryMap[i] &= ~MAP_W8;
745 sprintf(reply, "254 Mapping of write8 flow %s\r\n", code ? "started" : "stopped");
750 if (sscanf(arguments, "%02X", &code) != 1) {
751 sprintf(reply, "500 Malformed 155 command '%s'\r\n", cmd);
757 for (i = 0; i < 0x00200000; i++) {
758 MemoryMap[i] &= ~MAP_W16;
763 sprintf(reply, "255 Mapping of write16 flow %s\r\n", code ? "started" : "stopped");
768 if (sscanf(arguments, "%02X", &code) != 1) {
769 sprintf(reply, "500 Malformed 156 command '%s'\r\n", cmd);
775 for (i = 0; i < 0x00200000; i++) {
776 MemoryMap[i] &= ~MAP_W32;
781 sprintf(reply, "256 Mapping of write32 flow %s\r\n", code ? "started" : "stopped");
786 if (sscanf(arguments, "%02X", &code) != 1) {
787 sprintf(reply, "500 Malformed 160 command '%s'\r\n", cmd);
796 sprintf(reply, "260 Break on map of exec flow %s\r\n", code ? "started" : "stopped");
801 if (sscanf(arguments, "%02X", &code) != 1) {
802 sprintf(reply, "500 Malformed 161 command '%s'\r\n", cmd);
811 sprintf(reply, "261 Break on map of read8 flow %s\r\n", code ? "started" : "stopped");
816 if (sscanf(arguments, "%02X", &code) != 1) {
817 sprintf(reply, "500 Malformed 162 command '%s'\r\n", cmd);
826 sprintf(reply, "262 Break on map of read16 flow %s\r\n", code ? "started" : "stopped");
831 if (sscanf(arguments, "%02X", &code) != 1) {
832 sprintf(reply, "500 Malformed 163 command '%s'\r\n", cmd);
841 sprintf(reply, "263 Break on map of read32 flow %s\r\n", code ? "started" : "stopped");
846 if (sscanf(arguments, "%02X", &code) != 1) {
847 sprintf(reply, "500 Malformed 164 command '%s'\r\n", cmd);
856 sprintf(reply, "264 Break on map of write8 flow %s\r\n", code ? "started" : "stopped");
861 if (sscanf(arguments, "%02X", &code) != 1) {
862 sprintf(reply, "500 Malformed 165 command '%s'\r\n", cmd);
871 sprintf(reply, "265 Break on map of write16 flow %s\r\n", code ? "started" : "stopped");
876 if (sscanf(arguments, "%02X", &code) != 1) {
877 sprintf(reply, "500 Malformed 166 command '%s'\r\n", cmd);
886 sprintf(reply, "266 Break on map of write32 flow %s\r\n", code ? "started" : "stopped");
889 sfile = fopen("flow.idc", "wb");
890 fprintf(sfile, "#include <idc.idc>\r\n\r\n");
891 fprintf(sfile, "static main(void) {\r\n");
892 for (i = 0; i < 0x00200000; i++) {
893 if (IsMapMarked(i, MAP_EXEC_JAL)) {
894 fprintf(sfile, "\tMakeFunction(0X8%07X,BADADDR);\r\n", i);
897 fprintf(sfile, "}\r\n");
899 sfile = fopen("markcode.idc", "wb");
900 fprintf(sfile, "#include <idc.idc>\r\n\r\n");
901 fprintf(sfile, "static main(void) {\r\n");
902 for (i = 0; i < 0x00200000; i++) {
903 if (IsMapMarked(i, MAP_EXEC)) {
904 fprintf(sfile, "\tMakeCode(0X8%07X);\r\n", i);
907 fprintf(sfile, "}\r\n");
909 sprintf(reply, "270 flow.idc and markcode.idc dumped\r\n");
914 code = strtol(arguments, &p, 16);
916 if (p == arguments) {
919 for (bp = first; bp; bp = next_breakpoint(bp)) {
920 sprintf(reply, "%s400 %X@%08X-%s\r\n", reply, bp->number, bp->address, breakpoint_type_names[bp->type]);
923 sprintf(reply, "530 No breakpoint\r\n");
926 if ((bp = find_breakpoint(code))) {
927 sprintf(reply, "400 %X@%08X-%s\r\n", bp->number, bp->address, breakpoint_type_names[bp->type]);
929 sprintf(reply, "530 Invalid breakpoint number: %X\r\n", code);
936 code = strtol(arguments, &p, 16);
938 if (p == arguments) {
939 while (first != NULL) delete_breakpoint(first);
940 sprintf(reply, "401 All breakpoints deleted.\r\n");
942 if ((bp = find_breakpoint(code))) {
943 delete_breakpoint(bp);
944 sprintf(reply, "401 Breakpoint %X deleted.\r\n", code);
946 sprintf(reply, "530 Invalid breakpoint number: %X\r\n", code);
951 if (!arguments || sscanf(arguments, "%08X", &address) != 1) {
952 sprintf(reply, "500 Malformed 310 command '%s'\r\n", arguments);
955 // if ((address & 3) || (address < 0x80000000) || (address >= 0x80200000)) {
956 // sprintf(reply, "531 Invalid address %08X\r\n", address);
959 code = add_breakpoint(E, address);
960 sprintf(reply, "410 %X\r\n", code);
963 if (!arguments || sscanf(arguments, "%08X", &address) != 1) {
964 sprintf(reply, "500 Malformed 320 command '%s'\r\n", arguments);
967 if ((address < 0x80000000) || (address >= 0x80200000)) {
968 sprintf(reply, "532 Invalid address %08X\r\n", address);
971 code = add_breakpoint(R1, address);
972 sprintf(reply, "420 %X\r\n", code);
975 if (!arguments || sscanf(arguments, "%08X", &address) != 1) {
976 sprintf(reply, "500 Malformed 321 command '%s'\r\n", arguments);
979 if ((address & 1) || (address < 0x80000000) || (address >= 0x80200000)) {
980 sprintf(reply, "532 Invalid address %08X\r\n", address);
983 code = add_breakpoint(R2, address);
984 sprintf(reply, "421 %X\r\n", code);
987 if (!arguments || sscanf(arguments, "%08X", &address) != 1) {
988 sprintf(reply, "500 Malformed 322 command '%s'\r\n", arguments);
991 if ((address & 3) || (address < 0x80000000) || (address >= 0x80200000)) {
992 sprintf(reply, "532 Invalid address %08X\r\n", address);
995 code = add_breakpoint(R4, address);
996 sprintf(reply, "422 %X\r\n", code);
999 if (!arguments || sscanf(arguments, "%08X", &address) != 1) {
1000 sprintf(reply, "500 Malformed 330 command '%s'\r\n", arguments);
1003 if ((address < 0x80000000) || (address >= 0x80200000)) {
1004 sprintf(reply, "533 Invalid address %08X\r\n", address);
1007 code = add_breakpoint(W1, address);
1008 sprintf(reply, "430 %X\r\n", code);
1011 if (!arguments || sscanf(arguments, "%08X", &address) != 1) {
1012 sprintf(reply, "500 Malformed 331 command '%s'\r\n", arguments);
1015 if ((address & 1) || (address < 0x80000000) || (address >= 0x80200000)) {
1016 sprintf(reply, "533 Invalid address %08X\r\n", address);
1019 code = add_breakpoint(W2, address);
1020 sprintf(reply, "431 %X\r\n", code);
1023 if (!arguments || sscanf(arguments, "%08X", &address) != 1) {
1024 sprintf(reply, "500 Malformed 332 command '%s'\r\n", arguments);
1027 if ((address & 3) || (address < 0x80000000) || (address >= 0x80200000)) {
1028 sprintf(reply, "533 Invalid address %08X\r\n", address);
1031 code = add_breakpoint(W4, address);
1032 sprintf(reply, "432 %X\r\n", code);
1036 sprintf(reply, "490 Paused\r\n");
1040 sprintf(reply, "491 Resumed\r\n");
1045 trace = strtol(arguments, &p, 10);
1047 if (p == arguments) {
1051 sprintf(reply, "495 Tracing\r\n");
1057 sprintf(reply, "498 Soft resetting\r\n");
1063 sprintf(reply, "499 Resetting\r\n");
1066 sprintf(reply, "500 Unknown command '%s'\r\n", cmd);
1069 WriteSocket(reply, strlen(reply));
1072 WriteSocket(dump, size);
1081 void DebugCheckBP(u32 address, enum breakpoint_types type) {
1085 if (!debugger_active || reset)
1087 for (bp = first; bp; bp = next_breakpoint(bp)) {
1088 if ((bp->type == type) && (bp->address == address)) {
1089 sprintf(reply, "030 %X@%08X\r\n", bp->number, psxRegs.pc);
1090 WriteSocket(reply, strlen(reply));
1095 if (breakmp_e && type == E) {
1096 if (!IsMapMarked(address, MAP_EXEC)) {
1097 sprintf(reply, "010 %08X@%08X\r\n", address, psxRegs.pc);
1098 WriteSocket(reply, strlen(reply));
1102 if (breakmp_r8 && type == R1) {
1103 if (!IsMapMarked(address, MAP_R8)) {
1104 sprintf(reply, "011 %08X@%08X\r\n", address, psxRegs.pc);
1105 WriteSocket(reply, strlen(reply));
1109 if (breakmp_r16 && type == R2) {
1110 if (!IsMapMarked(address, MAP_R16)) {
1111 sprintf(reply, "012 %08X@%08X\r\n", address, psxRegs.pc);
1112 WriteSocket(reply, strlen(reply));
1116 if (breakmp_r32 && type == R4) {
1117 if (!IsMapMarked(address, MAP_R32)) {
1118 sprintf(reply, "013 %08X@%08X\r\n", address, psxRegs.pc);
1119 WriteSocket(reply, strlen(reply));
1123 if (breakmp_w8 && type == W1) {
1124 if (!IsMapMarked(address, MAP_W8)) {
1125 sprintf(reply, "014 %08X@%08X\r\n", address, psxRegs.pc);
1126 WriteSocket(reply, strlen(reply));
1130 if (breakmp_w16 && type == W2) {
1131 if (!IsMapMarked(address, MAP_W16)) {
1132 sprintf(reply, "015 %08X@%08X\r\n", address, psxRegs.pc);
1133 WriteSocket(reply, strlen(reply));
1137 if (breakmp_w32 && type == W4) {
1138 if (!IsMapMarked(address, MAP_W32)) {
1139 sprintf(reply, "016 %08X@%08X\r\n", address, psxRegs.pc);
1140 WriteSocket(reply, strlen(reply));
1144 if (mapping_r8 && type == R1) MarkMap(address, MAP_R8);
1145 if (mapping_r16 && type == R2) MarkMap(address, MAP_R16);
1146 if (mapping_r32 && type == R4) MarkMap(address, MAP_R32);
1147 if (mapping_w8 && type == W1) MarkMap(address, MAP_W8);
1148 if (mapping_w16 && type == W2) MarkMap(address, MAP_W16);
1149 if (mapping_w32 && type == W4) MarkMap(address, MAP_W32);