convert spaces to tabs in some ZXSpectrum files

This commit is contained in:
adelikat 2020-02-16 16:10:26 -06:00
parent ae87aabbb0
commit b03b6eb9de
10 changed files with 1439 additions and 1442 deletions

View File

@ -3,62 +3,62 @@ using BizHawk.Emulation.Common;
namespace BizHawk.Emulation.Cores.Computers.SinclairSpectrum
{
/// <summary>
/// ZXHawk: Core Class
/// * Controllers *
/// </summary>
public partial class ZXSpectrum
{
/// <summary>
/// The one ZX Hawk ControllerDefinition
/// </summary>
public ControllerDefinition ZXSpectrumControllerDefinition
{
get
{
ControllerDefinition definition = new ControllerDefinition();
definition.Name = "ZXSpectrum Controller";
/// <summary>
/// ZXHawk: Core Class
/// * Controllers *
/// </summary>
public partial class ZXSpectrum
{
/// <summary>
/// The one ZX Hawk ControllerDefinition
/// </summary>
public ControllerDefinition ZXSpectrumControllerDefinition
{
get
{
ControllerDefinition definition = new ControllerDefinition();
definition.Name = "ZXSpectrum Controller";
// joysticks
List<string> joys1 = new List<string>
{
// joysticks
List<string> joys1 = new List<string>
{
// P1 Joystick
"P1 Up", "P1 Down", "P1 Left", "P1 Right", "P1 Button",
};
};
foreach (var s in joys1)
{
definition.BoolButtons.Add(s);
definition.CategoryLabels[s] = "J1 (" + ((ZXSpectrumSyncSettings)SyncSettings as ZXSpectrumSyncSettings).JoystickType1.ToString() + ")";
}
foreach (var s in joys1)
{
definition.BoolButtons.Add(s);
definition.CategoryLabels[s] = "J1 (" + ((ZXSpectrumSyncSettings)SyncSettings as ZXSpectrumSyncSettings).JoystickType1.ToString() + ")";
}
List<string> joys2 = new List<string>
{
List<string> joys2 = new List<string>
{
// P2 Joystick
"P2 Up", "P2 Down", "P2 Left", "P2 Right", "P2 Button",
};
};
foreach (var s in joys2)
{
definition.BoolButtons.Add(s);
definition.CategoryLabels[s] = "J2 (" + ((ZXSpectrumSyncSettings)SyncSettings as ZXSpectrumSyncSettings).JoystickType2.ToString() + ")";
}
foreach (var s in joys2)
{
definition.BoolButtons.Add(s);
definition.CategoryLabels[s] = "J2 (" + ((ZXSpectrumSyncSettings)SyncSettings as ZXSpectrumSyncSettings).JoystickType2.ToString() + ")";
}
List<string> joys3 = new List<string>
{
List<string> joys3 = new List<string>
{
// P3 Joystick
"P3 Up", "P3 Down", "P3 Left", "P3 Right", "P3 Button",
};
};
foreach (var s in joys3)
{
definition.BoolButtons.Add(s);
definition.CategoryLabels[s] = "J3 (" + ((ZXSpectrumSyncSettings)SyncSettings as ZXSpectrumSyncSettings).JoystickType3.ToString() + ")";
}
foreach (var s in joys3)
{
definition.BoolButtons.Add(s);
definition.CategoryLabels[s] = "J3 (" + ((ZXSpectrumSyncSettings)SyncSettings as ZXSpectrumSyncSettings).JoystickType3.ToString() + ")";
}
// keyboard
List<string> keys = new List<string>
{
// keyboard
List<string> keys = new List<string>
{
// Controller mapping includes all keyboard keys from the following models:
// https://upload.wikimedia.org/wikipedia/commons/thumb/3/33/ZXSpectrum48k.jpg/1200px-ZXSpectrum48k.jpg
// https://upload.wikimedia.org/wikipedia/commons/c/ca/ZX_Spectrum%2B.jpg
@ -73,68 +73,68 @@ namespace BizHawk.Emulation.Cores.Computers.SinclairSpectrum
"Key Caps Shift", "Key Caps Lock", "Key Z", "Key X", "Key C", "Key V", "Key B", "Key N", "Key M", "Key Period",
// Keyboard - row 5
"Key Symbol Shift", "Key Semi-Colon", "Key Quote", "Key Left Cursor", "Key Right Cursor", "Key Space", "Key Up Cursor", "Key Down Cursor", "Key Comma",
};
};
foreach (var s in keys)
{
definition.BoolButtons.Add(s);
definition.CategoryLabels[s] = "Keyboard";
}
foreach (var s in keys)
{
definition.BoolButtons.Add(s);
definition.CategoryLabels[s] = "Keyboard";
}
// Power functions
List<string> power = new List<string>
{
// Power functions
List<string> power = new List<string>
{
// Power functions
"Reset", "Power"
};
};
foreach (var s in power)
{
definition.BoolButtons.Add(s);
definition.CategoryLabels[s] = "Power";
}
foreach (var s in power)
{
definition.BoolButtons.Add(s);
definition.CategoryLabels[s] = "Power";
}
// Datacorder (tape device)
List<string> tape = new List<string>
{
// Datacorder (tape device)
List<string> tape = new List<string>
{
// Tape functions
"Play Tape", "Stop Tape", "RTZ Tape", "Record Tape", "Insert Next Tape",
"Insert Previous Tape", "Next Tape Block", "Prev Tape Block", "Get Tape Status"
};
"Insert Previous Tape", "Next Tape Block", "Prev Tape Block", "Get Tape Status"
};
foreach (var s in tape)
{
definition.BoolButtons.Add(s);
definition.CategoryLabels[s] = "Datacorder";
}
foreach (var s in tape)
{
definition.BoolButtons.Add(s);
definition.CategoryLabels[s] = "Datacorder";
}
// Datacorder (tape device)
List<string> disk = new List<string>
{
// Datacorder (tape device)
List<string> disk = new List<string>
{
// Tape functions
"Insert Next Disk", "Insert Previous Disk", /*"Eject Current Disk",*/ "Get Disk Status"
};
};
foreach (var s in disk)
{
definition.BoolButtons.Add(s);
definition.CategoryLabels[s] = "+3 Disk Drive";
}
foreach (var s in disk)
{
definition.BoolButtons.Add(s);
definition.CategoryLabels[s] = "+3 Disk Drive";
}
return definition;
}
}
}
return definition;
}
}
}
/// <summary>
/// The possible joystick types
/// </summary>
public enum JoystickType
{
NULL,
Kempston,
SinclairLEFT,
SinclairRIGHT,
Cursor
}
/// <summary>
/// The possible joystick types
/// </summary>
public enum JoystickType
{
NULL,
Kempston,
SinclairLEFT,
SinclairRIGHT,
Cursor
}
}

View File

@ -6,175 +6,175 @@ using System.IO;
namespace BizHawk.Emulation.Cores.Computers.SinclairSpectrum
{
/// <summary>
/// ZXHawk: Core Class
/// * ICodeDataLog *
/// </summary>
public partial class ZXSpectrum : ICodeDataLogger
{
private ICodeDataLog _cdl;
/// <summary>
/// ZXHawk: Core Class
/// * ICodeDataLog *
/// </summary>
public partial class ZXSpectrum : ICodeDataLogger
{
private ICodeDataLog _cdl;
public void SetCDL(ICodeDataLog cdl)
{
_cdl = cdl;
if (cdl == null || !cdl.Active)
{
_cpu.ReadMemory = _machine.ReadMemory;
}
else
{
_cpu.ReadMemory = ReadMemory_CDL;
}
}
public void SetCDL(ICodeDataLog cdl)
{
_cdl = cdl;
if (cdl == null || !cdl.Active)
{
_cpu.ReadMemory = _machine.ReadMemory;
}
else
{
_cpu.ReadMemory = ReadMemory_CDL;
}
}
public void NewCDL(ICodeDataLog cdl)
{
cdl["System Bus"] = new byte[memoryDomains["System Bus"].Size];
public void NewCDL(ICodeDataLog cdl)
{
cdl["System Bus"] = new byte[memoryDomains["System Bus"].Size];
if (memoryDomains.Has("ROM - 128K Editor & Menu")) { cdl["ROM - 128K Editor & Menu"] = new byte[memoryDomains["ROM - 128K Editor & Menu"].Size]; }
if (memoryDomains.Has("ROM - 128K Syntax Checker")) { cdl["ROM - 128K Syntax Checker"] = new byte[memoryDomains["ROM - 128K Syntax Checker"].Size]; }
if (memoryDomains.Has("ROM - +3DOS")) { cdl["ROM - +3DOS"] = new byte[memoryDomains["ROM - +3DOS"].Size]; }
if (memoryDomains.Has("ROM - 48K BASIC")) { cdl["ROM - 48K BASIC"] = new byte[memoryDomains["ROM - 48K BASIC"].Size]; }
if (memoryDomains.Has("ROM - 128K Editor & Menu")) { cdl["ROM - 128K Editor & Menu"] = new byte[memoryDomains["ROM - 128K Editor & Menu"].Size]; }
if (memoryDomains.Has("ROM - 128K Syntax Checker")) { cdl["ROM - 128K Syntax Checker"] = new byte[memoryDomains["ROM - 128K Syntax Checker"].Size]; }
if (memoryDomains.Has("ROM - +3DOS")) { cdl["ROM - +3DOS"] = new byte[memoryDomains["ROM - +3DOS"].Size]; }
if (memoryDomains.Has("ROM - 48K BASIC")) { cdl["ROM - 48K BASIC"] = new byte[memoryDomains["ROM - 48K BASIC"].Size]; }
// different RAM bank ordering for < 128k models
if (_machineType == MachineType.ZXSpectrum16 || _machineType == MachineType.ZXSpectrum48)
{
if (memoryDomains.Has("RAM - BANK 0 (Screen)")) { cdl["RAM - BANK 0 (Screen)"] = new byte[memoryDomains["RAM - BANK 0 (Screen)"].Size]; }
if (memoryDomains.Has("RAM - BANK 1")) { cdl["RAM - BANK 1"] = new byte[memoryDomains["RAM - BANK 1"].Size]; }
if (memoryDomains.Has("RAM - BANK 2")) { cdl["RAM - BANK 2"] = new byte[memoryDomains["RAM - BANK 2"].Size]; }
}
else
{
if (memoryDomains.Has("RAM - BANK 5 (Screen)")) { cdl["RAM - BANK 5 (Screen)"] = new byte[memoryDomains["RAM - BANK 5 (Screen)"].Size]; }
if (memoryDomains.Has("RAM - BANK 2")) { cdl["RAM - BANK 2"] = new byte[memoryDomains["RAM - BANK 2"].Size]; }
if (memoryDomains.Has("RAM - BANK 0")) { cdl["RAM - BANK 0"] = new byte[memoryDomains["RAM - BANK 0"].Size]; }
if (memoryDomains.Has("RAM - BANK 1")) { cdl["RAM - BANK 1"] = new byte[memoryDomains["RAM - BANK 1"].Size]; }
if (memoryDomains.Has("RAM - BANK 3")) { cdl["RAM - BANK 3"] = new byte[memoryDomains["RAM - BANK 3"].Size]; }
if (memoryDomains.Has("RAM - BANK 4")) { cdl["RAM - BANK 4"] = new byte[memoryDomains["RAM - BANK 4"].Size]; }
if (memoryDomains.Has("RAM - BANK 6")) { cdl["RAM - BANK 6"] = new byte[memoryDomains["RAM - BANK 6"].Size]; }
if (memoryDomains.Has("RAM - BANK 7 (Shadow Screen)")) { cdl["RAM - BANK 7 (Shadow Screen)"] = new byte[memoryDomains["RAM - BANK 7 (Shadow Screen)"].Size]; }
}
// different RAM bank ordering for < 128k models
if (_machineType == MachineType.ZXSpectrum16 || _machineType == MachineType.ZXSpectrum48)
{
if (memoryDomains.Has("RAM - BANK 0 (Screen)")) { cdl["RAM - BANK 0 (Screen)"] = new byte[memoryDomains["RAM - BANK 0 (Screen)"].Size]; }
if (memoryDomains.Has("RAM - BANK 1")) { cdl["RAM - BANK 1"] = new byte[memoryDomains["RAM - BANK 1"].Size]; }
if (memoryDomains.Has("RAM - BANK 2")) { cdl["RAM - BANK 2"] = new byte[memoryDomains["RAM - BANK 2"].Size]; }
}
else
{
if (memoryDomains.Has("RAM - BANK 5 (Screen)")) { cdl["RAM - BANK 5 (Screen)"] = new byte[memoryDomains["RAM - BANK 5 (Screen)"].Size]; }
if (memoryDomains.Has("RAM - BANK 2")) { cdl["RAM - BANK 2"] = new byte[memoryDomains["RAM - BANK 2"].Size]; }
if (memoryDomains.Has("RAM - BANK 0")) { cdl["RAM - BANK 0"] = new byte[memoryDomains["RAM - BANK 0"].Size]; }
if (memoryDomains.Has("RAM - BANK 1")) { cdl["RAM - BANK 1"] = new byte[memoryDomains["RAM - BANK 1"].Size]; }
if (memoryDomains.Has("RAM - BANK 3")) { cdl["RAM - BANK 3"] = new byte[memoryDomains["RAM - BANK 3"].Size]; }
if (memoryDomains.Has("RAM - BANK 4")) { cdl["RAM - BANK 4"] = new byte[memoryDomains["RAM - BANK 4"].Size]; }
if (memoryDomains.Has("RAM - BANK 6")) { cdl["RAM - BANK 6"] = new byte[memoryDomains["RAM - BANK 6"].Size]; }
if (memoryDomains.Has("RAM - BANK 7 (Shadow Screen)")) { cdl["RAM - BANK 7 (Shadow Screen)"] = new byte[memoryDomains["RAM - BANK 7 (Shadow Screen)"].Size]; }
}
cdl.SubType = "ZXSpectrum";
cdl.SubVer = 0;
}
cdl.SubType = "ZXSpectrum";
cdl.SubVer = 0;
}
[FeatureNotImplemented]
public void DisassembleCDL(Stream s, ICodeDataLog cdl)
{
[FeatureNotImplemented]
public void DisassembleCDL(Stream s, ICodeDataLog cdl)
{
}
}
public enum CDLType
{
None,
ROM0, ROM1, ROM2, ROM3,
RAM0, RAM1, RAM2, RAM3,
RAM4, RAM5, RAM6, RAM7
}
public enum CDLType
{
None,
ROM0, ROM1, ROM2, ROM3,
RAM0, RAM1, RAM2, RAM3,
RAM4, RAM5, RAM6, RAM7
}
public struct CDLResult
{
public CDLType Type;
public int Address;
}
public struct CDLResult
{
public CDLType Type;
public int Address;
}
private byte ReadMemory_CDL(ushort addr)
{
var mapping = _machine.ReadCDL(addr);
var res = mapping.Type;
var address = mapping.Address;
private byte ReadMemory_CDL(ushort addr)
{
var mapping = _machine.ReadCDL(addr);
var res = mapping.Type;
var address = mapping.Address;
byte data = _machine.ReadMemory(addr);
byte data = _machine.ReadMemory(addr);
switch (res)
{
case CDLType.None:
default:
break;
switch (res)
{
case CDLType.None:
default:
break;
case CDLType.ROM0:
switch (_machineType)
{
case MachineType.ZXSpectrum16:
case MachineType.ZXSpectrum48:
_cdl["ROM - 48K BASIC"][address] = data;
break;
default:
_cdl["ROM - 128K Editor & Menu"][address] = data;
break;
}
break;
case CDLType.ROM0:
switch (_machineType)
{
case MachineType.ZXSpectrum16:
case MachineType.ZXSpectrum48:
_cdl["ROM - 48K BASIC"][address] = data;
break;
default:
_cdl["ROM - 128K Editor & Menu"][address] = data;
break;
}
break;
case CDLType.ROM1:
switch(_machineType)
{
case MachineType.ZXSpectrum128:
case MachineType.ZXSpectrum128Plus2:
_cdl["ROM - 48K BASIC"][address] = data;
break;
case MachineType.ZXSpectrum128Plus2a:
case MachineType.ZXSpectrum128Plus3:
_cdl["ROM - 128K Syntax Checker"][address] = data;
break;
}
break;
case CDLType.ROM1:
switch (_machineType)
{
case MachineType.ZXSpectrum128:
case MachineType.ZXSpectrum128Plus2:
_cdl["ROM - 48K BASIC"][address] = data;
break;
case MachineType.ZXSpectrum128Plus2a:
case MachineType.ZXSpectrum128Plus3:
_cdl["ROM - 128K Syntax Checker"][address] = data;
break;
}
break;
case CDLType.ROM2:
_cdl["ROM - +3DOS"][address] = data;
break;
case CDLType.ROM2:
_cdl["ROM - +3DOS"][address] = data;
break;
case CDLType.ROM3:
_cdl["ROM - 48K BASIC"][address] = data;
break;
case CDLType.ROM3:
_cdl["ROM - 48K BASIC"][address] = data;
break;
case CDLType.RAM0:
switch (_machineType)
{
case MachineType.ZXSpectrum16:
case MachineType.ZXSpectrum48:
_cdl["RAM - BANK 0 (Screen)"][address] = data;
break;
default:
_cdl["RAM - BANK 0"][address] = data;
break;
}
break;
case CDLType.RAM0:
switch (_machineType)
{
case MachineType.ZXSpectrum16:
case MachineType.ZXSpectrum48:
_cdl["RAM - BANK 0 (Screen)"][address] = data;
break;
default:
_cdl["RAM - BANK 0"][address] = data;
break;
}
break;
case CDLType.RAM1:
_cdl["RAM - BANK 1"][address] = data;
break;
case CDLType.RAM1:
_cdl["RAM - BANK 1"][address] = data;
break;
case CDLType.RAM2:
_cdl["RAM - BANK 2"][address] = data;
break;
case CDLType.RAM2:
_cdl["RAM - BANK 2"][address] = data;
break;
case CDLType.RAM3:
_cdl["RAM - BANK 3"][address] = data;
break;
case CDLType.RAM3:
_cdl["RAM - BANK 3"][address] = data;
break;
case CDLType.RAM4:
_cdl["RAM - BANK 4"][address] = data;
break;
case CDLType.RAM4:
_cdl["RAM - BANK 4"][address] = data;
break;
case CDLType.RAM5:
_cdl["RAM - BANK 5 (Screen)"][address] = data;
break;
case CDLType.RAM5:
_cdl["RAM - BANK 5 (Screen)"][address] = data;
break;
case CDLType.RAM6:
_cdl["RAM - BANK 6"][address] = data;
break;
case CDLType.RAM6:
_cdl["RAM - BANK 6"][address] = data;
break;
case CDLType.RAM7:
_cdl["RAM - BANK 7 (Shadow Screen)"][address] = data;
break;
}
case CDLType.RAM7:
_cdl["RAM - BANK 7 (Shadow Screen)"][address] = data;
break;
}
// update the system bus as well
// because why not
_cdl["System Bus"][addr] = data;
return data;
}
}
// update the system bus as well
// because why not
_cdl["System Bus"][addr] = data;
return data;
}
}
}

