more debugger functionality

This commit is contained in:
Kelvin Sherlock 2013-07-04 12:13:31 -04:00
parent 552d95f9e0
commit 27cd692790

View File

@ -188,46 +188,52 @@ namespace {
std::printf("\n");
}
}
bool ParseLine(const char *iter, Command *command);
extern "C" {
uint32_t debuggerReadLong(uint32_t address)
uint32_t disasm(uint32_t pc, uint16_t *op = nullptr)
{
uint32_t tmp = 0;
for (unsigned i = 0; i < 4; ++i)
static char strings[4][256];
if (pc >= Flags.memorySize)
{
if (address < Flags.memorySize)
tmp = (tmp << 8) + Flags.memory[address++];
if (op) *op = 0;
return pc;
}
return tmp;
}
uint16_t opcode = debuggerReadWord(pc);
if (op) *op = opcode;
uint16_t debuggerReadWord(uint32_t address)
if ((opcode & 0xf000) == 0xa000)
{
uint16_t tmp = 0;
for (unsigned i = 0; i < 2; ++i)
const char *name;
name = TrapName(opcode);
if (name)
{
if (address < Flags.memorySize)
tmp = (tmp << 8) + Flags.memory[address++];
printf("$%08X %-51s ; %04X\n", pc, name, opcode);
}
return tmp;
}
uint8_t debuggerReadByte(uint32_t address)
else
{
if (address < Flags.memorySize)
return Flags.memory[address];
printf("$%08X Tool #$%04X ; %04X\n",
pc, opcode, opcode);
}
return 0;
pc += 2;
return pc;
}
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]);
return pc;
}
}
void DebugHelp(const Command &cmd)
{
printf("help\n");
@ -278,6 +284,8 @@ void DebugDump(const Command &cmd)
}
}
void DebugList(const Command &cmd)
{
// TODO -- if no address, use previous address.
@ -291,41 +299,10 @@ void DebugList(const Command &cmd)
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]);
pc = disasm(pc);
}
}
}
@ -333,8 +310,30 @@ void DebugList(const Command &cmd)
void DebugPrintRegisters(const Command &cmd)
{
printf("PC: %08X CSR: %04x\n", cpuGetPC(), cpuGetSR());
char srbits[20];
uint16_t sr = cpuGetSR();
srbits[0] = sr & (1 << 15) ? 'T' : ' ';
srbits[1] = sr & (1 << 14) ? 'T' : ' ';
srbits[2] = sr & (1 << 13) ? 'S' : ' ';
srbits[3] = sr & (1 << 12) ? 'M' : ' ';
srbits[4] = ' ';
srbits[5] = sr & (1 << 10) ? 'I' : ' ';
srbits[6] = sr & (1 << 9) ? 'I' : ' ';
srbits[7] = sr & (1 << 8) ? 'I' : ' ';
srbits[8] = ' ';
srbits[9] = ' ';
srbits[10] = ' ';
srbits[11] = sr & (1 << 4) ? 'X' : ' ';
srbits[12] = sr & (1 << 3) ? 'N' : ' ';
srbits[13] = sr & (1 << 2) ? 'Z' : ' ';
srbits[14] = sr & (1 << 1) ? 'V' : ' ';
srbits[15] = sr & (1 << 0) ? 'C' : ' ';
srbits[16] = 0;
printf(" 0 1 2 3 4 5 6 7\n");
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)
@ -346,8 +345,178 @@ void DebugPrintRegisters(const Command &cmd)
cpuGetAReg(4), cpuGetAReg(5), cpuGetAReg(6), cpuGetAReg(7)
);
printf("PC: %08X CSR: %04x %s\n", cpuGetPC(), sr, srbits);
}
void DebugToolBreak(Command &cmd)
{
for (unsigned i = 0; i < cmd.argc; ++i)
{
int32_t tool = (int32_t)cmd.argv[i];
bool remove = false;
if (tool < 0)
{
tool = -tool;
remove = true;
}
if (tool >= 0xa000 && tool <= 0xafff)
{
if (remove) tbrkRemove(tool);
else tbrkAdd(tool);
}
else
{
fprintf(stderr, "Invalid tool: $%04x\n", tool);
}
}
}
void DebugBreak(Command &cmd)
{
// 24-bit only, - address to remove.
for (unsigned i = 0; i < cmd.argc; ++i)
{
int32_t address = (int32_t)cmd.argv[i];
bool remove = false;
if (address < 0)
{
address = -address;
remove = true;
}
if ((address & 0xff000000) == 0)
{
if (remove) brkRemove(address);
else brkAdd(address);
}
else
{
fprintf(stderr, "Invalid address: $%08x\n", address);
}
}
}
void DebugStep(const Command &cmd)
{
// TODO - step n to step specified # of instructions.
// TODO -- step @address to step until address?
// disasm 1 line, execute it.
int count = 0;
if (cmd.argc == 1) count = (int)cmd.argv[0];
if (count < 1) count = 1;
// TODO -- move to common function...
for (int i = 0; i < count; ++i)
{
uint16_t op;
cpuExecuteInstruction();
if (cpuGetStop()) break; // will this also be set by an interrupt?
uint32_t pc = cpuGetPC();
disasm(pc, &op);
// check for pc breaks
if (brkLookup(pc))
{
break;
}
// check for toolbreaks.
if ((op & 0xf000) == 0xa000)
{
if (tbrkLookup(op))
break;
}
uint32_t sp = cpuGetAReg(7);
if (sp < Flags.stackRange.first)
{
fprintf(stderr, "Stack overflow error\n");
break;
}
if (sp > Flags.stackRange.second)
{
fprintf(stderr, "Stack underflow error\n");
break;
}
}
}
void DebugSetARegister(Command &cmd)
{
if (cmd.argc != 2) return;
unsigned reg = cmd.argv[0];
uint32_t value = cmd.argv[1];
if (reg > 7) return;
if (reg == 7)
{
// sp/7 must be aligned.
if (value & 0x01)
{
fprintf(stderr, "Address is not aligned: $%08x\n", value);
return;
}
}
if (value > Flags.memorySize)
{
fprintf(stderr, "Warning: address exceeeds memory size: $%08x\n", value);
}
cpuSetAReg(reg, value);
}
void DebugSetDRegister(Command &cmd)
{
if (cmd.argc != 2) return;
unsigned reg = cmd.argv[0];
uint32_t value = cmd.argv[1];
cpuSetDReg(reg, value);
}
void DebugSetXRegister(Command &cmd)
{
if (cmd.argc != 2) return;
unsigned reg = cmd.argv[0];
uint32_t value = cmd.argv[1];
if (reg == 0)
{
if (value & 0x01)
{
fprintf(stderr, "Address is not aligned: $%08x\n", value);
return;
}
if (value > Flags.memorySize)
{
fprintf(stderr, "Warning: address exceeeds memory size: $%08x\n", value);
}
cpuSetPC(value);
return;
}
if (reg == 1)
{
cpuSetSR(value);
}
}
// todo -- add sigint trap. it shall set a flag to break.
void DebugShell()
@ -355,6 +524,11 @@ void DebugShell()
char *cp;
add_history("!Andy, it still has history!");
// start it up
printf("MPW Debugger shell\n\n");
disasm(cpuGetPC());
for(;;)
{
cp = readline("] ");
@ -391,6 +565,30 @@ void DebugShell()
DebugPrintRegisters(cmd);
break;
case Step:
DebugStep(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);
break;
default:
DebugHelp(cmd);
break;