You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
LD A,I and LD A,R bug
The NMOS Z80s suffer a problem whereby LD A,I and LD A,R record the state of IFF2 after it has been reset if an interrupt is delivered during that instruction. This behaviour, along with workarounds for this for use in interrupt handlers are documented in the Z80 Family Questions and Answers section of the Zilog Product Specifications Databook, and is useful for detecting the model of Z80 in use, so as to determine whether the CPU (assuming it is a genuine NMOS or CMOS Z80) provides an 'OUT (C),0' instruction (NMOS), or 'OUT (C),255' instead (CMOS). http://z80.info/zip/ZilogProductSpecsDatabook129-143.pdf
(OCRed version: https://archive.org/stream/Zilog-Z80familyDataBook1989OCR/Zilog-Z80familyDataBook1989OCR_djvu.txt)
From the Q&A clause mentioned:
Q: I don't seem to get the correct state of the interrupts when using the LD A, I and LD A, R instructions to read the state of IFF2. Why is this? How can I get around this?
A: On CMOS Z80 CPU, we've fixed this problem. On NMOS Z80 CPU, in certain narrowly defined circumstances, theZ80CPU interrupt enable latch, IFF2, does not necessarily reflect the true interrupt status. The two instructions LD A, R and LD A, I copy the state of interrupt enable latch (IFF2) into the parity flag and modifies the accumulator contents (See table 7.0.1 in the Z80 CPU technical manual for details). Thus, it is possible to determine whether interrupts are enabled or disabled at the time that the instruction is executed. This facility is necessary to save the complete state of the machine. However, if an interrupt is accepted by the CPU during the execution of the instruction -- implying that the interrupts must be enabled -- the P/V flag is cleared. This incorrectly asserts that interrupts were disabled at the time the instruction was executed.
I wasn't aware of the difference in LD A,I / LD A,R behaviour in that case. I'll have to see if I can write a program to detect it, though the always-on RAM contention in the SAM Coupé makes it difficult to do single-cycle adjustments for this particular test.
Perhaps it could be implemented using a new handler that returns whether an interrupt is due in the next N cycles? Those instructions could then check ahead to see if they should change the result in the NMOS case. We need to know exactly when IFF2 is sampled within the instruction though.
I understand we currently implement the CMOS behaviour. For NMOS, yes, we may need to change the way we initiate interrupts by letting the emulator know when ~INT is going to become active.
We need to know exactly when IFF2 is sampled within the instruction though.
If I remember it correctly that ~INT is being sampled during the last tick of instruction, then this suggests that we should get its value as it is at that last tick?
https://sinclair.wiki.zxnet.co.uk/wiki/Z80#Differences_between_NMOS_and_CMOS_Z80s says:
From the Q&A clause mentioned:
Related to #27.
The text was updated successfully, but these errors were encountered: