diff --git a/BizHawk.Emulation/BizHawk.Emulation.csproj b/BizHawk.Emulation/BizHawk.Emulation.csproj index 38751c3fee..f28b353438 100644 --- a/BizHawk.Emulation/BizHawk.Emulation.csproj +++ b/BizHawk.Emulation/BizHawk.Emulation.csproj @@ -149,6 +149,7 @@ + diff --git a/BizHawk.Emulation/Consoles/Nintendo/NES/Boards/MMC3_family/MMC3.cs b/BizHawk.Emulation/Consoles/Nintendo/NES/Boards/MMC3_family/MMC3.cs index 31b9461855..25e36221cc 100644 --- a/BizHawk.Emulation/Consoles/Nintendo/NES/Boards/MMC3_family/MMC3.cs +++ b/BizHawk.Emulation/Consoles/Nintendo/NES/Boards/MMC3_family/MMC3.cs @@ -321,7 +321,7 @@ namespace BizHawk.Emulation.Consoles.Nintendo return mmc3.Get_PRGBank_8K(addr); } - int MapCHR(int addr) + protected virtual int MapCHR(int addr) { int bank_1k = Get_CHRBank_1K(addr); bank_1k &= chr_mask; diff --git a/BizHawk.Emulation/Consoles/Nintendo/NES/Boards/MMC3_family/Mapper205.cs b/BizHawk.Emulation/Consoles/Nintendo/NES/Boards/MMC3_family/Mapper205.cs index 351f1bf0a2..25d37af063 100644 --- a/BizHawk.Emulation/Consoles/Nintendo/NES/Boards/MMC3_family/Mapper205.cs +++ b/BizHawk.Emulation/Consoles/Nintendo/NES/Boards/MMC3_family/Mapper205.cs @@ -68,7 +68,7 @@ namespace BizHawk.Emulation.Consoles.Nintendo return ROM[addr]; } - int MapCHR(int addr) + int MapCHR2(int addr) { int bank_1k = Get_CHRBank_1K(addr); bank_1k &= chr_mask; @@ -99,7 +99,7 @@ namespace BizHawk.Emulation.Consoles.Nintendo { if (addr < 0x2000) { - addr = MapCHR(addr); + addr = MapCHR2(addr); if (VROM != null) return VROM[addr + extra_vrom]; else return VRAM[addr]; diff --git a/BizHawk.Emulation/Consoles/Nintendo/NES/Boards/Mapper045.cs b/BizHawk.Emulation/Consoles/Nintendo/NES/Boards/Mapper045.cs new file mode 100644 index 0000000000..e7a95e382f --- /dev/null +++ b/BizHawk.Emulation/Consoles/Nintendo/NES/Boards/Mapper045.cs @@ -0,0 +1,142 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +namespace BizHawk.Emulation.Consoles.Nintendo +{ + class Mapper045 : MMC3Board_Base + { + //http://wiki.nesdev.com/w/index.php/INES_Mapper_045 + + int chr_bank_mask_2k; + int prg_bank_mask_8k; + int cur_reg = 0; + ByteBuffer regs = new ByteBuffer(4); + bool lock_regs = false; + + public override bool Configure(NES.EDetectionOrigin origin) + { + switch (Cart.board_type) + { + case "MAPPER045": + break; + default: + return false; + } + + chr_bank_mask_2k = Cart.chr_size / 2 - 1; + prg_bank_mask_8k = Cart.prg_size / 8 - 1; + BaseSetup(); + return true; + } + + public override void Dispose() + { + regs.Dispose(); + base.Dispose(); + } + + public override void SyncState(Serializer ser) + { + ser.Sync("regs", ref regs); + base.SyncState(ser); + } + + public override void WriteWRAM(int addr, byte value) + { + if (lock_regs) + { + base.WriteWRAM(addr, value); + } + else + { + regs[cur_reg] = value; + IncrementCounter(); + Sync45(); + } + } + + private void Sync45() + { + lock_regs = regs[3].Bit(6); + } + + private void IncrementCounter() + { + if (cur_reg == 3) + { + cur_reg = 0; + } + else + { + cur_reg++; + } + } + + public override void NESSoftReset() + { + lock_regs = false; + cur_reg = 0; + regs = new ByteBuffer(4); + base.NESSoftReset(); + } + + public override byte ReadPRG(int addr) + { + int bank_8k = Get_PRGBank_8K(addr); + bank_8k &= (regs[3] & 0x3F) ^ 0x3F; + bank_8k |= regs[1]; + bank_8k &= prg_mask; + addr = (bank_8k << 13) | (addr & 0x1FFF); + return ROM[addr]; + } + + private int CHR_AND() + { + switch (regs[2] & 0x0F) + { + default: + case 0: + case 1: + case 2: + case 3: + case 4: + case 5: + case 6: + case 7: + return 0x00; + case 8: + return 0x01; + case 9: + case 0xA: + case 0xB: + case 0xC: + + case 0xD: + return 0x3F; + case 0xE: + return 0x7F; + case 0xF: + return 0xFF; + } + } + + private int CHR_OR() + { + int x = regs[0] | ((regs[2] >> 4) << 8); + return x; + } + + protected override int MapCHR(int addr) + { + int bank_1k = Get_CHRBank_1K(addr); + + bank_1k &= CHR_AND(); + bank_1k |= CHR_OR(); + bank_1k &= chr_mask; + addr = (bank_1k << 10) | (addr & 0x3FF); + return addr; + } + } +}