5 ZEXALL tests now complete. Going to implement ALL remaining OpCOdes

This commit is contained in:
2026-04-23 16:51:21 +01:00
parent 112b6d15fe
commit 5892f7e491
4 changed files with 3532 additions and 1373 deletions

File diff suppressed because it is too large Load Diff

View File

@@ -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));

View File

@@ -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;
} }
} }

View File

@@ -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}";
});
}
}
else
{
this.Invoke((MethodInvoker)delegate
{
UpdateScreenBitmap();
this.Text = $"{_baseTitle} - FPS: {FramesPerSecond:F1} - Tape Loaded: {tapeLoaded.ToString()}";
});
}
//if (elapsedMs < targetTimeMs)
//{ // Throttle to real-time (50 FPS = 20ms)
// Thread.Sleep((int)(targetTimeMs - elapsedMs)); 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;