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;
|
|
|
|
|
|
2017-12-04 15:40:27 +00:00
|
|
|
|
switch (SyncSettings.MachineType)
|
2017-11-29 21:32:34 +00:00
|
|
|
|
{
|
|
|
|
|
case MachineType.ZXSpectrum48:
|
2017-11-30 12:08:36 +00:00
|
|
|
|
ControllerDefinition = ZXSpectrumControllerDefinition;
|
2017-12-04 15:40:27 +00:00
|
|
|
|
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-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);
|
|
|
|
|
ser.Register<ISoundProvider>(_machine.BuzzerDevice);
|
|
|
|
|
|
|
|
|
|
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;
|
|
|
|
|
|
|
|
|
|
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.ZXSpectrum48:
|
|
|
|
|
_machine = new ZX48(this, _cpu, file);
|
|
|
|
|
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, file);
|
|
|
|
|
var _systemRom128 = GetFirmware(0x8000, "128ROM");
|
|
|
|
|
var romData128 = RomData.InitROM(machineType, _systemRom128);
|
|
|
|
|
_machine.InitROM(romData128);
|
|
|
|
|
break;
|
2017-11-29 21:32:34 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#region IRegionable
|
|
|
|
|
|
|
|
|
|
public DisplayType Region => DisplayType.PAL;
|
|
|
|
|
|
|
|
|
|
#endregion
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
}
|