diff --git a/bin/debugger.cpp b/bin/debugger.cpp index 3d68b2b..15b32d1 100644 --- a/bin/debugger.cpp +++ b/bin/debugger.cpp @@ -32,7 +32,10 @@ namespace { + const uint32_t kGlobalSize = 0x10000; + bool sigInt = false; + bool memBreak = false; void sigIntHandler(int) { sigInt = true; @@ -180,6 +183,8 @@ namespace { // return false to break (toolbreak, address break, etc.) uint16_t op; + memBreak = false; + cpuExecuteInstruction(); uint32_t pc = cpuGetPC(); @@ -205,6 +210,13 @@ namespace { return false; } + if (memBreak) + { + printf("Memory break\n"); + memBreak = false; + return false; + } + // check for pc breaks if (brkMap.lookup(pc)) @@ -250,6 +262,70 @@ namespace { } + void MemoryLogger(uint32_t address, int size, int readWrite, uint32_t value) + { + + if (address < kGlobalSize && Flags.traceGlobals) + { + const char *name = GlobalName(address); + if (!name) name = "unknown"; + + fprintf(stdout, "%-20s %08x - ", name, address); + if (readWrite) + { + fprintf(stdout, " write %d bytes", size); + switch(size) + { + case 1: + fprintf(stdout, " [%02x]\n", value); + break; + case 2: + fprintf(stdout, " [%04x]\n", value); + break; + case 3: + fprintf(stdout, " [%06x]\n", value); + break; + case 4: + fprintf(stdout, " [%08x]\n", value); + break; + default: + fprintf(stdout, "\n"); + break; + } + } + else + { + fprintf(stdout, " read %d bytes\n", size); + } + } + + + // check for memory breaks. + if (readWrite) + { + // todo -- what if writing 1 byte 4-bit address? + // todo -- if not single stepping at time of break, should + // disasm the prev pc before printing. + + + if (!wbrkMap.lookup(address)) return; + + printf("Write $%08x\n", address); + // todo -- print previous value, old value. + + memBreak = true; + } + else + { + if (!rbrkMap.lookup(address)) return; + + printf("Read $%08x\n", address); + + memBreak = true; + } + } + + } @@ -564,7 +640,40 @@ void Break() } +void ReadBreak() +{} +void WriteBreak() +{} + + + +void ReadWriteBreak() +{ +} + + + +void ReadBreak(int32_t address) +{ + // sanity check address? + + if (address < 0) rbrkMap.remove(-address); + else rbrkMap.add(address); +} + +void WriteBreak(int32_t address) +{ + // sanity check address? + if (address < 0) wbrkMap.remove(-address); + else wbrkMap.add(address); +} + +void ReadWriteBreak(int32_t address) +{ + ReadBreak(address); + WriteBreak(address); +} void Step(const Command &cmd) { @@ -680,6 +789,7 @@ void Shell() disasm(cpuGetPC()); signal(SIGINT, sigIntHandler); + memorySetLoggingFunc(MemoryLogger); for(;;) { diff --git a/bin/debugger.h b/bin/debugger.h index ec0ce9f..06852bc 100644 --- a/bin/debugger.h +++ b/bin/debugger.h @@ -58,6 +58,15 @@ void ToolBreak(); void Break(int32_t address); void Break(); +void ReadBreak(); +void ReadBreak(int32_t address); + +void WriteBreak(); +void WriteBreak(int32_t address); + +void ReadWriteBreak(); +void ReadWriteBreak(int32_t address); + } #endif \ No newline at end of file diff --git a/bin/lexer.re.cpp b/bin/lexer.re.cpp index bb5b8a6..86760c9 100644 --- a/bin/lexer.re.cpp +++ b/bin/lexer.re.cpp @@ -240,6 +240,22 @@ bool ParseLine(const char *iter, Command *command) continue; } + 'mbrk' | 'mbreak' | 'rwbrk' | 'rwbreak' { + Parse(parser, tkRWBREAK, 0, command); + continue; + } + + 'rbrk' | 'rbreak' { + Parse(parser, tkRBREAK, 0, command); + continue; + } + + 'wbrk' | 'wbreak' { + Parse(parser, tkWBREAK, 0, command); + continue; + } + + 'g' | 'go' { Parse(parser, tkCONTINUE, 0, command); continue; diff --git a/bin/parser.lemon b/bin/parser.lemon index cc6993c..97a6995 100644 --- a/bin/parser.lemon +++ b/bin/parser.lemon @@ -93,6 +93,33 @@ stmt ::= TBREAK expr(a) EOL. Debug::ToolBreak(a); } +stmt ::= RBREAK EOL . +{ + Debug::ReadBreak(); +} + +stmt ::= RBREAK expr(a) EOL. +{ + Debug::ReadBreak(a); +} + +stmt ::= WBREAK EOL. +{ + Debug::WriteBreak(); +} + +stmt ::= WBREAK expr(a) EOL. +{ + Debug::WriteBreak(a); +} + + +stmt ::= RWBREAK expr(a) EOL . +{ + Debug::ReadWriteBreak(a); +} + + stmt ::= NEXT EOL. { command->action = Debug::cmdStep;