-
-
Notifications
You must be signed in to change notification settings - Fork 44
Z80 CPU Bug
In May 2022, I (Tony Brewer) discovered a Z80 bug that is present in the real CPU. It can occur if there is a special reset when the Z80 is halted. The bug was first found in 2014 without fully realising it is a bug. If you are unfamiliar with the special reset, I suggest reading the Special reset page.
A description and explanation of the Z80 special reset when halted bug follows.
Usually the program counter (PC) is incremented during cycle M1T1 of the opcode fetch. HALT
instruction, which stops PC from incrementing so that the same opcode after HALT
is fetched and ignored again and again until a reset or interrupt occurs.
When a special reset occurs when halted, PC does not increment during the first valid opcode fetch after HALT and is one less than it should be for the remainder of the instruction. HALT
the first opcode is read twice and it replaces either the correct second opcode or the first immediate byte if there is no prefix.
Instructions such as LD r,n
load register r with the LD r,n
opcode instead of n.
Instructions such as LD rr,nn
load the low reg with the LD rr,nn
opcode and the high reg with the low immediate byte.
All prefix instructions read the first prefix twice. For DD/FD
this simply adds 4T to the instruction which otherwise executes correctly.
All CB XX
instructions are executed as CB CB
= SET 1,E
instead of the intended instruction thus corrupting E.
All ED XX
instructions are executed as ED ED
, a harmless 8T NOP
.
Single-byte instructions after HALT
are not affected by this bug and execute normally if non-branching.
Jumps, calls and returns during which special reset occurs do not branch. If preceded by HALT
, CALL/RST
push an incorrect return address that is one too low and CALL/DJNZ/JR/JP nn
load the wrong branch address into WZ, which is preserved after the special reset takes place as are all registers except PC.
The bug can be studied most easily perhaps by using Visual Z80 Remix.
Copyright © Manuel Sainz de Baranda y Goñi, Tony Brewer and Peter Helcmanovsky
Published under the terms of the GNU Free Documentation License v1.3