Last active
November 19, 2021 18:53
-
-
Save Ced2911/1bba9b4893ec05268709a4a5b7917cfe to your computer and use it in GitHub Desktop.
SaturnBios.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
//TODO write a description for this script | |
//@author | |
//@category _NEW_ | |
//@keybinding | |
//@menupath | |
//@toolbar | |
import ghidra.app.script.GhidraScript; | |
import ghidra.program.model.util.*; | |
import ghidra.program.model.reloc.*; | |
import ghidra.program.model.data.*; | |
import ghidra.program.model.block.*; | |
import ghidra.program.model.symbol.*; | |
import ghidra.program.model.scalar.*; | |
import ghidra.program.model.mem.*; | |
import ghidra.program.model.listing.*; | |
import ghidra.program.model.lang.*; | |
import ghidra.program.model.pcode.*; | |
import ghidra.program.model.address.*; | |
import ghidra.app.util.importer.MessageLog; | |
import ghidra.util.task.TaskMonitor; | |
import ghidra.feature.fid.hash.FidHashQuad; | |
import ghidra.feature.fid.service.FidService; | |
import ghidra.program.model.listing.BookmarkType; | |
import ghidra.program.model.data.DataType; | |
import ghidra.program.model.data.AIFFDataType; | |
import java.util.ArrayList; | |
import java.util.HashMap; | |
import java.util.Map; | |
public class SaturnBios extends GhidraScript { | |
private MessageLog log; | |
public void createMemoryRegion( | |
// | |
String regionName, long startAddress, long endAddress, | |
// rwx | |
boolean read, boolean write, boolean execute, boolean _volatile, | |
// ... | |
Program program, TaskMonitor monitor, MessageLog log) { | |
// Direct | |
try { | |
Address addr; | |
MemoryBlock block; | |
long length = (endAddress - startAddress) + 1L; | |
addr = program.getAddressFactory().getDefaultAddressSpace().getAddress(startAddress); | |
if (program.getMemory().getBlock(addr) != null) { | |
block = program.getMemory().getBlock(addr); | |
block.setName(regionName); | |
} else { | |
block = program.getMemory().createInitializedBlock(regionName, addr, length, (byte) 0x00, monitor, | |
false); | |
} | |
block.setRead(read); | |
block.setWrite(write); | |
block.setExecute(execute); | |
// block.setVolatile(_volatile); | |
if ((startAddress & 0x20000000) == 0) { | |
// Mirror | |
Address cacheAddr; | |
cacheAddr = program.getAddressFactory().getDefaultAddressSpace().getAddress(startAddress | 0x20000000); | |
if (program.getMemory().getBlock(cacheAddr) != null) { | |
block = program.getMemory().getBlock(cacheAddr); | |
block.setName(regionName); | |
} else { | |
block = program.getMemory().createByteMappedBlock(regionName + "_mirror", cacheAddr, addr, length, | |
false); | |
} | |
block.setRead(read); | |
block.setWrite(write); | |
block.setExecute(execute); | |
// block.setVolatile(_volatile); | |
} | |
} catch (Exception e) { | |
log.appendException(e); | |
println("Failed to create region: " + regionName + e.getMessage()); | |
} | |
} | |
// | |
// Memory-Mapped Registers | |
// | |
// label the SMPC registers | |
public long labelCDRegisters(Program program, MessageLog log) { | |
// | |
// CD registers taken from: https://wiki.yabause.org/index.php5?title=CDBlock | |
// | |
final Long CD_BASE = 0x25890000L; | |
String name = "CD_"; | |
Address addr = program.getAddressFactory().getDefaultAddressSpace().getAddress(CD_BASE); | |
try { | |
addRegsU16(CD_BASE + 0x08, name + "HIRQ"); | |
addRegsU16(CD_BASE + 0x0C, name + "HIRQ_MASK"); | |
addRegsU16(CD_BASE + 0x18, name + "CR1"); | |
addRegsU16(CD_BASE + 0x1C, name + "CR2"); | |
addRegsU16(CD_BASE + 0x20, name + "CR3"); | |
addRegsU16(CD_BASE + 0x24, name + "CR4"); | |
addRegsU16(CD_BASE + 0x28, name + "MPEGRGB"); | |
} catch (Exception e) { | |
log.appendException(e); | |
} | |
return 0; | |
} | |
// | |
public long labelArcade(Program program, MessageLog log) { | |
// | |
// CD registers taken from: https://wiki.yabause.org/index.php5?title=CDBlock | |
// | |
final Long IO_BASE = 0x20400000L; | |
String name = "ARC_IO_"; | |
Address addr = program.getAddressFactory().getDefaultAddressSpace().getAddress(IO_BASE); | |
try { | |
addRegsU8(IO_BASE + 0x01, name + "A_P1"); | |
addRegsU8(IO_BASE + 0x03, name + "B_P2"); | |
addRegsU8(IO_BASE + 0x05, name + "C_SYS"); | |
addRegsU8(IO_BASE + 0x07, name + "D_OUT"); | |
addRegsU8(IO_BASE + 0x09, name + "E_P3"); | |
addRegsU8(IO_BASE + 0x0b, name + "F_P4"); | |
addRegsU8(IO_BASE + 0x0d, name + "G"); | |
addRegsU8(IO_BASE + 0x0f, name + "unused"); | |
addRegsU8(IO_BASE + 0x11, name + "DIR"); | |
addRegsU8(IO_BASE + 0x13, name + "TX1"); | |
addRegsU8(IO_BASE + 0x15, name + "TX2"); | |
addRegsU8(IO_BASE + 0x17, name + "RX1"); | |
addRegsU8(IO_BASE + 0x19, name + "RX2"); | |
addRegsU8(IO_BASE + 0x1b, name + "FLAG"); | |
addRegsU8(IO_BASE + 0x1d, name + "MODE"); | |
addRegsU8(IO_BASE + 0x1f, name + "PORT_AD"); | |
} catch (Exception e) { | |
log.appendException(e); | |
} | |
return 0; | |
} | |
// label the onchip registers 0xFFFFFE00 - 0xFFFFFFFF | |
public long labelOnchipRegisters(Program program, MessageLog log) { | |
// | |
// Onchip registers taken from: | |
// https://github.com/Yabause/yabause/blob/master/yabause/src/sh2core.c | |
// | |
String name = "Onchip_"; | |
Address onChipAddr = program.getAddressFactory().getDefaultAddressSpace().getAddress(0xFFFFFE00); | |
Address addr; | |
final Long BASE = 0xFFFFFE00L; | |
try { | |
addRegsU8(BASE + 0x000, name + "SMR"); | |
addRegsU8(BASE + 0x001, name + "BRR"); | |
addRegsU8(BASE + 0x002, name + "SCR"); | |
addRegsU8(BASE + 0x003, name + "TDR"); | |
addRegsU8(BASE + 0x004, name + "SSR"); | |
addRegsU8(BASE + 0x005, name + "RDR"); | |
addRegsU8(BASE + 0x010, name + "TIER"); | |
addRegsU8(BASE + 0x011, name + "FTCSR"); | |
addRegsU8(BASE + 0x012, name + "FTCSR.part.h"); | |
addRegsU8(BASE + 0x013, name + "FTCSR.part.L"); | |
addRegsU8(BASE + 0x014, name + "OCRA_OCRB_high"); | |
addRegsU8(BASE + 0x016, name + "TCR"); | |
addRegsU8(BASE + 0x017, name + "TOCR"); | |
addRegsU16(BASE + 0x018, name + "FICR"); | |
addRegsU16(BASE + 0x060, name + "IPRB"); | |
addRegsU16(BASE + 0x062, name + "VCRA"); | |
addRegsU16(BASE + 0x064, name + "VCRB"); | |
addRegsU16(BASE + 0x066, name + "VCRC"); | |
addRegsU16(BASE + 0x068, name + "VCRD"); | |
addRegsU8(BASE + 0x080, name + "WTCSR"); | |
addRegsU8(BASE + 0x081, name + "WTCNT"); | |
addRegsU16(BASE + 0x092, name + "CCR"); | |
addRegsU8(BASE + 0x0E0, name + "ICR_high"); | |
addRegsU8(BASE + 0x0E1, name + "ICR"); | |
addRegsU8(BASE + 0x0E2, name + "IPRA_high"); | |
addRegsU8(BASE + 0x0E3, name + "IPRA"); | |
addRegsU8(BASE + 0x0E4, name + "VCRWDT_high"); | |
addRegsU8(BASE + 0x0E5, name + "WCRWDT"); | |
addRegsU16(BASE + 0x100, name + "DVSR"); | |
addRegsU16(BASE + 0x120, name + "DVSR"); | |
addRegsU16(BASE + 0x104, name + "DVDNTL"); | |
addRegsU16(BASE + 0x124, name + "DVDNTL"); | |
addRegsU16(BASE + 0x108, name + "DVCR"); | |
addRegsU16(BASE + 0x128, name + "DVCR"); | |
addRegsU16(BASE + 0x10C, name + "VCRDIV"); | |
addRegsU16(BASE + 0x12C, name + "VCRDIV"); | |
addRegsU16(BASE + 0X110, name + "DVDNTH"); | |
addRegsU16(BASE + 0x130, name + "DVDNTH"); | |
addRegsU16(BASE + 0x114, name + "DVDNTL"); | |
addRegsU16(BASE + 0x134, name + "DVDNTL"); | |
addRegsU16(BASE + 0x118, name + "DVDNTUH"); | |
addRegsU16(BASE + 0x138, name + "DVDNTUH"); | |
addRegsU16(BASE + 0x11C, name + "DVDNTUL"); | |
addRegsU16(BASE + 0x13C, name + "DVDNTUL"); | |
addRegsU16(BASE + 0x180, name + "SAR0"); | |
addRegsU16(BASE + 0x184, name + "DAR0"); | |
addRegsU16(BASE + 0x188, name + "TCR0"); | |
addRegsU16(BASE + 0x18C, name + "CHCR0"); | |
addRegsU16(BASE + 0x190, name + "SAR1"); | |
addRegsU16(BASE + 0x194, name + "DAR1"); | |
addRegsU16(BASE + 0x198, name + "TCR1"); | |
addRegsU16(BASE + 0x19C, name + "CHCR1"); | |
addRegsU16(BASE + 0x1A0, name + "VCRDMA0"); | |
addRegsU16(BASE + 0x1A8, name + "VCRDMA1"); | |
addRegsU16(BASE + 0x1B0, name + "DMA0R"); | |
addRegsU16(BASE + 0x1E0, name + "BCR1"); | |
addRegsU16(BASE + 0x1E4, name + "BCR2"); | |
addRegsU16(BASE + 0x1E8, name + "WCR"); | |
addRegsU16(BASE + 0x1EC, name + "MCR"); | |
addRegsU16(BASE + 0x1F0, name + "RTCSR"); | |
addRegsU16(BASE + 0x1F4, name + "RTCNT"); | |
addRegsU16(BASE + 0x1F8, name + "RTCOR"); | |
} catch (Exception e) { | |
log.appendException(e); | |
} | |
return 0; | |
} | |
// label the SCU registers | |
public long labelSCURegisters(Program program, MessageLog log) { | |
// | |
// SCU registers taken from: | |
// https://github.com/ijacquez/libyaul/blob/develop/libyaul/scu/scu/map.h | |
// | |
final Long SCU_BASE = 0x25FE0000L; | |
String name = "SCU_"; | |
try { | |
addRegsU32(SCU_BASE + 0x0000, name + "D0R"); | |
addRegsU32(SCU_BASE + 0x0004, name + "D0W"); | |
addRegsU32(SCU_BASE + 0x0008, name + "D0C"); | |
addRegsU32(SCU_BASE + 0x000C, name + "D0AD"); | |
addRegsU32(SCU_BASE + 0x0010, name + "D0EN"); | |
addRegsU32(SCU_BASE + 0x0014, name + "D0MD"); | |
addRegsU32(SCU_BASE + 0x0020, name + "D1R"); | |
addRegsU32(SCU_BASE + 0x0024, name + "D1W"); | |
addRegsU32(SCU_BASE + 0x0028, name + "D1C"); | |
addRegsU32(SCU_BASE + 0x002C, name + "D1AD"); | |
addRegsU32(SCU_BASE + 0x0030, name + "D1EN"); | |
addRegsU32(SCU_BASE + 0x0034, name + "D1MD"); | |
addRegsU32(SCU_BASE + 0x0040, name + "D2R"); | |
addRegsU32(SCU_BASE + 0x0044, name + "D2W"); | |
addRegsU32(SCU_BASE + 0x0048, name + "D2C"); | |
addRegsU32(SCU_BASE + 0x004C, name + "D2AD"); | |
addRegsU32(SCU_BASE + 0x0050, name + "D2EN"); | |
addRegsU32(SCU_BASE + 0x0054, name + "D2MD"); | |
addRegsU32(SCU_BASE + 0x0060, name + "DSTP"); | |
addRegsU32(SCU_BASE + 0x007C, name + "DSTA"); | |
addRegsU32(SCU_BASE + 0x0080, name + "PPAF"); | |
addRegsU32(SCU_BASE + 0x0084, name + "PPD"); | |
addRegsU32(SCU_BASE + 0x0088, name + "PDA"); | |
addRegsU32(SCU_BASE + 0x008C, name + "PDD"); | |
addRegsU32(SCU_BASE + 0x0090, name + "T0C"); | |
addRegsU32(SCU_BASE + 0x0094, name + "T1S"); | |
addRegsU32(SCU_BASE + 0x0098, name + "T1MD"); | |
addRegsU32(SCU_BASE + 0x00A0, name + "IMS"); | |
addRegsU32(SCU_BASE + 0x00A4, name + "IST"); | |
addRegsU32(SCU_BASE + 0x00A8, name + "AIACK"); | |
addRegsU32(SCU_BASE + 0x00B0, name + "ASR0"); | |
addRegsU32(SCU_BASE + 0x00B4, name + "ASR1"); | |
addRegsU32(SCU_BASE + 0x00B8, name + "AREF"); | |
addRegsU32(SCU_BASE + 0x00C4, name + "RSEL"); | |
addRegsU32(SCU_BASE + 0x00C8, name + "VER"); | |
} catch (Exception e) { | |
log.appendException(e); | |
} | |
return 0; | |
} | |
// label the SMPC registers | |
public long labelSMPCRegisters(Program program, MessageLog log) { | |
// | |
// SMPC registers taken from: | |
// https://github.com/ijacquez/libyaul/scu/bus/cpu/smpc/smpc/map.h | |
// | |
final Long SMPC_BASE = 0x20100000L; | |
String name = "SMPC_"; | |
try { | |
addRegsU8(SMPC_BASE + 0x01F, name + "COMREG"); | |
addRegsU8(SMPC_BASE + 0x061, name + "SR"); | |
addRegsU8(SMPC_BASE + 0x063, name + "SF"); | |
addRegsU8(SMPC_BASE + 0x075, name + "PDR1"); | |
addRegsU8(SMPC_BASE + 0x077, name + "PDR2"); | |
addRegsU8(SMPC_BASE + 0x079, name + "DDR1"); | |
addRegsU8(SMPC_BASE + 0x07B, name + "DDR2"); | |
addRegsU8(SMPC_BASE + 0x07D, name + "IOSEL1"); | |
addRegsU8(SMPC_BASE + 0x07D, name + "IOSEL2"); | |
addRegsU8(SMPC_BASE + 0x07F, name + "EXLE1"); | |
addRegsU8(SMPC_BASE + 0x07F, name + "EXLE2"); | |
} catch (Exception e) { | |
log.appendException(e); | |
} | |
return 0; | |
} | |
// label the VDP1 registers | |
public long labelVDP1Registers(Program program, MessageLog log) { | |
// | |
// VDP1 registers taken from: | |
// https://github.com/ijacquez/libyaulscu/bus/b/vdp/vdp1/map.h | |
// | |
final Long VDP1_BASE = 0x25D00000L; | |
String name = "VDP1_"; | |
try { | |
addRegsU16(VDP1_BASE + 0x0000, name + "TVMR"); | |
addRegsU16(VDP1_BASE + 0x0002, name + "FBCR"); | |
addRegsU16(VDP1_BASE + 0x0004, name + "PTMR"); | |
addRegsU16(VDP1_BASE + 0x0006, name + "EWDR"); | |
addRegsU16(VDP1_BASE + 0x0008, name + "EWLR"); | |
addRegsU16(VDP1_BASE + 0x000A, name + "EWRR"); | |
addRegsU16(VDP1_BASE + 0x000C, name + "ENDR"); | |
addRegsU16(VDP1_BASE + 0x0010, name + "EDSR"); | |
addRegsU16(VDP1_BASE + 0x0012, name + "LOPR"); | |
addRegsU16(VDP1_BASE + 0x0014, name + "COPR"); | |
addRegsU16(VDP1_BASE + 0x0016, name + "MODR"); | |
} catch (Exception e) { | |
log.appendException(e); | |
} | |
return 0; | |
} | |
// label the VDP2 registers | |
public long labelVDP2Registers(Program program, MessageLog log) { | |
// | |
// VDP2 registers taken from: | |
// https://github.com/ijacquez/libyaul/scu/bus/b/vdp/vdp2/map.h | |
// | |
final Long VDP_BASE = 0x25F80000L; | |
String name = "VDP2_"; | |
try { | |
addRegsU16(VDP_BASE + 0x0000, name + "TVMD"); | |
addRegsU16(VDP_BASE + 0x0002, name + "EXTEN"); | |
addRegsU16(VDP_BASE + 0x0004, name + "TVSTAT"); | |
addRegsU16(VDP_BASE + 0x0006, name + "VRSIZE"); | |
addRegsU16(VDP_BASE + 0x0008, name + "HCNT"); | |
addRegsU16(VDP_BASE + 0x000A, name + "VCNT"); | |
addRegsU16(VDP_BASE + 0x000E, name + "RAMCTL"); | |
addRegsU16(VDP_BASE + 0x0010, name + "CYCA0L"); | |
addRegsU16(VDP_BASE + 0x0012, name + "CYCA0U"); | |
addRegsU16(VDP_BASE + 0x0014, name + "CYCA1L"); | |
addRegsU16(VDP_BASE + 0x0016, name + "CYCA1U"); | |
addRegsU16(VDP_BASE + 0x0018, name + "CYCB0L"); | |
addRegsU16(VDP_BASE + 0x001A, name + "CYCB0U"); | |
addRegsU16(VDP_BASE + 0x001C, name + "CYCB1L"); | |
addRegsU16(VDP_BASE + 0x001E, name + "CYCB1U"); | |
addRegsU16(VDP_BASE + 0x0020, name + "BGON"); | |
addRegsU16(VDP_BASE + 0x0022, name + "MZCTL"); | |
addRegsU16(VDP_BASE + 0x0024, name + "SFSEL"); | |
addRegsU16(VDP_BASE + 0x0026, name + "SFCODE"); | |
addRegsU16(VDP_BASE + 0x0028, name + "CHCTLA"); | |
addRegsU16(VDP_BASE + 0x002A, name + "CHCTLB"); | |
addRegsU16(VDP_BASE + 0x002C, name + "BMPNA"); | |
addRegsU16(VDP_BASE + 0x002E, name + "BMPNB"); | |
addRegsU16(VDP_BASE + 0x0030, name + "PNCN0"); | |
addRegsU16(VDP_BASE + 0x0032, name + "PNCN1"); | |
addRegsU16(VDP_BASE + 0x0034, name + "PNCN2"); | |
addRegsU16(VDP_BASE + 0x0036, name + "PNCN3"); | |
addRegsU16(VDP_BASE + 0x0038, name + "PNCR"); | |
addRegsU16(VDP_BASE + 0x003A, name + "PLSZ"); | |
addRegsU16(VDP_BASE + 0x003C, name + "MPOFN"); | |
addRegsU16(VDP_BASE + 0x003E, name + "MPOFR"); | |
addRegsU16(VDP_BASE + 0x0040, name + "MPABN0"); | |
addRegsU16(VDP_BASE + 0x0042, name + "MPCDN0"); | |
addRegsU16(VDP_BASE + 0x0044, name + "MPABN1"); | |
addRegsU16(VDP_BASE + 0x0046, name + "MPCDN1"); | |
addRegsU16(VDP_BASE + 0x0048, name + "MPABN2"); | |
addRegsU16(VDP_BASE + 0x004A, name + "MPCDN2"); | |
addRegsU16(VDP_BASE + 0x004C, name + "MPABN3"); | |
addRegsU16(VDP_BASE + 0x004E, name + "MPCDN3"); | |
addRegsU16(VDP_BASE + 0x0050, name + "MPABRA"); | |
addRegsU16(VDP_BASE + 0x0052, name + "MPCDRA"); | |
addRegsU16(VDP_BASE + 0x0054, name + "MPEFRA"); | |
addRegsU16(VDP_BASE + 0x0056, name + "MPGHRA"); | |
addRegsU16(VDP_BASE + 0x0058, name + "MPIJRA"); | |
addRegsU16(VDP_BASE + 0x005A, name + "MPKLRA"); | |
addRegsU16(VDP_BASE + 0x005C, name + "MPMNRA"); | |
addRegsU16(VDP_BASE + 0x005E, name + "MPOPRA"); | |
addRegsU16(VDP_BASE + 0x0060, name + "MPABRB"); | |
addRegsU16(VDP_BASE + 0x0062, name + "MPCDRB"); | |
addRegsU16(VDP_BASE + 0x0064, name + "MPEFRB"); | |
addRegsU16(VDP_BASE + 0x0066, name + "MPGHRB"); | |
addRegsU16(VDP_BASE + 0x0068, name + "MPIJRB"); | |
addRegsU16(VDP_BASE + 0x006A, name + "MPKLRB"); | |
addRegsU16(VDP_BASE + 0x006C, name + "MPMNRB"); | |
addRegsU16(VDP_BASE + 0x006E, name + "MPOPRB"); | |
addRegsU16(VDP_BASE + 0x0070, name + "SCXIN0"); | |
addRegsU16(VDP_BASE + 0x0072, name + "SCXDN0"); | |
addRegsU16(VDP_BASE + 0x0074, name + "SCYIN0"); | |
addRegsU16(VDP_BASE + 0x0076, name + "SCYDN0"); | |
addRegsU16(VDP_BASE + 0x0078, name + "ZMXIN0"); | |
addRegsU16(VDP_BASE + 0x007A, name + "ZMXDN0"); | |
addRegsU16(VDP_BASE + 0x007C, name + "ZMYIN0"); | |
addRegsU16(VDP_BASE + 0x007E, name + "ZMYDN0"); | |
addRegsU16(VDP_BASE + 0x0080, name + "SCXIN1"); | |
addRegsU16(VDP_BASE + 0x0082, name + "SCXDN1"); | |
addRegsU16(VDP_BASE + 0x0084, name + "SCYIN1"); | |
addRegsU16(VDP_BASE + 0x0086, name + "SCYDN1"); | |
addRegsU16(VDP_BASE + 0x0088, name + "ZMXIN1"); | |
addRegsU16(VDP_BASE + 0x008A, name + "ZMXDN1"); | |
addRegsU16(VDP_BASE + 0x008C, name + "ZMYIN1"); | |
addRegsU16(VDP_BASE + 0x008E, name + "ZMYDN1"); | |
addRegsU16(VDP_BASE + 0x0090, name + "SCXN2"); | |
addRegsU16(VDP_BASE + 0x0092, name + "SCYN2"); | |
addRegsU16(VDP_BASE + 0x0094, name + "SCXN3"); | |
addRegsU16(VDP_BASE + 0x0096, name + "SCYN3"); | |
addRegsU16(VDP_BASE + 0x0098, name + "ZMCTL"); | |
addRegsU16(VDP_BASE + 0x009A, name + "SCRCTL"); | |
addRegsU16(VDP_BASE + 0x009C, name + "VCSTAU"); | |
addRegsU16(VDP_BASE + 0x009E, name + "VCSTAL"); | |
addRegsU16(VDP_BASE + 0x00A0, name + "LSTA0U"); | |
addRegsU16(VDP_BASE + 0x00A2, name + "LSTA0L"); | |
addRegsU16(VDP_BASE + 0x00A4, name + "LSTA1U"); | |
addRegsU16(VDP_BASE + 0x00A6, name + "LSTA1L"); | |
addRegsU16(VDP_BASE + 0x00A8, name + "LCTAU"); | |
addRegsU16(VDP_BASE + 0x00AA, name + "LCTAL"); | |
addRegsU16(VDP_BASE + 0x00AC, name + "BKTAU"); | |
addRegsU16(VDP_BASE + 0x00AE, name + "BKTAL"); | |
addRegsU16(VDP_BASE + 0x00B0, name + "RPMD"); | |
addRegsU16(VDP_BASE + 0x00B2, name + "RPRCTL"); | |
addRegsU16(VDP_BASE + 0x00B4, name + "KTCTL"); | |
addRegsU16(VDP_BASE + 0x00B6, name + "KTAOF"); | |
addRegsU16(VDP_BASE + 0x00B8, name + "OVPNRA"); | |
addRegsU16(VDP_BASE + 0x00BA, name + "OVPNRB"); | |
addRegsU16(VDP_BASE + 0x00BC, name + "RPTAU"); | |
addRegsU16(VDP_BASE + 0x00BE, name + "RPTAL"); | |
addRegsU16(VDP_BASE + 0x00C0, name + "WPSX0"); | |
addRegsU16(VDP_BASE + 0x00C2, name + "WPSY0"); | |
addRegsU16(VDP_BASE + 0x00C4, name + "WPEX0"); | |
addRegsU16(VDP_BASE + 0x00C6, name + "WPEY0"); | |
addRegsU16(VDP_BASE + 0x00C8, name + "WPSX1"); | |
addRegsU16(VDP_BASE + 0x00CA, name + "WPSY1"); | |
addRegsU16(VDP_BASE + 0x00CC, name + "WPEX1"); | |
addRegsU16(VDP_BASE + 0x00CE, name + "WPEY1"); | |
addRegsU16(VDP_BASE + 0x00D0, name + "WCTLA"); | |
addRegsU16(VDP_BASE + 0x00D2, name + "WCTLB"); | |
addRegsU16(VDP_BASE + 0x00D4, name + "WCTLC"); | |
addRegsU16(VDP_BASE + 0x00D6, name + "WCTLD"); | |
addRegsU16(VDP_BASE + 0x00D8, name + "LWTA0U"); | |
addRegsU16(VDP_BASE + 0x00DA, name + "LWTA0L"); | |
addRegsU16(VDP_BASE + 0x00DC, name + "LWTA1U"); | |
addRegsU16(VDP_BASE + 0x00DE, name + "LWTA1L"); | |
addRegsU16(VDP_BASE + 0x00E0, name + "SPCTL"); | |
addRegsU16(VDP_BASE + 0x00E2, name + "SDCTL"); | |
addRegsU16(VDP_BASE + 0x00E4, name + "CRAOFA"); | |
addRegsU16(VDP_BASE + 0x00E6, name + "CRAOFB"); | |
addRegsU16(VDP_BASE + 0x00E8, name + "LNCLEN"); | |
addRegsU16(VDP_BASE + 0x00EA, name + "SFPRMD"); | |
addRegsU16(VDP_BASE + 0x00EC, name + "CCCTL"); | |
addRegsU16(VDP_BASE + 0x00EE, name + "SFCCMD"); | |
addRegsU16(VDP_BASE + 0x00F0, name + "PRISA"); | |
addRegsU16(VDP_BASE + 0x00F2, name + "PRISB"); | |
addRegsU16(VDP_BASE + 0x00F4, name + "PRISC"); | |
addRegsU16(VDP_BASE + 0x00F6, name + "PRISD"); | |
addRegsU16(VDP_BASE + 0x00F8, name + "PRINA"); | |
addRegsU16(VDP_BASE + 0x00FA, name + "PRINB"); | |
addRegsU16(VDP_BASE + 0x00FC, name + "PRIR"); | |
addRegsU16(VDP_BASE + 0x0100, name + "CCRSA"); | |
addRegsU16(VDP_BASE + 0x0102, name + "CCRSB"); | |
addRegsU16(VDP_BASE + 0x0104, name + "CCRSC"); | |
addRegsU16(VDP_BASE + 0x0106, name + "CCRSD"); | |
addRegsU16(VDP_BASE + 0x0108, name + "CCRNA"); | |
addRegsU16(VDP_BASE + 0x010A, name + "CCRNB"); | |
addRegsU16(VDP_BASE + 0x010C, name + "CCRR"); | |
addRegsU16(VDP_BASE + 0x010E, name + "CCRLB"); | |
addRegsU16(VDP_BASE + 0x0110, name + "CLOFEN"); | |
addRegsU16(VDP_BASE + 0x0112, name + "CLOFSL"); | |
addRegsU16(VDP_BASE + 0x0114, name + "COAR"); | |
addRegsU16(VDP_BASE + 0x0116, name + "COAG"); | |
addRegsU16(VDP_BASE + 0x0118, name + "COAB"); | |
addRegsU16(VDP_BASE + 0x011A, name + "COBR"); | |
addRegsU16(VDP_BASE + 0x011C, name + "COBG"); | |
addRegsU16(VDP_BASE + 0x011E, name + "COBB"); | |
} catch (Exception e) { | |
log.appendException(e); | |
} | |
return 0; | |
} | |
private void findBootSound() { | |
AIFFDataType aiffdt = new AIFFDataType(); | |
Memory memory = currentProgram.getMemory(); | |
MemoryBlock[] blocks = memory.getBlocks(); | |
ArrayList<Address> foundAdresses = new ArrayList<Address>(); | |
for (int i = 0; i < blocks.length; i++) { | |
if (blocks[i].isInitialized()) { | |
Address start = blocks[i].getStart(); | |
Address found = null; | |
while (true) { | |
found = memory.findBytes(start, blocks[i].getEnd(), AIFFDataType.MAGIC, AIFFDataType.MAGIC_MASK, | |
true, monitor); | |
if (found != null) { | |
foundAdresses.add(found); | |
start = found.add(1); | |
} else | |
break; | |
} | |
} | |
} | |
for (int i = 0; i < foundAdresses.size(); i++) { | |
try { | |
Data data = getDataAt(foundAdresses.get(i)); | |
if (data == null) { | |
Data newData = createData(foundAdresses.get(i), aiffdt); | |
currentProgram.getBookmarkManager().setBookmark(foundAdresses.get(i), BookmarkType.ANALYSIS, | |
"Embedded Media", "BootSound"); | |
} | |
} catch (Exception e) { | |
println("Invalid at " + foundAdresses.get(i).toString()); | |
} | |
} | |
} | |
private void addRegsU8(Long address, String name) { | |
try { | |
createByte(toAddr(address)); | |
createLabel(toAddr(address), name, true); | |
} catch (Exception e) { | |
println("Invalid reg at " + name.toString()); | |
} | |
} | |
private void addRegsU16(Long address, String name) { | |
try { | |
createWord(toAddr(address)); | |
createLabel(toAddr(address), name, true); | |
} catch (Exception e) { | |
println("Invalid reg at " + name.toString() + e.getMessage()); | |
} | |
} | |
private void addRegsU32(Long address, String name) { | |
try { | |
createDWord(toAddr(address)); | |
createLabel(toAddr(address), name, true); | |
} catch (Exception e) { | |
println("Invalid reg at " + name.toString()); | |
} | |
} | |
// TODO: split this into separate script file so raw binaries can use this same | |
// code | |
// TODO: add missing memory sections | |
public void createSegaSaturnMemoryMap(Program program, TaskMonitor monitor, MessageLog log) { | |
try { | |
// 0x00000000 - 0x000FFFFF: Boot ROM | |
createMemoryRegion("BootROM", 0x00000000, 0x000FFFFF, true, false, true, false, program, monitor, log); | |
// 0x00100000 0x0017FFFF SMPC Registers | |
createMemoryRegion("SMPCRegisters", 0x00100000, 0x0017FFFF, true, true, false, true, program, monitor, log); | |
// 0x00180000 0x001FFFFF Backup RAM | |
createMemoryRegion("BackRam", 0x00180000, 0x001FFFFF, true, true, false, false, program, monitor, log); | |
// 0x00200000 - 0x002FFFFF: Work RAM Low | |
createMemoryRegion("LRam", 0x00200000, 0x002FFFFF + 1, true, true, true, false, program, monitor, log); | |
// 0x00300000 0x003FFFFF Random Data On Every Read (mostly $00) | |
createMemoryRegion("Random", 0x00300000, 0x003FFFFF, true, true, false, false, program, monitor, log); | |
// 0x00400000 0x007FFFFF Always Returns $0000 | |
createMemoryRegion("$0000", 0x00400000, 0x007FFFFF, true, true, false, false, program, monitor, log); | |
// 0x00800000 0x00FFFFFF Always Returns $00000001000200030004000500060007 | |
createMemoryRegion("$1234567", 0x00800000, 0x00FFFFFF, true, true, false, false, program, monitor, log); | |
// 0x01000000 0x01FFFFFF Always Returns $FFFF. | |
createMemoryRegion("$FFFF", 0x01000000, 0x01FFFFFF, true, true, true, false, program, monitor, log); | |
// 0x02000000 0x03FFFFFF A-Bus CS0 | |
createMemoryRegion("CS0", 0x02000000, 0x03FFFFFF, true, true, true, false, program, monitor, log); | |
// 0x04000000 0x04FFFFFF A-Bus CS1 | |
createMemoryRegion("CS1", 0x04000000, 0x04FFFFFF, true, true, true, false, program, monitor, log); | |
// 0x05000000 0x057FFFFF A-Bus Dummy | |
createMemoryRegion("CS1Dummy", 0x05000000, 0x057FFFFF, true, true, true, false, program, monitor, log); | |
// 0x05800000 0x058FFFFF A-Bus CS2 | |
createMemoryRegion("CS2", 0x05800000, 0x058FFFFF, true, true, true, false, program, monitor, log); | |
// 0x05900000 0x059FFFFF Lockup When Read | |
createMemoryRegion("LockupWhenRead", 0x05900000, 0x059FFFFF, true, true, false, false, program, monitor, | |
log); | |
// 0x05A00000 0x05AFFFFF 68000 Work RAM | |
createMemoryRegion("68000Ram", 0x05A00000, 0x05AFFFFF, true, true, false, false, program, monitor, log); | |
// 0x05B00000 0x05BFFFFF SCSP Registers | |
createMemoryRegion("SCSPRegisters", 0x05B00000, 0x05BFFFFF, true, true, false, true, program, monitor, log); | |
// 0x05C00000 0x05C7FFFF VDP1 VRAM | |
createMemoryRegion("VDP1Vram", 0x05C00000, 0x05C7FFFF, true, true, false, false, program, monitor, log); | |
// 0x05C80000 0x05CFFFFF VDP1 Framebuffer | |
createMemoryRegion("VDP1Framebuffer", 0x05C80000, 0x05CFFFFF, true, true, false, false, program, monitor, | |
log); | |
// 0x05D00000 0x05D7FFFF VDP1 Registers | |
createMemoryRegion("VDP1Registers", 0x05D00000, 0x05D7FFFF, true, true, false, true, program, monitor, log); | |
// 0x05D80000 0x05DFFFFF Lockup When Read2 | |
createMemoryRegion("LockupR2", 0x05D80000, 0x05DFFFFF, true, true, false, false, program, monitor, log); | |
// 0x05E00000 0x05EFFFFF VDP2 VRAM | |
createMemoryRegion("VDP2Vram", 0x05E00000, 0x05EFFFFF, true, true, false, false, program, monitor, log); | |
// 0x05F00000 0x05F7FFFF VDP2 CRAM | |
createMemoryRegion("VDP2Cram", 0x05F00000, 0x05F7FFFF, true, true, false, false, program, monitor, log); | |
// 0x05F80000 0x05FBFFFF VDP2 Registers | |
createMemoryRegion("VDP2Registers", 0x05F80000, 0x05FBFFFF, true, true, false, true, program, monitor, log); | |
// 0x05FC0000 0x05FDFFFF Always Returns $000E0000 | |
createMemoryRegion("AlwaysReturns$E0000", 0x05FC0000, 0x05FDFFFF, true, true, false, false, program, | |
monitor, log); | |
// 0x05FE0000 0x05FEFFFF SCU Registers | |
createMemoryRegion("SCURegisters", 0x05FE0000, 0x05FEFFFF, true, true, false, true, program, monitor, log); | |
// 0x05FF0000 0x05FFFFFF Unknown Registers | |
createMemoryRegion("UnknownRegisters", 0x05FF0000, 0x05FFFFFF, true, true, false, true, program, monitor, | |
log); | |
// 0x06000000 - 0x07FFFFFF: Work RAM High | |
createMemoryRegion("HRam", 0x06000000, 0x07FFFFFF, true, true, true, false, program, monitor, log); | |
// sh2regs | |
createMemoryRegion("SHRegs", 0xFFFFFE00, 0xFFFFFFFF, true, true, true, true, program, monitor, log); | |
labelCDRegisters(program, log); | |
labelOnchipRegisters(program, log); | |
labelSCURegisters(program, log); | |
labelSMPCRegisters(program, log); | |
labelVDP1Registers(program, log); | |
labelVDP2Registers(program, log); | |
labelArcade(program, log); | |
} catch (Exception e) { | |
log.appendException(e); | |
} | |
} | |
public void addBiosFunc(int addr, String name) { | |
try { | |
int ptrJump = getInt(toAddr(addr)); | |
Data ptrData = createDWord(toAddr(addr)); | |
createLabel(toAddr(addr), String.format("jmp_%s", name), true); | |
createMemoryReference(ptrData, toAddr(ptrJump), ghidra.program.model.symbol.RefType.DATA); | |
disassemble(toAddr(ptrJump)); | |
createLabel(toAddr(ptrJump), String.format("call_%s", name), true); | |
createFunction(toAddr(ptrJump), String.format("%s", name)); | |
} catch (Exception e) { | |
log.appendException(e); | |
} | |
} | |
private void setInt(int addr, int v) throws Exception { | |
setInt(toAddr(addr), v); | |
} | |
private void memcpy(int destAddr, int startAddr, int len) throws Exception { | |
for (int i = 0; i < len; i++) { | |
try { | |
int dw = getInt(toAddr(startAddr + i)); | |
setInt(destAddr + i, dw); | |
} catch (Exception e) { | |
log.appendException(e); | |
} | |
} | |
} | |
private void memoryMap() throws Exception { | |
createSegaSaturnMemoryMap(currentProgram, monitor, log); | |
// Copy | |
// memcpy(0x06000150, 0x750, 0x344); | |
// Copy ... | |
// memcpy(0x6001100, 0x0001100, 0x80000 - 0x1100); | |
// Bios version | |
clearListing(toAddr(0x0800)); | |
clearListing(toAddr(0x06000200)); | |
createAsciiString(toAddr(0x0800)); | |
try { | |
createAsciiString(toAddr(0x06000200)); | |
} catch (Exception e) { | |
log.appendException(e); | |
} | |
} | |
private void diss() throws Exception { | |
/* | |
* // Init bios.. setInt(0x06000210, 0x00000210); setInt(0x0600026C, | |
* 0x0000026C); setInt(0x06000274, 0x00000274); setInt(0x06000280, 0x00000280); | |
* setInt(0x0600029C, 0x0000029C); setInt(0x060002DC, 0x000002DC); | |
* setInt(0x06000300, 0x00000300); setInt(0x06000304, 0x00000304); | |
* setInt(0x06000310, 0x00000310); setInt(0x06000314, 0x00000314); | |
* setInt(0x06000320, 0x00000320); setInt(0x06000324, 0x00000000); | |
* setInt(0x06000330, 0x00000330); setInt(0x06000334, 0x00000334); | |
* setInt(0x06000340, 0x00000340); setInt(0x06000344, 0x00000344); | |
* setInt(0x06000348, 0xFFFFFFFF); setInt(0x06000354, 0x00000000); | |
* setInt(0x06000358, 0x00000358); | |
*/ | |
// 0x00000226 | |
// createDWord(toAddr(0x00000226)); | |
// createLabel(toAddr(0x00000226), "ReturnFromException", true); | |
// Interrupt handler | |
for (Integer i = 0x400; i < 0x480; i += 4) { | |
Data ptrData = createDWord(toAddr(0x06000000 + i)); | |
createLabel(toAddr(0x06000000 + i), String.format("BiosHandleScuInterrupt_%d", i), true); | |
} | |
// Some tables ?... | |
// createDwords(toAddr(0x2d4), (0x380 - 0x2d4) / 4); | |
// entry point ? | |
int entryPoint = getInt(toAddr(0x0000000)) & 0x1FFFFFFF; | |
Data entryPointData = createDWord(toAddr(0x0000000)); | |
createDWord(toAddr(0x0000000)); | |
createLabel(toAddr(entryPoint), "_ENTRY_POINT", true); | |
createFunction(toAddr(entryPoint), "_start"); | |
createMemoryReference(entryPointData, toAddr(entryPoint), ghidra.program.model.symbol.RefType.DATA); | |
// GBR | |
for (Integer i = 0; i < 0x200; i += 4) { | |
int ptrJump = getInt(toAddr(0x0000000 + i)) & 0x1FFFFFFF; | |
Data ptrData = createDWord(toAddr(0x00000000 + i)); | |
createMemoryReference(ptrData, toAddr(ptrJump), ghidra.program.model.symbol.RefType.DATA); | |
disassemble(toAddr(ptrJump)); | |
} | |
for (Integer i = 0; i < 0x200; i += 4) { | |
Data ptrData = createDWord(toAddr(0x06000000 + i)); | |
createLabel(toAddr(0x06000000 + i), String.format("itr_%d", i), true); | |
} | |
try { | |
int returnFromExceptionAddr = getInt(toAddr(0x0000020)); | |
createDWord(toAddr(returnFromExceptionAddr)); | |
createLabel(toAddr(returnFromExceptionAddr), "ReturnFromException", true); | |
} catch (Exception e) { | |
log.appendException(e); | |
} | |
try { | |
int stackPointerAddr = getInt(toAddr(0x04)); | |
createDWord(toAddr(stackPointerAddr)); | |
createLabel(toAddr(stackPointerAddr), "ResetStackPointer", true); | |
} catch (Exception e) { | |
log.appendException(e); | |
} | |
try { | |
int illegalInstAddr = getInt(toAddr(0x10)); | |
createDWord(toAddr(illegalInstAddr)); | |
createLabel(toAddr(illegalInstAddr), "IllegalInstrInterupt", true); | |
} catch (Exception e) { | |
log.appendException(e); | |
} | |
try { | |
int nmiAddr = getInt(toAddr(0x2C)); | |
createDWord(toAddr(nmiAddr)); | |
createLabel(toAddr(nmiAddr), "NMI", true); | |
} catch (Exception e) { | |
log.appendException(e); | |
} | |
createFunction(toAddr(0x50ea), "decompress_logo_font"); | |
createLabel(toAddr(0x25a00000), "SOUND_RAM", true); | |
createLabel(toAddr(0x24FFFFFF), "Cart_id", true); | |
// Bios call... | |
addBiosFunc(0x06000210, "BiosPowerOnMemoryClear"); | |
addBiosFunc(0x06000268, "BiosLoadSomething_at_06004000"); | |
addBiosFunc(0x0600026C, "BiosExecuteCDPlayer"); | |
addBiosFunc(0x06000270, "bios_check_cd_auth"); | |
addBiosFunc(0x06000274, "BiosCheckMPEGCard"); | |
addBiosFunc(0x06000280, "BiosChangeScuInterruptPriority"); | |
addBiosFunc(0x06000288, "bios_loadcd_boot"); | |
addBiosFunc(0x0600028C, "bios_loadcd_parse_validate_ip"); // BiosCDINIT2 | |
addBiosFunc(0x06000298, "bios_loadcd_xxx"); | |
addBiosFunc(0x060002A0, "scu_reset"); | |
addBiosFunc(0x060002C4, "bios_HRAM_entrypoint"); | |
addBiosFunc(0x060002CC, "bios_loadcd_read"); | |
addBiosFunc(0x060002DC, "bios_play_disc"); | |
addBiosFunc(0x060002DC, "BiosCDINIT1"); | |
addBiosFunc(0x06000300, "BiosSetScuInterrupt"); | |
addBiosFunc(0x06000304, "BiosGetScuInterrupt"); | |
addBiosFunc(0x06000310, "BiosSetSh2Interrupt"); | |
addBiosFunc(0x06000314, "BiosGetSh2Interrupt"); | |
addBiosFunc(0x06000320, "BiosChangeSystemClock"); | |
addBiosFunc(0x06000328, "BiosChangeSystemClock2"); | |
addBiosFunc(0x06000330, "BiosGetSemaphore"); | |
addBiosFunc(0x06000334, "BiosClearSemaphore"); | |
addBiosFunc(0x06000340, "BiosSetScuInterruptMask"); | |
addBiosFunc(0x06000344, "BiosChangeScuInterruptMask"); | |
addBiosFunc(0x06000334, "BiosMemSet"); | |
addBiosFunc(0x06000338, "BiosMemCpy"); | |
addRegsU32(0x06000248L, "region_flag"); | |
addBiosFunc(0x060002C8, "bios_1a3C"); | |
// bup... | |
addBiosFunc(0x06000358, "bios_bup_init"); | |
Data pubVectAddr = createDWord(toAddr(0x6000354)); | |
createLabel(toAddr(0x6000354), String.format("bios_bup_vect_addr"), true); | |
// only works with correct memory setup | |
if (false) { | |
int pubVectInt = getInt(toAddr(0x6000354)); | |
addBiosFunc(pubVectInt + 4, "bios_bup_sel_part"); | |
addBiosFunc(pubVectInt + 8, "bios_bup_format"); | |
addBiosFunc(pubVectInt + 12, "bios_bup_stat"); | |
addBiosFunc(pubVectInt + 16, "bios_bup_write"); | |
addBiosFunc(pubVectInt + 20, "bios_bup_read"); | |
addBiosFunc(pubVectInt + 24, "bios_bup_delete"); | |
addBiosFunc(pubVectInt + 28, "bios_bup_dir"); | |
addBiosFunc(pubVectInt + 32, "bios_bup_verify"); | |
addBiosFunc(pubVectInt + 36, "bios_bup_get_date"); | |
addBiosFunc(pubVectInt + 40, "bios_bup_set_date"); | |
addBiosFunc(pubVectInt + 86, "bios_unknown_func"); | |
} | |
} | |
private void copy2bl() throws Exception { | |
// bios copy somestuff to main ram | |
memcpy(0x6020000, 0x40000, 0x400); | |
memcpy(0x6001100, 0x01100, 0x800); | |
} | |
public void run() throws Exception { | |
log = new MessageLog(); | |
memoryMap(); | |
copy2bl(); | |
diss(); | |
// Ressources | |
findBootSound(); | |
Map<Long, String> fid_hash = new HashMap<Long, String>() { | |
{ | |
// known hash - from Sega Saturn BIOS v1.00 (1994)(Sega)(JP)(M6) | |
// decompression | |
put(-4957357294425986193L, "compr_memset"); | |
put(8267093030358976781L, "compr_memcpy"); | |
put(8170632217599045526L, "uncompress_fmt1"); | |
put(7002974656940721789L, "uncompress_fmt2"); | |
put(-880055033493905191L, "uncompress"); | |
// common | |
put(-3215063894234191610L, "memset_000002ac"); | |
put(-1917158710479188708L, "memcpy_000002bc"); | |
// cd rom | |
put(-3960013885942437404L, "cd_write_command"); | |
put(440706581677110490L, "cd_read_return_status"); | |
put(1753148846564467649L, "cd_is_data_ready"); | |
put(9038101781666711820L, "cd_get_then_delete_sector_data"); | |
put(-2951319010860686687L, "cd_abort_file"); | |
put(252523138794864959L, "cd_wait_hirq"); | |
put(3921644145217220886L, "cd_connect_cd_to_filter"); | |
put(6652641698586143213L, "cd_reset_selector"); | |
put(7118378219280806410L, "cd_end_transfer"); | |
put(-7247300660382144158L, "cd_get_toc"); | |
put(-5748168935487761878L, "scu_reset"); | |
// scsp | |
put(-366585507627112407L, "scsp_reset"); | |
// vdp2 | |
put(-7281369988693427340L, "vdp2_reset"); | |
put(-617029235865965458L, "vdp2_reset_old"); | |
// arcade | |
put(-2899734622558521840L, "stv_save_input"); | |
put(8929775529747857369L, "SET_PDR1"); | |
put(-5695376958713899753L, "INIT_SOUND_uuuu"); | |
// bup | |
put(-934179304925463990L, "set_backup_header"); | |
put(8214877273008696814L, "check_cd_ip_bin");// 1a3c | |
// compare ipbin cd et bios à 00001b08 | |
// cleanup | |
put(-6136425346699106145L, "clean_vdp_regs_ram"); | |
} | |
}; | |
// currentProgram, monitor, log | |
FidService service = new FidService(); | |
FunctionManager functionManager = currentProgram.getFunctionManager(); | |
FunctionIterator functions = functionManager.getFunctions(true); | |
for (Function function : functions) { | |
if (monitor.isCancelled()) { | |
return; | |
} | |
FidHashQuad hashQuad = service.hashFunction(function); | |
if (hashQuad == null) { | |
continue; | |
} | |
if (fid_hash.containsKey(hashQuad.getFullHash())) { | |
println("full hash:" + String.valueOf(hashQuad.getFullHash()) + " fname"+function.getName()); | |
function.setName(fid_hash.get(hashQuad.getFullHash()), SourceType.USER_DEFINED); | |
} | |
} | |
} | |
} | |
// FUN_00001a18(void) | |
// 2bl (0x400) | |
// 0x40000 => 0x6020000 | |
// memcpy(0x6020000, 0x40000, 0x400) | |
// (*0x6020000)(); | |
// resources | |
// 00001744 | |
// 0x7000 decompresser vers hram+0x10000 (0x2b0) => 0x1fe4 => 0x2362 = us | |
// 0x2b0 => 0x4410 = jap | |
// - header: 10 01 09 E6 FF 7F | |
// FUN_00002c5c | |
// (decmpr ?) 0x438c / 0x455c | |
// decr a 51d0 (logo sega ?) | |
// FUN_000050ea => decompress sega logo | |
/* | |
* FUN_00002c5c(0x51d0, dst, 0x1000) uint FUN_00002c5c(int param_1,int | |
* *param_2,int param_3) | |
* | |
* | |
* | |
* | |
*/ | |
/** | |
* stv notes (stv110.bin) 00000220 => check reset ? 00003478 => check test btn | |
* 00004f96 => wait ioport or eprom ? 0000b1c0 => check cartridge | |
**/ |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment