_
Fixed an error Z80
_
Translation (C) 1999 Viper
original (C) 1995 Zilog Inc.,
Z80 Microprocessor Family
Product Specifications Databook
The Journal Deja Vu # 8 as well as somewhere
yet (in my opinion in the Voyager # 3) published an article by
Ivan Roshchina error Z80 processor in determining the state
interrupts.
Then, in Born Dead'e was talking about a
that the West is already five years old are aware of
this error and bypass its software
way.
VTS, bought in St. Petersburg, branded a book on Z80, found
that firmaproizvoditel not only knows about this unpleasant
features, but also took steps to address it. Modern processors
(CMOS) has issued a revised form. Thus, the definition real
processor or emulator will incorrect result in this Z80. Such
processors, for example, uses a Nemo
their computers KAY.
We offer you translation
from this book ...
- Cut ----------------------------------
Q: I can not determine the status of
interrupts LD A, I and LD A, R reading
state IFF2. Why? How to circumvent this problem?
A: The CMOS version of the Z80 CPU
we have eliminated this problem. In the NMOS version of the
Z80, in certain cases IFF2 correctly reflects the current
status of the interrupts. Two operations LD A, R and LD A, I
copy the state of the trigger resolution Interrupt bit in the P
/ V and change the contents of the battery. Possible to
determine status interrupt during execution
team. If an interrupt is
processor during the execution team
(Assuming interrupts are enabled), the flag P / V is cleared
that the lead to the wrong conclusion about illegal interrupts
during execution team.
This paradox can be resolved outside
trace processor. The problem is that the trigger IFF2 cleared
before they will be moved into a flag
P / V. Trigger status is not copied into
parity flag until the end of the interrupt
occurs when you run.
During the reception interrupt automatically clears the
trigger interrupt enable as well as the parity flag, although
whether interrupts are allowed or banned at the beginning of
the command.
Elegant solution to this anomaly is based on the fact that
the old value PC is stored on the stack during the reception
interrupts. The next entry point on
stack (the word following addresses contained in
stack pointer) can be cleaned before performing the LD A, I or
LD A, R. If a zero value has changed during the
the following command, then an interrupt has occurred. This
oznachet that interrupts were enabled, even if the flag
indicates the opposite parity. Naturally, if the parity flag is
set after the LD A, I or LD A, R - no need to check the stack.
Interrupt really allowed if the parity flag is this state.
Here are two routines. Both
return a flag thrown Carry, if
interrupts are enabled and, accordingly,
the opposite: set when prohibited
interrupts. Both ruin the battery (it
does not contain I or R to output). The status of all flags
except the transfer output undefined.
The first procedure can be located anywhere in memory,
eliminating the zero block (# 0000 - # 00FF). This is a small
limitation stems from the fact that routine checks only
significant byte of the next stack entry. This byte
is not equal to 0 if the routine is not in the zero block of
memory. The second procedure tests both bytes of stack, and
thus circumvents this restriction.
Viper> In fact, for most applications in the ZX Spectrum is
constraint plays no role.
Attention, these routines assume that the procedure for any
interruption of service includes interrupt before its
completion. They may return incorrect results if an interrupt
subroutine (ISR), which does not include interrupts, starts to
work after implementation of LD A, I or LD A, R.
Listing 1. This procedure should not be in the 0th block of
memory (# 0 - # 00FF)
GETIFF:
XOR A; C flag, acc = 0
PUSH AF; Stack bottom = # 00xx
POP AF; Restore SP
LD A, I; P flag = IFF2
RET PE; Exit if enabled
DEC SP; May be disabled
DEC SP; Has stack bottom been
POP AF; overwritten?
OR A; If not # 00xx, INT's
RET NZ; were actually enabled.
SCF; Otherwise, they really
RET; are disabled.
Listing 2. The procedure can be located anywhere in memory.
GETIFF:
PUSH HL; Save HL contents
XOR A; C flag, acc = 0
LD H, A; HL = # 0
LD L, A;
PUSH HL; Stack bottom = # 0000
POP HL; Restore SP
LD A, I; P flag = IFF2
JP PE, G1; Exit if isn't enabled.
DEC SP; May be disabled.
DEC SP; Let's see if stack
POP HL; bottom is still # 0000
LD A, H; Are any bits set in H
OR L; or in L?
POP HL; Restore old contents
RET NZ; HL <> 0 isn't enabled
SCF; Otherwise, they really
RET; are disabled.
G1 POP HL; Exit when P flag is
RET; set by LD A, I
- Cut ----------------------------------