From e5d46e1adc8a2e92d52bb7bccdc96bbca752fe5e Mon Sep 17 00:00:00 2001 From: zeromus Date: Wed, 21 Sep 2011 05:11:38 +0000 Subject: [PATCH] add vrc6 and reorg sunsoft-2 stuff a bit (its too nonsensical to give name a file after) --- BizHawk.Emulation/BizHawk.Emulation.csproj | 5 +- .../Consoles/Nintendo/NES/BoardSystem.cs | 17 +- .../NES/Boards/{Sunsoft2.cs => Mapper089.cs} | 71 +---- .../Consoles/Nintendo/NES/Boards/Mapper093.cs | 76 ++++++ .../Consoles/Nintendo/NES/Boards/VRC6.cs | 246 ++++++++++++++++++ .../Consoles/Nintendo/NES/Core.cs | 2 - 6 files changed, 334 insertions(+), 83 deletions(-) rename BizHawk.Emulation/Consoles/Nintendo/NES/Boards/{Sunsoft2.cs => Mapper089.cs} (53%) create mode 100644 BizHawk.Emulation/Consoles/Nintendo/NES/Boards/Mapper093.cs create mode 100644 BizHawk.Emulation/Consoles/Nintendo/NES/Boards/VRC6.cs diff --git a/BizHawk.Emulation/BizHawk.Emulation.csproj b/BizHawk.Emulation/BizHawk.Emulation.csproj index 9a2ef861e0..e56b8b229e 100644 --- a/BizHawk.Emulation/BizHawk.Emulation.csproj +++ b/BizHawk.Emulation/BizHawk.Emulation.csproj @@ -98,10 +98,11 @@ - + + @@ -118,7 +119,6 @@ - Code @@ -127,6 +127,7 @@ Code + diff --git a/BizHawk.Emulation/Consoles/Nintendo/NES/BoardSystem.cs b/BizHawk.Emulation/Consoles/Nintendo/NES/BoardSystem.cs index d1dfa5531a..e15ccb7fb8 100644 --- a/BizHawk.Emulation/Consoles/Nintendo/NES/BoardSystem.cs +++ b/BizHawk.Emulation/Consoles/Nintendo/NES/BoardSystem.cs @@ -188,7 +188,7 @@ namespace BizHawk.Emulation.Consoles.Nintendo protected void Assert_memtype(int value, string name, int[] valid) { foreach (int i in valid) if (value == i) return; - Assert(false, "unhandled {0} size", name); + Assert(false, "unhandled {0} size of {1}", name,value); } protected void AssertBattery(bool has_bat) { Assert(Cart.wram_battery == has_bat); } } @@ -453,18 +453,3 @@ namespace BizHawk.Emulation.Consoles.Nintendo } } } - - //STD_SAROM = MakeId< 1, 64, 64, 8, 0, CRM_0, NMT_H, 0 >::ID, - //STD_SBROM = MakeId< 1, 64, 64, 0, 0, CRM_0, NMT_H, 0 >::ID, - //STD_SCROM = MakeId< 1, 64, 128, 0, 0, CRM_0, NMT_H, 0 >::ID, - //STD_SEROM = MakeId< 1, 32, 64, 0, 0, CRM_0, NMT_H, 0 >::ID, - //STD_SFROM = MakeId< 1, 256, 64, 0, 0, CRM_0, NMT_H, 0 >::ID, - //STD_SGROM = MakeId< 1, 256, 0, 0, 0, CRM_8, NMT_H, 0 >::ID, - //STD_SHROM = MakeId< 1, 32, 128, 0, 0, CRM_0, NMT_H, 0 >::ID, - //STD_SJROM = MakeId< 1, 256, 64, 8, 0, CRM_0, NMT_H, 0 >::ID, - //STD_SKROM = MakeId< 1, 256, 128, 8, 0, CRM_0, NMT_H, 0 >::ID, - //STD_SLROM = MakeId< 1, 256, 128, 0, 0, CRM_0, NMT_H, 0 >::ID, - //STD_SNROM = MakeId< 1, 256, 0, 8, 0, CRM_8, NMT_H, 0 >::ID, - //STD_SOROM = MakeId< 1, 256, 0, 8, 8, CRM_8, NMT_H, 0 >::ID, - //STD_SUROM = MakeId< 1, 512, 0, 8, 0, CRM_8, NMT_H, 0 >::ID, - //STD_SXROM = MakeId< 1, 512, 0, 32, 0, CRM_8, NMT_H, 0 >::ID, \ No newline at end of file diff --git a/BizHawk.Emulation/Consoles/Nintendo/NES/Boards/Sunsoft2.cs b/BizHawk.Emulation/Consoles/Nintendo/NES/Boards/Mapper089.cs similarity index 53% rename from BizHawk.Emulation/Consoles/Nintendo/NES/Boards/Sunsoft2.cs rename to BizHawk.Emulation/Consoles/Nintendo/NES/Boards/Mapper089.cs index 9d0e233d94..641c33b085 100644 --- a/BizHawk.Emulation/Consoles/Nintendo/NES/Boards/Sunsoft2.cs +++ b/BizHawk.Emulation/Consoles/Nintendo/NES/Boards/Mapper089.cs @@ -4,6 +4,7 @@ using System.Diagnostics; namespace BizHawk.Emulation.Consoles.Nintendo { + //AKA Tenka no Goikenban: Mito Koumon class MAPPER89 : NES.NESBoardBase { int chr; @@ -15,11 +16,17 @@ namespace BizHawk.Emulation.Consoles.Nintendo { switch (Cart.board_type) { - case "MAPPER89": + case "SUNSOFT-2": break; default: return false; } + + //yes, the board type SUNSOFT-2 has a pcb type of SUNSOFT-3 + //(the pcb SUNSOFT-3R has a different revision of SUNSOFT-2 chip which works differently) + //and all these are different than the SUNSOFT-3 chip + if (Cart.pcb != "SUNSOFT-3") return false; + SetMirrorType(Cart.pad_h, Cart.pad_v); prg_bank_mask_16k = (Cart.prg_size / 16) - 1; prg_banks_16k[1] = 0xFF; @@ -77,66 +84,4 @@ namespace BizHawk.Emulation.Consoles.Nintendo return base.ReadPPU(addr); } } - - class MAPPER93 : NES.NESBoardBase - { - int prg_bank_mask_16k; - byte prg_bank_16k; - ByteBuffer prg_banks_16k = new ByteBuffer(2); - - public override bool Configure(NES.EDetectionOrigin origin) - { - switch (Cart.board_type) - { - case "MAPPER93": - break; - default: - return false; - } - SetMirrorType(Cart.pad_h, Cart.pad_v); - prg_bank_mask_16k = (Cart.prg_size / 16) - 1; - prg_banks_16k[1] = 0xFF; - return true; - } - - public override void Dispose() - { - prg_banks_16k.Dispose(); - base.Dispose(); - } - - public override void SyncState(Serializer ser) - { - base.SyncState(ser); - ser.Sync("prg_bank_mask_16k", ref prg_bank_mask_16k); - ser.Sync("prg_bank_16k", ref prg_bank_16k); - ser.Sync("prg_banks_16k", ref prg_banks_16k); - } - - void SyncPRG() - { - prg_banks_16k[0] = prg_bank_16k; - } - - public override void WritePRG(int addr, byte value) - { - prg_bank_16k = (byte)((value >> 4) & 15); - SyncPRG(); - - if (value.Bit(0)) - SetMirrorType(EMirrorType.Horizontal); - else - SetMirrorType(EMirrorType.Vertical); - } - - public override byte ReadPRG(int addr) - { - int bank_16k = addr >> 14; - int ofs = addr & ((1 << 14) - 1); - bank_16k = prg_banks_16k[bank_16k]; - bank_16k &= prg_bank_mask_16k; - addr = (bank_16k << 14) | ofs; - return ROM[addr]; - } - } } diff --git a/BizHawk.Emulation/Consoles/Nintendo/NES/Boards/Mapper093.cs b/BizHawk.Emulation/Consoles/Nintendo/NES/Boards/Mapper093.cs new file mode 100644 index 0000000000..4595ddaed2 --- /dev/null +++ b/BizHawk.Emulation/Consoles/Nintendo/NES/Boards/Mapper093.cs @@ -0,0 +1,76 @@ +using System; +using System.IO; +using System.Diagnostics; + +namespace BizHawk.Emulation.Consoles.Nintendo +{ + //AKA shanghai (although a lot of shanghais have been hacked to use a different mapper, so.... + //TODO - this hasnt been tested yet and isnt even close to right + class MAPPER93 : NES.NESBoardBase + { + int prg_bank_mask_16k; + byte prg_bank_16k; + ByteBuffer prg_banks_16k = new ByteBuffer(2); + + public override bool Configure(NES.EDetectionOrigin origin) + { + switch (Cart.board_type) + { + case "SUNSOFT-2": + break; + default: + return false; + } + + //yes, the board type SUNSOFT-2 has a pcb type of SUNSOFT-3R + //(the pcb SUNSOFT-3 has a different revision of SUNSOFT-2 chip which works differently) + //and all these are different than the SUNSOFT-3 chip + if (Cart.pcb != "SUNSOFT-3R") return false; + + SetMirrorType(Cart.pad_h, Cart.pad_v); + prg_bank_mask_16k = (Cart.prg_size / 16) - 1; + prg_banks_16k[1] = 0xFF; + return true; + } + + public override void Dispose() + { + prg_banks_16k.Dispose(); + base.Dispose(); + } + + public override void SyncState(Serializer ser) + { + base.SyncState(ser); + ser.Sync("prg_bank_mask_16k", ref prg_bank_mask_16k); + ser.Sync("prg_bank_16k", ref prg_bank_16k); + ser.Sync("prg_banks_16k", ref prg_banks_16k); + } + + void SyncPRG() + { + prg_banks_16k[0] = prg_bank_16k; + } + + public override void WritePRG(int addr, byte value) + { + prg_bank_16k = (byte)((value >> 4) & 15); + SyncPRG(); + + if (value.Bit(0)) + SetMirrorType(EMirrorType.Horizontal); + else + SetMirrorType(EMirrorType.Vertical); + } + + public override byte ReadPRG(int addr) + { + int bank_16k = addr >> 14; + int ofs = addr & ((1 << 14) - 1); + bank_16k = prg_banks_16k[bank_16k]; + bank_16k &= prg_bank_mask_16k; + addr = (bank_16k << 14) | ofs; + return ROM[addr]; + } + } +} diff --git a/BizHawk.Emulation/Consoles/Nintendo/NES/Boards/VRC6.cs b/BizHawk.Emulation/Consoles/Nintendo/NES/Boards/VRC6.cs new file mode 100644 index 0000000000..9bcc5d20db --- /dev/null +++ b/BizHawk.Emulation/Consoles/Nintendo/NES/Boards/VRC6.cs @@ -0,0 +1,246 @@ +using System; +using System.IO; +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 VRC4 as well. + public class VRC6 : NES.NESBoardBase + { + //configuration + int prg_bank_mask_8k, chr_bank_mask_1k; + bool newer_variant; + + //state + int prg_bank_16k, prg_bank_8k; + ByteBuffer prg_banks_8k = new ByteBuffer(4); + ByteBuffer chr_banks_1k = new ByteBuffer(8); + bool irq_mode; + bool irq_enabled, irq_pending, irq_autoen; + byte irq_reload; + byte irq_counter; + int irq_prescaler; + + public override void Dispose() + { + base.Dispose(); + prg_banks_8k.Dispose(); + chr_banks_1k.Dispose(); + } + + public override void SyncState(Serializer ser) + { + base.SyncState(ser); + ser.Sync("prg_bank_16k", ref prg_bank_16k); + ser.Sync("prg_bank_8k", ref prg_bank_8k); + ser.Sync("prg_banks_8k", ref prg_banks_8k); + ser.Sync("chr_banks_1k", ref chr_banks_1k); + 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_prescaler", ref irq_prescaler); + + if (ser.IsReader) + { + SyncPRG(); + } + } + + void SyncPRG() + { + prg_banks_8k[0] = (byte)(prg_bank_16k * 2); + prg_banks_8k[1] = (byte)(prg_bank_16k * 2 + 1); + prg_banks_8k[2] = (byte)(prg_bank_8k); + prg_banks_8k[3] = 0xFF; + } + + void SyncIRQ() + { + NES.irq_cart = (irq_pending && irq_enabled); + } + + public override bool Configure(NES.EDetectionOrigin origin) + { + switch (Cart.board_type) + { + case "KONAMI-VRC-6": + AssertPrg(256); AssertChr(128,256); AssertVram(0); AssertWram(0,8); + break; + default: + return false; + } + + if (Cart.pcb == "351951") + newer_variant = false; + else if (Cart.pcb == "351949A") + newer_variant = true; + else throw new Exception("Unknown PCB type for VRC6"); + + prg_bank_mask_8k = Cart.prg_size / 8 - 1; + chr_bank_mask_1k = Cart.chr_size - 1; + + prg_bank_16k = 0; + prg_bank_8k = 0; + SyncPRG(); + SetMirrorType(EMirrorType.Vertical); + + return true; + } + public override byte ReadPRG(int addr) + { + int bank_8k = addr >> 13; + int ofs = addr & ((1 << 13) - 1); + bank_8k = prg_banks_8k[bank_8k]; + bank_8k &= prg_bank_mask_8k; + addr = (bank_8k << 13) | ofs; + return ROM[addr]; + } + + public override byte ReadPPU(int addr) + { + if (addr < 0x2000) + { + int bank_1k = addr >> 10; + int ofs = addr & ((1 << 10) - 1); + bank_1k = chr_banks_1k[bank_1k]; + bank_1k &= chr_bank_mask_1k; + addr = (bank_1k << 10) | ofs; + return VROM[addr]; + } + else return base.ReadPPU(addr); + } + + public override void WritePRG(int addr, byte value) + { + if (newer_variant) + { + addr = (addr & 0xFFFC) | ((addr >> 1) & 1) | ((addr << 1) & 2); + } + switch (addr) + { + case 0x0000: //$8000 + case 0x0001: + case 0x0002: + case 0x0003: + prg_bank_16k = value; + SyncPRG(); + break; + + case 0x1000: //$9000 + case 0x1001: //$9001 + case 0x1002: //$9002 + //TODO pulse 1 + break; + + case 0x2000: //$A000 + case 0x2001: //$A001 + case 0x2002: //$A002 + //TODO pulse 2 + break; + + case 0x3000: //$B000 + case 0x3001: //$B001 + case 0x3002: //$B002 + //TODO sawtooth + break; + + case 0x3003: //$B003 + switch ((value>>2) & 3) + { + case 0: SetMirrorType(NES.NESBoardBase.EMirrorType.Vertical); break; + case 1: SetMirrorType(NES.NESBoardBase.EMirrorType.Horizontal); break; + case 2: SetMirrorType(NES.NESBoardBase.EMirrorType.OneScreenA); break; + case 3: SetMirrorType(NES.NESBoardBase.EMirrorType.OneScreenB); break; + } + break; + + case 0x4000: //$C000 + case 0x4001: + case 0x4002: + case 0x4003: + prg_bank_8k = value; + SyncPRG(); + break; + + case 0x5000: //$D000 + case 0x5001: //$D001 + case 0x5002: //$D002 + case 0x5003: //$D003 + chr_banks_1k[addr - 0x5000] = value; + break; + + case 0x6000: //$E000 + case 0x6001: //$E001 + case 0x6002: //$E002 + case 0x6003: //$E003 + chr_banks_1k[4+ addr - 0x6000] = value; + break; + + case 0x7000: //$F000 (reload) + irq_reload = value; + break; + case 0x7001: //$F001 (control) + irq_mode = value.Bit(2); + irq_autoen = value.Bit(0); + + if (value.Bit(1)) + { + //enabled + irq_enabled = true; + irq_counter = irq_reload; + irq_prescaler = 341; + } + else + { + //disabled + irq_enabled = false; + } + SyncIRQ(); + + break; + + case 0x7002: //$F002 (ack) + irq_pending = false; + irq_enabled = irq_autoen; + SyncIRQ(); + break; + } + } + + void ClockIRQ() + { + if (irq_counter == 0xFF) + { + irq_pending = true; + irq_counter = irq_reload; + SyncIRQ(); + } + else + irq_counter++; + } + + public override void ClockPPU() + { + if (!irq_enabled) return; + + if (irq_mode) + { + ClockIRQ(); + } + else + { + irq_prescaler--; + if (irq_prescaler == 0) + { + irq_prescaler += 341; + ClockIRQ(); + } + } + } + + } +} \ No newline at end of file diff --git a/BizHawk.Emulation/Consoles/Nintendo/NES/Core.cs b/BizHawk.Emulation/Consoles/Nintendo/NES/Core.cs index dfe32bf5b0..ea250186d8 100644 --- a/BizHawk.Emulation/Consoles/Nintendo/NES/Core.cs +++ b/BizHawk.Emulation/Consoles/Nintendo/NES/Core.cs @@ -59,8 +59,6 @@ namespace BizHawk.Emulation.Consoles.Nintendo cpu.PC = (ushort)(ReadMemory(0xFFFC) | (ReadMemory(0xFFFD) << 8)); cpu.P = 0x34; cpu.S = 0xFD; - - //cpu.debug = true; } bool resetSignal;