diff --git a/BizHawk.Emulation/BizHawk.Emulation.csproj b/BizHawk.Emulation/BizHawk.Emulation.csproj
index 3e26e648a4..38751c3fee 100644
--- a/BizHawk.Emulation/BizHawk.Emulation.csproj
+++ b/BizHawk.Emulation/BizHawk.Emulation.csproj
@@ -124,6 +124,7 @@
Code
+
diff --git a/BizHawk.Emulation/Consoles/Nintendo/NES/Boards/BANDAI_74_161_02_74.cs b/BizHawk.Emulation/Consoles/Nintendo/NES/Boards/BANDAI_74_161_02_74.cs
new file mode 100644
index 0000000000..4bb024bc51
--- /dev/null
+++ b/BizHawk.Emulation/Consoles/Nintendo/NES/Boards/BANDAI_74_161_02_74.cs
@@ -0,0 +1,157 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace BizHawk.Emulation.Consoles.Nintendo
+{
+ class BANDAI_74_161_02_74 : NES.NESBoardBase
+ {
+ /*
+ Here are Disch's original notes:
+ ========================
+ = Mapper 096 =
+ ========================
+
+
+ Example Games:
+ --------------------------
+ Oeka Kids - Anpanman no Hiragana Daisuki
+ Oeka Kids - Anpanman to Oekaki Shiyou!!
+
+
+ Notes:
+ ---------------------------
+ These games use the Oeka Kids tablet -- so you'll need to add support for that if you really want to test
+ these.
+
+ These games use 32k of CHR-RAM, which is swappable in a very unique fashion. Be sure to read the CHR Setup
+ section in detail.
+
+
+ Registers:
+ ---------------------------
+ I'm unsure whether or not this mapper suffers from bus conflicts. Use caution!
+
+
+ $8000-FFFF: [.... .CPP]
+ C = CHR Block select (see CHR Setup)
+ P = PRG Page select (32k @ $8000)
+
+
+
+ CHR Setup:
+ ---------------------------
+
+ This mapper is tricky!!!
+
+ Firstly, this mapper divides the 32k CHR-RAM into two 16k blocks (above 'C' bit selects which block is used).
+ The selected pages (including the fixed page) are taken from only the currently selected 16k block.
+
+ $0000 $0400 $0800 $0C00 $1000 $1400 $1800 $1C00
+ +-------------------------------+-------------------------------+
+ | **See below** | { 3 } |
+ +-------------------------------+-------------------------------+
+
+
+ But that's the easy part. This mapper does a very, very cool trick which watches the PPU address lines to
+ effectively "split" the nametable into 4 smaller sections -- thereby assigning a different CHR-RAM page to
+ each section. This allows **every single tile in the NT** to have a unique tile graphic!
+
+ Long story short:
+
+ A nametable spans from $2000-$23BF ($23C0-$23FF are the attribute table).
+ The mapper breaks the NT up like so:
+
+ $2000-20FF = use CHR page 0
+ $2100-21FF = use CHR page 1
+ $2200-22FF = use CHR page 2
+ $2300-23BF = use CHR page 3
+
+ the other nametables at $2400, $2800, $2C00 are broken up in the same fashion.
+
+
+
+
+ Long story long:
+
+ PPU Address lines are modified as the PPU fetches tiles, and also when the game manually changes the PPU
+ address (via the second write to $2006 --- or by the increment after read/writing $2007). The mapper
+ monitors every change to the PPU Address lines, and when it lies within a certain range, it swaps the
+ appropriate CHR page in.
+
+ It will only swap CHR when the address falls between $2000-2FFF (or mirrored regions like $6000-6FFF,
+ $A000-AFFF, $E000-EFFF). $3xxx will not trigger a swap.
+
+ When in that range, it checks to make sure the address is not attribute tables ((Addr AND $03FF) < $03C0).
+ Note I'm not 100% sure if the mapper really does this or not. It's very possible that attribute fetches will
+ also swap CHR... this would not really disrupt anything other than making the game be more careful about its
+ PPU writes.
+
+ When all that checks out, bits 8 and 9 (Addr AND $0300) select the 4k CHR page to swap in to $0000.
+
+
+ Note that the mapper does not distinguish between PPU driven line changes and game driven line changes.
+ This means that games can manually swap the CHR page by doing specific writes to $2006:
+
+
+ LDA #$20
+ STA $2006
+ STA $2006 ; Addr set to $20xx -- CHR page 0 selected
+
+ LDA #$21
+ STA $2006
+ STA $2006 ; Addr set to $21xx -- CHR page 1 selected
+
+ And in fact, games would HAVE to do that to select CHR, since that's the only way to fill CHR RAM with the
+ desired data. So make sure your emu supports this.
+ */
+ int chr_block;
+ int prg_bank_mask_32k;
+ byte prg_bank_32k;
+
+ public override bool Configure(NES.EDetectionOrigin origin)
+ {
+ //analyze board type
+ switch (Cart.board_type)
+ {
+ case "MAPPER096":
+ break;
+ default:
+ return false;
+ }
+
+ chr_block = 0;
+ prg_bank_mask_32k = Cart.prg_size / 32 - 1;
+ return true;
+ }
+
+ public override void SyncState(Serializer ser)
+ {
+ base.SyncState(ser);
+ ser.Sync("chr_block", ref chr_block);
+ ser.Sync("prg_bank_mask_16k", ref prg_bank_mask_32k);
+ ser.Sync("prg_bank_16k", ref prg_bank_32k);
+ }
+
+ public override void WritePRG(int addr, byte value)
+ {
+ prg_bank_mask_32k = (byte)(value & 0x03);
+ chr_block = (value >> 2) & 0x01;
+ }
+
+ public override byte ReadPRG(int addr)
+ {
+ int bank_32k = prg_bank_32k & prg_bank_mask_32k;
+ return ROM[(bank_32k * 0x8000) + addr];
+ }
+
+ public override byte ReadPPU(int addr)
+ {
+ if (addr < 0x2000)
+ {
+ }
+ return base.ReadPPU(addr);
+ }
+ }
+}