diff --git a/BizHawk.Emulation.Cores/Consoles/Nintendo/NES/Boards/MMC3_family/Mapper215.cs b/BizHawk.Emulation.Cores/Consoles/Nintendo/NES/Boards/MMC3_family/Mapper215.cs index 29b7c88258..83bdafa7fd 100644 --- a/BizHawk.Emulation.Cores/Consoles/Nintendo/NES/Boards/MMC3_family/Mapper215.cs +++ b/BizHawk.Emulation.Cores/Consoles/Nintendo/NES/Boards/MMC3_family/Mapper215.cs @@ -78,14 +78,14 @@ namespace BizHawk.Emulation.Cores.Nintendo.NES { base.SyncState(ser); ser.Sync("exRegs", ref exRegs); - ser.Sync("cmd", ref is_mk3); + ser.Sync("is_mk3", ref is_mk3); + ser.Sync("ptg_regs_8k", ref prg_regs_8k); ser.Sync("prg_mask", ref prg_mask_8k); ser.Sync("chr_mask", ref chr_mask_1k); } public void sync_prg(int i) { - if ((exRegs[0] & 0x80) == 0) { int temp = 0; @@ -101,8 +101,6 @@ namespace BizHawk.Emulation.Cores.Nintendo.NES prg_regs_8k[i] = (byte)(temp & prg_mask_8k); //} } - - } public void sync_prg_2() @@ -117,7 +115,6 @@ namespace BizHawk.Emulation.Cores.Nintendo.NES prg_regs_8k[1] = (byte)(bank+1); prg_regs_8k[2] = (byte)bank; prg_regs_8k[3] = (byte)(bank+1); - } else { @@ -126,7 +123,6 @@ namespace BizHawk.Emulation.Cores.Nintendo.NES sync_prg(2); sync_prg(3); } - } public override void WriteEXP(int addr, byte value) diff --git a/BizHawk.Emulation.Cores/Consoles/Nintendo/NES/Boards/MMC3_family/Mapper217.cs b/BizHawk.Emulation.Cores/Consoles/Nintendo/NES/Boards/MMC3_family/Mapper217.cs index 9839ddddea..e142867282 100644 --- a/BizHawk.Emulation.Cores/Consoles/Nintendo/NES/Boards/MMC3_family/Mapper217.cs +++ b/BizHawk.Emulation.Cores/Consoles/Nintendo/NES/Boards/MMC3_family/Mapper217.cs @@ -3,11 +3,15 @@ using BizHawk.Common.NumberExtensions; namespace BizHawk.Emulation.Cores.Nintendo.NES { - // TODO public sealed class Mapper217 : MMC3Board_Base { private ByteBuffer exRegs = new ByteBuffer(4); + public ByteBuffer prg_regs_8k = new ByteBuffer(4); + private int prg_mask_8k, chr_mask_1k; + private byte[] regs_sec = { 0, 6, 3, 7, 5, 2, 4, 1 }; + + public override bool Configure(NES.EDetectionOrigin origin) { switch (Cart.board_type) @@ -25,6 +29,14 @@ namespace BizHawk.Emulation.Cores.Nintendo.NES exRegs[2] = 0x03; exRegs[3] = 0x00; + prg_mask_8k = Cart.prg_size / 8 - 1; + chr_mask_1k = Cart.chr_size - 1; + + prg_regs_8k[0] = 0; + prg_regs_8k[1] = 1; + prg_regs_8k[2] = (byte)(0xFE & prg_mask_8k); + prg_regs_8k[3] = (byte)(0xFF & prg_mask_8k); + return true; } @@ -32,6 +44,26 @@ namespace BizHawk.Emulation.Cores.Nintendo.NES { base.SyncState(ser); ser.Sync("exRegs", ref exRegs); + ser.Sync("ptg_regs_8k", ref prg_regs_8k); + ser.Sync("prg_mask", ref prg_mask_8k); + ser.Sync("chr_mask", ref chr_mask_1k); + } + + public void sync_prg() + { + int temp = 0; + for (int i=0;i<4;i++) + { + temp = mmc3.prg_regs_8k[i]; + + if ((exRegs[1] & 0x8) > 0) + temp = temp & 0x1F; + else + temp = ((temp & 0x0F) | (exRegs[1] & 0x10)); + + temp |= (exRegs[1] << 5 & 0x60); + prg_regs_8k[i] = (byte)(temp & prg_mask_8k); + } } public override void WriteEXP(int addr, byte value) @@ -39,12 +71,28 @@ namespace BizHawk.Emulation.Cores.Nintendo.NES if (addr == 0x1000) { exRegs[0] = value; - // TODO: if value & 0x80, prg 16k mode + if ((value & 0x80)>0) + { + int bank = (byte)((value & 0x0F) | (exRegs[1] << 4 & 0x30)); + + bank *= 2; + bank &= prg_mask_8k; + + prg_regs_8k[0] = (byte)bank; + prg_regs_8k[1] = (byte)(bank + 1); + prg_regs_8k[2] = (byte)bank; + prg_regs_8k[3] = (byte)(bank + 1); + } + else + { + sync_prg(); + } } else if (addr == 0x1001) { exRegs[1] = value; + sync_prg(); } else if (addr == 0x1007) @@ -55,16 +103,103 @@ namespace BizHawk.Emulation.Cores.Nintendo.NES base.WriteEXP(addr, value); } - protected override int Get_PRGBank_8K(int addr) - { - if (exRegs[1].Bit(3)) - { - return base.Get_PRGBank_8K(addr) & 0x1F; - } - else - { - return base.Get_PRGBank_8K(addr) & 0x1F | (exRegs[1] & 0x10); - } + public override void WritePRG(int addr, byte value) + { + switch ((addr + 0x8000) & 0xE001) + { + case 0x8000: + if (exRegs[2] > 0) + { + base.WritePRG(0x4000, value); + } + else + { + base.WritePRG(0x0000, value); + sync_prg(); + } + break; + case 0x8001: + if (exRegs[2] > 0) + { + value = (byte)((value & 0xC0) | regs_sec[value & 0x07]); + exRegs[3] = 1; + + base.WritePRG(0x0000, value); + sync_prg(); + } + else + { + base.WritePRG(0x0001, value); + sync_prg(); + } + break; + case 0xA000: + if (exRegs[2] > 0) + { + if ((exRegs[3] > 0) && ((exRegs[0] & 0x80) == 0 || (mmc3.reg_addr & 0x7) < 6)) + { + exRegs[3] = 0; + base.WritePRG(0x0001, value); + sync_prg(); + } + } + else + { + if (value == 0) + { + SetMirrorType(EMirrorType.Vertical); + } + else + { + SetMirrorType(EMirrorType.Horizontal); + } + } + break; + case 0xA001: + if (exRegs[2] > 0) + { + if (value == 0) + { + SetMirrorType(EMirrorType.Vertical); + } + else + { + SetMirrorType(EMirrorType.Horizontal); + } + } else + { + base.WritePRG(0x2001, value); + } + break; + } + + if (addr>=0x4000) + base.WritePRG(addr, value); + } + + public override byte ReadPPU(int addr) + { + if (addr < 0x2000) + { + int bank_1k = base.Get_CHRBank_1K(addr); + + if ((exRegs[1] & 0x8) == 0) + bank_1k = (bank_1k & 0x7F) | (exRegs[1] << 3 & 0x80); + + bank_1k |= (exRegs[1] << 8 & 0x300); + bank_1k &= chr_mask_1k; + addr = (bank_1k << 10) | (addr & 0x3FF); + return VROM[addr]; + } + else return base.ReadPPU(addr); + } + + + public override byte ReadPRG(int addr) + { + int bank = addr >> 13; + bank = prg_regs_8k[bank]; + return ROM[(bank << 13) + (addr & 0x1FFF)]; } } }