diff --git a/bin/CMakeLists.txt b/bin/CMakeLists.txt index 8f9cbf5..6c491f3 100644 --- a/bin/CMakeLists.txt +++ b/bin/CMakeLists.txt @@ -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) diff --git a/bin/disasm.cpp b/bin/disasm.cpp new file mode 100644 index 0000000..f01255c --- /dev/null +++ b/bin/disasm.cpp @@ -0,0 +1,213 @@ +#include +#include +#include + +#include + +#include + +#include +#include +#include + + + +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; +} \ No newline at end of file diff --git a/bin/Traps.c b/bin/traps.c similarity index 100% rename from bin/Traps.c rename to bin/traps.c