mirror of
https://github.com/ksherlock/mpw.git
synced 2024-11-22 00:32:44 +00:00
disassembler
This commit is contained in:
parent
8dd95d50f2
commit
92b94373f3
@ -10,3 +10,7 @@ add_executable(mpw loader.cpp)
|
||||
target_link_libraries(mpw CPU_LIB)
|
||||
target_link_libraries(mpw TOOLBOX_LIB)
|
||||
target_link_libraries(mpw MPLITE_LIB)
|
||||
|
||||
|
||||
add_executable(disasm disasm.cpp traps.c)
|
||||
target_link_libraries(disasm CPU_LIB)
|
||||
|
213
bin/disasm.cpp
Normal file
213
bin/disasm.cpp
Normal file
@ -0,0 +1,213 @@
|
||||
#include <cstdio>
|
||||
#include <cstdint>
|
||||
#include <cassert>
|
||||
|
||||
#include <string>
|
||||
|
||||
#include <CoreServices/CoreServices.h>
|
||||
|
||||
#include <cpu/defs.h>
|
||||
#include <cpu/fmem.h>
|
||||
#include <cpu/CpuModule.h>
|
||||
|
||||
|
||||
|
||||
char strings[4][256];
|
||||
|
||||
const uint8_t *Memory = NULL;
|
||||
uint32_t MemorySize = 0;
|
||||
|
||||
|
||||
extern "C" { const char *TrapName(uint16_t trap); }
|
||||
|
||||
void ToolBox(uint32_t pc, uint16_t trap)
|
||||
{
|
||||
const char *name;
|
||||
|
||||
name = TrapName(trap);
|
||||
|
||||
if (name)
|
||||
{
|
||||
printf("$%08X %-51s ; %04X\n", pc, name, trap);
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("$%08X Tool #$%04X ; %04X\n", pc, trap, trap);
|
||||
}
|
||||
}
|
||||
|
||||
void help()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
|
||||
void code0(uint32_t data_size)
|
||||
{
|
||||
// dump the code 0 jump table.
|
||||
|
||||
uint32_t offset = 0;
|
||||
uint32_t pc;
|
||||
uint32_t size;
|
||||
printf("Above A5: $%08X\n", memoryReadLong(0));
|
||||
printf("Below A5: $%08X\n", memoryReadLong(4));
|
||||
printf("Jump Table Size: $%08X\n", size = memoryReadLong(8));
|
||||
printf("Jump Table Offset: $%08X\n", pc = memoryReadLong(12)); // aka CurJTOffset. should be 32.
|
||||
|
||||
offset = 16;
|
||||
|
||||
while (offset < data_size)
|
||||
{
|
||||
uint16_t off = memoryReadWord(offset);
|
||||
uint16_t seg = -1;
|
||||
if (memoryReadWord(offset + 2) == 0x3F3C && memoryReadWord(offset + 6) == 0xA9F0)
|
||||
{
|
||||
uint16_t seg = memoryReadWord(offset + 4);
|
||||
|
||||
// pc +2 since the first byte is the offset, not code.
|
||||
printf("$%08X %04X : %04X\n", pc + 2, seg, off);
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("$%08X ???\n", pc + 2);
|
||||
}
|
||||
offset += 8;
|
||||
pc += 8;
|
||||
}
|
||||
|
||||
printf("\n\n");
|
||||
}
|
||||
|
||||
void disasm(const char *name, int segment, uint32_t data_size)
|
||||
{
|
||||
|
||||
if (name && *name) printf("segment %d - %s\n", segment, name);
|
||||
else printf("segment %d\n", segment);
|
||||
|
||||
uint32_t pc = 0;
|
||||
|
||||
|
||||
uint16_t prevOP = 0;
|
||||
|
||||
while (pc < data_size)
|
||||
{
|
||||
for (unsigned j = 0; j < 4; ++j) strings[j][0] = 0;
|
||||
|
||||
uint16_t op = memoryReadWord(pc);
|
||||
|
||||
if (prevOP == 0x4E75 && op > 0x8000)
|
||||
{
|
||||
// RTS followed by debug symbol.
|
||||
unsigned len = (op >> 8) - 0x80;
|
||||
|
||||
std::string s;
|
||||
s.reserve(len);
|
||||
for (unsigned i = 0; i < len; ++ i)
|
||||
{
|
||||
|
||||
s.push_back(memoryReadByte(pc + 1 + i));
|
||||
}
|
||||
|
||||
printf("%s\n\n", s.c_str());
|
||||
pc = pc + 2 + len + 2;
|
||||
pc = (pc + 1) & ~0x01;
|
||||
|
||||
prevOP = 0;
|
||||
continue;
|
||||
}
|
||||
|
||||
if ((op & 0xf000) == 0xa000)
|
||||
{
|
||||
// tool call!
|
||||
|
||||
ToolBox(pc, op);
|
||||
pc += 2;
|
||||
prevOP = op;
|
||||
continue;
|
||||
}
|
||||
|
||||
pc = cpuDisOpcode(pc, strings[0], strings[1], strings[2], strings[3]);
|
||||
|
||||
// address, data, instruction, operand
|
||||
printf("%s %-10s %-40s ; %s\n", strings[0], strings[2], strings[3], strings[1]);
|
||||
|
||||
prevOP = op;
|
||||
}
|
||||
|
||||
printf("\n\n");
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
|
||||
ResFileRefNum refNum;
|
||||
FSRef ref;
|
||||
Handle h;
|
||||
|
||||
if (argc != 2)
|
||||
{
|
||||
help();
|
||||
return -1;
|
||||
}
|
||||
|
||||
assert( FSPathMakeRef( (const UInt8 *)argv[1], &ref, NULL) == noErr);
|
||||
|
||||
refNum = FSOpenResFile(&ref, fsRdPerm);
|
||||
assert(refNum != -1 );
|
||||
//UseResFile(refNum);
|
||||
|
||||
|
||||
cpuSetModel(3, 0); // 68030
|
||||
|
||||
int l = Count1Resources('CODE');
|
||||
|
||||
for (int i = 0; i < l; ++i)
|
||||
{
|
||||
ResAttributes attr;
|
||||
ResID resID;
|
||||
ResType resType;
|
||||
Str255 name;
|
||||
std::string cname;
|
||||
|
||||
h = Get1IndResource('CODE', i + 1);
|
||||
if (!h) continue;
|
||||
HLock(h);
|
||||
|
||||
|
||||
attr = GetResAttrs(h);
|
||||
GetResInfo(h, &resID, &resType, name);
|
||||
|
||||
// name is a p-string.
|
||||
if (name[0])
|
||||
{
|
||||
int l = name[0];
|
||||
cname.assign(name + 1, name + 1 + l);
|
||||
}
|
||||
|
||||
uint32_t size = GetHandleSize(h);
|
||||
uint8_t *data = *( uint8_t **)h;
|
||||
|
||||
if (resID == 0)
|
||||
{
|
||||
memorySetMemory(data, size);
|
||||
code0(size);
|
||||
}
|
||||
else
|
||||
{
|
||||
// 4-byte header for segment stuff.
|
||||
data += 4;
|
||||
size -= 4;
|
||||
memorySetMemory(data, size);
|
||||
disasm(cname.c_str(), resID, size);
|
||||
}
|
||||
|
||||
memorySetMemory(nullptr, 0);
|
||||
|
||||
ReleaseResource(h);
|
||||
}
|
||||
|
||||
|
||||
CloseResFile(refNum);
|
||||
|
||||
return 0;
|
||||
}
|
Loading…
Reference in New Issue
Block a user