Вокруг ZX Spectrum 1991 г.

Обработка прерываний - драйвер джойстика


Прерывание - это сигнал, с помощью которого процессор оповещается о внешнем событии. При его поступлении процессор приостанавливает выполнение текущей программы и передает управление специальной подпрограмме обработки прерывания, которую часто называют обработчиком прерывания. Прерывания подразделяются на маскируемые и немаскируемые. Первое может быть разрешено или запрещено (в этом случае процессор игнорирует сигнал прерывания) командами El (Enable Interrupt) или DI (Disable Interrupt). Второе-же безусловно выполняется при поступлении сигнала прерывания. В компьютере ZX Spectrum установлен микропроцессор Z80, имеющий две входные линии, на которые поступают сигналы прерываний: линия NMI используется для регистрации немаскируемых прерываний, а линия INT - для маскируемых. В компьютере с минимальной конфигурацией линия NMI не задействована (обычно она выводится на разъем для подключения внешних устройств), а линия INT подключена к блоку, вырабатывающему синхронизирующие сигналы для телевизора и активизируется с частотой кадровой развертки (50 раз в секунду) . Стандартный обработчик этого прерывания, код которого находится в постоянном запоминающем устройстве (ПЗУ), выполняет две функции: во-первых увеличивает на 1 значение трехбайтовой переменной, находящейся по адресу 23672 (#5С78), которая может использоваться прикладными программами для измерения промежутков времени с дискретностью 1/50 сек., и во-вторых, опрашивает состояние клавиатуры, преобразует коды нажатых клавиш во внутреннее представление и помещает их в буфер клавиатуры из которого они бу¬дут считываться интерпретатором Бейсика или прикладными программами. Поскольку в ZX Spectrum стандартный обработчик прерывания записан в ПЗУ, его код не может быть модифицирован программой. Единственный способ изменения процедуры обработки прерывания состоит в "перехвате" прерывания другим обработчиком. Рассмотрим как это можно сделать. Микропроцессор Z80 имеет три режима прерываний - 0,1 и 2. Вы¬бор нужного режима осуществляется командами IM 0, IM 1 или IM 2 соответственно. В режиме 0 прерывание отрабатывается также, как и на микропроцессоре i8080 (К580ВМ80), т.е. после поступления прерывания с шины данных считывается и исполняется код команды, формируемый обычно специальной микросхемой контроллера прерыва¬ний. В ZX Spectrum микросхема контроллера прерываний отсутствует, а используется схемотехническая особенность, состоящая в том, что при отключении от шины данных всех устройств ее линии переводятся в состояние "1". Поэтому, когда при поступлении сигнала прерывания от шины данных отключаются все устройства, это эквивалентно приходу от контроллера прерываний байта #FF, что соответствует команде RST #38. В режиме 1 при поступлении сигнала прерывания микропроцессор автоматически выполняет команду RST #38 ничего не считывая с шины данных. Т.е. режимы 0 и 1 на ZX Spectrum полностью идентичны. Наконец, режим 2. Это самый "хитрый" режим прерываний в Z80. Специально для этого режима в микропроцессоре имеется регистр вектора прерываний I. Значение регистра I может быть прочитано или записано командами LD А,I или LD I,А. При поступлении сигнала пре¬рывания процессор считывает с шины данных байт и формирует адрес, старший байт которого равен I, а младший равен считанному байту (напомним, что на ZX Spectrum он всегда равен #FF). Двухбайтовая ве¬личина, расположенная по этому адресу, интерпретируется далее про¬цессором как адрес обработчика прерывания. Таким образом "перехват" прерывания осуществляется следующим образом. По адресу #xxFF записывается адрес точки входа в новый обработчик прерывания. Затем в регистр I заносится значение хх и выполняется команда IM 2. Проиллюстрируем эту технику на примере драйвера джойстика. ORG #FEFF VECTOR DEFW ENTRY TABL DEFW #2713 ; значение DE для кнопки ’’вправо" DEFW #2704 ; значение DE для кнопки "влево" DEFW #2703 ; значение DE для кнопки "вниз" DEFW #270В ; значение DE для кнопки "вверх" DEFW #2723 ; значение DE для кнопки "огонь" ENTRY PUSH AF PUSH HL ; увеличиваем на 1 системный LD HL,(#5C78) ; счетчик времени INC HL LD (#5C78),HL LD A,H OR L JR NZ,L0048 INC (IY+64) L0048 PUSH BC PUSH DE CALL GETKEY POP DE POP BC POP HL POP AF EI RET GETKEY IN A,(#DF) ; опрос джойстика LD HL,#FFFF NOBIT RRCA INC HL ; поиск справа-налево единичного JR NC,NOBIT ; бита LD A,L CP 5 ; если не нажата ни одна из кнопок JP Z,#02BF ; джойстика, то опрос клавиатуры ADD HL,HL LD DE,TABL ; в противном случае опрос: клавиатуры ADD HL,DE ; имитируется занесением в DE LD Е, (HL) ; значения из таблицы TABL INC HL LD D, (HL) JP #02СЗ INIT LD A,#FE LD I.A IM 2 RET Процедура ENTRY идентична соответствующей процедуре обработчика прерываний, "прошитого" в ПЗУ, - значение 3-байтового системного счетчика времени увеличивается на 1 и производится вызов процедуры GETKEY, осуществляющей опрос джойстика и клавиатуры. Различия появляются в процедуре GETKEY. В ПЗУ находится следующий код: 02BF: CALL #028Е 02С2: RET NZ 02СЗ: LD HL,#5C00 Процедура #028Е осуществляет опрос клавиатуры и возвращает в регистровой паре DE коды нажатых клавиш. Если ни одна клавиша не нажата, то DE=#FFFF, если нажата ровно одна клавиша, то D=#FF, а в Е находится код клавиши. Если нажато две клавиши, причем одна из них CapsShift или SymbolShift, то код CapsShift или SymbolShift находится в D, а в Е находится код второй клавиши. Во всех этих случаях флаг Z установлен, свидетельствуя о разрешенной комбинации нажатых клавиш, для остальных комбинаций он сбрасывается. На рисунке схематично показана клавиатура и коды клавиш, возвращаемые в регистровой паре DE. В процедуре GETKEY опрашивается состояние порта джойстика. Положения кнопок индицируют биты 0-4: бит 0 - кнопка "вправо" (1 - нажата, 0 – не нажата); 1 - "влево", 2 - "вниз", 3 - "вверх", 4 - "огонь". Биты 5-7 всегда равны "1". Если нажатие кнопки джойстика не зафик¬сировано, то управление передается по адресу #02BF (стандартная обработка прерывания). В противном случае в регистровую пару DE помещается нужное значение из таблицы TABL (имитация вызова процедуры опроса клавиатуры #028Е) и управление также передается стандартному обработчику, но уже минуя опрос клавиатуры. Активизация драйвepa джойстика производится вызовом процедуры INIT. Ниже приводится текст драйвера джойстика на Бейсике. 1 DATA 65279,3 2 DATA «OBFF1327042703270B272327F5E52A785C2322785C7CB52003FD3440C5D5CD2658» 3 DATA «FFD1C1E1F1FBC9DBDF21FFFF0F2330F C7DFE05CABF02291101FF195E2356C3C319» 4 DATA «023EFEED47ED5EBD» 100 CLEAR 65278: GO SUB 9993 110 RANDOMIZE USR 65344: STOP 9993 READ a,S: FOR f=1 TO S 9994 READ 1$: LET 1=LEN 1$: LET s=0: LET k=2 9995 LET a$=l$(k-l): LET b$=l$(k) 9996 LET c=(CODE а$-48-(7*(а$>"@")))*16+CODE b$-48-(7*(b$>"@”)) 9997 IF kc THEN PRINT "error in string";f+l: STOP (продолжение следует)


СОДЕРЖАНИЕ:


  Оставте Ваш отзыв:

  НИК/ИМЯ
  ПОЧТА (шифруется)
  КОД



Темы: Игры, Программное обеспечение, Пресса, Аппаратное обеспечение, Сеть, Демосцена, Люди, Программирование

Похожие статьи:
Реклама - реклама и обьявления.
Enjoy - солнечный город.
Сенсация - история о том как Tot/i8 так и не подключил SIMM к пнетагону AloneCoder'a.
Бух - ПАПАХИ НА БАШНЯХ.
Смешно? - юмористический рассказ "Mortal Kombat".

В этот день...   21 ноября