┌────────────────────────────┐
│ ░▒▓▒▓▓█ INTERRUPTS █▓▓▒▓▒░ │
└────────────────────────────┘
(C) Time Keeper
Совсем недавно я обнаружил од-
ной из старых технических книг
информацию, которая меня очень
заинтриговала. Что я там нашел
скажу немного позднее, а для на-
чала вспомним теорию.
Итак, процессор Z80 имеет два
типа прерываний: маскируемое
(int), и немаскируемое (nmi).
После прихода сигнала прерывания
процессор выполняет цикл
подтверждения получения прерыва-
ния, во время которого на шину
данных нужно подать вектор
прерывания. Он может иметь одну
из трех форм, в зависимости от
трех режимов обработки прерыва-
ния, задаваемых программно.
В режиме 0 вектор восприни-
мается как однобайтный объектный
код команды, которая должна быть
выполнена после цикла подтвер-
ждения прерывания. Логика под-
тверждения прерывания в режиме 1
считает, что следующей после
подтверждения прерывания коман-
дой будет команда рестарта на
адрес #0056. Если используется
режим 1, вектор прерывания не
нужен вообще. В некоторых печат-
ных издания указано, что в ZX
Spectrum режим 0 аналогичен ре-
жиму 1. Вообще говоря, это не
совсем так. В идеале шина данных
компьютера "подтянута к плюсу",
т. е. при чтении вектора преры-
вания шина данных содержит число
#ff - в машинных кодах это ко-
манда RST #0056. Но это только в
идеале, на практике же нередко
встречаются компьютеры у которых
шина "висит в воздухе", т. е.
при считывании вектора шина дан-
ных содержит совершенно случай-
ные числа, поэтому замена режима
1 на режим 0 совершенно недопус-
тима! В режиме 2 вектор прерыва-
ния интерпретируется как младший
байт таблицы адресов обработки
прерываний. Старший байт содер-
жится в регистре I. Вместе они
образуют адрес в таблице, по ко-
торому берутся два байта адреса
обработки прерывания. Рассмотрим
подробнее, как используется вто-
рой режим прерываваний в прог-
раммах. Допустим, нам необходимо
"повесить" на прерывания проиг-
рывание музыки:
ORG #6101
CALL MUSIC ;Инициализация музыки.
DI
LD HL,#6000 ;Строим в памяти таблицу обработки
LD DE,#6001 ;прерываний длинной в 256 байт,
LD BC,#0100 ;т.е. с учетом того, что не все
LD (HL),#BF ;компьютеры имеют подтянутую к "+"
LDIR ;шину данных.
LD A,#C3 ;По адресу указанному в таблице,
LD (#BFBF),A ;т.е. #BFBF помещаем команду пере-
LD HL,INT_EXE ;хода JP INT_EXE.
LD (#BFC0),HL
LD A,#60 ;Ставим регистр I на начало таблицы.
LD I,A
IM 2 ;Включаем второй режим, и
EI ;разрешаем прерывания.
...
INT_EXE PUSH IX,IY,HL,DE,BC,AF ;Собственно сама программа
EXX ;обработки прерываний.
EX AF,AF'
PUSH HL,DE,BC,AF
CALL MUSIC+6
POP AF,BC,DE,HL
EXX
EX AF,AF'
POP AF,BC,HL,DE,IY,IX
EI
RET
В книге В. Ф. Королева "Мик-
ропроцессор Zilog Z*80" ( из се-
рии "В помощь разработчику мик-
ропроцессорной техники", 1992г.
изд. "Аргус-Мастер" ) сказано
следующее:
------------- Cut. -------------
Когда прерывание подтверждает-
ся в режиме 2, внешняя схема
должна поместить на шину данных
вектор подтверждения прерывания.
Процессор обьединит содержимое
регистра I с вектором подтвер-
ждения прерывания, образовав 16
битный адрес, который укажет на
соответствующий вектор адреса в
таблице обработки прерываний.
Поскольку 16-битовые адреса мо-
гут лежать в памяти лишь в сло-
вах с четными адресами, только
семь из восьми бит вектора
подтверждения прерывания исполь-
зуются процессором для формиро-
вания адреса в таблице, младший
бит адреса устанавливается в 0.
Таким образом:
Содержимое I Вектор с шины Двухбайтовый
(как старший + данных (как младший = адрес в таблице
байт). байт с нулевым млад- адресов обработки
шим битом). прерываний.
------------- Cut. -------------
После прочтения этой книги я
был немного в замешательстве.
Все везде пишут что для прерыва-
ния нужна табличка указывающая
на адрес в памяти, у которого
младший и старший байты должны
совпадать. Из прочитанного в
этой книги, вообще говоря, сле-
дует, что это не так! В приве-
денном примере в табличке содер-
жится число #BF, и, если верить
книге, адрес программы обслужи-
вания прерывания будет равен
#BFBE. У нас же программа распо-
ложена по адресу #BFBF. Посмот-
рев содержимое ячейки памяти по
этому адресу я обнаружил 0. Зна-
чит, попадая на адрес #BFBE,
процессор выполняет сначала ко-
манду NOP, а затем саму програм-
му обработки прерывания. А если
по адресу #BFBE будет расположе-
на, например, команда RST #00,
то это приведет к зависанию. Тем
не менее и в этом случае прог-
рамма осталась работоспособной.
Для полной уверенности я наб-
рал программу, тестирующую по
какой схеме формируется адрес
перехода при приходе прерывания:
с учетом нулевого бита или без.
Опробовав ее на всех процессо-
рах, которые оказались под ру-
кой, я получил один и тот же ре-
зультат: адрес формировался с
учетом нулевого бита. Несмотря
на полученные результаты, сомне-
ния остались. В книги говорилось
о фирменном Z-80 (zilog), а сре-
ди проверенных мной процессоров
такого не было, так что, для ме-
ня этот вопрос остается откры-
тым, и кто знает, какие еще сек-
реты может хранить в себе ма-
ленькая серенькая коробочка с
надписью Z-80...