Optron #35
25 апреля 2000

Ликбез - Прерывания в ZX Spectrum.

<b>Ликбез</b> - Прерывания в ZX Spectrum.
       Ассемблер - взгляд издалека

               Продолжение.
Начало в || 20, 21, 24, 25, 28-30, 32, 33

{}Инфарх, 2000

  Привет, энтузиасты! Что, небось заскуча-
ли на каникулах? Ничего, сейчас продолжим.
  На этот раз мы с вами поговорим о работе
с прерываниями. Для начала уясним, что это
такое. Итак...

                Прерывания

  Вы, может, и не подозреваете, что 50 раз
в  секунду  процессор отвлекается от обра-
ботки  вашей  программы и занимается неиз-
вестно чем... Например, опрашивает клавиа-
туру, изменяет значение системной перемен-
ной  FRAMES и т.д. Причём, делает это так,
что  вы  об этом и не догадываетесь. В эти
моменты  происходит  следующее:  процессор
обращается к подпрограме по адресу 56, как
будто   выполняет   команду   RST  56  или
CALL  56.  Отличие в том, что переход осу-
ществляется  не  программно,  а аппаратно.
Завершив  выполнение  вызванной процедуры,
процессор  продолжает  выполнять  основную
программу.
  На  первый  взгляд может показаться, что
от  такой  "фишки"  проку  никакого,  ведь
программно  в  ПЗУ  ничего  не изменишь. К
счастью, программист имеет возможность по-
менять адрес, по которому расположена про-
цедура обработки прерываний. Для этого ис-
пользуется упомянутый ранее регистр I.
  Прежде всего, надо запомнить, что имеет-
ся  три  режима  обработки прерываний. Они
обозначаются  соответственно  цифрами от 0
до  2.  Стандартный  режим - 1. Именно его
эксплуатирует  операционная систама. Нуле-
вой  режим  нам  не особенно интересен: на
практике  он ничем не отличается от перво-
го.  Заметьте,  именно на практике! Разли-
чия,  конечно, есть, да только в Спектруме
они  не  реализованы. Таким образом, самым
интересным для нас является режим 2.
  Для начала пару слов о том, как он рабо-
тает и что в этот момент в компьютере тво-
рится.  Когда  приходит сигнал прерывания,
процессор,  для  начала,  определяет адрес
указателя  на процедуру обработки прерыва-
ний.  Оный состоит из двух байт: младшего,
считанного с шины данных (его также имену-
ют  "вектор прерываний"), и старшего, счи-
танного  с регистра I. Полученное значение
помещается на шину адреса, а предыдущее её
содержимое  сохраняется на стеке. Всё это,
в   сущности,  является  вариантом  вызова
подпрограммы.
  "Но что означает этот термин  -  "вектор
прерываний"?"  - спросите вы.  Дело в том,
что термин этот связан с работой компьюте-
ров,  в  которых предусмотрена возможность
поступления нескольких запросов на  преры-
вание  ОДНОВРЕМЕННО.  Естественно,  в этой
ситуации необходимо определиться, какое из
прерываний  имеет приоритет. А это значит,
что  запрос на прерывание следует рассмат-
ривать как "вектор", который, как и всякий
порядочный вектор, характеризется, как ми-
нимум, двумя значениями (в данной ситуации
- источником и приоритетом). При поступле-
нии  запроса на прерывание оно обрабатыва-
ется  или  игнорируется  в  зависимости от
приоритета над выполняемым в данный момент
прерыванием.
  Ну,  а  для  Спектрума, хоть в нём и ис-
пользуется  только одно прерывание, термин
этот,  тем  не  менее, сохранён. Вот и вся
недолга.
  Как правило, значение вектора прерываний
у Speccy равно 255,  поэтому для определе-
ния адреса указателя достаточно содержимое
регистра I умножить  на  256  и  прибавить
255.  Итак,  попробуем вообразить те дейс-
твия,  которые необходимо  произвести  для
применения собственной процедуры обработки
прерывания:

  1) Запретить прерывания.  Это необходимо
