From 91fa1e663620e646b344c516357228b7c44de72b Mon Sep 17 00:00:00 2001 From: zeromus Date: Sun, 25 Sep 2011 01:07:24 +0000 Subject: [PATCH] nes-support vrc3 --- BizHawk.Emulation/BizHawk.Emulation.csproj | 1 + .../Consoles/Nintendo/Docs/compatibility.txt | 2 +- .../Consoles/Nintendo/NES/Boards/VRC2_4.cs | 2 +- .../Consoles/Nintendo/NES/Boards/VRC3.cs | 183 ++++++++++++++++++ .../Consoles/Nintendo/NES/Boards/VRC6.cs | 2 +- .../Consoles/Nintendo/NES/Boards/VRC7.cs | 2 +- 6 files changed, 188 insertions(+), 4 deletions(-) create mode 100644 BizHawk.Emulation/Consoles/Nintendo/NES/Boards/VRC3.cs diff --git a/BizHawk.Emulation/BizHawk.Emulation.csproj b/BizHawk.Emulation/BizHawk.Emulation.csproj index 5809b895dd..2a0b5e19a2 100644 --- a/BizHawk.Emulation/BizHawk.Emulation.csproj +++ b/BizHawk.Emulation/BizHawk.Emulation.csproj @@ -138,6 +138,7 @@ Code + diff --git a/BizHawk.Emulation/Consoles/Nintendo/Docs/compatibility.txt b/BizHawk.Emulation/Consoles/Nintendo/Docs/compatibility.txt index 78eeaf2948..0a1da02148 100644 --- a/BizHawk.Emulation/Consoles/Nintendo/Docs/compatibility.txt +++ b/BizHawk.Emulation/Consoles/Nintendo/Docs/compatibility.txt @@ -60,7 +60,7 @@ Open bus and bus conflict emulation is not considered complete or thorough in an 070 Misc Complete 071 Camerica Complete 072 Misc (J) Nothing -073 VRC3 Nothing +073 VRC3 Good 074 Pirate (CN) Junk 075 VRC1 Nothing 076 Misc (J) Nothing diff --git a/BizHawk.Emulation/Consoles/Nintendo/NES/Boards/VRC2_4.cs b/BizHawk.Emulation/Consoles/Nintendo/NES/Boards/VRC2_4.cs index e98f5980ad..a50bdf383b 100644 --- a/BizHawk.Emulation/Consoles/Nintendo/NES/Boards/VRC2_4.cs +++ b/BizHawk.Emulation/Consoles/Nintendo/NES/Boards/VRC2_4.cs @@ -5,7 +5,7 @@ using System.Diagnostics; namespace BizHawk.Emulation.Consoles.Nintendo { //mapper 21 + 22 + 23 + 25 (docs largely in 021.txt for VRC4 and 22.txt for VRC2) - //If you change any of the IRQ logic here, be sure to change it in VRC 6/7 as well. + //If you change any of the IRQ logic here, be sure to change it in VRC 3/6/7 as well. public class VRC2_4 : NES.NESBoardBase { //configuration diff --git a/BizHawk.Emulation/Consoles/Nintendo/NES/Boards/VRC3.cs b/BizHawk.Emulation/Consoles/Nintendo/NES/Boards/VRC3.cs new file mode 100644 index 0000000000..fee74647e2 --- /dev/null +++ b/BizHawk.Emulation/Consoles/Nintendo/NES/Boards/VRC3.cs @@ -0,0 +1,183 @@ +using System; +using System.IO; +using System.Diagnostics; + +namespace BizHawk.Emulation.Consoles.Nintendo +{ + //mapper 73 AKA salamander + //different IRQ logic than other VRC + public class VRC3 : NES.NESBoardBase + { + //configuration + int prg_bank_mask_16k; + + //state + IntBuffer prg_banks_16k = new IntBuffer(2); + bool irq_mode; + bool irq_enabled, irq_pending, irq_autoen; + ushort irq_reload; + ushort irq_counter; + int irq_cycles; + + public override void Dispose() + { + base.Dispose(); + prg_banks_16k.Dispose(); + } + + public override void SyncState(Serializer ser) + { + base.SyncState(ser); + ser.Sync("prg_banks_16k", ref prg_banks_16k); + ser.Sync("irq_mode", ref irq_mode); + ser.Sync("irq_enabled", ref irq_enabled); + ser.Sync("irq_pending", ref irq_pending); + ser.Sync("irq_autoen", ref irq_autoen); + ser.Sync("irq_reload", ref irq_reload); + ser.Sync("irq_counter", ref irq_counter); + ser.Sync("irq_cycles", ref irq_cycles); + } + + void SyncIRQ() + { + NES.irq_cart = (irq_pending && irq_enabled); + } + + public override bool Configure(NES.EDetectionOrigin origin) + { + switch (Cart.board_type) + { + case "KONAMI-VRC-3": + AssertPrg(128,512); AssertChr(0,128); AssertVram(0,8); AssertWram(0,8); + break; + default: + return false; + } + + prg_bank_mask_16k = Cart.prg_size / 16 - 1; + + SetMirrorType(EMirrorType.Vertical); + + prg_banks_16k[1] = (byte)(0xFF & prg_bank_mask_16k); + + return true; + } + public override byte ReadPRG(int addr) + { + int bank_16k = addr >> 14; + int ofs = addr & ((1 << 14) - 1); + bank_16k = prg_banks_16k[bank_16k]; + addr = (bank_16k << 14) | ofs; + return ROM[addr]; + } + + void WriteIrqReload(int bit, byte value) + { + int mask = 0xF << bit; + irq_reload = (ushort)((irq_reload & ~mask) | (value << bit)); + } + public override void WritePRG(int addr, byte value) + { + switch (addr) + { + case 0x0000: WriteIrqReload(0, value); break; + case 0x1000: WriteIrqReload(4, value); break; + case 0x2000: WriteIrqReload(8, value); break; + case 0x3000: WriteIrqReload(12, value); break; + + case 0x4000: + irq_mode = value.Bit(2); + irq_autoen = value.Bit(0); + + if (value.Bit(1)) + { + //enabled + irq_enabled = true; + if (irq_mode) + { + //8bit.. + irq_counter &= 0xFF00; + irq_counter |= (ushort)(irq_reload & 0xFF); + } + else + { + irq_counter = irq_reload; + } + irq_cycles = 3; + } + else + { + //disabled + irq_enabled = false; + } + + //acknowledge + irq_pending = false; + + SyncIRQ(); + + break; + + case 0x5000: + irq_pending = false; + irq_enabled = irq_autoen; + SyncIRQ(); + break; + + case 0x7000: + prg_banks_16k[0] = value & 0xF; + prg_banks_16k[0] &= prg_bank_mask_16k; + break; + + } + } + + void ClockIRQ() + { + if (irq_mode) + { + //8 bit mode + ushort temp = irq_counter; + temp &= 0xFF; + irq_counter &= 0xFF00; + if (temp == 0xFF) + { + irq_pending = true; + irq_counter = irq_reload; + irq_counter |= (ushort)(irq_reload & 0xFF); + SyncIRQ(); + } + else + { + temp++; + irq_counter |= temp; + } + } + else + { + //16 bit mode + if (irq_counter == 0xFFFF) + { + irq_pending = true; + irq_counter = irq_reload; + SyncIRQ(); + } + else + irq_counter++; + } + } + + public override void ClockPPU() + { + if (!irq_enabled) return; + + irq_cycles--; + if (irq_cycles == 0) + { + irq_cycles += 3; + ClockIRQ(); + } + } + + } +} \ No newline at end of file diff --git a/BizHawk.Emulation/Consoles/Nintendo/NES/Boards/VRC6.cs b/BizHawk.Emulation/Consoles/Nintendo/NES/Boards/VRC6.cs index 514adac252..38f5f8a5ae 100644 --- a/BizHawk.Emulation/Consoles/Nintendo/NES/Boards/VRC6.cs +++ b/BizHawk.Emulation/Consoles/Nintendo/NES/Boards/VRC6.cs @@ -5,7 +5,7 @@ using System.Diagnostics; namespace BizHawk.Emulation.Consoles.Nintendo { //mapper 24 + 26 - //If you change any of the IRQ logic here, be sure to change it in VRC 2/4/7 as well. + //If you change any of the IRQ logic here, be sure to change it in VRC 2/3/4/7 as well. public class VRC6 : NES.NESBoardBase { //configuration diff --git a/BizHawk.Emulation/Consoles/Nintendo/NES/Boards/VRC7.cs b/BizHawk.Emulation/Consoles/Nintendo/NES/Boards/VRC7.cs index 82d6affe43..9cb0cf02f7 100644 --- a/BizHawk.Emulation/Consoles/Nintendo/NES/Boards/VRC7.cs +++ b/BizHawk.Emulation/Consoles/Nintendo/NES/Boards/VRC7.cs @@ -5,7 +5,7 @@ using System.Diagnostics; namespace BizHawk.Emulation.Consoles.Nintendo { //mapper 85 - //If you change any of the IRQ logic here, be sure to change it in VRC 2/4/6 as well. + //If you change any of the IRQ logic here, be sure to change it in VRC 2/3/4/6 as well. public class VRC7 : NES.NESBoardBase { //configuration