diff --git a/bin/debugger.cpp b/bin/debugger.cpp index fb5eb59..05d46e4 100644 --- a/bin/debugger.cpp +++ b/bin/debugger.cpp @@ -2,9 +2,12 @@ #include #include #include +#include + #include #include -#include +#include +#include #include @@ -13,9 +16,61 @@ #include +#include +#include +#include +#include + +namespace { + + void hexdump(const uint8_t *data, ssize_t size, uint32_t address = 0) + { + const char *HexMap = "0123456789abcdef"; + + char buffer1[16 * 3 + 1 + 1]; + char buffer2[16 + 1]; + ssize_t offset = 0; + unsigned i, j; + + + while(size > 0) + { + std::memset(buffer1, ' ', sizeof(buffer1)); + std::memset(buffer2, ' ', sizeof(buffer2)); + + unsigned linelen = (unsigned)std::min(size, (ssize_t)16); + + + for (i = 0, j = 0; i < linelen; i++) + { + unsigned x = data[i]; + buffer1[j++] = HexMap[x >> 4]; + buffer1[j++] = HexMap[x & 0x0f]; + j++; + if (i == 7) j++; + + // isascii not part of std:: and may be a macro. + buffer2[i] = isascii(x) && std::isprint(x) ? x : '.'; + + } + + buffer1[sizeof(buffer1)-1] = 0; + buffer2[sizeof(buffer2)-1] = 0; + + + std::printf("%08x:\t%s\t%s\n", address + (unsigned)offset, buffer1, buffer2); + offset += 16; + data += 16; + size -= 16; + } + std::printf("\n"); + } + +} bool ParseLine(const char *iter, Command *command); + extern "C" { uint32_t debuggerReadLong(uint32_t address) @@ -30,14 +85,34 @@ extern "C" { return tmp; } + uint16_t debuggerReadWord(uint32_t address) + { + uint16_t tmp = 0; + for (unsigned i = 0; i < 2; ++i) + { + if (address < Flags.memorySize) + tmp = (tmp << 8) + Flags.memory[address++]; + } + + return tmp; + } + + uint8_t debuggerReadByte(uint32_t address) + { + if (address < Flags.memorySize) + return Flags.memory[address]; + + return 0; + } + } void DebugHelp(const Command &cmd) { printf("help\n"); printf("break expression\n"); - printf("step"); - printf("continue"); + printf("step\n"); + printf("continue\n"); printf("\n"); printf("print expression\n"); printf("list expression\n"); @@ -64,56 +139,15 @@ void DebugPrint(const Command &cmd) } } -void hexdump(const uint8_t *data, ssize_t size, uint32_t address = 0) -{ -const char *HexMap = "0123456789abcdef"; - - char buffer1[16 * 3 + 1 + 1]; - char buffer2[16 + 1]; - ssize_t offset = 0; - unsigned i, j; - - - while(size > 0) - { - std::memset(buffer1, ' ', sizeof(buffer1)); - std::memset(buffer2, ' ', sizeof(buffer2)); - - unsigned linelen = (unsigned)std::min(size, (ssize_t)16); - - - for (i = 0, j = 0; i < linelen; i++) - { - unsigned x = data[i]; - buffer1[j++] = HexMap[x >> 4]; - buffer1[j++] = HexMap[x & 0x0f]; - j++; - if (i == 7) j++; - - // isascii not part of std:: and may be a macro. - buffer2[i] = isascii(x) && std::isprint(x) ? x : '.'; - - } - - buffer1[sizeof(buffer1)-1] = 0; - buffer2[sizeof(buffer2)-1] = 0; - - - std::printf("%08x:\t%s\t%s\n", address + (unsigned)offset, buffer1, buffer2); - offset += 16; - data += 16; - size -= 16; - } - std::printf("\n"); -} void DebugDump(const Command &cmd) { // TODO -- if no address, use previous address. + // TODO -- support range? if (cmd.argc == 1) { uint32_t start = cmd.argv[0]; - if (start > Flags.memorySize) return; + if (start >= Flags.memorySize) return; uint32_t end = std::min(start + 512, Flags.memorySize); ssize_t size = end - start; @@ -123,6 +157,78 @@ void DebugDump(const Command &cmd) } } +void DebugList(const Command &cmd) +{ + // TODO -- if no address, use previous address. + // TODO -- support range? + if (cmd.argc == 1) + { + uint32_t pc = cmd.argv[0]; + if (pc & 0x01) + { + printf("address is not aligned: $%08x\n", pc); + return; + } + + static char strings[4][256]; + + + for (unsigned i = 0; i < 32; ++i) + { + + if (pc >= Flags.memorySize) break; + + uint16_t opcode = debuggerReadWord(pc); + + if ((opcode & 0xf000) == 0xa000) + { + + const char *name; + + name = TrapName(opcode); + + if (name) + { + printf("$%08X %-51s ; %04X\n", pc, name, opcode); + } + else + { + printf("$%08X Tool #$%04X ; %04X\n", + pc, opcode, opcode); + } + + pc += 2; + continue; + } + + for (unsigned j = 0; j < 4; ++j) strings[j][0] = 0; + + pc = cpuDisOpcode(pc, strings[0], strings[1], strings[2], strings[3]); + printf("%s %-10s %-40s ; %s\n", strings[0], strings[2], strings[3], strings[1]); + } + } +} + + +void DebugPrintRegisters(const Command &cmd) +{ + printf("PC: %08X CSR: %04x\n", cpuGetPC(), cpuGetSR()); + + printf("D: %08x %08x %08x %08x %08x %08x %08x %08x\n", + cpuGetDReg(0), cpuGetDReg(1), cpuGetDReg(2), cpuGetDReg(3), + cpuGetDReg(4), cpuGetDReg(5), cpuGetDReg(6), cpuGetDReg(7) + + ); + + printf("A: %08x %08x %08x %08x %08x %08x %08x %08x\n", + cpuGetAReg(0), cpuGetAReg(1), cpuGetAReg(2), cpuGetAReg(3), + cpuGetAReg(4), cpuGetAReg(5), cpuGetAReg(6), cpuGetAReg(7) + ); + +} + +// todo -- add sigint trap. it shall set a flag to break. + void DebugShell() { char *cp; @@ -156,6 +262,14 @@ void DebugShell() DebugDump(cmd); break; + case List: + DebugList(cmd); + break; + + case PrintRegisters: + DebugPrintRegisters(cmd); + break; + default: DebugHelp(cmd); break; diff --git a/debugger/commands.h b/debugger/commands.h index f5ab06d..5bfb8e4 100644 --- a/debugger/commands.h +++ b/debugger/commands.h @@ -4,6 +4,7 @@ enum { Help, Print, + PrintRegisters, Dump, List, Break, diff --git a/debugger/lexer.re.cpp b/debugger/lexer.re.cpp index 2ba4ce1..20fac03 100644 --- a/debugger/lexer.re.cpp +++ b/debugger/lexer.re.cpp @@ -262,6 +262,11 @@ bool ParseLine(const char *iter, Command *command) continue; } + 'l' | 'list' { + Parse(parser, tkLIST, 0, command); + continue; + } + 'n' | 'next' { Parse(parser, tkNEXT, 0, command); continue; @@ -328,5 +333,8 @@ bool ParseLine(const char *iter, Command *command) Parse(parser, 0, 0, command); ParseFree(parser, free); + if (!command->valid) + fprintf(stderr,"I don't understand.\n"); + return command->valid; } \ No newline at end of file diff --git a/debugger/parser.lemon b/debugger/parser.lemon index 1282937..1a83194 100644 --- a/debugger/parser.lemon +++ b/debugger/parser.lemon @@ -29,7 +29,7 @@ uint32_t debuggerReadLong(uint32_t); } %parse_failure { - fprintf(stderr,"I don't understand.\n"); + //fprintf(stderr,"I don't understand.\n"); command->valid = false; } @@ -59,6 +59,12 @@ stmt ::= expr(a) EOL. command->argv[0] = a; } +stmt ::= STAR EOL. +{ + command->action = PrintRegisters; + command->argc = 0; +} + stmt ::= PRINT expr(a) EOL. { command->action = Print;