Files
vt1200/ghidra_scripts/VerifyTMS34010.java

83 lines
3.6 KiB
Java

// 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;
}
}
}
}
}