View File

@ -4,146 +4,146 @@ using BizHawk.Emulation.Common;
namespace BizHawk.Emulation.Cores.Computers.SinclairSpectrum
{
/// <summary>
/// ZXHawk: Core Class
/// * IDebugggable *
/// </summary>
public partial class ZXSpectrum : IDebuggable
{
public IDictionary<string, RegisterValue> GetCpuFlagsAndRegisters()
{
return new Dictionary<string, RegisterValue>
{
["A"] = _cpu.Regs[_cpu.A],
["AF"] = _cpu.Regs[_cpu.F] + (_cpu.Regs[_cpu.A] << 8),
["B"] = _cpu.Regs[_cpu.B],
["BC"] = _cpu.Regs[_cpu.C] + (_cpu.Regs[_cpu.B] << 8),
["C"] = _cpu.Regs[_cpu.C],
["D"] = _cpu.Regs[_cpu.D],
["DE"] = _cpu.Regs[_cpu.E] + (_cpu.Regs[_cpu.D] << 8),
["E"] = _cpu.Regs[_cpu.E],
["F"] = _cpu.Regs[_cpu.F],
["H"] = _cpu.Regs[_cpu.H],
["HL"] = _cpu.Regs[_cpu.L] + (_cpu.Regs[_cpu.H] << 8),
["I"] = _cpu.Regs[_cpu.I],
["IX"] = _cpu.Regs[_cpu.Ixl] + (_cpu.Regs[_cpu.Ixh] << 8),
["IY"] = _cpu.Regs[_cpu.Iyl] + (_cpu.Regs[_cpu.Iyh] << 8),
["L"] = _cpu.Regs[_cpu.L],
["PC"] = _cpu.Regs[_cpu.PCl] + (_cpu.Regs[_cpu.PCh] << 8),
["R"] = _cpu.Regs[_cpu.R],
["Shadow AF"] = _cpu.Regs[_cpu.F_s] + (_cpu.Regs[_cpu.A_s] << 8),
["Shadow BC"] = _cpu.Regs[_cpu.C_s] + (_cpu.Regs[_cpu.B_s] << 8),
["Shadow DE"] = _cpu.Regs[_cpu.E_s] + (_cpu.Regs[_cpu.D_s] << 8),
["Shadow HL"] = _cpu.Regs[_cpu.L_s] + (_cpu.Regs[_cpu.H_s] << 8),
["SP"] = _cpu.Regs[_cpu.Iyl] + (_cpu.Regs[_cpu.Iyh] << 8),
["Flag C"] = _cpu.FlagC,
["Flag N"] = _cpu.FlagN,
["Flag P/V"] = _cpu.FlagP,
["Flag 3rd"] = _cpu.Flag3,
["Flag H"] = _cpu.FlagH,
["Flag 5th"] = _cpu.Flag5,
["Flag Z"] = _cpu.FlagZ,
["Flag S"] = _cpu.FlagS
};
}
/// <summary>
/// ZXHawk: Core Class
/// * IDebugggable *
/// </summary>
public partial class ZXSpectrum : IDebuggable
{
public IDictionary<string, RegisterValue> GetCpuFlagsAndRegisters()
{
return new Dictionary<string, RegisterValue>
{
["A"] = _cpu.Regs[_cpu.A],
["AF"] = _cpu.Regs[_cpu.F] + (_cpu.Regs[_cpu.A] << 8),
["B"] = _cpu.Regs[_cpu.B],
["BC"] = _cpu.Regs[_cpu.C] + (_cpu.Regs[_cpu.B] << 8),
["C"] = _cpu.Regs[_cpu.C],
["D"] = _cpu.Regs[_cpu.D],
["DE"] = _cpu.Regs[_cpu.E] + (_cpu.Regs[_cpu.D] << 8),
["E"] = _cpu.Regs[_cpu.E],
["F"] = _cpu.Regs[_cpu.F],
["H"] = _cpu.Regs[_cpu.H],
["HL"] = _cpu.Regs[_cpu.L] + (_cpu.Regs[_cpu.H] << 8),
["I"] = _cpu.Regs[_cpu.I],
["IX"] = _cpu.Regs[_cpu.Ixl] + (_cpu.Regs[_cpu.Ixh] << 8),
["IY"] = _cpu.Regs[_cpu.Iyl] + (_cpu.Regs[_cpu.Iyh] << 8),
["L"] = _cpu.Regs[_cpu.L],
["PC"] = _cpu.Regs[_cpu.PCl] + (_cpu.Regs[_cpu.PCh] << 8),
["R"] = _cpu.Regs[_cpu.R],
["Shadow AF"] = _cpu.Regs[_cpu.F_s] + (_cpu.Regs[_cpu.A_s] << 8),
["Shadow BC"] = _cpu.Regs[_cpu.C_s] + (_cpu.Regs[_cpu.B_s] << 8),
["Shadow DE"] = _cpu.Regs[_cpu.E_s] + (_cpu.Regs[_cpu.D_s] << 8),
["Shadow HL"] = _cpu.Regs[_cpu.L_s] + (_cpu.Regs[_cpu.H_s] << 8),
["SP"] = _cpu.Regs[_cpu.Iyl] + (_cpu.Regs[_cpu.Iyh] << 8),
["Flag C"] = _cpu.FlagC,
["Flag N"] = _cpu.FlagN,
["Flag P/V"] = _cpu.FlagP,
["Flag 3rd"] = _cpu.Flag3,
["Flag H"] = _cpu.FlagH,
["Flag 5th"] = _cpu.Flag5,
["Flag Z"] = _cpu.FlagZ,
["Flag S"] = _cpu.FlagS
};
}
public void SetCpuRegister(string register, int value)
{
switch (register)
{
default:
throw new InvalidOperationException();
case "A":
_cpu.Regs[_cpu.A] = (ushort)value;
break;
case "AF":
_cpu.Regs[_cpu.F] = (ushort)(value & 0xFF);
_cpu.Regs[_cpu.A] = (ushort)(value & 0xFF00);
break;
case "B":
_cpu.Regs[_cpu.B] = (ushort)value;
break;
case "BC":
_cpu.Regs[_cpu.C] = (ushort)(value & 0xFF);
_cpu.Regs[_cpu.B] = (ushort)(value & 0xFF00);
break;
case "C":
_cpu.Regs[_cpu.C] = (ushort)value;
break;
case "D":
_cpu.Regs[_cpu.D] = (ushort)value;
break;
case "DE":
_cpu.Regs[_cpu.E] = (ushort)(value & 0xFF);
_cpu.Regs[_cpu.D] = (ushort)(value & 0xFF00);
break;
case "E":
_cpu.Regs[_cpu.E] = (ushort)value;
break;
case "F":
_cpu.Regs[_cpu.F] = (ushort)value;
break;
case "H":
_cpu.Regs[_cpu.H] = (ushort)value;
break;
case "HL":
_cpu.Regs[_cpu.L] = (ushort)(value & 0xFF);
_cpu.Regs[_cpu.H] = (ushort)(value & 0xFF00);
break;
case "I":
_cpu.Regs[_cpu.I] = (ushort)value;
break;
case "IX":
_cpu.Regs[_cpu.Ixl] = (ushort)(value & 0xFF);
_cpu.Regs[_cpu.Ixh] = (ushort)(value & 0xFF00);
break;
case "IY":
_cpu.Regs[_cpu.Iyl] = (ushort)(value & 0xFF);
_cpu.Regs[_cpu.Iyh] = (ushort)(value & 0xFF00);
break;
case "L":
_cpu.Regs[_cpu.L] = (ushort)value;
break;
case "PC":
_cpu.Regs[_cpu.PCl] = (ushort)(value & 0xFF);
_cpu.Regs[_cpu.PCh] = (ushort)(value & 0xFF00);
break;
case "R":
_cpu.Regs[_cpu.R] = (ushort)value;
break;
case "Shadow AF":
_cpu.Regs[_cpu.F_s] = (ushort)(value & 0xFF);
_cpu.Regs[_cpu.A_s] = (ushort)(value & 0xFF00);
break;
case "Shadow BC":
_cpu.Regs[_cpu.C_s] = (ushort)(value & 0xFF);
_cpu.Regs[_cpu.B_s] = (ushort)(value & 0xFF00);
break;
case "Shadow DE":
_cpu.Regs[_cpu.E_s] = (ushort)(value & 0xFF);
_cpu.Regs[_cpu.D_s] = (ushort)(value & 0xFF00);
break;
case "Shadow HL":
_cpu.Regs[_cpu.L_s] = (ushort)(value & 0xFF);
_cpu.Regs[_cpu.H_s] = (ushort)(value & 0xFF00);
break;
case "SP":
_cpu.Regs[_cpu.SPl] = (ushort)(value & 0xFF);
_cpu.Regs[_cpu.SPh] = (ushort)(value & 0xFF00);
break;
}
}
public void SetCpuRegister(string register, int value)
{
switch (register)
{
default:
throw new InvalidOperationException();
case "A":
_cpu.Regs[_cpu.A] = (ushort)value;
break;
case "AF":
_cpu.Regs[_cpu.F] = (ushort)(value & 0xFF);
_cpu.Regs[_cpu.A] = (ushort)(value & 0xFF00);
break;
case "B":
_cpu.Regs[_cpu.B] = (ushort)value;
break;
case "BC":
_cpu.Regs[_cpu.C] = (ushort)(value & 0xFF);
_cpu.Regs[_cpu.B] = (ushort)(value & 0xFF00);
break;
case "C":
_cpu.Regs[_cpu.C] = (ushort)value;
break;
case "D":
_cpu.Regs[_cpu.D] = (ushort)value;
break;
case "DE":
_cpu.Regs[_cpu.E] = (ushort)(value & 0xFF);
_cpu.Regs[_cpu.D] = (ushort)(value & 0xFF00);
break;
case "E":
_cpu.Regs[_cpu.E] = (ushort)value;
break;
case "F":
_cpu.Regs[_cpu.F] = (ushort)value;
break;
case "H":
_cpu.Regs[_cpu.H] = (ushort)value;
break;
case "HL":
_cpu.Regs[_cpu.L] = (ushort)(value & 0xFF);
_cpu.Regs[_cpu.H] = (ushort)(value & 0xFF00);
break;
case "I":
_cpu.Regs[_cpu.I] = (ushort)value;
break;
case "IX":
_cpu.Regs[_cpu.Ixl] = (ushort)(value & 0xFF);
_cpu.Regs[_cpu.Ixh] = (ushort)(value & 0xFF00);
break;
case "IY":
_cpu.Regs[_cpu.Iyl] = (ushort)(value & 0xFF);
_cpu.Regs[_cpu.Iyh] = (ushort)(value & 0xFF00);
break;
case "L":
_cpu.Regs[_cpu.L] = (ushort)value;
break;
case "PC":
_cpu.Regs[_cpu.PCl] = (ushort)(value & 0xFF);
_cpu.Regs[_cpu.PCh] = (ushort)(value & 0xFF00);
break;
case "R":
_cpu.Regs[_cpu.R] = (ushort)value;
break;
case "Shadow AF":
_cpu.Regs[_cpu.F_s] = (ushort)(value & 0xFF);
_cpu.Regs[_cpu.A_s] = (ushort)(value & 0xFF00);
break;
case "Shadow BC":
_cpu.Regs[_cpu.C_s] = (ushort)(value & 0xFF);
_cpu.Regs[_cpu.B_s] = (ushort)(value & 0xFF00);
break;
case "Shadow DE":
_cpu.Regs[_cpu.E_s] = (ushort)(value & 0xFF);
_cpu.Regs[_cpu.D_s] = (ushort)(value & 0xFF00);
break;
case "Shadow HL":
_cpu.Regs[_cpu.L_s] = (ushort)(value & 0xFF);
_cpu.Regs[_cpu.H_s] = (ushort)(value & 0xFF00);
break;
case "SP":
_cpu.Regs[_cpu.SPl] = (ushort)(value & 0xFF);
_cpu.Regs[_cpu.SPh] = (ushort)(value & 0xFF00);
break;
}
}
public IMemoryCallbackSystem MemoryCallbacks { get; }
public IMemoryCallbackSystem MemoryCallbacks { get; }
public bool CanStep(StepType type) => false;
public bool CanStep(StepType type) => false;
[FeatureNotImplemented]
public void Step(StepType type)
{
throw new NotImplementedException();
}
[FeatureNotImplemented]
public void Step(StepType type)
{
throw new NotImplementedException();
}
public long TotalExecutedCycles => _cpu.TotalExecutedCycles;
}
public long TotalExecutedCycles => _cpu.TotalExecutedCycles;
}
}

