Implemented a load more Z80 OpCodes. Added a breakpoint to the debugger

This commit is contained in:
2026-04-09 17:31:56 +01:00
parent f22da937b5
commit 0ef8b9f3eb
4 changed files with 154 additions and 16 deletions

View File

@@ -11,6 +11,7 @@ namespace Desktop
private readonly Z80 _cpu;
private readonly MemoryBus _memoryBus;
private bool _isRunning = false;
private ushort? _breakpoint = null;
public DebuggerForm(Z80 cpu, MemoryBus memoryBus)
{
@@ -57,18 +58,45 @@ namespace Desktop
return;
}
// --- NEW: Parse the Breakpoint ---
if (!string.IsNullOrWhiteSpace(txtBreakpoint.Text))
{
if (ushort.TryParse(txtBreakpoint.Text, System.Globalization.NumberStyles.HexNumber, null, out ushort parsedBp))
{
_breakpoint = parsedBp;
}
else
{
MessageBox.Show("Invalid hex address in breakpoint!", "Error", MessageBoxButtons.OK, MessageBoxIcon.Warning);
return;
}
}
else
{
_breakpoint = null; // No text means no breakpoint
}
// ---------------------------------
// Start the run state
_isRunning = true;
btnRun.Text = "Stop";
// Fire up a background thread so the Windows UI doesn't freeze
// Fire up a background thread
await Task.Run(() =>
{
try
{
// Free-run the CPU until the flag is flipped or it crashes!
while (_isRunning)
{
// --- NEW: Breakpoint Check ---
// We check BEFORE stepping so it stops exactly on the instruction
if (_breakpoint.HasValue && _cpu.PC == _breakpoint.Value)
{
_isRunning = false;
break; // Cleanly exit the while loop
}
// -----------------------------
_cpu.Step();
}
}
@@ -76,22 +104,17 @@ namespace Desktop
{
_isRunning = false;
// We are on a background thread. We MUST use Invoke to tell the
// main UI thread to update the labels and show the message box!
this.Invoke((MethodInvoker)delegate
{
btnRun.Text = "Run";
UpdateDisplay();
MessageBox.Show(ex.Message, "CPU Break", MessageBoxButtons.OK, MessageBoxIcon.Information);
});
}
});
// If the user clicked Stop manually (no exception thrown), we still want to update the UI
if (!_isRunning)
{
UpdateDisplay();
}
// Whether it stopped because of a breakpoint, a crash, or the user clicking "Stop",
// we MUST update the UI when the background thread finishes!
btnRun.Text = "Run";
UpdateDisplay();
}
private void btnExit_Click(object sender, EventArgs e)
@@ -186,8 +209,6 @@ namespace Desktop
{
lstDisassembly.Items.Clear();
// THIS is the critical link! It forces the top of the list
// to always be exactly where the CPU currently is.
ushort currentPc = _cpu.PC;
int instructionsToShow = 8;
@@ -220,6 +241,12 @@ namespace Desktop
case 0x23:
mnemonic = "INC HL";
break;
case 0x28:
sbyte jrZOffset = (sbyte)_memoryBus.Read((ushort)(currentPc + 1));
ushort jrZDest = (ushort)(currentPc + 2 + jrZOffset);
mnemonic = $"JR Z, 0x{jrZDest:X4}";
instructionLength = 2;
break;
case 0x2B:
mnemonic = "DEC HL";
break;
@@ -229,6 +256,9 @@ namespace Desktop
mnemonic = $"JR NC, 0x{dest:X4}";
instructionLength = 2;
break;
case 0x35:
mnemonic = "DEC (HL)";
break;
case 0x36:
byte memValue = _memoryBus.Read((ushort)(currentPc + 1));
mnemonic = $"LD (HL), 0x{memValue:X2}";
@@ -268,6 +298,9 @@ namespace Desktop
mnemonic = $"OUT (0x{outPort:X2}), A";
instructionLength = 2;
break;
case 0xD9:
mnemonic = "EXX";
break;
case 0xDE:
byte sbcValue = _memoryBus.Read((ushort)(currentPc + 1));
mnemonic = $"SBC A, 0x{sbcValue:X2}";