Virtual Worlds
#01
31 декабря 1999 |
|
Железо - Прерывания: Кое-что непонятное о прерываниях второго рода.
┌────────────────────────────┐ │ ░▒▓▒▓▓█ 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...
Другие статьи номера:
Похожие статьи:
В этот день... 21 ноября