Ammendments to Z80 to make it system agnostic.

This commit is contained in:
2026-04-24 14:27:08 +01:00
parent 0e8462c8a5
commit 2842af182f
3 changed files with 61 additions and 118 deletions

View File

@@ -50,7 +50,7 @@ namespace Desktop
_memoryBus.CrapRAMData();
byte[] romData = RomLoader.Load("48.rom");
_memoryBus.LoadRom(romData);
_cpu = new Z80(_memoryBus, _simpleIoBus, _tapManager);
_cpu = new Z80(_memoryBus, _simpleIoBus);
_cpu.WaitStateCallback = _ula.GetContentionDelay;
}
@@ -112,6 +112,13 @@ namespace Desktop
long tStatesBefore = _cpu.TotalTStates;
// --- HARDWARE INTERCEPTS ---
if (_cpu.PC == 0x0556 && _tapManager.HasBlocks)
{
HandleInstantTapeLoad();
_cpu.TotalTStates += 100; // Charge some arbitrary time for the fast load
}
// --- Execute Instruction ---
_cpu.Step();
@@ -218,6 +225,52 @@ namespace Desktop
});
}
private void HandleInstantTapeLoad()
{
byte[] block = _tapManager.GetNextBlock(); // Your original Queue.Dequeue() method
if (block == null) return;
byte expectedFlag = _cpu.AF.High;
if (block[0] != expectedFlag)
{
// Block mismatch (e.g. found data when looking for a header)
// Clear the carry flag to simulate a tape loading error
_cpu.AF.Low &= unchecked((byte)~0x01);
ForceRet();
return;
}
int bytesToCopy = _cpu.DE.Word;
// Safety check just in case the TAP file is malformed
int actualBytes = Math.Min(bytesToCopy, block.Length - 1);
// Directly inject the payload into the RAM
for (int i = 0; i < actualBytes; i++)
{
_memoryBus.Write((ushort)(_cpu.IX.Word + i), block[i + 1]);
}
// --- Update Registers to match a PERFECT ROM Load ---
_cpu.IX.Word = (ushort)(_cpu.IX.Word + actualBytes);
_cpu.DE.Word = (ushort)(bytesToCopy - actualBytes); // Should hit 0
_cpu.HL.Word = 0x0000; // The ROM zeroes this out after calculating checksums
// Checksum Zero (A = 0x00), Success Flag / Zero Flag Set (F = 0x41)
_cpu.AF.Word = 0x0041;
ForceRet();
}
private void ForceRet()
{
// Pop the return address off the stack just like a real RET instruction
byte pcLow = _memoryBus.Read(_cpu.SP);
_cpu.SP++;
byte pcHigh = _memoryBus.Read(_cpu.SP);
_cpu.SP++;
_cpu.PC = (ushort)((pcHigh << 8) | pcLow);
}
private void UpdateScreenBitmap()
@@ -246,21 +299,14 @@ namespace Desktop
if (ofd.ShowDialog() == DialogResult.OK)
{
byte[] tapBytes = File.ReadAllBytes(ofd.FileName);
_cpu._tapManager.LoadTapData(tapBytes);
_tapManager.LoadTapData(tapBytes);
tapeLoaded = true;
}
}
_isPaused = false;
}
private void fastLoadingToolStripMenuItem_Click(object sender, EventArgs e)
{
// Toggle the checkmark UI
fastLoadingToolStripMenuItem.Checked = !fastLoadingToolStripMenuItem.Checked;
// Tell the CPU to enable or disable the ROM hijack
_cpu.EnableFastLoad = fastLoadingToolStripMenuItem.Checked;
}
private void openSNAToolStripMenuItem_Click(object sender, EventArgs e)
{
_isPaused = true;