ColecoVision - cleanup

This commit is contained in:
adelikat 2017-05-08 11:37:16 -05:00
parent d7928377f2
commit 01eb150b3d
5 changed files with 122 additions and 127 deletions

View File

@ -12,36 +12,36 @@ namespace BizHawk.Emulation.Cores.ColecoVision
{ {
return new Dictionary<string, RegisterValue> return new Dictionary<string, RegisterValue>
{ {
["A"] = Cpu.RegisterA, ["A"] = _cpu.RegisterA,
["AF"] = Cpu.RegisterAF, ["AF"] = _cpu.RegisterAF,
["B"] = Cpu.RegisterB, ["B"] = _cpu.RegisterB,
["BC"] = Cpu.RegisterBC, ["BC"] = _cpu.RegisterBC,
["C"] = Cpu.RegisterC, ["C"] = _cpu.RegisterC,
["D"] = Cpu.RegisterD, ["D"] = _cpu.RegisterD,
["DE"] = Cpu.RegisterDE, ["DE"] = _cpu.RegisterDE,
["E"] = Cpu.RegisterE, ["E"] = _cpu.RegisterE,
["F"] = Cpu.RegisterF, ["F"] = _cpu.RegisterF,
["H"] = Cpu.RegisterH, ["H"] = _cpu.RegisterH,
["HL"] = Cpu.RegisterHL, ["HL"] = _cpu.RegisterHL,
["I"] = Cpu.RegisterI, ["I"] = _cpu.RegisterI,
["IX"] = Cpu.RegisterIX, ["IX"] = _cpu.RegisterIX,
["IY"] = Cpu.RegisterIY, ["IY"] = _cpu.RegisterIY,
["L"] = Cpu.RegisterL, ["L"] = _cpu.RegisterL,
["PC"] = Cpu.RegisterPC, ["PC"] = _cpu.RegisterPC,
["R"] = Cpu.RegisterR, ["R"] = _cpu.RegisterR,
["Shadow AF"] = Cpu.RegisterShadowAF, ["Shadow AF"] = _cpu.RegisterShadowAF,
["Shadow BC"] = Cpu.RegisterShadowBC, ["Shadow BC"] = _cpu.RegisterShadowBC,
["Shadow DE"] = Cpu.RegisterShadowDE, ["Shadow DE"] = _cpu.RegisterShadowDE,
["Shadow HL"] = Cpu.RegisterShadowHL, ["Shadow HL"] = _cpu.RegisterShadowHL,
["SP"] = Cpu.RegisterSP, ["SP"] = _cpu.RegisterSP,
["Flag C"] = Cpu.RegisterF.Bit(0), ["Flag C"] = _cpu.RegisterF.Bit(0),
["Flag N"] = Cpu.RegisterF.Bit(1), ["Flag N"] = _cpu.RegisterF.Bit(1),
["Flag P/V"] = Cpu.RegisterF.Bit(2), ["Flag P/V"] = _cpu.RegisterF.Bit(2),
["Flag 3rd"] = Cpu.RegisterF.Bit(3), ["Flag 3rd"] = _cpu.RegisterF.Bit(3),
["Flag H"] = Cpu.RegisterF.Bit(4), ["Flag H"] = _cpu.RegisterF.Bit(4),
["Flag 5th"] = Cpu.RegisterF.Bit(5), ["Flag 5th"] = _cpu.RegisterF.Bit(5),
["Flag Z"] = Cpu.RegisterF.Bit(6), ["Flag Z"] = _cpu.RegisterF.Bit(6),
["Flag S"] = Cpu.RegisterF.Bit(7) ["Flag S"] = _cpu.RegisterF.Bit(7)
}; };
} }
@ -52,70 +52,70 @@ namespace BizHawk.Emulation.Cores.ColecoVision
default: default:
throw new InvalidOperationException(); throw new InvalidOperationException();
case "A": case "A":
Cpu.RegisterA = (byte)value; _cpu.RegisterA = (byte)value;
break; break;
case "AF": case "AF":
Cpu.RegisterAF = (byte)value; _cpu.RegisterAF = (byte)value;
break; break;
case "B": case "B":
Cpu.RegisterB = (byte)value; _cpu.RegisterB = (byte)value;
break; break;
case "BC": case "BC":
Cpu.RegisterBC = (byte)value; _cpu.RegisterBC = (byte)value;
break; break;
case "C": case "C":
Cpu.RegisterC = (byte)value; _cpu.RegisterC = (byte)value;
break; break;
case "D": case "D":
Cpu.RegisterD = (byte)value; _cpu.RegisterD = (byte)value;
break; break;
case "DE": case "DE":
Cpu.RegisterDE = (byte)value; _cpu.RegisterDE = (byte)value;
break; break;
case "E": case "E":
Cpu.RegisterE = (byte)value; _cpu.RegisterE = (byte)value;
break; break;
case "F": case "F":
Cpu.RegisterF = (byte)value; _cpu.RegisterF = (byte)value;
break; break;
case "H": case "H":
Cpu.RegisterH = (byte)value; _cpu.RegisterH = (byte)value;
break; break;
case "HL": case "HL":
Cpu.RegisterHL = (byte)value; _cpu.RegisterHL = (byte)value;
break; break;
case "I": case "I":
Cpu.RegisterI = (byte)value; _cpu.RegisterI = (byte)value;
break; break;
case "IX": case "IX":
Cpu.RegisterIX = (byte)value; _cpu.RegisterIX = (byte)value;
break; break;
case "IY": case "IY":
Cpu.RegisterIY = (byte)value; _cpu.RegisterIY = (byte)value;
break; break;
case "L": case "L":
Cpu.RegisterL = (byte)value; _cpu.RegisterL = (byte)value;
break; break;
case "PC": case "PC":
Cpu.RegisterPC = (ushort)value; _cpu.RegisterPC = (ushort)value;
break; break;
case "R": case "R":
Cpu.RegisterR = (byte)value; _cpu.RegisterR = (byte)value;
break; break;
case "Shadow AF": case "Shadow AF":
Cpu.RegisterShadowAF = (byte)value; _cpu.RegisterShadowAF = (byte)value;
break; break;
case "Shadow BC": case "Shadow BC":
Cpu.RegisterShadowBC = (byte)value; _cpu.RegisterShadowBC = (byte)value;
break; break;
case "Shadow DE": case "Shadow DE":
Cpu.RegisterShadowDE = (byte)value; _cpu.RegisterShadowDE = (byte)value;
break; break;
case "Shadow HL": case "Shadow HL":
Cpu.RegisterShadowHL = (byte)value; _cpu.RegisterShadowHL = (byte)value;
break; break;
case "SP": case "SP":
Cpu.RegisterSP = (byte)value; _cpu.RegisterSP = (byte)value;
break; break;
} }
} }
@ -130,6 +130,6 @@ namespace BizHawk.Emulation.Cores.ColecoVision
throw new NotImplementedException(); throw new NotImplementedException();
} }
public int TotalExecutedCycles => Cpu.TotalExecutedCycles; public int TotalExecutedCycles => _cpu.TotalExecutedCycles;
} }
} }

