|
KrNews
#11
31 декабря 1999 |
|
Z#80 BUG - Ошибка Z80 пофиксена (определение состояния прерываний).

_
Ошибка Z80 пофиксена
_
перевод (C) 1999 Viper
оригинал (C) 1995 Zilog Inc.,
Z80 Microprocessor Family
Product Specifications Databook
В журнале Deja Vu #8, а также где-то
еще (по-моему в Voyager #3) была опубли-
кована статья Ивана Рощина об ошибке
процессора Z80 при определении состояния
прерываний.
Затем в Born Dead'е была заметка о
том, что на Западе уже лет пять знают об
этой ошибке и обходят ее программным
способом.
VTS, купив в Санкт-Петербурге фирмен-
ную книгу по Z80, обнаружил, что фирма-
производитель не только знает об этой
неприятной особенности, но и приняла ме-
ры к ее устранению. Современные процес-
соры (CMOS) выпускаются уже в исправлен-
ном виде. Таким образом, определение
реального процессора или эмулятора даст
неверный результат на этих Z80. Такие
процессоры, например, использует Nemo в
своих компьютерах KAY.
Вашему вниманию предлагается перевод
из этой книги...
--cut-----------------------------------
Вопрос: Я не могу определить состояние
прерываний по LD A,I и LD A,R при чтении
состояния IFF2. Почему? Как обойти дан-
ную проблему?
Ответ: В CMOS варианте процессора Z80
мы устранили эту проблему. В NMOS вариа-
нте Z80 в определенных случаях IFF2 неп-
равильно отражает текущий статус преры-
ваний. Две операции LD A,R и LD A,I ко-
пируют состояние триггера разрешения
прерываний в бит P/V и изменяют содержи-
мое аккумулятора. Возможно определить
статус прерываний во время исполнения
команды. Если прерывание производится
процессором во время выполнения команды
(подразумевается, что прерывания разре-
шены), то флаг P/V будет очищен, что
приведет к неправильному выводу о запре-
щенных прерываниях во время выполнения
команды.
Этот парадокс может быть решен внешней
трассировкой процессора. Проблема заклю-
чается в том, что триггер IFF2 очищается
до того, как будет перенесен во флаг
P/V. Состояние триггера не копируется во
флаг четности до прекращения прерывания,
происходящего при выполнении команды.
Во время приема прерывания автоматиче-
ски очищается триггер разрешения преры-
ваний, равно как и флаг четности, несмо-
тря на то, были ли прерывания разрешены
или запрещены в начале выполнения коман-
ды.
Изящное решение данной аномалии осно-
вано на том факте, что старое значение
PC сохраняется на стеке во время приема
прерывания. Следующая точка входа на
стеке (слово ниже адреса содержащегося в
указателе стека) может быть очищена пе-
ред выполнением LD A,I или LD A,R. Если
это нулевое значение изменилось во время
выполнения следующей команды, то произо-
шло прерывание. Это означет, что преры-
вания были разрешены, даже если состоя-
ние флага четности указывает на обрат-
ное. Естественно, если флаг четности ус-
тановлен после выполнения LD A,I или LD
A,R - нет необходимости в проверке вер-
шины стека. Прерывания действительно ра-
зрешены, если флаг четности находится в
этом состоянии.
Здесь приведено две подпрограммы. Обе
возвращают сброшенный флаг Carry, если
прерывания разрешены и, соответственно,
наоборот: установленный при запрещенных
прерываниях. Обе портят аккумулятор (он
не содержит I или R на выходе). Состоя-
ние всех флагов кроме переноса на выходе
неопределено.
Первая процедура может быть расположе-
на где угодно в памяти, исключая нулевой
блок (#0000 -#00FF). Это небольшое ог-
раничение вытекает из того факта, что
подпрограмма проверяет только значимый
байт следующего входа стека. Этот байт
будет не равен 0, если подпрограмма рас-
положена не в нулевом блоке памяти. Вто-
рая процедура проверяет оба байта из
стека и, таким образом, обходит это ог-
раничение.
Viper> В действительности для большинст-
ва применений в системе ZX Spectrum это
ограничение не играет роли.
Внимание, эти подпрограммы предполага-
ют, что процедура обслуживания для любо-
го прерывания включает прерывания перед
ее завершением. Они могут вернуть невер-
ный результат, если подпрограмма обрабо-
тки прерываний (ISR), которая не вклю-
чает прерывания, начинает работать после
выполнения LD A,I или LD A,R.
Listing 1. Эта процедура не должна на-
ходиться в 0-ом блоке памяти (#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. Процедура может распола-
гаться где угодно в памяти.
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-----------------------------------
Другие статьи номера:
Похожие статьи:
В этот день... 1 ноября
Dnieprobite #03,
ACNews #13,
ZX Time #10,
Echo #07,
Funeral #1.5,
Info Guide #02,
ZX Guide #02,
Plutonium #14,
Crossroads #07,
ZX Club #09,
Black Crow #02,
Spectrum Expert #01,
C-Net Week #03,
Maximum #46,
Review #01,
Anigdot #46,
Nicron #05,
Spectrum Land #02,
Crysral Dream #01,
Platinum #02,
Oberon #02,
Echo #01,
Emulate #03,
ZX Format #01,
Speccy #02,
ZX Panorama #01