ChannelFHawk: Cart 2102 SRAM Implementation
This commit is contained in:
parent
ddf07ebe27
commit
2a67ad625f
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 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
|
||||
/// </summary>
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 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
|
||||
/// </summary>
|
||||
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();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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
|
|||
/// </summary>
|
||||
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;
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,106 @@
|
|||
|
||||
using BizHawk.Common;
|
||||
using BizHawk.Common.NumberExtensions;
|
||||
using System;
|
||||
using System.Collections;
|
||||
|
||||
namespace BizHawk.Emulation.Cores.Consoles.ChannelF
|
||||
{
|
||||
/// <summary>
|
||||
/// ChannelF Cartridge that utilises 2102 SRAM over IO
|
||||
/// </summary>
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,68 @@
|
|||
|
||||
using BizHawk.Common;
|
||||
using System;
|
||||
|
||||
namespace BizHawk.Emulation.Cores.Consoles.ChannelF
|
||||
{
|
||||
/// <summary>
|
||||
/// Saba Schach Mapper
|
||||
/// 6KB ROM / 2KB RAM
|
||||
/// Info here: http://www.seanriddle.com/chanfmulti.html
|
||||
/// </summary>
|
||||
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
|
||||
}
|
||||
}
|
||||
}
|
|
@ -43,11 +43,5 @@ namespace BizHawk.Emulation.Cores.Consoles.ChannelF
|
|||
{
|
||||
// no writeable hardware
|
||||
}
|
||||
|
||||
public override void SyncState(Serializer ser)
|
||||
{
|
||||
ser.BeginSection("Cart");
|
||||
ser.EndSection();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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());
|
||||
|
||||
|
|
Loading…
Reference in New Issue