View File

@ -12,14 +12,14 @@ namespace BizHawk.Emulation.Cores.ColecoVision
public void FrameAdvance(IController controller, bool render, bool renderSound) public void FrameAdvance(IController controller, bool render, bool renderSound)
{ {
_controller = controller; _controller = controller;
Cpu.Debug = Tracer.Enabled; _cpu.Debug = _tracer.Enabled;
frame++; _frame++;
_isLag = true; _isLag = true;
PSG.BeginFrame(Cpu.TotalExecutedCycles); PSG.BeginFrame(_cpu.TotalExecutedCycles);
if (Cpu.Debug && Cpu.Logger == null) // TODO, lets not do this on each frame. But lets refactor CoreComm/CoreComm first if (_cpu.Debug && _cpu.Logger == null) // TODO, lets not do this on each frame. But lets refactor CoreComm/CoreComm first
{ {
Cpu.Logger = (s) => Tracer.Put(s); _cpu.Logger = (s) => _tracer.Put(s);
} }
byte tempRet1 = ControllerDeck.ReadPort1(controller, true, true); byte tempRet1 = ControllerDeck.ReadPort1(controller, true, true);
@ -27,9 +27,9 @@ namespace BizHawk.Emulation.Cores.ColecoVision
bool intPending = (!tempRet1.Bit(4)) | (!tempRet2.Bit(4)); bool intPending = (!tempRet1.Bit(4)) | (!tempRet2.Bit(4));
VDP.ExecuteFrame(intPending); _vdp.ExecuteFrame(intPending);
PSG.EndFrame(Cpu.TotalExecutedCycles); PSG.EndFrame(_cpu.TotalExecutedCycles);
if (_isLag) if (_isLag)
{ {
@ -37,7 +37,7 @@ namespace BizHawk.Emulation.Cores.ColecoVision
} }
} }
public int Frame => frame; public int Frame => _frame;
public string SystemId => "Coleco"; public string SystemId => "Coleco";
@ -45,7 +45,7 @@ namespace BizHawk.Emulation.Cores.ColecoVision
public void ResetCounters() public void ResetCounters()
{ {
frame = 0; _frame = 0;
_lagCount = 0; _lagCount = 0;
_isLag = false; _isLag = false;
} }

