From 98169fd6b88e6efeb73478aecf7a001470e9ecc1 Mon Sep 17 00:00:00 2001 From: Adrian Conlon Date: Mon, 18 May 2026 20:06:57 +0100 Subject: [PATCH] Fix Z80 halt implementation --- Z80/Z80.UnitTests/HaltTests.cs | 14 ++++++++++++++ Z80/Z80.cs | 4 ++-- 2 files changed, 16 insertions(+), 2 deletions(-) diff --git a/Z80/Z80.UnitTests/HaltTests.cs b/Z80/Z80.UnitTests/HaltTests.cs index d8ad88b..c1aa15e 100644 --- a/Z80/Z80.UnitTests/HaltTests.cs +++ b/Z80/Z80.UnitTests/HaltTests.cs @@ -44,6 +44,20 @@ namespace Z80.UnitTests Assert.AreEqual(pcAfterHalt, this.cpu.PC.Joined, "PC must not advance while CPU is halted"); } + [TestMethod] + public void Halt_State_Forces_Nop_Regardless_Of_Memory_Contents() + { + // The Z80 manual states: "the data received from the memory is ignored + // and an NOP instruction is forced internally to the CPU." + // INC A (0x3C) at the looping address must not execute — A must be unchanged. + this.board.Poke(0x0000, 0x76); // HALT + this.board.Poke(0x0001, 0x3C); // INC A — must be suppressed while halted + this.cpu.A = 0x42; + this.cpu.Step(); // execute HALT — enters halt state, PC moves to 0x0001 + this.cpu.Step(); // looping — memory byte (INC A) must be ignored, NOP forced + Assert.AreEqual(0x42, this.cpu.A, "Memory contents must be ignored during HALT; NOP must be forced"); + } + [TestMethod] public void Halt_Nmi_Raises_Halt_Pin() { diff --git a/Z80/Z80.cs b/Z80/Z80.cs index fe49e78..7b56350 100644 --- a/Z80/Z80.cs +++ b/Z80/Z80.cs @@ -1676,9 +1676,9 @@ namespace Z80 protected override byte FetchInstruction() { this.LowerM1(); - base.FetchInstruction(); + var returned = base.FetchInstruction(); this.RaiseM1(); - return this.Bus.Data; + return returned; } private byte Subtract(byte operand, byte value, int carry = 0)