diff --git a/BizHawk.Emulation/BizHawk.Emulation.csproj b/BizHawk.Emulation/BizHawk.Emulation.csproj
index 13e58b398d..bc2ee55db0 100644
--- a/BizHawk.Emulation/BizHawk.Emulation.csproj
+++ b/BizHawk.Emulation/BizHawk.Emulation.csproj
@@ -79,6 +79,14 @@
+
+
+
+
+
+
+
+
Code
@@ -86,7 +94,6 @@
Code
-
Code
diff --git a/BizHawk.Emulation/Consoles/Nintendo/NES/BoardSystem.cs b/BizHawk.Emulation/Consoles/Nintendo/NES/BoardSystem.cs
index 7a4049f909..22a47268ad 100644
--- a/BizHawk.Emulation/Consoles/Nintendo/NES/BoardSystem.cs
+++ b/BizHawk.Emulation/Consoles/Nintendo/NES/BoardSystem.cs
@@ -82,7 +82,7 @@ namespace BizHawk.Emulation.Consoles.Nintendo
else SetMirrorType(EMirrorType.OneScreenB);
}
- protected void SetMirrorType(EMirrorType mirrorType)
+ public void SetMirrorType(EMirrorType mirrorType)
{
switch (mirrorType)
{
diff --git a/BizHawk.Emulation/Consoles/Nintendo/NES/Boards/MMC3_family/DRROM.cs b/BizHawk.Emulation/Consoles/Nintendo/NES/Boards/MMC3_family/DRROM.cs
new file mode 100644
index 0000000000..4fdf0a526d
--- /dev/null
+++ b/BizHawk.Emulation/Consoles/Nintendo/NES/Boards/MMC3_family/DRROM.cs
@@ -0,0 +1,61 @@
+using System;
+using System.IO;
+using System.Diagnostics;
+
+namespace BizHawk.Emulation.Consoles.Nintendo
+{
+ //this board contains a Namcot 109 and some extra ram for nametables
+ public class DRROM : Namcot109Board_Base
+ {
+ public override bool Configure(NES.EDetectionOrigin origin)
+ {
+ //analyze board type
+ switch (Cart.board_type)
+ {
+ case "NES-DRROM": //gauntlet (U)
+ AssertPrg(128); AssertChr(64); AssertVram(2); AssertWram(0);
+ break;
+ default:
+ return false;
+ }
+
+ BaseSetup();
+ SetMirrorType(Cart.pad_h, Cart.pad_v);
+
+ return true;
+ }
+
+ //the addressing logic for nametables is a bit speculative here
+ //how it is wired back to the NES and locally mirrored is unknown,
+ //but it probably doesnt matter in practice.
+ //still, purists could validate it.
+
+ public override byte ReadPPU(int addr)
+ {
+ if (addr < 0x2000)
+ {
+ //read patterns from mapper controlled area
+ return base.ReadPPU(addr);
+ }
+ else if (addr < 0x2800)
+ {
+ return VRAM[addr - 0x2000];
+ }
+ else return base.ReadPPU(addr);
+ }
+
+ public override void WritePPU(int addr, byte value)
+ {
+ if (addr < 0x2000)
+ {
+ //nothing wired here
+ }
+ else if (addr < 0x2800)
+ {
+ VRAM[addr - 0x2000] = value;
+ }
+ else base.WritePPU(addr, value);
+ }
+ }
+
+}
\ No newline at end of file
diff --git a/BizHawk.Emulation/Consoles/Nintendo/NES/Boards/MMC3_family/MMC3_family.cs b/BizHawk.Emulation/Consoles/Nintendo/NES/Boards/MMC3_family/MMC3_family.cs
new file mode 100644
index 0000000000..76aaaec427
--- /dev/null
+++ b/BizHawk.Emulation/Consoles/Nintendo/NES/Boards/MMC3_family/MMC3_family.cs
@@ -0,0 +1,284 @@
+//this file contains the MMC3 family of chips
+//which includes:
+//NAMCOT 109
+//MMC3 (which was apparently based on NAMCOT 109 and shares enough functionality to be derived from it in this codebase)
+
+//see http://nesdev.parodius.com/bbs/viewtopic.php?t=5426&sid=e7472c15a758ebf05c588c8330c2187f
+//and http://nesdev.parodius.com/bbs/viewtopic.php?t=311
+//for some info on NAMCOT 109
+
+//mappers handled by this:
+//004,095,118,119,206
+
+using System;
+using System.IO;
+using System.Diagnostics;
+
+namespace BizHawk.Emulation.Consoles.Nintendo
+{
+ public class Namcot109 : IDisposable
+ {
+ public Namcot109(int num_prg_banks)
+ {
+ bank_regs[8] = (byte)(num_prg_banks - 1);
+ bank_regs[9] = (byte)(num_prg_banks - 2);
+ }
+
+ public void Dispose()
+ {
+ bank_regs.Dispose();
+ prg_lookup.Dispose();
+ }
+
+ //state
+ public int chr_mode, prg_mode, reg_addr;
+
+ //this contains the 8 programmable regs and 2 more at the end to represent PRG banks -2 and -1; and 4 more at the end to break down chr regs 0 and 1
+ ByteBuffer bank_regs = new ByteBuffer(14);
+ ByteBuffer prg_lookup = new ByteBuffer(new byte[] { 6, 7, 9, 8, 9, 7, 6, 8 });
+ ByteBuffer chr_lookup = new ByteBuffer(new byte[] { 10, 11, 12, 13, 2, 3, 4, 5 });
+
+ public virtual void WritePRG(int addr, byte value)
+ {
+ switch (addr & 0x6001)
+ {
+ case 0x0000: //$8000
+ chr_mode = (value >> 7) & 1;
+ prg_mode = (value >> 6) & 1;
+ reg_addr = (value & 7);
+ break;
+ case 0x0001: //$8001
+ bank_regs[reg_addr] = value;
+ //setup the 2K chr regs
+ bank_regs[10] = (byte)((bank_regs[0] & ~1) + 0);
+ bank_regs[11] = (byte)((bank_regs[0] & ~1) + 1);
+ bank_regs[12] = (byte)((bank_regs[1] & ~1) + 0);
+ bank_regs[13] = (byte)((bank_regs[1] & ~1) + 1);
+ break;
+ }
+ }
+
+ public int Get_PRGBank_8K(int addr)
+ {
+ int bank_8k = addr >> 13;
+ bank_8k = bank_regs[prg_lookup[prg_mode * 4 + bank_8k]];
+ return bank_8k;
+ }
+
+ public int Get_CHRBank_1K(int addr)
+ {
+ int bank_1k = addr >> 10;
+ if (chr_mode == 1)
+ bank_1k ^= 4;
+ bank_1k = bank_regs[chr_lookup[bank_1k]];
+ return bank_1k;
+ }
+
+
+ }
+
+ public class MMC3 : Namcot109
+ {
+ NES.NESBoardBase board;
+ public MMC3(NES.NESBoardBase board, int num_prg_banks)
+ : base(num_prg_banks)
+ {
+ this.board = board;
+ }
+
+ //state
+ public NES.NESBoardBase.EMirrorType mirror;
+ int ppubus_state, ppubus_statecounter;
+ byte irq_reload, irq_counter;
+ bool irq_pending, irq_enable;
+
+ void SyncIRQ()
+ {
+ board.NES.irq_cart = irq_pending;
+ }
+
+ public override void WritePRG(int addr, byte value)
+ {
+ switch (addr & 0x6001)
+ {
+ case 0x0000: //$8000
+ case 0x0001: //$8001
+ base.WritePRG(addr, value);
+ break;
+ case 0x2000: //$A000
+ //mirroring
+ if ((value & 1) == 0) mirror = NES.NESBoardBase.EMirrorType.Vertical;
+ else mirror = NES.NESBoardBase.EMirrorType.Horizontal;
+ board.SetMirrorType(mirror);
+ break;
+ case 0x2001: //$A001
+ //wram enable/protect
+ break;
+ case 0x4000: //$C000
+ irq_reload = value;
+ break;
+ case 0x4001: //$C001
+ irq_counter = 0;
+ break;
+ case 0x6000: //$E000
+ irq_enable = false;
+ irq_pending = false;
+ SyncIRQ();
+ break;
+ case 0x6001: //$E001
+ irq_enable = true;
+ SyncIRQ();
+ break;
+ }
+ }
+
+ void ClockIRQ()
+ {
+ if (irq_counter == 0)
+ irq_counter = irq_reload;
+ else
+ {
+ irq_counter--;
+ //Console.WriteLine(irq_counter);
+ if (irq_counter == 0)
+ {
+ if (irq_enable)
+ irq_pending = true;
+ SyncIRQ();
+ }
+ }
+ }
+
+ //TODO - this should be determined from NES timestamps to correctly emulate ppu writes interfering
+ public void Tick_PPU(int addr)
+ {
+ ppubus_statecounter++;
+ int state = (addr >> 12) & 1;
+ if (ppubus_state == 0 && ppubus_statecounter > 1 && state == 1)
+ {
+ ppubus_statecounter = 0;
+ ClockIRQ();
+ }
+ if (ppubus_state != state)
+ {
+ ppubus_state = state;
+ }
+ }
+
+ }
+
+ public abstract class MMC3_Family_Board_Base : NES.NESBoardBase
+ {
+ //configuration
+ protected int prg_mask, chr_mask;
+
+ public override void Dispose()
+ {
+ mapper.Dispose();
+ }
+
+ protected Namcot109 mapper;
+ public override byte ReadPPU(int addr)
+ {
+ if (addr < 0x2000)
+ {
+ int bank_1k = mapper.Get_CHRBank_1K(addr);
+ bank_1k &= chr_mask;
+ addr = (bank_1k << 10) | (addr & 0x3FF);
+ if (VROM != null)
+ return VROM[addr];
+ else return VRAM[addr];
+ }
+ else return base.ReadPPU(addr);
+ }
+
+ public override void WritePPU(int addr, byte value)
+ {
+ base.WritePPU(addr, value);
+ }
+
+
+ public override void WritePRG(int addr, byte value)
+ {
+ mapper.WritePRG(addr, value);
+ }
+
+ public override byte ReadPRG(int addr)
+ {
+ int bank_8k = mapper.Get_PRGBank_8K(addr);
+ bank_8k &= prg_mask;
+ addr = (bank_8k << 13) | (addr & 0x1FFF);
+ return ROM[addr];
+ }
+
+ protected virtual void BaseSetup()
+ {
+ //remember to setup the PRG banks -1 and -2
+ int num_prg_banks = Cart.prg_size / 8;
+ prg_mask = num_prg_banks - 1;
+
+ int num_chr_banks = (Cart.chr_size);
+ chr_mask = num_chr_banks - 1;
+ }
+
+ //used by a couple of boards for controlling nametable wiring with the mapper
+ protected int RewireNametable_Mapper095_and_TLSROM(int addr, int bitsel)
+ {
+ int bank_1k = mapper.Get_CHRBank_1K(addr & 0x1FFF);
+ int nt = (bank_1k >> bitsel) & 1;
+ int ofs = addr & 0x3FF;
+ addr = 0x2000 + (nt << 10);
+ addr |= (ofs);
+ return addr;
+ }
+ }
+
+ public abstract class MMC3Board_Base : MMC3_Family_Board_Base
+ {
+ //configuration
+ protected int wram_mask;
+
+ //state
+ protected MMC3 mmc3;
+
+ public override byte ReadPPU(int addr)
+ {
+ mmc3.Tick_PPU(addr);
+ return base.ReadPPU(addr);
+ }
+
+ public override void WritePPU(int addr, byte value)
+ {
+ mmc3.Tick_PPU(addr);
+ base.WritePPU(addr, value);
+ }
+
+ public override void WritePRG(int addr, byte value)
+ {
+ base.WritePRG(addr, value);
+ }
+
+ protected override void BaseSetup()
+ {
+ wram_mask = (Cart.wram_size * 1024) - 1;
+
+ int num_prg_banks = Cart.prg_size / 8;
+ mapper = mmc3 = new MMC3(this,num_prg_banks);
+
+ base.BaseSetup();
+ SetMirrorType(EMirrorType.Vertical);
+ }
+ }
+
+ public abstract class Namcot109Board_Base : MMC3_Family_Board_Base
+ {
+ protected override void BaseSetup()
+ {
+ int num_prg_banks = Cart.prg_size / 8;
+ mapper = new Namcot109(num_prg_banks);
+
+ base.BaseSetup();
+ }
+ }
+
+}
\ No newline at end of file
diff --git a/BizHawk.Emulation/Consoles/Nintendo/NES/Boards/MMC3_family/Mapper095.cs b/BizHawk.Emulation/Consoles/Nintendo/NES/Boards/MMC3_family/Mapper095.cs
new file mode 100644
index 0000000000..021909f2f9
--- /dev/null
+++ b/BizHawk.Emulation/Consoles/Nintendo/NES/Boards/MMC3_family/Mapper095.cs
@@ -0,0 +1,40 @@
+using System;
+using System.IO;
+using System.Diagnostics;
+
+namespace BizHawk.Emulation.Consoles.Nintendo
+{
+ //pretty much just one game.
+ //wires the mapper outputs to control the nametables. check out the companion board TLSROM
+ public class Mapper095 : Namcot109Board_Base
+ {
+ public override bool Configure(NES.EDetectionOrigin origin)
+ {
+ //analyze board type
+ switch (Cart.board_type)
+ {
+ case "NAMCOT-3425": //dragon buster (J)
+ AssertPrg(128); AssertChr(32); AssertVram(0); AssertWram(0);
+ break;
+ default:
+ return false;
+ }
+
+ BaseSetup();
+ SetMirrorType(EMirrorType.Vertical);
+
+ return true;
+ }
+
+ public override byte ReadPPU(int addr)
+ {
+ if (addr < 0x2000) return base.ReadPPU(addr);
+ else return base.ReadPPU(RewireNametable_Mapper095_and_TLSROM(addr, 5));
+ }
+ public override void WritePPU(int addr, byte value)
+ {
+ if (addr < 0x2000) base.WritePPU(addr, value);
+ else base.WritePPU(RewireNametable_Mapper095_and_TLSROM(addr, 5), value);
+ }
+ }
+}
\ No newline at end of file
diff --git a/BizHawk.Emulation/Consoles/Nintendo/NES/Boards/MMC3_family/Mapper206.cs b/BizHawk.Emulation/Consoles/Nintendo/NES/Boards/MMC3_family/Mapper206.cs
new file mode 100644
index 0000000000..008ad40b52
--- /dev/null
+++ b/BizHawk.Emulation/Consoles/Nintendo/NES/Boards/MMC3_family/Mapper206.cs
@@ -0,0 +1,63 @@
+using System;
+using System.IO;
+using System.Diagnostics;
+
+namespace BizHawk.Emulation.Consoles.Nintendo
+{
+ //various japanese namcot 109 boards plus DEROM
+ public class Mapper206 : Namcot109Board_Base
+ {
+ public override bool Configure(NES.EDetectionOrigin origin)
+ {
+ //analyze board type
+ switch (Cart.board_type)
+ {
+ case "NES-DEROM": //R.B.I. baseball (U)
+ AssertPrg(64); AssertChr(32,64); AssertVram(0); AssertWram(0);
+ break;
+ case "NAMCOT-3401": //babel no tou (J)
+ AssertPrg(32); AssertChr(32); AssertVram(0); AssertWram(0);
+ break;
+ case "NAMCOT-3405": //side pocket (J)
+ AssertPrg(128); AssertChr(32); AssertVram(0); AssertWram(0);
+ throw new Exception("TODO - test please");
+ break;
+ case "NAMCOT-3406": //karnov (J)
+ AssertPrg(128); AssertChr(64); AssertVram(0); AssertWram(0);
+ break;
+ case "NAMCOT-3407": //family jockey (J)
+ AssertPrg(32); AssertChr(32); AssertVram(0); AssertWram(0);
+ break;
+ case "NAMCOT-3413": //pro yakyuu family stadium (J)
+ AssertPrg(64); AssertChr(32); AssertVram(0); AssertWram(0);
+ throw new Exception("TODO - test please");
+ break;
+ case "NAMCOT-3414": //family boxing (J)
+ AssertPrg(64); AssertChr(64); AssertVram(0); AssertWram(0);
+ break;
+ case "NAMCOT-3415": //mappy-land (J)
+ AssertPrg(128); AssertChr(32); AssertVram(0); AssertWram(0);
+ break;
+ case "NAMCOT-3416": //dragon slayer IV (J) (aka legacy of the wizard)
+ AssertPrg(128); AssertChr(64); AssertVram(0); AssertWram(0);
+ break;
+ case "NAMCOT-3417": //spy kid (J)
+ //apparently this shows up as namcot 108 as well but perhaps there is no difference
+ //(is this game older than the other namcot 109 games?)
+ AssertPrg(32); AssertChr(32); AssertVram(0); AssertWram(0);
+ throw new Exception("TODO - test please");
+ break;
+
+ default:
+ return false;
+ }
+
+ BaseSetup();
+ SetMirrorType(Cart.pad_h, Cart.pad_v);
+
+ return true;
+ }
+
+ }
+
+}
\ No newline at end of file
diff --git a/BizHawk.Emulation/Consoles/Nintendo/NES/Boards/MMC3_family/TLSROM.cs b/BizHawk.Emulation/Consoles/Nintendo/NES/Boards/MMC3_family/TLSROM.cs
new file mode 100644
index 0000000000..9334cb5663
--- /dev/null
+++ b/BizHawk.Emulation/Consoles/Nintendo/NES/Boards/MMC3_family/TLSROM.cs
@@ -0,0 +1,50 @@
+using System;
+using System.IO;
+using System.Diagnostics;
+
+namespace BizHawk.Emulation.Consoles.Nintendo
+{
+ //aka mapper 118
+ //wires the mapper outputs to control the nametables. check out the companion board Mapper095
+ public class TLSROM : MMC3Board_Base
+ {
+ public override bool Configure(NES.EDetectionOrigin origin)
+ {
+ //analyze board type
+ switch (Cart.board_type)
+ {
+ case "NES-TLSROM": //pro sport hockey (U)
+ AssertPrg(128); AssertChr(128); AssertVram(0); AssertWram(0);
+ break;
+ case "HVC-TKSROM": //ys III: wanderers from ys (J)
+ AssertPrg(256); AssertChr(128); AssertVram(0); AssertWram(8);
+ AssertBattery(true);
+ break;
+ default:
+ return false;
+ }
+
+ BaseSetup();
+ SetMirrorType(EMirrorType.Vertical);
+
+ return true;
+ }
+
+ public override void WritePRG(int addr, byte value)
+ {
+ base.WritePRG(addr, value);
+ }
+
+ public override byte ReadPPU(int addr)
+ {
+ if (addr < 0x2000) return base.ReadPPU(addr);
+ else return base.ReadPPU(RewireNametable_Mapper095_and_TLSROM(addr, 7));
+ }
+ public override void WritePPU(int addr, byte value)
+ {
+ if (addr < 0x2000) base.WritePPU(addr, value);
+ else base.WritePPU(RewireNametable_Mapper095_and_TLSROM(addr, 7), value);
+ }
+
+ }
+}
\ No newline at end of file
diff --git a/BizHawk.Emulation/Consoles/Nintendo/NES/Boards/MMC3_family/TQROM.cs b/BizHawk.Emulation/Consoles/Nintendo/NES/Boards/MMC3_family/TQROM.cs
new file mode 100644
index 0000000000..115e7613c2
--- /dev/null
+++ b/BizHawk.Emulation/Consoles/Nintendo/NES/Boards/MMC3_family/TQROM.cs
@@ -0,0 +1,69 @@
+using System;
+using System.IO;
+using System.Diagnostics;
+
+namespace BizHawk.Emulation.Consoles.Nintendo
+{
+ //aka mapper 119
+ //just high speed and pinbot with an MMC3 and some custom logic to select between chr rom and chr ram
+ public class TQSROM : MMC3Board_Base
+ {
+ public override bool Configure(NES.EDetectionOrigin origin)
+ {
+ //analyze board type
+ switch (Cart.board_type)
+ {
+ case "NES-TQROM": //high speed and pinbot
+ AssertPrg(128); AssertChr(64); AssertVram(8); AssertWram(0);
+ break;
+ default:
+ return false;
+ }
+
+ BaseSetup();
+
+ return true;
+ }
+
+ public override byte ReadPPU(int addr)
+ {
+ if (addr < 0x2000)
+ {
+ int bank_1k = mapper.Get_CHRBank_1K(addr);
+ int use_ram = (bank_1k >> 6) & 1;
+ if (use_ram == 1)
+ {
+ mmc3.Tick_PPU(addr);
+ addr = ((bank_1k&0x3f) << 10) | (addr & 0x3FF);
+ addr &= 0x1FFF;
+ return VRAM[addr];
+ }
+ else return base.ReadPPU(addr);
+ }
+ else
+ return base.ReadPPU(addr);
+ }
+
+ public override void WritePPU(int addr, byte value)
+ {
+ if (addr < 0x2000)
+ {
+ int bank_1k = mapper.Get_CHRBank_1K(addr);
+ int use_ram = (bank_1k >> 6) & 1;
+ if (use_ram == 1)
+ {
+ mmc3.Tick_PPU(addr);
+ addr = ((bank_1k & 0x3f) << 10) | (addr & 0x3FF);
+ addr &= 0x1FFF;
+ VRAM[addr] = value;
+ }
+ else base.WritePPU(addr, value);
+ }
+ else
+ base.WritePPU(addr, value);
+ }
+
+ }
+
+
+}
diff --git a/BizHawk.Emulation/Consoles/Nintendo/NES/Boards/MMC3_family/TVROM.cs b/BizHawk.Emulation/Consoles/Nintendo/NES/Boards/MMC3_family/TVROM.cs
new file mode 100644
index 0000000000..584ecee7b7
--- /dev/null
+++ b/BizHawk.Emulation/Consoles/Nintendo/NES/Boards/MMC3_family/TVROM.cs
@@ -0,0 +1,59 @@
+using System;
+using System.IO;
+using System.Diagnostics;
+
+namespace BizHawk.Emulation.Consoles.Nintendo
+{
+ public class TVROM : MMC3Board_Base
+ {
+ public override bool Configure(NES.EDetectionOrigin origin)
+ {
+ //analyze board type
+ switch (Cart.board_type)
+ {
+ case "NES-TVROM": //rad racer II (U)
+ AssertPrg(64); AssertChr(64); AssertVram(8); AssertWram(0);
+ AssertBattery(false);
+ break;
+ default:
+ return false;
+ }
+
+ BaseSetup();
+
+ return true;
+ }
+
+ //nesdev wiki says that the nes CIRAM doesnt get used at all.
+ //and that even though 8KB is really here, only 4KB gets used.
+ //still, purists could validate it.
+
+ public override byte ReadPPU(int addr)
+ {
+ mmc3.Tick_PPU(addr);
+ if (addr < 0x2000)
+ {
+ //read patterns from mapper controlled area
+ return base.ReadPPU(addr);
+ }
+ else
+ {
+ return VRAM[addr & 0xFFF];
+ }
+ }
+
+ public override void WritePPU(int addr, byte value)
+ {
+ mmc3.Tick_PPU(addr);
+ if (addr < 0x2000)
+ {
+ //nothing wired here
+ }
+ else
+ {
+ VRAM[addr & 0xFFF] = value;
+ }
+ }
+
+ }
+}
\ No newline at end of file
diff --git a/BizHawk.Emulation/Consoles/Nintendo/NES/Boards/MMC3_family/TxROM.cs b/BizHawk.Emulation/Consoles/Nintendo/NES/Boards/MMC3_family/TxROM.cs
new file mode 100644
index 0000000000..be3ada4fd6
--- /dev/null
+++ b/BizHawk.Emulation/Consoles/Nintendo/NES/Boards/MMC3_family/TxROM.cs
@@ -0,0 +1,104 @@
+using System;
+using System.IO;
+using System.Diagnostics;
+
+//http://wiki.nesdev.com/w/index.php/TxROM
+//read some background info on namco 108 and DxROM boards here
+
+namespace BizHawk.Emulation.Consoles.Nintendo
+{
+ public class TxROM : MMC3Board_Base
+ {
+ public override void WritePRG(int addr, byte value)
+ {
+ base.WritePRG(addr, value);
+ SetMirrorType(mmc3.mirror); //often redundant, but gets the job done
+ }
+
+ public override byte[] SaveRam
+ {
+ get
+ {
+ if (!Cart.wram_battery) return null;
+ return WRAM;
+ //some boards have a wram that is backed-up or not backed-up. need to handle that somehow
+ //(nestopia splits it into NVWRAM and WRAM but i didnt like that at first.. but it may player better with this architecture)
+ }
+ }
+
+ public override byte ReadWRAM(int addr)
+ {
+ if (Cart.wram_size != 0)
+ return WRAM[addr & wram_mask];
+ else return 0xFF;
+ }
+
+ public override void WriteWRAM(int addr, byte value)
+ {
+ if (Cart.wram_size != 0)
+ WRAM[addr & wram_mask] = value;
+ }
+
+
+ public override void SyncState(Serializer ser)
+ {
+ base.SyncState(ser);
+ }
+
+ public override bool Configure(NES.EDetectionOrigin origin)
+ {
+ //analyze board type
+ switch (Cart.board_type)
+ {
+ case "NES-TBROM": //tecmo world cup soccer (DE) [untested]
+ AssertPrg(64); AssertChr(64); AssertVram(0); AssertWram(0);
+ AssertBattery(false);
+ break;
+ case "NES-TEROM": //Adv of lolo 2
+ AssertPrg(32); AssertChr(32); AssertVram(0); AssertWram(0);
+ AssertBattery(false);
+ break;
+ case "NES-TFROM": //legacy of the wizard
+ AssertPrg(128); AssertChr(32, 64); AssertVram(0); AssertWram(0);
+ AssertBattery(false);
+ break;
+ case "NES-TGROM": //mega man 4 & 6
+ AssertPrg(128, 256, 512); AssertChr(0); AssertVram(8); AssertWram(0);
+ AssertBattery(false);
+ break;
+ case "NES-TKROM": //kirby's adventure
+ AssertPrg(128, 256, 512); AssertChr(128, 256); AssertVram(0); AssertWram(8);
+ break;
+ case "NES-TLROM": //mega man 3
+ AssertPrg(128, 256, 512); AssertChr(128, 256); AssertVram(0); AssertWram(0);
+ AssertBattery(false);
+ break;
+ case "NES-TL1ROM": //Double dragon 2
+ AssertPrg(128); AssertChr(128); AssertVram(0); AssertWram(0);
+ AssertBattery(false);
+ break;
+ case "NES-TL2ROM": //batman (U) ?
+ AssertPrg(128); AssertChr(128); AssertVram(0); AssertWram(0);
+ AssertBattery(false);
+ break;
+ case "NES-TSROM": //super mario bros. 3 (U)
+ AssertPrg(128, 256, 512); AssertChr(128, 256); AssertVram(0); AssertWram(8);
+ AssertBattery(false);
+ break;
+ case "NES-B4": //batman (U)
+ AssertPrg(128); AssertChr(128); AssertVram(0); AssertWram(0);
+ AssertBattery(false);
+ break;
+ default:
+ return false;
+ }
+
+ BaseSetup();
+
+ return true;
+ }
+
+ }
+
+
+}
diff --git a/BizHawk.Emulation/Consoles/Nintendo/NES/Boards/SxROM.cs b/BizHawk.Emulation/Consoles/Nintendo/NES/Boards/SxROM.cs
index 3cf70e1fed..a00ad17f88 100644
--- a/BizHawk.Emulation/Consoles/Nintendo/NES/Boards/SxROM.cs
+++ b/BizHawk.Emulation/Consoles/Nintendo/NES/Boards/SxROM.cs
@@ -225,7 +225,7 @@ namespace BizHawk.Emulation.Consoles.Nintendo
{
if (!Cart.wram_battery) return null;
return WRAM;
- //some boards have a pram that is backed-up or not backed-up. need to handle that somehow
+ //some boards have a wram that is backed-up or not backed-up. need to handle that somehow
//(nestopia splits it into NVWRAM and WRAM but i didnt like that at first.. but it may player better with this architecture)
}
}
diff --git a/BizHawk.Emulation/Consoles/Nintendo/NES/Boards/TxROM_DxROM.cs b/BizHawk.Emulation/Consoles/Nintendo/NES/Boards/TxROM_DxROM.cs
deleted file mode 100644
index 9b9bdf2e6a..0000000000
--- a/BizHawk.Emulation/Consoles/Nintendo/NES/Boards/TxROM_DxROM.cs
+++ /dev/null
@@ -1,322 +0,0 @@
-using System;
-using System.IO;
-using System.Diagnostics;
-
-//TODO - mapper 118 and 119 need to be gracefully worked in here.
-//but we might want to break them down into a new board type and reuse class mmc3. be sure to try that to see how it goes
-
-namespace BizHawk.Emulation.Consoles.Nintendo
-{
- public class TxROM_DxROM : NES.NESBoardBase
- {
- class MMC3 : IDisposable
- {
- NES.NESBoardBase board;
- public MMC3(NES.NESBoardBase board, int num_prg_banks)
- {
- this.board = board;
- bank_regs[8] = (byte)(num_prg_banks - 1);
- bank_regs[9] = (byte)(num_prg_banks - 2);
- }
-
- public void Dispose()
- {
- bank_regs.Dispose();
- prg_lookup.Dispose();
- }
-
- //state
- int chr_mode, prg_mode, reg_addr;
- public NES.NESBoardBase.EMirrorType mirror;
- int ppubus_state, ppubus_statecounter;
-
- //this contains the 8 programmable regs and 2 more at the end to represent PRG banks -2 and -1; and 4 more at the end to break down chr regs 0 and 1
- ByteBuffer bank_regs = new ByteBuffer(14);
- ByteBuffer prg_lookup = new ByteBuffer(new byte[] { 6, 7, 9, 8, 9, 7, 6, 8 });
- ByteBuffer chr_lookup = new ByteBuffer(new byte[] { 10, 11, 12, 13, 2, 3, 4, 5 });
- byte irq_reload, irq_counter;
- bool irq_pending, irq_enable;
-
- void SyncIRQ()
- {
- board.NES.irq_cart = irq_pending;
- }
-
- public void WritePRG(int addr, byte value)
- {
- switch (addr & 0x6001)
- {
- case 0x0000: //$8000
- chr_mode = (value >> 7) & 1;
- prg_mode = (value >> 6) & 1;
- reg_addr = (value & 7);
- break;
- case 0x0001: //$8001
- bank_regs[reg_addr] = value;
- //setup the 2K chr regs
- bank_regs[10] = (byte)((bank_regs[0] & ~1) + 0);
- bank_regs[11] = (byte)((bank_regs[0] & ~1) + 1);
- bank_regs[12] = (byte)((bank_regs[1] & ~1) + 0);
- bank_regs[13] = (byte)((bank_regs[1] & ~1) + 1);
- break;
- case 0x2000: //$A000
- //mirroring
- if ((value & 1) == 0) mirror = EMirrorType.Vertical;
- else mirror = EMirrorType.Horizontal;
- break;
- case 0x2001: //$A001
- //wram enable/protect
- break;
- case 0x4000: //$C000
- irq_reload = value;
- break;
- case 0x4001: //$C001
- irq_counter = 0;
- break;
- case 0x6000: //$E000
- irq_enable = false;
- irq_pending = false;
- SyncIRQ();
- break;
- case 0x6001: //$E001
- irq_enable = true;
- SyncIRQ();
- break;
- }
- }
-
- public int Get_PRGBank_8K(int addr)
- {
- int bank_8k = addr >> 13;
- bank_8k = bank_regs[prg_lookup[prg_mode * 4 + bank_8k]];
- return bank_8k;
- }
-
- public int Get_CHRBank_1K(int addr)
- {
- int bank_1k = addr >> 10;
- if (chr_mode == 1)
- bank_1k ^= 4;
- bank_1k = bank_regs[chr_lookup[bank_1k]];
- return bank_1k;
- }
-
- void ClockIRQ()
- {
- if (irq_counter == 0)
- irq_counter = irq_reload;
- else
- {
- irq_counter--;
- //Console.WriteLine(irq_counter);
- if (irq_counter == 0)
- {
- if (irq_enable)
- irq_pending = true;
- SyncIRQ();
- }
- }
- }
-
- //TODO - this should be determined from NES timestamps to correctly emulate ppu writes interfering
- public void Tick_PPU(int addr)
- {
- ppubus_statecounter++;
- int state = (addr >> 12) & 1;
- if (ppubus_state == 0 && ppubus_statecounter > 1 && state == 1)
- {
- ppubus_statecounter = 0;
- ClockIRQ();
- }
- if (ppubus_state != state)
- {
- ppubus_state = state;
- }
- }
-
- }
-
- //configuration
- int prg_mask, chr_mask;
- int wram_mask, vram_mask;
- int vram_bytes;
- bool fourscreen;
-
- //state
- MMC3 mmc3;
-
- public override void Dispose()
- {
- mmc3.Dispose();
- }
-
- public override void WritePRG(int addr, byte value)
- {
- mmc3.WritePRG(addr, value);
- SetMirrorType(mmc3.mirror); //often redundant, but gets the job done
- }
-
- public override byte ReadPRG(int addr)
- {
- int bank_8k = mmc3.Get_PRGBank_8K(addr);
- bank_8k &= prg_mask;
- addr = (bank_8k << 13) | (addr & 0x1FFF);
- return ROM[addr];
- }
-
- public override byte ReadPPU(int addr)
- {
- mmc3.Tick_PPU(addr);
- if (addr < 0x2000)
- {
- int bank_1k = mmc3.Get_CHRBank_1K(addr);
- bank_1k &= chr_mask;
- addr = (bank_1k << 10) | (addr & 0x3FF);
- if (VROM != null)
- return VROM[addr];
- else return VRAM[addr];
- }
- else if (fourscreen)
- {
- int myaddr = addr - 0x2000;
- if (myaddr < vram_bytes)
- return VRAM[myaddr];
- else
- return base.ReadPPU(addr);
- }
- else return base.ReadPPU(addr);
- }
-
- public override void WritePPU(int addr, byte value)
- {
- mmc3.Tick_PPU(addr);
- if (fourscreen)
- {
- if (addr >= 0x2000)
- {
- int myaddr = addr - 0x2000;
- if (myaddr < vram_bytes)
- VRAM[myaddr] = value;
- else
- base.WritePPU(addr, value);
- }
- else base.WritePPU(addr, value);
- }
- else base.WritePPU(addr, value);
- }
-
- public override byte ReadWRAM(int addr)
- {
- if (Cart.wram_size != 0)
- return WRAM[addr & wram_mask];
- else return 0xFF;
- }
-
- public override void WriteWRAM(int addr, byte value)
- {
- if (Cart.wram_size != 0)
- WRAM[addr & wram_mask] = value;
- }
-
- public override byte[] SaveRam
- {
- get
- {
- if (!Cart.wram_battery) return null;
- return WRAM;
- //some boards have a pram that is backed-up or not backed-up. need to handle that somehow
- //(nestopia splits it into NVWRAM and WRAM but i didnt like that at first.. but it may player better with this architecture)
- }
- }
-
- public override void SyncState(Serializer ser)
- {
- base.SyncState(ser);
- }
-
- public override bool Configure(NES.EDetectionOrigin origin)
- {
- //analyze board type
- switch (Cart.board_type)
- {
- case "NES-TBROM": //tecmo world cup soccer (DE) [untested]
- AssertPrg(64); AssertChr(64); AssertVram(0); AssertWram(0);
- AssertBattery(false);
- break;
- case "NES-TEROM": //Adv of lolo 2
- AssertPrg(32); AssertChr(32); AssertVram(0); AssertWram(0);
- AssertBattery(false);
- break;
- case "NES-TFROM": //legacy of the wizard
- AssertPrg(128); AssertChr(32, 64); AssertVram(0); AssertWram(0);
- AssertBattery(false);
- break;
- case "NES-TGROM": //mega man 4 & 6
- AssertPrg(128, 256, 512); AssertChr(0); AssertVram(8); AssertWram(0);
- AssertBattery(false);
- break;
- case "NES-TKROM": //kirby's adventure
- AssertPrg(128, 256, 512); AssertChr(128, 256); AssertVram(0); AssertWram(8);
- break;
- case "NES-TLROM": //mega man 3
- AssertPrg(128, 256, 512); AssertChr(128, 256); AssertVram(0); AssertWram(0);
- AssertBattery(false);
- break;
- case "NES-TL1ROM": //Double dragon 2
- AssertPrg(128); AssertChr(128); AssertVram(0); AssertWram(0);
- AssertBattery(false);
- break;
- case "NES-TL2ROM": //batman (U) ?
- AssertPrg(128); AssertChr(128); AssertVram(0); AssertWram(0);
- AssertBattery(false);
- break;
- case "NES-TQROM": //{mapper 119} high speed - ALMOST POSITIVELTY NEEDS WORK
- AssertPrg(128); AssertChr(64); AssertVram(8); AssertWram(0);
- AssertBattery(false);
- break;
- case "NES-TR1ROM": //gauntlet (U) - someone please test this
- AssertPrg(128); AssertChr(64); AssertVram(2); AssertWram(0);
- fourscreen = true;
- AssertBattery(false);
- break;
- case "NES-TSROM": //super mario bros. 3 (U)
- AssertPrg(128, 256, 512); AssertChr(128, 256); AssertVram(0); AssertWram(8);
- AssertBattery(false);
- break;
- case "NES-TVROM": //rad racer II (U)
- AssertPrg(64); AssertChr(64); AssertVram(8); AssertWram(0);
- fourscreen = true;
- AssertBattery(false);
- break;
- case "NES-B4": //batman (U)
- AssertPrg(128); AssertChr(128); AssertVram(0); AssertWram(0);
- AssertBattery(false);
- break;
- case "NES-DRROM": //gauntlet (U) sometimes
- AssertPrg(128); AssertChr(64); AssertVram(2); AssertWram(0);
- fourscreen = true;
- AssertBattery(false);
- break;
- default:
- return false;
- }
-
- //remember to setup the PRG banks -1 and -2
- int num_prg_banks = Cart.prg_size / 8;
- prg_mask = num_prg_banks - 1;
-
- int num_chr_banks = (Cart.chr_size);
- chr_mask = num_chr_banks - 1;
-
- wram_mask = (Cart.wram_size * 1024) - 1;
- vram_mask = (Cart.vram_size * 1024) - 1;
- vram_bytes = Cart.vram_size * 1024;
-
- mmc3 = new MMC3(this, num_prg_banks);
- SetMirrorType(EMirrorType.Vertical);
-
- return true;
- }
-
- }
-}