во  избежание запуска новой процедуры пре-
рывания  во время работы текущей, что чре-
вато...
  2) Записать по адресу, рассчитанному за-
ранее,  указатель  на  процедуру обработки
прерываний, а именно её адрес.
  3) Задать в  регистре I старший байт ад-
реса указателя на процедуру обработки.
  4) Установить  второй   режим  обработки
прерываний.
  5) Вновь разрешить прерывания.

  Естественно,  процедура обработки преры-
ваний  на  данный  момент уже должна нахо-
диться в памяти.
  Вот  вкратце и всё. Теперь - пару слов о
средствах реализации. Точнее, о командах.
Итак:

  DI   запрещение прерываний
  EI   разрешение прерываний

  IM 0
  IM 1
  IM 2  Установка  одного  из трёх режимов
        прерываний

  Теперь у вас есть и команды. Однако  пе-
ред  установкой своей процедуры  обработки
подумайте о том, должна ли она отключаться
и возвращать управление стандартной проце-
дуре. Для отключения же необходимо:

  1) Запретить прерывания.
  2) Восстановить  значение  I,  записав в
него 63.
  3) Назначить  командой IM 1 первый режим
прерываний.
  4) Разрешить прерывания.

  Но и это ещё не всё. Необходимо помнить,
что некоторые внешние устройства могут из-
менять  значение вектора прерываний. Кроме
того,  если  ваш  Speccy собран на коленях
"кривыми ручками" по заляпанной пивом схе-
ме,  вектор прерывания может скакать самым
непредсказуемым  образом.  Естественно,  в
таком  случае вероятность вызова процедуры
обработки  равняется  1/256.  Во избежание
глюков и головной боли программисты прибе-
гают  к  следующему  приёму: вместо записи
двух байт по определённому адресу выстраи-
вается  таблица размером не менее 257 байт
с  таким  расчётом,  чтобы  в любом случае
считывался  один  адрес.  Естественно, для
этого  все  элементы  таблицы  должны быть
одинаковы.
  Наиболее  удачным значением для заполне-
ния  этой  таблицы является 255. Не пугай-
тесь,  что  адрес  процедуры  будет  равен
#FFFF.  Этого  одного байта как раз хватит
для  размещения  кода  24 (команда JR). За
ней  последует  адрес #0000, по которому в
ПЗУ  находится значение #F3. Таким образом
получается  JR  65524. По этому адресу уже
можно  разместить комаду JP с самым произ-
вольным адресом перехода.
  Рассмотрим  пример установки своей  про-
цедуры обработки прерываний:

       LD   A,24      ;код команды JR
       LD   (65535),A
       LD   A,195     ;код команды JP
       LD   (65524),A
       LD   HL,ISR    ;адрес обработчика
       LD   (65525),HL
       LD   HL,#FE00
       LD   DE,#FE01
       LD   BC,#0100
       LD   (HL),#FF
       LD   A,H
       LDIR
       DI
       LD   I,A
       IM   2
       EI

  Вот  мы и подключили процедуру обработки
прерываний.   Рассмотрим  теперь  обратный
процесс, а именно возврат к режиму IM 1.

       DI
       LD   A,63
       LD   I,A
       IM   1
       EI

  И  напоследок - пример. Допустим, вы хо-
