From 7b02af404b5b2c6ff951190dcd02fa216b1bbba5 Mon Sep 17 00:00:00 2001 From: rsgrava Date: Wed, 14 Feb 2024 16:45:32 -0300 Subject: [PATCH] Add support for mapper 10 (MMC4) --- .../java/ghidranes/mappers/MMC4Mapper.java | 32 +++++++++++++++++++ .../java/ghidranes/mappers/NesMapper.java | 2 ++ README.md | 1 + 3 files changed, 35 insertions(+) create mode 100644 GhidraNes/src/main/java/ghidranes/mappers/MMC4Mapper.java diff --git a/GhidraNes/src/main/java/ghidranes/mappers/MMC4Mapper.java b/GhidraNes/src/main/java/ghidranes/mappers/MMC4Mapper.java new file mode 100644 index 0000000..2735386 --- /dev/null +++ b/GhidraNes/src/main/java/ghidranes/mappers/MMC4Mapper.java @@ -0,0 +1,32 @@ +package ghidranes.mappers; + +import java.util.Arrays; + +import ghidra.framework.store.LockException; +import ghidra.program.model.address.AddressOverflowException; +import ghidra.program.model.listing.Program; +import ghidra.program.model.mem.MemoryConflictException; +import ghidra.util.exception.CancelledException; +import ghidra.util.exception.DuplicateNameException; +import ghidra.util.task.TaskMonitor; +import ghidranes.NesRom; +import ghidranes.util.MemoryBlockDescription; + + +public class MMC4Mapper extends NesMapper { + @Override + public void updateMemoryMapForRom(NesRom rom, Program program, TaskMonitor monitor) throws LockException, MemoryConflictException, AddressOverflowException, CancelledException, DuplicateNameException { + int sramPermissions = MemoryBlockDescription.READ | MemoryBlockDescription.WRITE | MemoryBlockDescription.EXECUTE; + MemoryBlockDescription.uninitialized(0x6000, 0x2000, "SRAM", sramPermissions, false).create(program); + + int romPermissions = MemoryBlockDescription.READ | MemoryBlockDescription.EXECUTE; + for (int bank = 0; bank * 0x4000 < rom.prgRom.length; bank++) { + byte[] rombankBytes = Arrays.copyOfRange(rom.prgRom, bank * 0x4000, (bank + 1) * 0x4000); + MemoryBlockDescription.initialized(0x8000, 0x4000, "PRG" + bank, romPermissions, rombankBytes, bank != 0, monitor).create(program); + } + + int lastBank = rom.prgRom.length / 0x4000 - 1; + byte[] lastBankBytes = Arrays.copyOfRange(rom.prgRom, lastBank * 0x4000, (lastBank + 1) * 0x4000); + MemoryBlockDescription.initialized(0xC000, 0x4000, "PRG" + lastBank + "_MIRROR", romPermissions, lastBankBytes, false, monitor).create(program); + } +} diff --git a/GhidraNes/src/main/java/ghidranes/mappers/NesMapper.java b/GhidraNes/src/main/java/ghidranes/mappers/NesMapper.java index d475f04..c5539ad 100644 --- a/GhidraNes/src/main/java/ghidranes/mappers/NesMapper.java +++ b/GhidraNes/src/main/java/ghidranes/mappers/NesMapper.java @@ -21,6 +21,8 @@ public static NesMapper getMapper(int mapperNum) throws UnimplementedNesMapperEx return new MMC1Mapper(); case 7: return new AxROMMapper(); + case 10: + return new MMC4Mapper(); case 19: return new Mapper019(); default: diff --git a/README.md b/README.md index 88e5c8b..37693c8 100644 --- a/README.md +++ b/README.md @@ -10,6 +10,7 @@ A Ghidra extension to support disassembling and analyzing NES ROMs. - [NROM](https://www.nesdev.org/wiki/NROM) (mapper 0) - [MMC1](https://www.nesdev.org/wiki/MMC1) (mapper 1) - [AxROM](https://www.nesdev.org/wiki/AxROM) (mapper 7) + - [MMC4](https://www.nesdev.org/wiki/MMC4) (mapper 10) - [Namco 129/163](https://www.nesdev.org/wiki/INES_Mapper_019) (mapper 19) - Add labels and memory blocks in disassembly, making it easier to jump around a disassembled ROM!