5 ZEXALL tests now complete. Going to implement ALL remaining OpCOdes
This commit is contained in:
4765
Core/Cpu/Z80.cs
4765
Core/Cpu/Z80.cs
File diff suppressed because it is too large
Load Diff
@@ -1241,6 +1241,17 @@ namespace Desktop
|
|||||||
mnemonic = $"LD A, (IY{sign}{d})";
|
mnemonic = $"LD A, (IY{sign}{d})";
|
||||||
instructionLength = 3;
|
instructionLength = 3;
|
||||||
}
|
}
|
||||||
|
else if (fdOpcode == 0x84) // ADD A, IYH
|
||||||
|
{
|
||||||
|
|
||||||
|
mnemonic = $"ADD A, IYH";
|
||||||
|
instructionLength = 2;
|
||||||
|
}
|
||||||
|
else if (fdOpcode == 0x85) // ADD A, IYL
|
||||||
|
{
|
||||||
|
mnemonic = $"ADD A, IYL";
|
||||||
|
instructionLength = 2;
|
||||||
|
}
|
||||||
else if (fdOpcode == 0x86) // ADD A, (IY+d)
|
else if (fdOpcode == 0x86) // ADD A, (IY+d)
|
||||||
{
|
{
|
||||||
sbyte dAdd = (sbyte)_memoryBus.Read((ushort)(currentPc + 2));
|
sbyte dAdd = (sbyte)_memoryBus.Read((ushort)(currentPc + 2));
|
||||||
|
|||||||
16
Desktop/Form1.Designer.cs
generated
16
Desktop/Form1.Designer.cs
generated
@@ -44,7 +44,7 @@
|
|||||||
resetToolStripMenuItem1 = new ToolStripMenuItem();
|
resetToolStripMenuItem1 = new ToolStripMenuItem();
|
||||||
optionsToolStripMenuItem = new ToolStripMenuItem();
|
optionsToolStripMenuItem = new ToolStripMenuItem();
|
||||||
fastLoadingToolStripMenuItem = new ToolStripMenuItem();
|
fastLoadingToolStripMenuItem = new ToolStripMenuItem();
|
||||||
runZEXDOCToolStripMenuItem = new ToolStripMenuItem();
|
HighSpeedToolStripMenuItem = new ToolStripMenuItem();
|
||||||
((System.ComponentModel.ISupportInitialize)picScreen).BeginInit();
|
((System.ComponentModel.ISupportInitialize)picScreen).BeginInit();
|
||||||
menuStrip1.SuspendLayout();
|
menuStrip1.SuspendLayout();
|
||||||
SuspendLayout();
|
SuspendLayout();
|
||||||
@@ -156,7 +156,7 @@
|
|||||||
//
|
//
|
||||||
// optionsToolStripMenuItem
|
// optionsToolStripMenuItem
|
||||||
//
|
//
|
||||||
optionsToolStripMenuItem.DropDownItems.AddRange(new ToolStripItem[] { fastLoadingToolStripMenuItem, runZEXDOCToolStripMenuItem });
|
optionsToolStripMenuItem.DropDownItems.AddRange(new ToolStripItem[] { fastLoadingToolStripMenuItem, HighSpeedToolStripMenuItem });
|
||||||
optionsToolStripMenuItem.Name = "optionsToolStripMenuItem";
|
optionsToolStripMenuItem.Name = "optionsToolStripMenuItem";
|
||||||
optionsToolStripMenuItem.Size = new Size(75, 24);
|
optionsToolStripMenuItem.Size = new Size(75, 24);
|
||||||
optionsToolStripMenuItem.Text = "Options";
|
optionsToolStripMenuItem.Text = "Options";
|
||||||
@@ -170,12 +170,12 @@
|
|||||||
fastLoadingToolStripMenuItem.Text = "Fast TAP Loading";
|
fastLoadingToolStripMenuItem.Text = "Fast TAP Loading";
|
||||||
fastLoadingToolStripMenuItem.Click += fastLoadingToolStripMenuItem_Click;
|
fastLoadingToolStripMenuItem.Click += fastLoadingToolStripMenuItem_Click;
|
||||||
//
|
//
|
||||||
// runZEXDOCToolStripMenuItem
|
// HighSpeedToolStripMenuItem
|
||||||
//
|
//
|
||||||
runZEXDOCToolStripMenuItem.Name = "runZEXDOCToolStripMenuItem";
|
HighSpeedToolStripMenuItem.Name = "HighSpeedToolStripMenuItem";
|
||||||
runZEXDOCToolStripMenuItem.Size = new Size(224, 26);
|
HighSpeedToolStripMenuItem.Size = new Size(224, 26);
|
||||||
runZEXDOCToolStripMenuItem.Text = "Run ZEXDOC";
|
HighSpeedToolStripMenuItem.Text = "High Speed";
|
||||||
runZEXDOCToolStripMenuItem.Click += btnRunZexDoc_Click;
|
HighSpeedToolStripMenuItem.Click += btnHighSpeedToggle_Click;
|
||||||
//
|
//
|
||||||
// Form1
|
// Form1
|
||||||
//
|
//
|
||||||
@@ -213,6 +213,6 @@
|
|||||||
private ToolStripMenuItem resetToolStripMenuItem1;
|
private ToolStripMenuItem resetToolStripMenuItem1;
|
||||||
private ToolStripMenuItem optionsToolStripMenuItem;
|
private ToolStripMenuItem optionsToolStripMenuItem;
|
||||||
private ToolStripMenuItem fastLoadingToolStripMenuItem;
|
private ToolStripMenuItem fastLoadingToolStripMenuItem;
|
||||||
private ToolStripMenuItem runZEXDOCToolStripMenuItem;
|
private ToolStripMenuItem HighSpeedToolStripMenuItem;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
103
Desktop/Form1.cs
103
Desktop/Form1.cs
@@ -26,7 +26,8 @@ namespace Desktop
|
|||||||
public double FramesPerSecond = 0;
|
public double FramesPerSecond = 0;
|
||||||
public double TotalFrameTime = 0;
|
public double TotalFrameTime = 0;
|
||||||
public double FrameTime = 0;
|
public double FrameTime = 0;
|
||||||
public bool exceptionRaised = false;
|
public bool highSpeed = false;
|
||||||
|
public bool tapeLoaded = false;
|
||||||
|
|
||||||
|
|
||||||
public Form1()
|
public Form1()
|
||||||
@@ -102,18 +103,24 @@ namespace Desktop
|
|||||||
_tapManager.Update(elapsedTStates);
|
_tapManager.Update(elapsedTStates);
|
||||||
|
|
||||||
//Process audio at the correct time
|
//Process audio at the correct time
|
||||||
//while (_cpu.TotalTStates >= (long)(audioSampleCount * 79.365))
|
if (!highSpeed)
|
||||||
//{
|
{
|
||||||
// bool finalAudioOutput = _simpleIoBus.BeeperState ^ _tapManager.EarBit;
|
while (_cpu.TotalTStates >= (long)(audioSampleCount * 79.365))
|
||||||
// _beeper.AddSample(finalAudioOutput);
|
{
|
||||||
// audioSampleCount++;
|
bool finalAudioOutput = _simpleIoBus.BeeperState ^ _tapManager.EarBit;
|
||||||
//}
|
_beeper.AddSample(finalAudioOutput);
|
||||||
|
audioSampleCount++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// --- Check for End of Frame ---
|
// --- Check for End of Frame ---
|
||||||
if (_cpu.TotalTStates >= nextScanlineTarget)
|
if (_cpu.TotalTStates >= nextScanlineTarget)
|
||||||
{
|
{
|
||||||
// Tell the ULA to draw one line of pixels
|
// Tell the ULA to draw one line of pixels
|
||||||
_ula.RenderScanline((int)scanlineCount % 312);
|
if (!highSpeed || (TotalFrameCount % 10 == 0))
|
||||||
|
{
|
||||||
|
_ula.RenderScanline((int)scanlineCount % 312);
|
||||||
|
}
|
||||||
|
|
||||||
nextScanlineTarget += 224; // Advance target by ONE line (224 T-States)
|
nextScanlineTarget += 224; // Advance target by ONE line (224 T-States)
|
||||||
scanlineCount++;
|
scanlineCount++;
|
||||||
@@ -122,22 +129,41 @@ namespace Desktop
|
|||||||
if (scanlineCount % 312 == 0)
|
if (scanlineCount % 312 == 0)
|
||||||
{
|
{
|
||||||
_cpu.RequestInterrupt(); // 50Hz interrupt
|
_cpu.RequestInterrupt(); // 50Hz interrupt
|
||||||
|
|
||||||
this.Invoke((MethodInvoker)delegate
|
|
||||||
{
|
|
||||||
UpdateScreenBitmap();
|
|
||||||
this.Text = $"{_baseTitle} - FPS: {FramesPerSecond:F1} - Fast Loading: {_cpu.EnableFastLoad.ToString()}";
|
|
||||||
});
|
|
||||||
TotalFrameCount++;
|
TotalFrameCount++;
|
||||||
|
|
||||||
// Throttle to real-time (50 FPS = 20ms)
|
if (highSpeed)
|
||||||
//long targetTimeMs = (scanlineCount / 312) * 20;
|
{
|
||||||
//long elapsedMs = stopwatch.ElapsedMilliseconds;
|
if (TotalFrameCount % 10 == 0)
|
||||||
|
{
|
||||||
|
this.BeginInvoke((MethodInvoker)delegate
|
||||||
|
{
|
||||||
|
UpdateScreenBitmap();
|
||||||
|
this.Text = $"{_baseTitle} - FPS: {FramesPerSecond:F1}";
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
//if (elapsedMs < targetTimeMs)
|
}
|
||||||
//{
|
else
|
||||||
// Thread.Sleep((int)(targetTimeMs - elapsedMs));
|
{
|
||||||
//}
|
this.Invoke((MethodInvoker)delegate
|
||||||
|
{
|
||||||
|
UpdateScreenBitmap();
|
||||||
|
this.Text = $"{_baseTitle} - FPS: {FramesPerSecond:F1} - Tape Loaded: {tapeLoaded.ToString()}";
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Throttle to real-time (50 FPS = 20ms)
|
||||||
|
if (!highSpeed)
|
||||||
|
{
|
||||||
|
long targetTimeMs = (scanlineCount / 312) * 20;
|
||||||
|
long elapsedMs = stopwatch.ElapsedMilliseconds;
|
||||||
|
|
||||||
|
if (elapsedMs < targetTimeMs)
|
||||||
|
{
|
||||||
|
Thread.Sleep((int)(targetTimeMs - elapsedMs));
|
||||||
|
}
|
||||||
|
}
|
||||||
TotalFrameTime += fpsStopwatch.Elapsed.TotalMilliseconds;
|
TotalFrameTime += fpsStopwatch.Elapsed.TotalMilliseconds;
|
||||||
if (TotalFrameCount % 50 == 0)
|
if (TotalFrameCount % 50 == 0)
|
||||||
{
|
{
|
||||||
@@ -192,6 +218,7 @@ namespace Desktop
|
|||||||
{
|
{
|
||||||
byte[] tapBytes = File.ReadAllBytes(ofd.FileName);
|
byte[] tapBytes = File.ReadAllBytes(ofd.FileName);
|
||||||
_cpu._tapManager.LoadTapData(tapBytes);
|
_cpu._tapManager.LoadTapData(tapBytes);
|
||||||
|
tapeLoaded = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_isPaused = false;
|
_isPaused = false;
|
||||||
@@ -220,38 +247,10 @@ namespace Desktop
|
|||||||
_isPaused = false;
|
_isPaused = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void btnRunZexDoc_Click(object sender, EventArgs e)
|
private void btnHighSpeedToggle_Click(object sender, EventArgs e)
|
||||||
{
|
{
|
||||||
_isPaused = true;
|
this.HighSpeedToolStripMenuItem.Checked = !this.HighSpeedToolStripMenuItem.Checked;
|
||||||
|
highSpeed = this.HighSpeedToolStripMenuItem.Checked ? true : false;
|
||||||
using (OpenFileDialog ofd = new OpenFileDialog())
|
|
||||||
{
|
|
||||||
ofd.Filter = "CP/M Binaries (*.com, *.bin)|*.com;*.bin";
|
|
||||||
if (ofd.ShowDialog() == DialogResult.OK)
|
|
||||||
{
|
|
||||||
byte[] zexdocBytes = System.IO.File.ReadAllBytes(ofd.FileName);
|
|
||||||
|
|
||||||
// 1. Wipe the RAM completely clean
|
|
||||||
_memoryBus.CleanRAMData();
|
|
||||||
|
|
||||||
// 2. Load ZEXDOC exactly at CP/M start address 0x0100
|
|
||||||
for (int i = 0; i < zexdocBytes.Length; i++)
|
|
||||||
{
|
|
||||||
_memoryBus.Write((ushort)(0x0100 + i), zexdocBytes[i]);
|
|
||||||
}
|
|
||||||
|
|
||||||
// 3. Configure the CPU for CP/M
|
|
||||||
_cpu.IsZexDocMode = true;
|
|
||||||
_cpu.PC = 0x0100; // Execution starts here
|
|
||||||
_cpu.SP = 0xFFFF; // Put the stack at the very top of memory
|
|
||||||
|
|
||||||
// 4. Fake a RET address at 0x0000 so the test terminates gracefully when finished
|
|
||||||
_memoryBus.Write(0x0000, 0xD3); // OUT (n), A (A fake halt sequence)
|
|
||||||
|
|
||||||
// Unpause and watch the Visual Studio Output window!
|
|
||||||
_isPaused = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
private void btnRun_Click(object sender, EventArgs e) => _isPaused = false;
|
private void btnRun_Click(object sender, EventArgs e) => _isPaused = false;
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user