View File

@ -2,84 +2,84 @@
namespace BizHawk.Emulation.Cores.Computers.SinclairSpectrum
{
/// <summary>
/// ZXHawk: Core Class
/// * IEmulator *
/// </summary>
public partial class ZXSpectrum : IEmulator
{
public IEmulatorServiceProvider ServiceProvider { get; }
/// <summary>
/// ZXHawk: Core Class
/// * IEmulator *
/// </summary>
public partial class ZXSpectrum : IEmulator
{
public IEmulatorServiceProvider ServiceProvider { get; }
public ControllerDefinition ControllerDefinition { get; set; }
public ControllerDefinition ControllerDefinition { get; set; }
public bool FrameAdvance(IController controller, bool render, bool renderSound)
{
_controller = controller;
{
_controller = controller;
bool ren = render;
bool renSound = renderSound;
bool ren = render;
bool renSound = renderSound;
if (DeterministicEmulation)
{
ren = true;
renSound = true;
}
if (DeterministicEmulation)
{
ren = true;
renSound = true;
}
_isLag = true;
_isLag = true;
if (_tracer.Enabled)
{
_cpu.TraceCallback = s => _tracer.Put(s);
}
else
{
_cpu.TraceCallback = null;
}
if (_tracer.Enabled)
{
_cpu.TraceCallback = s => _tracer.Put(s);
}
else
{
_cpu.TraceCallback = null;
}
_machine.ExecuteFrame(ren, renSound);
_machine.ExecuteFrame(ren, renSound);
if (_isLag)
{
_lagCount++;
}
if (_isLag)
{
_lagCount++;
}
return true;
}
}
public int Frame
{
get
{
if (_machine == null)
return 0;
else
return _machine.FrameCount;
}
}
public int Frame
{
get
{
if (_machine == null)
return 0;
else
return _machine.FrameCount;
}
}
public string SystemId => "ZXSpectrum";
public string SystemId => "ZXSpectrum";
private bool deterministicEmulation;
public bool DeterministicEmulation
{
get { return deterministicEmulation; }
}
private bool deterministicEmulation;
public bool DeterministicEmulation
{
get { return deterministicEmulation; }
}
public void ResetCounters()
{
_machine.FrameCount = 0;
_lagCount = 0;
_isLag = false;
}
public void ResetCounters()
{
_machine.FrameCount = 0;
_lagCount = 0;
_isLag = false;
}
public CoreComm CoreComm { get; }
public CoreComm CoreComm { get; }
public void Dispose()
{
if (_machine != null)
{
_machine = null;
}
}
}
public void Dispose()
{
if (_machine != null)
{
_machine = null;
}
}
}
}

View File

@ -1,29 +1,28 @@
using System;
using BizHawk.Emulation.Common;
using BizHawk.Emulation.Common;
namespace BizHawk.Emulation.Cores.Computers.SinclairSpectrum
{
/// <summary>
/// ZXHawk: Core Class
/// * IInputPollable *
/// </summary>
public partial class ZXSpectrum : IInputPollable
{
public int LagCount
{
get => _lagCount;
set => _lagCount = value;
}
/// <summary>
/// ZXHawk: Core Class
/// * IInputPollable *
/// </summary>
public partial class ZXSpectrum : IInputPollable
{
public int LagCount
{
get => _lagCount;
set => _lagCount = value;
}
public bool IsLagFrame
{
get => _isLag;
set => _isLag = value;
}
public bool IsLagFrame
{
get => _isLag;
set => _isLag = value;
}
public IInputCallbackSystem InputCallbacks { get; }
public IInputCallbackSystem InputCallbacks { get; }
private int _lagCount = 0;
private bool _isLag = false;
}
private int _lagCount = 0;
private bool _isLag = false;
}
}

View File

