BizHawk/BizHawk.Emulation.Cores/Computers/SinclairSpectrum/ZXSpectrum.cs

182 lines
7.1 KiB
C#
Raw Normal View History

2017-11-29 21:32:34 +00:00
using BizHawk.Emulation.Common;
using BizHawk.Emulation.Cores.Components;
using BizHawk.Emulation.Cores.Components.Z80A;
using System;
using System.Collections.Generic;
2017-11-30 09:41:30 +00:00
using System.IO;
2017-11-29 21:32:34 +00:00
using System.Linq;
namespace BizHawk.Emulation.Cores.Computers.SinclairSpectrum
{
[Core(
"ZXHawk",
"Asnivor",
isPorted: false,
isReleased: false)]
[ServiceNotApplicable(typeof(IDriveLight))]
public partial class ZXSpectrum : IDebuggable, IInputPollable, IStatable, IRegionable
{
[CoreConstructor("ZXSpectrum")]
public ZXSpectrum(CoreComm comm, byte[] file, object settings, object syncSettings)
{
PutSyncSettings((ZXSpectrumSyncSettings)syncSettings ?? new ZXSpectrumSyncSettings());
PutSettings((ZXSpectrumSettings)settings ?? new ZXSpectrumSettings());
var ser = new BasicServiceProvider(this);
ServiceProvider = ser;
InputCallbacks = new InputCallbackSystem();
CoreComm = comm;
_cpu = new Z80A();
2017-11-30 09:41:30 +00:00
_tracer = new TraceBuffer { Header = _cpu.TraceHeader };
_file = file;
switch (SyncSettings.MachineType)
2017-11-29 21:32:34 +00:00
{
case MachineType.ZXSpectrum16:
ControllerDefinition = ZXSpectrumControllerDefinition;
Init(MachineType.ZXSpectrum16, SyncSettings.BorderType, SyncSettings.TapeLoadSpeed, _file);
break;
2017-11-29 21:32:34 +00:00
case MachineType.ZXSpectrum48:
ControllerDefinition = ZXSpectrumControllerDefinition;
Init(MachineType.ZXSpectrum48, SyncSettings.BorderType, SyncSettings.TapeLoadSpeed, _file);
2017-11-29 21:32:34 +00:00
break;
2017-12-05 10:02:57 +00:00
case MachineType.ZXSpectrum128:
ControllerDefinition = ZXSpectrumControllerDefinition;
Init(MachineType.ZXSpectrum128, SyncSettings.BorderType, SyncSettings.TapeLoadSpeed, _file);
break;
2017-12-05 10:26:06 +00:00
case MachineType.ZXSpectrum128Plus2:
ControllerDefinition = ZXSpectrumControllerDefinition;
Init(MachineType.ZXSpectrum128Plus2, SyncSettings.BorderType, SyncSettings.TapeLoadSpeed, _file);
break;
2017-12-07 15:43:28 +00:00
case MachineType.ZXSpectrum128Plus3:
ControllerDefinition = ZXSpectrumControllerDefinition;
Init(MachineType.ZXSpectrum128Plus3, SyncSettings.BorderType, SyncSettings.TapeLoadSpeed, _file);
break;
2017-11-29 21:32:34 +00:00
default:
throw new InvalidOperationException("Machine not yet emulated");
}
_cpu.MemoryCallbacks = MemoryCallbacks;
HardReset = _machine.HardReset;
SoftReset = _machine.SoftReset;
_cpu.FetchMemory = _machine.ReadMemory;
_cpu.ReadMemory = _machine.ReadMemory;
_cpu.WriteMemory = _machine.WriteMemory;
_cpu.ReadHardware = _machine.ReadPort;
_cpu.WriteHardware = _machine.WritePort;
2017-12-01 11:36:57 +00:00
_cpu.FetchDB = _machine.PushBus;
2017-11-29 21:32:34 +00:00
ser.Register<ITraceable>(_tracer);
ser.Register<IDisassemblable>(_cpu);
ser.Register<IVideoProvider>(_machine);
SoundMixer = new SoundProviderMixer(_machine.BuzzerDevice);
if (_machine.AYDevice != null)
SoundMixer.AddSource(_machine.AYDevice);
2017-12-07 10:49:43 +00:00
//SoundMixer.DisableSource(_machine.BuzzerDevice);
dcf = new DCFilter(SoundMixer, 1024);
ser.Register<ISoundProvider>(dcf);
//ser.Register<ISoundProvider>(_machine.AYDevice);
2017-11-29 21:32:34 +00:00
HardReset();
SetupMemoryDomains();
}
2017-11-30 09:41:30 +00:00
2017-11-29 21:32:34 +00:00
public Action HardReset;
public Action SoftReset;
private readonly Z80A _cpu;
private readonly TraceBuffer _tracer;
public IController _controller;
private SpectrumBase _machine;
2017-12-07 10:49:43 +00:00
private DCFilter dcf;
2017-11-29 21:32:34 +00:00
private byte[] _file;
2017-11-30 09:41:30 +00:00
public bool DiagRom = false;
2017-11-29 21:32:34 +00:00
private byte[] GetFirmware(int length, params string[] names)
{
2017-11-30 09:41:30 +00:00
if (DiagRom & File.Exists(Directory.GetCurrentDirectory() + @"\DiagROM.v28"))
{
var rom = File.ReadAllBytes(Directory.GetCurrentDirectory() + @"\DiagROM.v28");
return rom;
}
2017-11-29 21:32:34 +00:00
var result = names.Select(n => CoreComm.CoreFileProvider.GetFirmware("ZXSpectrum", n, false)).FirstOrDefault(b => b != null && b.Length == length);
if (result == null)
{
throw new MissingFirmwareException($"At least one of these firmwares is required: {string.Join(", ", names)}");
}
return result;
}
private void Init(MachineType machineType, BorderType borderType, TapeLoadSpeed tapeLoadSpeed, byte[] file)
{
// setup the emulated model based on the MachineType
switch (machineType)
{
case MachineType.ZXSpectrum16:
_machine = new ZX16(this, _cpu, borderType, file);
var _systemRom16 = GetFirmware(0x4000, "48ROM");
var romData16 = RomData.InitROM(machineType, _systemRom16);
_machine.InitROM(romData16);
break;
2017-11-29 21:32:34 +00:00
case MachineType.ZXSpectrum48:
_machine = new ZX48(this, _cpu, borderType, file);
2017-11-29 21:32:34 +00:00
var _systemRom = GetFirmware(0x4000, "48ROM");
var romData = RomData.InitROM(machineType, _systemRom);
_machine.InitROM(romData);
break;
2017-12-05 10:02:57 +00:00
case MachineType.ZXSpectrum128:
_machine = new ZX128(this, _cpu, borderType, file);
2017-12-05 10:02:57 +00:00
var _systemRom128 = GetFirmware(0x8000, "128ROM");
var romData128 = RomData.InitROM(machineType, _systemRom128);
_machine.InitROM(romData128);
break;
2017-12-05 10:26:06 +00:00
case MachineType.ZXSpectrum128Plus2:
_machine = new ZX128Plus2(this, _cpu, borderType, file);
2017-12-05 10:26:06 +00:00
var _systemRomP2 = GetFirmware(0x8000, "PLUS2ROM");
var romDataP2 = RomData.InitROM(machineType, _systemRomP2);
_machine.InitROM(romDataP2);
break;
2017-12-07 15:43:28 +00:00
case MachineType.ZXSpectrum128Plus3:
_machine = new ZX128Plus3(this, _cpu, borderType, file);
2017-12-07 15:43:28 +00:00
var _systemRomP3 = GetFirmware(0x10000, "PLUS3ROM");
var romDataP3 = RomData.InitROM(machineType, _systemRomP3);
_machine.InitROM(romDataP3);
System.Windows.Forms.MessageBox.Show("+3 is not working at all yet :/");
2017-12-07 15:43:28 +00:00
break;
2017-11-29 21:32:34 +00:00
}
}
#region IRegionable
public DisplayType Region => DisplayType.PAL;
#endregion
}
}