diff --git a/Assets/gamedb/gamedb_channelf.txt b/Assets/gamedb/gamedb_channelf.txt
index 18cdc344ac..e8d7681bd9 100644
--- a/Assets/gamedb/gamedb_channelf.txt
+++ b/Assets/gamedb/gamedb_channelf.txt
@@ -56,8 +56,8 @@ F80AF74B09D058B90E719BB7DFBDD50E Drag Race (USA) ChannelF USA
4C10FA5C7316C59EFA241043FC67DFA8 Magic Numbers - Mind Reader + Nim (USA) ChannelF USA
A8E6103FCAE4D0F9E14D9EDCFC3FC493 Math Quiz I - Addition + Subtraction (USA) ChannelF USA
86B77EAFDF7B806E19E01724987E384F Math Quiz II - Multiplication + Division (USA) ChannelF USA
-6565DF74539476D66FD78DE1BAC0259C Maze, Jailbreak, Blind-man's-bluff, Trailblazer (USA) ChannelF USA
-53E4CC2DA0F2C167E0692B794CB7692C Maze, Jailbreak, Blind-man's-bluff, Trailblazer (USA) (Alt 1) ChannelF USA
+6565DF74539476D66FD78DE1BAC0259C Maze, Jailbreak, Blind-man's-bluff, Trailblazer (USA) ChannelF board=MAZE USA
+53E4CC2DA0F2C167E0692B794CB7692C Maze, Jailbreak, Blind-man's-bluff, Trailblazer (USA) (Alt 1) ChannelF board=MAZE USA
2B3CA549E27579E4519A765FD8F52D0F Memory Match 1 & 2 (USA) ChannelF USA
1FBD86DCCA0E4619963B902C48AE77F2 Muehle, Tontauben-Schiessen, Kreatives Malspiel, Videoscope (Germany) ChannelF Germany
C2A44D22D3865B036479E9311C74D3AD Ordtaevling (Sweden) ChannelF Sweden
@@ -66,7 +66,7 @@ E90339B7068C6227D54F3C0CA637E017 Pinball Challenge (USA) ChannelF USA
9A894D745356A050F95410983C3BC54A Pro Football (USA) ChannelF USA
913ECBAA30816C6D78DE8651251761FC Rat' Mal (Germany) ChannelF Germany
3783B6AC359E21B99CFA17773AA811C6 Robot War, Torpedo Alley (USA) ChannelF USA
-5568205F926333914DEDC8EF8BF16AF2 Schach (Germany) ChannelF Germany
+5568205F926333914DEDC8EF8BF16AF2 Schach (Germany) ChannelF board=SCHACH Germany
442E362A39018F2D117F43FE013D1D8B Scrolling Mountains (200x)(Curtdawg) ChannelF
DFB66EE145FAB65062FDEADAFC8DC34C Slot Machine (USA) ChannelF USA
4CB12EDAE37DF23851884B82CA410754 Sonar Search (USA) ChannelF USA
diff --git a/src/BizHawk.Emulation.Cores/Consoles/Fairchild/ChannelF/Cart/VesCartBase.cs b/src/BizHawk.Emulation.Cores/Consoles/Fairchild/ChannelF/Cart/VesCartBase.cs
index d5b9f12aaf..6cf2183516 100644
--- a/src/BizHawk.Emulation.Cores/Consoles/Fairchild/ChannelF/Cart/VesCartBase.cs
+++ b/src/BizHawk.Emulation.Cores/Consoles/Fairchild/ChannelF/Cart/VesCartBase.cs
@@ -1,12 +1,13 @@
using BizHawk.Common;
+using BizHawk.Common.NumberExtensions;
using BizHawk.Emulation.Common;
+using System.Collections;
namespace BizHawk.Emulation.Cores.Consoles.ChannelF
{
public abstract class VesCartBase
{
- public abstract string BoardType { get; }
- public abstract void SyncState(Serializer ser);
+ public abstract string BoardType { get; }
public virtual void SyncByteArrayDomain(ChannelF sys)
{
@@ -27,6 +28,15 @@ namespace BizHawk.Emulation.Cores.Consoles.ChannelF
}
protected byte[] _ram;
+ // SRAM config
+ // taken from https://github.com/mamedev/mame/blob/ee1e4f9683a4953cb9d88f9256017fcbc38e3144/src/devices/bus/chanf/rom.cpp
+ // (license:BSD-3-Clause - copyright-holders:Fabio Priuli)
+ protected byte[] m_latch = new byte[2];
+ protected ushort m_addr_latch;
+ protected int m_addr;
+ protected int m_read_write;
+ protected int m_data0;
+
public abstract byte ReadBus(ushort addr);
public abstract void WriteBus(ushort addr, byte value);
public abstract byte ReadPort(ushort addr);
@@ -40,16 +50,131 @@ namespace BizHawk.Emulation.Cores.Consoles.ChannelF
switch (boardStr)
{
// standard cart layout - default to this
- case "STD":
- default:
+ case "STD":
// any number of F3851 Program Storage Units (1KB ROM each) or F3856 Program Storage Unit (2KB ROM)
// no on-pcb RAM and no extra IO
return new mapper_STD(rom);
+ case "MAZE":
+ return new mapper_MAZE(rom);
+
+ case "SCHACH":
+ default:
+ // F3853 Memory Interface Chip, 6KB of ROM and 2KB of RAM
+ return new mapper_SCHACH(rom);
+
case "HANG":
return new mapper_HANG(rom);
}
}
+
+ ///
+ /// Write method for carts that have an IO-accessible 2102 SRAM chip
+ /// Taken from: https://github.com/mamedev/mame/blob/ee1e4f9683a4953cb9d88f9256017fcbc38e3144/src/devices/bus/chanf/rom.cpp
+ /// license:BSD-3-Clause
+ /// copyright-holders:Fabio Priuli
+ ///
+ public void SRAM2102_Write(int index, byte data)
+ {
+ switch (index)
+ {
+ case 0:
+ m_latch[0] = data;
+
+ m_read_write = data.Bit(0) ? 1 : 0;// BIT(data, 0);
+
+ //m_addr_latch = (m_addr_latch & 0x3f3) | (BIT(data, 2) << 2) | (BIT(data, 1) << 3); // bits 2,3 come from this write!
+ m_addr_latch = (ushort)((m_addr_latch & 0x3f3) | (data.Bit(2) ? 1 : 0 << 2) | (data.Bit(1) ? 1 : 0 << 3)); // bits 2,3 come from this write!
+
+ m_addr = m_addr_latch;
+
+ m_data0 = data.Bit(3) ? 1 : 0; // BIT(data, 3);
+
+ if (m_read_write == 1)
+ RAM[m_addr] = (byte)m_data0;
+ break;
+
+ case 1:
+ m_latch[1] = data;
+ // all bits but 2,3 come from this write, but they are shuffled
+ // notice that data is 8bits, so when swapping bit8 & bit9 are always 0!
+ //m_addr_latch = (m_addr_latch & 0x0c) | (bitswap < 16 > ((uint16_t)data, 15, 14, 13, 12, 11, 10, 7, 6, 5, 3, 2, 1, 9, 8, 4, 0));
+
+ if (m_addr_latch > 0)
+ {
+ BitArray b = new BitArray(m_addr_latch);
+ b[9] = m_addr_latch.Bit(7);
+ b[8] = m_addr_latch.Bit(6);
+ b[7] = m_addr_latch.Bit(5);
+ b[6] = m_addr_latch.Bit(3);
+ b[5] = m_addr_latch.Bit(2);
+ b[4] = m_addr_latch.Bit(1);
+ b[3] = m_addr_latch.Bit(3);
+ b[2] = m_addr_latch.Bit(2);
+ b[1] = m_addr_latch.Bit(4);
+ b[0] = m_addr_latch.Bit(0);
+ var resBytes = new byte[1];
+ b.CopyTo(resBytes, 0);
+ m_addr_latch = resBytes[0];
+ }
+
+ break;
+
+ default:
+
+ break;
+ }
+ }
+
+ ///
+ /// Read method for carts that have an IO-accessible 2102 SRAM chip
+ /// Taken from: https://github.com/mamedev/mame/blob/ee1e4f9683a4953cb9d88f9256017fcbc38e3144/src/devices/bus/chanf/rom.cpp
+ /// license:BSD-3-Clause
+ /// copyright-holders:Fabio Priuli
+ ///
+ public byte SRAM2102_Read(int index)
+ {
+ switch (index)
+ {
+ case 0:
+ if (m_read_write == 0)
+ {
+ m_addr = m_addr_latch;
+ m_data0 = RAM[m_addr] & 1;
+ return (byte)((m_latch[0] & 0x7f) | (m_data0 << 7));
+ }
+
+ return m_latch[0];
+
+ case 1:
+ return m_latch[1];
+
+ default:
+ return 0xFF;
+ }
+ }
+
+ public void Reset()
+ {
+ m_latch[0] = 0;
+ m_latch[1] = 0;
+ m_addr = 0;
+ m_addr_latch = 0;
+ m_read_write = 0;
+ m_data0 = 0;
+ }
+
+ public virtual void SyncState(Serializer ser)
+ {
+ ser.BeginSection("Cart");
+ ser.Sync(nameof(RAM), ref _ram, false);
+ ser.Sync(nameof(m_latch), ref m_latch, false);
+ ser.Sync(nameof(m_addr_latch), ref m_addr_latch);
+ ser.Sync(nameof(m_addr), ref m_addr);
+ ser.Sync(nameof(m_read_write), ref m_read_write);
+ ser.Sync(nameof(m_data0), ref m_data0);
+ ser.EndSection();
+ }
}
}
diff --git a/src/BizHawk.Emulation.Cores/Consoles/Fairchild/ChannelF/Cart/mapper_HANG.cs b/src/BizHawk.Emulation.Cores/Consoles/Fairchild/ChannelF/Cart/mapper_HANG.cs
index 710d55b1ab..3b472e1cda 100644
--- a/src/BizHawk.Emulation.Cores/Consoles/Fairchild/ChannelF/Cart/mapper_HANG.cs
+++ b/src/BizHawk.Emulation.Cores/Consoles/Fairchild/ChannelF/Cart/mapper_HANG.cs
@@ -1,6 +1,8 @@
using BizHawk.Common;
+using BizHawk.Common.NumberExtensions;
using System;
+using System.Collections;
namespace BizHawk.Emulation.Cores.Consoles.ChannelF
{
@@ -10,7 +12,7 @@ namespace BizHawk.Emulation.Cores.Consoles.ChannelF
///
public class mapper_HANG : VesCartBase
{
- public override string BoardType => "STD";
+ public override string BoardType => "HANG";
public mapper_HANG(byte[] rom)
{
@@ -24,7 +26,7 @@ namespace BizHawk.Emulation.Cores.Consoles.ChannelF
}
}
- RAM = new byte[0];
+ RAM = new byte[0x400];
}
public override byte ReadBus(ushort addr)
@@ -40,18 +42,71 @@ namespace BizHawk.Emulation.Cores.Consoles.ChannelF
public override byte ReadPort(ushort addr)
{
- return 0xFF;
+ var result = 0xFF;
+
+ switch (addr)
+ {
+ case 0x24:
+ if (m_read_write == 0)
+ {
+ m_addr = m_addr_latch;
+ m_data0 = RAM[m_addr] & 1;
+ return (byte)((m_latch[0] & 0x7f) | (m_data0 << 7));
+ }
+
+ return m_latch[0];
+
+ case 0x25:
+ return m_latch[1];
+ }
+
+ return (byte)result;
}
public override void WritePort(ushort addr, byte data)
{
- // no writeable hardware
- }
+ switch (addr)
+ {
+ case 20:
+ m_latch[0] = data;
- public override void SyncState(Serializer ser)
- {
- ser.BeginSection("Cart");
- ser.EndSection();
+ m_read_write = data.Bit(0) ? 1 : 0;// BIT(data, 0);
+
+ //m_addr_latch = (m_addr_latch & 0x3f3) | (BIT(data, 2) a<< 2) | (BIT(data, 1) << 3); // bits 2,3 come from this write!
+ m_addr_latch = (ushort)((m_addr_latch & 0x3f3) | (data.Bit(2) ? 1 : 0 << 2) | (data.Bit(1) ? 1 : 0 << 3)); // bits 2,3 come from this write!
+
+ m_addr = m_addr_latch;
+
+ m_data0 = data.Bit(3) ? 1 : 0; // BIT(data, 3);
+
+ if (m_read_write == 1)
+ RAM[m_addr] = (byte)m_data0;
+ break;
+
+ case 21:
+ m_latch[1] = data;
+ // all bits but 2,3 come from this write, but they are shuffled
+ // notice that data is 8bits, so when swapping bit8 & bit9 are always 0!
+ //m_addr_latch = (m_addr_latch & 0x0c) | (bitswap < 16 > ((uint16_t)data, 15, 14, 13, 12, 11, 10, 7, 6, 5, 3, 2, 1, 9, 8, 4, 0));
+
+ BitArray b = new BitArray(m_addr_latch);
+ b[9] = m_addr_latch.Bit(7);
+ b[8] = m_addr_latch.Bit(6);
+ b[7] = m_addr_latch.Bit(5);
+ b[6] = m_addr_latch.Bit(3);
+ b[5] = m_addr_latch.Bit(2);
+ b[4] = m_addr_latch.Bit(1);
+ b[3] = m_addr_latch.Bit(3);
+ b[2] = m_addr_latch.Bit(2);
+ b[1] = m_addr_latch.Bit(4);
+ b[0] = m_addr_latch.Bit(0);
+ var resBytes = new byte[1];
+ b.CopyTo(resBytes, 0);
+ m_addr_latch = resBytes[0];
+
+ break;
+
+ }
+ }
}
- }
}
diff --git a/src/BizHawk.Emulation.Cores/Consoles/Fairchild/ChannelF/Cart/mapper_MAZE.cs b/src/BizHawk.Emulation.Cores/Consoles/Fairchild/ChannelF/Cart/mapper_MAZE.cs
new file mode 100644
index 0000000000..624c4d40af
--- /dev/null
+++ b/src/BizHawk.Emulation.Cores/Consoles/Fairchild/ChannelF/Cart/mapper_MAZE.cs
@@ -0,0 +1,106 @@
+
+using BizHawk.Common;
+using BizHawk.Common.NumberExtensions;
+using System;
+using System.Collections;
+
+namespace BizHawk.Emulation.Cores.Consoles.ChannelF
+{
+ ///
+ /// ChannelF Cartridge that utilises 2102 SRAM over IO
+ ///
+ public class mapper_MAZE : VesCartBase
+ {
+ public override string BoardType => "MAZE";
+
+ public mapper_MAZE(byte[] rom)
+ {
+ ROM = new byte[0xFFFF - 0x800];
+ for (int i = 0; i < rom.Length; i++)
+ {
+ ROM[i] = rom[i];
+ }
+
+ RAM = new byte[400];
+ }
+
+ public override byte ReadBus(ushort addr)
+ {
+ var off = addr - 0x800;
+ return ROM[off];
+ }
+
+ public override void WriteBus(ushort addr, byte value)
+ {
+ // no directly writeable memory
+ }
+
+ public override byte ReadPort(ushort addr)
+ {
+ var result = 0xFF;
+
+ switch (addr)
+ {
+ case 0x24:
+ if (m_read_write == 0)
+ {
+ m_addr = m_addr_latch;
+ m_data0 = RAM[m_addr] & 1;
+ return (byte)((m_latch[0] & 0x7f) | (m_data0 << 7));
+ }
+
+ return m_latch[0];
+
+ case 0x25:
+ return m_latch[1];
+ }
+
+ return (byte)result;
+ }
+
+ public override void WritePort(ushort addr, byte data)
+ {
+ switch (addr)
+ {
+ case 24:
+ m_latch[0] = data;
+
+ m_read_write = data.Bit(0) ? 1 : 0;// BIT(data, 0);
+
+ //m_addr_latch = (m_addr_latch & 0x3f3) | (BIT(data, 2) << 2) | (BIT(data, 1) << 3); // bits 2,3 come from this write!
+ m_addr_latch = (ushort)((m_addr_latch & 0x3f3) | (data.Bit(2) ? 1 : 0 << 2) | (data.Bit(1) ? 1 : 0 << 3)); // bits 2,3 come from this write!
+
+ m_addr = m_addr_latch;
+
+ m_data0 = data.Bit(3) ? 1 : 0; // BIT(data, 3);
+
+ if (m_read_write == 1)
+ RAM[m_addr] = (byte)m_data0;
+ break;
+
+ case 25:
+ m_latch[1] = data;
+ // all bits but 2,3 come from this write, but they are shuffled
+ // notice that data is 8bits, so when swapping bit8 & bit9 are always 0!
+ //m_addr_latch = (m_addr_latch & 0x0c) | (bitswap < 16 > ((uint16_t)data, 15, 14, 13, 12, 11, 10, 7, 6, 5, 3, 2, 1, 9, 8, 4, 0));
+
+ BitArray b = new BitArray(m_addr_latch);
+ b[9] = m_addr_latch.Bit(7);
+ b[8] = m_addr_latch.Bit(6);
+ b[7] = m_addr_latch.Bit(5);
+ b[6] = m_addr_latch.Bit(3);
+ b[5] = m_addr_latch.Bit(2);
+ b[4] = m_addr_latch.Bit(1);
+ b[3] = m_addr_latch.Bit(3);
+ b[2] = m_addr_latch.Bit(2);
+ b[1] = m_addr_latch.Bit(4);
+ b[0] = m_addr_latch.Bit(0);
+ var resBytes = new byte[1];
+ b.CopyTo(resBytes, 0);
+ m_addr_latch = resBytes[0];
+
+ break;
+ }
+ }
+ }
+}
diff --git a/src/BizHawk.Emulation.Cores/Consoles/Fairchild/ChannelF/Cart/mapper_SCHACH.cs b/src/BizHawk.Emulation.Cores/Consoles/Fairchild/ChannelF/Cart/mapper_SCHACH.cs
new file mode 100644
index 0000000000..afcc274300
--- /dev/null
+++ b/src/BizHawk.Emulation.Cores/Consoles/Fairchild/ChannelF/Cart/mapper_SCHACH.cs
@@ -0,0 +1,68 @@
+
+using BizHawk.Common;
+using System;
+
+namespace BizHawk.Emulation.Cores.Consoles.ChannelF
+{
+ ///
+ /// Saba Schach Mapper
+ /// 6KB ROM / 2KB RAM
+ /// Info here: http://www.seanriddle.com/chanfmulti.html
+ ///
+ public class mapper_SCHACH : VesCartBase
+ {
+ public override string BoardType => "MAZE";
+
+ public mapper_SCHACH(byte[] rom)
+ {
+ ROM = new byte[0xFFFF - 0x800];
+ for (int i = 0; i < rom.Length; i++)
+ {
+ ROM[i] = rom[i];
+ }
+
+ RAM = new byte[0x800 * 3];
+ }
+
+ public override byte ReadBus(ushort addr)
+ {
+ var result = 0x00;
+ var off = addr - 0x800;
+
+ if (addr >= 0x2000 && addr < 0x3000)
+ {
+ // 2KB RAM
+ result = RAM[addr - 0x2000];
+ }
+ else
+ {
+ result = ROM[off];
+ }
+
+ return (byte)result;
+ }
+
+ public override void WriteBus(ushort addr, byte value)
+ {
+ // 2KB writeable memory at 0x2800;
+ if (addr >= 0x2000 && addr < 0x3000)
+ {
+ RAM[addr - 0x2000] = value;
+ }
+ else
+ {
+
+ }
+ }
+
+ public override byte ReadPort(ushort addr)
+ {
+ return 0xFF;
+ }
+
+ public override void WritePort(ushort addr, byte data)
+ {
+ // no writeable hardware
+ }
+ }
+}
diff --git a/src/BizHawk.Emulation.Cores/Consoles/Fairchild/ChannelF/Cart/mapper_STD.cs b/src/BizHawk.Emulation.Cores/Consoles/Fairchild/ChannelF/Cart/mapper_STD.cs
index 04c8dfd7f5..37be4481e4 100644
--- a/src/BizHawk.Emulation.Cores/Consoles/Fairchild/ChannelF/Cart/mapper_STD.cs
+++ b/src/BizHawk.Emulation.Cores/Consoles/Fairchild/ChannelF/Cart/mapper_STD.cs
@@ -43,11 +43,5 @@ namespace BizHawk.Emulation.Cores.Consoles.ChannelF
{
// no writeable hardware
}
-
- public override void SyncState(Serializer ser)
- {
- ser.BeginSection("Cart");
- ser.EndSection();
- }
}
}
diff --git a/src/BizHawk.Emulation.Cores/Consoles/Fairchild/ChannelF/ChannelF.cs b/src/BizHawk.Emulation.Cores/Consoles/Fairchild/ChannelF/ChannelF.cs
index 322be5c37f..22cf9135fd 100644
--- a/src/BizHawk.Emulation.Cores/Consoles/Fairchild/ChannelF/ChannelF.cs
+++ b/src/BizHawk.Emulation.Cores/Consoles/Fairchild/ChannelF/ChannelF.cs
@@ -29,6 +29,7 @@ namespace BizHawk.Emulation.Cores.Consoles.ChannelF
var bios01 = CoreComm.CoreFileProvider.GetFirmwareOrThrow(new("ChannelF", "ChannelF_sl131253"));
var bios02 = CoreComm.CoreFileProvider.GetFirmwareOrThrow(new("ChannelF", "ChannelF_sl131254"));
+ //var bios02 = CoreComm.CoreFileProvider.GetFirmwareOrThrow(new("ChannelF", "ChannelF_sl90025"));
Cartridge = VesCartBase.Configure(_gameInfo.First(), _files.First());