commit
a992e988b2
|
@ -509,6 +509,12 @@
|
|||
<Compile Include="config\ZXSpectrum\ZXSpectrumAudioSettings.Designer.cs">
|
||||
<DependentUpon>ZXSpectrumAudioSettings.cs</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="config\ZXSpectrum\ZXSpectrumPokeMemory.cs">
|
||||
<SubType>Form</SubType>
|
||||
</Compile>
|
||||
<Compile Include="config\ZXSpectrum\ZXSpectrumPokeMemory.Designer.cs">
|
||||
<DependentUpon>ZXSpectrumPokeMemory.cs</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="config\ZXSpectrum\ZXSpectrumNonSyncSettings.cs">
|
||||
<SubType>Form</SubType>
|
||||
</Compile>
|
||||
|
@ -1431,6 +1437,9 @@
|
|||
<EmbeddedResource Include="config\ZXSpectrum\ZXSpectrumAudioSettings.resx">
|
||||
<DependentUpon>ZXSpectrumAudioSettings.cs</DependentUpon>
|
||||
</EmbeddedResource>
|
||||
<EmbeddedResource Include="config\ZXSpectrum\ZXSpectrumPokeMemory.resx">
|
||||
<DependentUpon>ZXSpectrumPokeMemory.cs</DependentUpon>
|
||||
</EmbeddedResource>
|
||||
<EmbeddedResource Include="config\ZXSpectrum\ZXSpectrumNonSyncSettings.resx">
|
||||
<DependentUpon>ZXSpectrumNonSyncSettings.cs</DependentUpon>
|
||||
</EmbeddedResource>
|
||||
|
|
|
@ -384,7 +384,12 @@
|
|||
this.zXSpectrumToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.ZXSpectrumCoreEmulationSettingsMenuItem = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.ZXSpectrumControllerConfigurationMenuItem = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.ZXSpectrumAudioSettingsMenuItem = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.ZXSpectrumNonSyncSettingsMenuItem = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.ZXSpectrumPokeMemoryMenuItem = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.ZXSpectrumMediaMenuItem = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.ZXSpectrumTapesSubMenu = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.ZXSpectrumDisksSubMenu = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.Atari7800HawkCoreMenuItem = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.MainStatusBar = new StatusStripEx();
|
||||
this.DumpStatusButton = new System.Windows.Forms.ToolStripDropDownButton();
|
||||
|
@ -457,7 +462,8 @@
|
|||
this.ShowMenuContextMenuSeparator = new System.Windows.Forms.ToolStripSeparator();
|
||||
this.ShowMenuContextMenuItem = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.timerMouseIdle = new System.Windows.Forms.Timer(this.components);
|
||||
this.ZXSpectrumAudioSettingsMenuItem = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.zxt1ToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.zxt2ToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.MainformMenu.SuspendLayout();
|
||||
this.MainStatusBar.SuspendLayout();
|
||||
this.MainFormContextMenu.SuspendLayout();
|
||||
|
@ -3401,7 +3407,9 @@
|
|||
this.ZXSpectrumCoreEmulationSettingsMenuItem,
|
||||
this.ZXSpectrumControllerConfigurationMenuItem,
|
||||
this.ZXSpectrumAudioSettingsMenuItem,
|
||||
this.ZXSpectrumNonSyncSettingsMenuItem});
|
||||
this.ZXSpectrumNonSyncSettingsMenuItem,
|
||||
this.ZXSpectrumPokeMemoryMenuItem,
|
||||
this.ZXSpectrumMediaMenuItem});
|
||||
this.zXSpectrumToolStripMenuItem.Name = "zXSpectrumToolStripMenuItem";
|
||||
this.zXSpectrumToolStripMenuItem.Size = new System.Drawing.Size(87, 19);
|
||||
this.zXSpectrumToolStripMenuItem.Text = "ZX Spectrum";
|
||||
|
@ -3421,6 +3429,13 @@
|
|||
this.ZXSpectrumControllerConfigurationMenuItem.Text = "Joystick Configuration";
|
||||
this.ZXSpectrumControllerConfigurationMenuItem.Click += new System.EventHandler(this.ZXSpectrumControllerConfigurationMenuItem_Click);
|
||||
//
|
||||
// ZXSpectrumAudioSettingsMenuItem
|
||||
//
|
||||
this.ZXSpectrumAudioSettingsMenuItem.Name = "ZXSpectrumAudioSettingsMenuItem";
|
||||
this.ZXSpectrumAudioSettingsMenuItem.Size = new System.Drawing.Size(201, 22);
|
||||
this.ZXSpectrumAudioSettingsMenuItem.Text = "Audio Settings";
|
||||
this.ZXSpectrumAudioSettingsMenuItem.Click += new System.EventHandler(this.ZXSpectrumAudioSettingsMenuItem_Click);
|
||||
//
|
||||
// ZXSpectrumNonSyncSettingsMenuItem
|
||||
//
|
||||
this.ZXSpectrumNonSyncSettingsMenuItem.Name = "ZXSpectrumNonSyncSettingsMenuItem";
|
||||
|
@ -3428,6 +3443,41 @@
|
|||
this.ZXSpectrumNonSyncSettingsMenuItem.Text = "Non-Sync Settings";
|
||||
this.ZXSpectrumNonSyncSettingsMenuItem.Click += new System.EventHandler(this.ZXSpectrumNonSyncSettingsMenuItem_Click);
|
||||
//
|
||||
// ZXSpectrumPokeMemoryMenuItem
|
||||
//
|
||||
this.ZXSpectrumPokeMemoryMenuItem.Name = "ZXSpectrumPokeMemoryMenuItem";
|
||||
this.ZXSpectrumPokeMemoryMenuItem.Size = new System.Drawing.Size(201, 22);
|
||||
this.ZXSpectrumPokeMemoryMenuItem.Text = "POKE Memory";
|
||||
this.ZXSpectrumPokeMemoryMenuItem.Click += new System.EventHandler(this.ZXSpectrumPokeMemoryMenuItem_Click);
|
||||
//
|
||||
// ZXSpectrumMediaMenuItem
|
||||
//
|
||||
this.ZXSpectrumMediaMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] {
|
||||
this.ZXSpectrumTapesSubMenu,
|
||||
this.ZXSpectrumDisksSubMenu});
|
||||
this.ZXSpectrumMediaMenuItem.Name = "ZXSpectrumMediaMenuItem";
|
||||
this.ZXSpectrumMediaMenuItem.Size = new System.Drawing.Size(201, 22);
|
||||
this.ZXSpectrumMediaMenuItem.Text = "Media";
|
||||
this.ZXSpectrumMediaMenuItem.DropDownOpened += new System.EventHandler(this.ZXSpectrumMediaMenuItem_DropDownOpened);
|
||||
//
|
||||
// ZXSpectrumTapesSubMenu
|
||||
//
|
||||
this.ZXSpectrumTapesSubMenu.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] {
|
||||
this.zxt1ToolStripMenuItem});
|
||||
this.ZXSpectrumTapesSubMenu.Name = "ZXSpectrumTapesSubMenu";
|
||||
this.ZXSpectrumTapesSubMenu.Size = new System.Drawing.Size(152, 22);
|
||||
this.ZXSpectrumTapesSubMenu.Text = "Tapes";
|
||||
this.ZXSpectrumTapesSubMenu.DropDownOpened += new System.EventHandler(this.ZXSpectrumTapesSubMenu_DropDownOpened);
|
||||
//
|
||||
// ZXSpectrumDisksSubMenu
|
||||
//
|
||||
this.ZXSpectrumDisksSubMenu.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] {
|
||||
this.zxt2ToolStripMenuItem});
|
||||
this.ZXSpectrumDisksSubMenu.Name = "ZXSpectrumDisksSubMenu";
|
||||
this.ZXSpectrumDisksSubMenu.Size = new System.Drawing.Size(152, 22);
|
||||
this.ZXSpectrumDisksSubMenu.Text = "Disks";
|
||||
this.ZXSpectrumDisksSubMenu.DropDownOpened += new System.EventHandler(this.ZXSpectrumDisksSubMenu_DropDownOpened);
|
||||
//
|
||||
// Atari7800HawkCoreMenuItem
|
||||
//
|
||||
this.Atari7800HawkCoreMenuItem.Name = "Atari7800HawkCoreMenuItem";
|
||||
|
@ -4054,12 +4104,17 @@
|
|||
this.timerMouseIdle.Interval = 2000;
|
||||
this.timerMouseIdle.Tick += new System.EventHandler(this.TimerMouseIdle_Tick);
|
||||
//
|
||||
// ZXSpectrumAudioSettingsMenuItem
|
||||
// zxt1ToolStripMenuItem
|
||||
//
|
||||
this.ZXSpectrumAudioSettingsMenuItem.Name = "ZXSpectrumAudioSettingsMenuItem";
|
||||
this.ZXSpectrumAudioSettingsMenuItem.Size = new System.Drawing.Size(201, 22);
|
||||
this.ZXSpectrumAudioSettingsMenuItem.Text = "Audio Settings";
|
||||
this.ZXSpectrumAudioSettingsMenuItem.Click += new System.EventHandler(this.ZXSpectrumAudioSettingsMenuItem_Click);
|
||||
this.zxt1ToolStripMenuItem.Name = "zxt1ToolStripMenuItem";
|
||||
this.zxt1ToolStripMenuItem.Size = new System.Drawing.Size(152, 22);
|
||||
this.zxt1ToolStripMenuItem.Text = "zxt1";
|
||||
//
|
||||
// zxt2ToolStripMenuItem
|
||||
//
|
||||
this.zxt2ToolStripMenuItem.Name = "zxt2ToolStripMenuItem";
|
||||
this.zxt2ToolStripMenuItem.Size = new System.Drawing.Size(152, 22);
|
||||
this.zxt2ToolStripMenuItem.Text = "zxt2";
|
||||
//
|
||||
// MainForm
|
||||
//
|
||||
|
@ -4530,5 +4585,11 @@
|
|||
private System.Windows.Forms.ToolStripMenuItem ZXSpectrumCoreEmulationSettingsMenuItem;
|
||||
private System.Windows.Forms.ToolStripMenuItem ZXSpectrumNonSyncSettingsMenuItem;
|
||||
private System.Windows.Forms.ToolStripMenuItem ZXSpectrumAudioSettingsMenuItem;
|
||||
private System.Windows.Forms.ToolStripMenuItem ZXSpectrumPokeMemoryMenuItem;
|
||||
private System.Windows.Forms.ToolStripMenuItem ZXSpectrumMediaMenuItem;
|
||||
private System.Windows.Forms.ToolStripMenuItem ZXSpectrumTapesSubMenu;
|
||||
private System.Windows.Forms.ToolStripMenuItem ZXSpectrumDisksSubMenu;
|
||||
private System.Windows.Forms.ToolStripMenuItem zxt1ToolStripMenuItem;
|
||||
private System.Windows.Forms.ToolStripMenuItem zxt2ToolStripMenuItem;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -25,6 +25,7 @@ using BizHawk.Emulation.Cores.Computers.AppleII;
|
|||
using BizHawk.Client.ApiHawk;
|
||||
using BizHawk.Emulation.Cores.Computers.Commodore64;
|
||||
using BizHawk.Emulation.Cores.Nintendo.Gameboy;
|
||||
using BizHawk.Emulation.Cores.Computers.SinclairSpectrum;
|
||||
|
||||
namespace BizHawk.Client.EmuHawk
|
||||
{
|
||||
|
@ -2487,6 +2488,82 @@ namespace BizHawk.Client.EmuHawk
|
|||
new ZXSpectrumAudioSettings().ShowDialog();
|
||||
}
|
||||
|
||||
private void ZXSpectrumPokeMemoryMenuItem_Click(object sender, EventArgs e)
|
||||
{
|
||||
new ZXSpectrumPokeMemory().ShowDialog();
|
||||
}
|
||||
|
||||
private void ZXSpectrumMediaMenuItem_DropDownOpened(object sender, EventArgs e)
|
||||
{
|
||||
if (Emulator is ZXSpectrum)
|
||||
{
|
||||
ZXSpectrumTapesSubMenu.Enabled = ((ZXSpectrum)Emulator)._tapeInfo.Count > 0;
|
||||
ZXSpectrumDisksSubMenu.Enabled = ((ZXSpectrum)Emulator)._diskInfo.Count > 0;
|
||||
}
|
||||
}
|
||||
|
||||
private void ZXSpectrumTapesSubMenu_DropDownOpened(object sender, EventArgs e)
|
||||
{
|
||||
ZXSpectrumTapesSubMenu.DropDownItems.Clear();
|
||||
|
||||
if (Emulator is ZXSpectrum)
|
||||
{
|
||||
var speccy = (ZXSpectrum)Emulator;
|
||||
var currSel = speccy._machine.TapeMediaIndex;
|
||||
|
||||
for (int i = 0; i < speccy._tapeInfo.Count; i++)
|
||||
{
|
||||
string name = speccy._tapeInfo[i].Name;
|
||||
|
||||
var menuItem = new ToolStripMenuItem
|
||||
{
|
||||
Name = i + "_" + name,
|
||||
Text = i + ": " + name,
|
||||
Checked = currSel == i
|
||||
};
|
||||
|
||||
int dummy = i;
|
||||
menuItem.Click += (o, ev) =>
|
||||
{
|
||||
speccy._machine.TapeMediaIndex = dummy;
|
||||
};
|
||||
|
||||
ZXSpectrumTapesSubMenu.DropDownItems.Add(menuItem);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void ZXSpectrumDisksSubMenu_DropDownOpened(object sender, EventArgs e)
|
||||
{
|
||||
ZXSpectrumDisksSubMenu.DropDownItems.Clear();
|
||||
|
||||
if (Emulator is ZXSpectrum)
|
||||
{
|
||||
var speccy = (ZXSpectrum)Emulator;
|
||||
var currSel = speccy._machine.DiskMediaIndex;
|
||||
|
||||
for (int i = 0; i < speccy._diskInfo.Count; i++)
|
||||
{
|
||||
string name = speccy._diskInfo[i].Name;
|
||||
|
||||
var menuItem = new ToolStripMenuItem
|
||||
{
|
||||
Name = i + "_" + name,
|
||||
Text = i + ": " + name,
|
||||
Checked = currSel == i
|
||||
};
|
||||
|
||||
int dummy = i;
|
||||
menuItem.Click += (o, ev) =>
|
||||
{
|
||||
speccy._machine.DiskMediaIndex = dummy;
|
||||
};
|
||||
|
||||
ZXSpectrumDisksSubMenu.DropDownItems.Add(menuItem);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Help
|
||||
|
|
|
@ -2752,8 +2752,16 @@ namespace BizHawk.Client.EmuHawk
|
|||
var attributes = Emulator.Attributes();
|
||||
|
||||
CoreNameStatusBarButton.Text = Emulator.DisplayName();
|
||||
CoreNameStatusBarButton.Image = Emulator.Icon();
|
||||
CoreNameStatusBarButton.ToolTipText = attributes.Ported ? "(ported) " : "";
|
||||
CoreNameStatusBarButton.Image = Emulator.Icon();
|
||||
CoreNameStatusBarButton.ToolTipText = attributes.Ported ? "(ported) " : "";
|
||||
|
||||
|
||||
if (Emulator.SystemId == "ZXSpectrum")
|
||||
{
|
||||
var core = (Emulation.Cores.Computers.SinclairSpectrum.ZXSpectrum)Emulator as Emulation.Cores.Computers.SinclairSpectrum.ZXSpectrum;
|
||||
CoreNameStatusBarButton.ToolTipText = core.GetMachineType();
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
private void ToggleKeyPriority()
|
||||
|
@ -4304,6 +4312,7 @@ namespace BizHawk.Client.EmuHawk
|
|||
{
|
||||
GenericCoreConfig.DoDialog(this, "PC-FX Settings");
|
||||
}
|
||||
|
||||
|
||||
private bool Rewind(ref bool runFrame, long currentTimestamp, out bool returnToRecording)
|
||||
{
|
||||
|
|
|
@ -0,0 +1,165 @@
|
|||
namespace BizHawk.Client.EmuHawk
|
||||
{
|
||||
partial class ZXSpectrumPokeMemory
|
||||
{
|
||||
/// <summary>
|
||||
/// Required designer variable.
|
||||
/// </summary>
|
||||
private System.ComponentModel.IContainer components = null;
|
||||
|
||||
/// <summary>
|
||||
/// Clean up any resources being used.
|
||||
/// </summary>
|
||||
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
|
||||
protected override void Dispose(bool disposing)
|
||||
{
|
||||
if (disposing && (components != null))
|
||||
{
|
||||
components.Dispose();
|
||||
}
|
||||
base.Dispose(disposing);
|
||||
}
|
||||
|
||||
#region Windows Form Designer generated code
|
||||
|
||||
/// <summary>
|
||||
/// Required method for Designer support - do not modify
|
||||
/// the contents of this method with the code editor.
|
||||
/// </summary>
|
||||
private void InitializeComponent()
|
||||
{
|
||||
System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(ZXSpectrumPokeMemory));
|
||||
this.OkBtn = new System.Windows.Forms.Button();
|
||||
this.CancelBtn = new System.Windows.Forms.Button();
|
||||
this.label1 = new System.Windows.Forms.Label();
|
||||
this.label4 = new System.Windows.Forms.Label();
|
||||
this.label2 = new System.Windows.Forms.Label();
|
||||
this.numericUpDownAddress = new System.Windows.Forms.NumericUpDown();
|
||||
this.label3 = new System.Windows.Forms.Label();
|
||||
this.numericUpDownByte = new System.Windows.Forms.NumericUpDown();
|
||||
((System.ComponentModel.ISupportInitialize)(this.numericUpDownAddress)).BeginInit();
|
||||
((System.ComponentModel.ISupportInitialize)(this.numericUpDownByte)).BeginInit();
|
||||
this.SuspendLayout();
|
||||
//
|
||||
// OkBtn
|
||||
//
|
||||
this.OkBtn.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
|
||||
this.OkBtn.Location = new System.Drawing.Point(150, 109);
|
||||
this.OkBtn.Name = "OkBtn";
|
||||
this.OkBtn.Size = new System.Drawing.Size(60, 23);
|
||||
this.OkBtn.TabIndex = 3;
|
||||
this.OkBtn.Text = "&OK";
|
||||
this.OkBtn.UseVisualStyleBackColor = true;
|
||||
this.OkBtn.Click += new System.EventHandler(this.OkBtn_Click);
|
||||
//
|
||||
// CancelBtn
|
||||
//
|
||||
this.CancelBtn.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
|
||||
this.CancelBtn.DialogResult = System.Windows.Forms.DialogResult.Cancel;
|
||||
this.CancelBtn.Location = new System.Drawing.Point(216, 109);
|
||||
this.CancelBtn.Name = "CancelBtn";
|
||||
this.CancelBtn.Size = new System.Drawing.Size(60, 23);
|
||||
this.CancelBtn.TabIndex = 4;
|
||||
this.CancelBtn.Text = "&Cancel";
|
||||
this.CancelBtn.UseVisualStyleBackColor = true;
|
||||
this.CancelBtn.Click += new System.EventHandler(this.CancelBtn_Click);
|
||||
//
|
||||
// label1
|
||||
//
|
||||
this.label1.AutoSize = true;
|
||||
this.label1.Location = new System.Drawing.Point(12, 14);
|
||||
this.label1.Name = "label1";
|
||||
this.label1.Size = new System.Drawing.Size(273, 13);
|
||||
this.label1.TabIndex = 17;
|
||||
this.label1.Text = "Enter an address to POKE along with a single byte value";
|
||||
//
|
||||
// label4
|
||||
//
|
||||
this.label4.AutoSize = true;
|
||||
this.label4.Location = new System.Drawing.Point(12, 52);
|
||||
this.label4.Name = "label4";
|
||||
this.label4.Size = new System.Drawing.Size(93, 13);
|
||||
this.label4.TabIndex = 27;
|
||||
this.label4.Text = "Address (0-65535)";
|
||||
//
|
||||
// label2
|
||||
//
|
||||
this.label2.AutoSize = true;
|
||||
this.label2.Location = new System.Drawing.Point(12, 27);
|
||||
this.label2.Name = "label2";
|
||||
this.label2.Size = new System.Drawing.Size(266, 13);
|
||||
this.label2.TabIndex = 29;
|
||||
this.label2.Text = "(Address values that target ROM space will be ignored)";
|
||||
//
|
||||
// numericUpDownAddress
|
||||
//
|
||||
this.numericUpDownAddress.Location = new System.Drawing.Point(15, 69);
|
||||
this.numericUpDownAddress.Maximum = new decimal(new int[] {
|
||||
65535,
|
||||
0,
|
||||
0,
|
||||
0});
|
||||
this.numericUpDownAddress.Name = "numericUpDownAddress";
|
||||
this.numericUpDownAddress.Size = new System.Drawing.Size(90, 20);
|
||||
this.numericUpDownAddress.TabIndex = 30;
|
||||
//
|
||||
// label3
|
||||
//
|
||||
this.label3.AutoSize = true;
|
||||
this.label3.Location = new System.Drawing.Point(123, 52);
|
||||
this.label3.Name = "label3";
|
||||
this.label3.Size = new System.Drawing.Size(70, 13);
|
||||
this.label3.TabIndex = 31;
|
||||
this.label3.Text = "Value (0-255)";
|
||||
//
|
||||
// numericUpDownByte
|
||||
//
|
||||
this.numericUpDownByte.Location = new System.Drawing.Point(126, 68);
|
||||
this.numericUpDownByte.Maximum = new decimal(new int[] {
|
||||
255,
|
||||
0,
|
||||
0,
|
||||
0});
|
||||
this.numericUpDownByte.Name = "numericUpDownByte";
|
||||
this.numericUpDownByte.Size = new System.Drawing.Size(67, 20);
|
||||
this.numericUpDownByte.TabIndex = 32;
|
||||
//
|
||||
// ZXSpectrumPokeMemory
|
||||
//
|
||||
this.AcceptButton = this.OkBtn;
|
||||
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
|
||||
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
|
||||
this.CancelButton = this.CancelBtn;
|
||||
this.ClientSize = new System.Drawing.Size(288, 144);
|
||||
this.Controls.Add(this.numericUpDownByte);
|
||||
this.Controls.Add(this.label3);
|
||||
this.Controls.Add(this.numericUpDownAddress);
|
||||
this.Controls.Add(this.label2);
|
||||
this.Controls.Add(this.label4);
|
||||
this.Controls.Add(this.label1);
|
||||
this.Controls.Add(this.CancelBtn);
|
||||
this.Controls.Add(this.OkBtn);
|
||||
this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon")));
|
||||
this.Name = "ZXSpectrumPokeMemory";
|
||||
this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent;
|
||||
this.Text = "Poke Memory";
|
||||
|
||||
((System.ComponentModel.ISupportInitialize)(this.numericUpDownAddress)).EndInit();
|
||||
((System.ComponentModel.ISupportInitialize)(this.numericUpDownByte)).EndInit();
|
||||
this.ResumeLayout(false);
|
||||
this.PerformLayout();
|
||||
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
private System.Windows.Forms.Button OkBtn;
|
||||
private System.Windows.Forms.Button CancelBtn;
|
||||
private System.Windows.Forms.Label label1;
|
||||
private System.Windows.Forms.Label label4;
|
||||
private System.Windows.Forms.Label label2;
|
||||
private System.Windows.Forms.NumericUpDown numericUpDownAddress;
|
||||
private System.Windows.Forms.Label label3;
|
||||
private System.Windows.Forms.NumericUpDown numericUpDownByte;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,39 @@
|
|||
using System;
|
||||
using System.Linq;
|
||||
using System.Windows.Forms;
|
||||
|
||||
using BizHawk.Client.Common;
|
||||
using BizHawk.Emulation.Cores.Computers.SinclairSpectrum;
|
||||
using System.Text;
|
||||
|
||||
namespace BizHawk.Client.EmuHawk
|
||||
{
|
||||
public partial class ZXSpectrumPokeMemory : Form
|
||||
{
|
||||
private ZXSpectrum.ZXSpectrumSettings _settings;
|
||||
|
||||
public ZXSpectrumPokeMemory()
|
||||
{
|
||||
InitializeComponent();
|
||||
}
|
||||
|
||||
private void OkBtn_Click(object sender, EventArgs e)
|
||||
{
|
||||
var speccy = (ZXSpectrum)Global.Emulator;
|
||||
var addr = (ushort)numericUpDownAddress.Value;
|
||||
var val = (byte)numericUpDownByte.Value;
|
||||
|
||||
speccy.PokeMemory(addr, val);
|
||||
|
||||
DialogResult = DialogResult.OK;
|
||||
Close();
|
||||
}
|
||||
|
||||
private void CancelBtn_Click(object sender, EventArgs e)
|
||||
{
|
||||
GlobalWin.OSD.AddMessage("POKE memory aborted");
|
||||
DialogResult = DialogResult.Cancel;
|
||||
Close();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,624 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<root>
|
||||
<!--
|
||||
Microsoft ResX Schema
|
||||
|
||||
Version 2.0
|
||||
|
||||
The primary goals of this format is to allow a simple XML format
|
||||
that is mostly human readable. The generation and parsing of the
|
||||
various data types are done through the TypeConverter classes
|
||||
associated with the data types.
|
||||
|
||||
Example:
|
||||
|
||||
... ado.net/XML headers & schema ...
|
||||
<resheader name="resmimetype">text/microsoft-resx</resheader>
|
||||
<resheader name="version">2.0</resheader>
|
||||
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
|
||||
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
|
||||
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
|
||||
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
|
||||
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
|
||||
<value>[base64 mime encoded serialized .NET Framework object]</value>
|
||||
</data>
|
||||
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
|
||||
<comment>This is a comment</comment>
|
||||
</data>
|
||||
|
||||
There are any number of "resheader" rows that contain simple
|
||||
name/value pairs.
|
||||
|
||||
Each data row contains a name, and value. The row also contains a
|
||||
type or mimetype. Type corresponds to a .NET class that support
|
||||
text/value conversion through the TypeConverter architecture.
|
||||
Classes that don't support this are serialized and stored with the
|
||||
mimetype set.
|
||||
|
||||
The mimetype is used for serialized objects, and tells the
|
||||
ResXResourceReader how to depersist the object. This is currently not
|
||||
extensible. For a given mimetype the value must be set accordingly:
|
||||
|
||||
Note - application/x-microsoft.net.object.binary.base64 is the format
|
||||
that the ResXResourceWriter will generate, however the reader can
|
||||
read any of the formats listed below.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.binary.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.soap.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.bytearray.base64
|
||||
value : The object must be serialized into a byte array
|
||||
: using a System.ComponentModel.TypeConverter
|
||||
: and then encoded with base64 encoding.
|
||||
-->
|
||||
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
|
||||
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
|
||||
<xsd:element name="root" msdata:IsDataSet="true">
|
||||
<xsd:complexType>
|
||||
<xsd:choice maxOccurs="unbounded">
|
||||
<xsd:element name="metadata">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" use="required" type="xsd:string" />
|
||||
<xsd:attribute name="type" type="xsd:string" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="assembly">
|
||||
<xsd:complexType>
|
||||
<xsd:attribute name="alias" type="xsd:string" />
|
||||
<xsd:attribute name="name" type="xsd:string" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="data">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
|
||||
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="resheader">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:choice>
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:schema>
|
||||
<resheader name="resmimetype">
|
||||
<value>text/microsoft-resx</value>
|
||||
</resheader>
|
||||
<resheader name="version">
|
||||
<value>2.0</value>
|
||||
</resheader>
|
||||
<resheader name="reader">
|
||||
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<resheader name="writer">
|
||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<assembly alias="System.Drawing" name="System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
|
||||
<data name="$this.Icon" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||
<value>
|
||||
AAABAAwAMDAQAAAABABoBgAAxgAAACAgEAAAAAQA6AIAAC4HAAAYGBAAAAAEAOgBAAAWCgAAEBAQAAAA
|
||||
BAAoAQAA/gsAADAwAAAAAAgAqA4AACYNAAAgIAAAAAAIAKgIAADOGwAAGBgAAAAACADIBgAAdiQAABAQ
|
||||
AAAAAAgAaAUAAD4rAAAwMAAAAAAgAKglAACmMAAAICAAAAAAIACoEAAATlYAABgYAAAAACAAiAkAAPZm
|
||||
AAAQEAAAAAAgAGgEAAB+cAAAKAAAADAAAABgAAAAAQAEAAAAAACABAAAAAAAAAAAAAAQAAAAEAAAAAAA
|
||||
AAAAAIAAAIAAAACAgACAAAAAgACAAICAAACAgIAAwMDAAAAA/wAA/wAAAP//AP8AAAD/AP8A//8AAP//
|
||||
/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAHR3AAAAAAAAAAAAAAAAAAAAAAAAAAAAdHdEcAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAHd0d3QAAAAAAAAAAAAAAAAAAAAAAAAAAEd8d3UAAAAAAAAAAAAAAAAAAAAAAAAAB3yHfHZw
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAd3fIyHVwAAAAAAAAAAAAAAAAAAAAAAAAfHh3jIxwAAAAAAAAAAAAAAAA
|
||||
AAAAAAAHd8jIyHdgAAAAAAAAAAAAAAAAAAAAAAAHd4yHfIdAAAAAAAAAAAAAAAAAAAAAAAAHyMjIyMhQ
|
||||
AAAAAAAAAAAAAAAAAAAAAAB3d3eMh4dgAAAAAAAAAAAAAAAAAAAAAAB8jIyIfIdQAAAAAAAAAAAAAAAA
|
||||
AAAAAAB3h4jIiMh3AAAAAAAAAAAAAAAAAAAAAAB8jIeHeIjHAAAAAAAAAAAAAAAAAAAAAAeIiHh4eMiE
|
||||
AAAAAAAAAAAAB0dHcAAAAAd8h4eIiIiHcAAAAAAAAAB0d3d3RwAAAAeIeIiIiIh3RwAAAAAAAHR3d8h3
|
||||
dAAAAAfIh4iIiHiIx0cAAAAAdHh3eIeHhwAAAAeHiIiIiIiId3R3dHR0eHd4h4eHhAAAAAd4eIiIiIiH
|
||||
x3d2d3eId4iIiIiIhwAAAAd4eIiI+IiIh3d3eHh3iIiIiIeHwAAAAAfIjHeIiIiIyIeHh4iIiIiIiIiI
|
||||
cAAAAAeIQ0R3h3iIiMiIiIiIiIiIiIiEAAAAAAfIR3d3d0iIiIh4iIeIiIiIiHhAAAAAAAB4d3d3SHiI
|
||||
h4fTiIi3iIiIeIwAAAAAAAB3h4d3eIeIiHiJiIuIiIh4jHAAAAAAAAAHyId3h3h4iIh4iIiIiIiHeAAA
|
||||
AAAAAAAAB8iMiMjIiIiIh4h3aMjHAAAAAAAAAAAAAAdYyIeIiIiMjId6d4eAAAAAAAAAAAAAAAAHdsjH
|
||||
eIeH6MiId3AAAAAAAAAAAAAAAIiIh4V8jIh4eIfHcAAAAAAAAAAAAACIiIh3AAAHd3h3fHcAAAAAAAAA
|
||||
AAAAAAiIjHgAAAAAAHx8eAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAD///////8AAP///////wAA////////AAD///////8AAP///////wAA////////
|
||||
AAD///////8AAP///////wAA//h/////AAD/4D////8AAP/AP////wAA/8A/////AAD/gB////8AAP8A
|
||||
H////wAA/wAf////AAD+AB////8AAP4AH////wAA/gAf////AAD8AB////8AAPwAH////wAA/AAP////
|
||||
AAD8AA////8AAPgAD//+BwAA+AAH//ADAAD4AAP/wAMAAPgAAP8AAwAA+AAAAAADAAD4AAAAAAMAAPgA
|
||||
AAAABwAA+AAAAAAHAAD4AAAAAA8AAPgAAAAAHwAA/AAAAAA/AAD8AAAAAH8AAP4AAAAA/wAA/4AAAAP/
|
||||
AAD/4AAAB/8AAP/4AAAf/wAA/8AAAH//AAD8A+AD//8AAPgP/A///wAA////////AAD///////8AAP//
|
||||
/////wAA////////AAD///////8AAP///////wAA////////AAAoAAAAIAAAAEAAAAABAAQAAAAAAAAC
|
||||
AAAAAAAAAAAAABAAAAAQAAAAAAAAAAAAgAAAgAAAAICAAIAAAACAAIAAgIAAAICAgADAwMAAAAD/AAD/
|
||||
AAAA//8A/wAAAP8A/wD//wAA////AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAdwAAAAAAAAAAAAAAAA
|
||||
AAd0dAAAAAAAAAAAAAAAAAB3x3cAAAAAAAAAAAAAAAAAd3fHcAAAAAAAAAAAAAAAB3yMh3AAAAAAAAAA
|
||||
AAAAAAfIeMdwAAAAAAAAAAAAAAAHjIyHQAAAAAAAAAAAAAAAfId4yHAAAAAAAAAAAAAAAHjIyIdQAAAA
|
||||
AAAAAAAAAAB3iId4YAAAAAAAAAdwAAAAjIiIiIUAAAAAAHd3dAAAB4iIiHh8cAAAAHd3x4dwAAd4iIiI
|
||||
h3Z3d3R3yIh4cAAHh4iIiIfHd3d4iIiIh3AAB3jHiIiIiHeHiIiIiIwAAAh3dXh4iMiIiIiIiIhwAAAA
|
||||
yGd0d4iIeIi4iIiMAAAAAIeHd4iIh32IiIiIcAAAAAAAd4jIyIiIiHeHyAAAAAAAAAB3h4iIh8h3dwAA
|
||||
AAAAAAAIh8fIh4eIaAAAAAAAAACIiHAAB8jIyAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA////////
|
||||
////////////////////n////g////wP///8B///+Af///gH///4B///8Af///AH///wB//n8AP/A+AB
|
||||
/AHgAAAB4AAAAeAAAAPgAAAH8AAAD/AAAB/8AAA//wAA//4AA//weA//////////////////////////
|
||||
//8oAAAAGAAAADAAAAABAAQAAAAAACABAAAAAAAAAAAAABAAAAAQAAAAAAAAAAAAgAAAgAAAAICAAIAA
|
||||
AACAAIAAgIAAAICAgADAwMAAAAD/AAD/AAAA//8A/wAAAP8A/wD//wAA////AAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHRwAAAAAAAAAAAAB3dAAAAAAAAAAAAA
|
||||
d8dwAAAAAAAAAAAAfId3AAAAAAAAAAAHeMjHAAAAAAAAAAAHyHh3AAAAAAAAAAAHh3eEAAAAAAAAAAAI
|
||||
yIiHAAAAAHd2cAAIiIiIQAAAd3d4UACHiIiId3d3eHiIcACHh4iIyHeHiIiIcAAIR3d4iIiIiIiMAAAH
|
||||
d3eIh3iIiIhwAAAAeMh4iIiHiMAAAAAAAHfIiMh4aAAAAAAAiIgHyIfIAAAAAAAIgAAAAIAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP///wD///8A////AP///wD8f/8A+H//APB/
|
||||
/wDwP/8A4D//AOA//wDgP/8A4D/BAOAfAQDAAAEAwAABAOAAAwDgAAcA8AAfAPwAPwDwgP8A5/f/AP//
|
||||
/wD///8A////ACgAAAAQAAAAIAAAAAEABAAAAAAAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAAACA
|
||||
AAAAgIAAgAAAAIAAgACAgAAAgICAAMDAwAAAAP8AAP8AAAD//wD/AAAA/wD/AP//AAD///8AAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAd1AAAAAAAAB8cAAAAAAAB4eAAAAAAAAHyMgAAAAAAAiIhwAAAHcACI
|
||||
iHcAd3hwAIz4jIeIiIAAd3eIiIiIAACHeIiIiHAAAACMeMh4AAAAiAAIgAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAD//wAA//8AAP//AADj/wAA4/8AAMP/AADB/wAAwfkAAMDBAADAAQAAwAMAAMAHAADwDwAAzn8AAP//
|
||||
AAD//wAAKAAAADAAAABgAAAAAQAIAAAAAAAACQAAAAAAAAAAAAAAAQAAAAEAAAAAAAA9OzsAZD8/AGg8
|
||||
PABtPj4AQkNDAEZIRwBWQkIAV0REAF5AQABbRkYAVklJAFxPTwBTU1MAXFJSAF5ZWQBkQEAAYUREAGZF
|
||||
RQBqQkEAYEtLAGNPTwBwQUEAfUZGAHJKSgB2SUkAfU9PAGBRUQBgVFQAZlZWAGZYWABqWVkAclZWAHpU
|
||||
VAB9W1oAbmJiAGtoaABtaWkAcWdnAHdnZwB8Y2MAe2pqAHJxcQB+dHQAd3l5AHl6egCGT08AiU9PAIFP
|
||||
UACGU1MAjVFRAIlWVgCMV1cAg1xbAIxaWQCQUlIAlVJSAJFXVgCXVVUAmVVVAJZaWQCSXV0AlV9eAJpZ
|
||||
WgCeW1sAml5eAKBZWgCgXFwAql9fAIRmZQCIZWQAhWtrAI5ragCTYmEAnGBhAJ9kYwCaZmYAk25uAJ1s
|
||||
awCFdHQAiXd3AIt+fgCWd3cAmHR0AJV5eQCbfHwAo2JhAKZhYQChZWUApGVkAKplZACsZGQAqmhnAKZr
|
||||
agCnbGsAqmloAKlubQCsbW0AtGZnALhsbACxb3AAv29wAKVxcACrc3IAr35+ALN0cwC5c3MAvXBxALR4
|
||||
dgC1fHsAunt6AMNtbgDGb3AAw3FyAMZwcQDGdXUAyHR1AMp3eADBeXkAxnt7AMB/fgDLensANLBSAEWf
|
||||
TgBBtFwAPMdnADHkdgDciiIAvoF/AISrdwDln0sA35lhAN2XfADgmmEA8LdlAO61cAArWPIALWT+AEh5
|
||||
+gDOf4AAfoCAAHiA1ABZv9wAZrnUAGK+2ABxnv4Ad6P/ADPX/QBw0OcAW+D7AIKEgwCPgoIAjI2NAJuC
|
||||
ggCUiIgAmYqKAJGSkgCjhIQAqoKCAKKLiwC+hIMAsoqKALaSgQCum5sAsZubALqqlQCdgr4Ar6ytALGh
|
||||
oAC6pKQAwoSDAMyBggDGiIYAyYiHAMWMigDMjIoA0ISFANKHiADUjIwA2Y6NAMCUjQDIk44A0JCPANaP
|
||||
kADHlZQAzpSSAMScmwDUkpIA2ZSVANWYlgDampcA2ZeYANWcnADam5sA4p2cAMChjwDeoJ4A5aCFAOaj
|
||||
jQDlpJoA2p6hAMOkowDOoaEAy62tANegoADdoqEA2aGpANGsrwDdq6kAwbG4ANGysQDdtLQA2ri3AOGk
|
||||
owDjqKYA66ylAOGnqADjq6oA6a2rAOOwrwDssK4A5K+wAOaztADttLIA57i2AO24tgDmurgA6rq6APC1
|
||||
swDyuLYA9Ly5APi+uwD1wL0A+cC9AKKMwACkk8QAqprMALSayACptsEAlaDkAOy/wACRxtQAgOv9AJnr
|
||||
9wDEwsoA5sbGAOzCwgDuyMcA7MzMAPPEwgDxy8oA9dPTAPja2gAAAAAAAAAAAP///wAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFAoIJQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAACYXODs4BCUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
KTNDQ0M7OAoAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAALllbYmJZQBcAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAYYWNwcHBwWy8mAAAAAAAAAAAAAAAAAAAA
|
||||
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
|
||||
AAAAAAAAAAAAAAAAAAD///////8AAP///////wAA////////AAD///////8AAP///////wAA////////
|
||||
AAD///////8AAP///////wAA//h/////AAD/4D////8AAP/AP////wAA/8A/////AAD/gB////8AAP8A
|
||||
H////wAA/wAf////AAD+AB////8AAP4AH////wAA/gAf////AAD8AB////8AAPwAH////wAA/AAP////
|
||||
AAD8AA////8AAPgAD//+BwAA+AAH//ADAAD4AAP/wAMAAPgAAP8AAwAA+AAAAAADAAD4AAAAAAMAAPgA
|
||||
AAAABwAA+AAAAAAHAAD4AAAAAA8AAPgAAAAAHwAA/AAAAAA/AAD8AAAAAH8AAP4AAAAA/wAA/4AAAAP/
|
||||
AAD/4AAAB/8AAP/4AAAf/wAA/8AAAH//AAD8A+AD//8AAPgP/A///wAA////////AAD///////8AAP//
|
||||
/////wAA////////AAD///////8AAP///////wAA////////AAAoAAAAIAAAAEAAAAABAAgAAAAAAAAE
|
||||
AAAAAAAAAAAAAAABAAAAAQAAAAAAAFFNTQBRUlIAU1RUAGJHRwBiT08Aa0lIAGJTUwBrVlYAYllZAGZc
|
||||
XABpWloAb1xbAHNTUwB7V1YAc1hXAHFbWwBkZWUAaWFhAG5kZABpamkAcGFhAHlubgB2cHAAf3V1AH55
|
||||
eQB8fX0AgUpKAI1PTwCLWFcAhlhYAI9ZWQCKXFsAm1ZWAJJZWQCWWVgAmlpbAJtcWwCiXFwAl2BfAIBg
|
||||
YACAZ2YAgG9vAI9oaACWZWQAmGBhAJ5kZACcaWoAmm9vAIV0dACNcHAAiXZ2AIB8fACac3IAm3V0AJ51
|
||||
dQCZfHwAnHx8AKNmZgCnZmYAqmJiAK5jYwCvb24AtWVmALBtbgC5bW0AvmxtAKx+fQCxcnIAtHBwALZz
|
||||
dACydXQAtnd2ALlwcAC5dnYAt3p5ALh5eAC8fHsAun18ALx+fQDGb3AAxnBxAMdzdADAd3YAyHJzAMlz
|
||||
dADJdXYAynd4AMd/fwDMe3wAzXx9AHunbwBhvHIAYsN4ANuLOwC2hn4A4Zt5APC3ZABte9sAX47+AHWM
|
||||
5QAl0foAY+P8AIeDgwCFhoYAioSEAJOIiACWi4sAmpKRAKGCgQCmhYUAqYGBAKuDhACniooApYyMAKiO
|
||||
jQCyhYMAvoWEALeNjQCrj5AAr5eXALSVlAC9lJMAmbCEAK6RugDBgYAAwoSCAMWDhADChoQAxYeFAM6A
|
||||
gQDFiIYAxoqIAMqIiQDMi4oAy4yKAMiPjQDPj44A0ISFANKJigDUi4wA04+NANWNjgDKkY8A0JCOANud
|
||||
iQDWj5AAzJSTAM2XlgDGm5oA1pGSANOUkgDVl5EA1pOUANiVlgDYmJUA2ZeYANKenADbmpsA3pmYANuc
|
||||
mgDbn5wA1aacAN6gngDqqZoA3Z+gAMyjowDCra0AxqysAMqpqQDboaAA3qKiAN6logDbp6UA3aWkANer
|
||||
qgDWsbMA0rW0ANe0tADfs7IA4aSiAOGlpQDkp6UA46imAOWopgDsraIA6qimAOGoqADhrqwA6a2rAOqv
|
||||
rADpsK4A7LGuAOGzswDlsbEA7bKxAO+1sgDotrYA5rm3AO+4twDot7sA6bq5AOu9uwDrv70A8bazAPG2
|
||||
tADxuLUA9Lm2APC9uwD2vboA9L+9APi+uwD4v7wA8sC+APXAvgD5wL0AkILJAKqXzACsu8cAqr/LALLV
|
||||
3QDawMIA48XFAOvDwQDswMAA7cTDAO/ExQDgxsgA8cbEAPTGxADwyskA9MvJAPLNzQD21dYA+NjZAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAA////AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAMEwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAqHCEcBQAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAayU9PSYbAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAdQlBSQiJpAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAM0pSUlJQPRcAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAnUlJSUlJGFQAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAFJSUlJSUkoQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAzUlJSWVJZfxAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAC5XWYqKioqGDgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAASoqMkpqa
|
||||
mqAsAAAAAAAAAAAAAAAAAABoNAAAAAAAAACMjJyuvLy2toYHAAAAAAAAAAAAABcOIDouBgAAAAAAc4yc
|
||||
tsHKysPAriIKAAAAAAAAABYgRk1LTX+DEAAAAABukqXB4ejo4dHPQCIEChcXEwggTXV/k66unKMpAAAA
|
||||
AG6Srsro6ero0dN/Rk1NRk2Dg4STrsbh4cHAt2sAAAAAbpKuOXPe6ajW15KGg4OGk528yuHo5eHPz882
|
||||
AAAAAAB4jCkDAxSoMabXt5yjt8ro3ePo5dbT09HTdAAAAAAAAABGcBFoGgFwdtfDwHxi2dpmZcrX09HP
|
||||
z0MAAAAAAAAAAHh/qWwaOa6cz9PNZGPYsdzbzc3DwLk2AAAAAAAAAAAAAAAvhpKakoyg19HNyKS5wHtb
|
||||
orZ/cwAAAAAAAAAAAAAAAAAANkaKWVm5zb1gYV6cXVxfNgAAAAAAAAAAAAAAAAAAALGvlTIuP1K5tqCR
|
||||
l4xfLwAAAAAAAAAAAAAAAAAAsbPBenkAAAAAcCVYjE0scwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD///////////////////////////+f///+D////A////wH
|
||||
///4B///+Af///gH///wB///8Af///AH/+fwA/8D4AH8AeAAAAHgAAAB4AAAA+AAAAfwAAAP8AAAH/wA
|
||||
AD//AAD//gAD//B4D////////////////////////////ygAAAAYAAAAMAAAAAEACAAAAAAAQAIAAAAA
|
||||
AAAAAAAAAAEAAAABAAAAAAAAWlJSAHBJSQB1SEgAe1dXAHdYWAB5WlkAel1dAGBiYgB1bGwAfWtrAHh2
|
||||
dgB9fn4Ag01NAIRXVwCIV1cAhV9eAItbWgCgX14ApV1dAJhgXwCNYGAAnWtqAJhtbQCCdnYAh3x8AI15
|
||||
eACeensAqGBgAKhoZwCga2oArGpqALNqagCzb28AtG1tALltbQCxb3AApnVzAKlzcwCqdHMApnp6AKd+
|
||||
fgCpensAq3x7ALZ3dgC8dHQAvH59AMZvcADGcHEAxXN0AMhycwDJdncAynh5AMx5egDNfn8Ajo1wAOek
|
||||
VgDGgH8A4p53AEZ2+gB8u4AAd8PaAIuEhACOh4cAjo6OAJ+DggCejo4Ao4SEAKSIiACsi4sAqo2MAK6P
|
||||
jgC+gYAAvoaGAL+KiACskJAAtJeXALWenQC5np4At6iOAKmyjgC9nroAwYSDAMaGhADOhoYAxomHAMiK
|
||||
iQDJjYwA0oeIANOOjwDUjY0A2ZiPANaPkADGkZEAx5eXAMySkADGnZwA1ZOSANeTlADWl5YA2JSVANGZ
|
||||
mADan50A3J6dAOCcmwDVoJ8A7K2fAMOtrQDXo6IA3aCgAN+kpADVq6oA3ay3AMu0tADPtrYA3L+/AOCi
|
||||
oQDhpqUA5KelAOinpgDlq6gA46usAOOvrQDqrqwA7LGuAOayswDjtrQA5re1AOqysQDts7EA57y6AO+8
|
||||
ugDrvL0A8LOwAPC1sgDwtrQA87q3APS6twD2vboA8b69APi/vAD2wb4A+cC9AJmTzwDHqMMAu8PMAIHf
|
||||
8QDByNAA7cLCAO3FwwDvxsQA5cjIAOzOzgDwxcQA9cbEAPPP0AD10tIAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAD///8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
BQMJAAAAAAAAAAAAAAAAAAAAAAAAAAAPHBMNAAAAAAAAAAAAAAAAAAAAAAAAABojLy8TAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAB0wMDAiPgAAAAAAAAAAAAAAAAAAAAAAQjAwMDAtGAAAAAAAAAAAAAAAAAAAAAAAFzIy
|
||||
NTU5CgAAAAAAAAAAAAAAAAAAAAAAIjZYWFxcBwAAAAAAAAAAAAAAAAAAAAAANlxtdW11JQAAAAAAAAAA
|
||||
PgcRDgkAAAAAXG1/lISAZgMAAAAAABkVLC5SVhcAAABNY3WWnJuLfB8UBAcQHkhWaX91dSsAAABNY2BM
|
||||
mJeCiVJSVl9laX+WloSJgEIAAAAAXAEIC0tGjnR0dJaRk5qNjIyJQwAAAAAAJkNADBtdjIaPO1GSPYuJ
|
||||
hnVEAAAAAAAAAClISWRcd4xwkGp8UE90VwAAAAAAAAAAAAAAKSQ1NYZ7OjhbPDdGAAAAAAAAAAAAAHNv
|
||||
YGsAKyJoXFYmRwAAAAAAAAAAAAAAcnIAAAAAAAAATgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA////AP//
|
||||
/wD///8A////APx//wD4f/8A8H//APA//wDgP/8A4D//AOA//wDgP8EA4B8BAMAAAQDAAAEA4AADAOAA
|
||||
BwDwAB8A/AA/APCA/wDn9/8A////AP///wD///8AKAAAABAAAAAgAAAAAQAIAAAAAAAAAQAAAAAAAAAA
|
||||
AAAAAQAAAAEAAAAAAABjZGQAdmRjAHtpaQB/eHgAgU9PAKBaWgCFbm0AlWtqAKptbgCwZ2cAsGhoAKxw
|
||||
cACteHkAvnJyAMZvcADGcHEAy3l5AMx9fgCFmXQAwIB/ANeUfQDhoX8AlIqJAJWMjACYiIgAoIaGAK2K
|
||||
igCxh4cAvoGAALKKigC4iYgAuJWVAL2cnACss50AuqKhAL+mpgDLgoIAxImHAMeNjADLkI8AxpWTANCS
|
||||
kQDYlZUA1J6dANqZmgDdnp4A1J+oAMaiogDOr68AzLKyANi5uADhpaIA4qypAOWtqADrrqsA4bKwAOay
|
||||
sgDtuLYA57++AOy4uADxtLIA8be0APa9ugDswL4A9sG+ALCcxwC5ncIA06zBALnH0QC2ytQA7sPDAPLS
|
||||
0gAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAP///wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAZBgUAAAAAAAAAAAAAAAAACw8KAAAAAAAAAAAAAAAAGhAQDgAAAAAAAAAAAAAAAAkRESUYAAAA
|
||||
AAAAAAAAAAAlKy4uBwAAAAAAAAcDAAAAKzlHPCYCAAAYCB0oKgAAAC0wSDs0FB0nLDlAOiwAAAANAQQb
|
||||
Pi9DRkVBPzUAAAAAJB4cKz5EQjMiNSkAAAAAAAAAHwwRNxYVEyQAAAAAAAAxMgAAACEgAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//8AAP//AAD//wAA4/8AAOP/AADD/wAAwf8AAMH5
|
||||
AADAwQAAwAEAAMADAADABwAA8A8AAM5/AAD//wAA//8AACgAAAAwAAAAYAAAAAEAIAAAAAAAgCUAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAABAAAAAkAAAAJAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMAAAAUAAAAOAEBAVUAAABUAAAANQAAABAAAAABAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAkFBSUvGRl5TCkpwlYuLtxDJCTQFw0NmQAA
|
||||
AEkAAAAPAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACGAwMKE8rK6V6RET2klJR/5ZS
|
||||
U/+OT0//ZDc38B0QEJoAAAAyAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAYDAwYVzAwoopP
|
||||
T/ygXVz/oFtb/55ZWf+bWFf/k1NT/1UvL9wGAwNcAAAADAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AARNKipxhk5O+adkY/+uZWX/tWdo/7VmZ/+qYWH/nltb/3hERPcfERGCAAAAFgAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAADEZGS1zQ0LXqGdm/7ptbf/Fb3D/x3Bx/8hwcf/BbW7/q2Vl/4hPT/82HR2gAAAAIAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAB1gxMYyYXl3/vXFx/8Zwcf/HcHH/x3Bx/8dwcf/HcHH/uG1t/5NY
|
||||
V/9EJia2AAAAKQAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPB8fNH1MS+K4cnH/x3Fy/8dwcf/HcHH/x3Bx/8dw
|
||||
cf/HcHH/wHBx/51gX/9PLCzGAAAAMwAAAAIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACXjU1h6NnZv/Fc3T/x3Bx/8dw
|
||||
cf/HcHH/x3Bx/8dwcf/HcHH/w3Jz/6ZoZ/9ZMzPTAQAAPQAAAAMAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAyFxccektK0b12
|
||||
dv/HcHH/x3Bx/8dwcf/HcHH/x3Bx/8dwcf/HcHH/xXR0/69wb/9jOjneBwMDSQAAAAUAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AABNKSlNlmBf9sh3d//HcHH/x3Bx/8dwcf/HcHH/x3Bx/8dwcf/HcHH/xnd3/7Z4d/9sQUDnDgcHVQAA
|
||||
AAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
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
|
||||
ov/grq3/4a6t/96lo//eoJ7/36Kg/+Cjof+IWVjnGwwMQwAAAAIAAAAAAAAAAAAAAAAAAAAARyQkL6Br
|
||||
auzZk5P/25qb/+GnqP/ntLT/7cDA//LLy//209T/+NjY//fX1//00ND/8cbG//W9u//4vrz/46ak/7d0
|
||||
c/+vb27/s3Jy/7d2df+ucXD/pWpp/6Npaf+nbWz/sHVz/7p9fP/EhYT/yImI/8WIhv/DiIb/ypGP/9eg
|
||||
n//hr63/57q5/+rCwP/rwsD/6bq4/+evrf/nq6n/6q6r/9qgnv9wRkbDBwAAHgAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAASCQkLZ1nZuvYkpP/25uc/+Opqv/qtrf/7cHB//TOzv/52Nj/+tzc//na2v/xz9D/8MfH//fA
|
||||
vv/6wb7/6a6r/8OBgP/DgoD/vX58/7h7ev+8fn3/woOC/8aHhv/HiYj/xoqJ/8aLif/Ijoz/zZST/9eg
|
||||
nv/hrav/6Lm3/+zCwf/uyMf/78nH/+/Dwf/uvLr/7ba0/+60sf/vtLL/8ri1/7J+fflMKSltAAAABAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAQyEhI5JcXOPWj5D/3Juc/8qVlf+BZmb/bl5e/4l4eP/AqKj/8tPT//LO
|
||||
zv+5p6b/w6qq//fBv//7wr//8LWy/86Ojf/Ojoz/0ZGP/9GSkP/OkY//zpOR/9GamP/VoJ//2qel/+Gv
|
||||
rf/nt7X/6727/+3Dwf/wycf/8czL//LLyf/yxsT/8cC+//G7uf/yubf/87m3//S7uP/4vrv/1J6c/3JH
|
||||
RrAdCgsWAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAANRcXEYJNTcvPiIn/15aW/2VNTf85Ojr/Q0VF/0JF
|
||||
RP9dXFz/n5GR/+S/v/+bh4f/hXp6/+25uP/7wr//9bu4/9qcmv/Zmpj/252b/96gnf/ipKH/5q+s/+u+
|
||||
vP/vycf/8srI/+3Hxv/wysj/9c7M//TNy//0ysj/9MbE//TBv//1vrz/9r26//e9u//4vrv/+L+8//vB
|
||||
vv/hqqf/g1ZVzDwcHC4AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAW4+Ppq/env/05OT/2ZX
|
||||
V/9rbm7/fX9//3l6ev99f3//cHJy/5F9ff+ff3//XFhY/9eop//8wr//+L+8/+Wppv/ipaP/5qil/96i
|
||||
pP/Kmaz/1qi1//LGxP/tyMf/qb3J/23E3P9kw9//vMTN//jDwP/3wb//+MC9//i/vf/5v73/+b+8//i/
|
||||
vP/3vrv/+L68/92mo/+IWlnRRSMjOAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFcv
|
||||
L0mbX1/y15GS/6GAgP9XV1b/iYuL/4CBgf98fX3/cnR0/1dPT/++j4//km9w/9Sfnv/6wL3/+cC9/+6z
|
||||
sP/ssK3/0Z+u/4OH1P9YffD/QGPs/7KYyv/Ct7z/Ytrz/3Ts//8s2f//cbvU//m+u//4v7z/+L67//e9
|
||||
uv/1vLn/9Lq3//O5tv/zuLX/0puZ/4RVVctGIyM4AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAADIXFwdrPDySq2ts/diZmf/ApKT/sKur/4CBgP95enr/iYiI/49zdP/do6P/36Ch/96e
|
||||
nv/zuLX/+sK///W7uP/1ubT/qZC//2qY+/9tnf//MGT6/56FxP/esK//nMbS/57n8/9+z+T/ybG3//a6
|
||||
t//zubb/8re0//C1s//utLH/7rKw/+qvrP++iIb9dklJtkMgISoAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABHIyMSazw8kZ5hYvXNjI3/2aSk/7OMjP+bd3f/sIKC/9KV
|
||||
lv/cnJz/2peY/9aRkf/koqL/+sG+//nAvf/5v7z/4amw/6qZx/+aouP/qpvP/+mxtv/2urj/6rGv/+S6
|
||||
u//ptrX/466n/+Ovqf/ssK7/6q6s/+isqv/oq6n/2J2b/6JubfFoPT2NOxoaFwAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOBoaCFowMFd7SEjAomZm9sWC
|
||||
gv/XkZL/25SV/9iSk//Wj5D/1IyN/9KHiP/UiIj/8bOx//rCv//3vbv/9ru4//O3s//xuLX/7q6e/+ej
|
||||
hf/npIn/7bCp/+Otp/+KsX3/ULdm/1WjWv+7oYz/5KWk/9uenP+4gH79glJRzVYuLlQgCAkGAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAA8HBwQVy4uS3FBQaCPV1fjsG5v/cmAgf/ShYb/0YKD/85+f//LeXr/2I2M//e8uf/1vLn/7rOx/+2y
|
||||
sP/lpJX/5qFY/+6xXP/djS3/35h9/86gl/9SwW7/Nd90/0WxXP+vlH//wYSE/49cW+VlOTmBQR4eHAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAGk7OhqIWFd8oG5u8J5qav+eX2D/tmts/8Z0df/KdHX/yXJz/92T
|
||||
k//3vLn/7LGu/+Snpf/dm5L/4Z1q/+61dP/fmmX/15WM/9eYlv/Bm43/r6uR/6uNgP+WYWDtbkBAnUwn
|
||||
JzQVAQECAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAiFJSBnhC
|
||||
QgpqNDQJWSUlB08dHQdfKisKfENDFJJWViinbGtRvYOCjtOcm8/pt7X157y6/7eOjfhxRUW7aTk5m4RK
|
||||
StehWlr6uGdo/8Zwcf/dkpH/8bSx/+OnpP/YmZj/1ZWT/9ealP/Vl5X/0JCP/8eIhv+zdnb/lFtc6nA/
|
||||
QKRSKio/JQwNBgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AADTn6AB2qioDMuUlCHBhYU8voCAWcCBgXTEhoaLzZGQqdeensngrKvn47Sz/NOop/+yiIfyi2Bgs2k+
|
||||
PlZXKysPAAAAAUYlJRxcMTFYcj4+pYpMTeWmXF3+xnl5/9+Zl//dnJr/z46M/8KCgf+vc3L/ll9e831L
|
||||
S8hlOTl/TigoMy0REQYAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAABzQUIDnmprDriGhifHlpZMzp6eeNCgoZ7On5+2yJqaybuPj9WnfHzVj2RkunVJ
|
||||
SYNbLy8/PRQUCgAAAAAAAAAAAAAAAAAAAAAAAAAAKRUVBU0pKSphNDRtd0BAsotNTd2ZW1vrkVlY4HtJ
|
||||
Sb5lOTmCUysrQTsbGxEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAWCwsA2Y4OA5xQkImdkhIRHhKSll0R0dibUBAWWI2
|
||||
NkNUKCgoOhISDAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMhkZB0km
|
||||
Jh5LJiYsRSEhITATFAsAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD///////8AAP//
|
||||
/////wAA////////AAD///////8AAP///////wAA////////AAD/+H////8AAP/gH////wAA/8Af////
|
||||
AAD/gA////8AAP+AD////wAA/wAP////AAD/AA////8AAP4AB////wAA/gAH////AAD8AAf///8AAPwA
|
||||
B////wAA/AAH////AAD8AAf///8AAPgAB////wAA+AAH//4HAAD4AAP/8AEAAPgAAf/AAQAA8AAA/wAA
|
||||
AADwAAAAAAAAAPAAAAAAAAAA8AAAAAAAAADwAAAAAAEAAPAAAAAAAQAA8AAAAAADAADwAAAAAAcAAPAA
|
||||
AAAADwAA+AAAAAAfAAD4AAAAAD8AAPwAAAAAfwAA/gAAAAD/AAD/gAAAA/8AAP/gAAAH/wAAgAAAAB//
|
||||
AAAAAAAAf/8AAAAD4AP//wAAgB/8H///AAD///////8AAP///////wAA////////AAD///////8AAP//
|
||||
/////wAA////////AAAoAAAAIAAAAEAAAAABACAAAAAAAIAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAYAAAAZAAAAGQAAAAYAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAARCQkYOh8fb0ooKK80HByiCQUFTAAAAAkAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAIhERFmA2Np2ITUz3lVNT/4dLS/5IKCi9AAAALwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAANjODiBllhY+61kZP+vY2P/pV5e/3xHRvEhEhJfAAAAAgAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAASSgoN41VVeS6bW3/xW9w/8dwcf+9bG3/klZW/jogIIEAAAAGAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAZ1RkWcs2xs/8dxcv/HcHH/x3Bx/8Zwcf+iYWH/SSkpmAAA
|
||||
AAsAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAUC0tMZtgX+fGcnP/x3Bx/8dwcf/HcHH/x3Fy/61q
|
||||
av9UMTGqAAAAEQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABxRER1tm9v/8hxcv/HcHH/x3Bx/8dw
|
||||
cf/HcnP/tnRz/185OboAAAAZAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABwAACIxXV7TEdHT/yHJz/8l1
|
||||
dv/Kd3j/ynd4/8p4eP/Bf37/bURDywAAACQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABNKysjo2Zm4Mt4
|
||||
ef/NfH3/z4GC/9GFhf/RhYb/0YWF/82Mi/9+UVHeCAICOwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIAAAAJAAAACwAAAAUAAAAAAAAAAAAAAAAAAAAAAAAAAGc+
|
||||
Pkm1c3P30IGC/9OJiv/XkZL/2ZaW/9mWl//YlJX/2JmY/5hnZfMeEBBrAAAABwAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAA0FAgItHhAQWzAbG4IqFxeHDQcHWwAAABkAAAAAAAAAAAAA
|
||||
AAAAAAAAek1MdMN/f//VjI3/2piZ/9+io//hqKn/4qmp/+Clpf/jpqT/wImH/04xMLwAAAA6AAAABQAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAABEbDg5GRygokW5CQs+MVlbxnGJh/JdfXvxnPz7hHA8PbgAA
|
||||
AAwAAAAAAAAAAAAAAACMW1qbz4qK/9qXl//gpqb/5rKz/+q6u//rvLz/6La2/+qxr//epKL/j1lZ+DUc
|
||||
HLACAQFPAAAAHQAAAA8AAAAPAAAAEwAAACIbDg5MVDExnYZUU+SpbWz+uXl4/7x+fP/AgoD/xoeF/72A
|
||||
f/9fOzu1AAAAHAAAAAAAAAAAAAAABJhkZK/VkZH/3Z+g/+axsf/twMD/8svL//LNzf/vxcX/8Lq4/+6z
|
||||
sf+1dHP/j1VU+144N9g7IiKqMhwclDcfH5RGKSmiYTw7v4tZWOiydXT+woOC/8aKiP/Ol5X/2aWj/9ui
|
||||
of/cnpz/2pyb/35TUrgAAAAVAAAAAAAAAAAAAAAFmmVkstaTk//hpaX/7Lm6//TLy//419f/+NnZ//TP
|
||||
z//1wb//9Lq3/8aGhP+1dHP/s3Rz/6xwb/+pb27+rnNy/7Z7ev/BhIL/yY2L/8+WlP/apqT/5be2/+vB
|
||||
v//rvrz/6bKw/+uvrf/Um5n/bUVEgAAAAAMAAAAAAAAAAAAAAAOTXV2q1ZGR/9CYmP+dfX7/o4yM/9e8
|
||||
vP/z0tL/zLOz/+u8u//5v7z/1peV/8uLif/Ki4r/yoyL/86Ukv/TnJv/2qSi/+Gtq//nuLb/7cPB//DJ
|
||||
x//xxsT/8b+9//G6t//zubf/77az/6d1dM89Hx8lAAAAAAAAAAAAAAAAAAAAAIJOTojNiIn/jGlp/01O
|
||||
Tv9UVlb/dnNz/7uhof+Pfn7/xJ+e//zCv//lqKb/3J2b/+Chnv/hpaT/7Ly5/+vHxv/MxMn/0MjN//LK
|
||||
yf/1x8X/9sLA//a/vP/3vrv/+L+8//S7uP+5hoXhYTo5RwAAAAAAAAAAAAAAAAAAAAAAAAAAaTs7RrVz
|
||||
dPKmfn7/cXJx/4SGhv97fX3/b2Zm/516ev+7kJD/+sG+//C2s//lqqr/rpbA/3aB2/+ql83/tMHK/2jc
|
||||
9P9OzOz/2r3B//q/vP/3vrv/9ry6//a8uf/ss7D/tYGA32c+Pk0AAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAvEhIHg01Njbp9fvrCn5//nI+P/4R7ev+fgID/2Jyd/9ybnP/ytrT/+b+8/+ewtf+Mld3/ZI36/5eI
|
||||
zv/Ttrn/sNLc/6/Czv/stLT/8re0/++0sf/tsq//2qCe/6Rxb8phODg+AAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAABCIB8MeUZGbqRpata8gYH8x4mJ/9eTk//YkpP/04qL/+Cbmv/5wL3/9726/+Sw
|
||||
t//Zrrn/56qY/+2smf/lr6n/nLWJ/4Gtdf/Pppn/3qGf/7yEg/KJWViYTyoqIAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQh0dGXJAQGOXXl7NtnR1/8V7fP/MfH3/znt8/+il
|
||||
o//0urj/7LCu/+Whg//rq13/35VX/9Kek/9yvXz/ZbNv/6iCdfqYY2O/aj4+TCUJCgcAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAACcamsBjFRVB4FERAh9PT0JjU1ND6VnZx+/hINF0JqZiNOjoty0iIf2hFBQw5lX
|
||||
V8+wY2P4xXR0/+aioP/oq6j/2pqT/92fif/Vlor/yYqJ/7N8efiVZmPGdERFYkEfHxIAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAALiFhgXFkJEdx5CQSMqSknbNlZWbz5uaws2cnOXBlJPnqH18r4dc
|
||||
XFFULy8OSCUlFm07O0+FSUmeoV1d3sF9fPrGhoX/snZ295xkZNiFUlKbbD4+T0UdHxIAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAc0JDA5FgYRKdbm46onR0Zp9ycnuWampzhFlZVmY6
|
||||
OikvDAwHAAAAAAAAAAAAAAAAAAAAAB0ODgRULCwhbjo7UXhERGVrPDxHTCYmGxAAAQMAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEAAAACAAAAAgAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAP//////////////////////D////gf///wH///4A///+AP///AD///wA///8AP//+AD
|
||||
///gA//D4AH+AeAA+ADgAAAAwAAAAMAAAADAAAAB4AAAA+AAAAfgAAAP8AAAH/wAAD8AAAD/AAAD/wB4
|
||||
D//H////////////////////KAAAABgAAAAwAAAAAQAgAAAAAABgCQAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAABMAAAAtAAAAEQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEAgIO1cwMM1qOjrsHhAQmwAA
|
||||
ABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAATCgogfUhI6ahgYP6lXV3+f0hI9wIBAT0AAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAsGBgFPLy6kuW1t/sZv
|
||||
cP/Gb3D/oF9e/hMKCmgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAB4QECynZmX7xnBx/sdwcf/HcHH/tG1t/h8REYMAAAABAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFAx
|
||||
MIzFc3T+xm9w/sdwcf7HcHH+vHR0/jAcHJkAAAACAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGQ4OAYVSUtfIcnP/yXZ3/st5ef/LeHn/xoB//kQq
|
||||
KrEAAAAGAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAJxYWGrNvb/7Nfn//0oeI/tSNjf/UjI3/1ZOS/mE+PtQAAAAXAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAIAAAARAAAALQAAADUAAAARAAAAAAAAAAAAAAAAQyYmUM6Ghv/Wj5D/3J2e/uCl
|
||||
pf/fpKT/4KOi/qRycPkHBARlAAAABQAAAAAAAAAAAAAAAAAAAAAAAAADAQAAJh8REYBYNTXMhVJR8XxM
|
||||
TO8gEhKeAAAAEAAAAAAAAAAAbUVEe9aPkP7doKD+5rKz/uu9vv7rvLz+6rKx/tqfnf5iNzfnCAQEcwAA
|
||||
ACoAAAAbAAAAIQIBATorGBiQhFNT67Z3dv68fn3+wYSD/siKiP6aZmX2AQAAKQAAAAAAAAAAd05Ni9eT
|
||||
lP/jq6z/7cLC/vXS0v/zz9D/8b69/uyxrv+samr/l15d+2tDQ+NkPz7bdkxL451nZve+gYD/yY2M/tWg
|
||||
n//jtrT/46+t/uOmpP+mdHPwBQMDFAAAAAAAAAAAdkpJh9iUlf7Hl5f+tJeX/uzOzv7lyMj+57y6/vS6
|
||||
t/7HhoX+xYaE/saJh/7MkpD+0ZmY/tejov7mt7X+7cXD/vDFxP7vvLr+8Le0/u2zsf5PMzOMDQcHAQAA
|
||||
AAAAAAAAYTg4X9OOj/9aUlL/YGJi/nh2dv+skJD/qo2M/vnAvf/dn53/4KKg/+Cnp/7vxsT/u8PM/sHI
|
||||
0P/1xsT/9sG+/ve+u//3vrv/87q3/ntVVLkkFhYIAAAAAAAAAAAAAAAAVC8wD6BkZOWjhIT/jo6O/n1+
|
||||
fv+eenv/xpGR/vi/vP/wtbL/mZPP/0Z2+v69nrr/gd/x/nfD2v/2vLr/9Lq3/vG2tP/lq6j/elJRrjQg
|
||||
IAoAAAAAAAAAAAAAAAAAAAAAAAAAAGc7OyeOWVnGv4eH/r2Fhf7YlZb+1Y6P/uinpv74v7z+3ay3/seo
|
||||
w/7srZ/+7LGv/qmyjv63qI7+5Kel/r2GhPZ1S0p1QCcmAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAd0pKOpReXtKxb3D/yXl6/sx5ev/ws7D/6q6s/+Ked/7npFb/2ZiP/ny7gP+OjW/9h1dWr2I7
|
||||
OiMAAAAAAAAAAAAAAAAAAAAAAAAAALSCggSqcXIbo2dnN61xcVS/h4eIzp2c2cKWle2OY2OGbz4+Y4xN
|
||||
Tr6zaWn84Jyb/9aXlv7Ji4r/p25t9INTUqZlPDw3AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAJJg
|
||||
YASjcnMorH9/a6h7e4yabm6Df1NTU3VKSgwAAAAAAAAAAAAAAABgNDQgcj8/bntHR4ZnPDxTVTExDQAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAP///wD///8A////APx//wD4P/8A8D//AOA//wDgH/8A4B//AMAf
|
||||
/wDAH8EAwA8AAMAAAADAAAAAwAAAAMAAAQDAAAMA4AAHAPgAHwAAAH8AAcH/AP///wD///8A////ACgA
|
||||
AAAQAAAAIAAAAAEAIAAAAAAAQAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADQc
|
||||
HA5LKSlUNBwcSAAAAAUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABsO
|
||||
DgV/SkqHm1hY+X5HR90tGRkuAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAB4SEhCr2Zm7sZwcf+oYWL5UC8vUwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAACnl9fnMRwcf/IcXL/tmxs/mI8PGgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAa0NCGbRsbdbMenv/zn5//8R9ff9ySkmCAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAAA
|
||||
AAkAAAAAAAAAAItYWDvFfn/y2ZWW/92fn//anJv/jWFgvwAAAB0AAAAAAAAAAAAAAAIzHBwiYjs7a3pM
|
||||
S6pqQkKjLBoaMwAAAACeZ2dZ05KS/em0tP/vxMT/77u6/8CHhfpmPDyvRysqYlExMV1ySEiGnWdn07qB
|
||||
gPzLkI//w4iG/HJLS3YAAAAAomloXsyRkf/DoKD/48bG/+jAv//hpKL/vX17/7h/fPu/iYj7z5qZ/+Gw
|
||||
rv/rvLr/77q3/9ScmuR9U1I+AAAAAJZbWz2ndnbxdG9v/4yCgv+4lJP/77Wy/86erP+6nsH/tsXR/8PH
|
||||
0P/4wsD/9b26/+Cppu2peXdiAAAAAQAAAABYKCgHn2lqe6eCguSsgoL90pKS//Cxrv/TrcP/s5y+/8i3
|
||||
s/+quab/26mh/82UktSgbm1TBAAAAwAAAACud3cEvYGBC7N6ehyyfHtyt39+3bNub9vLgYH05qak/+Kg
|
||||
g//OlH39jZR04Zd0aYmDT1EiAAAAAAAAAAAAAAAAr3t7D7aCgki5h4Z8uImJgah+fUltPz8ajU1ORq1s
|
||||
bI6vdHOgm2RkaYxJUiZgCygCAAAAAAAAAAAAAAAAAAAAAGo9PQF9UVEHcEdHCTodHQIAAAAAAAAAAAAA
|
||||
AAAAAAABAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//8AAP//AADh/wAAwf8AAMH/
|
||||
AACB/wAAgfkAAIDAAACAAAAAgAAAAIAAAACAAQAAAAcAAAAPAAAOfwAA//8AAA==
|
||||
</value>
|
||||
</data>
|
||||
</root>
|
|
@ -261,6 +261,9 @@
|
|||
<Compile Include="Computers\SinclairSpectrum\Hardware\Abstraction\IFDDHost.cs" />
|
||||
<Compile Include="Computers\SinclairSpectrum\Hardware\SoundOuput\AY38912.cs" />
|
||||
<Compile Include="Computers\SinclairSpectrum\Hardware\SoundOuput\Beeper.cs" />
|
||||
<Compile Include="Computers\SinclairSpectrum\Machine\CPUMonitor.cs" />
|
||||
<Compile Include="Computers\SinclairSpectrum\Machine\ULA.cs" />
|
||||
<Compile Include="Computers\SinclairSpectrum\Machine\ZXSpectrum128KPlus2a\ZX128Plus2a.Screen.cs" />
|
||||
<Compile Include="Computers\SinclairSpectrum\Media\Disk\FloppyDisk.cs" />
|
||||
<Compile Include="Computers\SinclairSpectrum\Hardware\Abstraction\IJoystick.cs" />
|
||||
<Compile Include="Computers\SinclairSpectrum\Hardware\Abstraction\IPortIODevice.cs" />
|
||||
|
@ -1434,6 +1437,8 @@
|
|||
<ItemGroup>
|
||||
<Compile Include="Computers\SinclairSpectrum\Hardware\Input\StandardKeyboard.cs" />
|
||||
<Compile Include="Computers\SinclairSpectrum\Machine\ZXSpectrum48K\ZX48.Port.cs" />
|
||||
<Compile Include="Computers\SinclairSpectrum\Machine\ZXSpectrum48K\ZX48.Screen.cs" />
|
||||
<Compile Include="Computers\SinclairSpectrum\Machine\ZXSpectrum128K\ZX128.Screen.cs" />
|
||||
<None Include="Computers\SinclairSpectrum\readme.md" />
|
||||
<Compile Include="Computers\SinclairSpectrum\Machine\SpectrumBase.Media.cs" />
|
||||
<None Include="Consoles\Atari\docs\stella.pdf" />
|
||||
|
|
|
@ -18,15 +18,19 @@ namespace BizHawk.Emulation.Cores.Components.Z80A
|
|||
|
||||
// variables for executing instructions
|
||||
public int instr_pntr = 0;
|
||||
public int bus_pntr = 0;
|
||||
public int mem_pntr = 0;
|
||||
public ushort instr_swap;
|
||||
public ushort[] cur_instr;
|
||||
public int opcode;
|
||||
public ushort[] BUSRQ;
|
||||
public ushort[] MEMRQ;
|
||||
public byte opcode;
|
||||
public bool NO_prefix, CB_prefix, IX_prefix, EXTD_prefix, IY_prefix, IXCB_prefix, IYCB_prefix;
|
||||
public bool IXCB_prefetch, IYCB_prefetch; // value is fetched before opcode
|
||||
public bool halted;
|
||||
public ushort PF;
|
||||
|
||||
public void FetchInstruction(byte opcode)
|
||||
public void FetchInstruction()
|
||||
{
|
||||
if (NO_prefix)
|
||||
{
|
||||
|
@ -102,7 +106,7 @@ namespace BizHawk.Emulation.Cores.Components.Z80A
|
|||
case 0x43: REG_OP(TR, B, E); break; // LD B, E
|
||||
case 0x44: REG_OP(TR, B, H); break; // LD B, H
|
||||
case 0x45: REG_OP(TR, B, L); break; // LD B, L
|
||||
case 0x46: REG_OP_IND(TR, B, L, H); break; // LD B, (HL)
|
||||
case 0x46: REG_OP_IND_HL(TR, B); break; // LD B, (HL)
|
||||
case 0x47: REG_OP(TR, B, A); break; // LD B, A
|
||||
case 0x48: REG_OP(TR, C, B); break; // LD C, B
|
||||
case 0x49: REG_OP(TR, C, C); break; // LD C, C
|
||||
|
@ -110,7 +114,7 @@ namespace BizHawk.Emulation.Cores.Components.Z80A
|
|||
case 0x4B: REG_OP(TR, C, E); break; // LD C, E
|
||||
case 0x4C: REG_OP(TR, C, H); break; // LD C, H
|
||||
case 0x4D: REG_OP(TR, C, L); break; // LD C, L
|
||||
case 0x4E: REG_OP_IND(TR, C, L, H); break; // LD C, (HL)
|
||||
case 0x4E: REG_OP_IND_HL(TR, C); break; // LD C, (HL)
|
||||
case 0x4F: REG_OP(TR, C, A); break; // LD C, A
|
||||
case 0x50: REG_OP(TR, D, B); break; // LD D, B
|
||||
case 0x51: REG_OP(TR, D, C); break; // LD D, C
|
||||
|
@ -118,7 +122,7 @@ namespace BizHawk.Emulation.Cores.Components.Z80A
|
|||
case 0x53: REG_OP(TR, D, E); break; // LD D, E
|
||||
case 0x54: REG_OP(TR, D, H); break; // LD D, H
|
||||
case 0x55: REG_OP(TR, D, L); break; // LD D, L
|
||||
case 0x56: REG_OP_IND(TR, D, L, H); break; // LD D, (HL)
|
||||
case 0x56: REG_OP_IND_HL(TR, D); break; // LD D, (HL)
|
||||
case 0x57: REG_OP(TR, D, A); break; // LD D, A
|
||||
case 0x58: REG_OP(TR, E, B); break; // LD E, B
|
||||
case 0x59: REG_OP(TR, E, C); break; // LD E, C
|
||||
|
@ -126,7 +130,7 @@ namespace BizHawk.Emulation.Cores.Components.Z80A
|
|||
case 0x5B: REG_OP(TR, E, E); break; // LD E, E
|
||||
case 0x5C: REG_OP(TR, E, H); break; // LD E, H
|
||||
case 0x5D: REG_OP(TR, E, L); break; // LD E, L
|
||||
case 0x5E: REG_OP_IND(TR, E, L, H); break; // LD E, (HL)
|
||||
case 0x5E: REG_OP_IND_HL(TR, E); break; // LD E, (HL)
|
||||
case 0x5F: REG_OP(TR, E, A); break; // LD E, A
|
||||
case 0x60: REG_OP(TR, H, B); break; // LD H, B
|
||||
case 0x61: REG_OP(TR, H, C); break; // LD H, C
|
||||
|
@ -134,7 +138,7 @@ namespace BizHawk.Emulation.Cores.Components.Z80A
|
|||
case 0x63: REG_OP(TR, H, E); break; // LD H, E
|
||||
case 0x64: REG_OP(TR, H, H); break; // LD H, H
|
||||
case 0x65: REG_OP(TR, H, L); break; // LD H, L
|
||||
case 0x66: REG_OP_IND(TR, H, L, H); break; // LD H, (HL)
|
||||
case 0x66: REG_OP_IND_HL(TR, H); break; // LD H, (HL)
|
||||
case 0x67: REG_OP(TR, H, A); break; // LD H, A
|
||||
case 0x68: REG_OP(TR, L, B); break; // LD L, B
|
||||
case 0x69: REG_OP(TR, L, C); break; // LD L, C
|
||||
|
@ -142,23 +146,23 @@ namespace BizHawk.Emulation.Cores.Components.Z80A
|
|||
case 0x6B: REG_OP(TR, L, E); break; // LD L, E
|
||||
case 0x6C: REG_OP(TR, L, H); break; // LD L, H
|
||||
case 0x6D: REG_OP(TR, L, L); break; // LD L, L
|
||||
case 0x6E: REG_OP_IND(TR, L, L, H); break; // LD L, (HL)
|
||||
case 0x6E: REG_OP_IND_HL(TR, L); break; // LD L, (HL)
|
||||
case 0x6F: REG_OP(TR, L, A); break; // LD L, A
|
||||
case 0x70: LD_8_IND(L, H, B); break; // LD (HL), B
|
||||
case 0x71: LD_8_IND(L, H, C); break; // LD (HL), C
|
||||
case 0x72: LD_8_IND(L, H, D); break; // LD (HL), D
|
||||
case 0x73: LD_8_IND(L, H, E); break; // LD (HL), E
|
||||
case 0x74: LD_8_IND(L, H, H); break; // LD (HL), H
|
||||
case 0x75: LD_8_IND(L, H, L); break; // LD (HL), L
|
||||
case 0x70: LD_8_IND_HL(B); break; // LD (HL), B
|
||||
case 0x71: LD_8_IND_HL(C); break; // LD (HL), C
|
||||
case 0x72: LD_8_IND_HL(D); break; // LD (HL), D
|
||||
case 0x73: LD_8_IND_HL(E); break; // LD (HL), E
|
||||
case 0x74: LD_8_IND_HL(H); break; // LD (HL), H
|
||||
case 0x75: LD_8_IND_HL(L); break; // LD (HL), L
|
||||
case 0x76: HALT_(); break; // HALT
|
||||
case 0x77: LD_8_IND(L, H, A); break; // LD (HL), A
|
||||
case 0x77: LD_8_IND_HL( A); break; // LD (HL), A
|
||||
case 0x78: REG_OP(TR, A, B); break; // LD A, B
|
||||
case 0x79: REG_OP(TR, A, C); break; // LD A, C
|
||||
case 0x7A: REG_OP(TR, A, D); break; // LD A, D
|
||||
case 0x7B: REG_OP(TR, A, E); break; // LD A, E
|
||||
case 0x7C: REG_OP(TR, A, H); break; // LD A, H
|
||||
case 0x7D: REG_OP(TR, A, L); break; // LD A, L
|
||||
case 0x7E: REG_OP_IND(TR, A, L, H); break; // LD A, (HL)
|
||||
case 0x7E: REG_OP_IND_HL(TR, A); break; // LD A, (HL)
|
||||
case 0x7F: REG_OP(TR, A, A); break; // LD A, A
|
||||
case 0x80: REG_OP(ADD8, A, B); break; // ADD A, B
|
||||
case 0x81: REG_OP(ADD8, A, C); break; // ADD A, C
|
||||
|
@ -856,7 +860,7 @@ namespace BizHawk.Emulation.Cores.Components.Z80A
|
|||
case 0xC8: RET_COND(FlagZ); break; // RET Z
|
||||
case 0xC9: RET_(); break; // RET
|
||||
case 0xCA: JP_COND(FlagZ); break; // JP Z
|
||||
case 0xCB: PREFIX_(IXCBpre); break; // PREFIX IXCB
|
||||
case 0xCB: PREFETCH_(IXCBpre); break; // PREFIX IXCB
|
||||
case 0xCC: CALL_COND(FlagZ); break; // CALL Z
|
||||
case 0xCD: CALL_COND(true); break; // CALL
|
||||
case 0xCE: REG_OP_IND_INC(ADC8, A, PCl, PCh); break; // ADC A, n
|
||||
|
@ -1121,7 +1125,7 @@ namespace BizHawk.Emulation.Cores.Components.Z80A
|
|||
case 0xC8: RET_COND(FlagZ); break; // RET Z
|
||||
case 0xC9: RET_(); break; // RET
|
||||
case 0xCA: JP_COND(FlagZ); break; // JP Z
|
||||
case 0xCB: PREFIX_(IYCBpre); break; // PREFIy IyCB
|
||||
case 0xCB: PREFETCH_(IYCBpre); break; // PREFIX IyCB
|
||||
case 0xCC: CALL_COND(FlagZ); break; // CALL Z
|
||||
case 0xCD: CALL_COND(true); break; // CALL
|
||||
case 0xCE: REG_OP_IND_INC(ADC8, A, PCl, PCh); break; // ADC A, n
|
||||
|
@ -1181,24 +1185,6 @@ namespace BizHawk.Emulation.Cores.Components.Z80A
|
|||
// the first byte fetched is the prefetch value to use with the instruction
|
||||
// we pick Ix or Iy here, the indexed value is stored in WZ
|
||||
// In this way, we don't need to pass them as an argument to the I_Funcs.
|
||||
if (IXCB_prefetch)
|
||||
{
|
||||
IXCB_prefetch = false;
|
||||
PF = opcode;
|
||||
Regs[ALU] = PF;
|
||||
PREFETCH_(Ixl, Ixh);
|
||||
return;
|
||||
}
|
||||
|
||||
if (IYCB_prefetch)
|
||||
{
|
||||
IYCB_prefetch = false;
|
||||
PF = opcode;
|
||||
Regs[ALU] = PF;
|
||||
PREFETCH_(Iyl, Iyh);
|
||||
return;
|
||||
}
|
||||
|
||||
IXCB_prefix = false;
|
||||
IYCB_prefix = false;
|
||||
NO_prefix = true;
|
||||
|
|
|
@ -33,17 +33,20 @@ namespace BizHawk.Emulation.Cores.Components.Z80A
|
|||
private void NMI_()
|
||||
{
|
||||
cur_instr = new ushort[]
|
||||
{IDLE,
|
||||
DEC16, SPl, SPh,
|
||||
WR, SPl, SPh, PCh,
|
||||
IDLE,
|
||||
DEC16, SPl, SPh,
|
||||
WR, SPl, SPh, PCl,
|
||||
IDLE,
|
||||
ASGN, PCl, 0x66,
|
||||
ASGN, PCh, 0,
|
||||
IDLE,
|
||||
{DEC16, SPl, SPh,
|
||||
TR, ALU, PCl,
|
||||
WAIT,
|
||||
WR_DEC, SPl, SPh, PCh,
|
||||
TR16, PCl, PCh, NMI_V, ZERO,
|
||||
WAIT,
|
||||
WR, SPl, SPh, ALU,
|
||||
IDLE,
|
||||
WAIT,
|
||||
OP_F,
|
||||
OP };
|
||||
|
||||
BUSRQ = new ushort[] { 0, SPh, 0, 0, SPh, 0, 0, PCh, 0, 0, 0 };
|
||||
MEMRQ = new ushort[] { 0, SPh, 0, 0, SPh, 0, 0, PCh, 0, 0, 0 };
|
||||
}
|
||||
|
||||
// Mode 0 interrupts only take effect if a CALL or RST is on the data bus
|
||||
|
@ -55,56 +58,65 @@ namespace BizHawk.Emulation.Cores.Components.Z80A
|
|||
{
|
||||
cur_instr = new ushort[]
|
||||
{IDLE,
|
||||
WAIT,
|
||||
RD_INC, ALU, PCl, PCh,
|
||||
IDLE,
|
||||
RD, ALU, PCl, PCh,
|
||||
IDLE,
|
||||
INC16, PCl, PCh,
|
||||
IDLE,
|
||||
WAIT,
|
||||
OP_F,
|
||||
OP };
|
||||
|
||||
BUSRQ = new ushort[] { PCh, 0, 0, PCh, 0, 0, 0 };
|
||||
MEMRQ = new ushort[] { PCh, 0, 0, PCh, 0, 0, 0 };
|
||||
}
|
||||
|
||||
// Just jump to $0038
|
||||
private void INTERRUPT_1()
|
||||
{
|
||||
cur_instr = new ushort[]
|
||||
{DEC16, SPl, SPh,
|
||||
IDLE,
|
||||
WR, SPl, SPh, PCh,
|
||||
IDLE,
|
||||
{IDLE,
|
||||
TR, ALU, PCl,
|
||||
DEC16, SPl, SPh,
|
||||
IDLE,
|
||||
WR, SPl, SPh, PCl,
|
||||
IDLE,
|
||||
ASGN, PCl, 0x38,
|
||||
IDLE,
|
||||
ASGN, PCh, 0,
|
||||
WAIT,
|
||||
WR_DEC, SPl, SPh, PCh,
|
||||
TR16, PCl, PCh, IRQ_V, ZERO,
|
||||
WAIT,
|
||||
WR, SPl, SPh, ALU,
|
||||
IDLE,
|
||||
WAIT,
|
||||
OP_F,
|
||||
OP };
|
||||
|
||||
BUSRQ = new ushort[] { I, 0, 0, SPh, 0, 0, SPh, 0, 0, PCh, 0, 0, 0 };
|
||||
MEMRQ = new ushort[] { I, 0, 0, SPh, 0, 0, SPh, 0, 0, PCh, 0, 0, 0 };
|
||||
}
|
||||
|
||||
// Interrupt mode 2 uses the I vector combined with a byte on the data bus
|
||||
private void INTERRUPT_2()
|
||||
{
|
||||
cur_instr = new ushort[]
|
||||
{IDLE,
|
||||
IDLE,
|
||||
FTCH_DB,
|
||||
TR, Z, DB,
|
||||
TR, W, I,
|
||||
{FTCH_DB,
|
||||
IDLE,
|
||||
DEC16, SPl, SPh,
|
||||
WR, SPl, SPh, PCh,
|
||||
TR16, Z, W, DB, I,
|
||||
WAIT,
|
||||
WR_DEC, SPl, SPh, PCh,
|
||||
IDLE,
|
||||
DEC16, SPl, SPh,
|
||||
WR, SPl, SPh, PCl,
|
||||
WAIT,
|
||||
WR, SPl, SPh, PCl,
|
||||
IDLE,
|
||||
RD, PCl, Z, W,
|
||||
INC16, Z, W,
|
||||
WAIT,
|
||||
RD_INC, PCl, Z, W,
|
||||
IDLE,
|
||||
WAIT,
|
||||
RD, PCh, Z, W,
|
||||
IDLE,
|
||||
IDLE,
|
||||
WAIT,
|
||||
OP_F,
|
||||
OP };
|
||||
|
||||
BUSRQ = new ushort[] { I, 0, 0, SPh, 0, 0, SPh, 0, 0, W, 0, 0, W, 0 ,0 ,PCh, 0, 0, 0 };
|
||||
MEMRQ = new ushort[] { I, 0, 0, SPh, 0, 0, SPh, 0, 0, W, 0, 0, W, 0, 0, PCh, 0, 0, 0 };
|
||||
}
|
||||
|
||||
private static ushort[] INT_vectors = new ushort[] {0x40, 0x48, 0x50, 0x58, 0x60};
|
||||
|
|
|
@ -11,10 +11,11 @@ namespace BizHawk.Emulation.Cores.Components.Z80A
|
|||
Regs[DB] = Regs[dest];
|
||||
}
|
||||
|
||||
public void I_Read_Func(ushort dest, ushort src_l, ushort src_h, ushort inc)
|
||||
public void Read_INC_Func(ushort dest, ushort src_l, ushort src_h)
|
||||
{
|
||||
Regs[dest] = ReadMemory((ushort)((Regs[src_l] | (Regs[src_h] << 8)) + inc));
|
||||
Regs[dest] = ReadMemory((ushort)(Regs[src_l] | (Regs[src_h]) << 8));
|
||||
Regs[DB] = Regs[dest];
|
||||
INC16_Func(src_l, src_h);
|
||||
}
|
||||
|
||||
public void Write_Func(ushort dest_l, ushort dest_h, ushort src)
|
||||
|
@ -23,10 +24,18 @@ namespace BizHawk.Emulation.Cores.Components.Z80A
|
|||
WriteMemory((ushort)(Regs[dest_l] | (Regs[dest_h] << 8)), (byte)Regs[src]);
|
||||
}
|
||||
|
||||
public void I_Write_Func(ushort dest_l, ushort dest_h, ushort inc, ushort src)
|
||||
public void Write_INC_Func(ushort dest_l, ushort dest_h, ushort src)
|
||||
{
|
||||
Regs[DB] = Regs[src];
|
||||
WriteMemory((ushort)((Regs[dest_l] | (Regs[dest_h] << 8)) + inc), (byte)Regs[src]);
|
||||
WriteMemory((ushort)(Regs[dest_l] | (Regs[dest_h] << 8)), (byte)Regs[src]);
|
||||
INC16_Func(dest_l, dest_h);
|
||||
}
|
||||
|
||||
public void Write_DEC_Func(ushort dest_l, ushort dest_h, ushort src)
|
||||
{
|
||||
Regs[DB] = Regs[src];
|
||||
WriteMemory((ushort)(Regs[dest_l] | (Regs[dest_h] << 8)), (byte)Regs[src]);
|
||||
DEC16_Func(dest_l, dest_h);
|
||||
}
|
||||
|
||||
public void OUT_Func(ushort dest_l, ushort dest_h, ushort src)
|
||||
|
@ -748,7 +757,7 @@ namespace BizHawk.Emulation.Cores.Components.Z80A
|
|||
FlagZ = Regs[A] == 0;
|
||||
FlagS = Regs[A] > 127;
|
||||
FlagP = iff2;
|
||||
Flag5 = (Regs[A] & 0x02) != 0;
|
||||
Flag5 = (Regs[A] & 0x20) != 0;
|
||||
Flag3 = (Regs[A] & 0x08) != 0;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -40,10 +40,25 @@ namespace BizHawk.Emulation.Cores.Components.Z80A
|
|||
public ushort H_s = 30;
|
||||
public ushort L_s = 31;
|
||||
public ushort DB = 32;
|
||||
public ushort scratch = 33;
|
||||
public ushort IRQ_V = 34; // IRQ mode 1 vector
|
||||
public ushort NMI_V = 35; // NMI vector
|
||||
|
||||
public ushort[] Regs = new ushort[36];
|
||||
|
||||
public bool FlagI;
|
||||
// IO Contention Constants. Need to distinguish port access and normal memory accesses for zx spectrum
|
||||
public const ushort BIO1 = 100;
|
||||
public const ushort BIO2 = 101;
|
||||
public const ushort BIO3 = 102;
|
||||
public const ushort BIO4 = 103;
|
||||
|
||||
public const ushort WIO1 = 105;
|
||||
public const ushort WIO2 = 106;
|
||||
public const ushort WIO3 = 107;
|
||||
public const ushort WIO4 = 108;
|
||||
|
||||
|
||||
public bool FlagI, FlagI1, FlagI2, FlagI3, FlagI4, FlagI5, FlagI6;
|
||||
|
||||
public bool FlagW; // wait flag, when set to true reads / writes will be delayed
|
||||
|
||||
|
@ -112,6 +127,17 @@ namespace BizHawk.Emulation.Cores.Components.Z80A
|
|||
Regs[i] = 0;
|
||||
}
|
||||
|
||||
// These registers are set as part of the reset process
|
||||
Regs[A] = 0xFF;
|
||||
Regs[F] = 0xFF;
|
||||
Regs[SPl] = 0xFF;
|
||||
Regs[SPh] = 0xFF;
|
||||
|
||||
// the IRQ1 vector is 0x38
|
||||
Regs[IRQ_V] = 0x38;
|
||||
// The NMI vector is constant 0x66
|
||||
Regs[NMI_V] = 0x66;
|
||||
|
||||
FlagI = false;
|
||||
FlagW = false;
|
||||
}
|
||||
|
|
|
@ -10,10 +10,13 @@ namespace BizHawk.Emulation.Cores.Components.Z80A
|
|||
private void NOP_()
|
||||
{
|
||||
cur_instr = new ushort[]
|
||||
{IDLE,
|
||||
IDLE,
|
||||
IDLE,
|
||||
OP };
|
||||
{ IDLE,
|
||||
WAIT,
|
||||
OP_F,
|
||||
OP };
|
||||
|
||||
BUSRQ = new ushort[] { PCh, 0, 0, 0 };
|
||||
MEMRQ = new ushort[] { PCh, 0, 0, 0 };
|
||||
}
|
||||
|
||||
// NOTE: In a real Z80, this operation just flips a switch to choose between 2 registers
|
||||
|
@ -22,18 +25,24 @@ namespace BizHawk.Emulation.Cores.Components.Z80A
|
|||
{
|
||||
cur_instr = new ushort[]
|
||||
{EXCH,
|
||||
IDLE,
|
||||
IDLE,
|
||||
WAIT,
|
||||
OP_F,
|
||||
OP };
|
||||
|
||||
BUSRQ = new ushort[] { PCh, 0, 0, 0 };
|
||||
MEMRQ = new ushort[] { PCh, 0, 0, 0 };
|
||||
}
|
||||
|
||||
private void EXX_()
|
||||
{
|
||||
cur_instr = new ushort[]
|
||||
{EXX,
|
||||
IDLE,
|
||||
IDLE,
|
||||
WAIT,
|
||||
OP_F,
|
||||
OP };
|
||||
|
||||
BUSRQ = new ushort[] { PCh, 0, 0, 0 };
|
||||
MEMRQ = new ushort[] { PCh, 0, 0, 0 };
|
||||
}
|
||||
|
||||
// this exchanges 2 16 bit registers
|
||||
|
@ -41,32 +50,41 @@ namespace BizHawk.Emulation.Cores.Components.Z80A
|
|||
{
|
||||
cur_instr = new ushort[]
|
||||
{EXCH_16, dest_l, dest_h, src_l, src_h,
|
||||
IDLE,
|
||||
IDLE,
|
||||
WAIT,
|
||||
OP_F,
|
||||
OP };
|
||||
|
||||
BUSRQ = new ushort[] { PCh, 0, 0, 0 };
|
||||
MEMRQ = new ushort[] { PCh, 0, 0, 0 };
|
||||
}
|
||||
|
||||
private void INC_16(ushort src_l, ushort src_h)
|
||||
{
|
||||
cur_instr = new ushort[]
|
||||
{IDLE,
|
||||
{INC16, src_l, src_h,
|
||||
IDLE,
|
||||
IDLE,
|
||||
INC16, src_l, src_h,
|
||||
IDLE,
|
||||
WAIT,
|
||||
OP_F,
|
||||
OP };
|
||||
|
||||
BUSRQ = new ushort[] { I, I, PCh, 0, 0, 0};
|
||||
MEMRQ = new ushort[] { 0, 0, PCh, 0, 0, 0 };
|
||||
}
|
||||
|
||||
|
||||
private void DEC_16(ushort src_l, ushort src_h)
|
||||
{
|
||||
cur_instr = new ushort[]
|
||||
{IDLE,
|
||||
IDLE,
|
||||
DEC16, src_l, src_h,
|
||||
{DEC16, src_l, src_h,
|
||||
IDLE,
|
||||
IDLE,
|
||||
WAIT,
|
||||
OP_F,
|
||||
OP };
|
||||
|
||||
BUSRQ = new ushort[] { I, I, PCh, 0, 0, 0};
|
||||
MEMRQ = new ushort[] { 0, 0, PCh, 0, 0, 0 };
|
||||
}
|
||||
|
||||
// this is done in two steps technically, but the flags don't work out using existing funcitons
|
||||
|
@ -74,26 +92,32 @@ namespace BizHawk.Emulation.Cores.Components.Z80A
|
|||
private void ADD_16(ushort dest_l, ushort dest_h, ushort src_l, ushort src_h)
|
||||
{
|
||||
cur_instr = new ushort[]
|
||||
{IDLE,
|
||||
{TR16, Z, W, dest_l, dest_h,
|
||||
IDLE,
|
||||
IDLE,
|
||||
TR16, Z, W, dest_l, dest_h,
|
||||
INC16, Z, W,
|
||||
IDLE,
|
||||
IDLE,
|
||||
ADD16, dest_l, dest_h, src_l, src_h,
|
||||
IDLE,
|
||||
IDLE,
|
||||
IDLE,
|
||||
WAIT,
|
||||
OP_F,
|
||||
OP };
|
||||
|
||||
BUSRQ = new ushort[] { I, I, I, I, I, I, I, PCh, 0, 0, 0 };
|
||||
MEMRQ = new ushort[] { 0, 0, 0, 0, 0, 0, 0, PCh, 0, 0, 0 };
|
||||
}
|
||||
|
||||
private void REG_OP(ushort operation, ushort dest, ushort src)
|
||||
{
|
||||
cur_instr = new ushort[]
|
||||
{operation, dest, src,
|
||||
IDLE,
|
||||
IDLE,
|
||||
WAIT,
|
||||
OP_F,
|
||||
OP };
|
||||
|
||||
BUSRQ = new ushort[] { PCh, 0, 0, 0 };
|
||||
MEMRQ = new ushort[] { PCh, 0, 0, 0 };
|
||||
}
|
||||
|
||||
// Operations using the I and R registers take one T-cycle longer
|
||||
|
@ -101,10 +125,13 @@ namespace BizHawk.Emulation.Cores.Components.Z80A
|
|||
{
|
||||
cur_instr = new ushort[]
|
||||
{operation, dest, src,
|
||||
IDLE,
|
||||
IDLE,
|
||||
SET_FL_IR, dest,
|
||||
WAIT,
|
||||
OP_F,
|
||||
OP };
|
||||
|
||||
BUSRQ = new ushort[] { I, PCh, 0, 0, 0 };
|
||||
MEMRQ = new ushort[] { 0, PCh, 0, 0, 0 };
|
||||
}
|
||||
|
||||
// note: do not use DEC here since no flags are affected by this operation
|
||||
|
@ -114,30 +141,36 @@ namespace BizHawk.Emulation.Cores.Components.Z80A
|
|||
{
|
||||
cur_instr = new ushort[]
|
||||
{IDLE,
|
||||
ASGN, B, (ushort)((Regs[B] - 1) & 0xFF),
|
||||
WAIT,
|
||||
RD_INC, Z, PCl, PCh,
|
||||
IDLE,
|
||||
ASGN, B, (ushort)((Regs[B] - 1) & 0xFF),
|
||||
IDLE,
|
||||
RD, Z, PCl, PCh,
|
||||
IDLE,
|
||||
INC16, PCl, PCh,
|
||||
IDLE,
|
||||
ASGN, W, 0,
|
||||
IDLE,
|
||||
ADDS, PCl, PCh, Z, W,
|
||||
TR16, Z, W, PCl, PCh,
|
||||
IDLE,
|
||||
WAIT,
|
||||
OP_F,
|
||||
OP };
|
||||
|
||||
BUSRQ = new ushort[] { I, PCh, 0, 0, PCh, PCh, PCh, PCh, PCh, PCh, 0, 0, 0 };
|
||||
MEMRQ = new ushort[] { 0, PCh, 0, 0, 0, 0, 0, 0, 0, PCh, 0, 0, 0 };
|
||||
}
|
||||
else
|
||||
{
|
||||
cur_instr = new ushort[]
|
||||
{IDLE,
|
||||
ASGN, B, (ushort)((Regs[B] - 1) & 0xFF),
|
||||
WAIT,
|
||||
RD_INC, ALU, PCl, PCh,
|
||||
IDLE,
|
||||
RD, ALU, PCl, PCh,
|
||||
IDLE,
|
||||
INC16, PCl, PCh,
|
||||
IDLE,
|
||||
WAIT,
|
||||
OP_F,
|
||||
OP };
|
||||
|
||||
BUSRQ = new ushort[] { I, PCh, 0, 0, PCh, 0, 0, 0 };
|
||||
MEMRQ = new ushort[] { 0, PCh, 0, 0, PCh, 0, 0, 0 };
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -148,6 +181,9 @@ namespace BizHawk.Emulation.Cores.Components.Z80A
|
|||
IDLE,
|
||||
IDLE,
|
||||
HALT };
|
||||
|
||||
BUSRQ = new ushort[] { PCh, 0, 0, 0 };
|
||||
MEMRQ = new ushort[] { PCh, 0, 0, 0 };
|
||||
}
|
||||
|
||||
private void JR_COND(bool cond)
|
||||
|
@ -156,28 +192,34 @@ namespace BizHawk.Emulation.Cores.Components.Z80A
|
|||
{
|
||||
cur_instr = new ushort[]
|
||||
{IDLE,
|
||||
IDLE,
|
||||
RD, Z, PCl, PCh,
|
||||
INC16, PCl, PCh,
|
||||
IDLE,
|
||||
WAIT,
|
||||
RD_INC, Z, PCl, PCh,
|
||||
IDLE,
|
||||
ASGN, W, 0,
|
||||
IDLE,
|
||||
ADDS, PCl, PCh, Z, W,
|
||||
TR16, Z, W, PCl, PCh,
|
||||
IDLE,
|
||||
ADDS, PCl, PCh, Z, W,
|
||||
TR16, Z, W, PCl, PCh,
|
||||
WAIT,
|
||||
OP_F,
|
||||
OP };
|
||||
|
||||
BUSRQ = new ushort[] { PCh, 0, 0, PCh, PCh, PCh, PCh, PCh, PCh, 0, 0, 0 };
|
||||
MEMRQ = new ushort[] { PCh, 0, 0, 0, 0, 0, 0, 0, PCh, 0, 0, 0 };
|
||||
}
|
||||
else
|
||||
{
|
||||
cur_instr = new ushort[]
|
||||
{IDLE,
|
||||
WAIT,
|
||||
RD_INC, ALU, PCl, PCh,
|
||||
IDLE,
|
||||
IDLE,
|
||||
RD, ALU, PCl, PCh,
|
||||
IDLE,
|
||||
INC16, PCl, PCh,
|
||||
WAIT,
|
||||
OP_F,
|
||||
OP };
|
||||
|
||||
BUSRQ = new ushort[] { PCh, 0, 0, PCh, 0, 0, 0 };
|
||||
MEMRQ = new ushort[] { PCh, 0, 0, PCh, 0, 0, 0 };
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -187,29 +229,35 @@ namespace BizHawk.Emulation.Cores.Components.Z80A
|
|||
{
|
||||
cur_instr = new ushort[]
|
||||
{IDLE,
|
||||
WAIT,
|
||||
RD_INC, Z, PCl, PCh,
|
||||
IDLE,
|
||||
RD, Z, PCl, PCh,
|
||||
INC16, PCl, PCh,
|
||||
RD, W, PCl, PCh,
|
||||
IDLE,
|
||||
INC16, PCl, PCh,
|
||||
WAIT,
|
||||
RD_INC, W, PCl, PCh,
|
||||
TR16, PCl, PCh, Z, W,
|
||||
IDLE,
|
||||
WAIT,
|
||||
OP_F,
|
||||
OP };
|
||||
|
||||
BUSRQ = new ushort[] { PCh, 0, 0, PCh, 0, 0, W, 0, 0, 0 };
|
||||
MEMRQ = new ushort[] { PCh, 0, 0, PCh, 0, 0, W, 0, 0, 0 };
|
||||
}
|
||||
else
|
||||
{
|
||||
cur_instr = new ushort[]
|
||||
{IDLE,
|
||||
WAIT,
|
||||
RD_INC, Z, PCl, PCh,
|
||||
IDLE,
|
||||
RD, Z, PCl, PCh,
|
||||
INC16, PCl, PCh,
|
||||
IDLE,
|
||||
RD, W, PCl, PCh,
|
||||
INC16, PCl, PCh,
|
||||
IDLE,
|
||||
WAIT,
|
||||
RD_INC, W, PCl, PCh,
|
||||
IDLE,
|
||||
WAIT,
|
||||
OP_F,
|
||||
OP };
|
||||
|
||||
BUSRQ = new ushort[] { PCh, 0, 0, PCh, 0, 0, PCh, 0, 0, 0 };
|
||||
MEMRQ = new ushort[] { PCh, 0, 0, PCh, 0, 0, PCh, 0, 0, 0 };
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -217,45 +265,54 @@ namespace BizHawk.Emulation.Cores.Components.Z80A
|
|||
{
|
||||
cur_instr = new ushort[]
|
||||
{IDLE,
|
||||
WAIT,
|
||||
RD_INC, Z, SPl, SPh,
|
||||
IDLE,
|
||||
RD, Z, SPl, SPh,
|
||||
INC16, SPl, SPh,
|
||||
IDLE,
|
||||
IDLE,
|
||||
RD, W, SPl, SPh,
|
||||
INC16, SPl, SPh,
|
||||
TR16, PCl, PCh, Z, W,
|
||||
WAIT,
|
||||
RD_INC, W, SPl, SPh,
|
||||
TR16, PCl, PCh, Z, W,
|
||||
WAIT,
|
||||
OP_F,
|
||||
OP };
|
||||
|
||||
BUSRQ = new ushort[] { SPh, 0, 0, SPh, 0, 0, W, 0, 0, 0 };
|
||||
MEMRQ = new ushort[] { SPh, 0, 0, SPh, 0, 0, W, 0, 0, 0 };
|
||||
}
|
||||
|
||||
private void RETI_()
|
||||
{
|
||||
cur_instr = new ushort[]
|
||||
{IDLE,
|
||||
WAIT,
|
||||
RD_INC, Z, SPl, SPh,
|
||||
IDLE,
|
||||
RD, Z, SPl, SPh,
|
||||
INC16, SPl, SPh,
|
||||
IDLE,
|
||||
IDLE,
|
||||
RD, W, SPl, SPh,
|
||||
INC16, SPl, SPh,
|
||||
WAIT,
|
||||
RD_INC, W, SPl, SPh,
|
||||
TR16, PCl, PCh, Z, W,
|
||||
WAIT,
|
||||
OP_F,
|
||||
OP };
|
||||
|
||||
BUSRQ = new ushort[] { SPh, 0, 0, SPh, 0, 0, W, 0, 0, 0 };
|
||||
MEMRQ = new ushort[] { SPh, 0, 0, SPh, 0, 0, W, 0, 0, 0 };
|
||||
}
|
||||
|
||||
private void RETN_()
|
||||
{
|
||||
cur_instr = new ushort[]
|
||||
{IDLE,
|
||||
IDLE,
|
||||
RD, Z, SPl, SPh,
|
||||
INC16, SPl, SPh,
|
||||
IDLE,
|
||||
RD, W, SPl, SPh,
|
||||
INC16, SPl, SPh,
|
||||
WAIT,
|
||||
RD_INC, Z, SPl, SPh,
|
||||
EI_RETN,
|
||||
WAIT,
|
||||
RD_INC, W, SPl, SPh,
|
||||
TR16, PCl, PCh, Z, W,
|
||||
WAIT,
|
||||
OP_F,
|
||||
OP };
|
||||
|
||||
BUSRQ = new ushort[] { SPh, 0, 0, SPh, 0, 0, W, 0, 0, 0 };
|
||||
MEMRQ = new ushort[] { SPh, 0, 0, SPh, 0, 0, W, 0, 0, 0 };
|
||||
}
|
||||
|
||||
|
||||
|
@ -266,24 +323,30 @@ namespace BizHawk.Emulation.Cores.Components.Z80A
|
|||
cur_instr = new ushort[]
|
||||
{IDLE,
|
||||
IDLE,
|
||||
RD, Z, SPl, SPh,
|
||||
INC16, SPl, SPh,
|
||||
WAIT,
|
||||
RD_INC, Z, SPl, SPh,
|
||||
IDLE,
|
||||
IDLE,
|
||||
RD, W, SPl, SPh,
|
||||
INC16, SPl, SPh,
|
||||
IDLE,
|
||||
WAIT,
|
||||
RD_INC, W, SPl, SPh,
|
||||
TR16, PCl, PCh, Z, W,
|
||||
WAIT,
|
||||
OP_F,
|
||||
OP };
|
||||
|
||||
BUSRQ = new ushort[] { I, SPh, 0, 0, SPh, 0, 0, W, 0, 0, 0 };
|
||||
MEMRQ = new ushort[] { 0, SPh, 0, 0, SPh, 0, 0, W, 0, 0, 0 };
|
||||
}
|
||||
else
|
||||
{
|
||||
cur_instr = new ushort[]
|
||||
{IDLE,
|
||||
IDLE,
|
||||
IDLE,
|
||||
IDLE,
|
||||
WAIT,
|
||||
OP_F,
|
||||
OP };
|
||||
|
||||
BUSRQ = new ushort[] { I, PCh, 0, 0, 0 };
|
||||
MEMRQ = new ushort[] { 0, PCh, 0, 0, 0 };
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -293,36 +356,42 @@ namespace BizHawk.Emulation.Cores.Components.Z80A
|
|||
{
|
||||
cur_instr = new ushort[]
|
||||
{IDLE,
|
||||
WAIT,
|
||||
RD_INC, Z, PCl, PCh,
|
||||
IDLE,
|
||||
RD, Z, PCl, PCh,
|
||||
INC16, PCl, PCh,
|
||||
IDLE,
|
||||
WAIT,
|
||||
RD, W, PCl, PCh,
|
||||
INC16, PCl, PCh,
|
||||
IDLE,
|
||||
DEC16, SPl, SPh,
|
||||
WAIT,
|
||||
WR_DEC, SPl, SPh, PCh,
|
||||
IDLE,
|
||||
WR, SPl, SPh, PCh,
|
||||
DEC16, SPl, SPh,
|
||||
WAIT,
|
||||
WR, SPl, SPh, PCl,
|
||||
IDLE,
|
||||
TR, PCl, Z,
|
||||
TR, PCh, W,
|
||||
TR16, PCl, PCh, Z, W,
|
||||
WAIT,
|
||||
OP_F,
|
||||
OP };
|
||||
|
||||
BUSRQ = new ushort[] { PCh, 0, 0, PCh, 0, 0, PCh, SPh, 0, 0, SPh, 0, 0, W, 0, 0, 0 };
|
||||
MEMRQ = new ushort[] { PCh, 0, 0, PCh, 0, 0, 0, SPh, 0, 0, SPh, 0, 0, W, 0, 0, 0 };
|
||||
}
|
||||
else
|
||||
{
|
||||
cur_instr = new ushort[]
|
||||
{IDLE,
|
||||
WAIT,
|
||||
RD_INC, Z, PCl, PCh,
|
||||
IDLE,
|
||||
RD, Z, PCl, PCh,
|
||||
WAIT,
|
||||
RD_INC, W, PCl, PCh,
|
||||
IDLE,
|
||||
INC16, PCl, PCh,
|
||||
IDLE,
|
||||
RD, W, PCl, PCh,
|
||||
IDLE,
|
||||
INC16, PCl, PCh,
|
||||
WAIT,
|
||||
OP_F,
|
||||
OP };
|
||||
|
||||
BUSRQ = new ushort[] { PCh, 0, 0, PCh, 0, 0, PCh, 0, 0, 0 };
|
||||
MEMRQ = new ushort[] { PCh, 0, 0, PCh, 0, 0, PCh, 0, 0, 0 };
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -330,34 +399,43 @@ namespace BizHawk.Emulation.Cores.Components.Z80A
|
|||
{
|
||||
cur_instr = new ushort[]
|
||||
{operation, src,
|
||||
IDLE,
|
||||
IDLE,
|
||||
WAIT,
|
||||
OP_F,
|
||||
OP };
|
||||
|
||||
BUSRQ = new ushort[] { PCh, 0, 0, 0 };
|
||||
MEMRQ = new ushort[] { PCh, 0, 0, 0 };
|
||||
}
|
||||
|
||||
private void BIT_OP(ushort operation, ushort bit, ushort src)
|
||||
{
|
||||
cur_instr = new ushort[]
|
||||
{operation, bit, src,
|
||||
IDLE,
|
||||
IDLE,
|
||||
WAIT,
|
||||
OP_F,
|
||||
OP };
|
||||
|
||||
BUSRQ = new ushort[] { PCh, 0, 0, 0 };
|
||||
MEMRQ = new ushort[] { PCh, 0, 0, 0 };
|
||||
}
|
||||
|
||||
private void PUSH_(ushort src_l, ushort src_h)
|
||||
{
|
||||
cur_instr = new ushort[]
|
||||
{IDLE,
|
||||
{DEC16, SPl, SPh,
|
||||
IDLE,
|
||||
DEC16, SPl, SPh,
|
||||
IDLE,
|
||||
WR, SPl, SPh, src_h,
|
||||
IDLE,
|
||||
DEC16, SPl, SPh,
|
||||
WAIT,
|
||||
WR_DEC, SPl, SPh, src_h,
|
||||
IDLE,
|
||||
WAIT,
|
||||
WR, SPl, SPh, src_l,
|
||||
IDLE,
|
||||
WAIT,
|
||||
OP_F,
|
||||
OP };
|
||||
|
||||
BUSRQ = new ushort[] { I, SPh, 0, 0, SPh, 0, 0, PCh, 0, 0, 0 };
|
||||
MEMRQ = new ushort[] { 0, SPh, 0, 0, SPh, 0, 0, PCh, 0, 0, 0 };
|
||||
}
|
||||
|
||||
|
||||
|
@ -365,76 +443,112 @@ namespace BizHawk.Emulation.Cores.Components.Z80A
|
|||
{
|
||||
cur_instr = new ushort[]
|
||||
{IDLE,
|
||||
RD, src_l, SPl, SPh,
|
||||
WAIT,
|
||||
RD_INC, src_l, SPl, SPh,
|
||||
IDLE,
|
||||
INC16, SPl, SPh,
|
||||
IDLE,
|
||||
RD, src_h, SPl, SPh,
|
||||
IDLE,
|
||||
INC16, SPl, SPh,
|
||||
WAIT,
|
||||
RD_INC, src_h, SPl, SPh,
|
||||
IDLE,
|
||||
WAIT,
|
||||
OP_F,
|
||||
OP };
|
||||
|
||||
BUSRQ = new ushort[] { SPh, 0, 0, SPh, 0, 0, PCh, 0, 0, 0 };
|
||||
MEMRQ = new ushort[] { SPh, 0, 0, SPh, 0, 0, PCh, 0, 0, 0 };
|
||||
}
|
||||
|
||||
private void RST_(ushort n)
|
||||
{
|
||||
cur_instr = new ushort[]
|
||||
{IDLE,
|
||||
{DEC16, SPl, SPh,
|
||||
IDLE,
|
||||
DEC16, SPl, SPh,
|
||||
WR, SPl, SPh, PCh,
|
||||
DEC16, SPl, SPh,
|
||||
WR, SPl, SPh, PCl,
|
||||
IDLE,
|
||||
ASGN, Z, n,
|
||||
ASGN, W, 0,
|
||||
WAIT,
|
||||
WR_DEC, SPl, SPh, PCh,
|
||||
RST, n,
|
||||
WAIT,
|
||||
WR, SPl, SPh, PCl,
|
||||
TR16, PCl, PCh, Z, W,
|
||||
WAIT,
|
||||
OP_F,
|
||||
OP };
|
||||
|
||||
BUSRQ = new ushort[] { I, SPh, 0, 0, SPh, 0, 0, W, 0, 0, 0 };
|
||||
MEMRQ = new ushort[] { 0, SPh, 0, 0, SPh, 0, 0, W, 0, 0, 0 };
|
||||
}
|
||||
|
||||
private void PREFIX_(ushort src)
|
||||
{
|
||||
cur_instr = new ushort[]
|
||||
{IDLE,
|
||||
IDLE,
|
||||
IDLE,
|
||||
WAIT,
|
||||
OP_F,
|
||||
PREFIX, src};
|
||||
|
||||
BUSRQ = new ushort[] { PCh, 0, 0, 0 };
|
||||
MEMRQ = new ushort[] { PCh, 0, 0, 0 };
|
||||
}
|
||||
|
||||
private void PREFETCH_(ushort src_l, ushort src_h)
|
||||
private void PREFETCH_(ushort src)
|
||||
{
|
||||
if (src == IXCBpre)
|
||||
{
|
||||
Regs[W] = Regs[Ixh];
|
||||
Regs[Z] = Regs[Ixl];
|
||||
}
|
||||
else
|
||||
{
|
||||
Regs[W] = Regs[Iyh];
|
||||
Regs[Z] = Regs[Iyl];
|
||||
}
|
||||
|
||||
cur_instr = new ushort[]
|
||||
{TR16, Z, W, src_l, src_h,
|
||||
{IDLE,
|
||||
WAIT,
|
||||
RD_INC, ALU, PCl, PCh,
|
||||
ADDS, Z, W, ALU, ZERO,
|
||||
WAIT,
|
||||
OP_F,
|
||||
IDLE,
|
||||
PREFIX, IXYprefetch };
|
||||
PREFIX, src,};
|
||||
|
||||
BUSRQ = new ushort[] { PCh, 0, 0, PCh, 0, 0, PCh, PCh };
|
||||
MEMRQ = new ushort[] { PCh, 0, 0, PCh, 0, 0, 0, 0 };
|
||||
}
|
||||
|
||||
private void DI_()
|
||||
{
|
||||
cur_instr = new ushort[]
|
||||
{DI,
|
||||
IDLE,
|
||||
IDLE,
|
||||
WAIT,
|
||||
OP_F,
|
||||
OP };
|
||||
|
||||
BUSRQ = new ushort[] { PCh, 0, 0, 0 };
|
||||
MEMRQ = new ushort[] { PCh, 0, 0, 0 };
|
||||
}
|
||||
|
||||
private void EI_()
|
||||
{
|
||||
cur_instr = new ushort[]
|
||||
{EI,
|
||||
IDLE,
|
||||
IDLE,
|
||||
WAIT,
|
||||
OP_F,
|
||||
OP };
|
||||
|
||||
BUSRQ = new ushort[] { PCh, 0, 0, 0 };
|
||||
MEMRQ = new ushort[] { PCh, 0, 0, 0 };
|
||||
}
|
||||
|
||||
private void JP_16(ushort src_l, ushort src_h)
|
||||
{
|
||||
cur_instr = new ushort[]
|
||||
{TR, PCl, src_l,
|
||||
IDLE,
|
||||
TR, PCh, src_h,
|
||||
{TR16, PCl, PCh, src_l, src_h,
|
||||
WAIT,
|
||||
OP_F,
|
||||
OP };
|
||||
|
||||
BUSRQ = new ushort[] { src_h, 0, 0, 0 };
|
||||
MEMRQ = new ushort[] { src_h, 0, 0, 0 };
|
||||
}
|
||||
|
||||
private void LD_SP_16(ushort src_l, ushort src_h)
|
||||
|
@ -442,68 +556,83 @@ namespace BizHawk.Emulation.Cores.Components.Z80A
|
|||
cur_instr = new ushort[]
|
||||
{IDLE,
|
||||
IDLE,
|
||||
TR, SPl, src_l,
|
||||
TR, SPh, src_h,
|
||||
IDLE,
|
||||
TR16, SPl, SPh, src_l, src_h,
|
||||
WAIT,
|
||||
OP_F,
|
||||
OP };
|
||||
|
||||
BUSRQ = new ushort[] { I, I, PCh, 0, 0, 0 };
|
||||
MEMRQ = new ushort[] { 0, 0, PCh, 0, 0, 0 };
|
||||
}
|
||||
|
||||
private void OUT_()
|
||||
{
|
||||
cur_instr = new ushort[]
|
||||
{IDLE,
|
||||
RD, Z, PCl, PCh,
|
||||
IDLE,
|
||||
INC16, PCl, PCh,
|
||||
TR, W, A,
|
||||
{TR, W, A,
|
||||
WAIT,
|
||||
RD_INC, Z, PCl, PCh,
|
||||
IDLE,
|
||||
WAIT,
|
||||
WAIT,
|
||||
OUT, Z, W, A,
|
||||
IDLE,
|
||||
INC16, Z, W,
|
||||
IDLE,
|
||||
IDLE,
|
||||
INC16, Z, ALU,
|
||||
WAIT,
|
||||
OP_F,
|
||||
OP};
|
||||
|
||||
BUSRQ = new ushort[] { PCh, 0, 0, WIO1, WIO2, WIO3, WIO4, PCh, 0, 0, 0 };
|
||||
MEMRQ = new ushort[] { PCh, 0, 0, WIO1, WIO2, WIO3, WIO4, PCh, 0, 0, 0 };
|
||||
}
|
||||
|
||||
private void OUT_REG_(ushort dest, ushort src)
|
||||
{
|
||||
cur_instr = new ushort[]
|
||||
{IDLE,
|
||||
IDLE,
|
||||
TR16, Z, W, C, B,
|
||||
OUT, Z, W, src,
|
||||
{TR16, Z, W, C, B,
|
||||
IDLE,
|
||||
INC16, Z, W,
|
||||
IDLE,
|
||||
OUT, Z, W, src,
|
||||
INC16, Z, W,
|
||||
WAIT,
|
||||
OP_F,
|
||||
OP};
|
||||
|
||||
BUSRQ = new ushort[] { BIO1, BIO2, BIO3, BIO4, PCh, 0, 0, 0 };
|
||||
MEMRQ = new ushort[] { BIO1, BIO2, BIO3, BIO4, PCh, 0, 0, 0 };
|
||||
}
|
||||
|
||||
private void IN_()
|
||||
{
|
||||
cur_instr = new ushort[]
|
||||
{IDLE,
|
||||
RD, Z, PCl, PCh,
|
||||
{TR, W, A,
|
||||
WAIT,
|
||||
RD_INC, Z, PCl, PCh,
|
||||
IDLE,
|
||||
INC16, PCl, PCh,
|
||||
TR, W, A,
|
||||
WAIT,
|
||||
WAIT,
|
||||
IN, A, Z, W,
|
||||
IDLE,
|
||||
INC16, Z, W,
|
||||
IDLE,
|
||||
IDLE,
|
||||
WAIT,
|
||||
OP_F,
|
||||
OP};
|
||||
|
||||
BUSRQ = new ushort[] { PCh, 0, 0, WIO1, WIO2, WIO3, WIO4, PCh, 0, 0, 0 };
|
||||
MEMRQ = new ushort[] { PCh, 0, 0, WIO1, WIO2, WIO3, WIO4, PCh, 0, 0, 0 };
|
||||
}
|
||||
|
||||
private void IN_REG_(ushort dest, ushort src)
|
||||
{
|
||||
cur_instr = new ushort[]
|
||||
{IDLE,
|
||||
IDLE,
|
||||
IN, dest, src, B,
|
||||
IDLE,
|
||||
TR16, Z, W, C, B,
|
||||
{TR16, Z, W, C, B,
|
||||
WAIT,
|
||||
WAIT,
|
||||
IN, dest, Z, W,
|
||||
INC16, Z, W,
|
||||
IDLE,
|
||||
WAIT,
|
||||
OP_F,
|
||||
OP};
|
||||
|
||||
BUSRQ = new ushort[] { BIO1, BIO2, BIO3, BIO4, PCh, 0, 0, 0 };
|
||||
MEMRQ = new ushort[] { BIO1, BIO2, BIO3, BIO4, PCh, 0, 0, 0 };
|
||||
}
|
||||
|
||||
private void REG_OP_16_(ushort op, ushort dest_l, ushort dest_h, ushort src_l, ushort src_h)
|
||||
|
@ -511,62 +640,74 @@ namespace BizHawk.Emulation.Cores.Components.Z80A
|
|||
cur_instr = new ushort[]
|
||||
{IDLE,
|
||||
IDLE,
|
||||
IDLE,
|
||||
TR16, Z, W, dest_l, dest_h,
|
||||
INC16, Z, W,
|
||||
IDLE,
|
||||
IDLE,
|
||||
op, dest_l, dest_h, src_l, src_h,
|
||||
IDLE,
|
||||
IDLE,
|
||||
WAIT,
|
||||
OP_F,
|
||||
OP};
|
||||
|
||||
BUSRQ = new ushort[] { I, I, I, I, I, I, I, PCh, 0, 0, 0 };
|
||||
MEMRQ = new ushort[] { 0, 0, 0, 0, 0, 0, 0, PCh, 0, 0, 0 };
|
||||
}
|
||||
|
||||
private void INT_MODE_(ushort src)
|
||||
{
|
||||
cur_instr = new ushort[]
|
||||
{IDLE,
|
||||
IDLE,
|
||||
INT_MODE, src,
|
||||
{INT_MODE, src,
|
||||
WAIT,
|
||||
OP_F,
|
||||
OP };
|
||||
|
||||
BUSRQ = new ushort[] { PCh, 0, 0, 0 };
|
||||
MEMRQ = new ushort[] { PCh, 0, 0, 0 };
|
||||
}
|
||||
|
||||
private void RRD_()
|
||||
{
|
||||
cur_instr = new ushort[]
|
||||
{IDLE,
|
||||
IDLE,
|
||||
TR16, Z, W, L, H,
|
||||
IDLE,
|
||||
{TR16, Z, W, L, H,
|
||||
WAIT,
|
||||
RD, ALU, Z, W,
|
||||
IDLE,
|
||||
RRD, ALU, A,
|
||||
IDLE,
|
||||
WR, Z, W, ALU,
|
||||
IDLE,
|
||||
INC16, Z, W,
|
||||
IDLE,
|
||||
IDLE,
|
||||
WAIT,
|
||||
WR_INC, Z, W, ALU,
|
||||
IDLE,
|
||||
WAIT,
|
||||
OP_F,
|
||||
OP };
|
||||
|
||||
BUSRQ = new ushort[] { H, 0, 0, H, H, H, H, W, 0, 0, PCh, 0, 0, 0 };
|
||||
MEMRQ = new ushort[] { H, 0, 0, 0, 0, 0, 0, W, 0, 0, PCh, 0, 0, 0 };
|
||||
}
|
||||
|
||||
private void RLD_()
|
||||
{
|
||||
cur_instr = new ushort[]
|
||||
{IDLE,
|
||||
IDLE,
|
||||
TR16, Z, W, L, H,
|
||||
IDLE,
|
||||
{TR16, Z, W, L, H,
|
||||
WAIT,
|
||||
RD, ALU, Z, W,
|
||||
IDLE,
|
||||
RLD, ALU, A,
|
||||
IDLE,
|
||||
WR, Z, W, ALU,
|
||||
IDLE,
|
||||
INC16, Z, W,
|
||||
IDLE,
|
||||
IDLE,
|
||||
WAIT,
|
||||
WR_INC, Z, W, ALU,
|
||||
IDLE,
|
||||
WAIT,
|
||||
OP_F,
|
||||
OP };
|
||||
|
||||
BUSRQ = new ushort[] { H, 0, 0, H, H, H, H, W, 0, 0, PCh, 0, 0, 0 };
|
||||
MEMRQ = new ushort[] { H, 0, 0, 0, 0, 0, 0, W, 0, 0, PCh, 0, 0, 0 };
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,32 +6,38 @@
|
|||
{
|
||||
cur_instr = new ushort[]
|
||||
{IDLE,
|
||||
IDLE,
|
||||
IDLE,
|
||||
WAIT,
|
||||
RD, ALU, src_l, src_h,
|
||||
IDLE,
|
||||
operation, ALU,
|
||||
IDLE,
|
||||
WAIT,
|
||||
WR, src_l, src_h, ALU,
|
||||
IDLE,
|
||||
IDLE,
|
||||
IDLE,
|
||||
WAIT,
|
||||
OP_F,
|
||||
OP };
|
||||
|
||||
BUSRQ = new ushort[] { src_h, 0, 0, src_h, src_h, 0, 0, PCh, 0, 0, 0 };
|
||||
MEMRQ = new ushort[] { src_h, 0, 0, 0, src_h, 0, 0, PCh, 0, 0, 0 };
|
||||
}
|
||||
|
||||
private void BIT_OP_IND(ushort operation, ushort bit, ushort src_l, ushort src_h)
|
||||
{
|
||||
cur_instr = new ushort[]
|
||||
{IDLE,
|
||||
IDLE,
|
||||
IDLE,
|
||||
WAIT,
|
||||
RD, ALU, src_l, src_h,
|
||||
IDLE,
|
||||
operation, bit, ALU,
|
||||
IDLE,
|
||||
WAIT,
|
||||
WR, src_l, src_h, ALU,
|
||||
IDLE,
|
||||
IDLE,
|
||||
WAIT,
|
||||
OP_F,
|
||||
OP };
|
||||
|
||||
BUSRQ = new ushort[] { src_h, 0, 0, src_h, src_h, 0, 0, PCh, 0, 0, 0 };
|
||||
MEMRQ = new ushort[] { src_h, 0, 0, 0, src_h, 0, 0, PCh, 0, 0, 0 };
|
||||
}
|
||||
|
||||
// Note that this operation uses I_BIT, same as indexed BIT.
|
||||
|
@ -42,214 +48,272 @@
|
|||
{
|
||||
cur_instr = new ushort[]
|
||||
{IDLE,
|
||||
IDLE,
|
||||
IDLE,
|
||||
WAIT,
|
||||
RD, ALU, src_l, src_h,
|
||||
IDLE,
|
||||
I_BIT, bit, ALU,
|
||||
IDLE,
|
||||
WAIT,
|
||||
OP_F,
|
||||
OP };
|
||||
|
||||
BUSRQ = new ushort[] { src_h, 0, 0, src_h, PCh, 0, 0, 0 };
|
||||
MEMRQ = new ushort[] { src_h, 0, 0, 0, PCh, 0, 0, 0 };
|
||||
}
|
||||
|
||||
private void REG_OP_IND_INC(ushort operation, ushort dest, ushort src_l, ushort src_h)
|
||||
{
|
||||
cur_instr = new ushort[]
|
||||
{IDLE,
|
||||
IDLE,
|
||||
RD, ALU, src_l, src_h,
|
||||
IDLE,
|
||||
WAIT,
|
||||
RD_INC, ALU, src_l, src_h,
|
||||
operation, dest, ALU,
|
||||
INC16, src_l, src_h,
|
||||
WAIT,
|
||||
OP_F,
|
||||
OP };
|
||||
|
||||
BUSRQ = new ushort[] { src_h, 0, 0, PCh, 0, 0, 0 };
|
||||
MEMRQ = new ushort[] { src_h, 0, 0, PCh, 0, 0, 0 };
|
||||
}
|
||||
|
||||
private void REG_OP_IND(ushort operation, ushort dest, ushort src_l, ushort src_h)
|
||||
{
|
||||
cur_instr = new ushort[]
|
||||
{IDLE,
|
||||
IDLE,
|
||||
TR16, Z, W, src_l, src_h,
|
||||
RD, ALU, Z, W,
|
||||
INC16, Z, W,
|
||||
operation, dest, ALU,
|
||||
{TR16, Z, W, src_l, src_h,
|
||||
WAIT,
|
||||
RD_INC, ALU, Z, W,
|
||||
operation, dest, ALU,
|
||||
WAIT,
|
||||
OP_F,
|
||||
OP };
|
||||
|
||||
BUSRQ = new ushort[] { src_h, 0, 0, PCh, 0, 0, 0 };
|
||||
MEMRQ = new ushort[] { src_h, 0, 0, PCh, 0, 0, 0 };
|
||||
}
|
||||
|
||||
// different because HL doesn't effect WZ
|
||||
private void REG_OP_IND_HL(ushort operation, ushort dest)
|
||||
{
|
||||
cur_instr = new ushort[]
|
||||
{IDLE,
|
||||
WAIT,
|
||||
RD, ALU, L, H,
|
||||
operation, dest, ALU,
|
||||
WAIT,
|
||||
OP_F,
|
||||
OP };
|
||||
|
||||
BUSRQ = new ushort[] { H, 0, 0, PCh, 0, 0, 0 };
|
||||
MEMRQ = new ushort[] { H, 0, 0, PCh, 0, 0, 0 };
|
||||
}
|
||||
|
||||
private void LD_16_IND_nn(ushort src_l, ushort src_h)
|
||||
{
|
||||
cur_instr = new ushort[]
|
||||
{IDLE,
|
||||
RD, Z, PCl, PCh,
|
||||
WAIT,
|
||||
RD_INC, Z, PCl, PCh,
|
||||
IDLE,
|
||||
INC16, PCl, PCh,
|
||||
WAIT,
|
||||
RD_INC, W, PCl, PCh,
|
||||
IDLE,
|
||||
RD, W, PCl, PCh,
|
||||
IDLE,
|
||||
INC16, PCl, PCh,
|
||||
IDLE,
|
||||
WR, Z, W, src_l,
|
||||
IDLE,
|
||||
INC16, Z, W,
|
||||
WAIT,
|
||||
WR_INC, Z, W, src_l,
|
||||
IDLE,
|
||||
WAIT,
|
||||
WR, Z, W, src_h,
|
||||
IDLE,
|
||||
WAIT,
|
||||
OP_F,
|
||||
OP };
|
||||
|
||||
BUSRQ = new ushort[] { PCh, 0, 0, PCh, 0, 0, W, 0, 0, W, 0, 0, PCh, 0, 0, 0 };
|
||||
MEMRQ = new ushort[] { PCh, 0, 0, PCh, 0, 0, W, 0, 0, W, 0, 0, PCh, 0, 0, 0 };
|
||||
}
|
||||
|
||||
private void LD_IND_16_nn(ushort dest_l, ushort dest_h)
|
||||
{
|
||||
cur_instr = new ushort[]
|
||||
{IDLE,
|
||||
RD, Z, PCl, PCh,
|
||||
WAIT,
|
||||
RD_INC, Z, PCl, PCh,
|
||||
IDLE,
|
||||
INC16, PCl, PCh,
|
||||
WAIT,
|
||||
RD_INC, W, PCl, PCh,
|
||||
IDLE,
|
||||
RD, W, PCl, PCh,
|
||||
IDLE,
|
||||
INC16, PCl, PCh,
|
||||
IDLE,
|
||||
RD, dest_l, Z, W,
|
||||
IDLE,
|
||||
INC16, Z, W,
|
||||
WAIT,
|
||||
RD_INC, dest_l, Z, W,
|
||||
IDLE,
|
||||
WAIT,
|
||||
RD, dest_h, Z, W,
|
||||
IDLE,
|
||||
WAIT,
|
||||
OP_F,
|
||||
OP };
|
||||
|
||||
BUSRQ = new ushort[] { PCh, 0, 0, PCh, 0, 0, W, 0, 0, W, 0, 0, PCh, 0, 0, 0 };
|
||||
MEMRQ = new ushort[] { PCh, 0, 0, PCh, 0, 0, W, 0, 0, W, 0, 0, PCh, 0, 0, 0 };
|
||||
}
|
||||
|
||||
private void LD_8_IND_nn(ushort src)
|
||||
{
|
||||
cur_instr = new ushort[]
|
||||
{IDLE,
|
||||
RD, Z, PCl, PCh,
|
||||
WAIT,
|
||||
RD_INC, Z, PCl, PCh,
|
||||
IDLE,
|
||||
INC16, PCl, PCh,
|
||||
WAIT,
|
||||
RD_INC, W, PCl, PCh,
|
||||
IDLE,
|
||||
RD, W, PCl, PCh,
|
||||
IDLE,
|
||||
INC16, PCl, PCh,
|
||||
IDLE,
|
||||
WR, Z, W, src,
|
||||
INC16, Z, W,
|
||||
WAIT,
|
||||
WR_INC, Z, W, src,
|
||||
TR, W, A,
|
||||
WAIT,
|
||||
OP_F,
|
||||
OP };
|
||||
|
||||
BUSRQ = new ushort[] { PCh, 0, 0, PCh, 0, 0, W, 0, 0, PCh, 0, 0, 0 };
|
||||
MEMRQ = new ushort[] { PCh, 0, 0, PCh, 0, 0, W, 0, 0, PCh, 0, 0, 0 };
|
||||
}
|
||||
|
||||
private void LD_IND_8_nn(ushort dest)
|
||||
{
|
||||
cur_instr = new ushort[]
|
||||
{IDLE,
|
||||
RD, Z, PCl, PCh,
|
||||
WAIT,
|
||||
RD_INC, Z, PCl, PCh,
|
||||
IDLE,
|
||||
INC16, PCl, PCh,
|
||||
WAIT,
|
||||
RD_INC, W, PCl, PCh,
|
||||
IDLE,
|
||||
RD, W, PCl, PCh,
|
||||
WAIT,
|
||||
RD_INC, dest, Z, W,
|
||||
IDLE,
|
||||
INC16, PCl, PCh,
|
||||
IDLE,
|
||||
RD, dest, Z, W,
|
||||
IDLE,
|
||||
INC16, Z, W,
|
||||
WAIT,
|
||||
OP_F,
|
||||
OP };
|
||||
|
||||
BUSRQ = new ushort[] { PCh, 0, 0, PCh, 0, 0, W, 0, 0, PCh, 0, 0, 0 };
|
||||
MEMRQ = new ushort[] { PCh, 0, 0, PCh, 0, 0, W, 0, 0, PCh, 0, 0, 0 };
|
||||
}
|
||||
|
||||
private void LD_8_IND(ushort dest_l, ushort dest_h, ushort src)
|
||||
{
|
||||
cur_instr = new ushort[]
|
||||
{IDLE,
|
||||
IDLE,
|
||||
TR16, Z, W, dest_l, dest_h,
|
||||
WR, Z, W, src,
|
||||
INC16, Z, W,
|
||||
TR, W, A,
|
||||
{TR16, Z, W, dest_l, dest_h,
|
||||
WAIT,
|
||||
WR_INC, Z, W, src,
|
||||
TR, W, A,
|
||||
WAIT,
|
||||
OP_F,
|
||||
OP };
|
||||
|
||||
BUSRQ = new ushort[] { dest_h, 0, 0, PCh, 0, 0, 0 };
|
||||
MEMRQ = new ushort[] { dest_h, 0, 0, PCh, 0, 0, 0 };
|
||||
}
|
||||
|
||||
// seperate HL needed since it doesn't effect the WZ pair
|
||||
private void LD_8_IND_HL(ushort src)
|
||||
{
|
||||
cur_instr = new ushort[]
|
||||
{IDLE,
|
||||
WAIT,
|
||||
WR, L, H, src,
|
||||
IDLE,
|
||||
WAIT,
|
||||
OP_F,
|
||||
OP };
|
||||
|
||||
BUSRQ = new ushort[] { H, 0, 0, PCh, 0, 0, 0 };
|
||||
MEMRQ = new ushort[] { H, 0, 0, PCh, 0, 0, 0 };
|
||||
}
|
||||
|
||||
private void LD_8_IND_IND(ushort dest_l, ushort dest_h, ushort src_l, ushort src_h)
|
||||
{
|
||||
cur_instr = new ushort[]
|
||||
{IDLE,
|
||||
WAIT,
|
||||
RD_INC, ALU, src_l, src_h,
|
||||
IDLE,
|
||||
IDLE,
|
||||
RD, ALU, src_l, src_h,
|
||||
IDLE,
|
||||
INC16, src_l, src_h,
|
||||
IDLE,
|
||||
WAIT,
|
||||
WR, dest_l, dest_h, ALU,
|
||||
IDLE,
|
||||
WAIT,
|
||||
OP_F,
|
||||
OP };
|
||||
|
||||
BUSRQ = new ushort[] { src_h, 0, 0, dest_h, 0, 0, PCh, 0, 0, 0 };
|
||||
MEMRQ = new ushort[] { src_h, 0, 0, dest_h, 0, 0, PCh, 0, 0, 0 };
|
||||
}
|
||||
|
||||
private void LD_IND_8_INC(ushort dest, ushort src_l, ushort src_h)
|
||||
{
|
||||
cur_instr = new ushort[]
|
||||
{IDLE,
|
||||
WAIT,
|
||||
RD_INC, dest, src_l, src_h,
|
||||
IDLE,
|
||||
IDLE,
|
||||
RD, dest, src_l, src_h,
|
||||
IDLE,
|
||||
INC16, src_l, src_h,
|
||||
WAIT,
|
||||
OP_F,
|
||||
OP };
|
||||
}
|
||||
|
||||
private void LD_IND_8_DEC(ushort dest, ushort src_l, ushort src_h)
|
||||
{
|
||||
cur_instr = new ushort[]
|
||||
{IDLE,
|
||||
IDLE,
|
||||
IDLE,
|
||||
RD, dest, src_l, src_h,
|
||||
IDLE,
|
||||
DEC16, src_l, src_h,
|
||||
IDLE,
|
||||
OP };
|
||||
BUSRQ = new ushort[] { src_h, 0, 0, PCh, 0, 0, 0 };
|
||||
MEMRQ = new ushort[] { src_h, 0, 0, PCh, 0, 0, 0 };
|
||||
}
|
||||
|
||||
private void LD_IND_16(ushort dest_l, ushort dest_h, ushort src_l, ushort src_h)
|
||||
{
|
||||
cur_instr = new ushort[]
|
||||
{IDLE,
|
||||
WAIT,
|
||||
RD_INC, dest_l, src_l, src_h,
|
||||
IDLE,
|
||||
WAIT,
|
||||
RD_INC, dest_h, src_l, src_h,
|
||||
IDLE,
|
||||
RD, dest_l, src_l, src_h,
|
||||
IDLE,
|
||||
INC16, src_l, src_h,
|
||||
RD, dest_h, src_l, src_h,
|
||||
IDLE,
|
||||
INC16, src_l, src_h,
|
||||
WAIT,
|
||||
OP_F,
|
||||
OP };
|
||||
|
||||
BUSRQ = new ushort[] { src_h, 0, 0, src_h, 0, 0, PCh, 0, 0, 0 };
|
||||
MEMRQ = new ushort[] { src_h, 0, 0, src_h, 0, 0, PCh, 0, 0, 0 };
|
||||
}
|
||||
|
||||
private void INC_8_IND(ushort src_l, ushort src_h)
|
||||
{
|
||||
cur_instr = new ushort[]
|
||||
{IDLE,
|
||||
IDLE,
|
||||
IDLE,
|
||||
WAIT,
|
||||
RD, ALU, src_l, src_h,
|
||||
IDLE,
|
||||
INC8, ALU,
|
||||
IDLE,
|
||||
WAIT,
|
||||
WR, src_l, src_h, ALU,
|
||||
IDLE,
|
||||
IDLE,
|
||||
WAIT,
|
||||
OP_F,
|
||||
OP };
|
||||
|
||||
BUSRQ = new ushort[] { src_h, 0, 0, src_h, src_h, 0, 0, PCh, 0, 0, 0 };
|
||||
MEMRQ = new ushort[] { src_h, 0, 0, 0, src_h, 0, 0, PCh, 0, 0, 0 };
|
||||
}
|
||||
|
||||
private void DEC_8_IND(ushort src_l, ushort src_h)
|
||||
{
|
||||
cur_instr = new ushort[]
|
||||
{IDLE,
|
||||
IDLE,
|
||||
IDLE,
|
||||
WAIT,
|
||||
RD, ALU, src_l, src_h,
|
||||
IDLE,
|
||||
DEC8, ALU,
|
||||
IDLE,
|
||||
WAIT,
|
||||
WR, src_l, src_h, ALU,
|
||||
IDLE,
|
||||
IDLE,
|
||||
WAIT,
|
||||
OP_F,
|
||||
OP };
|
||||
|
||||
BUSRQ = new ushort[] { src_h, 0, 0, src_h, src_h, 0, 0, PCh, 0, 0, 0 };
|
||||
MEMRQ = new ushort[] { src_h, 0, 0, 0, src_h, 0, 0, PCh, 0, 0, 0 };
|
||||
}
|
||||
|
||||
// NOTE: WZ implied for the wollowing 3 functions
|
||||
|
@ -257,197 +321,214 @@
|
|||
{
|
||||
cur_instr = new ushort[]
|
||||
{IDLE,
|
||||
IDLE,
|
||||
WAIT,
|
||||
RD, ALU, Z, W,
|
||||
IDLE,
|
||||
operation, ALU,
|
||||
IDLE,
|
||||
WAIT,
|
||||
WR, Z, W, ALU,
|
||||
IDLE,
|
||||
TR, dest, ALU,
|
||||
IDLE,
|
||||
WAIT,
|
||||
OP_F,
|
||||
OP };
|
||||
|
||||
BUSRQ = new ushort[] { W, 0, 0, W, W, 0, 0, PCh, 0, 0, 0 };
|
||||
MEMRQ = new ushort[] { W, 0, 0, 0, W, 0, 0, PCh, 0, 0, 0 };
|
||||
}
|
||||
|
||||
private void I_BIT_OP(ushort operation, ushort bit, ushort dest)
|
||||
{
|
||||
cur_instr = new ushort[]
|
||||
{IDLE,
|
||||
IDLE,
|
||||
WAIT,
|
||||
RD, ALU, Z, W,
|
||||
IDLE,
|
||||
operation, bit, ALU,
|
||||
IDLE,
|
||||
WAIT,
|
||||
WR, Z, W, ALU,
|
||||
IDLE,
|
||||
TR, dest, ALU,
|
||||
IDLE,
|
||||
WAIT,
|
||||
OP_F,
|
||||
OP };
|
||||
|
||||
BUSRQ = new ushort[] { W, 0, 0, W, W, 0, 0, PCh, 0, 0, 0 };
|
||||
MEMRQ = new ushort[] { W, 0, 0, 0, W, 0, 0, PCh, 0, 0, 0 };
|
||||
}
|
||||
|
||||
private void I_BIT_TE(ushort bit)
|
||||
{
|
||||
cur_instr = new ushort[]
|
||||
{IDLE,
|
||||
IDLE,
|
||||
IDLE,
|
||||
WAIT,
|
||||
RD, ALU, Z, W,
|
||||
IDLE,
|
||||
I_BIT, bit, ALU,
|
||||
IDLE,
|
||||
WAIT,
|
||||
OP_F,
|
||||
OP };
|
||||
|
||||
BUSRQ = new ushort[] { W, 0, 0, W, PCh, 0, 0, 0 };
|
||||
MEMRQ = new ushort[] { W, 0, 0, 0, PCh, 0, 0, 0 };
|
||||
}
|
||||
|
||||
private void I_OP_n(ushort operation, ushort src_l, ushort src_h)
|
||||
{
|
||||
cur_instr = new ushort[]
|
||||
{IDLE,
|
||||
IDLE,
|
||||
WAIT,
|
||||
RD, ALU, PCl, PCh,
|
||||
INC16, PCl, PCh,
|
||||
IDLE,
|
||||
IDLE,
|
||||
TR16, Z, W, src_l, src_h,
|
||||
ADDS, Z, W, ALU, ZERO,
|
||||
IDLE,
|
||||
ADDS, Z, W, ALU, ZERO,
|
||||
IDLE,
|
||||
INC16, PCl, PCh,
|
||||
WAIT,
|
||||
RD, ALU, Z, W,
|
||||
IDLE,
|
||||
IDLE,
|
||||
operation, ALU,
|
||||
IDLE,
|
||||
IDLE,
|
||||
IDLE,
|
||||
WAIT,
|
||||
WR, Z, W, ALU,
|
||||
IDLE,
|
||||
WAIT,
|
||||
OP_F,
|
||||
OP };
|
||||
|
||||
BUSRQ = new ushort[] { PCh, 0, 0, PCh, PCh, PCh, PCh, PCh, W, 0, 0, W, W, 0, 0, PCh, 0, 0, 0 };
|
||||
MEMRQ = new ushort[] { PCh, 0, 0, 0, 0, 0, 0, 0, W, 0, 0, 0, W, 0, 0, PCh, 0, 0, 0 };
|
||||
}
|
||||
|
||||
private void I_OP_n_n(ushort src_l, ushort src_h)
|
||||
{
|
||||
cur_instr = new ushort[]
|
||||
{IDLE,
|
||||
IDLE,
|
||||
RD, ALU, PCl, PCh,
|
||||
INC16, PCl, PCh,
|
||||
IDLE,
|
||||
TR16, Z, W, src_l, src_h,
|
||||
IDLE,
|
||||
{TR16, Z, W, src_l, src_h,
|
||||
WAIT,
|
||||
RD_INC, ALU, PCl, PCh,
|
||||
ADDS, Z, W, ALU, ZERO,
|
||||
IDLE,
|
||||
WAIT,
|
||||
RD, ALU, PCl, PCh,
|
||||
INC16, PCl, PCh,
|
||||
IDLE,
|
||||
IDLE,
|
||||
INC16, PCl, PCh,
|
||||
WAIT,
|
||||
WR, Z, W, ALU,
|
||||
IDLE,
|
||||
WAIT,
|
||||
OP_F,
|
||||
OP };
|
||||
|
||||
BUSRQ = new ushort[] { PCh, 0, 0, PCh, 0, 0, PCh, PCh, W, 0, 0, PCh, 0, 0, 0 };
|
||||
MEMRQ = new ushort[] { PCh, 0, 0, PCh, 0, 0, 0, 0, W, 0, 0, PCh, 0, 0, 0 };
|
||||
}
|
||||
|
||||
private void I_REG_OP_IND_n(ushort operation, ushort dest, ushort src_l, ushort src_h)
|
||||
{
|
||||
cur_instr = new ushort[]
|
||||
{IDLE,
|
||||
IDLE,
|
||||
WAIT,
|
||||
RD, ALU, PCl, PCh,
|
||||
IDLE,
|
||||
INC16, PCl, PCh,
|
||||
IDLE,
|
||||
TR16, Z, W, src_l, src_h,
|
||||
IDLE,
|
||||
ADDS, Z, W, ALU, ZERO,
|
||||
IDLE,
|
||||
INC16, PCl, PCh,
|
||||
WAIT,
|
||||
RD, ALU, Z, W,
|
||||
IDLE,
|
||||
operation, dest, ALU,
|
||||
IDLE,
|
||||
operation, dest, ALU,
|
||||
WAIT,
|
||||
OP_F,
|
||||
OP };
|
||||
|
||||
BUSRQ = new ushort[] { PCh, 0, 0, PCh, PCh, PCh, PCh, PCh, W, 0, 0, PCh, 0, 0, 0 };
|
||||
MEMRQ = new ushort[] { PCh, 0, 0, 0, 0, 0, 0, 0, W, 0, 0, PCh, 0, 0, 0 };
|
||||
}
|
||||
|
||||
private void I_LD_8_IND_n(ushort dest_l, ushort dest_h, ushort src)
|
||||
{
|
||||
cur_instr = new ushort[]
|
||||
{IDLE,
|
||||
WAIT,
|
||||
RD, ALU, PCl, PCh,
|
||||
IDLE,
|
||||
INC16, PCl, PCh,
|
||||
IDLE,
|
||||
TR16, Z, W, dest_l, dest_h,
|
||||
IDLE,
|
||||
ADDS, Z, W, ALU, ZERO,
|
||||
IDLE,
|
||||
WR, Z, W, src,
|
||||
IDLE,
|
||||
IDLE,
|
||||
IDLE,
|
||||
INC16, PCl, PCh,
|
||||
WAIT,
|
||||
WR, Z, W, src,
|
||||
IDLE,
|
||||
WAIT,
|
||||
OP_F,
|
||||
OP };
|
||||
|
||||
BUSRQ = new ushort[] { PCh, 0, 0, PCh, PCh, PCh, PCh, PCh, Z, 0, 0, PCh, 0, 0, 0 };
|
||||
MEMRQ = new ushort[] { PCh, 0, 0, 0, 0, 0, 0, 0, Z, 0, 0, PCh, 0, 0, 0 };
|
||||
}
|
||||
|
||||
private void LD_OP_R(ushort operation, ushort repeat_instr)
|
||||
{
|
||||
cur_instr = new ushort[]
|
||||
{RD, ALU, L, H,
|
||||
IDLE,
|
||||
WR, E, D, ALU,
|
||||
IDLE,
|
||||
operation, L, H,
|
||||
IDLE,
|
||||
operation, E, D,
|
||||
IDLE,
|
||||
DEC16, C, B,
|
||||
SET_FL_LD,
|
||||
IDLE,
|
||||
OP_R, 0, operation, repeat_instr };
|
||||
{IDLE,
|
||||
WAIT,
|
||||
RD, ALU, L, H,
|
||||
operation, L, H,
|
||||
WAIT,
|
||||
WR, E, D, ALU,
|
||||
IDLE,
|
||||
SET_FL_LD_R, 0, operation, repeat_instr};
|
||||
|
||||
BUSRQ = new ushort[] { H, 0, 0, D, 0, 0, D, D };
|
||||
MEMRQ = new ushort[] { H, 0, 0, D, 0, 0, 0, 0 };
|
||||
}
|
||||
|
||||
private void CP_OP_R(ushort operation, ushort repeat_instr)
|
||||
{
|
||||
cur_instr = new ushort[]
|
||||
{IDLE,
|
||||
IDLE,
|
||||
{IDLE,
|
||||
WAIT,
|
||||
RD, ALU, L, H,
|
||||
operation, L, H,
|
||||
IDLE,
|
||||
IDLE,
|
||||
DEC16, C, B,
|
||||
SET_FL_CP,
|
||||
IDLE,
|
||||
operation, Z, W,
|
||||
IDLE,
|
||||
OP_R, 1, operation, repeat_instr };
|
||||
SET_FL_CP_R, 1, operation, repeat_instr};
|
||||
|
||||
BUSRQ = new ushort[] { H, 0, 0, H, H, H, H, H };
|
||||
MEMRQ = new ushort[] { H, 0, 0, 0, 0, 0, 0, 0 };
|
||||
}
|
||||
|
||||
private void IN_OP_R(ushort operation, ushort repeat_instr)
|
||||
{
|
||||
cur_instr = new ushort[]
|
||||
{IN, ALU, C, B,
|
||||
{IDLE,
|
||||
IDLE,
|
||||
WR, L, H, ALU,
|
||||
WAIT,
|
||||
WAIT,
|
||||
IN, ALU, C, B,
|
||||
IDLE,
|
||||
operation, L, H,
|
||||
IDLE,
|
||||
TR16, Z, W, C, B,
|
||||
operation, Z, W,
|
||||
IDLE,
|
||||
DEC8, B,
|
||||
IDLE,
|
||||
OP_R, 2, operation, repeat_instr };
|
||||
WAIT,
|
||||
REP_OP_I, L, H, ALU, operation, 2, operation, repeat_instr };
|
||||
|
||||
BUSRQ = new ushort[] { I, BIO1, BIO2, BIO3, BIO4, H, 0, 0};
|
||||
MEMRQ = new ushort[] { 0, BIO1, BIO2, BIO3, BIO4, H, 0, 0 };
|
||||
}
|
||||
|
||||
private void OUT_OP_R(ushort operation, ushort repeat_instr)
|
||||
{
|
||||
cur_instr = new ushort[]
|
||||
{RD, ALU, L, H,
|
||||
{IDLE,
|
||||
IDLE,
|
||||
OUT, C, B, ALU,
|
||||
WAIT,
|
||||
RD, ALU, L, H,
|
||||
IDLE,
|
||||
IDLE,
|
||||
operation, L, H,
|
||||
DEC8, B,
|
||||
IDLE,
|
||||
TR16, Z, W, C, B,
|
||||
operation, Z, W,
|
||||
IDLE,
|
||||
OP_R, 3, operation, repeat_instr };
|
||||
WAIT,
|
||||
WAIT,
|
||||
REP_OP_O, C, B, ALU, operation, 3, operation, repeat_instr };
|
||||
|
||||
BUSRQ = new ushort[] { I, H, 0, 0, BIO1, BIO2, BIO3, BIO4 };
|
||||
MEMRQ = new ushort[] { 0, H, 0, 0, BIO1, BIO2, BIO3, BIO4 };
|
||||
}
|
||||
|
||||
// this is an indirect change of a a 16 bit register with memory
|
||||
|
@ -455,24 +536,27 @@
|
|||
{
|
||||
cur_instr = new ushort[]
|
||||
{IDLE,
|
||||
IDLE,
|
||||
RD, Z, dest_l, dest_h,
|
||||
WAIT,
|
||||
RD_INC, Z, dest_l, dest_h,
|
||||
IDLE,
|
||||
IDLE,
|
||||
I_RD, W, dest_l, dest_h, 1,
|
||||
WAIT,
|
||||
RD, W, dest_l, dest_h,
|
||||
IDLE,
|
||||
IDLE,
|
||||
WR, dest_l, dest_h, src_l,
|
||||
IDLE,
|
||||
IDLE,
|
||||
I_WR, dest_l, dest_h, 1, src_h,
|
||||
WAIT,
|
||||
WR_DEC, dest_l, dest_h, src_h,
|
||||
IDLE,
|
||||
WAIT,
|
||||
WR, dest_l, dest_h, src_l,
|
||||
IDLE,
|
||||
IDLE,
|
||||
TR16, src_l, src_h, Z, W,
|
||||
IDLE,
|
||||
IDLE,
|
||||
IDLE,
|
||||
WAIT,
|
||||
OP_F,
|
||||
OP };
|
||||
|
||||
BUSRQ = new ushort[] { dest_h, 0, 0, dest_h, 0, 0, dest_h, dest_h, 0, 0, dest_h, 0, 0, dest_h, dest_h, PCh, 0, 0, 0 };
|
||||
MEMRQ = new ushort[] { dest_h, 0, 0, dest_h, 0, 0, 0, dest_h, 0, 0, dest_h, 0, 0, 0, 0, PCh, 0, 0, 0 };
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -14,69 +14,75 @@ namespace BizHawk.Emulation.Cores.Components.Z80A
|
|||
// operations that can take place in an instruction
|
||||
public const ushort IDLE = 0;
|
||||
public const ushort OP = 1;
|
||||
public const ushort OP_R = 2; // used for repeating operations
|
||||
public const ushort OP_F = 2; // used for repeating operations
|
||||
public const ushort HALT = 3;
|
||||
public const ushort RD = 4;
|
||||
public const ushort WR = 5;
|
||||
public const ushort I_RD = 6;
|
||||
public const ushort I_WR = 7;
|
||||
public const ushort TR = 8;
|
||||
public const ushort TR16 = 9;
|
||||
public const ushort ADD16 = 10;
|
||||
public const ushort ADD8 = 11;
|
||||
public const ushort SUB8 = 12;
|
||||
public const ushort ADC8 = 13;
|
||||
public const ushort SBC8 = 14;
|
||||
public const ushort SBC16 = 15;
|
||||
public const ushort ADC16 = 16;
|
||||
public const ushort INC16 = 17;
|
||||
public const ushort INC8 = 18;
|
||||
public const ushort DEC16 = 19;
|
||||
public const ushort DEC8 = 20;
|
||||
public const ushort RLC = 21;
|
||||
public const ushort RL = 22;
|
||||
public const ushort RRC = 23;
|
||||
public const ushort RR = 24;
|
||||
public const ushort CPL = 25;
|
||||
public const ushort DA = 26;
|
||||
public const ushort SCF = 27;
|
||||
public const ushort CCF = 28;
|
||||
public const ushort AND8 = 29;
|
||||
public const ushort XOR8 = 30;
|
||||
public const ushort OR8 = 31;
|
||||
public const ushort CP8 = 32;
|
||||
public const ushort SLA = 33;
|
||||
public const ushort SRA = 34;
|
||||
public const ushort SRL = 35;
|
||||
public const ushort SLL = 36;
|
||||
public const ushort BIT = 37;
|
||||
public const ushort RES = 38;
|
||||
public const ushort SET = 39;
|
||||
public const ushort EI = 40;
|
||||
public const ushort DI = 41;
|
||||
public const ushort EXCH = 42;
|
||||
public const ushort EXX = 43;
|
||||
public const ushort EXCH_16 = 44;
|
||||
public const ushort PREFIX = 45;
|
||||
public const ushort PREFETCH = 46;
|
||||
public const ushort ASGN = 47;
|
||||
public const ushort ADDS = 48; // signed 16 bit operation used in 2 instructions
|
||||
public const ushort INT_MODE = 49;
|
||||
public const ushort EI_RETN = 50;
|
||||
public const ushort EI_RETI = 51; // reti has no delay in interrupt enable
|
||||
public const ushort OUT = 52;
|
||||
public const ushort IN = 53;
|
||||
public const ushort NEG = 54;
|
||||
public const ushort RRD = 55;
|
||||
public const ushort RLD = 56;
|
||||
public const ushort SET_FL_LD = 57;
|
||||
public const ushort SET_FL_CP = 58;
|
||||
public const ushort SET_FL_IR = 59;
|
||||
public const ushort I_BIT = 60;
|
||||
public const ushort HL_BIT = 61;
|
||||
public const ushort FTCH_DB = 62;
|
||||
public const ushort WAIT = 63; // enterred when readin or writing and FlagW is true
|
||||
public const ushort RD_INC = 6; // read and increment
|
||||
public const ushort WR_INC = 7; // write and increment
|
||||
public const ushort WR_DEC = 8; // write and increment (for stack pointer)
|
||||
public const ushort TR = 9;
|
||||
public const ushort TR16 = 10;
|
||||
public const ushort ADD16 = 11;
|
||||
public const ushort ADD8 = 12;
|
||||
public const ushort SUB8 = 13;
|
||||
public const ushort ADC8 = 14;
|
||||
public const ushort SBC8 = 15;
|
||||
public const ushort SBC16 = 16;
|
||||
public const ushort ADC16 = 17;
|
||||
public const ushort INC16 = 18;
|
||||
public const ushort INC8 = 19;
|
||||
public const ushort DEC16 = 20;
|
||||
public const ushort DEC8 = 21;
|
||||
public const ushort RLC = 22;
|
||||
public const ushort RL = 23;
|
||||
public const ushort RRC = 24;
|
||||
public const ushort RR = 25;
|
||||
public const ushort CPL = 26;
|
||||
public const ushort DA = 27;
|
||||
public const ushort SCF = 28;
|
||||
public const ushort CCF = 29;
|
||||
public const ushort AND8 = 30;
|
||||
public const ushort XOR8 = 31;
|
||||
public const ushort OR8 = 32;
|
||||
public const ushort CP8 = 33;
|
||||
public const ushort SLA = 34;
|
||||
public const ushort SRA = 35;
|
||||
public const ushort SRL = 36;
|
||||
public const ushort SLL = 37;
|
||||
public const ushort BIT = 38;
|
||||
public const ushort RES = 39;
|
||||
public const ushort SET = 40;
|
||||
public const ushort EI = 41;
|
||||
public const ushort DI = 42;
|
||||
public const ushort EXCH = 43;
|
||||
public const ushort EXX = 44;
|
||||
public const ushort EXCH_16 = 45;
|
||||
public const ushort PREFIX = 46;
|
||||
public const ushort PREFETCH = 47;
|
||||
public const ushort ASGN = 48;
|
||||
public const ushort ADDS = 49; // signed 16 bit operation used in 2 instructions
|
||||
public const ushort INT_MODE = 50;
|
||||
public const ushort EI_RETN = 51;
|
||||
public const ushort EI_RETI = 52; // reti has no delay in interrupt enable
|
||||
public const ushort OUT = 53;
|
||||
public const ushort IN = 54;
|
||||
public const ushort NEG = 55;
|
||||
public const ushort RRD = 56;
|
||||
public const ushort RLD = 57;
|
||||
public const ushort SET_FL_LD_R = 58;
|
||||
public const ushort SET_FL_CP_R = 59;
|
||||
public const ushort SET_FL_IR = 60;
|
||||
public const ushort I_BIT = 61;
|
||||
public const ushort HL_BIT = 62;
|
||||
public const ushort FTCH_DB = 63;
|
||||
public const ushort WAIT = 64; // enterred when readin or writing and FlagW is true
|
||||
public const ushort RST = 65;
|
||||
public const ushort REP_OP_I = 66;
|
||||
public const ushort REP_OP_O = 67;
|
||||
|
||||
// non-state variables
|
||||
public ushort Ztemp1, Ztemp2, Ztemp3, Ztemp4;
|
||||
public byte temp_R;
|
||||
|
||||
public Z80A()
|
||||
|
@ -90,8 +96,15 @@ namespace BizHawk.Emulation.Cores.Components.Z80A
|
|||
ResetRegisters();
|
||||
ResetInterrupts();
|
||||
TotalExecutedCycles = 0;
|
||||
cur_instr = new ushort[] { OP };
|
||||
instr_pntr = 0;
|
||||
cur_instr = new ushort[]
|
||||
{ IDLE,
|
||||
WAIT,
|
||||
OP_F,
|
||||
OP };
|
||||
|
||||
BUSRQ = new ushort[] { PCh, 0, 0, 0 };
|
||||
MEMRQ = new ushort[] { PCh, 0, 0, 0 };
|
||||
instr_pntr = 0; bus_pntr = 0; mem_pntr = 0;
|
||||
NO_prefix = true;
|
||||
}
|
||||
|
||||
|
@ -147,6 +160,14 @@ namespace BizHawk.Emulation.Cores.Components.Z80A
|
|||
// Execute instructions
|
||||
public void ExecuteOne()
|
||||
{
|
||||
//FlagI6 = FlagI5;
|
||||
FlagI5 = FlagI4;
|
||||
FlagI4 = FlagI3;
|
||||
FlagI3 = FlagI2;
|
||||
FlagI2 = FlagI1;
|
||||
FlagI1 = FlagI;
|
||||
|
||||
bus_pntr++; mem_pntr++;
|
||||
switch (cur_instr[instr_pntr++])
|
||||
{
|
||||
case IDLE:
|
||||
|
@ -174,9 +195,9 @@ namespace BizHawk.Emulation.Cores.Components.Z80A
|
|||
iff1 = false;
|
||||
NMI_();
|
||||
NMICallback();
|
||||
instr_pntr = 0;
|
||||
instr_pntr = 0; bus_pntr = 0; mem_pntr = 0;
|
||||
}
|
||||
else if (iff1 && FlagI)
|
||||
else if (iff1 && FlagI5)
|
||||
{
|
||||
iff1 = iff2 = false;
|
||||
EI_pending = 0;
|
||||
|
@ -201,23 +222,15 @@ namespace BizHawk.Emulation.Cores.Components.Z80A
|
|||
break;
|
||||
}
|
||||
IRQCallback();
|
||||
instr_pntr = 0;
|
||||
instr_pntr = 0; bus_pntr = 0; mem_pntr = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
if(!FlagW)
|
||||
{
|
||||
if (OnExecFetch != null) OnExecFetch(RegPC);
|
||||
if (TraceCallback != null) TraceCallback(State());
|
||||
FetchInstruction(FetchMemory(RegPC++));
|
||||
instr_pntr = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
instr_pntr--;
|
||||
instr_swap = OP;
|
||||
cur_instr[instr_pntr] = WAIT;
|
||||
}
|
||||
if (OnExecFetch != null) OnExecFetch(RegPC);
|
||||
if (TraceCallback != null) TraceCallback(State());
|
||||
RegPC++;
|
||||
FetchInstruction();
|
||||
instr_pntr = 0; bus_pntr = 0; mem_pntr = 0;
|
||||
}
|
||||
|
||||
temp_R = (byte)(Regs[R] & 0x7F);
|
||||
|
@ -225,143 +238,9 @@ namespace BizHawk.Emulation.Cores.Components.Z80A
|
|||
temp_R &= 0x7F;
|
||||
Regs[R] = (byte)((Regs[R] & 0x80) | temp_R);
|
||||
break;
|
||||
case OP_R:
|
||||
// determine if we repeat based on what operation we are doing
|
||||
// single execution versions also come here, but never repeat
|
||||
ushort temp1 = cur_instr[instr_pntr++];
|
||||
ushort temp2 = cur_instr[instr_pntr++];
|
||||
ushort temp3 = cur_instr[instr_pntr++];
|
||||
|
||||
bool repeat = false;
|
||||
int Reg16_d = Regs[C] | (Regs[B] << 8);
|
||||
switch (temp1)
|
||||
{
|
||||
case 0:
|
||||
repeat = Reg16_d != 0;
|
||||
break;
|
||||
case 1:
|
||||
repeat = (Reg16_d != 0) && !FlagZ;
|
||||
break;
|
||||
case 2:
|
||||
repeat = Regs[B] != 0;
|
||||
break;
|
||||
case 3:
|
||||
repeat = Regs[B] != 0;
|
||||
break;
|
||||
}
|
||||
|
||||
// if we repeat, we do a 5 cycle refresh which decrements PC by 2
|
||||
// if we don't repeat, continue on as a normal opcode fetch
|
||||
if (repeat && temp3 > 0)
|
||||
{
|
||||
cur_instr = new ushort[]
|
||||
{IDLE,
|
||||
DEC16, PCl, PCh,
|
||||
IDLE,
|
||||
DEC16, PCl, PCh,
|
||||
OP };
|
||||
|
||||
instr_pntr = 0;
|
||||
// adjust WZ register accordingly
|
||||
switch (temp1)
|
||||
{
|
||||
case 0:
|
||||
// TEST: PC before or after the instruction?
|
||||
Regs[Z] = Regs[PCl];
|
||||
Regs[W] = Regs[PCh];
|
||||
INC16_Func(Z, W);
|
||||
break;
|
||||
case 1:
|
||||
// TEST: PC before or after the instruction?
|
||||
Regs[Z] = Regs[PCl];
|
||||
Regs[W] = Regs[PCh];
|
||||
INC16_Func(Z, W);
|
||||
break;
|
||||
case 2:
|
||||
// Nothing
|
||||
break;
|
||||
case 3:
|
||||
// Nothing
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Interrupts can occur at this point, so process them accordingly
|
||||
// Read the opcode of the next instruction
|
||||
if (EI_pending > 0)
|
||||
{
|
||||
EI_pending--;
|
||||
if (EI_pending == 0) { IFF1 = IFF2 = true; }
|
||||
}
|
||||
|
||||
// Process interrupt requests.
|
||||
if (nonMaskableInterruptPending)
|
||||
{
|
||||
nonMaskableInterruptPending = false;
|
||||
|
||||
if (TraceCallback != null)
|
||||
{
|
||||
TraceCallback(new TraceInfo{Disassembly = "====NMI====", RegisterInfo = ""});
|
||||
}
|
||||
|
||||
iff2 = iff1;
|
||||
iff1 = false;
|
||||
NMI_();
|
||||
NMICallback();
|
||||
instr_pntr = 0;
|
||||
}
|
||||
else if (iff1 && FlagI)
|
||||
{
|
||||
iff1 = iff2 = false;
|
||||
EI_pending = 0;
|
||||
|
||||
if (TraceCallback != null)
|
||||
{
|
||||
TraceCallback(new TraceInfo{Disassembly = "====IRQ====", RegisterInfo = ""});
|
||||
}
|
||||
|
||||
switch (interruptMode)
|
||||
{
|
||||
case 0:
|
||||
// Requires something to be pushed onto the data bus
|
||||
// we'll assume it's a zero for now
|
||||
INTERRUPT_0(0);
|
||||
break;
|
||||
case 1:
|
||||
INTERRUPT_1();
|
||||
break;
|
||||
case 2:
|
||||
INTERRUPT_2();
|
||||
break;
|
||||
}
|
||||
IRQCallback();
|
||||
instr_pntr = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!FlagW)
|
||||
{
|
||||
if (OnExecFetch != null) OnExecFetch(RegPC);
|
||||
if (TraceCallback != null) TraceCallback(State());
|
||||
FetchInstruction(FetchMemory(RegPC++));
|
||||
instr_pntr = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
instr_pntr--;
|
||||
instr_swap = OP;
|
||||
cur_instr[instr_pntr] = WAIT;
|
||||
}
|
||||
}
|
||||
|
||||
temp_R = (byte)(Regs[R] & 0x7F);
|
||||
temp_R++;
|
||||
temp_R &= 0x7F;
|
||||
Regs[R] = (byte)((Regs[R] & 0x80) | temp_R);
|
||||
}
|
||||
case OP_F:
|
||||
opcode = FetchMemory(RegPC);
|
||||
break;
|
||||
|
||||
case HALT:
|
||||
halted = true;
|
||||
// NOTE: Check how halt state effects the DB
|
||||
|
@ -389,7 +268,7 @@ namespace BizHawk.Emulation.Cores.Components.Z80A
|
|||
NMICallback();
|
||||
halted = false;
|
||||
}
|
||||
else if (iff1 && FlagI)
|
||||
else if (iff1 && FlagI5)
|
||||
{
|
||||
iff1 = iff2 = false;
|
||||
EI_pending = 0;
|
||||
|
@ -416,69 +295,28 @@ namespace BizHawk.Emulation.Cores.Components.Z80A
|
|||
IRQCallback();
|
||||
halted = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
cur_instr = new ushort[]
|
||||
{IDLE,
|
||||
IDLE,
|
||||
IDLE,
|
||||
HALT };
|
||||
}
|
||||
|
||||
temp_R = (byte)(Regs[R] & 0x7F);
|
||||
temp_R++;
|
||||
temp_R &= 0x7F;
|
||||
Regs[R] = (byte)((Regs[R] & 0x80) | temp_R);
|
||||
|
||||
instr_pntr = 0;
|
||||
instr_pntr = 0; bus_pntr = 0; mem_pntr = 0;
|
||||
break;
|
||||
case RD:
|
||||
if (!FlagW)
|
||||
{
|
||||
Read_Func(cur_instr[instr_pntr++], cur_instr[instr_pntr++], cur_instr[instr_pntr++]);
|
||||
}
|
||||
else
|
||||
{
|
||||
instr_pntr--;
|
||||
instr_swap = RD;
|
||||
cur_instr[instr_pntr] = WAIT;
|
||||
}
|
||||
|
||||
Read_Func(cur_instr[instr_pntr++], cur_instr[instr_pntr++], cur_instr[instr_pntr++]);
|
||||
break;
|
||||
case WR:
|
||||
if (!FlagW)
|
||||
{
|
||||
Write_Func(cur_instr[instr_pntr++], cur_instr[instr_pntr++], cur_instr[instr_pntr++]);
|
||||
}
|
||||
else
|
||||
{
|
||||
instr_pntr--;
|
||||
instr_swap = WR;
|
||||
cur_instr[instr_pntr] = WAIT;
|
||||
}
|
||||
Write_Func(cur_instr[instr_pntr++], cur_instr[instr_pntr++], cur_instr[instr_pntr++]);
|
||||
break;
|
||||
case I_RD:
|
||||
if (!FlagW)
|
||||
{
|
||||
I_Read_Func(cur_instr[instr_pntr++], cur_instr[instr_pntr++], cur_instr[instr_pntr++], cur_instr[instr_pntr++]);
|
||||
}
|
||||
else
|
||||
{
|
||||
instr_pntr--;
|
||||
instr_swap = I_RD;
|
||||
cur_instr[instr_pntr] = WAIT;
|
||||
}
|
||||
case RD_INC:
|
||||
Read_INC_Func(cur_instr[instr_pntr++], cur_instr[instr_pntr++], cur_instr[instr_pntr++]);
|
||||
break;
|
||||
case I_WR:
|
||||
if (!FlagW)
|
||||
{
|
||||
I_Write_Func(cur_instr[instr_pntr++], cur_instr[instr_pntr++], cur_instr[instr_pntr++], cur_instr[instr_pntr++]);
|
||||
}
|
||||
else
|
||||
{
|
||||
instr_pntr--;
|
||||
instr_swap =I_WR;
|
||||
cur_instr[instr_pntr] = WAIT;
|
||||
}
|
||||
case WR_INC:
|
||||
Write_INC_Func(cur_instr[instr_pntr++], cur_instr[instr_pntr++], cur_instr[instr_pntr++]);
|
||||
break;
|
||||
case WR_DEC:
|
||||
Write_DEC_Func(cur_instr[instr_pntr++], cur_instr[instr_pntr++], cur_instr[instr_pntr++]);
|
||||
break;
|
||||
case TR:
|
||||
TR_Func(cur_instr[instr_pntr++], cur_instr[instr_pntr++]);
|
||||
|
@ -603,11 +441,12 @@ namespace BizHawk.Emulation.Cores.Components.Z80A
|
|||
if (prefix_src == EXTDpre) { EXTD_prefix = true; }
|
||||
if (prefix_src == IXpre) { IX_prefix = true; }
|
||||
if (prefix_src == IYpre) { IY_prefix = true; }
|
||||
if (prefix_src == IXCBpre) { IXCB_prefix = true; IXCB_prefetch = true; }
|
||||
if (prefix_src == IYCBpre) { IYCB_prefix = true; IYCB_prefetch = true; }
|
||||
if (prefix_src == IXCBpre) { IXCB_prefix = true; }
|
||||
if (prefix_src == IYCBpre) { IYCB_prefix = true; }
|
||||
|
||||
FetchInstruction(FetchMemory(RegPC++));
|
||||
instr_pntr = 0;
|
||||
RegPC++;
|
||||
FetchInstruction();
|
||||
instr_pntr = 0; bus_pntr = 0; mem_pntr = 0;
|
||||
// only the first prefix in a double prefix increases R, although I don't know how / why
|
||||
if (prefix_src < 4)
|
||||
{
|
||||
|
@ -632,28 +471,10 @@ namespace BizHawk.Emulation.Cores.Components.Z80A
|
|||
iff1 = iff2;
|
||||
break;
|
||||
case OUT:
|
||||
if (!FlagW)
|
||||
{
|
||||
OUT_Func(cur_instr[instr_pntr++], cur_instr[instr_pntr++], cur_instr[instr_pntr++]);
|
||||
}
|
||||
else
|
||||
{
|
||||
instr_pntr--;
|
||||
instr_swap = OUT;
|
||||
cur_instr[instr_pntr] = WAIT;
|
||||
}
|
||||
OUT_Func(cur_instr[instr_pntr++], cur_instr[instr_pntr++], cur_instr[instr_pntr++]);
|
||||
break;
|
||||
case IN:
|
||||
if (!FlagW)
|
||||
{
|
||||
IN_Func(cur_instr[instr_pntr++], cur_instr[instr_pntr++], cur_instr[instr_pntr++]);
|
||||
}
|
||||
else
|
||||
{
|
||||
instr_pntr--;
|
||||
instr_swap = IN;
|
||||
cur_instr[instr_pntr] = WAIT;
|
||||
}
|
||||
IN_Func(cur_instr[instr_pntr++], cur_instr[instr_pntr++], cur_instr[instr_pntr++]);
|
||||
break;
|
||||
case NEG:
|
||||
NEG_8_Func(cur_instr[instr_pntr++]);
|
||||
|
@ -667,11 +488,78 @@ namespace BizHawk.Emulation.Cores.Components.Z80A
|
|||
case RLD:
|
||||
RLD_Func(cur_instr[instr_pntr++], cur_instr[instr_pntr++]);
|
||||
break;
|
||||
case SET_FL_LD:
|
||||
case SET_FL_LD_R:
|
||||
DEC16_Func(C, B);
|
||||
SET_FL_LD_Func();
|
||||
|
||||
Ztemp1 = cur_instr[instr_pntr++];
|
||||
Ztemp2 = cur_instr[instr_pntr++];
|
||||
Ztemp3 = cur_instr[instr_pntr++];
|
||||
|
||||
if (((Regs[C] | (Regs[B] << 8)) != 0) && (Ztemp3 > 0))
|
||||
{
|
||||
cur_instr = new ushort[]
|
||||
{DEC16, PCl, PCh,
|
||||
DEC16, PCl, PCh,
|
||||
TR16, Z, W, PCl, PCh,
|
||||
INC16, Z, W,
|
||||
IDLE,
|
||||
Ztemp2, E, D,
|
||||
WAIT,
|
||||
OP_F,
|
||||
OP};
|
||||
|
||||
BUSRQ = new ushort[] { D, D, D, D, D, PCh, 0, 0, 0 };
|
||||
MEMRQ = new ushort[] { 0, 0, 0, 0, 0, PCh, 0, 0, 0 };
|
||||
}
|
||||
else
|
||||
{
|
||||
cur_instr = new ushort[]
|
||||
{ Ztemp2, E, D,
|
||||
WAIT,
|
||||
OP_F,
|
||||
OP };
|
||||
|
||||
BUSRQ = new ushort[] { PCh, 0, 0, 0 };
|
||||
MEMRQ = new ushort[] { PCh, 0, 0, 0 };
|
||||
}
|
||||
instr_pntr = 0; bus_pntr = 0; mem_pntr = 0;
|
||||
break;
|
||||
case SET_FL_CP:
|
||||
case SET_FL_CP_R:
|
||||
SET_FL_CP_Func();
|
||||
|
||||
Ztemp1 = cur_instr[instr_pntr++];
|
||||
Ztemp2 = cur_instr[instr_pntr++];
|
||||
Ztemp3 = cur_instr[instr_pntr++];
|
||||
|
||||
if (((Regs[C] | (Regs[B] << 8)) != 0) && (Ztemp3 > 0) && !FlagZ)
|
||||
{
|
||||
cur_instr = new ushort[]
|
||||
{DEC16, PCl, PCh,
|
||||
DEC16, PCl, PCh,
|
||||
TR16, Z, W, PCl, PCh,
|
||||
INC16, Z, W,
|
||||
IDLE,
|
||||
Ztemp2, L, H,
|
||||
WAIT,
|
||||
OP_F,
|
||||
OP};
|
||||
|
||||
BUSRQ = new ushort[] { H, H, H, H, H, PCh, 0, 0, 0 };
|
||||
MEMRQ = new ushort[] { 0, 0, 0, 0, 0, PCh, 0, 0, 0 };
|
||||
}
|
||||
else
|
||||
{
|
||||
cur_instr = new ushort[]
|
||||
{ Ztemp2, L, H,
|
||||
WAIT,
|
||||
OP_F,
|
||||
OP };
|
||||
|
||||
BUSRQ = new ushort[] { PCh, 0, 0, 0 };
|
||||
MEMRQ = new ushort[] { PCh, 0, 0, 0 };
|
||||
}
|
||||
instr_pntr = 0; bus_pntr = 0; mem_pntr = 0;
|
||||
break;
|
||||
case SET_FL_IR:
|
||||
SET_FL_IR_Func(cur_instr[instr_pntr++]);
|
||||
|
@ -682,38 +570,135 @@ namespace BizHawk.Emulation.Cores.Components.Z80A
|
|||
case WAIT:
|
||||
if (FlagW)
|
||||
{
|
||||
instr_pntr--;
|
||||
instr_pntr--; bus_pntr--; mem_pntr--;
|
||||
}
|
||||
break;
|
||||
case RST:
|
||||
Regs[Z] = cur_instr[instr_pntr++];
|
||||
Regs[W] = 0;
|
||||
break;
|
||||
case REP_OP_I:
|
||||
Write_Func(cur_instr[instr_pntr++], cur_instr[instr_pntr++], cur_instr[instr_pntr++]);
|
||||
|
||||
Ztemp4 = cur_instr[instr_pntr++];
|
||||
if (Ztemp4 == DEC16)
|
||||
{
|
||||
TR16_Func(Z, W, C, B);
|
||||
DEC16_Func(Z, W);
|
||||
DEC8_Func(B);
|
||||
|
||||
// take care of other flags
|
||||
// taken from 'undocumented z80 documented' and Fuse
|
||||
FlagN = Regs[ALU].Bit(7);
|
||||
FlagH = FlagC = ((Regs[ALU] + Regs[C] - 1) & 0xFF) < Regs[ALU];
|
||||
FlagP = TableParity[((Regs[ALU] + Regs[C] - 1) & 7) ^ Regs[B]];
|
||||
}
|
||||
else
|
||||
{
|
||||
TR16_Func(Z, W, C, B);
|
||||
INC16_Func(Z, W);
|
||||
DEC8_Func(B);
|
||||
|
||||
// take care of other flags
|
||||
// taken from 'undocumented z80 documented' and Fuse
|
||||
FlagN = Regs[ALU].Bit(7);
|
||||
FlagH = FlagC = ((Regs[ALU] + Regs[C] + 1) & 0xFF) < Regs[ALU];
|
||||
FlagP = TableParity[((Regs[ALU] + Regs[C] + 1) & 7) ^ Regs[B]];
|
||||
}
|
||||
|
||||
Ztemp1 = cur_instr[instr_pntr++];
|
||||
Ztemp2 = cur_instr[instr_pntr++];
|
||||
Ztemp3 = cur_instr[instr_pntr++];
|
||||
|
||||
if ((Regs[B] != 0) && (Ztemp3 > 0))
|
||||
{
|
||||
cur_instr = new ushort[]
|
||||
{IDLE,
|
||||
IDLE,
|
||||
DEC16, PCl, PCh,
|
||||
DEC16, PCl, PCh,
|
||||
IDLE,
|
||||
Ztemp2, L, H,
|
||||
WAIT,
|
||||
OP_F,
|
||||
OP};
|
||||
|
||||
BUSRQ = new ushort[] { H, H, H, H, H, PCh, 0, 0, 0 };
|
||||
MEMRQ = new ushort[] { 0, 0, 0, 0, 0, PCh, 0, 0, 0 };
|
||||
}
|
||||
else
|
||||
{
|
||||
switch (instr_swap)
|
||||
{
|
||||
case OP:
|
||||
if (OnExecFetch != null) OnExecFetch(RegPC);
|
||||
if (TraceCallback != null) TraceCallback(State());
|
||||
FetchInstruction(FetchMemory(RegPC++));
|
||||
instr_pntr = 0;
|
||||
break;
|
||||
case RD:
|
||||
Read_Func(cur_instr[instr_pntr++], cur_instr[instr_pntr++], cur_instr[instr_pntr++]);
|
||||
break;
|
||||
case WR:
|
||||
Write_Func(cur_instr[instr_pntr++], cur_instr[instr_pntr++], cur_instr[instr_pntr++]);
|
||||
break;
|
||||
case I_RD:
|
||||
I_Read_Func(cur_instr[instr_pntr++], cur_instr[instr_pntr++], cur_instr[instr_pntr++], cur_instr[instr_pntr++]);
|
||||
break;
|
||||
case I_WR:
|
||||
I_Read_Func(cur_instr[instr_pntr++], cur_instr[instr_pntr++], cur_instr[instr_pntr++], cur_instr[instr_pntr++]);
|
||||
break;
|
||||
case IN:
|
||||
IN_Func(cur_instr[instr_pntr++], cur_instr[instr_pntr++], cur_instr[instr_pntr++]);
|
||||
break;
|
||||
case OUT:
|
||||
OUT_Func(cur_instr[instr_pntr++], cur_instr[instr_pntr++], cur_instr[instr_pntr++]);
|
||||
break;
|
||||
}
|
||||
cur_instr = new ushort[]
|
||||
{ Ztemp2, L, H,
|
||||
WAIT,
|
||||
OP_F,
|
||||
OP };
|
||||
|
||||
BUSRQ = new ushort[] { PCh, 0, 0, 0 };
|
||||
MEMRQ = new ushort[] { PCh, 0, 0, 0 };
|
||||
}
|
||||
instr_pntr = 0; bus_pntr = 0; mem_pntr = 0;
|
||||
break;
|
||||
case REP_OP_O:
|
||||
OUT_Func(cur_instr[instr_pntr++], cur_instr[instr_pntr++], cur_instr[instr_pntr++]);
|
||||
|
||||
Ztemp4 = cur_instr[instr_pntr++];
|
||||
if (Ztemp4 == DEC16)
|
||||
{
|
||||
DEC16_Func(L, H);
|
||||
DEC8_Func(B);
|
||||
TR16_Func(Z, W, C, B);
|
||||
DEC16_Func(Z, W);
|
||||
}
|
||||
else
|
||||
{
|
||||
INC16_Func(L, H);
|
||||
DEC8_Func(B);
|
||||
TR16_Func(Z, W, C, B);
|
||||
INC16_Func(Z, W);
|
||||
}
|
||||
|
||||
// take care of other flags
|
||||
// taken from 'undocumented z80 documented'
|
||||
FlagN = Regs[ALU].Bit(7);
|
||||
FlagH = FlagC = (Regs[ALU] + Regs[L]) > 0xFF;
|
||||
FlagP = TableParity[((Regs[ALU] + Regs[L]) & 7) ^ (Regs[B])];
|
||||
|
||||
Ztemp1 = cur_instr[instr_pntr++];
|
||||
Ztemp2 = cur_instr[instr_pntr++];
|
||||
Ztemp3 = cur_instr[instr_pntr++];
|
||||
|
||||
if ((Regs[B] != 0) && (Ztemp3 > 0))
|
||||
{
|
||||
cur_instr = new ushort[]
|
||||
{IDLE,
|
||||
IDLE,
|
||||
DEC16, PCl, PCh,
|
||||
DEC16, PCl, PCh,
|
||||
IDLE,
|
||||
IDLE,//DEC16, B, ALU,
|
||||
WAIT,
|
||||
OP_F,
|
||||
OP};
|
||||
|
||||
//Regs[B] = (ushort)((Regs[B] + 1) & 0xFF);
|
||||
|
||||
|
||||
BUSRQ = new ushort[] { B, B, B, B, B, PCh, 0, 0, 0 };
|
||||
MEMRQ = new ushort[] { 0, 0, 0, 0, 0, PCh, 0, 0, 0 };
|
||||
}
|
||||
else
|
||||
{
|
||||
cur_instr = new ushort[]
|
||||
{ IDLE,
|
||||
WAIT,
|
||||
OP_F,
|
||||
OP };
|
||||
|
||||
BUSRQ = new ushort[] { PCh, 0, 0, 0 };
|
||||
MEMRQ = new ushort[] { PCh, 0, 0, 0 };
|
||||
}
|
||||
instr_pntr = 0; bus_pntr = 0; mem_pntr = 0;
|
||||
break;
|
||||
}
|
||||
TotalExecutedCycles++;
|
||||
|
@ -787,10 +772,20 @@ namespace BizHawk.Emulation.Cores.Components.Z80A
|
|||
ser.Sync("EI_pending", ref EI_pending);
|
||||
|
||||
ser.Sync("instr_pntr", ref instr_pntr);
|
||||
ser.Sync("bus_pntr", ref bus_pntr);
|
||||
ser.Sync("mem_pntr", ref mem_pntr);
|
||||
ser.Sync("cur_instr", ref cur_instr, false);
|
||||
ser.Sync("BUSRQ", ref BUSRQ, false);
|
||||
ser.Sync("MEMRQ", ref MEMRQ, false);
|
||||
ser.Sync("instr_swap", ref instr_swap);
|
||||
ser.Sync("opcode", ref opcode);
|
||||
ser.Sync("FlagI", ref FlagI);
|
||||
ser.Sync("FlagI1", ref FlagI1);
|
||||
ser.Sync("FlagI2", ref FlagI2);
|
||||
ser.Sync("FlagI3", ref FlagI3);
|
||||
ser.Sync("FlagI4", ref FlagI4);
|
||||
ser.Sync("FlagI5", ref FlagI5);
|
||||
ser.Sync("FlagI6", ref FlagI6);
|
||||
ser.Sync("FlagW", ref FlagW);
|
||||
|
||||
ser.Sync("NO Preifx", ref NO_prefix);
|
||||
|
|
|
@ -0,0 +1,409 @@
|
|||
using BizHawk.Common;
|
||||
using BizHawk.Emulation.Cores.Components.Z80A;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace BizHawk.Emulation.Cores.Computers.SinclairSpectrum
|
||||
{
|
||||
public class CPUMonitor
|
||||
{
|
||||
#region Devices
|
||||
|
||||
private SpectrumBase _machine;
|
||||
private Z80A _cpu;
|
||||
public MachineType machineType = MachineType.ZXSpectrum48;
|
||||
|
||||
#endregion
|
||||
|
||||
#region Lookups
|
||||
|
||||
/// <summary>
|
||||
/// CPU total executes t-states
|
||||
/// </summary>
|
||||
public long TotalExecutedCycles => _cpu.TotalExecutedCycles;
|
||||
|
||||
/// <summary>
|
||||
/// Current BUSRQ line array
|
||||
/// </summary>
|
||||
public ushort BUSRQ
|
||||
{
|
||||
get
|
||||
{
|
||||
switch (machineType)
|
||||
{
|
||||
case MachineType.ZXSpectrum128Plus2a:
|
||||
case MachineType.ZXSpectrum128Plus3:
|
||||
return _cpu.MEMRQ[_cpu.bus_pntr];
|
||||
default:
|
||||
return _cpu.BUSRQ[_cpu.mem_pntr];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Construction
|
||||
|
||||
public CPUMonitor(SpectrumBase machine)
|
||||
{
|
||||
_machine = machine;
|
||||
_cpu = _machine.CPU;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region State
|
||||
|
||||
/// <summary>
|
||||
/// The last 16-bit port address that was detected
|
||||
/// </summary>
|
||||
public ushort lastPortAddr;
|
||||
|
||||
/// <summary>
|
||||
/// If true, the next read memory operation has been contended
|
||||
/// </summary>
|
||||
public bool NextMemReadContended;
|
||||
|
||||
#endregion
|
||||
|
||||
#region Methods
|
||||
|
||||
/// <summary>
|
||||
/// Handles the ULA and CPU cycle clocks, along with any memory and port contention
|
||||
/// </summary>
|
||||
public void ExecuteCycle()
|
||||
{
|
||||
// simulate the ULA clock cycle before the CPU cycle
|
||||
_machine.ULADevice.CycleClock(TotalExecutedCycles);
|
||||
|
||||
// is the next CPU cycle causing a BUSRQ or IORQ?
|
||||
if (BUSRQ > 0)
|
||||
{
|
||||
// check for IORQ
|
||||
if (!CheckIO())
|
||||
{
|
||||
// is the memory address of the BUSRQ potentially contended?
|
||||
if (_machine.IsContended(AscertainBUSRQAddress()))
|
||||
{
|
||||
var cont = _machine.ULADevice.GetContentionValue((int)_machine.CurrentFrameCycle);
|
||||
if (cont > 0)
|
||||
{
|
||||
_cpu.TotalExecutedCycles += cont;
|
||||
NextMemReadContended = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
_cpu.ExecuteOne();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up the current BUSRQ address that is about to be signalled on the upcoming cycle
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
private ushort AscertainBUSRQAddress()
|
||||
{
|
||||
ushort addr = 0;
|
||||
switch (BUSRQ)
|
||||
{
|
||||
// PCh
|
||||
case 1:
|
||||
addr = (ushort)(_cpu.Regs[_cpu.PCl] | _cpu.Regs[_cpu.PCh] << 8);
|
||||
break;
|
||||
// SPh
|
||||
case 3:
|
||||
addr = (ushort)(_cpu.Regs[_cpu.SPl] | _cpu.Regs[_cpu.SPh] << 8);
|
||||
break;
|
||||
// A
|
||||
case 4:
|
||||
addr = (ushort)(_cpu.Regs[_cpu.F] | _cpu.Regs[_cpu.A] << 8);
|
||||
break;
|
||||
// B
|
||||
case 6:
|
||||
addr = (ushort)(_cpu.Regs[_cpu.C] | _cpu.Regs[_cpu.B] << 8);
|
||||
break;
|
||||
// D
|
||||
case 8:
|
||||
addr = (ushort)(_cpu.Regs[_cpu.E] | _cpu.Regs[_cpu.D] << 8);
|
||||
break;
|
||||
// H
|
||||
case 10:
|
||||
addr = (ushort)(_cpu.Regs[_cpu.L] | _cpu.Regs[_cpu.H] << 8);
|
||||
break;
|
||||
// W
|
||||
case 12:
|
||||
addr = (ushort)(_cpu.Regs[_cpu.Z] | _cpu.Regs[_cpu.W] << 8);
|
||||
break;
|
||||
// Ixh
|
||||
case 16:
|
||||
addr = (ushort)(_cpu.Regs[_cpu.Ixl] | _cpu.Regs[_cpu.Ixh] << 8);
|
||||
break;
|
||||
// Iyh
|
||||
case 18:
|
||||
addr = (ushort)(_cpu.Regs[_cpu.Iyl] | _cpu.Regs[_cpu.Iyh] << 8);
|
||||
break;
|
||||
// I
|
||||
case 21:
|
||||
addr = (ushort)(_cpu.Regs[_cpu.R] | _cpu.Regs[_cpu.I] << 8);
|
||||
break;
|
||||
// BC
|
||||
case Z80A.BIO1:
|
||||
case Z80A.BIO2:
|
||||
case Z80A.BIO3:
|
||||
case Z80A.BIO4:
|
||||
addr = (ushort)(_cpu.Regs[_cpu.C] | _cpu.Regs[_cpu.B] << 8);
|
||||
break;
|
||||
// WZ
|
||||
case Z80A.WIO1:
|
||||
case Z80A.WIO2:
|
||||
case Z80A.WIO3:
|
||||
case Z80A.WIO4:
|
||||
addr = (ushort)(_cpu.Regs[_cpu.Z] | _cpu.Regs[_cpu.W] << 8);
|
||||
break;
|
||||
}
|
||||
|
||||
return addr;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Running every cycle, this determines whether the upcoming BUSRQ is for an IO operation
|
||||
/// Also processes any contention
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
private bool CheckIO()
|
||||
{
|
||||
bool isIO = false;
|
||||
|
||||
switch (BUSRQ)
|
||||
{
|
||||
// BC: T1
|
||||
case Z80A.BIO1:
|
||||
lastPortAddr = AscertainBUSRQAddress();
|
||||
isIO = true;
|
||||
if (IsIOCycleContended(1))
|
||||
_cpu.TotalExecutedCycles += _machine.ULADevice.GetPortContentionValue((int)_machine.CurrentFrameCycle);
|
||||
break;
|
||||
// BC: T2
|
||||
case Z80A.BIO2:
|
||||
lastPortAddr = AscertainBUSRQAddress();
|
||||
isIO = true;
|
||||
if (IsIOCycleContended(2))
|
||||
_cpu.TotalExecutedCycles += _machine.ULADevice.GetPortContentionValue((int)_machine.CurrentFrameCycle);
|
||||
break;
|
||||
// BC: T3
|
||||
case Z80A.BIO3:
|
||||
lastPortAddr = AscertainBUSRQAddress();
|
||||
isIO = true;
|
||||
if (IsIOCycleContended(3))
|
||||
_cpu.TotalExecutedCycles += _machine.ULADevice.GetPortContentionValue((int)_machine.CurrentFrameCycle);
|
||||
break;
|
||||
// BC: T4
|
||||
case Z80A.BIO4:
|
||||
lastPortAddr = AscertainBUSRQAddress();
|
||||
isIO = true;
|
||||
if (IsIOCycleContended(4))
|
||||
_cpu.TotalExecutedCycles += _machine.ULADevice.GetPortContentionValue((int)_machine.CurrentFrameCycle);
|
||||
break;
|
||||
|
||||
// WZ: T1
|
||||
case Z80A.WIO1:
|
||||
lastPortAddr = AscertainBUSRQAddress();
|
||||
isIO = true;
|
||||
if (IsIOCycleContended(1))
|
||||
_cpu.TotalExecutedCycles += _machine.ULADevice.GetPortContentionValue((int)_machine.CurrentFrameCycle);
|
||||
break;
|
||||
// WZ: T2
|
||||
case Z80A.WIO2:
|
||||
lastPortAddr = AscertainBUSRQAddress();
|
||||
isIO = true;
|
||||
if (IsIOCycleContended(2))
|
||||
_cpu.TotalExecutedCycles += _machine.ULADevice.GetPortContentionValue((int)_machine.CurrentFrameCycle);
|
||||
break;
|
||||
// WZ: T3
|
||||
case Z80A.WIO3:
|
||||
lastPortAddr = AscertainBUSRQAddress();
|
||||
isIO = true;
|
||||
if (IsIOCycleContended(3))
|
||||
_cpu.TotalExecutedCycles += _machine.ULADevice.GetPortContentionValue((int)_machine.CurrentFrameCycle);
|
||||
break;
|
||||
// WZ: T4
|
||||
case Z80A.WIO4:
|
||||
lastPortAddr = AscertainBUSRQAddress();
|
||||
isIO = true;
|
||||
if (IsIOCycleContended(4))
|
||||
_cpu.TotalExecutedCycles += _machine.ULADevice.GetPortContentionValue((int)_machine.CurrentFrameCycle);
|
||||
break;
|
||||
}
|
||||
|
||||
return isIO;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns TRUE if the supplied T-cycle within an IO operation has the possibility of being contended
|
||||
/// This can be different based on the emulated ZX Spectrum model
|
||||
/// </summary>
|
||||
/// <param name="T"></param>
|
||||
/// <returns></returns>
|
||||
private bool IsIOCycleContended(int T)
|
||||
{
|
||||
bool lowBitSet = (lastPortAddr & 0x0001) != 0;
|
||||
bool highByte407f = false;
|
||||
|
||||
switch (machineType)
|
||||
{
|
||||
case MachineType.ZXSpectrum16:
|
||||
case MachineType.ZXSpectrum48:
|
||||
|
||||
if ((lastPortAddr & 0xc000) == 0x4000)
|
||||
highByte407f = true;
|
||||
|
||||
if (highByte407f)
|
||||
{
|
||||
// high byte 40-7f
|
||||
if (lowBitSet)
|
||||
{
|
||||
// high byte 40-7f
|
||||
// low bit set
|
||||
// C:1, C:1, C:1, C:1
|
||||
switch (T)
|
||||
{
|
||||
case 1:
|
||||
case 2:
|
||||
case 3:
|
||||
case 4:
|
||||
return true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// high byte 40-7f
|
||||
// low bit reset
|
||||
// C:1, C:3
|
||||
switch (T)
|
||||
{
|
||||
case 1:
|
||||
case 2:
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// high byte not 40-7f
|
||||
if (lowBitSet)
|
||||
{
|
||||
// high byte not 40-7f
|
||||
// low bit set
|
||||
// N:4
|
||||
}
|
||||
else
|
||||
{
|
||||
// high byte not 40-7f
|
||||
// low bit reset
|
||||
// N:1, C:3
|
||||
switch (T)
|
||||
{
|
||||
case 2:
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case MachineType.ZXSpectrum128:
|
||||
case MachineType.ZXSpectrum128Plus2:
|
||||
if ((lastPortAddr & 0xc000) == 0x4000 || (lastPortAddr & 0xc000) == 0xc000 && _machine.ContendedBankPaged())
|
||||
highByte407f = true;
|
||||
|
||||
if (highByte407f)
|
||||
{
|
||||
// high byte 40-7f
|
||||
if (lowBitSet)
|
||||
{
|
||||
// high byte 40-7f
|
||||
// low bit set
|
||||
// C:1, C:1, C:1, C:1
|
||||
switch (T)
|
||||
{
|
||||
case 1:
|
||||
case 2:
|
||||
case 3:
|
||||
case 4:
|
||||
return true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// high byte 40-7f
|
||||
// low bit reset
|
||||
// C:1, C:3
|
||||
switch (T)
|
||||
{
|
||||
case 1:
|
||||
case 2:
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// high byte not 40-7f
|
||||
if (lowBitSet)
|
||||
{
|
||||
// high byte not 40-7f
|
||||
// low bit set
|
||||
// N:4
|
||||
}
|
||||
else
|
||||
{
|
||||
// high byte not 40-7f
|
||||
// low bit reset
|
||||
// N:1, C:3
|
||||
switch (T)
|
||||
{
|
||||
case 2:
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case MachineType.ZXSpectrum128Plus2a:
|
||||
case MachineType.ZXSpectrum128Plus3:
|
||||
// No contention occurs as the ULA only applies contention when the Z80 MREQ line is active
|
||||
// (which is not during an IO operation)
|
||||
break;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Called when the first byte of an instruction is fetched
|
||||
/// </summary>
|
||||
/// <param name="firstByte"></param>
|
||||
public void OnExecFetch(ushort firstByte)
|
||||
{
|
||||
// fetch instruction without incrementing pc
|
||||
//_cpu.FetchInstruction(_cpu.FetchMemory(firstByte));
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Serialization
|
||||
|
||||
public void SyncState(Serializer ser)
|
||||
{
|
||||
ser.BeginSection("CPUMonitor");
|
||||
ser.Sync("lastPortAddr", ref lastPortAddr);
|
||||
ser.Sync("NextMemReadContended", ref NextMemReadContended);
|
||||
ser.EndSection();
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
|
@ -50,7 +50,7 @@ namespace BizHawk.Emulation.Cores.Computers.SinclairSpectrum
|
|||
/// Signs that all paging is disabled
|
||||
/// If this is TRUE, then 128k and above machines need a hard reset before paging is allowed again
|
||||
/// </summary>
|
||||
protected bool PagingDisabled;
|
||||
public bool PagingDisabled;
|
||||
|
||||
/// <summary>
|
||||
/// Index of the currently paged ROM
|
||||
|
@ -87,10 +87,13 @@ namespace BizHawk.Emulation.Cores.Computers.SinclairSpectrum
|
|||
/// </summary>
|
||||
protected int PagingConfiguration;
|
||||
|
||||
/// <summary>
|
||||
/// The last byte that was read after contended cycles
|
||||
/// </summary>
|
||||
public byte LastContendedReadByte;
|
||||
|
||||
#endregion
|
||||
|
||||
|
||||
|
||||
#region Memory Related Methods
|
||||
|
||||
/// <summary>
|
||||
|
@ -153,9 +156,23 @@ namespace BizHawk.Emulation.Cores.Computers.SinclairSpectrum
|
|||
public virtual byte FetchScreenMemory(ushort addr)
|
||||
{
|
||||
var value = ReadBus((ushort)((addr & 0x3FFF) + 0x4000));
|
||||
//var value = ReadBus(addr);
|
||||
return value;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Checks whether supplied address is in a potentially contended bank
|
||||
/// </summary>
|
||||
/// <param name="addr"></param>
|
||||
public abstract bool IsContended(ushort addr);
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Returns TRUE if there is a contended bank paged in
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public abstract bool ContendedBankPaged();
|
||||
|
||||
#endregion
|
||||
|
||||
#region Helper Methods
|
||||
|
|
|
@ -40,88 +40,17 @@ namespace BizHawk.Emulation.Cores.Computers.SinclairSpectrum
|
|||
/// Increments the CPU totalCycles counter by the tStates value specified
|
||||
/// </summary>
|
||||
/// <param name="tStates"></param>
|
||||
public virtual void PortContention(int tStates)
|
||||
{
|
||||
CPU.TotalExecutedCycles += tStates;
|
||||
}
|
||||
//public virtual void PortContention(int tStates)
|
||||
//{
|
||||
// CPU.TotalExecutedCycles += tStates;
|
||||
//}
|
||||
|
||||
/// <summary>
|
||||
/// Simulates IO port contention based on the supplied address
|
||||
/// This method is for 48k and 128k/+2 machines only and should be overridden for other models
|
||||
/// </summary>
|
||||
/// <param name="addr"></param>
|
||||
public virtual void ContendPortAddress(ushort addr)
|
||||
{
|
||||
return;
|
||||
|
||||
/*
|
||||
It takes four T states for the Z80 to read a value from an I/O port, or write a value to a port. As is the case with memory access,
|
||||
this can be lengthened by the ULA. There are two effects which occur here:
|
||||
|
||||
If the port address being accessed has its low bit reset, the ULA is required to supply the result, which leads to a delay if it is
|
||||
currently busy handling the screen.
|
||||
The address of the port being accessed is placed on the data bus. If this is in the range 0x4000 to 0x7fff, the ULA treats this as an
|
||||
attempted access to contended memory and therefore introduces a delay. If the port being accessed is between 0xc000 and 0xffff,
|
||||
this effect does not apply, even on a 128K machine if a contended memory bank is paged into the range 0xc000 to 0xffff.
|
||||
|
||||
These two effects combine to lead to the following contention patterns:
|
||||
|
||||
High byte | |
|
||||
in 40 - 7F? | Low bit | Contention pattern
|
||||
------------+---------+-------------------
|
||||
No | Reset | N:1, C:3
|
||||
No | Set | N:4
|
||||
Yes | Reset | C:1, C:3
|
||||
Yes | Set | C:1, C:1, C:1, C:1
|
||||
|
||||
The 'Contention pattern' column should be interpreted from left to right. An "N:n" entry means that no delay is applied at this cycle, and the Z80 continues uninterrupted for 'n' T states. A "C:n" entry means that the ULA halts the Z80; the delay is exactly the same as would occur for a contended memory access at this cycle (eg 6 T states at cycle 14335, 5 at 14336, etc on the 48K machine). After this delay, the Z80 then continues for 'n' cycles.
|
||||
*/
|
||||
|
||||
// is the low bit reset (i.e. is this addressing the ULA)?
|
||||
bool lowBit = (addr & 0x0001) != 0;
|
||||
|
||||
if ((addr & 0xc000) == 0x4000 || (addr & 0xc000) == 0xC000)
|
||||
{
|
||||
// high byte is in 40 - 7F
|
||||
if (lowBit)
|
||||
{
|
||||
// lowbit is set
|
||||
// C:1, C:1, C:1, C:1
|
||||
for (int i = 0; i < 4; i++)
|
||||
{
|
||||
CPU.TotalExecutedCycles += ULADevice.contentionTable[CurrentFrameCycle];
|
||||
CPU.TotalExecutedCycles++;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// low bit is reset
|
||||
// C:1, C:3
|
||||
CPU.TotalExecutedCycles += ULADevice.contentionTable[CurrentFrameCycle];
|
||||
CPU.TotalExecutedCycles++;
|
||||
CPU.TotalExecutedCycles += ULADevice.contentionTable[CurrentFrameCycle];
|
||||
CPU.TotalExecutedCycles += 3;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// high byte is NOT in 40 - 7F
|
||||
if (lowBit)
|
||||
{
|
||||
// lowbit is set
|
||||
// C:1, C:1, C:1, C:1
|
||||
CPU.TotalExecutedCycles += 4;
|
||||
}
|
||||
else
|
||||
{
|
||||
// lowbit is reset
|
||||
// N:1, C:3
|
||||
CPU.TotalExecutedCycles++;
|
||||
CPU.TotalExecutedCycles += ULADevice.contentionTable[CurrentFrameCycle];
|
||||
CPU.TotalExecutedCycles += 3;
|
||||
}
|
||||
}
|
||||
}
|
||||
//public abstract void ContendPort(ushort addr);
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -32,7 +32,13 @@ namespace BizHawk.Emulation.Cores.Computers.SinclairSpectrum
|
|||
/// <summary>
|
||||
/// The emulated ULA device
|
||||
/// </summary>
|
||||
public ULABase ULADevice { get; set; }
|
||||
//public ULABase ULADevice { get; set; }
|
||||
public ULA ULADevice { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Monitors CPU cycles
|
||||
/// </summary>
|
||||
public CPUMonitor CPUMon { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The spectrum buzzer/beeper
|
||||
|
@ -141,6 +147,9 @@ namespace BizHawk.Emulation.Cores.Computers.SinclairSpectrum
|
|||
/// </summary>
|
||||
public virtual void ExecuteFrame(bool render, bool renderSound)
|
||||
{
|
||||
ULADevice.FrameEnd = false;
|
||||
ULADevice.ULACycleCounter = CurrentFrameCycle;
|
||||
|
||||
InputRead = false;
|
||||
_render = render;
|
||||
_renderSound = renderSound;
|
||||
|
@ -152,49 +161,42 @@ namespace BizHawk.Emulation.Cores.Computers.SinclairSpectrum
|
|||
|
||||
if (_renderSound)
|
||||
{
|
||||
//BuzzerDevice.StartFrame();
|
||||
//TapeBuzzer.StartFrame();
|
||||
|
||||
if (AYDevice != null)
|
||||
AYDevice.StartFrame();
|
||||
}
|
||||
|
||||
PollInput();
|
||||
|
||||
while (CurrentFrameCycle < ULADevice.FrameLength)
|
||||
for (;;)
|
||||
{
|
||||
// check for interrupt
|
||||
ULADevice.CheckForInterrupt(CurrentFrameCycle);
|
||||
|
||||
// run a single CPU instruction
|
||||
CPU.ExecuteOne();
|
||||
// run the CPU Monitor cycle
|
||||
CPUMon.ExecuteCycle();
|
||||
|
||||
// cycle the tape device
|
||||
if (UPDDiskDevice == null || !UPDDiskDevice.FDD_IsDiskLoaded)
|
||||
TapeDevice.TapeCycle();
|
||||
|
||||
// has frame end been reached?
|
||||
if (ULADevice.FrameEnd)
|
||||
break;
|
||||
}
|
||||
|
||||
OverFlow = (int)CurrentFrameCycle - ULADevice.FrameLength;
|
||||
|
||||
// we have reached the end of a frame
|
||||
LastFrameStartCPUTick = CPU.TotalExecutedCycles - OverFlow;
|
||||
|
||||
// paint the buffer if needed
|
||||
if (ULADevice.needsPaint && _render)
|
||||
ULADevice.UpdateScreenBuffer(ULADevice.FrameLength);
|
||||
// paint the buffer at end of frame
|
||||
if (_render)
|
||||
ULADevice.RenderScreen(ULADevice.FrameLength);
|
||||
|
||||
if (_renderSound)
|
||||
{
|
||||
//BuzzerDevice.EndFrame();
|
||||
//TapeBuzzer.EndFrame();
|
||||
}
|
||||
ULADevice.LastTState = 0;
|
||||
|
||||
if (AYDevice != null)
|
||||
AYDevice.EndFrame();
|
||||
|
||||
FrameCount++;
|
||||
|
||||
// setup for next frame
|
||||
ULADevice.ResetInterrupt();
|
||||
|
||||
|
||||
if (UPDDiskDevice == null || !UPDDiskDevice.FDD_IsDiskLoaded)
|
||||
TapeDevice.EndFrame();
|
||||
|
||||
|
@ -203,8 +205,7 @@ namespace BizHawk.Emulation.Cores.Computers.SinclairSpectrum
|
|||
// is this a lag frame?
|
||||
Spectrum.IsLagFrame = !InputRead;
|
||||
|
||||
// FDC debug
|
||||
|
||||
// FDC debug
|
||||
if (UPDDiskDevice != null && UPDDiskDevice.writeDebug)
|
||||
{
|
||||
// only write UPD log every second
|
||||
|
@ -223,7 +224,7 @@ namespace BizHawk.Emulation.Cores.Computers.SinclairSpectrum
|
|||
/// </summary>
|
||||
public virtual void HardReset()
|
||||
{
|
||||
ULADevice.ResetInterrupt();
|
||||
//ULADevice.ResetInterrupt();
|
||||
ROMPaged = 0;
|
||||
SpecialPagingMode = false;
|
||||
RAMPaged = 0;
|
||||
|
@ -275,7 +276,7 @@ namespace BizHawk.Emulation.Cores.Computers.SinclairSpectrum
|
|||
/// </summary>
|
||||
public virtual void SoftReset()
|
||||
{
|
||||
ULADevice.ResetInterrupt();
|
||||
//ULADevice.ResetInterrupt();
|
||||
ROMPaged = 0;
|
||||
SpecialPagingMode = false;
|
||||
RAMPaged = 0;
|
||||
|
@ -356,11 +357,13 @@ namespace BizHawk.Emulation.Cores.Computers.SinclairSpectrum
|
|||
ser.Sync("PagingConfiguration", ref PagingConfiguration);
|
||||
ser.Sync("ROMhigh", ref ROMhigh);
|
||||
ser.Sync("ROMlow", ref ROMlow);
|
||||
ser.Sync("LastContendedReadByte", ref LastContendedReadByte);
|
||||
|
||||
KeyboardDevice.SyncState(ser);
|
||||
BuzzerDevice.SyncState(ser);
|
||||
TapeBuzzer.SyncState(ser);
|
||||
ULADevice.SyncState(ser);
|
||||
CPUMon.SyncState(ser);
|
||||
|
||||
if (AYDevice != null)
|
||||
{
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -4,6 +4,7 @@ using BizHawk.Emulation.Common;
|
|||
|
||||
namespace BizHawk.Emulation.Cores.Computers.SinclairSpectrum
|
||||
{
|
||||
/*
|
||||
/// <summary>
|
||||
/// ULA (Uncommitted Logic Array) implementation
|
||||
/// </summary>
|
||||
|
@ -78,6 +79,11 @@ namespace BizHawk.Emulation.Cores.Computers.SinclairSpectrum
|
|||
/// </summary>
|
||||
public byte[] contentionTable;
|
||||
|
||||
/// <summary>
|
||||
/// Contention offset (used for testing)
|
||||
/// </summary>
|
||||
public int contentionOffset = 0; // -5;
|
||||
|
||||
#endregion
|
||||
|
||||
#region Screen Rendering
|
||||
|
@ -86,6 +92,12 @@ namespace BizHawk.Emulation.Cores.Computers.SinclairSpectrum
|
|||
/// Video output buffer
|
||||
/// </summary>
|
||||
public int[] ScreenBuffer;
|
||||
|
||||
/// <summary>
|
||||
/// Screen rendering T-State info
|
||||
/// </summary>
|
||||
public RenderCycle[] RenderTable;
|
||||
|
||||
/// <summary>
|
||||
/// Display memory
|
||||
/// </summary>
|
||||
|
@ -246,14 +258,14 @@ namespace BizHawk.Emulation.Cores.Computers.SinclairSpectrum
|
|||
#region Interrupt
|
||||
|
||||
/// <summary>
|
||||
/// The number of T-States that the INT pin is simulated to be held low
|
||||
/// The t-state within the frame that an interrupt is raised
|
||||
/// </summary>
|
||||
public int InterruptPeriod;
|
||||
public int InterruptStart;
|
||||
|
||||
/// <summary>
|
||||
/// The longest instruction cycle count
|
||||
/// The number of T-States that the INT pin is simulated to be held low
|
||||
/// </summary>
|
||||
protected int LongestOperationCycles = 23;
|
||||
public int InterruptDuration = 32;
|
||||
|
||||
/// <summary>
|
||||
/// Signs that an interrupt has been raised in this frame.
|
||||
|
@ -287,13 +299,13 @@ namespace BizHawk.Emulation.Cores.Computers.SinclairSpectrum
|
|||
return;
|
||||
}
|
||||
|
||||
if (currentCycle < LongestOperationCycles)// InterruptPeriod)
|
||||
if (currentCycle < InterruptStart)
|
||||
{
|
||||
// interrupt does not need to be raised yet
|
||||
return;
|
||||
}
|
||||
|
||||
if (currentCycle >= InterruptPeriod + LongestOperationCycles)
|
||||
if (currentCycle > InterruptStart + InterruptDuration)
|
||||
{
|
||||
// interrupt should have already been raised and the cpu may or
|
||||
// may not have caught it. The time has passed so revoke the signal
|
||||
|
@ -350,31 +362,7 @@ namespace BizHawk.Emulation.Cores.Computers.SinclairSpectrum
|
|||
/// <param name="addr"></param>
|
||||
/// <returns></returns>
|
||||
public abstract bool IsContended(int addr);
|
||||
|
||||
/// <summary>
|
||||
/// Contends the machine for a given address
|
||||
/// </summary>
|
||||
/// <param name="addr"></param>
|
||||
public virtual void Contend(ushort addr)
|
||||
{
|
||||
if (IsContended(addr) && !(_machine is ZX128Plus3))
|
||||
{
|
||||
_machine.CPU.TotalExecutedCycles += contentionTable[CurrentTStateInFrame];
|
||||
}
|
||||
}
|
||||
|
||||
public virtual void Contend(int addr, int time, int count)
|
||||
{
|
||||
if (IsContended(addr) && !(_machine is ZX128Plus3))
|
||||
{
|
||||
for (int f = 0; f < count; f++)
|
||||
{
|
||||
_machine.CPU.TotalExecutedCycles += contentionTable[CurrentTStateInFrame] + time;
|
||||
}
|
||||
}
|
||||
else
|
||||
_machine.CPU.TotalExecutedCycles += count * time;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Resets render state once interrupt is generated
|
||||
|
@ -401,6 +389,7 @@ namespace BizHawk.Emulation.Cores.Computers.SinclairSpectrum
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Builds the T-State to attribute map used with the floating bus
|
||||
/// </summary>
|
||||
|
@ -426,6 +415,32 @@ namespace BizHawk.Emulation.Cores.Computers.SinclairSpectrum
|
|||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the floating bus value
|
||||
/// </summary>
|
||||
public virtual void ReadFloatingBus(ref int result)
|
||||
{
|
||||
// Floating bus is read on the previous cycle
|
||||
long _tStates = _machine.CurrentFrameCycle - 1;
|
||||
|
||||
// if we are on the top or bottom border return 0xff
|
||||
if ((_tStates < contentionStartPeriod) || (_tStates > contentionEndPeriod))
|
||||
{
|
||||
result = 0xff;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (floatingBusTable[_tStates] < 0)
|
||||
{
|
||||
result = 0xff;
|
||||
}
|
||||
else
|
||||
{
|
||||
result = _machine.ReadBus((ushort)floatingBusTable[_tStates]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Updates the screen buffer based on the number of T-States supplied
|
||||
/// </summary>
|
||||
|
@ -444,7 +459,7 @@ namespace BizHawk.Emulation.Cores.Computers.SinclairSpectrum
|
|||
}
|
||||
|
||||
//the additional 1 tstate is required to get correct number of bytes to output in ircontention.sna
|
||||
elapsedTStates = (_tstates + 1 - lastTState) - 1;
|
||||
elapsedTStates = (_tstates + 1 - lastTState);
|
||||
|
||||
//It takes 4 tstates to write 1 byte. Or, 2 pixels per t-state.
|
||||
|
||||
|
@ -755,6 +770,27 @@ namespace BizHawk.Emulation.Cores.Computers.SinclairSpectrum
|
|||
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
*/
|
||||
/*
|
||||
#endregion
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// T-State display mapping
|
||||
/// </summary>
|
||||
public class RenderCycle
|
||||
{
|
||||
public RenderType Type { get; set; }
|
||||
public short DisplayAddress { get; set; }
|
||||
public short AttributeAddress { get; set; }
|
||||
public int ContentionValue { get; set; }
|
||||
public short FloatingBusAddress { get; set; }
|
||||
}
|
||||
|
||||
public enum RenderType
|
||||
{
|
||||
None,
|
||||
Border,
|
||||
Display
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
|
|
@ -134,6 +134,7 @@ namespace BizHawk.Emulation.Cores.Computers.SinclairSpectrum
|
|||
|
||||
// RAM 0x4000 (RAM5 - Bank5 or shadow bank RAM7)
|
||||
case 1:
|
||||
ULADevice.RenderScreen((int)CurrentFrameCycle);
|
||||
RAM5[addr % 0x4000] = value;
|
||||
break;
|
||||
|
||||
|
@ -162,6 +163,7 @@ namespace BizHawk.Emulation.Cores.Computers.SinclairSpectrum
|
|||
RAM4[addr % 0x4000] = value;
|
||||
break;
|
||||
case 5:
|
||||
ULADevice.RenderScreen((int)CurrentFrameCycle);
|
||||
RAM5[addr % 0x4000] = value;
|
||||
break;
|
||||
case 6:
|
||||
|
@ -175,10 +177,6 @@ namespace BizHawk.Emulation.Cores.Computers.SinclairSpectrum
|
|||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
// update ULA screen buffer if necessary
|
||||
if ((addr & 49152) == 16384 && _render)
|
||||
ULADevice.UpdateScreenBuffer(CurrentFrameCycle);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -189,9 +187,6 @@ namespace BizHawk.Emulation.Cores.Computers.SinclairSpectrum
|
|||
/// <returns></returns>
|
||||
public override byte ReadMemory(ushort addr)
|
||||
{
|
||||
if (ULADevice.IsContended(addr))
|
||||
CPU.TotalExecutedCycles += ULADevice.contentionTable[CurrentFrameCycle];
|
||||
|
||||
var data = ReadBus(addr);
|
||||
return data;
|
||||
}
|
||||
|
@ -204,13 +199,57 @@ namespace BizHawk.Emulation.Cores.Computers.SinclairSpectrum
|
|||
/// <param name="value"></param>
|
||||
public override void WriteMemory(ushort addr, byte value)
|
||||
{
|
||||
// apply contention if necessary
|
||||
if (ULADevice.IsContended(addr))
|
||||
CPU.TotalExecutedCycles += ULADevice.contentionTable[CurrentFrameCycle];
|
||||
|
||||
WriteBus(addr, value);
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Checks whether supplied address is in a potentially contended bank
|
||||
/// </summary>
|
||||
/// <param name="addr"></param>
|
||||
public override bool IsContended(ushort addr)
|
||||
{
|
||||
var a = addr & 0xc000;
|
||||
|
||||
if (a == 0x4000)
|
||||
{
|
||||
// low port contention
|
||||
return true;
|
||||
}
|
||||
|
||||
if (a == 0xc000)
|
||||
{
|
||||
// high port contention - check for contended bank paged in
|
||||
switch (RAMPaged)
|
||||
{
|
||||
case 1:
|
||||
case 3:
|
||||
case 5:
|
||||
case 7:
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns TRUE if there is a contended bank paged in
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public override bool ContendedBankPaged()
|
||||
{
|
||||
switch (RAMPaged)
|
||||
{
|
||||
case 1:
|
||||
case 3:
|
||||
case 5:
|
||||
case 7:
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// ULA reads the memory at the specified address
|
||||
/// (No memory contention)
|
||||
|
|
|
@ -18,18 +18,36 @@ namespace BizHawk.Emulation.Cores.Computers.SinclairSpectrum
|
|||
{
|
||||
bool deviceAddressed = true;
|
||||
|
||||
// process IO contention
|
||||
ContendPortAddress(port);
|
||||
|
||||
int result = 0xFF;
|
||||
|
||||
// ports 0x3ffd & 0x7ffd
|
||||
// traditionally thought to be write-only
|
||||
if (port == 0x3ffd || port == 0x7ffd)
|
||||
{
|
||||
// https://faqwiki.zxnet.co.uk/wiki/ZX_Spectrum_128
|
||||
// HAL bugs
|
||||
// Reads from port 0x7ffd cause a crash, as the 128's HAL10H8 chip does not distinguish between reads and writes to this port,
|
||||
// resulting in a floating data bus being used to set the paging registers.
|
||||
|
||||
// -asni (2018-06-08) - need this to pass the final portread tests from fusetest.tap
|
||||
|
||||
// get the floating bus value
|
||||
ULADevice.ReadFloatingBus((int)CurrentFrameCycle, ref result, port);
|
||||
// use this to set the paging registers
|
||||
WritePort(port, (byte)result);
|
||||
// return the floating bus value
|
||||
return (byte)result;
|
||||
}
|
||||
|
||||
// check AY
|
||||
if (AYDevice.ReadPort(port, ref result))
|
||||
return (byte)result;
|
||||
|
||||
// Kempston joystick input takes priority over all other input
|
||||
byte lowByte = (byte)(port & 0xff);
|
||||
|
||||
// Kempston joystick input takes priority over keyboard input
|
||||
// if this is detected just return the kempston byte
|
||||
if ((port & 0xe0) == 0 || (port & 0x20) == 0)
|
||||
if (lowByte == 0x1f)
|
||||
{
|
||||
if (LocateUniqueJoystick(JoystickType.Kempston) != null)
|
||||
return (byte)((KempstonJoystick)LocateUniqueJoystick(JoystickType.Kempston) as KempstonJoystick).JoyLine;
|
||||
|
@ -53,25 +71,7 @@ namespace BizHawk.Emulation.Cores.Computers.SinclairSpectrum
|
|||
if (!deviceAddressed)
|
||||
{
|
||||
// If this is an unused port the floating memory bus should be returned
|
||||
// Floating bus is read on the previous cycle
|
||||
long _tStates = CurrentFrameCycle - 1;
|
||||
|
||||
// if we are on the top or bottom border return 0xff
|
||||
if ((_tStates < ULADevice.contentionStartPeriod) || (_tStates > ULADevice.contentionEndPeriod))
|
||||
{
|
||||
result = 0xff;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (ULADevice.floatingBusTable[_tStates] < 0)
|
||||
{
|
||||
result = 0xff;
|
||||
}
|
||||
else
|
||||
{
|
||||
result = ReadBus((ushort)ULADevice.floatingBusTable[_tStates]);
|
||||
}
|
||||
}
|
||||
ULADevice.ReadFloatingBus((int)CurrentFrameCycle, ref result, port);
|
||||
}
|
||||
|
||||
return (byte)result;
|
||||
|
@ -84,9 +84,6 @@ namespace BizHawk.Emulation.Cores.Computers.SinclairSpectrum
|
|||
/// <param name="value"></param>
|
||||
public override void WritePort(ushort port, byte value)
|
||||
{
|
||||
// process IO contention
|
||||
ContendPortAddress(port);
|
||||
|
||||
// get a BitArray of the port
|
||||
BitArray portBits = new BitArray(BitConverter.GetBytes(port));
|
||||
// get a BitArray of the value byte
|
||||
|
@ -142,7 +139,6 @@ namespace BizHawk.Emulation.Cores.Computers.SinclairSpectrum
|
|||
{
|
||||
// store the last OUT byte
|
||||
LastULAOutByte = value;
|
||||
CPU.TotalExecutedCycles += ULADevice.contentionTable[CurrentFrameCycle];
|
||||
|
||||
/*
|
||||
Bit 7 6 5 4 3 2 1 0
|
||||
|
@ -152,10 +148,11 @@ namespace BizHawk.Emulation.Cores.Computers.SinclairSpectrum
|
|||
*/
|
||||
|
||||
// Border - LSB 3 bits hold the border colour
|
||||
if (ULADevice.borderColour != (value & BORDER_BIT))
|
||||
ULADevice.UpdateScreenBuffer(CurrentFrameCycle);
|
||||
|
||||
ULADevice.borderColour = value & BORDER_BIT;
|
||||
if (ULADevice.BorderColor != (value & BORDER_BIT))
|
||||
{
|
||||
ULADevice.RenderScreen((int)CurrentFrameCycle);
|
||||
ULADevice.BorderColor = value & BORDER_BIT;
|
||||
}
|
||||
|
||||
// Buzzer
|
||||
BuzzerDevice.ProcessPulseValue((value & EAR_BIT) != 0);
|
||||
|
|
|
@ -0,0 +1,50 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace BizHawk.Emulation.Cores.Computers.SinclairSpectrum
|
||||
{
|
||||
class Screen128 : ULA
|
||||
{
|
||||
#region Construction
|
||||
|
||||
public Screen128(SpectrumBase machine)
|
||||
: base(machine)
|
||||
{
|
||||
// interrupt
|
||||
InterruptStartTime = 3;
|
||||
InterruptLength = 36;
|
||||
// offsets
|
||||
RenderTableOffset = 58;
|
||||
ContentionOffset = 6;
|
||||
FloatingBusOffset = 1;
|
||||
// timing
|
||||
ClockSpeed = 3546900;
|
||||
FrameCycleLength = 70908;
|
||||
ScanlineTime = 228;
|
||||
BorderLeftTime = 24;
|
||||
BorderRightTime = 24;
|
||||
FirstPaperLine = 63;
|
||||
FirstPaperTState = 64;
|
||||
// screen layout
|
||||
Border4T = true;
|
||||
Border4TStage = 2;
|
||||
ScreenWidth = 256;
|
||||
ScreenHeight = 192;
|
||||
BorderTopHeight = 48; // 55; // 48;
|
||||
BorderBottomHeight = 48; // 56;
|
||||
BorderLeftWidth = 48;
|
||||
BorderRightWidth = 48;
|
||||
ScanLineWidth = BorderLeftWidth + ScreenWidth + BorderRightWidth;
|
||||
|
||||
RenderingTable = new RenderTable(this,
|
||||
MachineType.ZXSpectrum128);
|
||||
|
||||
SetupScreenSize();
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
|
@ -1,6 +1,7 @@
|
|||
|
||||
namespace BizHawk.Emulation.Cores.Computers.SinclairSpectrum
|
||||
{
|
||||
/*
|
||||
class ULA128 : ULABase
|
||||
{
|
||||
#region Construction
|
||||
|
@ -8,8 +9,8 @@ namespace BizHawk.Emulation.Cores.Computers.SinclairSpectrum
|
|||
public ULA128(SpectrumBase machine)
|
||||
: base(machine)
|
||||
{
|
||||
InterruptPeriod = 36;
|
||||
LongestOperationCycles = 64 + 2;
|
||||
InterruptStart = 0;
|
||||
//LongestOperationCycles = 64 + 2;
|
||||
FrameLength = 70908;
|
||||
ClockSpeed = 3546900;
|
||||
|
||||
|
@ -189,4 +190,5 @@ namespace BizHawk.Emulation.Cores.Computers.SinclairSpectrum
|
|||
|
||||
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
|
|
@ -21,12 +21,16 @@ namespace BizHawk.Emulation.Cores.Computers.SinclairSpectrum
|
|||
Spectrum = spectrum;
|
||||
CPU = cpu;
|
||||
|
||||
CPUMon = new CPUMonitor(this);
|
||||
CPUMon.machineType = MachineType.ZXSpectrum128;
|
||||
|
||||
ROMPaged = 0;
|
||||
SHADOWPaged = false;
|
||||
RAMPaged = 0;
|
||||
PagingDisabled = false;
|
||||
|
||||
ULADevice = new ULA128(this);
|
||||
//ULADevice = new ULA128(this);
|
||||
ULADevice = new Screen128(this); // still todo
|
||||
|
||||
BuzzerDevice = new Beeper(this);
|
||||
BuzzerDevice.Init(44100, ULADevice.FrameLength);
|
||||
|
|
|
@ -236,9 +236,11 @@ namespace BizHawk.Emulation.Cores.Computers.SinclairSpectrum
|
|||
break;
|
||||
case 1:
|
||||
case 2:
|
||||
ULADevice.RenderScreen((int)CurrentFrameCycle);
|
||||
RAM5[addr % 0x4000] = value;
|
||||
break;
|
||||
case 3:
|
||||
ULADevice.RenderScreen((int)CurrentFrameCycle);
|
||||
RAM7[addr % 0x4000] = value;
|
||||
break;
|
||||
}
|
||||
|
@ -265,6 +267,7 @@ namespace BizHawk.Emulation.Cores.Computers.SinclairSpectrum
|
|||
RAM3[addr % 0x4000] = value;
|
||||
break;
|
||||
case 1:
|
||||
ULADevice.RenderScreen((int)CurrentFrameCycle);
|
||||
RAM7[addr % 0x4000] = value;
|
||||
break;
|
||||
}
|
||||
|
@ -299,6 +302,7 @@ namespace BizHawk.Emulation.Cores.Computers.SinclairSpectrum
|
|||
|
||||
// RAM 0x4000 (RAM5 - Bank5 only)
|
||||
case 1:
|
||||
ULADevice.RenderScreen((int)CurrentFrameCycle);
|
||||
RAM5[addr % 0x4000] = value;
|
||||
break;
|
||||
|
||||
|
@ -327,12 +331,14 @@ namespace BizHawk.Emulation.Cores.Computers.SinclairSpectrum
|
|||
RAM4[addr % 0x4000] = value;
|
||||
break;
|
||||
case 5:
|
||||
ULADevice.RenderScreen((int)CurrentFrameCycle);
|
||||
RAM5[addr % 0x4000] = value;
|
||||
break;
|
||||
case 6:
|
||||
RAM6[addr % 0x4000] = value;
|
||||
break;
|
||||
case 7:
|
||||
ULADevice.RenderScreen((int)CurrentFrameCycle);
|
||||
RAM7[addr % 0x4000] = value;
|
||||
break;
|
||||
}
|
||||
|
@ -341,10 +347,6 @@ namespace BizHawk.Emulation.Cores.Computers.SinclairSpectrum
|
|||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// update ULA screen buffer if necessary
|
||||
if ((addr & 49152) == 16384 && _render)
|
||||
ULADevice.UpdateScreenBuffer(CurrentFrameCycle);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -355,10 +357,13 @@ namespace BizHawk.Emulation.Cores.Computers.SinclairSpectrum
|
|||
/// <returns></returns>
|
||||
public override byte ReadMemory(ushort addr)
|
||||
{
|
||||
if (ULADevice.IsContended(addr))
|
||||
CPU.TotalExecutedCycles += ULADevice.contentionTable[CurrentFrameCycle];
|
||||
|
||||
var data = ReadBus(addr);
|
||||
if (CPUMon.NextMemReadContended)
|
||||
{
|
||||
LastContendedReadByte = data;
|
||||
CPUMon.NextMemReadContended = false;
|
||||
}
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
|
@ -370,13 +375,80 @@ namespace BizHawk.Emulation.Cores.Computers.SinclairSpectrum
|
|||
/// <param name="value"></param>
|
||||
public override void WriteMemory(ushort addr, byte value)
|
||||
{
|
||||
// apply contention if necessary
|
||||
if (ULADevice.IsContended(addr))
|
||||
CPU.TotalExecutedCycles += ULADevice.contentionTable[CurrentFrameCycle];
|
||||
|
||||
// update ULA screen buffer if necessary BEFORE T1 write
|
||||
/*
|
||||
if (!SpecialPagingMode)
|
||||
{
|
||||
if (((addr & 49152) == 16384 || ((addr & 0xc000) == 0xc000) && (RAMPaged == 5 || RAMPaged == 7)) && _render)
|
||||
ULADevice.RenderScreen((int)CurrentFrameCycle);
|
||||
}
|
||||
else
|
||||
{
|
||||
switch (PagingConfiguration)
|
||||
{
|
||||
case 2:
|
||||
case 3:
|
||||
if ((addr & 49152) == 16384)
|
||||
ULADevice.RenderScreen((int)CurrentFrameCycle);
|
||||
break;
|
||||
case 1:
|
||||
if ((addr & 49152) == 16384 || addr >= 0xc000)
|
||||
ULADevice.RenderScreen((int)CurrentFrameCycle);
|
||||
break;
|
||||
}
|
||||
}
|
||||
*/
|
||||
WriteBus(addr, value);
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Checks whether supplied address is in a potentially contended bank
|
||||
/// </summary>
|
||||
/// <param name="addr"></param>
|
||||
public override bool IsContended(ushort addr)
|
||||
{
|
||||
var a = addr & 0xc000;
|
||||
|
||||
if (a == 0x4000)
|
||||
{
|
||||
// low port contention
|
||||
return true;
|
||||
}
|
||||
|
||||
if (a == 0xc000)
|
||||
{
|
||||
// high port contention - check for contended bank paged in
|
||||
switch (RAMPaged)
|
||||
{
|
||||
case 4:
|
||||
case 5:
|
||||
case 6:
|
||||
case 7:
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns TRUE if there is a contended bank paged in
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public override bool ContendedBankPaged()
|
||||
{
|
||||
switch (RAMPaged)
|
||||
{
|
||||
case 4:
|
||||
case 5:
|
||||
case 6:
|
||||
case 7:
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// ULA reads the memory at the specified address
|
||||
/// (No memory contention)
|
||||
|
|
|
@ -18,18 +18,17 @@ namespace BizHawk.Emulation.Cores.Computers.SinclairSpectrum
|
|||
{
|
||||
bool deviceAddressed = true;
|
||||
|
||||
// process IO contention
|
||||
ContendPortAddress(port);
|
||||
|
||||
int result = 0xFF;
|
||||
|
||||
// check AY
|
||||
if (AYDevice.ReadPort(port, ref result))
|
||||
return (byte)result;
|
||||
|
||||
// Kempston joystick input takes priority over all other input
|
||||
byte lowByte = (byte)(port & 0xff);
|
||||
|
||||
// Kempston joystick input takes priority over all keyboard input
|
||||
// if this is detected just return the kempston byte
|
||||
if ((port & 0xe0) == 0 || (port & 0x20) == 0)
|
||||
if (lowByte == 0x1f)
|
||||
{
|
||||
if (LocateUniqueJoystick(JoystickType.Kempston) != null)
|
||||
return (byte)((KempstonJoystick)LocateUniqueJoystick(JoystickType.Kempston) as KempstonJoystick).JoyLine;
|
||||
|
@ -53,99 +52,8 @@ namespace BizHawk.Emulation.Cores.Computers.SinclairSpectrum
|
|||
if (!deviceAddressed)
|
||||
{
|
||||
// If this is an unused port the floating memory bus should be returned
|
||||
// Floating bus is read on the previous cycle
|
||||
long _tStates = CurrentFrameCycle - 1;
|
||||
|
||||
// if we are on the top or bottom border return 0xff
|
||||
if ((_tStates < ULADevice.contentionStartPeriod) || (_tStates > ULADevice.contentionEndPeriod))
|
||||
{
|
||||
result = 0xff;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (ULADevice.floatingBusTable[_tStates] < 0)
|
||||
{
|
||||
result = 0xff;
|
||||
}
|
||||
else
|
||||
{
|
||||
result = ReadBus((ushort)ULADevice.floatingBusTable[_tStates]);
|
||||
}
|
||||
}
|
||||
ULADevice.ReadFloatingBus((int)CurrentFrameCycle, ref result, port);
|
||||
}
|
||||
/*
|
||||
// Check whether the low bit is reset
|
||||
// Technically the ULA should respond to every even I/O address
|
||||
bool lowBitReset = (port & 0x0001) == 0;
|
||||
|
||||
// Kempston joystick input takes priority over all other input
|
||||
// if this is detected just return the kempston byte
|
||||
if ((port & 0xe0) == 0 || (port & 0x20) == 0)
|
||||
{
|
||||
if (LocateUniqueJoystick(JoystickType.Kempston) != null)
|
||||
return (byte)((KempstonJoystick)LocateUniqueJoystick(JoystickType.Kempston) as KempstonJoystick).JoyLine;
|
||||
|
||||
InputRead = true;
|
||||
}
|
||||
else if (lowBitReset)
|
||||
{
|
||||
// Even I/O address so get input from keyboard
|
||||
KeyboardDevice.ReadPort(port, ref result);
|
||||
|
||||
TapeDevice.MonitorRead();
|
||||
|
||||
// not a lagframe
|
||||
InputRead = true;
|
||||
|
||||
// tape loading monitor cycle
|
||||
//TapeDevice.MonitorRead();
|
||||
|
||||
// process tape INs
|
||||
TapeDevice.ReadPort(port, ref result);
|
||||
}
|
||||
else
|
||||
{
|
||||
// devices other than the ULA will respond here
|
||||
// (e.g. the AY sound chip in a 128k spectrum
|
||||
|
||||
// AY register activate - on +3/2a both FFFD and BFFD active AY
|
||||
if ((port & 0xc002) == 0xc000)
|
||||
{
|
||||
result = (int)AYDevice.PortRead();
|
||||
}
|
||||
else if ((port & 0xc002) == 0x8000)
|
||||
{
|
||||
result = (int)AYDevice.PortRead();
|
||||
}
|
||||
|
||||
// Kempston Mouse
|
||||
|
||||
/*
|
||||
else if ((port & 0xF002) == 0x2000) //Is bit 12 set and bits 13,14,15 and 1 reset?
|
||||
{
|
||||
//result = udpDrive.DiskStatusRead();
|
||||
|
||||
// disk drive is not yet implemented - return a max status byte for the menu to load
|
||||
result = 255;
|
||||
}
|
||||
else if ((port & 0xF002) == 0x3000)
|
||||
{
|
||||
//result = udpDrive.DiskReadByte();
|
||||
result = 0;
|
||||
}
|
||||
|
||||
else if ((port & 0xF002) == 0x0)
|
||||
{
|
||||
if (PagingDisabled)
|
||||
result = 0x1;
|
||||
else
|
||||
result = 0xff;
|
||||
}
|
||||
*//*
|
||||
|
||||
// if unused port the floating memory bus should be returned (still todo)
|
||||
}
|
||||
*/
|
||||
|
||||
return (byte)result;
|
||||
}
|
||||
|
@ -157,9 +65,6 @@ namespace BizHawk.Emulation.Cores.Computers.SinclairSpectrum
|
|||
/// <param name="value"></param>
|
||||
public override void WritePort(ushort port, byte value)
|
||||
{
|
||||
// process IO contention
|
||||
ContendPortAddress(port);
|
||||
|
||||
// get a BitArray of the port
|
||||
BitArray portBits = new BitArray(BitConverter.GetBytes(port));
|
||||
// get a BitArray of the value byte
|
||||
|
@ -241,10 +146,11 @@ namespace BizHawk.Emulation.Cores.Computers.SinclairSpectrum
|
|||
*/
|
||||
|
||||
// Border - LSB 3 bits hold the border colour
|
||||
if (ULADevice.borderColour != (value & BORDER_BIT))
|
||||
ULADevice.UpdateScreenBuffer(CurrentFrameCycle);
|
||||
|
||||
ULADevice.borderColour = value & BORDER_BIT;
|
||||
if (ULADevice.BorderColor != (value & BORDER_BIT))
|
||||
{
|
||||
ULADevice.RenderScreen((int)CurrentFrameCycle);
|
||||
ULADevice.BorderColor = value & BORDER_BIT;
|
||||
}
|
||||
|
||||
// Buzzer
|
||||
BuzzerDevice.ProcessPulseValue((value & EAR_BIT) != 0);
|
||||
|
@ -279,15 +185,5 @@ namespace BizHawk.Emulation.Cores.Computers.SinclairSpectrum
|
|||
}
|
||||
set { ROMPaged = value; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Override port contention
|
||||
/// +3/2a does not have the same ULA IO contention
|
||||
/// </summary>
|
||||
/// <param name="addr"></param>
|
||||
public override void ContendPortAddress(ushort addr)
|
||||
{
|
||||
//CPU.TotalExecutedCycles += 4;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,52 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace BizHawk.Emulation.Cores.Computers.SinclairSpectrum
|
||||
{
|
||||
class Screen128Plus2a : ULA
|
||||
{
|
||||
#region Construction
|
||||
|
||||
public Screen128Plus2a(SpectrumBase machine)
|
||||
: base(machine)
|
||||
{
|
||||
// interrupt
|
||||
InterruptStartTime = 0;
|
||||
InterruptLength = 32;
|
||||
// offsets
|
||||
RenderTableOffset = 58;
|
||||
ContentionOffset = 9;
|
||||
FloatingBusOffset = 0;
|
||||
// timing
|
||||
ClockSpeed = 3546900;
|
||||
FrameCycleLength = 70908;
|
||||
ScanlineTime = 228;
|
||||
BorderLeftTime = 24;
|
||||
BorderRightTime = 24;
|
||||
FirstPaperLine = 63;
|
||||
FirstPaperTState = 64;
|
||||
// screen layout
|
||||
Border4T = true;
|
||||
Border4TStage = 2;
|
||||
ScreenWidth = 256;
|
||||
ScreenHeight = 192;
|
||||
BorderTopHeight = 48;// 55;
|
||||
BorderBottomHeight = 48; // 56;
|
||||
BorderLeftWidth = 48;
|
||||
BorderRightWidth = 48;
|
||||
ScanLineWidth = BorderLeftWidth + ScreenWidth + BorderRightWidth;
|
||||
|
||||
RenderingTable = new RenderTable(this,
|
||||
MachineType.ZXSpectrum128Plus2a);
|
||||
|
||||
SetupScreenSize();
|
||||
|
||||
GenerateP3PortTable();
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
|
@ -1,6 +1,7 @@
|
|||
|
||||
namespace BizHawk.Emulation.Cores.Computers.SinclairSpectrum
|
||||
{
|
||||
/*
|
||||
class ULAPlus2a : ULABase
|
||||
{
|
||||
#region Construction
|
||||
|
@ -8,8 +9,8 @@ namespace BizHawk.Emulation.Cores.Computers.SinclairSpectrum
|
|||
public ULAPlus2a(SpectrumBase machine)
|
||||
: base(machine)
|
||||
{
|
||||
InterruptPeriod = 36;
|
||||
LongestOperationCycles = 64 + 2;
|
||||
InterruptStart = 0;
|
||||
//LongestOperationCycles = 64 + 2;
|
||||
FrameLength = 70908;
|
||||
ClockSpeed = 3546900;
|
||||
|
||||
|
@ -193,4 +194,5 @@ namespace BizHawk.Emulation.Cores.Computers.SinclairSpectrum
|
|||
|
||||
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
|
|
@ -21,12 +21,16 @@ namespace BizHawk.Emulation.Cores.Computers.SinclairSpectrum
|
|||
Spectrum = spectrum;
|
||||
CPU = cpu;
|
||||
|
||||
CPUMon = new CPUMonitor(this);
|
||||
CPUMon.machineType = MachineType.ZXSpectrum128Plus2a;
|
||||
|
||||
ROMPaged = 0;
|
||||
SHADOWPaged = false;
|
||||
RAMPaged = 0;
|
||||
PagingDisabled = false;
|
||||
|
||||
ULADevice = new ULAPlus2a(this);
|
||||
//ULADevice = new ULAPlus2a(this);
|
||||
ULADevice = new Screen128Plus2a(this); // still todo
|
||||
|
||||
BuzzerDevice = new Beeper(this);
|
||||
BuzzerDevice.Init(44100, ULADevice.FrameLength);
|
||||
|
|
|
@ -236,10 +236,12 @@ namespace BizHawk.Emulation.Cores.Computers.SinclairSpectrum
|
|||
break;
|
||||
case 1:
|
||||
case 2:
|
||||
ULADevice.RenderScreen((int)CurrentFrameCycle);
|
||||
RAM5[addr % 0x4000] = value;
|
||||
break;
|
||||
case 3:
|
||||
RAM7[addr % 0x4000] = value;
|
||||
ULADevice.RenderScreen((int)CurrentFrameCycle);
|
||||
RAM7[addr % 0x4000] = value;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
@ -265,6 +267,7 @@ namespace BizHawk.Emulation.Cores.Computers.SinclairSpectrum
|
|||
RAM3[addr % 0x4000] = value;
|
||||
break;
|
||||
case 1:
|
||||
ULADevice.RenderScreen((int)CurrentFrameCycle);
|
||||
RAM7[addr % 0x4000] = value;
|
||||
break;
|
||||
}
|
||||
|
@ -299,6 +302,7 @@ namespace BizHawk.Emulation.Cores.Computers.SinclairSpectrum
|
|||
|
||||
// RAM 0x4000 (RAM5 - Bank5 only)
|
||||
case 1:
|
||||
ULADevice.RenderScreen((int)CurrentFrameCycle);
|
||||
RAM5[addr % 0x4000] = value;
|
||||
break;
|
||||
|
||||
|
@ -327,12 +331,14 @@ namespace BizHawk.Emulation.Cores.Computers.SinclairSpectrum
|
|||
RAM4[addr % 0x4000] = value;
|
||||
break;
|
||||
case 5:
|
||||
ULADevice.RenderScreen((int)CurrentFrameCycle);
|
||||
RAM5[addr % 0x4000] = value;
|
||||
break;
|
||||
case 6:
|
||||
RAM6[addr % 0x4000] = value;
|
||||
break;
|
||||
case 7:
|
||||
ULADevice.RenderScreen((int)CurrentFrameCycle);
|
||||
RAM7[addr % 0x4000] = value;
|
||||
break;
|
||||
}
|
||||
|
@ -341,10 +347,6 @@ namespace BizHawk.Emulation.Cores.Computers.SinclairSpectrum
|
|||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// update ULA screen buffer if necessary
|
||||
if ((addr & 49152) == 16384 && _render)
|
||||
ULADevice.UpdateScreenBuffer(CurrentFrameCycle);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -355,10 +357,13 @@ namespace BizHawk.Emulation.Cores.Computers.SinclairSpectrum
|
|||
/// <returns></returns>
|
||||
public override byte ReadMemory(ushort addr)
|
||||
{
|
||||
if (ULADevice.IsContended(addr))
|
||||
CPU.TotalExecutedCycles += ULADevice.contentionTable[CurrentFrameCycle];
|
||||
|
||||
var data = ReadBus(addr);
|
||||
if (CPUMon.NextMemReadContended)
|
||||
{
|
||||
LastContendedReadByte = data;
|
||||
CPUMon.NextMemReadContended = false;
|
||||
}
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
|
@ -370,13 +375,81 @@ namespace BizHawk.Emulation.Cores.Computers.SinclairSpectrum
|
|||
/// <param name="value"></param>
|
||||
public override void WriteMemory(ushort addr, byte value)
|
||||
{
|
||||
// apply contention if necessary
|
||||
if (ULADevice.IsContended(addr))
|
||||
CPU.TotalExecutedCycles += ULADevice.contentionTable[CurrentFrameCycle];
|
||||
/*
|
||||
// update ULA screen buffer if necessary BEFORE T1 write
|
||||
if (!SpecialPagingMode)
|
||||
{
|
||||
if (((addr & 49152) == 16384 || ((addr & 0xc000) == 0xc000) && (RAMPaged == 5 || RAMPaged == 7)) && _render)
|
||||
ULADevice.RenderScreen((int)CurrentFrameCycle);
|
||||
}
|
||||
else
|
||||
{
|
||||
switch (PagingConfiguration)
|
||||
{
|
||||
case 2:
|
||||
case 3:
|
||||
if ((addr & 49152) == 16384)
|
||||
ULADevice.RenderScreen((int)CurrentFrameCycle);
|
||||
break;
|
||||
case 1:
|
||||
if ((addr & 49152) == 16384 || addr >= 0xc000)
|
||||
ULADevice.RenderScreen((int)CurrentFrameCycle);
|
||||
break;
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
WriteBus(addr, value);
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Checks whether supplied address is in a potentially contended bank
|
||||
/// </summary>
|
||||
/// <param name="addr"></param>
|
||||
public override bool IsContended(ushort addr)
|
||||
{
|
||||
var a = addr & 0xc000;
|
||||
|
||||
if (a == 0x4000)
|
||||
{
|
||||
// low port contention
|
||||
return true;
|
||||
}
|
||||
|
||||
if (a == 0xc000)
|
||||
{
|
||||
// high port contention - check for contended bank paged in
|
||||
switch (RAMPaged)
|
||||
{
|
||||
case 4:
|
||||
case 5:
|
||||
case 6:
|
||||
case 7:
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns TRUE if there is a contended bank paged in
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public override bool ContendedBankPaged()
|
||||
{
|
||||
switch (RAMPaged)
|
||||
{
|
||||
case 4:
|
||||
case 5:
|
||||
case 6:
|
||||
case 7:
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// ULA reads the memory at the specified address
|
||||
/// (No memory contention)
|
||||
|
|
|
@ -18,18 +18,17 @@ namespace BizHawk.Emulation.Cores.Computers.SinclairSpectrum
|
|||
{
|
||||
bool deviceAddressed = true;
|
||||
|
||||
// process IO contention
|
||||
ContendPortAddress(port);
|
||||
|
||||
int result = 0xFF;
|
||||
|
||||
// check AY
|
||||
if (AYDevice.ReadPort(port, ref result))
|
||||
return (byte)result;
|
||||
|
||||
// Kempston joystick input takes priority over all other input
|
||||
byte lowByte = (byte)(port & 0xff);
|
||||
|
||||
// Kempston joystick input takes priority over all keyboard input
|
||||
// if this is detected just return the kempston byte
|
||||
if ((port & 0xe0) == 0 || (port & 0x20) == 0)
|
||||
if (lowByte == 0x1f)
|
||||
{
|
||||
if (LocateUniqueJoystick(JoystickType.Kempston) != null)
|
||||
return (byte)((KempstonJoystick)LocateUniqueJoystick(JoystickType.Kempston) as KempstonJoystick).JoyLine;
|
||||
|
@ -57,25 +56,7 @@ namespace BizHawk.Emulation.Cores.Computers.SinclairSpectrum
|
|||
if (!deviceAddressed)
|
||||
{
|
||||
// If this is an unused port the floating memory bus should be returned
|
||||
// Floating bus is read on the previous cycle
|
||||
long _tStates = CurrentFrameCycle - 1;
|
||||
|
||||
// if we are on the top or bottom border return 0xff
|
||||
if ((_tStates < ULADevice.contentionStartPeriod) || (_tStates > ULADevice.contentionEndPeriod))
|
||||
{
|
||||
result = 0xff;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (ULADevice.floatingBusTable[_tStates] < 0)
|
||||
{
|
||||
result = 0xff;
|
||||
}
|
||||
else
|
||||
{
|
||||
result = ReadBus((ushort)ULADevice.floatingBusTable[_tStates]);
|
||||
}
|
||||
}
|
||||
ULADevice.ReadFloatingBus((int)CurrentFrameCycle, ref result, port);
|
||||
}
|
||||
|
||||
return (byte)result;
|
||||
|
@ -88,9 +69,6 @@ namespace BizHawk.Emulation.Cores.Computers.SinclairSpectrum
|
|||
/// <param name="value"></param>
|
||||
public override void WritePort(ushort port, byte value)
|
||||
{
|
||||
// process IO contention
|
||||
ContendPortAddress(port);
|
||||
|
||||
// get a BitArray of the port
|
||||
BitArray portBits = new BitArray(BitConverter.GetBytes(port));
|
||||
// get a BitArray of the value byte
|
||||
|
@ -174,10 +152,11 @@ namespace BizHawk.Emulation.Cores.Computers.SinclairSpectrum
|
|||
*/
|
||||
|
||||
// Border - LSB 3 bits hold the border colour
|
||||
if (ULADevice.borderColour != (value & BORDER_BIT))
|
||||
ULADevice.UpdateScreenBuffer(CurrentFrameCycle);
|
||||
|
||||
ULADevice.borderColour = value & BORDER_BIT;
|
||||
if (ULADevice.BorderColor != (value & BORDER_BIT))
|
||||
{
|
||||
ULADevice.RenderScreen((int)CurrentFrameCycle);
|
||||
ULADevice.BorderColor = value & BORDER_BIT;
|
||||
}
|
||||
|
||||
// Buzzer
|
||||
BuzzerDevice.ProcessPulseValue((value & EAR_BIT) != 0);
|
||||
|
@ -212,15 +191,5 @@ namespace BizHawk.Emulation.Cores.Computers.SinclairSpectrum
|
|||
}
|
||||
set { ROMPaged = value; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Override port contention
|
||||
/// +3/2a does not have the same ULA IO contention
|
||||
/// </summary>
|
||||
/// <param name="addr"></param>
|
||||
public override void ContendPortAddress(ushort addr)
|
||||
{
|
||||
//CPU.TotalExecutedCycles += 4;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
|
||||
namespace BizHawk.Emulation.Cores.Computers.SinclairSpectrum
|
||||
{
|
||||
/*
|
||||
class ULAPlus3 : ULABase
|
||||
{
|
||||
#region Construction
|
||||
|
@ -8,8 +9,8 @@ namespace BizHawk.Emulation.Cores.Computers.SinclairSpectrum
|
|||
public ULAPlus3(SpectrumBase machine)
|
||||
: base(machine)
|
||||
{
|
||||
InterruptPeriod = 36;
|
||||
LongestOperationCycles = 64 + 2;
|
||||
InterruptStart = 0;
|
||||
//LongestOperationCycles = 64 + 2;
|
||||
FrameLength = 70908;
|
||||
ClockSpeed = 3546900;
|
||||
|
||||
|
@ -193,4 +194,5 @@ namespace BizHawk.Emulation.Cores.Computers.SinclairSpectrum
|
|||
|
||||
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
|
|
@ -20,13 +20,18 @@ namespace BizHawk.Emulation.Cores.Computers.SinclairSpectrum
|
|||
{
|
||||
Spectrum = spectrum;
|
||||
CPU = cpu;
|
||||
|
||||
|
||||
CPUMon = new CPUMonitor(this);
|
||||
CPUMon.machineType = MachineType.ZXSpectrum128Plus3;
|
||||
|
||||
ROMPaged = 0;
|
||||
SHADOWPaged = false;
|
||||
RAMPaged = 0;
|
||||
PagingDisabled = false;
|
||||
|
||||
ULADevice = new ULAPlus3(this);
|
||||
// ULADevice = new ULAPlus3(this);
|
||||
ULADevice = new Screen128Plus2a(this); // still todo
|
||||
|
||||
BuzzerDevice = new Beeper(this);
|
||||
BuzzerDevice.Init(44100, ULADevice.FrameLength);
|
||||
|
|
|
@ -24,7 +24,6 @@ namespace BizHawk.Emulation.Cores.Computers.SinclairSpectrum
|
|||
|
||||
#endregion
|
||||
|
||||
|
||||
#region Memory
|
||||
|
||||
/* 48K Spectrum has NO memory paging
|
||||
|
@ -86,13 +85,10 @@ namespace BizHawk.Emulation.Cores.Computers.SinclairSpectrum
|
|||
// cannot write to ROM
|
||||
break;
|
||||
case 1:
|
||||
ULADevice.RenderScreen((int)CurrentFrameCycle);
|
||||
RAM0[index] = value;
|
||||
break;
|
||||
}
|
||||
|
||||
// update ULA screen buffer if necessary
|
||||
if ((addr & 49152) == 16384 && _render)
|
||||
ULADevice.UpdateScreenBuffer(CurrentFrameCycle);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -103,9 +99,6 @@ namespace BizHawk.Emulation.Cores.Computers.SinclairSpectrum
|
|||
/// <returns></returns>
|
||||
public override byte ReadMemory(ushort addr)
|
||||
{
|
||||
if (ULADevice.IsContended(addr))
|
||||
CPU.TotalExecutedCycles += ULADevice.contentionTable[CurrentFrameCycle];
|
||||
|
||||
var data = ReadBus(addr);
|
||||
return data;
|
||||
}
|
||||
|
@ -118,10 +111,6 @@ namespace BizHawk.Emulation.Cores.Computers.SinclairSpectrum
|
|||
/// <param name="value"></param>
|
||||
public override void WriteMemory(ushort addr, byte value)
|
||||
{
|
||||
// apply contention if necessary
|
||||
if (ULADevice.IsContended(addr))
|
||||
CPU.TotalExecutedCycles += ULADevice.contentionTable[CurrentFrameCycle];
|
||||
|
||||
WriteBus(addr, value);
|
||||
}
|
||||
|
||||
|
|
|
@ -77,19 +77,16 @@ namespace BizHawk.Emulation.Cores.Computers.SinclairSpectrum
|
|||
// cannot write to ROM
|
||||
break;
|
||||
case 1:
|
||||
ULADevice.RenderScreen((int)CurrentFrameCycle);
|
||||
RAM0[index] = value;
|
||||
break;
|
||||
case 2:
|
||||
RAM1[index] = value;
|
||||
RAM1[index] = value;
|
||||
break;
|
||||
case 3:
|
||||
RAM2[index] = value;
|
||||
break;
|
||||
}
|
||||
|
||||
// update ULA screen buffer if necessary
|
||||
if ((addr & 49152) == 16384 && _render)
|
||||
ULADevice.UpdateScreenBuffer(CurrentFrameCycle);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -100,9 +97,6 @@ namespace BizHawk.Emulation.Cores.Computers.SinclairSpectrum
|
|||
/// <returns></returns>
|
||||
public override byte ReadMemory(ushort addr)
|
||||
{
|
||||
if (ULADevice.IsContended(addr))
|
||||
CPU.TotalExecutedCycles += ULADevice.contentionTable[CurrentFrameCycle];
|
||||
|
||||
var data = ReadBus(addr);
|
||||
return data;
|
||||
}
|
||||
|
@ -114,14 +108,30 @@ namespace BizHawk.Emulation.Cores.Computers.SinclairSpectrum
|
|||
/// <param name="addr"></param>
|
||||
/// <param name="value"></param>
|
||||
public override void WriteMemory(ushort addr, byte value)
|
||||
{
|
||||
// apply contention if necessary
|
||||
if (ULADevice.IsContended(addr))
|
||||
CPU.TotalExecutedCycles += ULADevice.contentionTable[CurrentFrameCycle];
|
||||
|
||||
{
|
||||
WriteBus(addr, value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Checks whether supplied address is in a potentially contended bank
|
||||
/// </summary>
|
||||
/// <param name="addr"></param>
|
||||
public override bool IsContended(ushort addr)
|
||||
{
|
||||
if ((addr & 49152) == 16384)
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns TRUE if there is a contended bank paged in
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public override bool ContendedBankPaged()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets up the ROM
|
||||
/// </summary>
|
||||
|
|
|
@ -15,18 +15,16 @@ namespace BizHawk.Emulation.Cores.Computers.SinclairSpectrum
|
|||
/// <returns></returns>
|
||||
public override byte ReadPort(ushort port)
|
||||
{
|
||||
// process IO contention
|
||||
ContendPortAddress(port);
|
||||
|
||||
int result = 0xFF;
|
||||
|
||||
// Check whether the low bit is reset
|
||||
// Technically the ULA should respond to every even I/O address
|
||||
bool lowBitReset = (port & 0x0001) == 0;
|
||||
|
||||
// Kempston joystick input takes priority over all other input
|
||||
byte lowByte = (byte)(port & 0xff);
|
||||
|
||||
// Kempston joystick input takes priority over keyboard input
|
||||
// if this is detected just return the kempston byte
|
||||
if ((port & 0xe0) == 0 || (port & 0x20) == 0)
|
||||
if (lowByte == 0x1f)
|
||||
{
|
||||
if (LocateUniqueJoystick(JoystickType.Kempston) != null)
|
||||
return (byte)((KempstonJoystick)LocateUniqueJoystick(JoystickType.Kempston) as KempstonJoystick).JoyLine;
|
||||
|
@ -34,6 +32,7 @@ namespace BizHawk.Emulation.Cores.Computers.SinclairSpectrum
|
|||
// not a lag frame
|
||||
InputRead = true;
|
||||
}
|
||||
// Even ports always address the ULA
|
||||
else if (lowBitReset)
|
||||
{
|
||||
// Even I/O address so get input from keyboard
|
||||
|
@ -56,25 +55,7 @@ namespace BizHawk.Emulation.Cores.Computers.SinclairSpectrum
|
|||
|
||||
|
||||
// If this is an unused port the floating memory bus should be returned
|
||||
// Floating bus is read on the previous cycle
|
||||
long _tStates = CurrentFrameCycle - 1;
|
||||
|
||||
// if we are on the top or bottom border return 0xff
|
||||
if ((_tStates < ULADevice.contentionStartPeriod) || (_tStates > ULADevice.contentionEndPeriod))
|
||||
{
|
||||
result = 0xff;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (ULADevice.floatingBusTable[_tStates] < 0)
|
||||
{
|
||||
result = 0xff;
|
||||
}
|
||||
else
|
||||
{
|
||||
result = ReadBus((ushort)ULADevice.floatingBusTable[_tStates]);
|
||||
}
|
||||
}
|
||||
ULADevice.ReadFloatingBus((int)CurrentFrameCycle, ref result, port);
|
||||
}
|
||||
|
||||
return (byte)result;
|
||||
|
@ -87,9 +68,6 @@ namespace BizHawk.Emulation.Cores.Computers.SinclairSpectrum
|
|||
/// <param name="value"></param>
|
||||
public override void WritePort(ushort port, byte value)
|
||||
{
|
||||
// process IO contention
|
||||
ContendPortAddress(port);
|
||||
|
||||
// Check whether the low bit is reset
|
||||
// Technically the ULA should respond to every even I/O address
|
||||
if ((port & 0x0001) != 0)
|
||||
|
@ -106,14 +84,12 @@ namespace BizHawk.Emulation.Cores.Computers.SinclairSpectrum
|
|||
*/
|
||||
|
||||
// Border - LSB 3 bits hold the border colour
|
||||
if (ULADevice.borderColour != (value & BORDER_BIT))
|
||||
if (ULADevice.BorderColor != (value & BORDER_BIT))
|
||||
{
|
||||
// border value has changed - update the screen buffer
|
||||
ULADevice.UpdateScreenBuffer(CurrentFrameCycle);
|
||||
ULADevice.RenderScreen((int)CurrentFrameCycle);
|
||||
ULADevice.BorderColor = value & BORDER_BIT;
|
||||
}
|
||||
|
||||
ULADevice.borderColour = value & BORDER_BIT;
|
||||
|
||||
// Buzzer
|
||||
BuzzerDevice.ProcessPulseValue((value & EAR_BIT) != 0);
|
||||
|
||||
|
@ -124,6 +100,6 @@ namespace BizHawk.Emulation.Cores.Computers.SinclairSpectrum
|
|||
//TapeDevice.ProcessMicBit((value & MIC_BIT) != 0);
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,50 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace BizHawk.Emulation.Cores.Computers.SinclairSpectrum
|
||||
{
|
||||
class Screen48 : ULA
|
||||
{
|
||||
#region Construction
|
||||
|
||||
public Screen48(SpectrumBase machine)
|
||||
: base(machine)
|
||||
{
|
||||
// interrupt
|
||||
InterruptStartTime = 3;
|
||||
InterruptLength = 32;
|
||||
// offsets
|
||||
RenderTableOffset = 56;
|
||||
ContentionOffset = 6;
|
||||
FloatingBusOffset = 1;
|
||||
// timing
|
||||
ClockSpeed = 3500000;
|
||||
FrameCycleLength = 69888;
|
||||
ScanlineTime = 224;
|
||||
BorderLeftTime = 24;
|
||||
BorderRightTime = 24;
|
||||
FirstPaperLine = 64;
|
||||
FirstPaperTState = 64;
|
||||
// screen layout
|
||||
Border4T = true;
|
||||
Border4TStage = 0;
|
||||
ScreenWidth = 256;
|
||||
ScreenHeight = 192;
|
||||
BorderTopHeight = 48;// 55;// 48;
|
||||
BorderBottomHeight = 48;// 56;
|
||||
BorderLeftWidth = 48;
|
||||
BorderRightWidth = 48;
|
||||
ScanLineWidth = BorderLeftWidth + ScreenWidth + BorderRightWidth;
|
||||
|
||||
RenderingTable = new RenderTable(this,
|
||||
MachineType.ZXSpectrum48);
|
||||
|
||||
SetupScreenSize();
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
|
@ -1,6 +1,9 @@
|
|||
|
||||
using System.Linq;
|
||||
|
||||
namespace BizHawk.Emulation.Cores.Computers.SinclairSpectrum
|
||||
{
|
||||
/*
|
||||
class ULA48 : ULABase
|
||||
{
|
||||
#region Construction
|
||||
|
@ -8,8 +11,8 @@ namespace BizHawk.Emulation.Cores.Computers.SinclairSpectrum
|
|||
public ULA48(SpectrumBase machine)
|
||||
: base(machine)
|
||||
{
|
||||
InterruptPeriod = 32;
|
||||
LongestOperationCycles = 64;
|
||||
InterruptStart = 0;// 5; // 0; // 3; // 0;// 32;
|
||||
//LongestOperationCycles = 32;
|
||||
FrameLength = 69888;
|
||||
ClockSpeed = 3500000;
|
||||
|
||||
|
@ -55,7 +58,10 @@ namespace BizHawk.Emulation.Cores.Computers.SinclairSpectrum
|
|||
|
||||
public override void Reset()
|
||||
{
|
||||
contentionStartPeriod = 14335; // + LateTiming;
|
||||
contentionOffset = 0;
|
||||
InterruptStart = 0;
|
||||
|
||||
contentionStartPeriod = 14335;// + contentionOffset; // + LateTiming;
|
||||
contentionEndPeriod = contentionStartPeriod + (ScreenHeight * TstatesPerScanline);
|
||||
screen = _machine.RAM0;
|
||||
screenByteCtr = DisplayStart;
|
||||
|
@ -160,6 +166,30 @@ namespace BizHawk.Emulation.Cores.Computers.SinclairSpectrum
|
|||
h += TstatesPerScanline - 128;
|
||||
}
|
||||
|
||||
// offset floating bus table
|
||||
var offset = 0;
|
||||
|
||||
if (offset != 0)
|
||||
{
|
||||
var fbt = floatingBusTable.ToArray();
|
||||
for (int i = 0; i < FrameLength; i++)
|
||||
{
|
||||
var off = i + offset;
|
||||
if (off < 0)
|
||||
{
|
||||
off = FrameLength - 1 + off;
|
||||
}
|
||||
else if (off >= FrameLength)
|
||||
{
|
||||
off = off - FrameLength;
|
||||
}
|
||||
|
||||
fbt[off] = floatingBusTable[i];
|
||||
}
|
||||
|
||||
floatingBusTable = fbt.ToArray();
|
||||
}
|
||||
|
||||
//build bottom border
|
||||
while (t < actualULAStart + (TstateAtTop) + (ScreenHeight * TstatesPerScanline) + (TstateAtBottom))
|
||||
{
|
||||
|
@ -177,4 +207,5 @@ namespace BizHawk.Emulation.Cores.Computers.SinclairSpectrum
|
|||
|
||||
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
|
|
@ -21,7 +21,10 @@ namespace BizHawk.Emulation.Cores.Computers.SinclairSpectrum
|
|||
Spectrum = spectrum;
|
||||
CPU = cpu;
|
||||
|
||||
ULADevice = new ULA48(this);
|
||||
CPUMon = new CPUMonitor(this);
|
||||
|
||||
//ULADevice = new ULA48(this);
|
||||
ULADevice = new Screen48(this);
|
||||
|
||||
BuzzerDevice = new Beeper(this);
|
||||
BuzzerDevice.Init(44100, ULADevice.FrameLength);
|
||||
|
|
|
@ -410,6 +410,28 @@ namespace BizHawk.Emulation.Cores.Computers.SinclairSpectrum
|
|||
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) * (double)100;
|
||||
sb.Append(p.ToString("N0") + "%");
|
||||
SendMessage(sb.ToString().TrimEnd('\n'), MessageCategory.Tape);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
|
|
@ -7,249 +7,11 @@ using System.Threading.Tasks;
|
|||
|
||||
namespace BizHawk.Emulation.Cores.Computers.SinclairSpectrum
|
||||
{
|
||||
/// <summary>
|
||||
/// Utilities
|
||||
/// </summary>
|
||||
public partial class ZXSpectrum
|
||||
{
|
||||
/*
|
||||
* CPU Helper Methods
|
||||
*/
|
||||
|
||||
public ushort RegPC
|
||||
{
|
||||
get { return (ushort)((_cpu.Regs[0] << 8 | _cpu.Regs[1])); }
|
||||
set
|
||||
{
|
||||
_cpu.Regs[1] = (ushort)(value & 0xFF);
|
||||
_cpu.Regs[0] = (ushort)((value >> 8) & 0xFF);
|
||||
}
|
||||
}
|
||||
|
||||
public ushort RegIX
|
||||
{
|
||||
get { return (ushort)((_cpu.Regs[15] << 8 | _cpu.Regs[16] )); }
|
||||
set
|
||||
{
|
||||
_cpu.Regs[16] = (ushort)(value & 0xFF);
|
||||
_cpu.Regs[15] = (ushort)((value >> 8) & 0xFF);
|
||||
}
|
||||
}
|
||||
|
||||
public ushort RegDE
|
||||
{
|
||||
get { return (ushort)((_cpu.Regs[8] << 8 | _cpu.Regs[9] )); }
|
||||
set
|
||||
{
|
||||
_cpu.Regs[9] = (ushort)(value & 0xFF);
|
||||
_cpu.Regs[8] = (ushort)((value >> 8) & 0xFF);
|
||||
}
|
||||
}
|
||||
|
||||
public ushort RegAF
|
||||
{
|
||||
get { return (ushort)((_cpu.Regs[4] << 8 | _cpu.Regs[5])); }
|
||||
set
|
||||
{
|
||||
_cpu.Regs[5] = (ushort)(value & 0xFF);
|
||||
_cpu.Regs[4] = (ushort)((value >> 8) & 0xFF);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Gets the IX word value
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public ushort Get16BitIX()
|
||||
{
|
||||
return Convert.ToUInt16(_cpu.Regs[_cpu.Ixh] | _cpu.Regs[_cpu.Ixl] << 8);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Set the IX word value
|
||||
/// </summary>
|
||||
/// <param name="Ixh"></param>
|
||||
/// <param name="Ixl"></param>
|
||||
public void Set16BitIX(ushort IX)
|
||||
{
|
||||
_cpu.Regs[_cpu.Ixh] = (ushort)(IX & 0xFF);
|
||||
_cpu.Regs[_cpu.Ixl] = (ushort)((IX >> 8) & 0xff);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the AF word value
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public ushort Get16BitAF()
|
||||
{
|
||||
return Convert.ToUInt16(_cpu.Regs[_cpu.A] | _cpu.Regs[_cpu.F] << 8);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Set the AF word value
|
||||
/// </summary>
|
||||
/// <param name="Ixh"></param>
|
||||
/// <param name="Ixl"></param>
|
||||
public void Set16BitAF(ushort AF)
|
||||
{
|
||||
_cpu.Regs[_cpu.A] = (ushort)(AF & 0xFF);
|
||||
_cpu.Regs[_cpu.F] = (ushort)((AF >> 8) & 0xff);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the AF shadow word value
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public ushort Get16BitAF_()
|
||||
{
|
||||
return Convert.ToUInt16(_cpu.Regs[_cpu.A_s] | _cpu.Regs[_cpu.F_s] << 8);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Set the AF shadow word value
|
||||
/// </summary>
|
||||
/// <param name="Ixh"></param>
|
||||
/// <param name="Ixl"></param>
|
||||
public void Set16BitAF_(ushort AF_)
|
||||
{
|
||||
_cpu.Regs[_cpu.A_s] = (ushort)(AF_ & 0xFF);
|
||||
_cpu.Regs[_cpu.F_s] = (ushort)((AF_ >> 8) & 0xff);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the DE word value
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public ushort Get16BitDE()
|
||||
{
|
||||
return Convert.ToUInt16(_cpu.Regs[_cpu.E] | _cpu.Regs[_cpu.D] << 8);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Set the DE word value
|
||||
/// </summary>
|
||||
/// <param name="Ixh"></param>
|
||||
/// <param name="Ixl"></param>
|
||||
public void Set16BitDE(ushort DE)
|
||||
{
|
||||
_cpu.Regs[_cpu.D] = (ushort)(DE & 0xFF);
|
||||
_cpu.Regs[_cpu.E] = (ushort)((DE >> 8) & 0xff);
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Z80 Status Indicator Flag Reset masks
|
||||
/// </summary>
|
||||
/// <seealso cref="FlagsSetMask"/>
|
||||
[Flags]
|
||||
public enum FlagsResetMask : byte
|
||||
{
|
||||
/// <summary>Sign Flag</summary>
|
||||
S = 0x7F,
|
||||
|
||||
/// <summary>Zero Flag</summary>
|
||||
Z = 0xBF,
|
||||
|
||||
/// <summary>This flag is not used.</summary>
|
||||
R5 = 0xDF,
|
||||
|
||||
/// <summary>Half Carry Flag</summary>
|
||||
H = 0xEF,
|
||||
|
||||
/// <summary>This flag is not used.</summary>
|
||||
R3 = 0xF7,
|
||||
|
||||
/// <summary>Parity/Overflow Flag</summary>
|
||||
PV = 0xFB,
|
||||
|
||||
/// <summary>Add/Subtract Flag</summary>
|
||||
N = 0xFD,
|
||||
|
||||
/// <summary>Carry Flag</summary>
|
||||
C = 0xFE,
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Z80 Status Indicator Flag Set masks
|
||||
/// </summary>
|
||||
/// <seealso cref="FlagsResetMask"/>
|
||||
[Flags]
|
||||
public enum FlagsSetMask : byte
|
||||
{
|
||||
/// <summary>Sign Flag</summary>
|
||||
/// <remarks>
|
||||
/// The Sign Flag (S) stores the state of the most-significant bit of
|
||||
/// the Accumulator (bit 7). When the Z80 CPU performs arithmetic
|
||||
/// operations on signed numbers, the binary twos complement notation
|
||||
/// is used to represent and process numeric information.
|
||||
/// </remarks>
|
||||
S = 0x80,
|
||||
|
||||
/// <summary>
|
||||
/// Zero Flag
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// The Zero Flag is set (1) or cleared (0) if the result generated by
|
||||
/// the execution of certain instructions is 0. For 8-bit arithmetic and
|
||||
/// logical operations, the Z flag is set to a 1 if the resulting byte in
|
||||
/// the Accumulator is 0. If the byte is not 0, the Z flag is reset to 0.
|
||||
/// </remarks>
|
||||
Z = 0x40,
|
||||
|
||||
/// <summary>This flag is not used.</summary>
|
||||
R5 = 0x20,
|
||||
|
||||
/// <summary>Half Carry Flag</summary>
|
||||
/// <remarks>
|
||||
/// The Half Carry Flag (H) is set (1) or cleared (0) depending on the
|
||||
/// Carry and Borrow status between bits 3 and 4 of an 8-bit arithmetic
|
||||
/// operation. This flag is used by the Decimal Adjust Accumulator (DAA)
|
||||
/// instruction to correct the result of a packed BCD add or subtract operation.
|
||||
/// </remarks>
|
||||
H = 0x10,
|
||||
|
||||
/// <summary>This flag is not used.</summary>
|
||||
R3 = 0x08,
|
||||
|
||||
/// <summary>Parity/Overflow Flag</summary>
|
||||
/// <remarks>
|
||||
/// The Parity/Overflow (P/V) Flag is set to a specific state depending on
|
||||
/// the operation being performed. For arithmetic operations, this flag
|
||||
/// indicates an overflow condition when the result in the Accumulator is
|
||||
/// greater than the maximum possible number (+127) or is less than the
|
||||
/// minimum possible number (–128). This overflow condition is determined by
|
||||
/// examining the sign bits of the operands.
|
||||
/// </remarks>
|
||||
PV = 0x04,
|
||||
|
||||
/// <summary>Add/Subtract Flag</summary>
|
||||
/// <remarks>
|
||||
/// The Add/Subtract Flag (N) is used by the Decimal Adjust Accumulator
|
||||
/// instruction (DAA) to distinguish between the ADD and SUB instructions.
|
||||
/// For ADD instructions, N is cleared to 0. For SUB instructions, N is set to 1.
|
||||
/// </remarks>
|
||||
N = 0x02,
|
||||
|
||||
/// <summary>Carry Flag</summary>
|
||||
/// <remarks>
|
||||
/// The Carry Flag (C) is set or cleared depending on the operation being performed.
|
||||
/// </remarks>
|
||||
C = 0x01,
|
||||
|
||||
/// <summary>
|
||||
/// Combination of S, Z, and PV
|
||||
/// </summary>
|
||||
SZPV = S | Z | PV,
|
||||
|
||||
/// <summary>
|
||||
/// Combination of N, and H
|
||||
/// </summary>
|
||||
NH = N | H,
|
||||
|
||||
/// <summary>
|
||||
/// Combination of R3, and R5
|
||||
/// </summary>
|
||||
R3R5 = R3 | R5
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Helper method that returns a single INT32 from a BitArray
|
||||
/// </summary>
|
||||
|
@ -264,5 +26,44 @@ namespace BizHawk.Emulation.Cores.Computers.SinclairSpectrum
|
|||
bitArray.CopyTo(array, 0);
|
||||
return array[0];
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// POKEs a memory bus address
|
||||
/// </summary>
|
||||
/// <param name="addr"></param>
|
||||
/// <param name="value"></param>
|
||||
public void PokeMemory(ushort addr, byte value)
|
||||
{
|
||||
_machine.WriteBus(addr, value);
|
||||
}
|
||||
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
return m;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -91,6 +91,7 @@ namespace BizHawk.Emulation.Cores.Computers.SinclairSpectrum
|
|||
_cpu.ReadHardware = _machine.ReadPort;
|
||||
_cpu.WriteHardware = _machine.WritePort;
|
||||
_cpu.FetchDB = _machine.PushBus;
|
||||
_cpu.OnExecFetch = _machine.CPUMon.OnExecFetch;
|
||||
|
||||
ser.Register<ITraceable>(_tracer);
|
||||
ser.Register<IDisassemblable>(_cpu);
|
||||
|
|
Loading…
Reference in New Issue