Mercurial > vba-linux
diff src/sdl/debugger.cpp @ 1:f9f4f1b99eed
importing src directory
author | Robert McIntyre <rlm@mit.edu> |
---|---|
date | Sat, 03 Mar 2012 10:31:27 -0600 |
parents | |
children |
line wrap: on
line diff
1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/src/sdl/debugger.cpp Sat Mar 03 10:31:27 2012 -0600 1.3 @@ -0,0 +1,1460 @@ 1.4 +// VisualBoyAdvance - Nintendo Gameboy/GameboyAdvance (TM) emulator. 1.5 +// Copyright (C) 1999-2003 Forgotten 1.6 +// Copyright (C) 2004 Forgotten and the VBA development team 1.7 + 1.8 +// This program is free software; you can redistribute it and/or modify 1.9 +// it under the terms of the GNU General Public License as published by 1.10 +// the Free Software Foundation; either version 2, or(at your option) 1.11 +// any later version. 1.12 +// 1.13 +// This program is distributed in the hope that it will be useful, 1.14 +// but WITHOUT ANY WARRANTY; without even the implied warranty of 1.15 +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 1.16 +// GNU General Public License for more details. 1.17 +// 1.18 +// You should have received a copy of the GNU General Public License 1.19 +// along with this program; if not, write to the Free Software Foundation, 1.20 +// Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 1.21 + 1.22 +extern "C" { 1.23 +#include <stdio.h> 1.24 +#include <stdlib.h> 1.25 +} // FIXME: should use c++ headers instead 1.26 + 1.27 +#include <string.h> 1.28 + 1.29 +#include "Port.h" 1.30 +#include "gba/GBA.h" 1.31 +#include "gba/GBAGlobals.h" 1.32 +#include "gba/GBACheats.h" 1.33 +#include "gba/armdis.h" 1.34 +#include "gba/elf.h" 1.35 +#include "common/System.h" 1.36 +#include "exprNode.h" 1.37 + 1.38 +extern bool debugger; 1.39 +extern int emulating; 1.40 + 1.41 +extern struct EmulatedSystem theEmulator; 1.42 + 1.43 +#define debuggerReadMemory(addr) \ 1.44 + READ32LE((&map[(addr)>>24].address[(addr) & map[(addr)>>24].mask])) 1.45 + 1.46 +#define debuggerReadHalfWord(addr) \ 1.47 + READ16LE((&map[(addr)>>24].address[(addr) & map[(addr)>>24].mask])) 1.48 + 1.49 +#define debuggerReadByte(addr) \ 1.50 + map[(addr)>>24].address[(addr) & map[(addr)>>24].mask] 1.51 + 1.52 +#define debuggerWriteMemory(addr, value) \ 1.53 + WRITE32LE(&map[(addr)>>24].address[(addr) & map[(addr)>>24].mask], value) 1.54 + 1.55 +#define debuggerWriteHalfWord(addr, value) \ 1.56 + WRITE16LE(&map[(addr)>>24].address[(addr) & map[(addr)>>24].mask], value) 1.57 + 1.58 +#define debuggerWriteByte(addr, value) \ 1.59 + map[(addr)>>24].address[(addr) & map[(addr)>>24].mask] = (value) 1.60 + 1.61 +struct breakpointInfo { 1.62 + u32 address; 1.63 + u32 value; 1.64 + int size; 1.65 +}; 1.66 + 1.67 +struct DebuggerCommand { 1.68 + const char *name; 1.69 + void (*function)(int,char **); 1.70 + const char *help; 1.71 + const char *syntax; 1.72 +}; 1.73 + 1.74 +void debuggerContinueAfterBreakpoint(); 1.75 + 1.76 +void debuggerHelp(int,char **); 1.77 +void debuggerNext(int,char **); 1.78 +void debuggerContinue(int, char **); 1.79 +void debuggerRegisters(int, char **); 1.80 +void debuggerBreak(int, char **); 1.81 +void debuggerBreakDelete(int, char **); 1.82 +void debuggerBreakList(int, char **); 1.83 +void debuggerBreakArm(int, char **); 1.84 +void debuggerBreakWriteClear(int, char **); 1.85 +void debuggerBreakThumb(int, char **); 1.86 +void debuggerBreakWrite(int, char **); 1.87 +void debuggerDebug(int, char **); 1.88 +void debuggerDisassemble(int, char **); 1.89 +void debuggerDisassembleArm(int, char **); 1.90 +void debuggerDisassembleThumb(int, char **); 1.91 +void debuggerEditByte(int, char **); 1.92 +void debuggerEditHalfWord(int, char **); 1.93 +void debuggerEdit(int, char **); 1.94 +void debuggerIo(int, char **); 1.95 +void debuggerLocals(int, char **); 1.96 +void debuggerMemoryByte(int, char **); 1.97 +void debuggerMemoryHalfWord(int, char **); 1.98 +void debuggerMemory(int, char **); 1.99 +void debuggerPrint(int, char **); 1.100 +void debuggerQuit(int, char **); 1.101 +void debuggerSetRadix(int, char **); 1.102 +void debuggerSymbols(int, char **); 1.103 +void debuggerVerbose(int, char **); 1.104 +void debuggerWhere(int, char **); 1.105 + 1.106 +DebuggerCommand debuggerCommands[] = { 1.107 + { "?", debuggerHelp, "Shows this help information. Type ? <command> for command help", "[<command>]" }, 1.108 + { "ba", debuggerBreakArm, "Adds an ARM breakpoint", "<address>" }, 1.109 + { "bd", debuggerBreakDelete,"Deletes a breakpoint", "<number>" }, 1.110 + { "bl", debuggerBreakList, "Lists breakpoints" }, 1.111 + { "bpw", debuggerBreakWrite, "Break on write", "<address> <size>" }, 1.112 + { "bpwc", debuggerBreakWriteClear, "Clear break on write", NULL }, 1.113 + { "break", debuggerBreak, "Adds a breakpoint on the given function", "<function>|<line>|<file:line>" }, 1.114 + { "bt", debuggerBreakThumb, "Adds a THUMB breakpoint", "<address>" }, 1.115 + { "c", debuggerContinue, "Continues execution" , NULL }, 1.116 + { "d", debuggerDisassemble, "Disassembles instructions", "[<address> [<number>]]" }, 1.117 + { "da", debuggerDisassembleArm, "Disassembles ARM instructions", "[<address> [<number>]]" }, 1.118 + { "dt", debuggerDisassembleThumb, "Disassembles THUMB instructions", "[<address> [<number>]]" }, 1.119 + { "eb", debuggerEditByte, "Modify memory location (byte)", "<address> <hex value>" }, 1.120 + { "eh", debuggerEditHalfWord,"Modify memory location (half-word)","<address> <hex value>" }, 1.121 + { "ew", debuggerEdit, "Modify memory location (word)", "<address> <hex value" }, 1.122 + { "h", debuggerHelp, "Shows this help information. Type h <command> for command help", "[<command>]" }, 1.123 + { "io", debuggerIo, "Show I/O registers status", "[video|video2|dma|timer|misc]" }, 1.124 + { "locals", debuggerLocals, "Shows local variables", NULL }, 1.125 + { "mb", debuggerMemoryByte, "Shows memory contents (bytes)", "<address>" }, 1.126 + { "mh", debuggerMemoryHalfWord, "Shows memory contents (half-words)", "<address>"}, 1.127 + { "mw", debuggerMemory, "Shows memory contents (words)", "<address>" }, 1.128 + { "n", debuggerNext, "Executes the next instruction", "[<count>]" }, 1.129 + { "print", debuggerPrint, "Print the value of a expression (if known)", "[/x|/o|/d] <expression>" }, 1.130 + { "q", debuggerQuit, "Quits the emulator", NULL }, 1.131 + { "r", debuggerRegisters, "Shows ARM registers", NULL }, 1.132 + { "radix", debuggerSetRadix, "Sets the print radix", "<radix>" }, 1.133 + { "symbols", debuggerSymbols, "List symbols", "[<symbol>]" }, 1.134 +#ifndef FINAL_VERSION 1.135 + { "trace", debuggerDebug, "Sets the trace level", "<value>" }, 1.136 +#endif 1.137 +#ifdef DEV_VERSION 1.138 + { "verbose", debuggerVerbose, "Change verbose setting", "<value>" }, 1.139 +#endif 1.140 + { "where", debuggerWhere, "Shows call chain", NULL }, 1.141 + { NULL, NULL, NULL, NULL} // end marker 1.142 +}; 1.143 + 1.144 +breakpointInfo debuggerBreakpointList[100]; 1.145 + 1.146 +int debuggerNumOfBreakpoints = 0; 1.147 +bool debuggerAtBreakpoint = false; 1.148 +int debuggerBreakpointNumber = 0; 1.149 +int debuggerRadix = 0; 1.150 + 1.151 +void debuggerApplyBreakpoint(u32 address, int num, int size) 1.152 +{ 1.153 + if(size) 1.154 + debuggerWriteMemory(address, (u32)(0xe1200070 | 1.155 + (num & 0xf) | 1.156 + ((num<<4)&0xf0))); 1.157 + else 1.158 + debuggerWriteHalfWord(address, 1.159 + (u16)(0xbe00 | num)); 1.160 +} 1.161 + 1.162 +void debuggerDisableBreakpoints() 1.163 +{ 1.164 + for(int i = 0; i < debuggerNumOfBreakpoints; i++) { 1.165 + if(debuggerBreakpointList[i].size) 1.166 + debuggerWriteMemory(debuggerBreakpointList[i].address, 1.167 + debuggerBreakpointList[i].value); 1.168 + else 1.169 + debuggerWriteHalfWord(debuggerBreakpointList[i].address, 1.170 + debuggerBreakpointList[i].value); 1.171 + } 1.172 +} 1.173 + 1.174 +void debuggerEnableBreakpoints(bool skipPC) 1.175 +{ 1.176 + for(int i = 0; i < debuggerNumOfBreakpoints; i++) { 1.177 + if(debuggerBreakpointList[i].address == armNextPC && skipPC) 1.178 + continue; 1.179 + 1.180 + debuggerApplyBreakpoint(debuggerBreakpointList[i].address, 1.181 + i, 1.182 + debuggerBreakpointList[i].size); 1.183 + } 1.184 +} 1.185 + 1.186 +void debuggerUsage(const char *cmd) 1.187 +{ 1.188 + for(int i = 0; ; i++) { 1.189 + if(debuggerCommands[i].name) { 1.190 + if(!strcmp(debuggerCommands[i].name, cmd)) { 1.191 + printf("%s %s\t%s\n", 1.192 + debuggerCommands[i].name, 1.193 + debuggerCommands[i].syntax ? debuggerCommands[i].syntax : "", 1.194 + debuggerCommands[i].help); 1.195 + break; 1.196 + } 1.197 + } else { 1.198 + printf("Unrecognized command '%s'.", cmd); 1.199 + break; 1.200 + } 1.201 + } 1.202 +} 1.203 + 1.204 +void debuggerPrintBaseType(Type *t, u32 value, u32 location, 1.205 + LocationType type, 1.206 + int bitSize, int bitOffset) 1.207 +{ 1.208 + if(bitSize) { 1.209 + if(bitOffset) 1.210 + value >>= ((t->size*8)-bitOffset-bitSize); 1.211 + value &= (1 << bitSize)-1; 1.212 + } else { 1.213 + if(t->size == 2) 1.214 + value &= 0xFFFF; 1.215 + else if(t->size == 1) 1.216 + value &= 0xFF; 1.217 + } 1.218 + 1.219 + if(t->size == 8) { 1.220 + u64 value = 0; 1.221 + if(type == LOCATION_memory) { 1.222 + value = debuggerReadMemory(location) | 1.223 + ((u64)debuggerReadMemory(location+4)<<32); 1.224 + } else if(type == LOCATION_register) { 1.225 + value = reg[location].I | ((u64)reg[location+1].I << 32); 1.226 + } 1.227 + switch(t->encoding) { 1.228 + case DW_ATE_signed: 1.229 + switch(debuggerRadix) { 1.230 + case 0: 1.231 + printf("%lld", value); 1.232 + break; 1.233 + case 1: 1.234 + printf("0x%llx", value); 1.235 + break; 1.236 + case 2: 1.237 + printf("0%llo", value); 1.238 + break; 1.239 + } 1.240 + break; 1.241 + case DW_ATE_unsigned: 1.242 + switch(debuggerRadix) { 1.243 + case 0: 1.244 + printf("%llu", value); 1.245 + break; 1.246 + case 1: 1.247 + printf("0x%llx", value); 1.248 + break; 1.249 + case 2: 1.250 + printf("0%llo", value); 1.251 + break; 1.252 + } 1.253 + break; 1.254 + default: 1.255 + printf("Unknowing 64-bit encoding\n"); 1.256 + } 1.257 + return; 1.258 + } 1.259 + 1.260 + switch(t->encoding) { 1.261 + case DW_ATE_boolean: 1.262 + if(value) 1.263 + printf("true"); 1.264 + else 1.265 + printf("false"); 1.266 + break; 1.267 + case DW_ATE_signed: 1.268 + switch(debuggerRadix) { 1.269 + case 0: 1.270 + printf("%d", value); 1.271 + break; 1.272 + case 1: 1.273 + printf("0x%x", value); 1.274 + break; 1.275 + case 2: 1.276 + printf("0%o", value); 1.277 + break; 1.278 + } 1.279 + break; 1.280 + case DW_ATE_unsigned: 1.281 + case DW_ATE_unsigned_char: 1.282 + switch(debuggerRadix) { 1.283 + case 0: 1.284 + printf("%u", value); 1.285 + break; 1.286 + case 1: 1.287 + printf("0x%x", value); 1.288 + break; 1.289 + case 2: 1.290 + printf("0%o", value); 1.291 + break; 1.292 + } 1.293 + break; 1.294 + default: 1.295 + printf("UNKNOWN BASE %d %08x", t->encoding, value); 1.296 + } 1.297 +} 1.298 + 1.299 +char *debuggerPrintType(Type *t) 1.300 +{ 1.301 + char buffer[1024]; 1.302 + static char buffer2[1024]; 1.303 + 1.304 + if(t->type == TYPE_pointer) { 1.305 + if(t->pointer) 1.306 + strcpy(buffer, debuggerPrintType(t->pointer)); 1.307 + else 1.308 + strcpy(buffer, "void"); 1.309 + sprintf(buffer2, "%s *", buffer); 1.310 + return buffer2; 1.311 + } else if(t->type == TYPE_reference) { 1.312 + strcpy(buffer, debuggerPrintType(t->pointer)); 1.313 + sprintf(buffer2, "%s &", buffer); 1.314 + return buffer2; 1.315 + } 1.316 + return t->name; 1.317 +} 1.318 + 1.319 +void debuggerPrintValueInternal(Function *, Type *, ELFBlock *, int, int, u32); 1.320 +void debuggerPrintValueInternal(Function *f, Type *t, 1.321 + int bitSize, int bitOffset, 1.322 + u32 objLocation, LocationType type); 1.323 + 1.324 +u32 debuggerGetValue(u32 location, LocationType type) 1.325 +{ 1.326 + switch(type) { 1.327 + case LOCATION_memory: 1.328 + return debuggerReadMemory(location); 1.329 + case LOCATION_register: 1.330 + return reg[location].I; 1.331 + case LOCATION_value: 1.332 + return location; 1.333 + } 1.334 + return 0; 1.335 +} 1.336 + 1.337 +void debuggerPrintPointer(Type *t, u32 value) 1.338 +{ 1.339 + printf("(%s)0x%08x", debuggerPrintType(t), value); 1.340 +} 1.341 + 1.342 +void debuggerPrintReference(Type *t, u32 value) 1.343 +{ 1.344 + printf("(%s)0x%08x", debuggerPrintType(t), value); 1.345 +} 1.346 + 1.347 +void debuggerPrintFunction(Type *t, u32 value) 1.348 +{ 1.349 + printf("(%s)0x%08x", debuggerPrintType(t), value); 1.350 +} 1.351 + 1.352 +void debuggerPrintArray(Type *t, u32 value) 1.353 +{ 1.354 + // todo 1.355 + printf("(%s[])0x%08x", debuggerPrintType(t->array->type), value); 1.356 +} 1.357 + 1.358 +void debuggerPrintMember(Function *f, 1.359 + Member *m, 1.360 + u32 objLocation, 1.361 + u32 location) 1.362 +{ 1.363 + int bitSize = m->bitSize; 1.364 + if(bitSize) { 1.365 + u32 value = 0; 1.366 + int off = m->bitOffset; 1.367 + int size = m->byteSize; 1.368 + u32 v = 0; 1.369 + if(size == 1) 1.370 + v = debuggerReadByte(location); 1.371 + else if(size == 2) 1.372 + v = debuggerReadHalfWord(location); 1.373 + else if(size == 4) 1.374 + v = debuggerReadMemory(location); 1.375 + 1.376 + while(bitSize) { 1.377 + int top = size*8 - off; 1.378 + int bot = top - bitSize; 1.379 + top--; 1.380 + if(bot >= 0) { 1.381 + value = (v >> (size*8 - bitSize - off)) & ((1 << bitSize)-1); 1.382 + bitSize = 0; 1.383 + } else { 1.384 + value |= (v & ((1 << top)-1)) << (bitSize - top); 1.385 + bitSize -= (top+1); 1.386 + location -= size; 1.387 + off = 0; 1.388 + if(size == 1) 1.389 + v = debuggerReadByte(location); 1.390 + else if(size == 2) 1.391 + v = debuggerReadHalfWord(location); 1.392 + else 1.393 + v = debuggerReadMemory(location); 1.394 + } 1.395 + } 1.396 + debuggerPrintBaseType(m->type, value, location, LOCATION_memory, 1.397 + bitSize, 0); 1.398 + } else { 1.399 + debuggerPrintValueInternal(f, m->type, m->location, m->bitSize, 1.400 + m->bitOffset, objLocation); 1.401 + } 1.402 +} 1.403 + 1.404 +void debuggerPrintStructure(Function *f, Type *t, u32 objLocation) 1.405 +{ 1.406 + printf("{"); 1.407 + int count = t->structure->memberCount; 1.408 + int i = 0; 1.409 + while(i < count) { 1.410 + Member *m = &t->structure->members[i]; 1.411 + printf("%s=", m->name); 1.412 + LocationType type; 1.413 + u32 location = elfDecodeLocation(f, m->location, &type, objLocation); 1.414 + debuggerPrintMember(f, m, objLocation, location); 1.415 + i++; 1.416 + if(i < count) 1.417 + printf(","); 1.418 + } 1.419 + printf("}"); 1.420 +} 1.421 + 1.422 +void debuggerPrintUnion(Function *f, Type *t, u32 objLocation) 1.423 +{ 1.424 + // todo 1.425 + printf("{"); 1.426 + int count = t->structure->memberCount; 1.427 + int i = 0; 1.428 + while(i < count) { 1.429 + Member *m = &t->structure->members[i]; 1.430 + printf("%s=", m->name); 1.431 + debuggerPrintMember(f, m, objLocation, 0); 1.432 + i++; 1.433 + if(i < count) 1.434 + printf(","); 1.435 + } 1.436 + printf("}"); 1.437 +} 1.438 + 1.439 +void debuggerPrintEnum(Type *t, u32 value) 1.440 +{ 1.441 + int i; 1.442 + for(i = 0; i < t->enumeration->count; i++) { 1.443 + EnumMember *m = (EnumMember *)&t->enumeration->members[i]; 1.444 + if(value == m->value) { 1.445 + puts(m->name); 1.446 + return; 1.447 + } 1.448 + } 1.449 + printf("(UNKNOWN VALUE) %d", value); 1.450 +} 1.451 + 1.452 +void debuggerPrintValueInternal(Function *f, Type *t, 1.453 + int bitSize, int bitOffset, 1.454 + u32 objLocation, LocationType type) 1.455 +{ 1.456 + u32 value = debuggerGetValue(objLocation, type); 1.457 + if(!t) { 1.458 + printf("void"); 1.459 + return; 1.460 + } 1.461 + switch(t->type) { 1.462 + case TYPE_base: 1.463 + debuggerPrintBaseType(t, value, objLocation, type, bitSize, bitOffset); 1.464 + break; 1.465 + case TYPE_pointer: 1.466 + debuggerPrintPointer(t, value); 1.467 + break; 1.468 + case TYPE_reference: 1.469 + debuggerPrintReference(t, value); 1.470 + break; 1.471 + case TYPE_function: 1.472 + debuggerPrintFunction(t, value); 1.473 + break; 1.474 + case TYPE_array: 1.475 + debuggerPrintArray(t, objLocation); 1.476 + break; 1.477 + case TYPE_struct: 1.478 + debuggerPrintStructure(f, t, objLocation); 1.479 + break; 1.480 + case TYPE_union: 1.481 + debuggerPrintUnion(f, t, objLocation); 1.482 + break; 1.483 + case TYPE_enum: 1.484 + debuggerPrintEnum(t, value); 1.485 + break; 1.486 + default: 1.487 + printf("%08x", value); 1.488 + break; 1.489 + } 1.490 +} 1.491 + 1.492 +void debuggerPrintValueInternal(Function *f, Type *t, ELFBlock *loc, 1.493 + int bitSize, int bitOffset, u32 objLocation) 1.494 +{ 1.495 + LocationType type; 1.496 + u32 location; 1.497 + if(loc) { 1.498 + if(objLocation) 1.499 + location = elfDecodeLocation(f, loc, &type, objLocation); 1.500 + else 1.501 + location = elfDecodeLocation(f, loc,&type); 1.502 + } else { 1.503 + location = objLocation; 1.504 + type = LOCATION_memory; 1.505 + } 1.506 + 1.507 + debuggerPrintValueInternal(f, t, bitSize, bitOffset, location, type); 1.508 +} 1.509 + 1.510 +void debuggerPrintValue(Function *f, Object *o) 1.511 +{ 1.512 + debuggerPrintValueInternal(f, o->type, o->location, 0, 0, 0); 1.513 + 1.514 + printf("\n"); 1.515 +} 1.516 + 1.517 +void debuggerSymbols(int argc, char **argv) 1.518 +{ 1.519 + int i = 0; 1.520 + u32 value; 1.521 + u32 size; 1.522 + int type; 1.523 + bool match = false; 1.524 + int matchSize = 0; 1.525 + char *matchStr = NULL; 1.526 + 1.527 + if(argc == 2) { 1.528 + match = true; 1.529 + matchSize = strlen(argv[1]); 1.530 + matchStr = argv[1]; 1.531 + } 1.532 + printf("Symbol Value Size Type \n"); 1.533 + printf("-------------------- ------- -------- -------\n"); 1.534 + char *s = NULL; 1.535 + while((s = elfGetSymbol(i, &value, &size, &type))) { 1.536 + if(*s) { 1.537 + if(match) { 1.538 + if(strncmp(s, matchStr, matchSize) != 0) { 1.539 + i++; 1.540 + continue; 1.541 + } 1.542 + } 1.543 + const char *ts = "?"; 1.544 + switch(type) { 1.545 + case 2: 1.546 + ts = "ARM"; 1.547 + break; 1.548 + case 0x0d: 1.549 + ts = "THUMB"; 1.550 + break; 1.551 + case 1: 1.552 + ts = "DATA"; 1.553 + break; 1.554 + } 1.555 + printf("%-20s %08x %08x %-7s\n", 1.556 + s, value, size, ts); 1.557 + } 1.558 + i++; 1.559 + } 1.560 +} 1.561 + 1.562 +void debuggerSetRadix(int argc, char **argv) 1.563 +{ 1.564 + if(argc != 2) 1.565 + debuggerUsage(argv[0]); 1.566 + else { 1.567 + int r = atoi(argv[1]); 1.568 + 1.569 + bool error = false; 1.570 + switch(r) { 1.571 + case 10: 1.572 + debuggerRadix = 0; 1.573 + break; 1.574 + case 8: 1.575 + debuggerRadix = 2; 1.576 + break; 1.577 + case 16: 1.578 + debuggerRadix = 1; 1.579 + break; 1.580 + default: 1.581 + error = true; 1.582 + printf("Unknown radix %d. Valid values are 8, 10 and 16.\n", r); 1.583 + break; 1.584 + } 1.585 + if(!error) 1.586 + printf("Radix set to %d\n", r); 1.587 + } 1.588 +} 1.589 + 1.590 +void debuggerPrint(int argc, char **argv) 1.591 +{ 1.592 + if(argc != 2 && argc != 3) { 1.593 + debuggerUsage(argv[0]); 1.594 + } else { 1.595 + u32 pc = armNextPC; 1.596 + Function *f = NULL; 1.597 + CompileUnit *u = NULL; 1.598 + 1.599 + elfGetCurrentFunction(pc, 1.600 + &f, &u); 1.601 + 1.602 + int oldRadix = debuggerRadix; 1.603 + if(argc == 3) { 1.604 + if(argv[1][0] == '/') { 1.605 + if(argv[1][1] == 'x') 1.606 + debuggerRadix = 1; 1.607 + else if(argv[1][1] == 'o') 1.608 + debuggerRadix = 2; 1.609 + else if(argv[1][1] == 'd') 1.610 + debuggerRadix = 0; 1.611 + else { 1.612 + printf("Unknown format %c\n", argv[1][1]); 1.613 + return; 1.614 + } 1.615 + } else { 1.616 + printf("Unknown option %s\n", argv[1]); 1.617 + return; 1.618 + } 1.619 + } 1.620 + 1.621 + char *s = argc == 2 ? argv[1] : argv[2]; 1.622 + 1.623 + extern char *exprString; 1.624 + extern int exprCol; 1.625 + extern int yyparse(); 1.626 + exprString = s; 1.627 + exprCol = 0; 1.628 + if(!yyparse()) { 1.629 + extern Node *result; 1.630 + if(result->resolve(result, f, u)) { 1.631 + if(result->member) 1.632 + debuggerPrintMember(f, 1.633 + result->member, 1.634 + result->objLocation, 1.635 + result->location); 1.636 + else 1.637 + debuggerPrintValueInternal(f, result->type, 0, 0, 1.638 + result->location, 1.639 + result->locType); 1.640 + printf("\n"); 1.641 + } else { 1.642 + printf("Error resolving expression\n"); 1.643 + } 1.644 + } else { 1.645 + printf("Error parsing expression:\n"); 1.646 + printf("%s\n", s); 1.647 + exprCol--; 1.648 + for(int i = 0; i < exprCol; i++) 1.649 + printf(" "); 1.650 + printf("^\n"); 1.651 + } 1.652 + extern void exprCleanBuffer(); 1.653 + exprCleanBuffer(); 1.654 + exprNodeCleanUp(); 1.655 + debuggerRadix = oldRadix; 1.656 + } 1.657 +} 1.658 + 1.659 +void debuggerHelp(int n, char **args) 1.660 +{ 1.661 + if(n == 2) { 1.662 + debuggerUsage(args[1]); 1.663 + } else { 1.664 + for(int i = 0; ; i++) { 1.665 + if(debuggerCommands[i].name) { 1.666 + printf("%s\t%s\n", debuggerCommands[i].name, debuggerCommands[i].help); 1.667 + } else 1.668 + break; 1.669 + } 1.670 + } 1.671 +} 1.672 + 1.673 +void debuggerDebug(int n, char **args) 1.674 +{ 1.675 + if(n == 2) { 1.676 + int v = 0; 1.677 + sscanf(args[1], "%d", &v); 1.678 + systemDebug = v; 1.679 + printf("Debug level set to %d\n", systemDebug); 1.680 + } else 1.681 + debuggerUsage("trace"); 1.682 +} 1.683 + 1.684 +void debuggerVerbose(int n, char **args) 1.685 +{ 1.686 + if(n == 2) { 1.687 + int v = 0; 1.688 + sscanf(args[1], "%d", &v); 1.689 + systemVerbose = v; 1.690 + printf("Verbose level set to %d\n", systemVerbose); 1.691 + } else 1.692 + debuggerUsage("verbose"); 1.693 +} 1.694 + 1.695 +void debuggerWhere(int n, char **args) 1.696 +{ 1.697 + void elfPrintCallChain(u32); 1.698 + elfPrintCallChain(armNextPC); 1.699 +} 1.700 + 1.701 +void debuggerLocals(int n, char **args) 1.702 +{ 1.703 + Function *f = NULL; 1.704 + CompileUnit *u = NULL; 1.705 + u32 pc = armNextPC; 1.706 + if(elfGetCurrentFunction(pc, 1.707 + &f, &u)) { 1.708 + Object *o = f->parameters; 1.709 + while(o) { 1.710 + printf("%s=", o->name); 1.711 + debuggerPrintValue(f, o); 1.712 + o = o->next; 1.713 + } 1.714 + 1.715 + o = f->variables; 1.716 + while(o) { 1.717 + bool visible = o->startScope ? pc>=o->startScope : true; 1.718 + if(visible) 1.719 + visible = o->endScope ? pc < o->endScope : true; 1.720 + if(visible) { 1.721 + printf("%s=", o->name); 1.722 + debuggerPrintValue(f, o); 1.723 + } 1.724 + o = o->next; 1.725 + } 1.726 + } else { 1.727 + printf("No information for current address\n"); 1.728 + } 1.729 +} 1.730 + 1.731 +void debuggerNext(int n, char **args) 1.732 +{ 1.733 + int count = 1; 1.734 + if(n == 2) { 1.735 + sscanf(args[1], "%d", &count); 1.736 + } 1.737 + for(int i = 0; i < count; i++) { 1.738 + if(debuggerAtBreakpoint) { 1.739 + debuggerContinueAfterBreakpoint(); 1.740 + debuggerEnableBreakpoints(false); 1.741 + } else 1.742 + theEmulator.emuMain(1); 1.743 + } 1.744 + debuggerDisableBreakpoints(); 1.745 + Function *f = NULL; 1.746 + CompileUnit *u = NULL; 1.747 + u32 a = armNextPC; 1.748 + if(elfGetCurrentFunction(a, &f, &u)) { 1.749 + char *file; 1.750 + int line = elfFindLine(u, f, a, &file); 1.751 + 1.752 + printf("File %s, function %s, line %d\n", file, f->name, 1.753 + line); 1.754 + } 1.755 + debuggerRegisters(0, NULL); 1.756 +} 1.757 + 1.758 +void debuggerContinue(int n, char **args) 1.759 +{ 1.760 + if(debuggerAtBreakpoint) 1.761 + debuggerContinueAfterBreakpoint(); 1.762 + debuggerEnableBreakpoints(false); 1.763 + debugger = false; 1.764 +} 1.765 + 1.766 +void debuggerSignal(int sig,int number) 1.767 +{ 1.768 + switch(sig) { 1.769 + case 4: 1.770 + { 1.771 + printf("Illegal instruction at %08x\n", armNextPC); 1.772 + debugger = true; 1.773 + } 1.774 + break; 1.775 + case 5: 1.776 + { 1.777 + printf("Breakpoint %d reached\n", number); 1.778 + debugger = true; 1.779 + debuggerAtBreakpoint = true; 1.780 + debuggerBreakpointNumber = number; 1.781 + debuggerDisableBreakpoints(); 1.782 + 1.783 + Function *f = NULL; 1.784 + CompileUnit *u = NULL; 1.785 + 1.786 + if(elfGetCurrentFunction(armNextPC, &f, &u)) { 1.787 + char *file; 1.788 + int line = elfFindLine(u,f,armNextPC,&file); 1.789 + printf("File %s, function %s, line %d\n", file, f->name, 1.790 + line); 1.791 + } 1.792 + } 1.793 + break; 1.794 + default: 1.795 + printf("Unknown signal %d\n", sig); 1.796 + break; 1.797 + } 1.798 +} 1.799 + 1.800 +void debuggerBreakList(int, char **) 1.801 +{ 1.802 + printf("Num Address Type Symbol\n"); 1.803 + printf("--- -------- ----- ------\n"); 1.804 + for(int i = 0; i < debuggerNumOfBreakpoints; i++) { 1.805 + printf("%3d %08x %s %s\n",i, debuggerBreakpointList[i].address, 1.806 + debuggerBreakpointList[i].size ? "ARM" : "THUMB", 1.807 + elfGetAddressSymbol(debuggerBreakpointList[i].address)); 1.808 + } 1.809 +} 1.810 + 1.811 +void debuggerBreakDelete(int n, char **args) 1.812 +{ 1.813 + if(n == 2) { 1.814 + int n = 0; 1.815 + sscanf(args[1], "%d", &n); 1.816 + printf("Deleting breakpoint %d (%d)\n", n, debuggerNumOfBreakpoints); 1.817 + if(n >= 0 && n < debuggerNumOfBreakpoints) { 1.818 + n++; 1.819 + if(n < debuggerNumOfBreakpoints) { 1.820 + for(int i = n; i < debuggerNumOfBreakpoints; i++) { 1.821 + debuggerBreakpointList[i-1].address = 1.822 + debuggerBreakpointList[i].address; 1.823 + debuggerBreakpointList[i-1].value = 1.824 + debuggerBreakpointList[i].value; 1.825 + debuggerBreakpointList[i-1].size = 1.826 + debuggerBreakpointList[i].size; 1.827 + } 1.828 + } 1.829 + debuggerNumOfBreakpoints--; 1.830 + } 1.831 + } else 1.832 + debuggerUsage("bd"); 1.833 +} 1.834 + 1.835 +void debuggerBreak(int n, char **args) 1.836 +{ 1.837 + if(n == 2) { 1.838 + u32 address = 0; 1.839 + u32 value = 0; 1.840 + int type = 0; 1.841 + char *s = args[1]; 1.842 + char c = *s; 1.843 + if(strchr(s, ':')) { 1.844 + char *name = s; 1.845 + char *l = strchr(s, ':'); 1.846 + *l++ = 0; 1.847 + int line = atoi(l); 1.848 + 1.849 + u32 addr; 1.850 + Function *f; 1.851 + CompileUnit *u; 1.852 + 1.853 + if(elfFindLineInModule(&addr, name, line)) { 1.854 + if(elfGetCurrentFunction(addr, &f, &u)) { 1.855 + u32 addr2; 1.856 + if(elfGetSymbolAddress(f->name, &addr2, &value, &type)) { 1.857 + address = addr; 1.858 + } else { 1.859 + printf("Unable to get function symbol data\n"); 1.860 + return; 1.861 + } 1.862 + } else { 1.863 + printf("Unable to find function for address\n"); 1.864 + return; 1.865 + } 1.866 + } else { 1.867 + printf("Unable to find module or line\n"); 1.868 + return; 1.869 + } 1.870 + } else if(c >= '0' && c <= '9') { 1.871 + int line = atoi(s); 1.872 + Function *f; 1.873 + CompileUnit *u; 1.874 + u32 addr; 1.875 + 1.876 + if(elfGetCurrentFunction(armNextPC, &f, &u)) { 1.877 + if(elfFindLineInUnit(&addr, u, line)) { 1.878 + if(elfGetCurrentFunction(addr, &f, &u)) { 1.879 + u32 addr2; 1.880 + if(elfGetSymbolAddress(f->name, &addr2, &value, &type)) { 1.881 + address = addr; 1.882 + } else { 1.883 + printf("Unable to get function symbol data\n"); 1.884 + return; 1.885 + } 1.886 + } else { 1.887 + printf("Unable to find function for address\n"); 1.888 + return; 1.889 + } 1.890 + } else { 1.891 + printf("Unable to find line\n"); 1.892 + return; 1.893 + } 1.894 + } else { 1.895 + printf("Cannot find current function\n"); 1.896 + return; 1.897 + } 1.898 + } else { 1.899 + if(!elfGetSymbolAddress(s, &address, &value, &type)) { 1.900 + printf("Function %s not found\n", args[1]); 1.901 + return; 1.902 + } 1.903 + } 1.904 + if(type == 0x02 || type == 0x0d) { 1.905 + int i = debuggerNumOfBreakpoints; 1.906 + int size = 0; 1.907 + if(type == 2) 1.908 + size = 1; 1.909 + debuggerBreakpointList[i].address = address; 1.910 + debuggerBreakpointList[i].value = type == 0x02 ? 1.911 + debuggerReadMemory(address) : debuggerReadHalfWord(address); 1.912 + debuggerBreakpointList[i].size = size; 1.913 + // debuggerApplyBreakpoint(address, i, size); 1.914 + debuggerNumOfBreakpoints++; 1.915 + if(size) 1.916 + printf("Added ARM breakpoint at %08x\n", address); 1.917 + else 1.918 + printf("Added THUMB breakpoint at %08x\n", address); 1.919 + } else { 1.920 + printf("%s is not a function symbol\n", args[1]); 1.921 + } 1.922 + } else 1.923 + debuggerUsage("break"); 1.924 +} 1.925 + 1.926 +void debuggerBreakThumb(int n, char **args) 1.927 +{ 1.928 + if(n == 2) { 1.929 + u32 address = 0; 1.930 + sscanf(args[1],"%x", &address); 1.931 + int i = debuggerNumOfBreakpoints; 1.932 + debuggerBreakpointList[i].address = address; 1.933 + debuggerBreakpointList[i].value = debuggerReadHalfWord(address); 1.934 + debuggerBreakpointList[i].size = 0; 1.935 + // debuggerApplyBreakpoint(address, i, 0); 1.936 + debuggerNumOfBreakpoints++; 1.937 + printf("Added THUMB breakpoint at %08x\n", address); 1.938 + } else 1.939 + debuggerUsage("bt"); 1.940 +} 1.941 + 1.942 +void debuggerBreakArm(int n, char **args) 1.943 +{ 1.944 + if(n == 2) { 1.945 + u32 address = 0; 1.946 + sscanf(args[1],"%x", &address); 1.947 + int i = debuggerNumOfBreakpoints; 1.948 + debuggerBreakpointList[i].address = address; 1.949 + debuggerBreakpointList[i].value = debuggerReadMemory(address); 1.950 + debuggerBreakpointList[i].size = 1; 1.951 + // debuggerApplyBreakpoint(address, i, 1); 1.952 + debuggerNumOfBreakpoints++; 1.953 + printf("Added ARM breakpoint at %08x\n", address); 1.954 + } else 1.955 + debuggerUsage("ba"); 1.956 +} 1.957 + 1.958 +void debuggerBreakOnWrite(u32 *mem, u32 oldvalue, u32 value, int size) 1.959 +{ 1.960 + u32 address = 0; 1.961 + if(mem >= (u32*)&workRAM[0] && mem <= (u32*)&workRAM[0x3ffff]) 1.962 + address = 0x2000000 + ((u64)mem - (u64)&workRAM[0]); 1.963 + else 1.964 + address = 0x3000000 + ((u64)mem - (u64)&internalRAM[0]); 1.965 + 1.966 + if(size == 2) 1.967 + printf("Breakpoint (on write) address %08x old:%08x new:%08x\n", 1.968 + address, oldvalue, value); 1.969 + else if(size == 1) 1.970 + printf("Breakpoint (on write) address %08x old:%04x new:%04x\n", 1.971 + address, (u16)oldvalue,(u16)value); 1.972 + else 1.973 + printf("Breakpoint (on write) address %08x old:%02x new:%02x\n", 1.974 + address, (u8)oldvalue, (u8)value); 1.975 + debugger = true; 1.976 +} 1.977 + 1.978 +void debuggerBreakWriteClear(int n, char **args) 1.979 +{ 1.980 + memset(freezeWorkRAM, false, 0x40000); 1.981 + memset(freezeInternalRAM, false, 0x8000); 1.982 + printf("Cleared all break on write\n"); 1.983 +} 1.984 + 1.985 +void debuggerBreakWrite(int n, char **args) 1.986 +{ 1.987 + if(n == 3) { 1.988 + if(cheatsNumber != 0) { 1.989 + printf("Cheats are enabled. Cannot continue.\n"); 1.990 + return; 1.991 + } 1.992 + u32 address = 0; 1.993 + sscanf(args[1], "%x", &address); 1.994 + int n = 0; 1.995 + sscanf(args[2], "%d", &n); 1.996 + 1.997 + if(address < 0x2000000 || address > 0x3007fff) { 1.998 + printf("Invalid address: %08x\n", address); 1.999 + return; 1.1000 + } 1.1001 + 1.1002 + if(address > 0x203ffff && address < 0x3000000) { 1.1003 + printf("Invalid address: %08x\n", address); 1.1004 + return; 1.1005 + } 1.1006 + 1.1007 + u32 final = address + n; 1.1008 + 1.1009 + if(address < 0x2040000 && final > 0x2040000) { 1.1010 + printf("Invalid byte count: %d\n", n); 1.1011 + return; 1.1012 + } else if(address < 0x3008000 && final > 0x3008000) { 1.1013 + printf("Invalid byte count: %d\n", n); 1.1014 + return; 1.1015 + } 1.1016 + printf("Added break on write at %08x for %d bytes\n", address, n); 1.1017 + for(int i = 0; i < n; i++) { 1.1018 + if((address >> 24) == 2) 1.1019 + freezeWorkRAM[address & 0x3ffff] = true; 1.1020 + else 1.1021 + freezeInternalRAM[address & 0x7fff] = true; 1.1022 + address++; 1.1023 + } 1.1024 + } else 1.1025 + debuggerUsage("bpw"); 1.1026 +} 1.1027 + 1.1028 +void debuggerDisassembleArm(int n, char **args) 1.1029 +{ 1.1030 + char buffer[80]; 1.1031 + u32 pc = reg[15].I; 1.1032 + pc -= 4; 1.1033 + int count = 20; 1.1034 + if(n >= 2) { 1.1035 + sscanf(args[1], "%x", &pc); 1.1036 + } 1.1037 + if(pc & 3) { 1.1038 + printf("Misaligned address %08x\n", pc); 1.1039 + pc &= 0xfffffffc; 1.1040 + } 1.1041 + if(n >= 3) { 1.1042 + sscanf(args[2], "%d", &count); 1.1043 + } 1.1044 + int i = 0; 1.1045 + int len = 0; 1.1046 + char format[30]; 1.1047 + for(i = 0; i < count; i++) { 1.1048 + int l = strlen(elfGetAddressSymbol(pc+4*i)); 1.1049 + if(l > len) 1.1050 + len = l; 1.1051 + } 1.1052 + sprintf(format, "%%08x %%-%ds %%s\n", len); 1.1053 + for(i = 0; i < count; i++) { 1.1054 + u32 addr = pc; 1.1055 + pc += disArm(pc, buffer, 2); 1.1056 + printf(format, addr, elfGetAddressSymbol(addr), buffer); 1.1057 + } 1.1058 +} 1.1059 + 1.1060 +void debuggerDisassembleThumb(int n, char **args) 1.1061 +{ 1.1062 + char buffer[80]; 1.1063 + u32 pc = reg[15].I; 1.1064 + pc -= 2; 1.1065 + int count = 20; 1.1066 + if(n >= 2) { 1.1067 + sscanf(args[1], "%x", &pc); 1.1068 + } 1.1069 + if(pc & 1) { 1.1070 + printf("Misaligned address %08x\n", pc); 1.1071 + pc &= 0xfffffffe; 1.1072 + } 1.1073 + if(n >= 3) { 1.1074 + sscanf(args[2], "%d", &count); 1.1075 + } 1.1076 + 1.1077 + int i = 0; 1.1078 + int len = 0; 1.1079 + char format[30]; 1.1080 + for(i = 0; i < count; i++) { 1.1081 + int l = strlen(elfGetAddressSymbol(pc+2*i)); 1.1082 + if(l > len) 1.1083 + len = l; 1.1084 + } 1.1085 + sprintf(format, "%%08x %%-%ds %%s\n", len); 1.1086 + 1.1087 + for(i = 0; i < count; i++) { 1.1088 + u32 addr = pc; 1.1089 + pc += disThumb(pc, buffer, 2); 1.1090 + printf(format, addr, elfGetAddressSymbol(addr), buffer); 1.1091 + } 1.1092 +} 1.1093 + 1.1094 +void debuggerDisassemble(int n, char **args) 1.1095 +{ 1.1096 + if(armState) 1.1097 + debuggerDisassembleArm(n, args); 1.1098 + else 1.1099 + debuggerDisassembleThumb(n, args); 1.1100 +} 1.1101 + 1.1102 +void debuggerContinueAfterBreakpoint() 1.1103 +{ 1.1104 + printf("Continuing after breakpoint\n"); 1.1105 + debuggerEnableBreakpoints(true); 1.1106 + theEmulator.emuMain(1); 1.1107 + debuggerAtBreakpoint = false; 1.1108 +} 1.1109 + 1.1110 +void debuggerRegisters(int, char **) 1.1111 +{ 1.1112 + char *command[3]; 1.1113 + char buffer[10]; 1.1114 + 1.1115 + printf("R00=%08x R04=%08x R08=%08x R12=%08x\n", 1.1116 + reg[0].I, reg[4].I, reg[8].I, reg[12].I); 1.1117 + printf("R01=%08x R05=%08x R09=%08x R13=%08x\n", 1.1118 + reg[1].I, reg[5].I, reg[9].I, reg[13].I); 1.1119 + printf("R02=%08x R06=%08x R10=%08x R14=%08x\n", 1.1120 + reg[2].I, reg[6].I, reg[10].I, reg[14].I); 1.1121 + printf("R03=%08x R07=%08x R11=%08x R15=%08x\n", 1.1122 + reg[3].I, reg[7].I, reg[11].I, reg[15].I); 1.1123 + printf("CPSR=%08x (%c%c%c%c%c%c%c Mode: %02x)\n", 1.1124 + reg[16].I, 1.1125 + (N_FLAG ? 'N' : '.'), 1.1126 + (Z_FLAG ? 'Z' : '.'), 1.1127 + (C_FLAG ? 'C' : '.'), 1.1128 + (V_FLAG ? 'V' : '.'), 1.1129 + (armIrqEnable ? '.' : 'I'), 1.1130 + ((!(reg[16].I & 0x40)) ? '.' : 'F'), 1.1131 + (armState ? '.' : 'T'), 1.1132 + armMode); 1.1133 + sprintf(buffer,"%08x", armState ? reg[15].I - 4 : reg[15].I - 2); 1.1134 + command[0]=const_cast<char *>("m"); 1.1135 + command[1]=buffer; 1.1136 + command[2]=const_cast<char *>("1"); 1.1137 + debuggerDisassemble(3, command); 1.1138 +} 1.1139 + 1.1140 +void debuggerIoVideo() 1.1141 +{ 1.1142 + printf("DISPCNT = %04x\n", DISPCNT); 1.1143 + printf("DISPSTAT = %04x\n", DISPSTAT); 1.1144 + printf("VCOUNT = %04x\n", VCOUNT); 1.1145 + printf("BG0CNT = %04x\n", BG0CNT); 1.1146 + printf("BG1CNT = %04x\n", BG1CNT); 1.1147 + printf("BG2CNT = %04x\n", BG2CNT); 1.1148 + printf("BG3CNT = %04x\n", BG3CNT); 1.1149 + printf("WIN0H = %04x\n", WIN0H); 1.1150 + printf("WIN0V = %04x\n", WIN0V); 1.1151 + printf("WIN1H = %04x\n", WIN1H); 1.1152 + printf("WIN1V = %04x\n", WIN1V); 1.1153 + printf("WININ = %04x\n", WININ); 1.1154 + printf("WINOUT = %04x\n", WINOUT); 1.1155 + printf("MOSAIC = %04x\n", MOSAIC); 1.1156 + printf("BLDMOD = %04x\n", BLDMOD); 1.1157 + printf("COLEV = %04x\n", COLEV); 1.1158 + printf("COLY = %04x\n", COLY); 1.1159 +} 1.1160 + 1.1161 +void debuggerIoVideo2() 1.1162 +{ 1.1163 + printf("BG0HOFS = %04x\n", BG0HOFS); 1.1164 + printf("BG0VOFS = %04x\n", BG0VOFS); 1.1165 + printf("BG1HOFS = %04x\n", BG1HOFS); 1.1166 + printf("BG1VOFS = %04x\n", BG1VOFS); 1.1167 + printf("BG2HOFS = %04x\n", BG2HOFS); 1.1168 + printf("BG2VOFS = %04x\n", BG2VOFS); 1.1169 + printf("BG3HOFS = %04x\n", BG3HOFS); 1.1170 + printf("BG3VOFS = %04x\n", BG3VOFS); 1.1171 + printf("BG2PA = %04x\n", BG2PA); 1.1172 + printf("BG2PB = %04x\n", BG2PB); 1.1173 + printf("BG2PC = %04x\n", BG2PC); 1.1174 + printf("BG2PD = %04x\n", BG2PD); 1.1175 + printf("BG2X = %08x\n", (BG2X_H<<16)|BG2X_L); 1.1176 + printf("BG2Y = %08x\n", (BG2Y_H<<16)|BG2Y_L); 1.1177 + printf("BG3PA = %04x\n", BG3PA); 1.1178 + printf("BG3PB = %04x\n", BG3PB); 1.1179 + printf("BG3PC = %04x\n", BG3PC); 1.1180 + printf("BG3PD = %04x\n", BG3PD); 1.1181 + printf("BG3X = %08x\n", (BG3X_H<<16)|BG3X_L); 1.1182 + printf("BG3Y = %08x\n", (BG3Y_H<<16)|BG3Y_L); 1.1183 +} 1.1184 + 1.1185 +void debuggerIoDMA() 1.1186 +{ 1.1187 + printf("DM0SAD = %08x\n", (DM0SAD_H<<16)|DM0SAD_L); 1.1188 + printf("DM0DAD = %08x\n", (DM0DAD_H<<16)|DM0DAD_L); 1.1189 + printf("DM0CNT = %08x\n", (DM0CNT_H<<16)|DM0CNT_L); 1.1190 + printf("DM1SAD = %08x\n", (DM1SAD_H<<16)|DM1SAD_L); 1.1191 + printf("DM1DAD = %08x\n", (DM1DAD_H<<16)|DM1DAD_L); 1.1192 + printf("DM1CNT = %08x\n", (DM1CNT_H<<16)|DM1CNT_L); 1.1193 + printf("DM2SAD = %08x\n", (DM2SAD_H<<16)|DM2SAD_L); 1.1194 + printf("DM2DAD = %08x\n", (DM2DAD_H<<16)|DM2DAD_L); 1.1195 + printf("DM2CNT = %08x\n", (DM2CNT_H<<16)|DM2CNT_L); 1.1196 + printf("DM3SAD = %08x\n", (DM3SAD_H<<16)|DM3SAD_L); 1.1197 + printf("DM3DAD = %08x\n", (DM3DAD_H<<16)|DM3DAD_L); 1.1198 + printf("DM3CNT = %08x\n", (DM3CNT_H<<16)|DM3CNT_L); 1.1199 +} 1.1200 + 1.1201 +void debuggerIoTimer() 1.1202 +{ 1.1203 + printf("TM0D = %04x\n", TM0D); 1.1204 + printf("TM0CNT = %04x\n", TM0CNT); 1.1205 + printf("TM1D = %04x\n", TM1D); 1.1206 + printf("TM1CNT = %04x\n", TM1CNT); 1.1207 + printf("TM2D = %04x\n", TM2D); 1.1208 + printf("TM2CNT = %04x\n", TM2CNT); 1.1209 + printf("TM3D = %04x\n", TM3D); 1.1210 + printf("TM3CNT = %04x\n", TM3CNT); 1.1211 +} 1.1212 + 1.1213 +void debuggerIoMisc() 1.1214 +{ 1.1215 + printf("P1 = %04x\n", P1); 1.1216 + printf("IE = %04x\n", IE); 1.1217 + printf("IF = %04x\n", IF); 1.1218 + printf("IME = %04x\n", IME); 1.1219 +} 1.1220 + 1.1221 +void debuggerIo(int n, char **args) 1.1222 +{ 1.1223 + if(n == 1) { 1.1224 + debuggerIoVideo(); 1.1225 + return; 1.1226 + } 1.1227 + if(!strcmp(args[1], "video")) 1.1228 + debuggerIoVideo(); 1.1229 + else if(!strcmp(args[1], "video2")) 1.1230 + debuggerIoVideo2(); 1.1231 + else if(!strcmp(args[1], "dma")) 1.1232 + debuggerIoDMA(); 1.1233 + else if(!strcmp(args[1], "timer")) 1.1234 + debuggerIoTimer(); 1.1235 + else if(!strcmp(args[1], "misc")) 1.1236 + debuggerIoMisc(); 1.1237 + else printf("Unrecognized option %s\n", args[1]); 1.1238 +} 1.1239 + 1.1240 +void debuggerEditByte(int n, char **args) 1.1241 +{ 1.1242 + if(n == 3) { 1.1243 + u32 address; 1.1244 + u32 byte; 1.1245 + sscanf(args[1], "%x", &address); 1.1246 + sscanf(args[2], "%x", &byte); 1.1247 + debuggerWriteByte(address, (u8)byte); 1.1248 + } else 1.1249 + debuggerUsage("eb"); 1.1250 +} 1.1251 + 1.1252 +void debuggerEditHalfWord(int n, char **args) 1.1253 +{ 1.1254 + if(n == 3) { 1.1255 + u32 address; 1.1256 + u32 byte; 1.1257 + sscanf(args[1], "%x", &address); 1.1258 + if(address & 1) { 1.1259 + printf("Error: address must be half-word aligned\n"); 1.1260 + return; 1.1261 + } 1.1262 + sscanf(args[2], "%x", &byte); 1.1263 + debuggerWriteHalfWord(address, (u16)byte); 1.1264 + } else 1.1265 + debuggerUsage("eh"); 1.1266 +} 1.1267 + 1.1268 +void debuggerEdit(int n, char **args) 1.1269 +{ 1.1270 + if(n == 3) { 1.1271 + u32 address; 1.1272 + u32 byte; 1.1273 + sscanf(args[1], "%x", &address); 1.1274 + if(address & 3) { 1.1275 + printf("Error: address must be word aligned\n"); 1.1276 + return; 1.1277 + } 1.1278 + sscanf(args[2], "%x", &byte); 1.1279 + debuggerWriteMemory(address, (u32)byte); 1.1280 + } else 1.1281 + debuggerUsage("ew"); 1.1282 +} 1.1283 + 1.1284 + 1.1285 +#define ASCII(c) (c) < 32 ? '.' : (c) > 127 ? '.' : (c) 1.1286 + 1.1287 +void debuggerMemoryByte(int n, char **args) 1.1288 +{ 1.1289 + if(n == 2) { 1.1290 + u32 addr = 0; 1.1291 + sscanf(args[1], "%x", &addr); 1.1292 + for(int ii = 0; ii < 16; ii++) { 1.1293 + int a = debuggerReadByte(addr); 1.1294 + int b = debuggerReadByte(addr+1); 1.1295 + int c = debuggerReadByte(addr+2); 1.1296 + int d = debuggerReadByte(addr+3); 1.1297 + int e = debuggerReadByte(addr+4); 1.1298 + int f = debuggerReadByte(addr+5); 1.1299 + int g = debuggerReadByte(addr+6); 1.1300 + int h = debuggerReadByte(addr+7); 1.1301 + int i = debuggerReadByte(addr+8); 1.1302 + int j = debuggerReadByte(addr+9); 1.1303 + int k = debuggerReadByte(addr+10); 1.1304 + int l = debuggerReadByte(addr+11); 1.1305 + int m = debuggerReadByte(addr+12); 1.1306 + int n = debuggerReadByte(addr+13); 1.1307 + int o = debuggerReadByte(addr+14); 1.1308 + int p = debuggerReadByte(addr+15); 1.1309 + 1.1310 + printf("%08x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c\n", 1.1311 + addr,a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p, 1.1312 + ASCII(a),ASCII(b),ASCII(c),ASCII(d), 1.1313 + ASCII(e),ASCII(f),ASCII(g),ASCII(h), 1.1314 + ASCII(i),ASCII(j),ASCII(k),ASCII(l), 1.1315 + ASCII(m),ASCII(n),ASCII(o),ASCII(p)); 1.1316 + addr += 16; 1.1317 + } 1.1318 + } else 1.1319 + debuggerUsage("mb"); 1.1320 +} 1.1321 + 1.1322 +void debuggerMemoryHalfWord(int n, char **args) 1.1323 +{ 1.1324 + if(n == 2) { 1.1325 + u32 addr = 0; 1.1326 + sscanf(args[1], "%x", &addr); 1.1327 + addr = addr & 0xfffffffe; 1.1328 + for(int ii = 0; ii < 16; ii++) { 1.1329 + int a = debuggerReadByte(addr); 1.1330 + int b = debuggerReadByte(addr+1); 1.1331 + int c = debuggerReadByte(addr+2); 1.1332 + int d = debuggerReadByte(addr+3); 1.1333 + int e = debuggerReadByte(addr+4); 1.1334 + int f = debuggerReadByte(addr+5); 1.1335 + int g = debuggerReadByte(addr+6); 1.1336 + int h = debuggerReadByte(addr+7); 1.1337 + int i = debuggerReadByte(addr+8); 1.1338 + int j = debuggerReadByte(addr+9); 1.1339 + int k = debuggerReadByte(addr+10); 1.1340 + int l = debuggerReadByte(addr+11); 1.1341 + int m = debuggerReadByte(addr+12); 1.1342 + int n = debuggerReadByte(addr+13); 1.1343 + int o = debuggerReadByte(addr+14); 1.1344 + int p = debuggerReadByte(addr+15); 1.1345 + 1.1346 + printf("%08x %02x%02x %02x%02x %02x%02x %02x%02x %02x%02x %02x%02x %02x%02x %02x%02x %c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c\n", 1.1347 + addr,b,a,d,c,f,e,h,g,j,i,l,k,n,m,p,o, 1.1348 + ASCII(a),ASCII(b),ASCII(c),ASCII(d), 1.1349 + ASCII(e),ASCII(f),ASCII(g),ASCII(h), 1.1350 + ASCII(i),ASCII(j),ASCII(k),ASCII(l), 1.1351 + ASCII(m),ASCII(n),ASCII(o),ASCII(p)); 1.1352 + addr += 16; 1.1353 + } 1.1354 + } else 1.1355 + debuggerUsage("mh"); 1.1356 +} 1.1357 + 1.1358 +void debuggerMemory(int n, char **args) 1.1359 +{ 1.1360 + if(n == 2) { 1.1361 + u32 addr = 0; 1.1362 + sscanf(args[1], "%x", &addr); 1.1363 + addr = addr & 0xfffffffc; 1.1364 + for(int ii = 0; ii < 16; ii++) { 1.1365 + int a = debuggerReadByte(addr); 1.1366 + int b = debuggerReadByte(addr+1); 1.1367 + int c = debuggerReadByte(addr+2); 1.1368 + int d = debuggerReadByte(addr+3); 1.1369 + 1.1370 + int e = debuggerReadByte(addr+4); 1.1371 + int f = debuggerReadByte(addr+5); 1.1372 + int g = debuggerReadByte(addr+6); 1.1373 + int h = debuggerReadByte(addr+7); 1.1374 + 1.1375 + int i = debuggerReadByte(addr+8); 1.1376 + int j = debuggerReadByte(addr+9); 1.1377 + int k = debuggerReadByte(addr+10); 1.1378 + int l = debuggerReadByte(addr+11); 1.1379 + 1.1380 + int m = debuggerReadByte(addr+12); 1.1381 + int n = debuggerReadByte(addr+13); 1.1382 + int o = debuggerReadByte(addr+14); 1.1383 + int p = debuggerReadByte(addr+15); 1.1384 + 1.1385 + printf("%08x %02x%02x%02x%02x %02x%02x%02x%02x %02x%02x%02x%02x %02x%02x%02x%02x %c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c\n", 1.1386 + addr,d,c,b,a,h,g,f,e,l,k,j,i,p,o,n,m, 1.1387 + ASCII(a),ASCII(b),ASCII(c),ASCII(d), 1.1388 + ASCII(e),ASCII(f),ASCII(g),ASCII(h), 1.1389 + ASCII(i),ASCII(j),ASCII(k),ASCII(l), 1.1390 + ASCII(m),ASCII(n),ASCII(o),ASCII(p)); 1.1391 + addr += 16; 1.1392 + } 1.1393 + } else 1.1394 + debuggerUsage("mw"); 1.1395 +} 1.1396 + 1.1397 +void debuggerQuit(int, char **) 1.1398 +{ 1.1399 + char buffer[10]; 1.1400 + printf("Are you sure you want to quit (y/n)? "); 1.1401 + fgets(buffer, 1024, stdin); 1.1402 + 1.1403 + if(buffer[0] == 'y' || buffer[0] == 'Y') { 1.1404 + debugger = false; 1.1405 + emulating = false; 1.1406 + } 1.1407 +} 1.1408 + 1.1409 +void debuggerOutput(char *s, u32 addr) 1.1410 +{ 1.1411 + if(s) 1.1412 + puts(s); 1.1413 + else { 1.1414 + char c; 1.1415 + 1.1416 + c = debuggerReadByte(addr); 1.1417 + addr++; 1.1418 + while(c) { 1.1419 + putchar(c); 1.1420 + c = debuggerReadByte(addr); 1.1421 + addr++; 1.1422 + } 1.1423 + } 1.1424 +} 1.1425 + 1.1426 +void debuggerMain() 1.1427 +{ 1.1428 + char buffer[1024]; 1.1429 + char *commands[10]; 1.1430 + int commandCount = 0; 1.1431 + 1.1432 + if(theEmulator.emuUpdateCPSR) 1.1433 + theEmulator.emuUpdateCPSR(); 1.1434 + debuggerRegisters(0, NULL); 1.1435 + 1.1436 + while(debugger) { 1.1437 + systemSoundPause(); 1.1438 + printf("debugger> "); 1.1439 + commandCount = 0; 1.1440 + char *s = fgets(buffer, 1024, stdin); 1.1441 + 1.1442 + commands[0] = strtok(s, " \t\n"); 1.1443 + if(commands[0] == NULL) 1.1444 + continue; 1.1445 + commandCount++; 1.1446 + while((s = strtok(NULL, " \t\n"))) { 1.1447 + commands[commandCount++] = s; 1.1448 + if(commandCount == 10) 1.1449 + break; 1.1450 + } 1.1451 + 1.1452 + for(int j = 0; ; j++) { 1.1453 + if(debuggerCommands[j].name == NULL) { 1.1454 + printf("Unrecognized command %s. Type h for help.\n", commands[0]); 1.1455 + break; 1.1456 + } 1.1457 + if(!strcmp(commands[0], debuggerCommands[j].name)) { 1.1458 + debuggerCommands[j].function(commandCount, commands); 1.1459 + break; 1.1460 + } 1.1461 + } 1.1462 + } 1.1463 +}