C64 - reorg some core code
This commit is contained in:
parent
aaf3d0a559
commit
b416645768
|
@ -109,11 +109,25 @@
|
||||||
<DependentUpon>TI83.cs</DependentUpon>
|
<DependentUpon>TI83.cs</DependentUpon>
|
||||||
</Compile>
|
</Compile>
|
||||||
<Compile Include="Calculator\TI83LinkPort.cs" />
|
<Compile Include="Calculator\TI83LinkPort.cs" />
|
||||||
<Compile Include="Computers\Commodore64\C64.Core.cs" />
|
|
||||||
<Compile Include="Computers\Commodore64\C64.cs" />
|
<Compile Include="Computers\Commodore64\C64.cs" />
|
||||||
<Compile Include="Computers\Commodore64\C64.IStatable.cs" />
|
<Compile Include="Computers\Commodore64\C64.IDebuggable.cs">
|
||||||
|
<DependentUpon>C64.cs</DependentUpon>
|
||||||
|
</Compile>
|
||||||
|
<Compile Include="Computers\Commodore64\C64.IDriveLight.cs">
|
||||||
|
<DependentUpon>C64.cs</DependentUpon>
|
||||||
|
</Compile>
|
||||||
|
<Compile Include="Computers\Commodore64\C64.IInputPollable.cs">
|
||||||
|
<DependentUpon>C64.cs</DependentUpon>
|
||||||
|
</Compile>
|
||||||
|
<Compile Include="Computers\Commodore64\C64.IMemoryDomains.cs">
|
||||||
|
<DependentUpon>C64.cs</DependentUpon>
|
||||||
|
</Compile>
|
||||||
|
<Compile Include="Computers\Commodore64\C64.IStatable.cs">
|
||||||
|
<DependentUpon>C64.cs</DependentUpon>
|
||||||
|
</Compile>
|
||||||
<Compile Include="Computers\Commodore64\C64.Motherboard.cs" />
|
<Compile Include="Computers\Commodore64\C64.Motherboard.cs" />
|
||||||
<Compile Include="Computers\Commodore64\C64.MotherboardInterface.cs" />
|
<Compile Include="Computers\Commodore64\C64.MotherboardInterface.cs" />
|
||||||
|
<Compile Include="Computers\Commodore64\C64Util.cs" />
|
||||||
<Compile Include="Computers\Commodore64\Cartridge\Mapper0000.cs" />
|
<Compile Include="Computers\Commodore64\Cartridge\Mapper0000.cs" />
|
||||||
<Compile Include="Computers\Commodore64\C64.Input.cs" />
|
<Compile Include="Computers\Commodore64\C64.Input.cs" />
|
||||||
<Compile Include="Computers\Commodore64\Cartridge\Mapper0005.cs" />
|
<Compile Include="Computers\Commodore64\Cartridge\Mapper0005.cs" />
|
||||||
|
|
|
@ -1,178 +0,0 @@
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.IO;
|
|
||||||
using BizHawk.Emulation.Common;
|
|
||||||
using BizHawk.Emulation.Cores.Computers.Commodore64.MOS;
|
|
||||||
|
|
||||||
namespace BizHawk.Emulation.Cores.Computers.Commodore64
|
|
||||||
{
|
|
||||||
public enum Region
|
|
||||||
{
|
|
||||||
NTSC,
|
|
||||||
PAL
|
|
||||||
}
|
|
||||||
|
|
||||||
sealed public partial class C64 : IEmulator, IDebuggable
|
|
||||||
{
|
|
||||||
private Motherboard board;
|
|
||||||
private bool loadPrg;
|
|
||||||
|
|
||||||
private byte[] GetFirmware(string name, int length)
|
|
||||||
{
|
|
||||||
byte[] result = CoreComm.CoreFileProvider.GetFirmware("C64", name, true);
|
|
||||||
if (result.Length != length)
|
|
||||||
throw new MissingFirmwareException(string.Format("Firmware {0} was {1} bytes, should be {2} bytes", name, result.Length, length));
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void Init(Region initRegion)
|
|
||||||
{
|
|
||||||
board = new Motherboard(this, initRegion);
|
|
||||||
InitRoms();
|
|
||||||
board.Init();
|
|
||||||
InitMedia();
|
|
||||||
|
|
||||||
// configure video
|
|
||||||
CoreComm.VsyncDen = board.vic.CyclesPerFrame;
|
|
||||||
CoreComm.VsyncNum = board.vic.CyclesPerSecond;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void InitMedia()
|
|
||||||
{
|
|
||||||
switch (inputFileInfo.Extension.ToUpper())
|
|
||||||
{
|
|
||||||
case @".CRT":
|
|
||||||
Cart cart = Cart.Load(inputFileInfo.Data);
|
|
||||||
if (cart != null)
|
|
||||||
{
|
|
||||||
board.cartPort.Connect(cart);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case @".PRG":
|
|
||||||
if (inputFileInfo.Data.Length > 2)
|
|
||||||
loadPrg = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void InitRoms()
|
|
||||||
{
|
|
||||||
byte[] basicRom = GetFirmware("Basic", 0x2000);
|
|
||||||
byte[] charRom = GetFirmware("Chargen", 0x1000);
|
|
||||||
byte[] kernalRom = GetFirmware("Kernal", 0x2000);
|
|
||||||
|
|
||||||
board.basicRom = new Chip23XX(Chip23XXmodel.Chip2364, basicRom);
|
|
||||||
board.kernalRom = new Chip23XX(Chip23XXmodel.Chip2364, kernalRom);
|
|
||||||
board.charRom = new Chip23XX(Chip23XXmodel.Chip2332, charRom);
|
|
||||||
}
|
|
||||||
|
|
||||||
// ------------------------------------
|
|
||||||
|
|
||||||
public bool DriveLED
|
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
|
||||||
//return (disk.PeekVia1(0x00) & 0x08) != 0;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void HardReset()
|
|
||||||
{
|
|
||||||
board.HardReset();
|
|
||||||
//disk.HardReset();
|
|
||||||
}
|
|
||||||
|
|
||||||
public IDictionary<string, int> GetCpuFlagsAndRegisters()
|
|
||||||
{
|
|
||||||
return new Dictionary<string, int>
|
|
||||||
{
|
|
||||||
{ "A", board.cpu.A },
|
|
||||||
{ "X", board.cpu.X },
|
|
||||||
{ "Y", board.cpu.Y },
|
|
||||||
{ "S", board.cpu.S },
|
|
||||||
{ "PC", board.cpu.PC },
|
|
||||||
{ "Flag C", board.cpu.FlagC ? 1 : 0 },
|
|
||||||
{ "Flag Z", board.cpu.FlagZ ? 1 : 0 },
|
|
||||||
{ "Flag I", board.cpu.FlagI ? 1 : 0 },
|
|
||||||
{ "Flag D", board.cpu.FlagD ? 1 : 0 },
|
|
||||||
{ "Flag B", board.cpu.FlagB ? 1 : 0 },
|
|
||||||
{ "Flag V", board.cpu.FlagV ? 1 : 0 },
|
|
||||||
{ "Flag N", board.cpu.FlagN ? 1 : 0 },
|
|
||||||
{ "Flag T", board.cpu.FlagT ? 1 : 0 }
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
public void SetCpuRegister(string register, int value)
|
|
||||||
{
|
|
||||||
switch (register)
|
|
||||||
{
|
|
||||||
default:
|
|
||||||
throw new InvalidOperationException();
|
|
||||||
case "A":
|
|
||||||
board.cpu.A = (byte)value;
|
|
||||||
break;
|
|
||||||
case "X":
|
|
||||||
board.cpu.X = (byte)value;
|
|
||||||
break;
|
|
||||||
case "Y":
|
|
||||||
board.cpu.Y = (byte)value;
|
|
||||||
break;
|
|
||||||
case "S":
|
|
||||||
board.cpu.S = (byte)value;
|
|
||||||
break;
|
|
||||||
case "PC":
|
|
||||||
board.cpu.PC = (ushort)value;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
[FeatureNotImplemented]
|
|
||||||
public void Step(StepType type) { throw new NotImplementedException(); }
|
|
||||||
|
|
||||||
public ITracer Tracer
|
|
||||||
{
|
|
||||||
[FeatureNotImplemented]
|
|
||||||
get { throw new NotImplementedException(); }
|
|
||||||
}
|
|
||||||
|
|
||||||
public IMemoryCallbackSystem MemoryCallbacks
|
|
||||||
{
|
|
||||||
[FeatureNotImplemented]
|
|
||||||
get { throw new NotImplementedException(); }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static public class C64Util
|
|
||||||
{
|
|
||||||
static public string ToBinary(int n, int charsmin)
|
|
||||||
{
|
|
||||||
string result = "";
|
|
||||||
|
|
||||||
while (n > 0 || charsmin > 0)
|
|
||||||
{
|
|
||||||
result = (((n & 0x1) != 0) ? "1" : "0") + result;
|
|
||||||
n >>= 1;
|
|
||||||
if (charsmin > 0)
|
|
||||||
charsmin--;
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
static public string ToHex(int n, int charsmin)
|
|
||||||
{
|
|
||||||
string result = "";
|
|
||||||
|
|
||||||
while (n > 0 || charsmin > 0)
|
|
||||||
{
|
|
||||||
result = "0123456789ABCDEF".Substring((n & 0xF), 1) + result;
|
|
||||||
n >>= 4;
|
|
||||||
if (charsmin > 0)
|
|
||||||
charsmin--;
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -0,0 +1,69 @@
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
|
||||||
|
using BizHawk.Emulation.Common;
|
||||||
|
|
||||||
|
namespace BizHawk.Emulation.Cores.Computers.Commodore64
|
||||||
|
{
|
||||||
|
public partial class C64 : IDebuggable
|
||||||
|
{
|
||||||
|
public IDictionary<string, int> GetCpuFlagsAndRegisters()
|
||||||
|
{
|
||||||
|
return new Dictionary<string, int>
|
||||||
|
{
|
||||||
|
{ "A", board.cpu.A },
|
||||||
|
{ "X", board.cpu.X },
|
||||||
|
{ "Y", board.cpu.Y },
|
||||||
|
{ "S", board.cpu.S },
|
||||||
|
{ "PC", board.cpu.PC },
|
||||||
|
{ "Flag C", board.cpu.FlagC ? 1 : 0 },
|
||||||
|
{ "Flag Z", board.cpu.FlagZ ? 1 : 0 },
|
||||||
|
{ "Flag I", board.cpu.FlagI ? 1 : 0 },
|
||||||
|
{ "Flag D", board.cpu.FlagD ? 1 : 0 },
|
||||||
|
{ "Flag B", board.cpu.FlagB ? 1 : 0 },
|
||||||
|
{ "Flag V", board.cpu.FlagV ? 1 : 0 },
|
||||||
|
{ "Flag N", board.cpu.FlagN ? 1 : 0 },
|
||||||
|
{ "Flag T", board.cpu.FlagT ? 1 : 0 }
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
public void SetCpuRegister(string register, int value)
|
||||||
|
{
|
||||||
|
switch (register)
|
||||||
|
{
|
||||||
|
default:
|
||||||
|
throw new InvalidOperationException();
|
||||||
|
case "A":
|
||||||
|
board.cpu.A = (byte)value;
|
||||||
|
break;
|
||||||
|
case "X":
|
||||||
|
board.cpu.X = (byte)value;
|
||||||
|
break;
|
||||||
|
case "Y":
|
||||||
|
board.cpu.Y = (byte)value;
|
||||||
|
break;
|
||||||
|
case "S":
|
||||||
|
board.cpu.S = (byte)value;
|
||||||
|
break;
|
||||||
|
case "PC":
|
||||||
|
board.cpu.PC = (ushort)value;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public ITracer Tracer
|
||||||
|
{
|
||||||
|
[FeatureNotImplemented]
|
||||||
|
get { throw new NotImplementedException(); }
|
||||||
|
}
|
||||||
|
|
||||||
|
public IMemoryCallbackSystem MemoryCallbacks
|
||||||
|
{
|
||||||
|
[FeatureNotImplemented]
|
||||||
|
get { throw new NotImplementedException(); }
|
||||||
|
}
|
||||||
|
|
||||||
|
[FeatureNotImplemented]
|
||||||
|
public void Step(StepType type) { throw new NotImplementedException(); }
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,19 @@
|
||||||
|
using BizHawk.Emulation.Common;
|
||||||
|
|
||||||
|
namespace BizHawk.Emulation.Cores.Computers.Commodore64
|
||||||
|
{
|
||||||
|
public partial class C64 : IDriveLight
|
||||||
|
{
|
||||||
|
public bool DriveLightEnabled { get { return true; } }
|
||||||
|
public bool DriveLightOn { get; private set; }
|
||||||
|
|
||||||
|
public bool DriveLED
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
//return (disk.PeekVia1(0x00) & 0x08) != 0;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,23 @@
|
||||||
|
using BizHawk.Emulation.Common;
|
||||||
|
|
||||||
|
namespace BizHawk.Emulation.Cores.Computers.Commodore64
|
||||||
|
{
|
||||||
|
public partial class C64 : IInputPollable
|
||||||
|
{
|
||||||
|
public bool IsLagFrame
|
||||||
|
{
|
||||||
|
get { return _islag; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public int LagCount
|
||||||
|
{
|
||||||
|
get { return _lagcount; }
|
||||||
|
set { _lagcount = value; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public IInputCallbackSystem InputCallbacks { get; private set; }
|
||||||
|
|
||||||
|
private bool _islag = true;
|
||||||
|
private int _lagcount = 0;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,33 @@
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using BizHawk.Emulation.Common;
|
||||||
|
|
||||||
|
namespace BizHawk.Emulation.Cores.Computers.Commodore64
|
||||||
|
{
|
||||||
|
public partial class C64 : IMemoryDomains
|
||||||
|
{
|
||||||
|
public MemoryDomainList MemoryDomains
|
||||||
|
{
|
||||||
|
get { return memoryDomains; }
|
||||||
|
}
|
||||||
|
|
||||||
|
private MemoryDomainList memoryDomains;
|
||||||
|
|
||||||
|
private void SetupMemoryDomains()
|
||||||
|
{
|
||||||
|
|
||||||
|
// chips must be initialized before this code runs!
|
||||||
|
var domains = new List<MemoryDomain>(1);
|
||||||
|
domains.Add(new MemoryDomain("System Bus", 0x10000, MemoryDomain.Endian.Little, board.cpu.Peek, board.cpu.Poke));
|
||||||
|
domains.Add(new MemoryDomain("RAM", 0x10000, MemoryDomain.Endian.Little, board.ram.Peek, board.ram.Poke));
|
||||||
|
domains.Add(new MemoryDomain("CIA0", 0x10, MemoryDomain.Endian.Little, board.cia0.Peek, board.cia0.Poke));
|
||||||
|
domains.Add(new MemoryDomain("CIA1", 0x10, MemoryDomain.Endian.Little, board.cia1.Peek, board.cia1.Poke));
|
||||||
|
domains.Add(new MemoryDomain("VIC", 0x40, MemoryDomain.Endian.Little, board.vic.Peek, board.vic.Poke));
|
||||||
|
domains.Add(new MemoryDomain("SID", 0x20, MemoryDomain.Endian.Little, board.sid.Peek, board.sid.Poke));
|
||||||
|
//domains.Add(new MemoryDomain("1541 Bus", 0x10000, MemoryDomain.Endian.Little, new Func<int, byte>(disk.Peek), new Action<int, byte>(disk.Poke)));
|
||||||
|
//domains.Add(new MemoryDomain("1541 VIA0", 0x10, MemoryDomain.Endian.Little, new Func<int, byte>(disk.PeekVia0), new Action<int, byte>(disk.PokeVia0)));
|
||||||
|
//domains.Add(new MemoryDomain("1541 VIA1", 0x10, MemoryDomain.Endian.Little, new Func<int, byte>(disk.PeekVia1), new Action<int, byte>(disk.PokeVia1)));
|
||||||
|
//domains.Add(new MemoryDomain("1541 RAM", 0x1000, MemoryDomain.Endian.Little, new Func<int, byte>(disk.PeekRam), new Action<int, byte>(disk.PokeRam)));
|
||||||
|
memoryDomains = new MemoryDomainList(domains);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -7,6 +7,8 @@ namespace BizHawk.Emulation.Cores.Computers.Commodore64
|
||||||
{
|
{
|
||||||
sealed public partial class C64 : IStatable
|
sealed public partial class C64 : IStatable
|
||||||
{
|
{
|
||||||
|
public bool BinarySaveStatesPreferred { get { return false; } }
|
||||||
|
|
||||||
public void LoadStateBinary(BinaryReader br)
|
public void LoadStateBinary(BinaryReader br)
|
||||||
{
|
{
|
||||||
SyncState(new Serializer(br));
|
SyncState(new Serializer(br));
|
||||||
|
@ -27,7 +29,16 @@ namespace BizHawk.Emulation.Cores.Computers.Commodore64
|
||||||
SyncState(new Serializer(writer));
|
SyncState(new Serializer(writer));
|
||||||
}
|
}
|
||||||
|
|
||||||
void SyncState(Serializer ser)
|
public byte[] SaveStateBinary()
|
||||||
|
{
|
||||||
|
MemoryStream ms = new MemoryStream();
|
||||||
|
BinaryWriter bw = new BinaryWriter(ms);
|
||||||
|
SaveStateBinary(bw);
|
||||||
|
bw.Flush();
|
||||||
|
return ms.ToArray();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void SyncState(Serializer ser)
|
||||||
{
|
{
|
||||||
ser.BeginSection("core");
|
ser.BeginSection("core");
|
||||||
board.SyncState(ser);
|
board.SyncState(ser);
|
||||||
|
|
|
@ -7,6 +7,13 @@ using BizHawk.Emulation.Cores.Computers.Commodore64.MOS;
|
||||||
|
|
||||||
namespace BizHawk.Emulation.Cores.Computers.Commodore64
|
namespace BizHawk.Emulation.Cores.Computers.Commodore64
|
||||||
{
|
{
|
||||||
|
// TODO: use the EMulation.Common Region enum
|
||||||
|
public enum Region
|
||||||
|
{
|
||||||
|
NTSC,
|
||||||
|
PAL
|
||||||
|
}
|
||||||
|
|
||||||
[CoreAttributes(
|
[CoreAttributes(
|
||||||
"C64Hawk",
|
"C64Hawk",
|
||||||
"SaxxonPIke",
|
"SaxxonPIke",
|
||||||
|
@ -14,11 +21,25 @@ namespace BizHawk.Emulation.Cores.Computers.Commodore64
|
||||||
isReleased: false
|
isReleased: false
|
||||||
)]
|
)]
|
||||||
[ServiceNotApplicable(typeof(ISettable<,>))]
|
[ServiceNotApplicable(typeof(ISettable<,>))]
|
||||||
sealed public partial class C64 : IEmulator, IMemoryDomains, IStatable, IInputPollable, IDriveLight
|
sealed public partial class C64 : IEmulator, IMemoryDomains, IStatable, IInputPollable, IDriveLight, IDebuggable
|
||||||
{
|
{
|
||||||
|
// framework
|
||||||
|
public C64(CoreComm comm, GameInfo game, byte[] rom, string romextension)
|
||||||
|
{
|
||||||
|
ServiceProvider = new BasicServiceProvider(this);
|
||||||
|
InputCallbacks = new InputCallbackSystem();
|
||||||
|
|
||||||
|
inputFileInfo = new InputFileInfo();
|
||||||
|
inputFileInfo.Data = rom;
|
||||||
|
inputFileInfo.Extension = romextension;
|
||||||
|
CoreComm = comm;
|
||||||
|
Init(Region.PAL);
|
||||||
|
cyclesPerFrame = board.vic.CyclesPerFrame;
|
||||||
|
SetupMemoryDomains();
|
||||||
|
HardReset();
|
||||||
|
}
|
||||||
|
|
||||||
// internal variables
|
// internal variables
|
||||||
private bool _islag = true;
|
|
||||||
private int _lagcount = 0;
|
|
||||||
private int _frame = 0;
|
private int _frame = 0;
|
||||||
private int cyclesPerFrame;
|
private int cyclesPerFrame;
|
||||||
private InputFileInfo inputFileInfo;
|
private InputFileInfo inputFileInfo;
|
||||||
|
@ -32,15 +53,9 @@ namespace BizHawk.Emulation.Cores.Computers.Commodore64
|
||||||
|
|
||||||
public string BoardName { get { return null; } }
|
public string BoardName { get { return null; } }
|
||||||
|
|
||||||
// memory domains
|
|
||||||
private MemoryDomainList memoryDomains;
|
|
||||||
public MemoryDomainList MemoryDomains { get { return memoryDomains; } }
|
|
||||||
|
|
||||||
// running state
|
// running state
|
||||||
public bool DeterministicEmulation { get { return true; } set { ; } }
|
public bool DeterministicEmulation { get { return true; } set { ; } }
|
||||||
public int Frame { get { return _frame; } set { _frame = value; } }
|
public int Frame { get { return _frame; } set { _frame = value; } }
|
||||||
public bool IsLagFrame { get { return _islag; } }
|
|
||||||
public int LagCount { get { return _lagcount; } set { _lagcount = value; } }
|
|
||||||
public void ResetCounters()
|
public void ResetCounters()
|
||||||
{
|
{
|
||||||
_frame = 0;
|
_frame = 0;
|
||||||
|
@ -74,23 +89,6 @@ namespace BizHawk.Emulation.Cores.Computers.Commodore64
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// framework
|
|
||||||
public C64(CoreComm comm, GameInfo game, byte[] rom, string romextension)
|
|
||||||
{
|
|
||||||
ServiceProvider = new BasicServiceProvider(this);
|
|
||||||
inputFileInfo = new InputFileInfo();
|
|
||||||
inputFileInfo.Data = rom;
|
|
||||||
inputFileInfo.Extension = romextension;
|
|
||||||
CoreComm = comm;
|
|
||||||
Init(Region.PAL);
|
|
||||||
cyclesPerFrame = board.vic.CyclesPerFrame;
|
|
||||||
SetupMemoryDomains();
|
|
||||||
HardReset();
|
|
||||||
}
|
|
||||||
|
|
||||||
public bool DriveLightEnabled { get { return true; } }
|
|
||||||
public bool DriveLightOn { get; private set; }
|
|
||||||
|
|
||||||
public IEmulatorServiceProvider ServiceProvider { get; private set; }
|
public IEmulatorServiceProvider ServiceProvider { get; private set; }
|
||||||
|
|
||||||
public void Dispose()
|
public void Dispose()
|
||||||
|
@ -180,35 +178,64 @@ namespace BizHawk.Emulation.Cores.Computers.Commodore64
|
||||||
throw new FileNotFoundException();
|
throw new FileNotFoundException();
|
||||||
}
|
}
|
||||||
|
|
||||||
public byte[] SaveStateBinary()
|
private Motherboard board;
|
||||||
|
private bool loadPrg;
|
||||||
|
|
||||||
|
private byte[] GetFirmware(string name, int length)
|
||||||
{
|
{
|
||||||
MemoryStream ms = new MemoryStream();
|
byte[] result = CoreComm.CoreFileProvider.GetFirmware("C64", name, true);
|
||||||
BinaryWriter bw = new BinaryWriter(ms);
|
if (result.Length != length)
|
||||||
SaveStateBinary(bw);
|
throw new MissingFirmwareException(string.Format("Firmware {0} was {1} bytes, should be {2} bytes", name, result.Length, length));
|
||||||
bw.Flush();
|
return result;
|
||||||
return ms.ToArray();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool BinarySaveStatesPreferred { get { return false; } }
|
private void Init(Region initRegion)
|
||||||
|
|
||||||
private readonly InputCallbackSystem _inputCallbacks = new InputCallbackSystem();
|
|
||||||
public IInputCallbackSystem InputCallbacks { get { return _inputCallbacks; } }
|
|
||||||
|
|
||||||
private void SetupMemoryDomains()
|
|
||||||
{
|
{
|
||||||
// chips must be initialized before this code runs!
|
board = new Motherboard(this, initRegion);
|
||||||
var domains = new List<MemoryDomain>(1);
|
InitRoms();
|
||||||
domains.Add(new MemoryDomain("System Bus", 0x10000, MemoryDomain.Endian.Little, board.cpu.Peek, board.cpu.Poke));
|
board.Init();
|
||||||
domains.Add(new MemoryDomain("RAM", 0x10000, MemoryDomain.Endian.Little, board.ram.Peek, board.ram.Poke));
|
InitMedia();
|
||||||
domains.Add(new MemoryDomain("CIA0", 0x10, MemoryDomain.Endian.Little, board.cia0.Peek, board.cia0.Poke));
|
|
||||||
domains.Add(new MemoryDomain("CIA1", 0x10, MemoryDomain.Endian.Little, board.cia1.Peek, board.cia1.Poke));
|
// configure video
|
||||||
domains.Add(new MemoryDomain("VIC", 0x40, MemoryDomain.Endian.Little, board.vic.Peek, board.vic.Poke));
|
CoreComm.VsyncDen = board.vic.CyclesPerFrame;
|
||||||
domains.Add(new MemoryDomain("SID", 0x20, MemoryDomain.Endian.Little, board.sid.Peek, board.sid.Poke));
|
CoreComm.VsyncNum = board.vic.CyclesPerSecond;
|
||||||
//domains.Add(new MemoryDomain("1541 Bus", 0x10000, MemoryDomain.Endian.Little, new Func<int, byte>(disk.Peek), new Action<int, byte>(disk.Poke)));
|
}
|
||||||
//domains.Add(new MemoryDomain("1541 VIA0", 0x10, MemoryDomain.Endian.Little, new Func<int, byte>(disk.PeekVia0), new Action<int, byte>(disk.PokeVia0)));
|
|
||||||
//domains.Add(new MemoryDomain("1541 VIA1", 0x10, MemoryDomain.Endian.Little, new Func<int, byte>(disk.PeekVia1), new Action<int, byte>(disk.PokeVia1)));
|
private void InitMedia()
|
||||||
//domains.Add(new MemoryDomain("1541 RAM", 0x1000, MemoryDomain.Endian.Little, new Func<int, byte>(disk.PeekRam), new Action<int, byte>(disk.PokeRam)));
|
{
|
||||||
memoryDomains = new MemoryDomainList(domains);
|
switch (inputFileInfo.Extension.ToUpper())
|
||||||
|
{
|
||||||
|
case @".CRT":
|
||||||
|
Cart cart = Cart.Load(inputFileInfo.Data);
|
||||||
|
if (cart != null)
|
||||||
|
{
|
||||||
|
board.cartPort.Connect(cart);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case @".PRG":
|
||||||
|
if (inputFileInfo.Data.Length > 2)
|
||||||
|
loadPrg = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void InitRoms()
|
||||||
|
{
|
||||||
|
byte[] basicRom = GetFirmware("Basic", 0x2000);
|
||||||
|
byte[] charRom = GetFirmware("Chargen", 0x1000);
|
||||||
|
byte[] kernalRom = GetFirmware("Kernal", 0x2000);
|
||||||
|
|
||||||
|
board.basicRom = new Chip23XX(Chip23XXmodel.Chip2364, basicRom);
|
||||||
|
board.kernalRom = new Chip23XX(Chip23XXmodel.Chip2364, kernalRom);
|
||||||
|
board.charRom = new Chip23XX(Chip23XXmodel.Chip2332, charRom);
|
||||||
|
}
|
||||||
|
|
||||||
|
// ------------------------------------
|
||||||
|
|
||||||
|
public void HardReset()
|
||||||
|
{
|
||||||
|
board.HardReset();
|
||||||
|
//disk.HardReset();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,35 @@
|
||||||
|
namespace BizHawk.Emulation.Cores.Computers.Commodore64
|
||||||
|
{
|
||||||
|
public static class C64Util
|
||||||
|
{
|
||||||
|
static public string ToBinary(int n, int charsmin)
|
||||||
|
{
|
||||||
|
string result = "";
|
||||||
|
|
||||||
|
while (n > 0 || charsmin > 0)
|
||||||
|
{
|
||||||
|
result = (((n & 0x1) != 0) ? "1" : "0") + result;
|
||||||
|
n >>= 1;
|
||||||
|
if (charsmin > 0)
|
||||||
|
charsmin--;
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
static public string ToHex(int n, int charsmin)
|
||||||
|
{
|
||||||
|
string result = "";
|
||||||
|
|
||||||
|
while (n > 0 || charsmin > 0)
|
||||||
|
{
|
||||||
|
result = "0123456789ABCDEF".Substring((n & 0xF), 1) + result;
|
||||||
|
n >>= 4;
|
||||||
|
if (charsmin > 0)
|
||||||
|
charsmin--;
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -7,9 +7,9 @@ using BizHawk.Common;
|
||||||
|
|
||||||
namespace BizHawk.Emulation.Cores.Computers.Commodore64
|
namespace BizHawk.Emulation.Cores.Computers.Commodore64
|
||||||
{
|
{
|
||||||
static class SaveState
|
internal static class SaveState
|
||||||
{
|
{
|
||||||
static private Encoding encoding = Encoding.Unicode;
|
static private Encoding encoding = Encoding.Unicode;
|
||||||
|
|
||||||
static public void SyncObject(Serializer ser, object obj)
|
static public void SyncObject(Serializer ser, object obj)
|
||||||
{
|
{
|
||||||
|
@ -70,13 +70,13 @@ namespace BizHawk.Emulation.Cores.Computers.Commodore64
|
||||||
ser.Sync(member.Name, ref refBool);
|
ser.Sync(member.Name, ref refBool);
|
||||||
currentValue = refBool;
|
currentValue = refBool;
|
||||||
break;
|
break;
|
||||||
case "Boolean[]":
|
case "Boolean[]":
|
||||||
{
|
{
|
||||||
bool[] tmp = (bool[])currentValue;
|
bool[] tmp = (bool[])currentValue;
|
||||||
ser.Sync(member.Name, ref tmp, false);
|
ser.Sync(member.Name, ref tmp, false);
|
||||||
currentValue = tmp;
|
currentValue = tmp;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case "Byte":
|
case "Byte":
|
||||||
refByte = (Byte)currentValue;
|
refByte = (Byte)currentValue;
|
||||||
ser.Sync(member.Name, ref refByte);
|
ser.Sync(member.Name, ref refByte);
|
||||||
|
@ -92,8 +92,8 @@ namespace BizHawk.Emulation.Cores.Computers.Commodore64
|
||||||
ser.Sync(member.Name, ref refByteBuffer);
|
ser.Sync(member.Name, ref refByteBuffer);
|
||||||
currentValue = refByteBuffer;
|
currentValue = refByteBuffer;
|
||||||
break;
|
break;
|
||||||
case "Func`1":
|
case "Func`1":
|
||||||
break;
|
break;
|
||||||
case "Int16":
|
case "Int16":
|
||||||
refInt16 = (Int16)currentValue;
|
refInt16 = (Int16)currentValue;
|
||||||
ser.Sync(member.Name, ref refInt16);
|
ser.Sync(member.Name, ref refInt16);
|
||||||
|
@ -137,14 +137,14 @@ namespace BizHawk.Emulation.Cores.Computers.Commodore64
|
||||||
ser.Sync(member.Name, ref refSByte);
|
ser.Sync(member.Name, ref refSByte);
|
||||||
currentValue = refSByte;
|
currentValue = refSByte;
|
||||||
break;
|
break;
|
||||||
case "String":
|
case "String":
|
||||||
{
|
{
|
||||||
var refString = (String)currentValue;
|
var refString = (String)currentValue;
|
||||||
var refVal = new ByteBuffer(encoding.GetBytes(refString));
|
var refVal = new ByteBuffer(encoding.GetBytes(refString));
|
||||||
ser.Sync(member.Name, ref refVal);
|
ser.Sync(member.Name, ref refVal);
|
||||||
currentValue = encoding.GetString(refVal.Arr);
|
currentValue = encoding.GetString(refVal.Arr);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case "UInt16":
|
case "UInt16":
|
||||||
refUInt16 = (UInt16)currentValue;
|
refUInt16 = (UInt16)currentValue;
|
||||||
ser.Sync(member.Name, ref refUInt16);
|
ser.Sync(member.Name, ref refUInt16);
|
||||||
|
@ -155,40 +155,40 @@ namespace BizHawk.Emulation.Cores.Computers.Commodore64
|
||||||
ser.Sync(member.Name, ref refUInt32);
|
ser.Sync(member.Name, ref refUInt32);
|
||||||
currentValue = refUInt32;
|
currentValue = refUInt32;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
{
|
{
|
||||||
Type t = currentValue.GetType();
|
Type t = currentValue.GetType();
|
||||||
if (t.IsEnum)
|
if (t.IsEnum)
|
||||||
{
|
{
|
||||||
refInt32 = (Int32)currentValue;
|
refInt32 = (Int32)currentValue;
|
||||||
ser.Sync(member.Name, ref refInt32);
|
ser.Sync(member.Name, ref refInt32);
|
||||||
currentValue = refInt32;
|
currentValue = refInt32;
|
||||||
}
|
}
|
||||||
else if (t.IsValueType)
|
else if (t.IsValueType)
|
||||||
{
|
{
|
||||||
fail = true;
|
fail = true;
|
||||||
}
|
}
|
||||||
else if (t.IsClass)
|
else if (t.IsClass)
|
||||||
{
|
{
|
||||||
fail = true;
|
fail = true;
|
||||||
foreach (var method in t.GetMethods())
|
foreach (var method in t.GetMethods())
|
||||||
{
|
{
|
||||||
if (method.Name == "SyncState")
|
if (method.Name == "SyncState")
|
||||||
{
|
{
|
||||||
ser.BeginSection(fieldInfo.Name);
|
ser.BeginSection(fieldInfo.Name);
|
||||||
method.Invoke(currentValue, new object[] {(Serializer)ser});
|
method.Invoke(currentValue, new object[] { (Serializer)ser });
|
||||||
ser.EndSection();
|
ser.EndSection();
|
||||||
fail = false;
|
fail = false;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
fail = true;
|
fail = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue