diff --git a/BizHawk.Emulation/BizHawk.Emulation.csproj b/BizHawk.Emulation/BizHawk.Emulation.csproj index 0e34513b07..99e1888f05 100644 --- a/BizHawk.Emulation/BizHawk.Emulation.csproj +++ b/BizHawk.Emulation/BizHawk.Emulation.csproj @@ -183,6 +183,7 @@ + diff --git a/BizHawk.Emulation/Consoles/Nintendo/NES/Boards/MLT-MAX15.cs b/BizHawk.Emulation/Consoles/Nintendo/NES/Boards/MLT-MAX15.cs new file mode 100644 index 0000000000..e53bdc98d5 --- /dev/null +++ b/BizHawk.Emulation/Consoles/Nintendo/NES/Boards/MLT-MAX15.cs @@ -0,0 +1,153 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +namespace BizHawk.Emulation.Consoles.Nintendo +{ + class MLT_MAX15 : NES.NESBoardBase + { + //http://wiki.nesdev.com/w/index.php/INES_Mapper_234 + + bool mode = false; + int block_high = 0; + int block_low = 0; + byte prg_bank = 0; + byte chr_bank_high = 0; + byte chr_bank_low = 0; + int prg_bank_mask_32k = 0; + int chr_bank_mask_8k = 0; + bool reg_0_locked = false; + public override bool Configure(NES.EDetectionOrigin origin) + { + switch (Cart.board_type) + { + case "MAPPER234": + case "MLT-MAXI15": + break; + default: + return false; + } + + prg_bank_mask_32k = Cart.prg_size / 32 - 1; + chr_bank_mask_8k = Cart.chr_size / 8 - 1; + + return true; + } + + public override void NESSoftReset() + { + mode = false; + block_high = 0; + block_low = 0; + prg_bank = 0; + chr_bank_high = 0; + reg_0_locked = false; + base.NESSoftReset(); + SetMirrorType(EMirrorType.Vertical); + } + + public override void SyncState(Serializer ser) + { + ser.Sync("mode", ref mode); + ser.Sync("block_high", ref block_high); + ser.Sync("block_low", ref block_low); + ser.Sync("prg_bank", ref prg_bank); + ser.Sync("chr_bank", ref chr_bank_high); + ser.Sync("reg_0_locked", ref reg_0_locked); + base.SyncState(ser); + } + + public override void WritePRG(int addr, byte value) + { + if (addr < 0x7F80) + { + base.WritePRG(addr, value); + } + else + { + switch (addr & 0x7FF8) + { + case 0x7F80: + case 0x7F88: + case 0x7F90: + case 0x7F98: + if (!reg_0_locked) + { + if (value > 0) + { + reg_0_locked = true; + } + block_high = (value >> 1) & 0x07; + block_low = value & 0x01; + mode = value.Bit(6); + if (value.Bit(7)) + { + SetMirrorType(EMirrorType.Horizontal); + } + else + { + SetMirrorType(EMirrorType.Vertical); + } + } + break; + case 0x7FC0: + case 0x7FC8: + case 0x7FD0: + case 0x7FD8: + //Console.WriteLine("This mapper is doing undocumented register writes!"); + break; + case 0x7FE8: + case 0x7FF0: + prg_bank = (byte)(value & 0x01); + chr_bank_high = (byte)((value >> 4) & 0x03); + chr_bank_low = (byte)((value >> 6) & 0x01); + //Console.WriteLine("chr_lw: {0}, chr_hg: {1}, value: {2}", chr_bank_low, chr_bank_high, value); + break; + } + } + } + + public override byte ReadPRG(int addr) + { + int bank; + if (mode) + { + bank = (block_high << 1) | prg_bank; + } + else + { + bank = (block_high << 1) | block_low; + } + + byte value = ROM[((bank & prg_bank_mask_32k) * 0x8000) + (addr & 0x7FFF)]; + + if (addr >= 0x7F80) + { + WritePRG(addr, value); + } + + return value; + + } + + public override byte ReadPPU(int addr) + { + if (addr < 0x2000) + { + int bank; + if (mode) + { + bank = (block_high << 3) | (chr_bank_low << 2) | chr_bank_high; + } + else + { + bank = (block_high << 3) | (block_low << 2) | chr_bank_high; + } + + return VROM[((bank & chr_bank_mask_8k) * 0x2000) + (addr & 0x1FFF)]; + } + return base.ReadPPU(addr); + } + } +}