@ -5,107 +5,107 @@ using BizHawk.Emulation.Common;
namespace BizHawk.Emulation.Cores.Computers.SinclairSpectrum
{
/// <summary>
/// ZXHawk: Core Class
/// * Memory Domains *
/// </summary>
public partial class ZXSpectrum
{
internal IMemoryDomains memoryDomains;
private readonly Dictionary<string, MemoryDomainByteArray> _byteArrayDomains = new Dictionary<string, MemoryDomainByteArray>();
private bool _memoryDomainsInit = false;
/// <summary>
/// ZXHawk: Core Class
/// * Memory Domains *
/// </summary>
public partial class ZXSpectrum
{
internal IMemoryDomains memoryDomains;
private readonly Dictionary<string, MemoryDomainByteArray> _byteArrayDomains = new Dictionary<string, MemoryDomainByteArray>();
private bool _memoryDomainsInit = false;
private void SetupMemoryDomains()
{
var domains = new List<MemoryDomain>
{
new MemoryDomainDelegate("System Bus", 0x10000, MemoryDomain.Endian.Little,
(addr) =>
{
if (addr < 0 || addr >= 65536)
{
throw new ArgumentOutOfRangeException();
}
return _machine.ReadBus((ushort)addr);
},
(addr, value) =>
{
if (addr < 0 || addr >= 65536)
{
throw new ArgumentOutOfRangeException();
}
private void SetupMemoryDomains()
{
var domains = new List<MemoryDomain>
{
new MemoryDomainDelegate("System Bus", 0x10000, MemoryDomain.Endian.Little,
(addr) =>
{
if (addr < 0 || addr >= 65536)
{
throw new ArgumentOutOfRangeException();
}
return _machine.ReadBus((ushort)addr);
},
(addr, value) =>
{
if (addr < 0 || addr >= 65536)
{
throw new ArgumentOutOfRangeException();
}
_machine.WriteBus((ushort)addr, value);
}, 1)
};
_machine.WriteBus((ushort)addr, value);
}, 1)
};
SyncAllByteArrayDomains();
SyncAllByteArrayDomains();
memoryDomains = new MemoryDomainList(_byteArrayDomains.Values.Concat(domains).ToList());
(ServiceProvider as BasicServiceProvider).Register<IMemoryDomains>(memoryDomains);
memoryDomains = new MemoryDomainList(_byteArrayDomains.Values.Concat(domains).ToList());
(ServiceProvider as BasicServiceProvider).Register<IMemoryDomains>(memoryDomains);
_memoryDomainsInit = true;
}
_memoryDomainsInit = true;
}
private void SyncAllByteArrayDomains()
{
switch (_machineType)
{
case MachineType.ZXSpectrum16:
SyncByteArrayDomain("ROM - 48K BASIC", _machine.ROM0);
SyncByteArrayDomain("RAM - BANK 0 (Screen)", _machine.RAM0);
break;
case MachineType.ZXSpectrum48:
SyncByteArrayDomain("ROM - 48K BASIC", _machine.ROM0);
SyncByteArrayDomain("RAM - BANK 0 (Screen)", _machine.RAM0);
SyncByteArrayDomain("RAM - BANK 1", _machine.RAM1);
SyncByteArrayDomain("RAM - BANK 2", _machine.RAM2);
break;
private void SyncAllByteArrayDomains()
{
switch (_machineType)
{
case MachineType.ZXSpectrum16:
SyncByteArrayDomain("ROM - 48K BASIC", _machine.ROM0);
SyncByteArrayDomain("RAM - BANK 0 (Screen)", _machine.RAM0);
break;
case MachineType.ZXSpectrum48:
SyncByteArrayDomain("ROM - 48K BASIC", _machine.ROM0);
SyncByteArrayDomain("RAM - BANK 0 (Screen)", _machine.RAM0);
SyncByteArrayDomain("RAM - BANK 1", _machine.RAM1);
SyncByteArrayDomain("RAM - BANK 2", _machine.RAM2);
break;
case MachineType.ZXSpectrum128:
case MachineType.ZXSpectrum128Plus2:
SyncByteArrayDomain("ROM - 128K Editor & Menu", _machine.ROM0);
SyncByteArrayDomain("ROM - 48K BASIC", _machine.ROM1);
SyncByteArrayDomain("RAM - BANK 5 (Screen)", _machine.RAM5);
SyncByteArrayDomain("RAM - BANK 2", _machine.RAM2);
SyncByteArrayDomain("RAM - BANK 0", _machine.RAM0);
SyncByteArrayDomain("RAM - BANK 1", _machine.RAM1);
SyncByteArrayDomain("RAM - BANK 3", _machine.RAM3);
SyncByteArrayDomain("RAM - BANK 4", _machine.RAM4);
SyncByteArrayDomain("RAM - BANK 6", _machine.RAM6);
SyncByteArrayDomain("RAM - BANK 7 (Shadow Screen)", _machine.RAM7);
break;
case MachineType.ZXSpectrum128:
case MachineType.ZXSpectrum128Plus2:
SyncByteArrayDomain("ROM - 128K Editor & Menu", _machine.ROM0);
SyncByteArrayDomain("ROM - 48K BASIC", _machine.ROM1);
SyncByteArrayDomain("RAM - BANK 5 (Screen)", _machine.RAM5);
SyncByteArrayDomain("RAM - BANK 2", _machine.RAM2);
SyncByteArrayDomain("RAM - BANK 0", _machine.RAM0);
SyncByteArrayDomain("RAM - BANK 1", _machine.RAM1);
SyncByteArrayDomain("RAM - BANK 3", _machine.RAM3);
SyncByteArrayDomain("RAM - BANK 4", _machine.RAM4);
SyncByteArrayDomain("RAM - BANK 6", _machine.RAM6);
SyncByteArrayDomain("RAM - BANK 7 (Shadow Screen)", _machine.RAM7);
break;
case MachineType.ZXSpectrum128Plus2a:
case MachineType.ZXSpectrum128Plus3:
SyncByteArrayDomain("ROM - 128K Editor & Menu", _machine.ROM0);
SyncByteArrayDomain("ROM - 128K Syntax Checker", _machine.ROM1);
SyncByteArrayDomain("ROM - +3DOS", _machine.ROM2);
SyncByteArrayDomain("ROM - 48K BASIC", _machine.ROM3);
SyncByteArrayDomain("RAM - BANK 5 (Screen)", _machine.RAM5);
SyncByteArrayDomain("RAM - BANK 2", _machine.RAM2);
SyncByteArrayDomain("RAM - BANK 0", _machine.RAM0);
SyncByteArrayDomain("RAM - BANK 1", _machine.RAM1);
SyncByteArrayDomain("RAM - BANK 3", _machine.RAM3);
SyncByteArrayDomain("RAM - BANK 4", _machine.RAM4);
SyncByteArrayDomain("RAM - BANK 6", _machine.RAM6);
SyncByteArrayDomain("RAM - BANK 7 (Shadow Screen)", _machine.RAM7);
break;
}
}
case MachineType.ZXSpectrum128Plus2a:
case MachineType.ZXSpectrum128Plus3:
SyncByteArrayDomain("ROM - 128K Editor & Menu", _machine.ROM0);
SyncByteArrayDomain("ROM - 128K Syntax Checker", _machine.ROM1);
SyncByteArrayDomain("ROM - +3DOS", _machine.ROM2);
SyncByteArrayDomain("ROM - 48K BASIC", _machine.ROM3);
SyncByteArrayDomain("RAM - BANK 5 (Screen)", _machine.RAM5);
SyncByteArrayDomain("RAM - BANK 2", _machine.RAM2);
SyncByteArrayDomain("RAM - BANK 0", _machine.RAM0);
SyncByteArrayDomain("RAM - BANK 1", _machine.RAM1);
SyncByteArrayDomain("RAM - BANK 3", _machine.RAM3);
SyncByteArrayDomain("RAM - BANK 4", _machine.RAM4);
SyncByteArrayDomain("RAM - BANK 6", _machine.RAM6);
SyncByteArrayDomain("RAM - BANK 7 (Shadow Screen)", _machine.RAM7);
break;
}
}
private void SyncByteArrayDomain(string name, byte[] data)
{
if (_memoryDomainsInit || _byteArrayDomains.ContainsKey(name))
{
var m = _byteArrayDomains[name];
m.Data = data;
}
else
{
var m = new MemoryDomainByteArray(name, MemoryDomain.Endian.Little, data, true, 1);
_byteArrayDomains.Add(name, m);
}
}
}
private void SyncByteArrayDomain(string name, byte[] data)
{
if (_memoryDomainsInit || _byteArrayDomains.ContainsKey(name))
{
var m = _byteArrayDomains[name];
m.Data = data;
}
else
{
var m = new MemoryDomainByteArray(name, MemoryDomain.Endian.Little, data, true, 1);
_byteArrayDomains.Add(name, m);
}
}
}
}

View File

