From c8cd1c64bcb799b89aef85dbcda9c4c8fed36b36 Mon Sep 17 00:00:00 2001 From: qufb Date: Thu, 20 Oct 2022 00:30:04 +0100 Subject: [PATCH] Extend 32X support --- src/main/java/sega/MarsUserHeader.java | 93 ++++++++++++ src/main/java/sega/SegaLoader.java | 201 +++++++++++++++++++++---- src/main/java/sega/SegmentOptions.java | 34 +++++ 3 files changed, 302 insertions(+), 26 deletions(-) create mode 100644 src/main/java/sega/MarsUserHeader.java create mode 100644 src/main/java/sega/SegmentOptions.java diff --git a/src/main/java/sega/MarsUserHeader.java b/src/main/java/sega/MarsUserHeader.java new file mode 100644 index 0000000..de32cc7 --- /dev/null +++ b/src/main/java/sega/MarsUserHeader.java @@ -0,0 +1,93 @@ +package sega; + +import java.io.IOException; + +import ghidra.app.util.bin.BinaryReader; +import ghidra.app.util.bin.StructConverter; +import ghidra.program.model.data.DataType; +import ghidra.program.model.data.Structure; +import ghidra.program.model.data.StructureDataType; + +class MarsUserHeader implements StructConverter { + private byte[] moduleName = null; + private long version = 0; + private long sourceAddress = 0; + private long destinationAddress = 0; + private long size = 0; + private long sh2MasterStartAddress = 0; + private long sh2SlaveStartAddress = 0; + private long sh2MasterVectorBaseAddress = 0; + private long sh2SlaveVectorBaseAddress = 0; + + MarsUserHeader(BinaryReader reader) throws IOException { + + if (reader.length() < 0x2d) { + return; + } + + reader.setPointerIndex(0x3c0); + + moduleName = reader.readNextByteArray(0x10); + version = reader.readNextUnsignedInt(); + sourceAddress = reader.readNextUnsignedInt(); + destinationAddress = reader.readNextUnsignedInt(); + size = reader.readNextUnsignedInt(); + sh2MasterStartAddress = reader.readNextUnsignedInt(); + sh2SlaveStartAddress = reader.readNextUnsignedInt(); + sh2MasterVectorBaseAddress = reader.readNextUnsignedInt(); + sh2SlaveVectorBaseAddress = reader.readNextUnsignedInt(); + } + + @Override + public DataType toDataType() { + Structure s = new StructureDataType("MARSUserHeader", 0); + + s.add(STRING, 0x10, "moduleName", null); + s.add(DWORD, 0x04, "version", null); + s.add(POINTER, 0x04, "sourceAddress", null); + s.add(POINTER, 0x04, "destinationAddress", null); + s.add(DWORD, 0x04, "size", null); + s.add(POINTER, 0x04, "sh2MasterStartAddress", null); + s.add(POINTER, 0x04, "sh2SlaveStartAddress", null); + s.add(POINTER, 0x04, "sh2MasterVectorBaseAddress", null); + s.add(POINTER, 0x04, "sh2SlaveVectorBaseAddress", null); + + return s; + } + + public byte[] getModuleName() { + return moduleName; + } + + public long getVersion() { + return version; + } + + public long getSourceAddress() { + return sourceAddress; + } + + public long getDestinationAddress() { + return destinationAddress; + } + + public long getSize() { + return size; + } + + public long getSh2MasterStartAddress() { + return sh2MasterStartAddress; + } + + public long getSh2SlaveStartAddress() { + return sh2SlaveStartAddress; + } + + public long getSh2MasterVectorBaseAddress() { + return sh2MasterVectorBaseAddress; + } + + public long getSh2SlaveVectorBaseAddress() { + return sh2SlaveVectorBaseAddress; + } +} diff --git a/src/main/java/sega/SegaLoader.java b/src/main/java/sega/SegaLoader.java index b69b217..083fd9d 100644 --- a/src/main/java/sega/SegaLoader.java +++ b/src/main/java/sega/SegaLoader.java @@ -4,9 +4,9 @@ * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at - * + * * http://www.apache.org/licenses/LICENSE-2.0 - * + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. @@ -22,6 +22,7 @@ import docking.widgets.OptionDialog; import ghidra.app.cmd.data.CreateArrayCmd; +import ghidra.app.plugin.core.analysis.AutoAnalysisManager; import ghidra.app.util.Option; import ghidra.app.util.bin.BinaryReader; import ghidra.app.util.bin.ByteProvider; @@ -29,9 +30,11 @@ import ghidra.app.util.opinion.AbstractLibrarySupportLoader; import ghidra.app.util.opinion.LoadSpec; import ghidra.framework.store.LockException; +import ghidra.program.disassemble.Disassembler; import ghidra.program.flatapi.FlatProgramAPI; import ghidra.program.model.address.Address; import ghidra.program.model.address.AddressOverflowException; +import ghidra.program.model.address.AddressSet; import ghidra.program.model.data.ByteDataType; import ghidra.program.model.data.DWordDataType; import ghidra.program.model.data.DataType; @@ -39,12 +42,14 @@ import ghidra.program.model.data.DataUtilities.ClearDataMode; import ghidra.program.model.data.WordDataType; import ghidra.program.model.lang.LanguageCompilerSpecPair; +import ghidra.program.model.listing.BookmarkType; import ghidra.program.model.listing.Program; import ghidra.program.model.mem.Memory; import ghidra.program.model.mem.MemoryBlock; import ghidra.program.model.mem.MemoryConflictException; import ghidra.program.model.symbol.SourceType; import ghidra.program.model.util.CodeUnitInsertionException; +import ghidra.util.exception.CancelledException; import ghidra.util.exception.InvalidInputException; import ghidra.util.task.TaskMonitor; @@ -54,9 +59,11 @@ public class SegaLoader extends AbstractLibrarySupportLoader { public static final String LOADER_NAME = "Sega Mega Drive / Genesis Loader"; - + private VectorsTable vectors; private GameHeader header; + private MarsUserHeader marsUserHeader; + private SegmentOptions segmentOptions; @Override public String getName() { @@ -71,6 +78,10 @@ public Collection findSupportedLoadSpecs(ByteProvider provider) throws if (reader.readAsciiString(0x100, 4).equals("SEGA")) { loadSpecs.add(new LoadSpec(this, 0, new LanguageCompilerSpecPair("68000:BE:32:MC68020", "default"), true)); + + if (reader.readAsciiString(0x3c0, 15).equals("MARS CHECK MODE")) { + loadSpecs.add(new LoadSpec(this, 0, new LanguageCompilerSpecPair("SuperH:BE:32:SH-2", "default"), false)); + } } return loadSpecs; @@ -84,30 +95,36 @@ protected void load(ByteProvider provider, LoadSpec loadSpec, List