View File

@ -24,7 +24,7 @@ namespace BizHawk.Emulation.Cores.ColecoVision
throw new ArgumentOutOfRangeException(); throw new ArgumentOutOfRangeException();
} }
return Cpu.ReadMemory((ushort)addr); return _cpu.ReadMemory((ushort)addr);
}, },
(addr, value) => (addr, value) =>
{ {
@ -33,7 +33,7 @@ namespace BizHawk.Emulation.Cores.ColecoVision
throw new ArgumentOutOfRangeException(); throw new ArgumentOutOfRangeException();
} }
Cpu.WriteMemory((ushort)addr, value); _cpu.WriteMemory((ushort)addr, value);
}, 1) }, 1)
}; };
@ -47,8 +47,8 @@ namespace BizHawk.Emulation.Cores.ColecoVision
private void SyncAllByteArrayDomains() private void SyncAllByteArrayDomains()
{ {
SyncByteArrayDomain("Main RAM", Ram); SyncByteArrayDomain("Main RAM", _ram);
SyncByteArrayDomain("Video RAM", VDP.VRAM); SyncByteArrayDomain("Video RAM", _vdp.VRAM);
} }
private void SyncByteArrayDomain(string name, byte[] data) private void SyncByteArrayDomain(string name, byte[] data)

View File

