// Verify the TMS34010 language load + disassembly and print a few regions. // // NOTE: the TMS34010 module ships "Midway arcade" default memory blocks // (VRAM/RAM/GFX/ROM ...), so currentProgram.getImageBase() is NOT the address // of our loaded ROM. We locate the loaded block by name instead. //@category VT1200 import ghidra.app.script.GhidraScript; import ghidra.app.cmd.disassemble.DisassembleCommand; import ghidra.program.model.address.Address; import ghidra.program.model.address.AddressSet; import ghidra.program.model.address.AddressSpace; import ghidra.program.model.listing.Instruction; import ghidra.program.model.mem.MemoryBlock; public class VerifyTMS34010 extends GhidraScript { @Override public void run() throws Exception { AddressSpace space = currentProgram.getAddressFactory().getDefaultAddressSpace(); println("=== program: " + currentProgram.getName()); println("=== language: " + currentProgram.getLanguageID()); println("=== image base: 0x" + Long.toHexString(currentProgram.getImageBase().getOffset()) + " (language default)"); // The loaded ROM is the only *initialized* block; the language's // default blocks are all uninitialized. Pick the largest such block. long base = -1; long best = -1; for (MemoryBlock b : currentProgram.getMemory().getBlocks()) { if (b.isInitialized()) { long len = b.getEnd().getOffset() - b.getStart().getOffset(); println(String.format(" loaded block %-8s %s - %s (%,d bytes)", b.getName(), b.getStart(), b.getEnd(), len + 1)); if (len > best) { best = len; base = b.getStart().getOffset(); } } } if (base < 0) { base = currentProgram.getImageBase().getOffset(); } println(String.format("=== ROM block base: 0x%08X", base)); // Disassemble by following control flow from the reset target and the // resolvable interrupt vectors, bounded to the ROM block. MemoryBlock rom = null; for (MemoryBlock b : currentProgram.getMemory().getBlocks()) { if (b.isInitialized() && b.getStart().getOffset() == base) { rom = b; } } AddressSet restrict = new AddressSet(space.getAddress(base), space.getAddress(base + 0x1C0000 - 1)); AddressSet starts = new AddressSet(); starts.add(space.getAddress(base + 0x8)); // reset target (POST) for (long o : new long[] { 0xF88, 0xF98, 0xFA0 }) { starts.add(space.getAddress(base + o)); // vector 1, 22, 23 } new DisassembleCommand(starts, restrict, true).applyTo(currentProgram, monitor); // the module's incomplete pcode limits flow-following, so also // disassemble the boot/exception bank (first 256 KiB) linearly. AddressSet bank0 = new AddressSet(space.getAddress(base), space.getAddress(base + 0x40000 - 1)); new DisassembleCommand(bank0, null, false).applyTo(currentProgram, monitor); long[] offs = { 0x0, 0x8, 0xF88 }; // header, reset target, vector-1 target for (long o : offs) { println(String.format("--- ROM+0x%X ---", o)); int n = 0; for (Instruction ins : currentProgram.getListing() .getInstructions(space.getAddress(base + o), true)) { println(String.format(" 0x%08X: %s", ins.getAddress().getOffset(), ins)); if (++n >= 8) { break; } } } } }