mirror of
https://github.com/ksherlock/mpw.git
synced 2025-01-09 13:30:34 +00:00
debugger updates
This commit is contained in:
parent
6fbde7e1bf
commit
eedf675ebd
@ -25,8 +25,14 @@ add_custom_command(
|
||||
DEPENDS debugger.h
|
||||
)
|
||||
|
||||
add_custom_command(
|
||||
OUTPUT loadtrap.cpp
|
||||
COMMAND ragel -p -G2 -o loadtrap.cpp "${CMAKE_CURRENT_SOURCE_DIR}/loadtrap.rl"
|
||||
MAIN_DEPENDENCY loadtrap.rl
|
||||
DEPENDS debugger.h
|
||||
)
|
||||
|
||||
add_executable(mpw loader.cpp debugger.cpp address_map.cpp lexer.cpp parser.cpp)
|
||||
add_executable(mpw loader.cpp debugger.cpp address_map.cpp lexer.cpp parser.cpp loadtrap.cpp)
|
||||
target_link_libraries(mpw CPU_LIB)
|
||||
target_link_libraries(mpw TOOLBOX_LIB)
|
||||
target_link_libraries(mpw MPW_LIB)
|
||||
|
@ -16,6 +16,21 @@ public:
|
||||
|
||||
void clear();
|
||||
|
||||
std::unordered_map<uint32_t, unsigned>::iterator begin()
|
||||
{
|
||||
return map.begin();
|
||||
}
|
||||
|
||||
std::unordered_map<uint32_t, unsigned>::iterator end()
|
||||
{
|
||||
return map.end();
|
||||
}
|
||||
|
||||
size_t size()
|
||||
{
|
||||
return map.size();
|
||||
}
|
||||
|
||||
private:
|
||||
std::array<unsigned, 4096> pageMap;
|
||||
std::unordered_map<uint32_t, unsigned> map;
|
||||
@ -34,6 +49,21 @@ public:
|
||||
|
||||
void clear();
|
||||
|
||||
std::unordered_map<uint32_t, unsigned>::iterator begin()
|
||||
{
|
||||
return map.begin();
|
||||
}
|
||||
|
||||
std::unordered_map<uint32_t, unsigned>::iterator end()
|
||||
{
|
||||
return map.end();
|
||||
}
|
||||
|
||||
size_t size()
|
||||
{
|
||||
return map.size();
|
||||
}
|
||||
|
||||
private:
|
||||
std::unordered_map<uint32_t, unsigned> map;
|
||||
|
||||
|
@ -28,6 +28,8 @@
|
||||
#include <macos/traps.h>
|
||||
#include <macos/sysequ.h>
|
||||
|
||||
#include <mpw/mpw.h>
|
||||
|
||||
namespace {
|
||||
|
||||
bool sigInt = false;
|
||||
@ -41,6 +43,7 @@ namespace {
|
||||
AddressMap wbrkMap; // write breaks.
|
||||
ToolMap tbrkMap; // tool breaks.
|
||||
|
||||
std::unordered_map<std::string, uint16_t> toolMap;
|
||||
|
||||
|
||||
void hexdump(const uint8_t *data, ssize_t size, uint32_t address = 0)
|
||||
@ -439,6 +442,34 @@ void ToolBreak(int32_t tool)
|
||||
}
|
||||
}
|
||||
|
||||
void ToolBreak()
|
||||
{
|
||||
// list all tool breaks.
|
||||
|
||||
if (!tbrkMap.size())
|
||||
{
|
||||
printf("No tool breaks\n");
|
||||
return;
|
||||
}
|
||||
|
||||
std::vector<unsigned> v;
|
||||
v.reserve(tbrkMap.size());
|
||||
|
||||
for (auto kv : tbrkMap)
|
||||
{
|
||||
v.push_back(kv.first);
|
||||
}
|
||||
|
||||
std::sort(v.begin(), v.end());
|
||||
|
||||
for (auto trap : v)
|
||||
{
|
||||
const char *name = TrapName(trap);
|
||||
if (!name) name = "";
|
||||
printf("$%04x %s\n", trap, name);
|
||||
}
|
||||
}
|
||||
|
||||
void Break(int32_t address)
|
||||
{
|
||||
// 24-bit only, - address to remove.
|
||||
@ -463,6 +494,34 @@ void Break(int32_t address)
|
||||
}
|
||||
|
||||
|
||||
void Break()
|
||||
{
|
||||
// list all tool breaks.
|
||||
|
||||
if (!brkMap.size())
|
||||
{
|
||||
printf("No breaks\n");
|
||||
return;
|
||||
}
|
||||
|
||||
std::vector<unsigned> v;
|
||||
v.reserve(brkMap.size());
|
||||
|
||||
for (auto kv : brkMap)
|
||||
{
|
||||
v.push_back(kv.first);
|
||||
}
|
||||
|
||||
std::sort(v.begin(), v.end());
|
||||
|
||||
for (auto address : v)
|
||||
{
|
||||
printf("$%08x", address);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void Step(const Command &cmd)
|
||||
{
|
||||
@ -543,6 +602,20 @@ void SetXRegister(unsigned reg, uint32_t value)
|
||||
}
|
||||
|
||||
|
||||
uint16_t TrapNumber(const std::string &s)
|
||||
{
|
||||
auto iter = toolMap.find(s);
|
||||
if (iter == toolMap.end()) return 0;
|
||||
return iter->second;
|
||||
}
|
||||
|
||||
uint16_t TrapNumber(const char *cp)
|
||||
{
|
||||
if (!cp || !*cp) return 0;
|
||||
std::string s(cp);
|
||||
return TrapNumber(s);
|
||||
}
|
||||
|
||||
|
||||
// TODO -- RUN command - reload, re-initialize, re-execute
|
||||
// TODO -- parser calls commands directly (except trace/step/run/etc)
|
||||
@ -552,6 +625,13 @@ void Shell()
|
||||
|
||||
add_history("!Andy, it still has history!");
|
||||
|
||||
{
|
||||
// load the tool trap file.
|
||||
std::string path = MPW::RootDir();
|
||||
path += "/Traps.text";
|
||||
toolMap = LoadTrapFile(path);
|
||||
}
|
||||
|
||||
// start it up
|
||||
printf("MPW Debugger shell\n\n");
|
||||
disasm(cpuGetPC());
|
||||
|
@ -3,6 +3,9 @@
|
||||
|
||||
|
||||
#include <cstdint>
|
||||
#include <unordered_map>
|
||||
#include <functional>
|
||||
#include <string>
|
||||
|
||||
// Debugger is a function in MacTypes.h
|
||||
namespace Debug {
|
||||
@ -25,6 +28,12 @@ struct Command {
|
||||
|
||||
bool ParseLine(const char *iter, Command *command);
|
||||
|
||||
std::unordered_map<std::string, uint16_t> LoadTrapFile(const std::string &path);
|
||||
|
||||
uint16_t TrapNumber(const std::string &);
|
||||
uint16_t TrapNumber(const char *);
|
||||
|
||||
|
||||
void Shell();
|
||||
void Help();
|
||||
|
||||
@ -44,7 +53,10 @@ void SetDRegister(unsigned reg, uint32_t value);
|
||||
void SetXRegister(unsigned reg, uint32_t value);
|
||||
|
||||
void ToolBreak(int32_t tool);
|
||||
void ToolBreak();
|
||||
|
||||
void Break(int32_t address);
|
||||
void Break();
|
||||
|
||||
}
|
||||
|
||||
|
@ -304,4 +304,7 @@ bool ParseLine(const char *iter, Command *command)
|
||||
return command->valid;
|
||||
}
|
||||
|
||||
|
||||
|
||||
} // namespace Debugger
|
||||
|
||||
|
93
bin/loadtrap.rl
Normal file
93
bin/loadtrap.rl
Normal file
@ -0,0 +1,93 @@
|
||||
|
||||
#include <unordered_map>
|
||||
#include <string>
|
||||
#include <cstdio>
|
||||
|
||||
#include "debugger.h"
|
||||
|
||||
%%{
|
||||
|
||||
machine traplist;
|
||||
|
||||
action error {
|
||||
fprintf(stderr, "Invalid line: %d %.*s", line, (int)length, cp);
|
||||
fprintf(stderr, "%s - %x\n", name.c_str(), trap);
|
||||
}
|
||||
|
||||
main :=
|
||||
[ \t]*
|
||||
[_A-Za-z][_A-Za-z0-9]* @{
|
||||
name.push_back(fc);
|
||||
}
|
||||
[ \t]*
|
||||
'='
|
||||
[ \t]*
|
||||
('0x' | '$')
|
||||
[0-9A-Fa-f]+ @{
|
||||
trap = (trap << 4) + digittoint(fc);
|
||||
}
|
||||
[ \t\r\n]*
|
||||
|
||||
%eof {
|
||||
// final state
|
||||
map.emplace(name, trap);
|
||||
}
|
||||
@eof(error)
|
||||
$err(error)
|
||||
|
||||
;
|
||||
|
||||
}%%
|
||||
|
||||
namespace Debug {
|
||||
std::unordered_map<std::string, uint16_t> LoadTrapFile(const std::string &path)
|
||||
{
|
||||
%% write data nofinal;
|
||||
|
||||
FILE *fp;
|
||||
|
||||
std::unordered_map<std::string, uint16_t> map;
|
||||
|
||||
fp = fopen(path.c_str(), "r");
|
||||
if (!fp)
|
||||
{
|
||||
fprintf(stderr, "Unable to open file %s\n", path.c_str());
|
||||
return map;
|
||||
}
|
||||
|
||||
int line = 0;
|
||||
for(;;)
|
||||
{
|
||||
char *cp;
|
||||
|
||||
size_t length;
|
||||
cp = fgetln(fp, &length);
|
||||
if (!cp) break;
|
||||
++line;
|
||||
|
||||
while (isspace(*cp) && length)
|
||||
{
|
||||
++cp;
|
||||
length--;
|
||||
}
|
||||
if (!length) continue;
|
||||
if (*cp == '#') continue;
|
||||
|
||||
char *p = cp;
|
||||
char *pe = p + length;
|
||||
char *eof = p + length;
|
||||
int cs;
|
||||
|
||||
std::string name;
|
||||
uint16_t trap = 0;
|
||||
|
||||
%% write init;
|
||||
/* ... */
|
||||
%% write exec;
|
||||
}
|
||||
|
||||
fclose(fp);
|
||||
return map;
|
||||
}
|
||||
|
||||
}
|
@ -67,6 +67,11 @@ stmt ::= PRINT expr(a) EOL.
|
||||
Debug::Print(a);
|
||||
}
|
||||
|
||||
stmt ::= BREAK EOL.
|
||||
{
|
||||
Debug::Break();
|
||||
}
|
||||
|
||||
stmt ::= BREAK expr(a) EOL.
|
||||
{
|
||||
Debug::Break(a);
|
||||
@ -78,6 +83,11 @@ stmt ::= CONTINUE EOL.
|
||||
command->argc = 0;
|
||||
}
|
||||
|
||||
stmt ::= TBREAK EOL.
|
||||
{
|
||||
Debug::ToolBreak();
|
||||
}
|
||||
|
||||
stmt ::= TBREAK expr(a) EOL.
|
||||
{
|
||||
Debug::ToolBreak(a);
|
||||
|
Loading…
Reference in New Issue
Block a user