@ -53,11 +53,11 @@ namespace BizHawk.Emulation.Cores.ColecoVision
private void SyncState(Serializer ser) private void SyncState(Serializer ser)
{ {
ser.BeginSection("Coleco"); ser.BeginSection("Coleco");
Cpu.SyncState(ser); _cpu.SyncState(ser);
VDP.SyncState(ser); _vdp.SyncState(ser);
PSG.SyncState(ser); PSG.SyncState(ser);
ser.Sync("RAM", ref Ram, false); ser.Sync("RAM", ref _ram, false);
ser.Sync("Frame", ref frame); ser.Sync("Frame", ref _frame);
ser.Sync("LagCount", ref _lagCount); ser.Sync("LagCount", ref _lagCount);
ser.Sync("IsLag", ref _isLag); ser.Sync("IsLag", ref _isLag);
ser.EndSection(); ser.EndSection();

View File

@ -15,13 +15,13 @@ namespace BizHawk.Emulation.Cores.ColecoVision
[CoreConstructor("Coleco")] [CoreConstructor("Coleco")]
public ColecoVision(CoreComm comm, GameInfo game, byte[] rom, object syncSettings) public ColecoVision(CoreComm comm, GameInfo game, byte[] rom, object syncSettings)
{ {
ServiceProvider = new BasicServiceProvider(this); var ser = new BasicServiceProvider(this);
MemoryCallbacks = new MemoryCallbackSystem(); MemoryCallbacks = new MemoryCallbackSystem();
CoreComm = comm; CoreComm = comm;
_syncSettings = (ColecoSyncSettings)syncSettings ?? new ColecoSyncSettings(); _syncSettings = (ColecoSyncSettings)syncSettings ?? new ColecoSyncSettings();
bool skipbios = _syncSettings.SkipBiosIntro; bool skipbios = _syncSettings.SkipBiosIntro;
Cpu = new Z80A _cpu = new Z80A
{ {
ReadMemory = ReadMemory, ReadMemory = ReadMemory,
WriteMemory = WriteMemory, WriteMemory = WriteMemory,
@ -32,15 +32,15 @@ namespace BizHawk.Emulation.Cores.ColecoVision
PSG = new SN76489(); PSG = new SN76489();
_fakeSyncSound = new FakeSyncSound(PSG, 735); _fakeSyncSound = new FakeSyncSound(PSG, 735);
(ServiceProvider as BasicServiceProvider).Register<ISoundProvider>(_fakeSyncSound); ser.Register<ISoundProvider>(_fakeSyncSound);
ControllerDeck = new ColecoVisionControllerDeck(_syncSettings.Port1, _syncSettings.Port2); ControllerDeck = new ColecoVisionControllerDeck(_syncSettings.Port1, _syncSettings.Port2);
VDP = new TMS9918A(Cpu); _vdp = new TMS9918A(_cpu);
(ServiceProvider as BasicServiceProvider).Register<IVideoProvider>(VDP); ser.Register<IVideoProvider>(_vdp);
// TODO: hack to allow bios-less operation would be nice, no idea if its feasible // TODO: hack to allow bios-less operation would be nice, no idea if its feasible
BiosRom = CoreComm.CoreFileProvider.GetFirmware("Coleco", "Bios", true, "Coleco BIOS file is required."); _biosRom = CoreComm.CoreFileProvider.GetFirmware("Coleco", "Bios", true, "Coleco BIOS file is required.");
// gamedb can overwrite the syncsettings; this is ok // gamedb can overwrite the syncsettings; this is ok
if (game["NoSkip"]) if (game["NoSkip"])
@ -49,45 +49,47 @@ namespace BizHawk.Emulation.Cores.ColecoVision
} }
LoadRom(rom, skipbios); LoadRom(rom, skipbios);
_game = game;
SetupMemoryDomains(); SetupMemoryDomains();
Tracer.Header = Cpu.TraceHeader; _tracer.Header = _cpu.TraceHeader;
var serviceProvider = ServiceProvider as BasicServiceProvider; ser.Register<IDisassemblable>(new Disassembler());
serviceProvider.Register<IDisassemblable>(new Disassembler()); ser.Register<ITraceable>(_tracer);
serviceProvider.Register<ITraceable>(Tracer);
ServiceProvider = ser;
} }
// ROM private readonly Z80A _cpu;
private byte[] RomData; private readonly TMS9918A _vdp;
private byte[] BiosRom; private readonly byte[] _biosRom;
private readonly TraceBuffer _tracer = new TraceBuffer();
// Machine
private Z80A Cpu;
private TMS9918A VDP;
private byte[] Ram = new byte[1024];
private readonly TraceBuffer Tracer = new TraceBuffer();
public ColecoVisionControllerDeck ControllerDeck { get; private set; }
private const ushort RamSizeMask = 0x03FF;
private byte[] _romData;
private byte[] _ram = new byte[1024];
private int _frame;
private IController _controller; private IController _controller;
private enum InputPortMode
{
Left, Right
}
private InputPortMode _inputPortSelection;
public ColecoVisionControllerDeck ControllerDeck { get; }
private void LoadRom(byte[] rom, bool skipbios) private void LoadRom(byte[] rom, bool skipbios)
{ {
RomData = new byte[0x8000]; _romData = new byte[0x8000];
for (int i = 0; i < 0x8000; i++) for (int i = 0; i < 0x8000; i++)
{ {
RomData[i] = rom[i % rom.Length]; _romData[i] = rom[i % rom.Length];
} }
// hack to skip colecovision title screen // hack to skip colecovision title screen
if (skipbios) if (skipbios)
{ {
RomData[0] = 0x55; _romData[0] = 0x55;
RomData[1] = 0xAA; _romData[1] = 0xAA;
} }
} }
@ -99,10 +101,10 @@ namespace BizHawk.Emulation.Cores.ColecoVision
{ {
if ((port & 1) == 0) if ((port & 1) == 0)
{ {
return VDP.ReadData(); return _vdp.ReadData();
} }
return VDP.ReadVdpStatus(); return _vdp.ReadVdpStatus();
} }
if (port >= 0xE0) if (port >= 0xE0)
@ -126,11 +128,11 @@ namespace BizHawk.Emulation.Cores.ColecoVision
{ {
if ((port & 1) == 0) if ((port & 1) == 0)
{ {
VDP.WriteVdpData(value); _vdp.WriteVdpData(value);
} }
else else
{ {
VDP.WriteVdpControl(value); _vdp.WriteVdpControl(value);
} }
return; return;
@ -138,43 +140,38 @@ namespace BizHawk.Emulation.Cores.ColecoVision
if (port >= 0x80 && port <= 0x9F) if (port >= 0x80 && port <= 0x9F)
{ {
InputPortSelection = InputPortMode.Right; _inputPortSelection = InputPortMode.Right;
return; return;
} }
if (port >= 0xC0 && port <= 0xDF) if (port >= 0xC0 && port <= 0xDF)
{ {
InputPortSelection = InputPortMode.Left; _inputPortSelection = InputPortMode.Left;
return; return;
} }
if (port >= 0xE0) if (port >= 0xE0)
{ {
PSG.WritePsgData(value, Cpu.TotalExecutedCycles); PSG.WritePsgData(value, _cpu.TotalExecutedCycles);
return;
} }
} }
private GameInfo _game;
public enum InputPortMode { Left, Right }
private InputPortMode InputPortSelection;
private byte ReadController1() private byte ReadController1()
{ {
_isLag = false; _isLag = false;
byte retval; byte retval;
if (InputPortSelection == InputPortMode.Left) if (_inputPortSelection == InputPortMode.Left)
{ {
retval = ControllerDeck.ReadPort1(_controller, true, false); retval = ControllerDeck.ReadPort1(_controller, true, false);
return retval; return retval;
} }
if (InputPortSelection == InputPortMode.Right) if (_inputPortSelection == InputPortMode.Right)
{ {
retval = ControllerDeck.ReadPort1(_controller, false, false); retval = ControllerDeck.ReadPort1(_controller, false, false);
return retval; return retval;
} }
return 0x7F; return 0x7F;
} }
@ -182,52 +179,50 @@ namespace BizHawk.Emulation.Cores.ColecoVision
{ {
_isLag = false; _isLag = false;
byte retval; byte retval;
if (InputPortSelection == InputPortMode.Left) if (_inputPortSelection == InputPortMode.Left)
{ {
retval = ControllerDeck.ReadPort2(_controller, true, false); retval = ControllerDeck.ReadPort2(_controller, true, false);
return retval; return retval;
} }
if (InputPortSelection == InputPortMode.Right) if (_inputPortSelection == InputPortMode.Right)
{ {
retval = ControllerDeck.ReadPort2(_controller, false, false); retval = ControllerDeck.ReadPort2(_controller, false, false);
return retval; return retval;
} }
return 0x7F; return 0x7F;
} }
private int frame; private byte ReadMemory(ushort addr)
public byte ReadMemory(ushort addr)
{ {
if (addr >= 0x8000) if (addr >= 0x8000)
{ {
return RomData[addr & 0x7FFF]; return _romData[addr & 0x7FFF];
} }
if (addr >= 0x6000) if (addr >= 0x6000)
{ {
return Ram[addr & 1023]; return _ram[addr & 1023];
} }
if (addr < 0x2000) if (addr < 0x2000)
{ {
return BiosRom[addr]; return _biosRom[addr];
} }
//Console.WriteLine("Unhandled read at {0:X4}", addr); ////Console.WriteLine("Unhandled read at {0:X4}", addr);
return 0xFF; return 0xFF;
} }
public void WriteMemory(ushort addr, byte value) private void WriteMemory(ushort addr, byte value)
{ {
if (addr >= 0x6000 && addr < 0x8000) if (addr >= 0x6000 && addr < 0x8000)
{ {
Ram[addr & 1023] = value; _ram[addr & 1023] = value;
return;
} }
//Console.WriteLine("Unhandled write at {0:X4}:{1:X2}", addr, value); ////Console.WriteLine("Unhandled write at {0:X4}:{1:X2}", addr, value);
} }
} }
} }