From c2bbaf76722c3e2eb7540a4d91de78aba4ca07db Mon Sep 17 00:00:00 2001 From: Marc Parsons Date: Sat, 11 Apr 2026 02:38:20 +0100 Subject: [PATCH] Implemented many more OpCodes - 11042026_02_38 --- Core/Cpu/Z80.cs | 17 +++++ Desktop/DebuggerForm.Designer.cs | 109 +++++++++++++++++++------------ Desktop/DebuggerForm.cs | 21 +++++- 3 files changed, 106 insertions(+), 41 deletions(-) diff --git a/Core/Cpu/Z80.cs b/Core/Cpu/Z80.cs index 9f85c39..746433a 100644 --- a/Core/Cpu/Z80.cs +++ b/Core/Cpu/Z80.cs @@ -447,6 +447,8 @@ namespace Core.Cpu case 0xF9: // LD SP, HL SP = HL.Word; // (Use SP.Word = HL.Word if you made SP a RegisterPair) return 6; + case 0xFD: + return ExecuteFDPrefix(); default: throw new NotImplementedException($"Opcode 0x{opcode:X2} at PC 0x{(PC - 1):X4} is not implemented."); } @@ -509,5 +511,20 @@ namespace Core.Cpu throw new NotImplementedException($"Extended ED Opcode 0x{extendedOpcode:X2} at PC 0x{(PC - 1):X4} is not implemented."); } } + + private int ExecuteFDPrefix() + { + byte opcode = FetchByte(); + + switch (opcode) + { + case 0x21: // LD IY, nn + IY.Word = FetchWord(); + return 14; // Takes 14 T-States + + default: + throw new NotImplementedException($"FD prefix opcode {opcode:X2} not implemented!"); + } + } } } \ No newline at end of file diff --git a/Desktop/DebuggerForm.Designer.cs b/Desktop/DebuggerForm.Designer.cs index 689e36f..6789316 100644 --- a/Desktop/DebuggerForm.Designer.cs +++ b/Desktop/DebuggerForm.Designer.cs @@ -48,94 +48,96 @@ label1 = new Label(); txtBreakpoint = new TextBox(); label2 = new Label(); + lblIX = new Label(); + lblIY = new Label(); SuspendLayout(); // // lblAF // lblAF.AutoSize = true; - lblAF.Location = new Point(10, 7); + lblAF.Location = new Point(12, 9); lblAF.Margin = new Padding(2, 0, 2, 0); lblAF.Name = "lblAF"; - lblAF.Size = new Size(26, 20); + lblAF.Size = new Size(33, 25); lblAF.TabIndex = 0; lblAF.Text = "AF"; // // lblBC // lblBC.AutoSize = true; - lblBC.Location = new Point(9, 48); + lblBC.Location = new Point(11, 60); lblBC.Margin = new Padding(2, 0, 2, 0); lblBC.Name = "lblBC"; - lblBC.Size = new Size(27, 20); + lblBC.Size = new Size(33, 25); lblBC.TabIndex = 1; lblBC.Text = "BC"; // // lblDE // lblDE.AutoSize = true; - lblDE.Location = new Point(10, 100); + lblDE.Location = new Point(12, 125); lblDE.Margin = new Padding(2, 0, 2, 0); lblDE.Name = "lblDE"; - lblDE.Size = new Size(28, 20); + lblDE.Size = new Size(34, 25); lblDE.TabIndex = 2; lblDE.Text = "DE"; // // lblHL // lblHL.AutoSize = true; - lblHL.Location = new Point(10, 150); + lblHL.Location = new Point(12, 188); lblHL.Margin = new Padding(2, 0, 2, 0); lblHL.Name = "lblHL"; - lblHL.Size = new Size(27, 20); + lblHL.Size = new Size(33, 25); lblHL.TabIndex = 3; lblHL.Text = "HL"; // // lblPC // lblPC.AutoSize = true; - lblPC.Location = new Point(9, 200); + lblPC.Location = new Point(11, 250); lblPC.Margin = new Padding(2, 0, 2, 0); lblPC.Name = "lblPC"; - lblPC.Size = new Size(26, 20); + lblPC.Size = new Size(33, 25); lblPC.TabIndex = 4; lblPC.Text = "PC"; // // lblSP // lblSP.AutoSize = true; - lblSP.Location = new Point(9, 252); + lblSP.Location = new Point(11, 315); lblSP.Margin = new Padding(2, 0, 2, 0); lblSP.Name = "lblSP"; - lblSP.Size = new Size(25, 20); + lblSP.Size = new Size(32, 25); lblSP.TabIndex = 6; lblSP.Text = "SP"; // // lblFlags // lblFlags.AutoSize = true; - lblFlags.Location = new Point(88, 52); + lblFlags.Location = new Point(110, 65); lblFlags.Margin = new Padding(2, 0, 2, 0); lblFlags.Name = "lblFlags"; - lblFlags.Size = new Size(43, 20); + lblFlags.Size = new Size(53, 25); lblFlags.TabIndex = 7; lblFlags.Text = "Flags"; // // lblTStates // lblTStates.AutoSize = true; - lblTStates.Location = new Point(88, 7); + lblTStates.Location = new Point(110, 9); lblTStates.Margin = new Padding(2, 0, 2, 0); lblTStates.Name = "lblTStates"; - lblTStates.Size = new Size(63, 20); + lblTStates.Size = new Size(75, 25); lblTStates.TabIndex = 8; lblTStates.Text = "T-States"; // // txtMemoryStart // - txtMemoryStart.Location = new Point(300, 21); + txtMemoryStart.Location = new Point(375, 26); txtMemoryStart.Margin = new Padding(2); txtMemoryStart.Name = "txtMemoryStart"; - txtMemoryStart.Size = new Size(121, 27); + txtMemoryStart.Size = new Size(150, 31); txtMemoryStart.TabIndex = 9; txtMemoryStart.Text = "Memory Start"; txtMemoryStart.TextAlign = HorizontalAlignment.Center; @@ -143,10 +145,10 @@ // // btnStep // - btnStep.Location = new Point(9, 315); + btnStep.Location = new Point(8, 523); btnStep.Margin = new Padding(2); btnStep.Name = "btnStep"; - btnStep.Size = new Size(90, 27); + btnStep.Size = new Size(112, 34); btnStep.TabIndex = 12; btnStep.Text = "Step"; btnStep.UseVisualStyleBackColor = true; @@ -154,10 +156,10 @@ // // btnRun // - btnRun.Location = new Point(122, 315); + btnRun.Location = new Point(149, 523); btnRun.Margin = new Padding(2); btnRun.Name = "btnRun"; - btnRun.Size = new Size(90, 27); + btnRun.Size = new Size(112, 34); btnRun.TabIndex = 13; btnRun.Text = "Run"; btnRun.UseVisualStyleBackColor = true; @@ -165,10 +167,10 @@ // // btnRefreshMemory // - btnRefreshMemory.Location = new Point(425, 21); + btnRefreshMemory.Location = new Point(531, 26); btnRefreshMemory.Margin = new Padding(2); btnRefreshMemory.Name = "btnRefreshMemory"; - btnRefreshMemory.Size = new Size(90, 27); + btnRefreshMemory.Size = new Size(112, 34); btnRefreshMemory.TabIndex = 14; btnRefreshMemory.Text = "Refresh Memory"; btnRefreshMemory.UseVisualStyleBackColor = true; @@ -176,37 +178,39 @@ // // txtMemoryView // - txtMemoryView.Location = new Point(88, 80); + txtMemoryView.Location = new Point(110, 100); txtMemoryView.Margin = new Padding(2); txtMemoryView.Name = "txtMemoryView"; - txtMemoryView.Size = new Size(416, 195); + txtMemoryView.Size = new Size(519, 243); txtMemoryView.TabIndex = 15; txtMemoryView.Text = "Memory View Window"; // // lstDisassembly // lstDisassembly.FormattingEnabled = true; - lstDisassembly.Location = new Point(523, 11); + lstDisassembly.ItemHeight = 25; + lstDisassembly.Location = new Point(654, 14); lstDisassembly.Margin = new Padding(2); lstDisassembly.Name = "lstDisassembly"; - lstDisassembly.Size = new Size(252, 264); + lstDisassembly.Size = new Size(314, 329); lstDisassembly.TabIndex = 16; // // lstStack // lstStack.FormattingEnabled = true; - lstStack.Location = new Point(779, 11); + lstStack.ItemHeight = 25; + lstStack.Location = new Point(974, 14); lstStack.Margin = new Padding(2); lstStack.Name = "lstStack"; - lstStack.Size = new Size(130, 264); + lstStack.Size = new Size(162, 329); lstStack.TabIndex = 17; // // btnExit // - btnExit.Location = new Point(818, 313); + btnExit.Location = new Point(1019, 520); btnExit.Margin = new Padding(2); btnExit.Name = "btnExit"; - btnExit.Size = new Size(90, 27); + btnExit.Size = new Size(112, 34); btnExit.TabIndex = 18; btnExit.Text = "Full Exit"; btnExit.UseVisualStyleBackColor = true; @@ -215,33 +219,56 @@ // label1 // label1.AutoSize = true; - label1.Location = new Point(289, 288); + label1.Location = new Point(361, 360); + label1.Margin = new Padding(4, 0, 4, 0); label1.Name = "label1"; - label1.Size = new Size(81, 20); + label1.Size = new Size(97, 25); label1.TabIndex = 19; label1.Text = "Breakpoint"; // // txtBreakpoint // - txtBreakpoint.Location = new Point(376, 281); + txtBreakpoint.Location = new Point(470, 351); + txtBreakpoint.Margin = new Padding(4, 4, 4, 4); txtBreakpoint.Name = "txtBreakpoint"; - txtBreakpoint.Size = new Size(125, 27); + txtBreakpoint.Size = new Size(155, 31); txtBreakpoint.TabIndex = 20; // // label2 // label2.AutoSize = true; - label2.Location = new Point(233, 21); + label2.Location = new Point(291, 26); + label2.Margin = new Padding(4, 0, 4, 0); label2.Name = "label2"; - label2.Size = new Size(62, 20); + label2.Size = new Size(77, 25); label2.TabIndex = 21; label2.Text = "Address"; // + // lblIX + // + lblIX.AutoSize = true; + lblIX.Location = new Point(11, 373); + lblIX.Name = "lblIX"; + lblIX.Size = new Size(28, 25); + lblIX.TabIndex = 22; + lblIX.Text = "IX"; + // + // lblIY + // + lblIY.AutoSize = true; + lblIY.Location = new Point(12, 430); + lblIY.Name = "lblIY"; + lblIY.Size = new Size(27, 25); + lblIY.TabIndex = 23; + lblIY.Text = "IY"; + // // DebuggerForm // - AutoScaleDimensions = new SizeF(8F, 20F); + AutoScaleDimensions = new SizeF(10F, 25F); AutoScaleMode = AutoScaleMode.Font; - ClientSize = new Size(928, 350); + ClientSize = new Size(1160, 568); + Controls.Add(lblIY); + Controls.Add(lblIX); Controls.Add(label2); Controls.Add(txtBreakpoint); Controls.Add(label1); @@ -290,6 +317,8 @@ private Label label1; private TextBox txtBreakpoint; private Label label2; + private Label lblIX; + private Label lblIY; //private TextBox textBox4; } } \ No newline at end of file diff --git a/Desktop/DebuggerForm.cs b/Desktop/DebuggerForm.cs index 2c26139..73f26d2 100644 --- a/Desktop/DebuggerForm.cs +++ b/Desktop/DebuggerForm.cs @@ -132,6 +132,8 @@ namespace Desktop lblHL.Text = $"HL: {_cpu.HL.Word:X4}"; lblPC.Text = $"PC: {_cpu.PC:X4}"; lblSP.Text = $"SP: {_cpu.SP:X4}"; + lblIX.Text = $"IX: {_cpu.IX.Word:X4}"; + lblIY.Text = $"IY: {_cpu.IY.Word:X4}"; // 2. Update Flags & T-States lblFlags.Text = $"Flags: {_cpu.GetFlagsString()}"; @@ -345,7 +347,7 @@ namespace Desktop ushort bcAddr = (ushort)(_memoryBus.Read((ushort)(currentPc + 2)) | (_memoryBus.Read((ushort)(currentPc + 3)) << 8)); mnemonic = $"LD (0x{bcAddr:X4}), BC"; instructionLength = 4; - break; + break; case 0x47: mnemonic = "LD I, A"; instructionLength = 2; // 0xED + 0x47 @@ -384,6 +386,23 @@ namespace Desktop case 0xF9: mnemonic = "LD SP, HL"; break; + case 0xFD: + { + byte fdOpcode = _memoryBus.Read((ushort)(currentPc + 1)); + + if (fdOpcode == 0x21) // LD IY, nn + { + ushort iyVal = (ushort)(_memoryBus.Read((ushort)(currentPc + 2)) | (_memoryBus.Read((ushort)(currentPc + 3)) << 8)); + mnemonic = $"LD IY, 0x{iyVal:X4}"; + instructionLength = 4; + } + else + { + mnemonic = $"FD PREFIX UNKNOWN (0x{fdOpcode:X2})"; + instructionLength = 2; // Fallback so we don't freeze the UI + } + break; + } default: mnemonic = $"UNKNOWN (0x{opcode:X2})"; break;