mirror of
https://github.com/ksherlock/mpw.git
synced 2024-11-24 13:32:39 +00:00
move debugger code into bin, clean up dispatch
This commit is contained in:
parent
62a374ee16
commit
6fbde7e1bf
@ -12,4 +12,3 @@ add_subdirectory(toolbox)
|
||||
add_subdirectory(mplite)
|
||||
add_subdirectory(mpw)
|
||||
add_subdirectory(macos)
|
||||
add_subdirectory(debugger)
|
@ -2,13 +2,32 @@
|
||||
#set(CMAKE_CXX_COMPILER "clang++")
|
||||
set(CMAKE_CXX_FLAGS "-std=c++11 -stdlib=libc++ -Wall -Wno-deprecated-declarations -g")
|
||||
SET(CMAKE_EXE_LINKER_FLAGS "-framework Carbon")
|
||||
set(CMAKE_INCLUDE_CURRENT_DIR ON)
|
||||
|
||||
add_definitions(-I ${CMAKE_SOURCE_DIR}/)
|
||||
|
||||
|
||||
add_executable(mpw loader.cpp debugger.cpp address_map.cpp)
|
||||
add_custom_command(
|
||||
OUTPUT lexer.cpp
|
||||
COMMAND re2c -b -i -o lexer.cpp "${CMAKE_CURRENT_SOURCE_DIR}/lexer.re.cpp"
|
||||
MAIN_DEPENDENCY lexer.re.cpp
|
||||
DEPENDS debugger.h parser.h
|
||||
)
|
||||
|
||||
add_custom_command(
|
||||
OUTPUT parser.cpp parser.h
|
||||
COMMAND cp -f "${CMAKE_CURRENT_SOURCE_DIR}/parser.lemon" "parser.lemon"
|
||||
COMMAND lemon parser.lemon
|
||||
COMMAND cp -f parser.h "${CMAKE_CURRENT_SOURCE_DIR}/"
|
||||
COMMAND cp -f parser.out "${CMAKE_CURRENT_SOURCE_DIR}/"
|
||||
COMMAND mv -f parser.c parser.cpp
|
||||
MAIN_DEPENDENCY parser.lemon
|
||||
DEPENDS debugger.h
|
||||
)
|
||||
|
||||
|
||||
add_executable(mpw loader.cpp debugger.cpp address_map.cpp lexer.cpp parser.cpp)
|
||||
target_link_libraries(mpw CPU_LIB)
|
||||
target_link_libraries(mpw DEBUGGER_LIB)
|
||||
target_link_libraries(mpw TOOLBOX_LIB)
|
||||
target_link_libraries(mpw MPW_LIB)
|
||||
target_link_libraries(mpw MPLITE_LIB)
|
||||
|
307
bin/debugger.cpp
307
bin/debugger.cpp
@ -20,7 +20,7 @@
|
||||
#include "loader.h"
|
||||
#include "address_map.h"
|
||||
|
||||
#include <debugger/commands.h>
|
||||
#include "debugger.h"
|
||||
|
||||
#include <cpu/defs.h>
|
||||
#include <cpu/CpuModule.h>
|
||||
@ -28,45 +28,6 @@
|
||||
#include <macos/traps.h>
|
||||
#include <macos/sysequ.h>
|
||||
|
||||
bool ParseLine(const char *iter, Command *command);
|
||||
|
||||
extern "C" {
|
||||
|
||||
uint32_t debuggerReadLong(uint32_t address)
|
||||
{
|
||||
uint32_t tmp = 0;
|
||||
for (unsigned i = 0; i < 4; ++i)
|
||||
{
|
||||
if (address < Flags.memorySize)
|
||||
tmp = (tmp << 8) + Flags.memory[address++];
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
namespace {
|
||||
|
||||
bool sigInt = false;
|
||||
@ -148,7 +109,7 @@ namespace {
|
||||
pc += mboffset;
|
||||
// check for MacsBug name after rts.
|
||||
std::string s;
|
||||
unsigned b = debuggerReadByte(pc);
|
||||
unsigned b = Debug::ReadByte(pc);
|
||||
if (b > 0x80 && b < 0xa0)
|
||||
{
|
||||
b -= 0x80;
|
||||
@ -156,7 +117,7 @@ namespace {
|
||||
s.reserve(b);
|
||||
for (unsigned i = 0; i < b; ++i)
|
||||
{
|
||||
s.push_back(debuggerReadByte(pc++));
|
||||
s.push_back(Debug::ReadByte(pc++));
|
||||
}
|
||||
printf("%s\n", s.c_str());
|
||||
}
|
||||
@ -175,7 +136,7 @@ namespace {
|
||||
return pc;
|
||||
}
|
||||
|
||||
uint16_t opcode = debuggerReadWord(pc);
|
||||
uint16_t opcode = Debug::ReadWord(pc);
|
||||
if (op) *op = opcode;
|
||||
|
||||
if ((opcode & 0xf000) == 0xa000)
|
||||
@ -220,7 +181,7 @@ namespace {
|
||||
|
||||
uint32_t pc = cpuGetPC();
|
||||
if (trace) disasm(pc, &op);
|
||||
else op = debuggerReadWord(pc);
|
||||
else op = Debug::ReadWord(pc);
|
||||
|
||||
if (Flags.traceMacsbug && !trace)
|
||||
printMacsbug(pc, op);
|
||||
@ -289,8 +250,46 @@ namespace {
|
||||
|
||||
}
|
||||
|
||||
#pragma mark - Debugger
|
||||
|
||||
void DebugHelp(const Command &cmd)
|
||||
namespace Debug {
|
||||
|
||||
uint32_t ReadLong(uint32_t address)
|
||||
{
|
||||
uint32_t tmp = 0;
|
||||
for (unsigned i = 0; i < 4; ++i)
|
||||
{
|
||||
if (address < Flags.memorySize)
|
||||
tmp = (tmp << 8) + Flags.memory[address++];
|
||||
}
|
||||
|
||||
return tmp;
|
||||
}
|
||||
|
||||
|
||||
uint16_t ReadWord(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 ReadByte(uint32_t address)
|
||||
{
|
||||
if (address < Flags.memorySize)
|
||||
return Flags.memory[address];
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void Help()
|
||||
{
|
||||
printf("help\n");
|
||||
printf("break expression\n");
|
||||
@ -307,64 +306,76 @@ void DebugHelp(const Command &cmd)
|
||||
}
|
||||
|
||||
|
||||
void DebugPrint(const Command &cmd)
|
||||
void Print(uint32_t data)
|
||||
{
|
||||
for (unsigned i = 0; i < cmd.argc; ++i)
|
||||
{
|
||||
uint32_t data = cmd.argv[i];
|
||||
printf("$%08x %12u", data, data);
|
||||
if (data & 0x80000000)
|
||||
printf(" %12d", (int32_t)data);
|
||||
if ((data & 0xffff8000) == 0x8000)
|
||||
printf(" %6d", (int16_t)data);
|
||||
printf("$%08x %12u", data, data);
|
||||
if (data & 0x80000000)
|
||||
printf(" %12d", (int32_t)data);
|
||||
if ((data & 0xffff8000) == 0x8000)
|
||||
printf(" %6d", (int16_t)data);
|
||||
|
||||
printf("\n");
|
||||
|
||||
printf("\n");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void DebugDump(const Command &cmd)
|
||||
void Dump(uint32_t start, int size)
|
||||
{
|
||||
// TODO -- if no address, use previous address.
|
||||
// TODO -- support range?
|
||||
|
||||
|
||||
uint32_t start = cmd.argv[0];
|
||||
uint32_t end = cmd.argc == 2 ? cmd.argv[1] : start + 256;
|
||||
if (size <= 0) return;
|
||||
|
||||
uint32_t end = start + size;
|
||||
|
||||
if (start >= Flags.memorySize) return;
|
||||
|
||||
end = std::min(end, Flags.memorySize);
|
||||
ssize_t size = end - start;
|
||||
size = end - start;
|
||||
|
||||
hexdump(Flags.memory + start, size, start);
|
||||
}
|
||||
|
||||
|
||||
|
||||
void DebugList(const Command &cmd)
|
||||
// grr... need separate count/range options.
|
||||
void List(uint32_t pc, int count)
|
||||
{
|
||||
// TODO -- if no address, use previous address.
|
||||
// TODO -- support range?
|
||||
if (cmd.argc == 1)
|
||||
if (pc & 0x01)
|
||||
{
|
||||
uint32_t pc = cmd.argv[0];
|
||||
if (pc & 0x01)
|
||||
{
|
||||
printf("address is not aligned: $%08x\n", pc);
|
||||
return;
|
||||
}
|
||||
printf("address is not aligned: $%08x\n", pc);
|
||||
return;
|
||||
}
|
||||
|
||||
for (unsigned i = 0; i < 32; ++i)
|
||||
{
|
||||
if (pc >= Flags.memorySize) break;
|
||||
pc = disasm(pc);
|
||||
}
|
||||
for (int i = 0; i < count; ++i)
|
||||
{
|
||||
if (pc >= Flags.memorySize) break;
|
||||
pc = disasm(pc);
|
||||
}
|
||||
}
|
||||
|
||||
void List(uint32_t pc, uint32_t endpc)
|
||||
{
|
||||
if (endpc < pc) return;
|
||||
|
||||
void DebugPrintRegisters(const Command &cmd)
|
||||
if (pc & 0x01)
|
||||
{
|
||||
printf("address is not aligned: $%08x\n", pc);
|
||||
return;
|
||||
}
|
||||
|
||||
while (pc <= endpc)
|
||||
{
|
||||
if (pc >= Flags.memorySize) break;
|
||||
pc = disasm(pc);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
void PrintRegisters()
|
||||
{
|
||||
char srbits[20];
|
||||
|
||||
@ -406,60 +417,54 @@ void DebugPrintRegisters(const Command &cmd)
|
||||
}
|
||||
|
||||
|
||||
void DebugToolBreak(Command &cmd)
|
||||
void ToolBreak(int32_t tool)
|
||||
{
|
||||
for (unsigned i = 0; i < cmd.argc; ++i)
|
||||
|
||||
bool remove = false;
|
||||
|
||||
if (tool < 0)
|
||||
{
|
||||
int32_t tool = (int32_t)cmd.argv[i];
|
||||
bool remove = false;
|
||||
tool = -tool;
|
||||
remove = true;
|
||||
}
|
||||
|
||||
if (tool < 0)
|
||||
{
|
||||
tool = -tool;
|
||||
remove = true;
|
||||
}
|
||||
|
||||
if (tool >= 0xa000 && tool <= 0xafff)
|
||||
{
|
||||
if (remove) tbrkMap.remove(tool);
|
||||
else tbrkMap.add(tool);
|
||||
}
|
||||
else
|
||||
{
|
||||
fprintf(stderr, "Invalid tool: $%04x\n", tool);
|
||||
}
|
||||
if (tool >= 0xa000 && tool <= 0xafff)
|
||||
{
|
||||
if (remove) tbrkMap.remove(tool);
|
||||
else tbrkMap.add(tool);
|
||||
}
|
||||
else
|
||||
{
|
||||
fprintf(stderr, "Invalid tool: $%04x\n", tool);
|
||||
}
|
||||
}
|
||||
|
||||
void DebugBreak(Command &cmd)
|
||||
void Break(int32_t address)
|
||||
{
|
||||
// 24-bit only, - address to remove.
|
||||
for (unsigned i = 0; i < cmd.argc; ++i)
|
||||
|
||||
bool remove = false;
|
||||
|
||||
if (address < 0)
|
||||
{
|
||||
int32_t address = (int32_t)cmd.argv[i];
|
||||
bool remove = false;
|
||||
address = -address;
|
||||
remove = true;
|
||||
}
|
||||
|
||||
if (address < 0)
|
||||
{
|
||||
address = -address;
|
||||
remove = true;
|
||||
}
|
||||
|
||||
if ((address & 0xff000000) == 0)
|
||||
{
|
||||
if (remove) brkMap.remove(address);
|
||||
else brkMap.add(address);
|
||||
}
|
||||
else
|
||||
{
|
||||
fprintf(stderr, "Invalid address: $%08x\n", address);
|
||||
}
|
||||
if ((address & 0xff000000) == 0)
|
||||
{
|
||||
if (remove) brkMap.remove(address);
|
||||
else brkMap.add(address);
|
||||
}
|
||||
else
|
||||
{
|
||||
fprintf(stderr, "Invalid address: $%08x\n", address);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void DebugStep(const Command &cmd)
|
||||
void Step(const Command &cmd)
|
||||
{
|
||||
// TODO - step n to step specified # of instructions.
|
||||
// TODO -- step @address to step until address?
|
||||
@ -478,17 +483,13 @@ void DebugStep(const Command &cmd)
|
||||
}
|
||||
|
||||
|
||||
void DebugContinue(const Command &cmd)
|
||||
void Continue(const Command &cmd)
|
||||
{
|
||||
while (step(false)) ;
|
||||
}
|
||||
|
||||
void DebugSetARegister(Command &cmd)
|
||||
void SetARegister(unsigned reg, uint32_t value)
|
||||
{
|
||||
if (cmd.argc != 2) return;
|
||||
unsigned reg = cmd.argv[0];
|
||||
uint32_t value = cmd.argv[1];
|
||||
|
||||
if (reg > 7) return;
|
||||
if (reg == 7)
|
||||
{
|
||||
@ -509,20 +510,15 @@ void DebugSetARegister(Command &cmd)
|
||||
}
|
||||
|
||||
|
||||
void DebugSetDRegister(Command &cmd)
|
||||
void SetDRegister(unsigned reg, uint32_t value)
|
||||
{
|
||||
if (cmd.argc != 2) return;
|
||||
unsigned reg = cmd.argv[0];
|
||||
uint32_t value = cmd.argv[1];
|
||||
if (reg > 7) return;
|
||||
|
||||
cpuSetDReg(reg, value);
|
||||
}
|
||||
|
||||
void DebugSetXRegister(Command &cmd)
|
||||
void SetXRegister(unsigned reg, uint32_t value)
|
||||
{
|
||||
if (cmd.argc != 2) return;
|
||||
unsigned reg = cmd.argv[0];
|
||||
uint32_t value = cmd.argv[1];
|
||||
|
||||
if (reg == 0)
|
||||
{
|
||||
@ -541,7 +537,7 @@ void DebugSetXRegister(Command &cmd)
|
||||
|
||||
if (reg == 1)
|
||||
{
|
||||
cpuSetSR(value);
|
||||
cpuSetSR(value & 0xffff);
|
||||
}
|
||||
|
||||
}
|
||||
@ -550,7 +546,7 @@ void DebugSetXRegister(Command &cmd)
|
||||
|
||||
// TODO -- RUN command - reload, re-initialize, re-execute
|
||||
// TODO -- parser calls commands directly (except trace/step/run/etc)
|
||||
void DebugShell()
|
||||
void Shell()
|
||||
{
|
||||
char *cp;
|
||||
|
||||
@ -582,55 +578,19 @@ void DebugShell()
|
||||
{
|
||||
switch(cmd.action)
|
||||
{
|
||||
case NullCommand:
|
||||
case cmdNull:
|
||||
break;
|
||||
|
||||
case Print:
|
||||
DebugPrint(cmd);
|
||||
case cmdStep:
|
||||
Step(cmd);
|
||||
break;
|
||||
|
||||
case Dump:
|
||||
DebugDump(cmd);
|
||||
break;
|
||||
|
||||
case List:
|
||||
DebugList(cmd);
|
||||
break;
|
||||
|
||||
case PrintRegisters:
|
||||
DebugPrintRegisters(cmd);
|
||||
break;
|
||||
|
||||
case Step:
|
||||
DebugStep(cmd);
|
||||
break;
|
||||
|
||||
case Continue:
|
||||
DebugContinue(cmd);
|
||||
break;
|
||||
|
||||
case TBreak:
|
||||
DebugToolBreak(cmd);
|
||||
break;
|
||||
|
||||
case Break:
|
||||
DebugBreak(cmd);
|
||||
break;
|
||||
|
||||
case SetARegister:
|
||||
DebugSetARegister(cmd);
|
||||
break;
|
||||
|
||||
case SetDRegister:
|
||||
DebugSetDRegister(cmd);
|
||||
break;
|
||||
|
||||
case SetXRegister:
|
||||
DebugSetXRegister(cmd);
|
||||
case cmdContinue:
|
||||
Continue(cmd);
|
||||
break;
|
||||
|
||||
default:
|
||||
DebugHelp(cmd);
|
||||
Help();
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -643,3 +603,6 @@ void DebugShell()
|
||||
|
||||
}
|
||||
|
||||
} // namespace Debugger
|
||||
|
||||
|
||||
|
51
bin/debugger.h
Normal file
51
bin/debugger.h
Normal file
@ -0,0 +1,51 @@
|
||||
#ifndef __debugger_h__
|
||||
#define __debugger_h__
|
||||
|
||||
|
||||
#include <cstdint>
|
||||
|
||||
// Debugger is a function in MacTypes.h
|
||||
namespace Debug {
|
||||
|
||||
|
||||
enum {
|
||||
cmdNull,
|
||||
cmdContinue,
|
||||
cmdStep,
|
||||
cmdRun,
|
||||
};
|
||||
|
||||
struct Command {
|
||||
bool valid;
|
||||
int action;
|
||||
uint32_t argc;
|
||||
uint32_t argv[10];
|
||||
};
|
||||
|
||||
|
||||
bool ParseLine(const char *iter, Command *command);
|
||||
|
||||
void Shell();
|
||||
void Help();
|
||||
|
||||
uint32_t ReadLong(uint32_t);
|
||||
uint16_t ReadWord(uint32_t);
|
||||
uint8_t ReadByte(uint32_t);
|
||||
|
||||
void Print(uint32_t value);
|
||||
void PrintRegisters();
|
||||
|
||||
void Dump(uint32_t address, int count = 256);
|
||||
void List(uint32_t address, int count = 20);
|
||||
void List(uint32_t pc, uint32_t endpc);
|
||||
|
||||
void SetARegister(unsigned reg, uint32_t value);
|
||||
void SetDRegister(unsigned reg, uint32_t value);
|
||||
void SetXRegister(unsigned reg, uint32_t value);
|
||||
|
||||
void ToolBreak(int32_t tool);
|
||||
void Break(int32_t address);
|
||||
|
||||
}
|
||||
|
||||
#endif
|
@ -6,7 +6,7 @@
|
||||
#include <cstdint>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "commands.h"
|
||||
#include "debugger.h"
|
||||
#include "parser.h"
|
||||
|
||||
// re2c -b -i
|
||||
@ -16,7 +16,7 @@
|
||||
|
||||
void *ParseAlloc(void *(*mallocProc)(size_t));
|
||||
void ParseFree(void *p, void (*freeProc)(void*));
|
||||
void Parse(void *yyp, int yymajor, uint32_t yyminor, Command *command);
|
||||
void Parse(void *yyp, int yymajor, uint32_t yyminor, Debug::Command *command);
|
||||
void ParseTrace(FILE *TraceFILE, char *zTracePrompt);
|
||||
//}
|
||||
|
||||
@ -51,58 +51,9 @@ namespace {
|
||||
}
|
||||
}
|
||||
|
||||
#if 0
|
||||
/*
|
||||
* unordered_set of breakpoints?
|
||||
* bloom filter via std::bitset<16 * 1024> ?
|
||||
*/
|
||||
|
||||
class AddressFilter {
|
||||
std::bitset<4096> pageSet;
|
||||
std::unordered_set<uint32_t> addSet;
|
||||
|
||||
bool test(uint32_t address) const
|
||||
{
|
||||
if (address > 0xffffff) return false;
|
||||
if (!pageSet[address >> 12]) return false;
|
||||
|
||||
return addSet.find(address) != addSet.end();
|
||||
}
|
||||
|
||||
void add(uint32_t address)
|
||||
{
|
||||
if (address > 0xffffff) return;
|
||||
|
||||
pageSet[address >> 12] = true;
|
||||
addSet.insert(address);
|
||||
}
|
||||
|
||||
void remove(uint32_t address)
|
||||
{
|
||||
if (address > 0xffffff) return;
|
||||
|
||||
auto iter = addSet.find(address);
|
||||
if (iter != addSet.end())
|
||||
{
|
||||
addSet.remove();
|
||||
// need to re-scan all addresses to update the pageSet...
|
||||
uint32_t page = address >> 12;
|
||||
pageSet[page] = false;
|
||||
for (auto x : addSet)
|
||||
{
|
||||
if ((x >> 12) == page)
|
||||
{
|
||||
addSet[page] = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
namespace Debug {
|
||||
bool ParseLine(const char *iter, Command *command)
|
||||
{
|
||||
void *parser;
|
||||
@ -110,7 +61,7 @@ bool ParseLine(const char *iter, Command *command)
|
||||
parser = ParseAlloc(malloc);
|
||||
|
||||
//ParseTrace(stdout, "--> ");
|
||||
|
||||
command->action = cmdNull;
|
||||
for (;;)
|
||||
{
|
||||
const char *begin = iter;
|
||||
@ -351,4 +302,6 @@ bool ParseLine(const char *iter, Command *command)
|
||||
fprintf(stderr,"I don't understand.\n");
|
||||
|
||||
return command->valid;
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace Debugger
|
@ -29,6 +29,7 @@
|
||||
#include <macos/traps.h>
|
||||
|
||||
#include "loader.h"
|
||||
#include "debugger.h"
|
||||
|
||||
Settings Flags;
|
||||
|
||||
@ -767,7 +768,7 @@ int main(int argc, char **argv)
|
||||
cpuInitializeFromNewPC(address);
|
||||
|
||||
|
||||
if (Flags.debugger) DebugShell();
|
||||
if (Flags.debugger) Debug::Shell();
|
||||
else MainLoop();
|
||||
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
|
||||
%extra_argument { struct Command *command }
|
||||
%extra_argument { Debug::Command *command }
|
||||
%token_prefix tk
|
||||
|
||||
%token_type {uint32_t}
|
||||
@ -7,7 +7,7 @@
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include "commands.h"
|
||||
#include "debugger.h"
|
||||
|
||||
#include <toolbox/MM.h>
|
||||
#ifdef __cplusplus
|
||||
@ -18,7 +18,6 @@ uint32_t cpuGetSR();
|
||||
uint32_t cpuGetPC();
|
||||
uint32_t cpuGetAReg(unsigned);
|
||||
uint32_t cpuGetDReg(unsigned);
|
||||
uint32_t debuggerReadLong(uint32_t);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
@ -55,103 +54,87 @@ uint32_t debuggerReadLong(uint32_t);
|
||||
|
||||
stmt ::= expr(a) EOL.
|
||||
{
|
||||
command->action = Print;
|
||||
command->argc = 1;
|
||||
command->argv[0] = a;
|
||||
Debug::Print(a);
|
||||
}
|
||||
|
||||
stmt ::= STAR EOL.
|
||||
{
|
||||
command->action = PrintRegisters;
|
||||
command->argc = 0;
|
||||
Debug::PrintRegisters();
|
||||
}
|
||||
|
||||
stmt ::= PRINT expr(a) EOL.
|
||||
{
|
||||
command->action = Print;
|
||||
command->argc = 1;
|
||||
command->argv[0] = a;
|
||||
Debug::Print(a);
|
||||
}
|
||||
|
||||
stmt ::= BREAK expr(a) EOL.
|
||||
{
|
||||
command->action = Break;
|
||||
command->argc = 1;
|
||||
command->argv[0] = a;
|
||||
Debug::Break(a);
|
||||
}
|
||||
|
||||
stmt ::= CONTINUE EOL.
|
||||
{
|
||||
command->action = Continue;
|
||||
command->action = Debug::cmdContinue;
|
||||
command->argc = 0;
|
||||
}
|
||||
|
||||
stmt ::= TBREAK expr(a) EOL.
|
||||
{
|
||||
// negative number = remove it.
|
||||
command->action = TBreak;
|
||||
command->argc = 1;
|
||||
command->argv[0] = a;
|
||||
Debug::ToolBreak(a);
|
||||
}
|
||||
|
||||
stmt ::= NEXT EOL.
|
||||
{
|
||||
command->action = Step;
|
||||
command->action = Debug::cmdStep;
|
||||
command->argc = 0;
|
||||
}
|
||||
|
||||
stmt ::= NEXT expr(a) EOL.
|
||||
{
|
||||
command->action = Step;
|
||||
command->action = Debug::cmdStep;
|
||||
command->argc = 1;
|
||||
command->argv[0] = a;
|
||||
}
|
||||
|
||||
stmt ::= DUMP expr(a) EOL.
|
||||
{
|
||||
command->action = Dump;
|
||||
command->argc = 1;
|
||||
command->argv[0] = a;
|
||||
Debug::Dump(a);
|
||||
}
|
||||
|
||||
stmt ::= DUMP expr(a) COLON expr(b) EOL.
|
||||
{
|
||||
// range dump
|
||||
command->action = Dump;
|
||||
command->argc = 2;
|
||||
command->argv[0] = a;
|
||||
command->argv[1] = b;
|
||||
Debug::Dump(a, b - a);
|
||||
}
|
||||
|
||||
stmt ::= DUMP expr(a) AT expr(b) EOL.
|
||||
{
|
||||
// count dump
|
||||
command->action = Dump;
|
||||
command->argc = 2;
|
||||
command->argv[0] = a;
|
||||
command->argv[1] = a+b;
|
||||
Debug::Dump(a, b);
|
||||
}
|
||||
|
||||
stmt ::= LIST expr(a) EOL.
|
||||
{
|
||||
command->action = List;
|
||||
command->argc = 1;
|
||||
command->argv[0] = a;
|
||||
Debug::List(a);
|
||||
}
|
||||
|
||||
|
||||
stmt ::= expr(a) SEMIH EOL.
|
||||
{
|
||||
command->action = Dump;
|
||||
command->argc = 1;
|
||||
command->argv[0] = a;
|
||||
Debug::Dump(a);
|
||||
}
|
||||
|
||||
stmt ::= expr(a) COLON expr(b) SEMIH EOL.
|
||||
{
|
||||
Debug::Dump(a, b - a);
|
||||
}
|
||||
|
||||
stmt ::= expr(a) AT expr(b) SEMIH EOL.
|
||||
{
|
||||
Debug::Dump(a, b);
|
||||
}
|
||||
|
||||
|
||||
stmt ::= expr(a) SEMII EOL.
|
||||
{
|
||||
command->action = NullCommand;
|
||||
command->argc = 0;
|
||||
|
||||
MM::Native::MemoryInfo(a);
|
||||
}
|
||||
|
||||
@ -159,40 +142,28 @@ stmt ::= expr(a) SEMII EOL.
|
||||
|
||||
stmt ::= expr(a) SEMIL EOL.
|
||||
{
|
||||
command->action = List;
|
||||
command->argc = 1;
|
||||
command->argv[0] = a;
|
||||
Debug::List(a);
|
||||
}
|
||||
|
||||
|
||||
stmt ::= DREGISTER(a) EQ expr(b) EOL.
|
||||
{
|
||||
command->action = SetDRegister;
|
||||
command->argc = 2;
|
||||
command->argv[0] = a;
|
||||
command->argv[1] = b;
|
||||
Debug::SetDRegister(a, b);
|
||||
}
|
||||
|
||||
stmt ::= AREGISTER(a) EQ expr(b) EOL.
|
||||
{
|
||||
command->action = SetARegister;
|
||||
command->argc = 2;
|
||||
command->argv[0] = a;
|
||||
command->argv[1] = b;
|
||||
Debug::SetARegister(a, b);
|
||||
}
|
||||
|
||||
stmt ::= XREGISTER(a) EQ expr(b) EOL.
|
||||
{
|
||||
command->action = SetXRegister;
|
||||
command->argc = 2;
|
||||
command->argv[0] = a;
|
||||
command->argv[1] = b;
|
||||
Debug::SetXRegister(a, b);
|
||||
}
|
||||
|
||||
stmt ::= HELP EOL.
|
||||
{
|
||||
command->action = Help;
|
||||
command->argc = 0;
|
||||
Debug::Help();
|
||||
}
|
||||
|
||||
expr(rhs) ::= unary(a). { rhs = a; }
|
||||
@ -221,7 +192,7 @@ unary(rhs) ::= PLUS unary(a). [BANG] { rhs = a; }
|
||||
unary(rhs) ::= MINUS unary(a). [BANG] { rhs = -a; }
|
||||
unary(rhs) ::= TILDE unary(a). { rhs = ~a; }
|
||||
unary(rhs) ::= BANG unary(a). { rhs = !a; }
|
||||
unary(rhs) ::= STAR unary(a). [BANG] { rhs = debuggerReadLong(a); }
|
||||
unary(rhs) ::= STAR unary(a). [BANG] { rhs = Debug::ReadLong(a); }
|
||||
|
||||
|
||||
term(rhs) ::= LPAREN expr(a) RPAREN. { rhs = a; }
|
@ -1,25 +0,0 @@
|
||||
set(CMAKE_INCLUDE_CURRENT_DIR ON)
|
||||
add_definitions(-I ${CMAKE_SOURCE_DIR}/)
|
||||
|
||||
|
||||
set(DEBUGGER_SRC lexer.cpp parser.cpp)
|
||||
|
||||
add_custom_command(
|
||||
OUTPUT lexer.cpp
|
||||
COMMAND re2c -b -i -o lexer.cpp "${CMAKE_CURRENT_SOURCE_DIR}/lexer.re.cpp"
|
||||
MAIN_DEPENDENCY lexer.re.cpp
|
||||
DEPENDS commands.h parser.h
|
||||
)
|
||||
|
||||
add_custom_command(
|
||||
OUTPUT parser.cpp parser.h
|
||||
COMMAND cp -f "${CMAKE_CURRENT_SOURCE_DIR}/parser.lemon" "parser.lemon"
|
||||
COMMAND lemon parser.lemon
|
||||
COMMAND cp -f parser.h "${CMAKE_CURRENT_SOURCE_DIR}/"
|
||||
COMMAND cp -f parser.out "${CMAKE_CURRENT_SOURCE_DIR}/"
|
||||
COMMAND mv -f parser.c parser.cpp
|
||||
MAIN_DEPENDENCY parser.lemon
|
||||
DEPENDS commands.h
|
||||
)
|
||||
|
||||
add_library(DEBUGGER_LIB ${DEBUGGER_SRC})
|
@ -1,30 +0,0 @@
|
||||
#ifndef __debugger_commands__
|
||||
#define __debugger_commands__
|
||||
|
||||
|
||||
enum {
|
||||
NullCommand,
|
||||
Help,
|
||||
Print,
|
||||
PrintRegisters,
|
||||
Dump,
|
||||
List,
|
||||
Info,
|
||||
Break,
|
||||
TBreak,
|
||||
Continue,
|
||||
Step,
|
||||
SetARegister,
|
||||
SetDRegister,
|
||||
SetXRegister,
|
||||
};
|
||||
|
||||
struct Command {
|
||||
bool valid;
|
||||
int action;
|
||||
uint32_t argc;
|
||||
uint32_t argv[10];
|
||||
};
|
||||
|
||||
|
||||
#endif
|
Loading…
Reference in New Issue
Block a user