diff --git a/Core/Cpu/Z80.cs b/Core/Cpu/Z80.cs index 7e57470..247542e 100644 --- a/Core/Cpu/Z80.cs +++ b/Core/Cpu/Z80.cs @@ -449,6 +449,14 @@ namespace Core.Cpu case 0x16: // LD D, n DE.High = FetchByte(); return 7; + case 0x18: // JR d + sbyte jumpDistance = (sbyte)FetchByte(); + + // PC has already been incremented by FetchByte(), so it is + // pointing exactly where it needs to be for the relative addition. + PC = (ushort)(PC + jumpDistance); + + return 12; case 0x19: // ADD HL, DE Add16(DE.Word); return 11; @@ -646,6 +654,9 @@ namespace Core.Cpu case 0xDE: // SBC A, n Sbc(FetchByte()); return 7; + case 0xE9: // JP (HL) + PC = HL.Word; + return 4; // Takes 4 T-States case 0xEB: // EX DE, HL ushort tempEx = DE.Word; DE.Word = HL.Word; @@ -856,11 +867,38 @@ namespace Core.Cpu _memory.Write(targetAddress, memValRes4); return 23; + case 0xAE: // RES 5, (IY+d) + byte memValRes5 = _memory.Read(targetAddress); + + // 0xDF is Binary 1101 1111 + // ANDing perfectly preserves all other bits while forcing Bit 5 to 0 + memValRes5 &= 0xDF; + + _memory.Write(targetAddress, memValRes5); + return 23; + case 0xC6: // SET 0, (IY+d) + byte memValSet0 = _memory.Read(targetAddress); + + // 0x01 is Binary 0000 0001 + // ORing forces Bit 0 to 1 and perfectly preserves all other bits + memValSet0 |= 0x01; + + _memory.Write(targetAddress, memValSet0); + return 23; // Takes 23 T-States case 0xCE: // SET 1, (IY+d) memVal = _memory.Read(targetAddress); memVal |= 0x02; // 0x02 is Binary 0000 0010 (Bit 1) _memory.Write(targetAddress, memVal); - return 23; // Takes 23 T-States + return 23; + case 0xE6: // SET 4, (IY+d) + byte memValSet4 = _memory.Read(targetAddress); + + // 0x10 is Binary 0001 0000 + // ORing perfectly preserves all other bits while forcing Bit 4 to 1 + memValSet4 |= 0x10; + + _memory.Write(targetAddress, memValSet4); + return 23; default: throw new NotImplementedException($"FD CB opcode {bitOpcode:X2} not implemented!"); diff --git a/Desktop/DebuggerForm.cs b/Desktop/DebuggerForm.cs index 11bc6a3..1154405 100644 --- a/Desktop/DebuggerForm.cs +++ b/Desktop/DebuggerForm.cs @@ -282,6 +282,14 @@ namespace Desktop mnemonic = $"LD D, 0x{dImm:X2}"; instructionLength = 2; break; + case 0x18: + sbyte dUnconditional = (sbyte)_memoryBus.Read((ushort)(currentPc + 1)); + // Calculate the target address based on the PC *after* this 2-byte instruction + ushort targetAddressUnconditional = (ushort)(currentPc + 2 + dUnconditional); + + mnemonic = $"JR 0x{targetAddressUnconditional:X4}"; + instructionLength = 2; + break; case 0x19: mnemonic = "ADD HL, DE"; break; @@ -453,6 +461,9 @@ namespace Desktop mnemonic = $"SBC A, 0x{sbcValue:X2}"; instructionLength = 2; break; + case 0xE9: + mnemonic = "JP (HL)"; + break; case 0xEB: mnemonic = "EX DE, HL"; break; @@ -578,15 +589,26 @@ namespace Desktop sbyte d = (sbyte)_memoryBus.Read((ushort)(currentPc + 2)); byte cbOpcode = _memoryBus.Read((ushort)(currentPc + 3)); string sign = d >= 0 ? "+" : ""; - - if (cbOpcode == 0xCE) - { - mnemonic = $"SET 1, (IY{sign}{d})"; - } - else if (cbOpcode == 0x8E) + if (cbOpcode == 0x8E) { mnemonic = $"RES 1, (IY{sign}{d})"; } + else if (cbOpcode == 0xAE) + { + mnemonic = $"RES 5, (IY{sign}{d})"; + } + else if (cbOpcode == 0xC6) + { + mnemonic = $"SET 0, (IY{sign}{d})"; + } + else if (cbOpcode == 0xCE) + { + mnemonic = $"SET 1, (IY{sign}{d})"; + } + else if (cbOpcode == 0xE6) + { + mnemonic = $"SET 4, (IY{sign}{d})"; + } else { mnemonic = $"FD CB {d:X2} {cbOpcode:X2}"; // Fallback