@ -8,322 +8,322 @@ using BizHawk.Emulation.Cores.Sound;
namespace BizHawk.Emulation.Cores.Computers.SinclairSpectrum
{
/// <summary>
/// ZXHawk: Core Class
/// * ISettable *
/// </summary>
public partial class ZXSpectrum : ISettable<ZXSpectrum.ZXSpectrumSettings, ZXSpectrum.ZXSpectrumSyncSettings>
{
internal ZXSpectrumSettings Settings = new ZXSpectrumSettings();
internal ZXSpectrumSyncSettings SyncSettings = new ZXSpectrumSyncSettings();
/// <summary>
/// ZXHawk: Core Class
/// * ISettable *
/// </summary>
public partial class ZXSpectrum : ISettable<ZXSpectrum.ZXSpectrumSettings, ZXSpectrum.ZXSpectrumSyncSettings>
{
internal ZXSpectrumSettings Settings = new ZXSpectrumSettings();
internal ZXSpectrumSyncSettings SyncSettings = new ZXSpectrumSyncSettings();
public ZXSpectrumSettings GetSettings()
{
return Settings.Clone();
}
public ZXSpectrumSettings GetSettings()
{
return Settings.Clone();
}
public ZXSpectrumSyncSettings GetSyncSettings()
{
return SyncSettings.Clone();
}
public ZXSpectrumSyncSettings GetSyncSettings()
{
return SyncSettings.Clone();
}
public bool PutSettings(ZXSpectrumSettings o)
{
// restore user settings to devices
if (_machine != null && _machine.AYDevice != null)
{
((AY38912)_machine.AYDevice as AY38912).PanningConfiguration = o.AYPanConfig;
_machine.AYDevice.Volume = o.AYVolume;
}
if (_machine != null && _machine.BuzzerDevice != null)
{
((OneBitBeeper)_machine.BuzzerDevice as OneBitBeeper).Volume = o.EarVolume;
}
if (_machine != null && _machine.TapeBuzzer != null)
{
((OneBitBeeper)_machine.TapeBuzzer as OneBitBeeper).Volume = o.TapeVolume;
}
public bool PutSettings(ZXSpectrumSettings o)
{
// restore user settings to devices
if (_machine != null && _machine.AYDevice != null)
{
((AY38912)_machine.AYDevice as AY38912).PanningConfiguration = o.AYPanConfig;
_machine.AYDevice.Volume = o.AYVolume;
}
if (_machine != null && _machine.BuzzerDevice != null)
{
((OneBitBeeper)_machine.BuzzerDevice as OneBitBeeper).Volume = o.EarVolume;
}
if (_machine != null && _machine.TapeBuzzer != null)
{
((OneBitBeeper)_machine.TapeBuzzer as OneBitBeeper).Volume = o.TapeVolume;
}
Settings = o;
Settings = o;
return false;
}
return false;
}
public bool PutSyncSettings(ZXSpectrumSyncSettings o)
{
bool ret = ZXSpectrumSyncSettings.NeedsReboot(SyncSettings, o);
SyncSettings = o;
return ret;
}
public bool PutSyncSettings(ZXSpectrumSyncSettings o)
{
bool ret = ZXSpectrumSyncSettings.NeedsReboot(SyncSettings, o);
SyncSettings = o;
return ret;
}
public class ZXSpectrumSettings
{
[DisplayName("AY-3-8912 Panning Config")]
[Description("Set the PSG panning configuration.\nThe chip has 3 audio channels that can be outputed in different configurations")]
[DefaultValue(AY38912.AYPanConfig.ABC)]
public AY38912.AYPanConfig AYPanConfig { get; set; }
public class ZXSpectrumSettings
{
[DisplayName("AY-3-8912 Panning Config")]
[Description("Set the PSG panning configuration.\nThe chip has 3 audio channels that can be outputed in different configurations")]
[DefaultValue(AY38912.AYPanConfig.ABC)]
public AY38912.AYPanConfig AYPanConfig { get; set; }
[DisplayName("Core OSD Message Verbosity")]
[Description("Full: Display all GUI messages\nMedium: Display only emulator/device generated messages\nNone: Show no messages")]
[DefaultValue(OSDVerbosity.Medium)]
public OSDVerbosity OSDMessageVerbosity { get; set; }
[DisplayName("Core OSD Message Verbosity")]
[Description("Full: Display all GUI messages\nMedium: Display only emulator/device generated messages\nNone: Show no messages")]
[DefaultValue(OSDVerbosity.Medium)]
public OSDVerbosity OSDMessageVerbosity { get; set; }
[DisplayName("Tape Loading Volume")]
[Description("The buzzer volume when the tape is playing")]
[DefaultValue(50)]
public int TapeVolume { get; set; }
[DisplayName("Tape Loading Volume")]
[Description("The buzzer volume when the tape is playing")]
[DefaultValue(50)]
public int TapeVolume { get; set; }
[DisplayName("Ear (buzzer output) Volume")]
[Description("The buzzer volume when sound is being generated by the spectrum")]
[DefaultValue(90)]
public int EarVolume { get; set; }
[DisplayName("Ear (buzzer output) Volume")]
[Description("The buzzer volume when sound is being generated by the spectrum")]
[DefaultValue(90)]
public int EarVolume { get; set; }
[DisplayName("AY-3-8912 Volume")]
[Description("The AY chip volume")]
[DefaultValue(75)]
public int AYVolume { get; set; }
[DisplayName("AY-3-8912 Volume")]
[Description("The AY chip volume")]
[DefaultValue(75)]
public int AYVolume { get; set; }
[DisplayName("Default Background Color")]
[Description("The default BG color")]
[DefaultValue(0)]
public int BackgroundColor { get; set; }
[DisplayName("Default Background Color")]
[Description("The default BG color")]
[DefaultValue(0)]
public int BackgroundColor { get; set; }
[DisplayName("Use Core Border Color")]
[Description("The core renders the background color from the last detected generated border color")]
[DefaultValue(false)]
public bool UseCoreBorderForBackground { get; set; }
[DisplayName("Use Core Border Color")]
[Description("The core renders the background color from the last detected generated border color")]
[DefaultValue(false)]
public bool UseCoreBorderForBackground { get; set; }
public ZXSpectrumSettings Clone()
{
return (ZXSpectrumSettings)MemberwiseClone();
}
public ZXSpectrumSettings Clone()
{
return (ZXSpectrumSettings)MemberwiseClone();
}
public ZXSpectrumSettings()
{
BizHawk.Common.SettingsUtil.SetDefaultValues(this);
}
}
public ZXSpectrumSettings()
{
BizHawk.Common.SettingsUtil.SetDefaultValues(this);
}
}
public class ZXSpectrumSyncSettings
{
[DisplayName("Deterministic Emulation")]
[Description("If true, the core agrees to behave in a completely deterministic manner")]
[DefaultValue(true)]
public bool DeterministicEmulation { get; set; }
public class ZXSpectrumSyncSettings
{
[DisplayName("Deterministic Emulation")]
[Description("If true, the core agrees to behave in a completely deterministic manner")]
[DefaultValue(true)]
public bool DeterministicEmulation { get; set; }
[DisplayName("Spectrum model")]
[Description("The model of spectrum to be emulated")]
[DefaultValue(MachineType.ZXSpectrum48)]
public MachineType MachineType { get; set; }
[DisplayName("Spectrum model")]
[Description("The model of spectrum to be emulated")]
[DefaultValue(MachineType.ZXSpectrum48)]
public MachineType MachineType { get; set; }
[DisplayName("Border type")]
[Description("Select how to show the border area")]
[DefaultValue(BorderType.Full)]
public BorderType BorderType { get; set; }
[DisplayName("Border type")]
[Description("Select how to show the border area")]
[DefaultValue(BorderType.Full)]
public BorderType BorderType { get; set; }
[DisplayName("Tape Load Speed")]
[Description("Select how fast the spectrum loads the game from tape")]
[DefaultValue(TapeLoadSpeed.Accurate)]
public TapeLoadSpeed TapeLoadSpeed { get; set; }
[DisplayName("Tape Load Speed")]
[Description("Select how fast the spectrum loads the game from tape")]
[DefaultValue(TapeLoadSpeed.Accurate)]
public TapeLoadSpeed TapeLoadSpeed { get; set; }
[DisplayName("Joystick 1")]
[Description("The emulated joystick assigned to P1 (SHOULD BE UNIQUE TYPE!)")]
[DefaultValue(JoystickType.Kempston)]
public JoystickType JoystickType1 { get; set; }
[DisplayName("Joystick 1")]
[Description("The emulated joystick assigned to P1 (SHOULD BE UNIQUE TYPE!)")]
[DefaultValue(JoystickType.Kempston)]
public JoystickType JoystickType1 { get; set; }
[DisplayName("Joystick 2")]
[Description("The emulated joystick assigned to P2 (SHOULD BE UNIQUE TYPE!)")]
[DefaultValue(JoystickType.SinclairLEFT)]
public JoystickType JoystickType2 { get; set; }
[DisplayName("Joystick 2")]
[Description("The emulated joystick assigned to P2 (SHOULD BE UNIQUE TYPE!)")]
[DefaultValue(JoystickType.SinclairLEFT)]
public JoystickType JoystickType2 { get; set; }
[DisplayName("Joystick 3")]
[Description("The emulated joystick assigned to P3 (SHOULD BE UNIQUE TYPE!)")]
[DefaultValue(JoystickType.SinclairRIGHT)]
public JoystickType JoystickType3 { get; set; }
[DisplayName("Joystick 3")]
[Description("The emulated joystick assigned to P3 (SHOULD BE UNIQUE TYPE!)")]
[DefaultValue(JoystickType.SinclairRIGHT)]
public JoystickType JoystickType3 { get; set; }
[DisplayName("Auto-load/stop tape")]
[Description("Auto or manual tape operation. Auto will attempt to detect CPU tape traps and automatically Stop/Start the tape")]
[DefaultValue(true)]
public bool AutoLoadTape { get; set; }
[DisplayName("Auto-load/stop tape")]
[Description("Auto or manual tape operation. Auto will attempt to detect CPU tape traps and automatically Stop/Start the tape")]
[DefaultValue(true)]
public bool AutoLoadTape { get; set; }
public ZXSpectrumSyncSettings Clone()
{
return (ZXSpectrumSyncSettings)MemberwiseClone();
}
public ZXSpectrumSyncSettings Clone()
{
return (ZXSpectrumSyncSettings)MemberwiseClone();
}
public ZXSpectrumSyncSettings()
{
SettingsUtil.SetDefaultValues(this);
}
public ZXSpectrumSyncSettings()
{
SettingsUtil.SetDefaultValues(this);
}
public static bool NeedsReboot(ZXSpectrumSyncSettings x, ZXSpectrumSyncSettings y)
{
return !DeepEquality.DeepEquals(x, y);
}
}
public static bool NeedsReboot(ZXSpectrumSyncSettings x, ZXSpectrumSyncSettings y)
{
return !DeepEquality.DeepEquals(x, y);
}
}
/// <summary>
/// Verbosity of the ZXHawk generated OSD messages
/// </summary>
public enum OSDVerbosity
{
/// <summary>
/// Show all OSD messages
/// </summary>
Full,
/// <summary>
/// Only show machine/device generated messages
/// </summary>
Medium,
/// <summary>
/// No core-driven OSD messages
/// </summary>
None
}
/// <summary>
/// Verbosity of the ZXHawk generated OSD messages
/// </summary>
public enum OSDVerbosity
{
/// <summary>
/// Show all OSD messages
/// </summary>
Full,
/// <summary>
/// Only show machine/device generated messages
/// </summary>
Medium,
/// <summary>
/// No core-driven OSD messages
/// </summary>
None
}
/// <summary>
/// The size of the Spectrum border
/// </summary>
public enum BorderType
{
/// <summary>
/// How it was originally back in the day
/// </summary>
Full,
/// <summary>
/// The size of the Spectrum border
/// </summary>
public enum BorderType
{
/// <summary>
/// How it was originally back in the day
/// </summary>
Full,
/// <summary>
/// All borders 24px
/// </summary>
Medium,
/// <summary>
/// All borders 24px
/// </summary>
Medium,
/// <summary>
/// All borders 10px
/// </summary>
Small,
/// <summary>
/// All borders 10px
/// </summary>
Small,
/// <summary>
/// No border at all
/// </summary>
None,
/// <summary>
/// No border at all
/// </summary>
None,
/// <summary>
/// Top and bottom border removed so that the result is *almost* 16:9
/// </summary>
Widescreen,
}
/// <summary>
/// Top and bottom border removed so that the result is *almost* 16:9
/// </summary>
Widescreen,
}
/// <summary>
/// The speed at which the tape is loaded
/// NOT IN USE YET
/// </summary>
public enum TapeLoadSpeed
{
Accurate,
//Fast,
//Fastest
}
}
/// <summary>
/// The speed at which the tape is loaded
/// NOT IN USE YET
/// </summary>
public enum TapeLoadSpeed
{
Accurate,
//Fast,
//Fastest
}
}
/// <summary>
/// Provides information on each emulated machine
/// </summary>
public class ZXMachineMetaData
{
public MachineType MachineType { get; set; }
public string Name { get; set; }
public string Description { get; set; }
public string Released { get; set; }
public string CPU { get; set; }
public string Memory { get; set; }
public string Video { get; set; }
public string Audio { get; set; }
public string Media { get; set; }
public string OtherMisc { get; set; }
/// <summary>
/// Provides information on each emulated machine
/// </summary>
public class ZXMachineMetaData
{
public MachineType MachineType { get; set; }
public string Name { get; set; }
public string Description { get; set; }
public string Released { get; set; }
public string CPU { get; set; }
public string Memory { get; set; }
public string Video { get; set; }
public string Audio { get; set; }
public string Media { get; set; }
public string OtherMisc { get; set; }
Dictionary<string, string> Data = new Dictionary<string, string>();
Dictionary<string, string> Data = new Dictionary<string, string>();
/// <summary>
/// Detailed info to be displayed within the settings UIs
/// </summary>
public static ZXMachineMetaData GetMetaObject(MachineType type)
{
ZXMachineMetaData m = new ZXMachineMetaData();
m.MachineType = type;
public static ZXMachineMetaData GetMetaObject(MachineType type)
{
ZXMachineMetaData m = new ZXMachineMetaData();
m.MachineType = type;
switch (type)
{
case MachineType.ZXSpectrum16:
m.Name = "Sinclair ZX Spectrum 16K";
m.Description = "The original ZX Spectrum 16K RAM version. Aside from available RAM this machine is technically identical to the 48K machine that was released at the same time. ";
m.Description += "Due to the small amount of RAM, very few games were actually made to run on this model.";
m.Released = "1982";
m.CPU = "Zilog Z80A @ 3.5MHz";
m.Memory = "16KB ROM / 16KB RAM";
m.Video = "ULA @ 7MHz - PAL (50.08Hz Interrupt)";
m.Audio = "Beeper (HW 1ch. / 10oct.) - Internal Speaker";
m.Media = "Cassette Tape (via 3rd party external tape player)";
break;
case MachineType.ZXSpectrum48:
m.Name = "Sinclair ZX Spectrum 48K / 48K+";
m.Description = "The original ZX Spectrum 48K RAM version. 2 years later a 'plus' version was released that had a better keyboard. ";
m.Description += "Electronically both the 48K and + are identical, so ZXHawk treats them as the same emulated machine. ";
m.Description += "These machines dominated the UK 8-bit home computer market throughout the 1980's so most non-128k only games are compatible.";
m.Released = "1982 (48K) / 1984 (48K+)";
m.CPU = "Zilog Z80A @ 3.5MHz";
m.Memory = "16KB ROM / 48KB RAM";
m.Video = "ULA @ 7MHz - PAL (50.08Hz Interrupt)";
m.Audio = "Beeper (HW 1ch. / 10oct.) - Internal Speaker";
m.Media = "Cassette Tape (via 3rd party external tape player)";
break;
case MachineType.ZXSpectrum128:
m.Name = "Sinclair ZX Spectrum 128";
m.Description = "The first Spectrum 128K machine released in Spain in 1985 and later UK in 1986. ";
m.Description += "With an updated ROM and new memory paging system to work around the Z80's 16-bit address bus. ";
m.Description += "The 128 shipped with a copy of the 48k ROM (that is paged in when required) and a new startup menu with the option of dropping into a '48k mode'. ";
m.Description += "Even so, there were some compatibility issues with older Spectrum games that were written to utilise some of the previous model's intricacies. ";
m.Description += "Many games released after 1985 supported the new AY-3-8912 PSG chip making for far superior audio. The extra memory also enabled many games to be loaded in all at once (rather than loading each level from tape when needed).";
m.Released = "1985 / 1986";
m.CPU = "Zilog Z80A @ 3.5469 MHz";
m.Memory = "32KB ROM / 128KB RAM";
m.Video = "ULA @ 7.0938MHz - PAL (50.01Hz Interrupt)";
m.Audio = "Beeper (HW 1ch. / 10oct.) & General Instruments AY-3-8912 PSG (3ch) - RF Output";
m.Media = "Cassette Tape (via 3rd party external tape player)";
break;
case MachineType.ZXSpectrum128Plus2:
m.Name = "Sinclair ZX Spectrum +2";
m.Description = "The first Sinclair Spectrum 128K machine that was released after Amstrad purchased Sinclair in 1986. ";
m.Description += "Electronically it was almost identical to the 128, but with the addition of a built-in tape deck and 2 Sinclair Joystick ports.";
m.Released = "1986";
m.CPU = "Zilog Z80A @ 3.5469 MHz";
m.Memory = "32KB ROM / 128KB RAM";
m.Video = "ULA @ 7.0938MHz - PAL (50.01Hz Interrupt)";
m.Audio = "Beeper (HW 1ch. / 10oct.) & General Instruments AY-3-8912 PSG (3ch) - RF Output";
m.Media = "Cassette Tape (via built-in Datacorder)";
break;
case MachineType.ZXSpectrum128Plus2a:
m.Name = "Sinclair ZX Spectrum +2a";
m.Description = "The +2a looks almost identical to the +2 but is a variant of the +3 machine that was released the same year (except with the same built-in datacorder that the +2 had rather than a floppy drive). ";
m.Description += "Memory paging again changed significantly and this (along with memory contention timing changes) caused more compatibility issues with some older games. ";
m.Description += "Although functionally identical to the +3, it does not contain floppy disk controller.";
m.Released = "1987";
m.CPU = "Zilog Z80A @ 3.5469 MHz";
m.Memory = "64KB ROM / 128KB RAM";
m.Video = "ULA @ 7.0938MHz - PAL (50.01Hz Interrupt)";
m.Audio = "Beeper (HW 1ch. / 10oct.) & General Instruments AY-3-8912 PSG (3ch) - RF Output";
m.Media = "Cassette Tape (via built-in Datacorder)";
break;
case MachineType.ZXSpectrum128Plus3:
m.Name = "Sinclair ZX Spectrum +3";
m.Description = "Amstrad released the +3 the same year as the +2a, but it featured a built-in floppy drive rather than a datacorder. An external cassette player could still be connected though as in the older 48k models. ";
m.Description += "Memory paging again changed significantly and this (along with memory contention timing changes) caused more compatibility issues with some older games. ";
m.Released = "1987";
m.CPU = "Zilog Z80A @ 3.5469 MHz";
m.Memory = "64KB ROM / 128KB RAM";
m.Video = "ULA @ 7.0938MHz - PAL (50.01Hz Interrupt)";
m.Audio = "Beeper (HW 1ch. / 10oct.) & General Instruments AY-3-8912 PSG (3ch) - RF Output";
m.Media = "3\" Floppy Disk (via built-in Floppy Drive)";
break;
switch (type)
{
case MachineType.ZXSpectrum16:
m.Name = "Sinclair ZX Spectrum 16K";
m.Description = "The original ZX Spectrum 16K RAM version. Aside from available RAM this machine is technically identical to the 48K machine that was released at the same time. ";
m.Description += "Due to the small amount of RAM, very few games were actually made to run on this model.";
m.Released = "1982";
m.CPU = "Zilog Z80A @ 3.5MHz";
m.Memory = "16KB ROM / 16KB RAM";
m.Video = "ULA @ 7MHz - PAL (50.08Hz Interrupt)";
m.Audio = "Beeper (HW 1ch. / 10oct.) - Internal Speaker";
m.Media = "Cassette Tape (via 3rd party external tape player)";
break;
case MachineType.ZXSpectrum48:
m.Name = "Sinclair ZX Spectrum 48K / 48K+";
m.Description = "The original ZX Spectrum 48K RAM version. 2 years later a 'plus' version was released that had a better keyboard. ";
m.Description += "Electronically both the 48K and + are identical, so ZXHawk treats them as the same emulated machine. ";
m.Description += "These machines dominated the UK 8-bit home computer market throughout the 1980's so most non-128k only games are compatible.";
m.Released = "1982 (48K) / 1984 (48K+)";
m.CPU = "Zilog Z80A @ 3.5MHz";
m.Memory = "16KB ROM / 48KB RAM";
m.Video = "ULA @ 7MHz - PAL (50.08Hz Interrupt)";
m.Audio = "Beeper (HW 1ch. / 10oct.) - Internal Speaker";
m.Media = "Cassette Tape (via 3rd party external tape player)";
break;
case MachineType.ZXSpectrum128:
m.Name = "Sinclair ZX Spectrum 128";
m.Description = "The first Spectrum 128K machine released in Spain in 1985 and later UK in 1986. ";
m.Description += "With an updated ROM and new memory paging system to work around the Z80's 16-bit address bus. ";
m.Description += "The 128 shipped with a copy of the 48k ROM (that is paged in when required) and a new startup menu with the option of dropping into a '48k mode'. ";
m.Description += "Even so, there were some compatibility issues with older Spectrum games that were written to utilise some of the previous model's intricacies. ";
m.Description += "Many games released after 1985 supported the new AY-3-8912 PSG chip making for far superior audio. The extra memory also enabled many games to be loaded in all at once (rather than loading each level from tape when needed).";
m.Released = "1985 / 1986";
m.CPU = "Zilog Z80A @ 3.5469 MHz";
m.Memory = "32KB ROM / 128KB RAM";
m.Video = "ULA @ 7.0938MHz - PAL (50.01Hz Interrupt)";
m.Audio = "Beeper (HW 1ch. / 10oct.) & General Instruments AY-3-8912 PSG (3ch) - RF Output";
m.Media = "Cassette Tape (via 3rd party external tape player)";
break;
case MachineType.ZXSpectrum128Plus2:
m.Name = "Sinclair ZX Spectrum +2";
m.Description = "The first Sinclair Spectrum 128K machine that was released after Amstrad purchased Sinclair in 1986. ";
m.Description += "Electronically it was almost identical to the 128, but with the addition of a built-in tape deck and 2 Sinclair Joystick ports.";
m.Released = "1986";
m.CPU = "Zilog Z80A @ 3.5469 MHz";
m.Memory = "32KB ROM / 128KB RAM";
m.Video = "ULA @ 7.0938MHz - PAL (50.01Hz Interrupt)";
m.Audio = "Beeper (HW 1ch. / 10oct.) & General Instruments AY-3-8912 PSG (3ch) - RF Output";
m.Media = "Cassette Tape (via built-in Datacorder)";
break;
case MachineType.ZXSpectrum128Plus2a:
m.Name = "Sinclair ZX Spectrum +2a";
m.Description = "The +2a looks almost identical to the +2 but is a variant of the +3 machine that was released the same year (except with the same built-in datacorder that the +2 had rather than a floppy drive). ";
m.Description += "Memory paging again changed significantly and this (along with memory contention timing changes) caused more compatibility issues with some older games. ";
m.Description += "Although functionally identical to the +3, it does not contain floppy disk controller.";
m.Released = "1987";
m.CPU = "Zilog Z80A @ 3.5469 MHz";
m.Memory = "64KB ROM / 128KB RAM";
m.Video = "ULA @ 7.0938MHz - PAL (50.01Hz Interrupt)";
m.Audio = "Beeper (HW 1ch. / 10oct.) & General Instruments AY-3-8912 PSG (3ch) - RF Output";
m.Media = "Cassette Tape (via built-in Datacorder)";
break;
case MachineType.ZXSpectrum128Plus3:
m.Name = "Sinclair ZX Spectrum +3";
m.Description = "Amstrad released the +3 the same year as the +2a, but it featured a built-in floppy drive rather than a datacorder. An external cassette player could still be connected though as in the older 48k models. ";
m.Description += "Memory paging again changed significantly and this (along with memory contention timing changes) caused more compatibility issues with some older games. ";
m.Released = "1987";
m.CPU = "Zilog Z80A @ 3.5469 MHz";
m.Memory = "64KB ROM / 128KB RAM";
m.Video = "ULA @ 7.0938MHz - PAL (50.01Hz Interrupt)";
m.Audio = "Beeper (HW 1ch. / 10oct.) & General Instruments AY-3-8912 PSG (3ch) - RF Output";
m.Media = "3\" Floppy Disk (via built-in Floppy Drive)";
break;
case MachineType.Pentagon128:
m.Name = "(NOT WORKING YET) Pentagon 128 Clone";
m.Description = " ";
@ -337,89 +337,89 @@ namespace BizHawk.Emulation.Cores.Computers.SinclairSpectrum
break;
}
m.Data.Add(ZXSpectrum.GetMemberName((ZXMachineMetaData c) => c.Name), m.Name.Trim());
m.Data.Add(ZXSpectrum.GetMemberName((ZXMachineMetaData c) => c.Description), m.Description.Trim());
m.Data.Add(ZXSpectrum.GetMemberName((ZXMachineMetaData c) => c.Released), m.Released.Trim());
m.Data.Add(ZXSpectrum.GetMemberName((ZXMachineMetaData c) => c.CPU), m.CPU.Trim());
m.Data.Add(ZXSpectrum.GetMemberName((ZXMachineMetaData c) => c.Memory), m.Memory.Trim());
m.Data.Add(ZXSpectrum.GetMemberName((ZXMachineMetaData c) => c.Video), m.Video.Trim());
m.Data.Add(ZXSpectrum.GetMemberName((ZXMachineMetaData c) => c.Audio), m.Audio.Trim());
m.Data.Add(ZXSpectrum.GetMemberName((ZXMachineMetaData c) => c.Media), m.Media.Trim());
m.Data.Add(ZXSpectrum.GetMemberName((ZXMachineMetaData c) => c.Name), m.Name.Trim());
m.Data.Add(ZXSpectrum.GetMemberName((ZXMachineMetaData c) => c.Description), m.Description.Trim());
m.Data.Add(ZXSpectrum.GetMemberName((ZXMachineMetaData c) => c.Released), m.Released.Trim());
m.Data.Add(ZXSpectrum.GetMemberName((ZXMachineMetaData c) => c.CPU), m.CPU.Trim());
m.Data.Add(ZXSpectrum.GetMemberName((ZXMachineMetaData c) => c.Memory), m.Memory.Trim());
m.Data.Add(ZXSpectrum.GetMemberName((ZXMachineMetaData c) => c.Video), m.Video.Trim());
m.Data.Add(ZXSpectrum.GetMemberName((ZXMachineMetaData c) => c.Audio), m.Audio.Trim());
m.Data.Add(ZXSpectrum.GetMemberName((ZXMachineMetaData c) => c.Media), m.Media.Trim());
return m;
}
return m;
}
/// <summary>
/// Returns machine metadata as a formatted string (to be displayed in a textbox)
/// </summary>
public static string GetMetaString(MachineType type)
{
var m = GetMetaObject(type);
public static string GetMetaString(MachineType type)
{
var m = GetMetaObject(type);
StringBuilder sb = new StringBuilder();
StringBuilder sb = new StringBuilder();
// get longest title
int titleLen = 0;
foreach (var d in m.Data)
{
if (d.Key.Length > titleLen)
titleLen = d.Key.Length;
}
// get longest title
int titleLen = 0;
foreach (var d in m.Data)
{
if (d.Key.Length > titleLen)
titleLen = d.Key.Length;
}
var maxDataLineLen = 40;
var maxDataLineLen = 40;
// generate layout
foreach (var d in m.Data)
{
var tLen = d.Key.Length;
var makeup = (titleLen - tLen) / 4;
sb.Append(d.Key + ":\t");
for (int i = 0; i < makeup; i++)
{
if (tLen > 4)
sb.Append("\t");
else
{
makeup--;
sb.Append("\t");
}
}
// generate layout
foreach (var d in m.Data)
{
var tLen = d.Key.Length;
var makeup = (titleLen - tLen) / 4;
sb.Append(d.Key + ":\t");
for (int i = 0; i < makeup; i++)
{
if (tLen > 4)
sb.Append("\t");
else
{
makeup--;
sb.Append("\t");
}
}
// output the data splitting and tabbing as neccessary
var arr = d.Value.Split(' ');
//int cnt = 0;
// output the data splitting and tabbing as neccessary
var arr = d.Value.Split(' ');
//int cnt = 0;
List<string> builder = new List<string>();
string working = "";
foreach (var s in arr)
{
var len = s.Length;
if (working.Length + 1 + len > maxDataLineLen)
{
// new line needed
builder.Add(working.Trim(' '));
working = "";
}
working += s + " ";
}
List<string> builder = new List<string>();
string working = "";
foreach (var s in arr)
{
var len = s.Length;
if (working.Length + 1 + len > maxDataLineLen)
{
// new line needed
builder.Add(working.Trim(' '));
working = "";
}
working += s + " ";
}
builder.Add(working.Trim(' '));
builder.Add(working.Trim(' '));
// output the data
for (int i = 0; i < builder.Count; i++)
{
if (i != 0)
{
sb.Append("\t");
sb.Append("\t");
}
// output the data
for (int i = 0; i < builder.Count; i++)
{
if (i != 0)
{
sb.Append("\t");
sb.Append("\t");
}
sb.Append(builder[i]);
sb.Append("\r\n");
}
}
sb.Append(builder[i]);
sb.Append("\r\n");
}
}
return sb.ToString();
}
}
return sb.ToString();
}
}
}

View File

@ -4,486 +4,486 @@ using System.Text;
namespace BizHawk.Emulation.Cores.Computers.SinclairSpectrum
{
/// <summary>
/// ZXHawk: Core Class
/// * Handles all messaging (OSD) operations *
/// </summary>
public partial class ZXSpectrum
{
/// <summary>
/// Writes a message to the OSD
/// </summary>
public void SendMessage(string message, MessageCategory category)
{
if (!CheckMessageSettings(category))
return;
StringBuilder sb = new StringBuilder();
switch (category)
{
case MessageCategory.Tape:
sb.Append("DATACORDER: ");
sb.Append(message);
break;
case MessageCategory.Input:
sb.Append("INPUT DETECTED: ");
sb.Append(message);
break;
case MessageCategory.Disk:
sb.Append("DISK DRIVE: ");
sb.Append(message);
break;
case MessageCategory.Emulator:
case MessageCategory.Misc:
sb.Append("ZXHAWK: ");
sb.Append(message);
break;
}
CoreComm.Notify(sb.ToString());
}
#region Input Message Methods
/// <summary>
/// Called when certain input presses are detected
/// </summary>
public void OSD_FireInputMessage(string input)
{
StringBuilder sb = new StringBuilder();
sb.Append(input);
SendMessage(sb.ToString().TrimEnd('\n'), MessageCategory.Input);
}
#endregion
#region DiskDevice Message Methods
/// <summary>
/// Disk message that is fired on core init
/// </summary>
public void OSD_DiskInit()
{
StringBuilder sb = new StringBuilder();
if (_machine.diskImages != null && _machine.UPDDiskDevice != null)
{
sb.Append("Disk Media Imported (count: " + _machine.diskImages.Count() + ")");
SendMessage(sb.ToString().TrimEnd('\n'), MessageCategory.Emulator);
}
}
/// <summary>
/// Disk message that is fired when a new disk is inserted into the drive
/// </summary>
public void OSD_DiskInserted()
{
StringBuilder sb = new StringBuilder();
if (_machine.UPDDiskDevice == null)
{
sb.Append("No Drive Present");
SendMessage(sb.ToString().TrimEnd('\n'), MessageCategory.Disk);
return;
}
sb.Append("DISK INSERTED (" + _machine.DiskMediaIndex + ": " + _diskInfo[_machine.DiskMediaIndex].Name + ")");
SendMessage(sb.ToString().TrimEnd('\n'), MessageCategory.Disk);
}
/// <summary>
/// Tape message that prints the current status of the tape device
/// </summary>
public void OSD_ShowDiskStatus()
{
StringBuilder sb = new StringBuilder();
if (_machine.UPDDiskDevice == null)
{
sb.Append("No Drive Present");
SendMessage(sb.ToString().TrimEnd('\n'), MessageCategory.Disk);
return;
}
if (_diskInfo.Count == 0)
{
sb.Append("No Disk Loaded");
SendMessage(sb.ToString().TrimEnd('\n'), MessageCategory.Disk);
return;
}
if (_machine.UPDDiskDevice != null)
{
if (_machine.UPDDiskDevice.DiskPointer == null)
{
sb.Append("No Disk Loaded");
SendMessage(sb.ToString().TrimEnd('\n'), MessageCategory.Disk);
return;
}
sb.Append("Disk: " + _machine.DiskMediaIndex + ": " + _diskInfo[_machine.DiskMediaIndex].Name);
SendMessage(sb.ToString().TrimEnd('\n'), MessageCategory.Disk);
sb.Clear();
string protection = "None";
protection = Enum.GetName(typeof(ProtectionType), _machine.UPDDiskDevice.DiskPointer.Protection);
if (protection == "None")
protection += " (OR UNKNOWN)";
sb.Append("Detected Protection: " + protection);
SendMessage(sb.ToString().TrimEnd('\n'), MessageCategory.Disk);
sb.Clear();
sb.Append("Status: ");
if (_machine.UPDDiskDevice.DriveLight)
sb.Append("READING/WRITING DATA");
else
sb.Append("UNKNOWN");
SendMessage(sb.ToString().TrimEnd('\n'), MessageCategory.Disk);
sb.Clear();
}
}
#endregion
#region TapeDevice Message Methods
/// <summary>
/// Tape message that is fired on core init
/// </summary>
public void OSD_TapeInit()
{
if (_tapeInfo.Count == 0)
return;
StringBuilder sb = new StringBuilder();
sb.Append("Tape Media Imported (count: " + _tapeInfo.Count() + ")");
SendMessage(sb.ToString().TrimEnd('\n'), MessageCategory.Emulator);
}
/// <summary>
/// Tape message that is fired when tape is playing
/// </summary>
public void OSD_TapePlaying()
{
if (_tapeInfo.Count == 0)
return;
StringBuilder sb = new StringBuilder();
sb.Append("PLAYING (" + _machine.TapeMediaIndex + ": " + _tapeInfo[_machine.TapeMediaIndex].Name + ")");
SendMessage(sb.ToString().TrimEnd('\n'), MessageCategory.Tape);
}
/// <summary>
/// Tape message that is fired when tape is stopped
/// </summary>
public void OSD_TapeStopped()
{
if (_tapeInfo.Count == 0)
return;
StringBuilder sb = new StringBuilder();
sb.Append("STOPPED (" + _machine.TapeMediaIndex + ": " + _tapeInfo[_machine.TapeMediaIndex].Name + ")");
SendMessage(sb.ToString().TrimEnd('\n'), MessageCategory.Tape);
}
/// <summary>
/// Tape message that is fired when tape is rewound
/// </summary>
public void OSD_TapeRTZ()
{
if (_tapeInfo.Count == 0)
return;
StringBuilder sb = new StringBuilder();
sb.Append("REWOUND (" + _machine.TapeMediaIndex + ": " + _tapeInfo[_machine.TapeMediaIndex].Name + ")");
SendMessage(sb.ToString().TrimEnd('\n'), MessageCategory.Tape);
}
/// <summary>
/// Tape message that is fired when a new tape is inserted into the datacorder
/// </summary>
public void OSD_TapeInserted()
{
if (_tapeInfo.Count == 0)
return;
StringBuilder sb = new StringBuilder();
sb.Append("TAPE INSERTED (" + _machine.TapeMediaIndex + ": " + _tapeInfo[_machine.TapeMediaIndex].Name + ")");
SendMessage(sb.ToString().TrimEnd('\n'), MessageCategory.Tape);
}
/// <summary>
/// Tape message that is fired when a tape is stopped automatically
/// </summary>
public void OSD_TapeStoppedAuto()
{
StringBuilder sb = new StringBuilder();
if (_tapeInfo.Count == 0)
{
sb.Append("No Tape Loaded");
SendMessage(sb.ToString().TrimEnd('\n'), MessageCategory.Tape);
return;
}
sb.Append("STOPPED (Auto Tape Trap Detected)");
SendMessage(sb.ToString().TrimEnd('\n'), MessageCategory.Tape);
}
/// <summary>
/// Tape message that is fired when a tape is started automatically
/// </summary>
public void OSD_TapePlayingAuto()
{
StringBuilder sb = new StringBuilder();
if (_tapeInfo.Count == 0)
{
sb.Append("No Tape Loaded");
SendMessage(sb.ToString().TrimEnd('\n'), MessageCategory.Tape);
return;
}
sb.Append("PLAYING (Auto Tape Trap Detected)");
SendMessage(sb.ToString().TrimEnd('\n'), MessageCategory.Tape);
}
/// <summary>
/// Tape message that is fired when a new block starts playing
/// </summary>
public void OSD_TapePlayingBlockInfo(string blockinfo)
{
StringBuilder sb = new StringBuilder();
if (_tapeInfo.Count == 0)
{
sb.Append("No Tape Loaded");
SendMessage(sb.ToString().TrimEnd('\n'), MessageCategory.Tape);
return;
}
sb.Append("...Starting Block " + blockinfo);
SendMessage(sb.ToString().TrimEnd('\n'), MessageCategory.Tape);
}
/// <summary>
/// Tape message that is fired when a tape block is skipped (because it is empty)
/// </summary>
public void OSD_TapePlayingSkipBlockInfo(string blockinfo)
{
StringBuilder sb = new StringBuilder();
if (_tapeInfo.Count == 0)
{
sb.Append("No Tape Loaded");
SendMessage(sb.ToString().TrimEnd('\n'), MessageCategory.Tape);
return;
}
sb.Append("...Skipping Empty Block " + blockinfo);
/// <summary>
/// ZXHawk: Core Class
/// * Handles all messaging (OSD) operations *
/// </summary>
public partial class ZXSpectrum
{
/// <summary>
/// Writes a message to the OSD
/// </summary>
public void SendMessage(string message, MessageCategory category)
{
if (!CheckMessageSettings(category))
return;
StringBuilder sb = new StringBuilder();
switch (category)
{
case MessageCategory.Tape:
sb.Append("DATACORDER: ");
sb.Append(message);
break;
case MessageCategory.Input:
sb.Append("INPUT DETECTED: ");
sb.Append(message);
break;
case MessageCategory.Disk:
sb.Append("DISK DRIVE: ");
sb.Append(message);
break;
case MessageCategory.Emulator:
case MessageCategory.Misc:
sb.Append("ZXHAWK: ");
sb.Append(message);
break;
}
CoreComm.Notify(sb.ToString());
}
#region Input Message Methods
/// <summary>
/// Called when certain input presses are detected
/// </summary>
public void OSD_FireInputMessage(string input)
{
StringBuilder sb = new StringBuilder();
sb.Append(input);
SendMessage(sb.ToString().TrimEnd('\n'), MessageCategory.Input);
}
#endregion
#region DiskDevice Message Methods
/// <summary>
/// Disk message that is fired on core init
/// </summary>
public void OSD_DiskInit()
{
StringBuilder sb = new StringBuilder();
if (_machine.diskImages != null && _machine.UPDDiskDevice != null)
{
sb.Append("Disk Media Imported (count: " + _machine.diskImages.Count() + ")");
SendMessage(sb.ToString().TrimEnd('\n'), MessageCategory.Emulator);
}
}
/// <summary>
/// Disk message that is fired when a new disk is inserted into the drive
/// </summary>
public void OSD_DiskInserted()
{
StringBuilder sb = new StringBuilder();
if (_machine.UPDDiskDevice == null)
{
sb.Append("No Drive Present");
SendMessage(sb.ToString().TrimEnd('\n'), MessageCategory.Disk);
return;
}
sb.Append("DISK INSERTED (" + _machine.DiskMediaIndex + ": " + _diskInfo[_machine.DiskMediaIndex].Name + ")");
SendMessage(sb.ToString().TrimEnd('\n'), MessageCategory.Disk);
}
/// <summary>
/// Tape message that prints the current status of the tape device
/// </summary>
public void OSD_ShowDiskStatus()
{
StringBuilder sb = new StringBuilder();
if (_machine.UPDDiskDevice == null)
{
sb.Append("No Drive Present");
SendMessage(sb.ToString().TrimEnd('\n'), MessageCategory.Disk);
return;
}
if (_diskInfo.Count == 0)
{
sb.Append("No Disk Loaded");
SendMessage(sb.ToString().TrimEnd('\n'), MessageCategory.Disk);
return;
}
if (_machine.UPDDiskDevice != null)
{
if (_machine.UPDDiskDevice.DiskPointer == null)
{
sb.Append("No Disk Loaded");
SendMessage(sb.ToString().TrimEnd('\n'), MessageCategory.Disk);
return;
}
sb.Append("Disk: " + _machine.DiskMediaIndex + ": " + _diskInfo[_machine.DiskMediaIndex].Name);
SendMessage(sb.ToString().TrimEnd('\n'), MessageCategory.Disk);
sb.Clear();
string protection = "None";
protection = Enum.GetName(typeof(ProtectionType), _machine.UPDDiskDevice.DiskPointer.Protection);
if (protection == "None")
protection += " (OR UNKNOWN)";
sb.Append("Detected Protection: " + protection);
SendMessage(sb.ToString().TrimEnd('\n'), MessageCategory.Disk);
sb.Clear();
sb.Append("Status: ");
if (_machine.UPDDiskDevice.DriveLight)
sb.Append("READING/WRITING DATA");
else
sb.Append("UNKNOWN");
SendMessage(sb.ToString().TrimEnd('\n'), MessageCategory.Disk);
sb.Clear();
}
}
#endregion
#region TapeDevice Message Methods
/// <summary>
/// Tape message that is fired on core init
/// </summary>
public void OSD_TapeInit()
{
if (_tapeInfo.Count == 0)
return;
StringBuilder sb = new StringBuilder();
sb.Append("Tape Media Imported (count: " + _tapeInfo.Count() + ")");
SendMessage(sb.ToString().TrimEnd('\n'), MessageCategory.Emulator);
}
/// <summary>
/// Tape message that is fired when tape is playing
/// </summary>
public void OSD_TapePlaying()
{
if (_tapeInfo.Count == 0)
return;
StringBuilder sb = new StringBuilder();
sb.Append("PLAYING (" + _machine.TapeMediaIndex + ": " + _tapeInfo[_machine.TapeMediaIndex].Name + ")");
SendMessage(sb.ToString().TrimEnd('\n'), MessageCategory.Tape);
}
/// <summary>
/// Tape message that is fired when tape is stopped
/// </summary>
public void OSD_TapeStopped()
{
if (_tapeInfo.Count == 0)
return;
StringBuilder sb = new StringBuilder();
sb.Append("STOPPED (" + _machine.TapeMediaIndex + ": " + _tapeInfo[_machine.TapeMediaIndex].Name + ")");
SendMessage(sb.ToString().TrimEnd('\n'), MessageCategory.Tape);
}
/// <summary>
/// Tape message that is fired when tape is rewound
/// </summary>
public void OSD_TapeRTZ()
{
if (_tapeInfo.Count == 0)
return;
StringBuilder sb = new StringBuilder();
sb.Append("REWOUND (" + _machine.TapeMediaIndex + ": " + _tapeInfo[_machine.TapeMediaIndex].Name + ")");
SendMessage(sb.ToString().TrimEnd('\n'), MessageCategory.Tape);
}
/// <summary>
/// Tape message that is fired when a new tape is inserted into the datacorder
/// </summary>
public void OSD_TapeInserted()
{
if (_tapeInfo.Count == 0)
return;
StringBuilder sb = new StringBuilder();
sb.Append("TAPE INSERTED (" + _machine.TapeMediaIndex + ": " + _tapeInfo[_machine.TapeMediaIndex].Name + ")");
SendMessage(sb.ToString().TrimEnd('\n'), MessageCategory.Tape);
}
/// <summary>
/// Tape message that is fired when a tape is stopped automatically
/// </summary>
public void OSD_TapeStoppedAuto()
{
StringBuilder sb = new StringBuilder();
if (_tapeInfo.Count == 0)
{
sb.Append("No Tape Loaded");
SendMessage(sb.ToString().TrimEnd('\n'), MessageCategory.Tape);
return;
}
sb.Append("STOPPED (Auto Tape Trap Detected)");
SendMessage(sb.ToString().TrimEnd('\n'), MessageCategory.Tape);
}
/// <summary>
/// Tape message that is fired when a tape is started automatically
/// </summary>
public void OSD_TapePlayingAuto()
{
StringBuilder sb = new StringBuilder();
if (_tapeInfo.Count == 0)
{
sb.Append("No Tape Loaded");
SendMessage(sb.ToString().TrimEnd('\n'), MessageCategory.Tape);
return;
}
sb.Append("PLAYING (Auto Tape Trap Detected)");
SendMessage(sb.ToString().TrimEnd('\n'), MessageCategory.Tape);
}
/// <summary>
/// Tape message that is fired when a new block starts playing
/// </summary>
public void OSD_TapePlayingBlockInfo(string blockinfo)
{
StringBuilder sb = new StringBuilder();
if (_tapeInfo.Count == 0)
{
sb.Append("No Tape Loaded");
SendMessage(sb.ToString().TrimEnd('\n'), MessageCategory.Tape);
return;
}
sb.Append("...Starting Block " + blockinfo);
SendMessage(sb.ToString().TrimEnd('\n'), MessageCategory.Tape);
}
/// <summary>
/// Tape message that is fired when a tape block is skipped (because it is empty)
/// </summary>
public void OSD_TapePlayingSkipBlockInfo(string blockinfo)
{
StringBuilder sb = new StringBuilder();
if (_tapeInfo.Count == 0)
{
sb.Append("No Tape Loaded");
SendMessage(sb.ToString().TrimEnd('\n'), MessageCategory.Tape);
return;
}
sb.Append("...Skipping Empty Block " + blockinfo);
SendMessage(sb.ToString().TrimEnd('\n'), MessageCategory.Tape);
}
/// <summary>
/// Tape message that is fired when a tape is started automatically
/// </summary>
public void OSD_TapeEndDetected(string blockinfo)
{
StringBuilder sb = new StringBuilder();
if (_tapeInfo.Count == 0)
{
sb.Append("No Tape Loaded");
SendMessage(sb.ToString().TrimEnd('\n'), MessageCategory.Tape);
return;
}
sb.Append("...Skipping Empty Block " + blockinfo);
SendMessage(sb.ToString().TrimEnd('\n'), MessageCategory.Tape);
}
/// <summary>
/// Tape message that is fired when user has manually skipped to the next block
/// </summary>
public void OSD_TapeNextBlock(string blockinfo)
{
StringBuilder sb = new StringBuilder();
if (_tapeInfo.Count == 0)
{
sb.Append("No Tape Loaded");
SendMessage(sb.ToString().TrimEnd('\n'), MessageCategory.Tape);
return;
}
sb.Append("Manual Skip Next " + blockinfo);
SendMessage(sb.ToString().TrimEnd('\n'), MessageCategory.Tape);
}
/// <summary>
/// Tape message that is fired when user has manually skipped to the next block
/// </summary>
public void OSD_TapePrevBlock(string blockinfo)
{
StringBuilder sb = new StringBuilder();
if (_tapeInfo.Count == 0)
{
sb.Append("No Tape Loaded");
SendMessage(sb.ToString().TrimEnd('\n'), MessageCategory.Tape);
return;
}
sb.Append("Manual Skip Prev " + blockinfo);
SendMessage(sb.ToString().TrimEnd('\n'), MessageCategory.Tape);
}
/// <summary>
/// Tape message that prints the current status of the tape device
/// </summary>
public void OSD_ShowTapeStatus()
{
StringBuilder sb = new StringBuilder();
if (_tapeInfo.Count == 0)
{
sb.Append("No Tape Loaded");
SendMessage(sb.ToString().TrimEnd('\n'), MessageCategory.Tape);
return;
}
sb.Append("Status: ");
if (_machine.TapeDevice.TapeIsPlaying)
sb.Append("PLAYING");
else
sb.Append("STOPPED");
SendMessage(sb.ToString().TrimEnd('\n'), MessageCategory.Tape);
sb.Clear();
sb.Append("Tape: " + _machine.TapeMediaIndex + ": " + _tapeInfo[_machine.TapeMediaIndex].Name);
SendMessage(sb.ToString().TrimEnd('\n'), MessageCategory.Tape);
sb.Clear();
sb.Append("Block: ");
sb.Append("(" + (_machine.TapeDevice.CurrentDataBlockIndex + 1) +
" of " + _machine.TapeDevice.DataBlocks.Count() + ") " +
_machine.TapeDevice.DataBlocks[_machine.TapeDevice.CurrentDataBlockIndex].BlockDescription);
SendMessage(sb.ToString().TrimEnd('\n'), MessageCategory.Tape);
sb.Clear();
sb.Append("Block Pos: ");
int pos = _machine.TapeDevice.Position;
int end = _machine.TapeDevice.DataBlocks[_machine.TapeDevice.CurrentDataBlockIndex].DataPeriods.Count;
double p = 0;
if (end != 0)
p = ((double)pos / (double)end) * 100.0;
sb.Append(p.ToString("N0") + "%");
SendMessage(sb.ToString().TrimEnd('\n'), MessageCategory.Tape);
sb.Clear();
// get position within the tape itself
sb.Append("Tape Pos: ");
var ind = _machine.TapeDevice.CurrentDataBlockIndex;
int cnt = 0;
for (int i = 0; i < ind; i++)
{
cnt += _machine.TapeDevice.DataBlocks[i].DataPeriods.Count;
}
// now we are at our current block
int ourPos = cnt + pos;
cnt += end;
// count periods in the remaining blocks
for (int i = ind + 1; i < _machine.TapeDevice.DataBlocks.Count; i++)
{
cnt += _machine.TapeDevice.DataBlocks[i].DataPeriods.Count;
}
// work out overall position within the tape
p = 0;
p = ((double)ourPos / (double)cnt) * 100.0;
sb.Append(p.ToString("N0") + "%");
SendMessage(sb.ToString().TrimEnd('\n'), MessageCategory.Tape);
}
#endregion
/// <summary>
/// Checks whether message category is allowed to be sent
/// </summary>
public bool CheckMessageSettings(MessageCategory category)
{
switch (Settings.OSDMessageVerbosity)
{
case OSDVerbosity.Full:
return true;
case OSDVerbosity.None:
return false;
case OSDVerbosity.Medium:
switch (category)
{
case MessageCategory.Disk:
case MessageCategory.Emulator:
case MessageCategory.Tape:
case MessageCategory.Misc:
return true;
default:
return false;
}
default:
return true;
}
}
/// <summary>
/// Defines the different message categories
/// </summary>
public enum MessageCategory
{
/// <summary>
/// No defined category as such
/// </summary>
Misc,
/// <summary>
/// User generated input messages (at the moment only tape/disk controls)
/// </summary>
Input,
/// <summary>
/// Tape device generated messages
/// </summary>
Tape,
/// <summary>
/// Disk device generated messages
/// </summary>
Disk,
/// <summary>
/// Emulator generated messages
/// </summary>
Emulator
}
}
SendMessage(sb.ToString().TrimEnd('\n'), MessageCategory.Tape);
}
/// <summary>
/// Tape message that is fired when a tape is started automatically
/// </summary>
public void OSD_TapeEndDetected(string blockinfo)
{
StringBuilder sb = new StringBuilder();
if (_tapeInfo.Count == 0)
{
sb.Append("No Tape Loaded");
SendMessage(sb.ToString().TrimEnd('\n'), MessageCategory.Tape);
return;
}
sb.Append("...Skipping Empty Block " + blockinfo);
SendMessage(sb.ToString().TrimEnd('\n'), MessageCategory.Tape);
}
/// <summary>
/// Tape message that is fired when user has manually skipped to the next block
/// </summary>
public void OSD_TapeNextBlock(string blockinfo)
{
StringBuilder sb = new StringBuilder();
if (_tapeInfo.Count == 0)
{
sb.Append("No Tape Loaded");
SendMessage(sb.ToString().TrimEnd('\n'), MessageCategory.Tape);
return;
}
sb.Append("Manual Skip Next " + blockinfo);
SendMessage(sb.ToString().TrimEnd('\n'), MessageCategory.Tape);
}
/// <summary>
/// Tape message that is fired when user has manually skipped to the next block
/// </summary>
public void OSD_TapePrevBlock(string blockinfo)
{
StringBuilder sb = new StringBuilder();
if (_tapeInfo.Count == 0)
{
sb.Append("No Tape Loaded");
SendMessage(sb.ToString().TrimEnd('\n'), MessageCategory.Tape);
return;
}
sb.Append("Manual Skip Prev " + blockinfo);
SendMessage(sb.ToString().TrimEnd('\n'), MessageCategory.Tape);
}
/// <summary>
/// Tape message that prints the current status of the tape device
/// </summary>
public void OSD_ShowTapeStatus()
{
StringBuilder sb = new StringBuilder();
if (_tapeInfo.Count == 0)
{
sb.Append("No Tape Loaded");
SendMessage(sb.ToString().TrimEnd('\n'), MessageCategory.Tape);
return;
}
sb.Append("Status: ");
if (_machine.TapeDevice.TapeIsPlaying)
sb.Append("PLAYING");
else
sb.Append("STOPPED");
SendMessage(sb.ToString().TrimEnd('\n'), MessageCategory.Tape);
sb.Clear();
sb.Append("Tape: " + _machine.TapeMediaIndex + ": " + _tapeInfo[_machine.TapeMediaIndex].Name);
SendMessage(sb.ToString().TrimEnd('\n'), MessageCategory.Tape);
sb.Clear();
sb.Append("Block: ");
sb.Append("(" + (_machine.TapeDevice.CurrentDataBlockIndex + 1) +
" of " + _machine.TapeDevice.DataBlocks.Count() + ") " +
_machine.TapeDevice.DataBlocks[_machine.TapeDevice.CurrentDataBlockIndex].BlockDescription);
SendMessage(sb.ToString().TrimEnd('\n'), MessageCategory.Tape);
sb.Clear();
sb.Append("Block Pos: ");
int pos = _machine.TapeDevice.Position;
int end = _machine.TapeDevice.DataBlocks[_machine.TapeDevice.CurrentDataBlockIndex].DataPeriods.Count;
double p = 0;
if (end != 0)
p = ((double)pos / (double)end) * 100.0;
sb.Append(p.ToString("N0") + "%");
SendMessage(sb.ToString().TrimEnd('\n'), MessageCategory.Tape);
sb.Clear();
// get position within the tape itself
sb.Append("Tape Pos: ");
var ind = _machine.TapeDevice.CurrentDataBlockIndex;
int cnt = 0;
for (int i = 0; i < ind; i++)
{
cnt += _machine.TapeDevice.DataBlocks[i].DataPeriods.Count;
}
// now we are at our current block
int ourPos = cnt + pos;
cnt += end;
// count periods in the remaining blocks
for (int i = ind + 1; i < _machine.TapeDevice.DataBlocks.Count; i++)
{
cnt += _machine.TapeDevice.DataBlocks[i].DataPeriods.Count;
}
// work out overall position within the tape
p = 0;
p = ((double)ourPos / (double)cnt) * 100.0;
sb.Append(p.ToString("N0") + "%");
SendMessage(sb.ToString().TrimEnd('\n'), MessageCategory.Tape);
}
#endregion
/// <summary>
/// Checks whether message category is allowed to be sent
/// </summary>
public bool CheckMessageSettings(MessageCategory category)
{
switch (Settings.OSDMessageVerbosity)
{
case OSDVerbosity.Full:
return true;
case OSDVerbosity.None:
return false;
case OSDVerbosity.Medium:
switch (category)
{
case MessageCategory.Disk:
case MessageCategory.Emulator:
case MessageCategory.Tape:
case MessageCategory.Misc:
return true;
default:
return false;
}
default:
return true;
}
}
/// <summary>
/// Defines the different message categories
/// </summary>
public enum MessageCategory
{
/// <summary>
/// No defined category as such
/// </summary>
Misc,
/// <summary>
/// User generated input messages (at the moment only tape/disk controls)
/// </summary>
Input,
/// <summary>
/// Tape device generated messages
/// </summary>
Tape,
/// <summary>
/// Disk device generated messages
/// </summary>
Disk,
/// <summary>
/// Emulator generated messages
/// </summary>
Emulator
}
}
}

View File

@ -4,82 +4,82 @@ using System.Linq.Expressions;
namespace BizHawk.Emulation.Cores.Computers.SinclairSpectrum
{
/// <summary>
/// ZXHawk: Core Class
/// * Misc Utilities *
/// </summary>
public partial class ZXSpectrum
{
/// <summary>
/// Helper method that returns a single INT32 from a BitArray
/// </summary>
public static int GetIntFromBitArray(BitArray bitArray)
{
if (bitArray.Length > 32)
throw new ArgumentException("Argument length shall be at most 32 bits.");
/// <summary>
/// ZXHawk: Core Class
/// * Misc Utilities *
/// </summary>
public partial class ZXSpectrum
{
/// <summary>
/// Helper method that returns a single INT32 from a BitArray
/// </summary>
public static int GetIntFromBitArray(BitArray bitArray)
{
if (bitArray.Length > 32)
throw new ArgumentException("Argument length shall be at most 32 bits.");
int[] array = new int[1];
bitArray.CopyTo(array, 0);
return array[0];
}
int[] array = new int[1];
bitArray.CopyTo(array, 0);
return array[0];
}
/// <summary>
/// POKEs a memory bus address
/// </summary>
public void PokeMemory(ushort addr, byte value)
{
_machine.WriteBus(addr, value);
}
/// <summary>
/// POKEs a memory bus address
/// </summary>
public void PokeMemory(ushort addr, byte value)
{
_machine.WriteBus(addr, value);
}
/// <summary>
/// Called by MainForm so that the core label can display a more detailed tooltip about the emulated spectrum model
/// </summary>
public string GetMachineType()
{
string m = "";
switch (SyncSettings.MachineType)
{
case MachineType.ZXSpectrum16:
m = "(Sinclair) ZX Spectrum 16K";
break;
case MachineType.ZXSpectrum48:
m = "(Sinclair) ZX Spectrum 48K";
break;
case MachineType.ZXSpectrum128:
m = "(Sinclair) ZX Spectrum 128K";
break;
case MachineType.ZXSpectrum128Plus2:
m = "(Amstrad) ZX Spectrum 128K +2";
break;
case MachineType.ZXSpectrum128Plus2a:
m = "(Amstrad) ZX Spectrum 128K +2a";
break;
case MachineType.ZXSpectrum128Plus3:
m = "(Amstrad) ZX Spectrum 128K +3";
break;
public string GetMachineType()
{
string m = "";
switch (SyncSettings.MachineType)
{
case MachineType.ZXSpectrum16:
m = "(Sinclair) ZX Spectrum 16K";
break;
case MachineType.ZXSpectrum48:
m = "(Sinclair) ZX Spectrum 48K";
break;
case MachineType.ZXSpectrum128:
m = "(Sinclair) ZX Spectrum 128K";
break;
case MachineType.ZXSpectrum128Plus2:
m = "(Amstrad) ZX Spectrum 128K +2";
break;
case MachineType.ZXSpectrum128Plus2a:
m = "(Amstrad) ZX Spectrum 128K +2a";
break;
case MachineType.ZXSpectrum128Plus3:
m = "(Amstrad) ZX Spectrum 128K +3";
break;
case MachineType.Pentagon128:
m = "(Clone) Pentagon 128K";
break;
}
}
return m;
}
return m;
}
/// <summary>
/// Called by MainForm - dumps a close approximation of the Spectaculator SZX snapshot format
/// DEV use only - this is nowhere near accurate
/// </summary>
public byte[] GetSZXSnapshot()
{
return SZX.ExportSZX(_machine);
}
public byte[] GetSZXSnapshot()
{
return SZX.ExportSZX(_machine);
}
/// <summary>
/// Utility method to get MemberName from an object
/// </summary>
public static string GetMemberName<T, TValue>(Expression<Func<T, TValue>> memberAccess)
{
return ((MemberExpression)memberAccess.Body).Member.Name;
}
}
public static string GetMemberName<T, TValue>(Expression<Func<T, TValue>> memberAccess)
{
return ((MemberExpression)memberAccess.Body).Member.Name;
}
}
}

View File

@ -1,6 +1,4 @@
using System;
using BizHawk.Common.BufferExtensions;
using BizHawk.Emulation.Common;
using BizHawk.Emulation.Common;
namespace BizHawk.Emulation.Cores.Consoles.ChannelF
{