тите воспроизводить музыку во время работы
вашей программы. Если вы используете мело-
дию,  откомпилированную  в  одном из музы-
кальных   редакторов  и  оснащённую  стан-
дартным  плеером, проблем у вас не возник-
нет.  Для  проигрывания  необходимо каждые
1/50  секудны  вызывать  плеер,  а значит,
частота  прерываний вам идеально подходит.
Перед тем, как начать воспроизведение, не-
обходимо проинициализировать плеер, сделав
CALL по сответствующему адресу. Адрес ини-
циализации,  равно как и проигрывания, за-
висит  от  конкретного редактора и условий
компиляции.  Однако часто бывает, что ини-
циализация  расположена в самом начале ме-
лодии,  а  проигрывание  ноты ещё на шесть
байт  дальше.  Если допустить, что мелодия
компилирована  под адрес #C000, то инициа-
лизация будет расположена по адресу #C000,
а воспроизведение ноты - по адресу #C006.
  Теперь  подкорректируем  наши примеры. В
процедуру  установки второго режима преры-
ваний  добавьте CALL #C000 для инициализа-
ции.  Это следует проделать и с процедурой
восстановления прежнего режима прерываний.
Для  чего? Чтобы после того, как вы отклю-
чили  музыку,  AY не продолжал тянуть пос-
леднюю  ноту.  Инициализация  позволит вам
быстро "заткнуть глотку" динамику.
  А теперь посмотрм на саму процедуру:

ISR    DI
       PUSH AF   ;сохраняем все регистры
       PUSH BC   ;для нормального возврата
       PUSH DE   ;в основную программу
       PUSH HL

       CALL #C006;вызываем плеер

       POP  HL   ;восстанавливаем
       POP  DE   ;сохраненные значения
       POP  BC
       POP  AF
       EI        ;разрешение прерываний
       RET       ;и возврат

  Если  вы всё сделали правильно и опреде-
лили  адреса инициализации и проигрывания,
музыка должна зазвучать.
  Упомянём ещё одну команду для облегчения
жизни - HALT. Когда процессор набредает на
неё,  он  приостанавливает  работу  и ждёт
сигнала  прерывания. После его поступления
управление передаётся процедуре  обработки
прерывания. А после её завершения основная
программа  продолжает свою работу с коман-
ды,  следующей  за HALT. Это позволяет ис-
пользовать  HALT  для  синхронизации вашей
программы  с  прерываниями.
  Ну, вроде всё пока с  теорией.  Осталось
только,  как  водится,  изложить кое-что о
флагах и вариантах команд. Взгляните:

      ╔═══════════╤═══════════════╗
      ║ Мнемоника │    Флаги      ║
      ║ операции  ├───────────────╢
      ║           │ C Z P/V S N H ║
      ╟───────────┼───────────────╢
      ║   DI      │ . .  .  . . . ║
      ║   EI      │ . .  .  . . . ║
      ║   IM 0    │ . .  .  . . . ║
      ║   IM 1    │ . .  .  . . . ║
      ║   IM 2    │ . .  .  . . . ║
      ║   LD A,I  │ . x  x  x 0 0 ║
      ║   LD I,A  │ . .  .  . . . ║
      ║   HALT    │ . .  .  . . . ║
      ╚═══════════╧═══════════════╝

  Вот и все  флаги.  Теперь  можете  смело
приступать  к  озвучиванию своих программ.
Не забывайте только,  что некоторые плееры
имеют привычку разрешать прерывания. Также
непосредственно после перехода на процеду-
ру  обработки прерываня по HALT прерывания
оказываются запрещёнными.

          Продолжение следует...

              ──══════════──





Другие статьи номера:

Ликбез - Прерывания в ZX Spectrum.

Литстраничка - Путь перед рассветом (памяти Роджера Желязны).

Мнение - Феномен электронной почты (взгляд и чувства программиста).

Обоз - Обзор прессы: Always 1, Micro 23, ZX-News 50, Полесье 15.

Обратная связь - Письма от читателей.

Стихи - Люди сделаны не из стали.

Страницы истории - О завтрашнем времени.

Четыре килобайта - Смена главного редактора газеты.


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

Похожие статьи:
Юмор - школьные истории.
Анекдоты - 20 анекдотов...
Реклама - у нас нет рекламы читателей.
Графика - картинка АNSI графики.
Презентация - Презентация новой игры "Угадай мелодию".

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