Amazing #02
14 июля 1998

Ассемблер - Контроль времени (работа с прерываниями).

<b>Ассемблер</b> - Контроль времени (работа с прерываниями).
(C) 1998 by Mr.Beeper

Music by Ironman

 

 Контроль времени (работа с прерываниями)

Прерывания с полным правом можно отнести к
наиболее   мощным  и  интересным  ресурсам
компьютера. К сожалению,  работа с ними из
Бейсика   абсолютно  невозможна  и  именно
поэтому  данный  вопрос  для многих из вас
может  оказаться  совершенно новым и неиз-
вестным.   К  настоящему  моменту  вы уже,
должно  быть,  достаточно  освоились с ас-
семблером  и  надеемся,  неплохо представ-
ляете,  как  работает  микропроцессор, что
дает возможность понять, что будет нижепе-
речесляться.  Для  начала  выясним, что же
собой  представляют прерывания. Попробуем,
не  вдаваясь  в  конструкторские тонкости,
объяснить принцип этого явления просто "на
пальцах".  Когда вы находитесь в редакторе
Бейсика или TASM и размышляете над очеред-
ной  строкой программы, компьютер не торо-
пит  вас  и  терпеливо ожидает нажатия той
или  иной кла виши. Может даже показаться,
что процессор в это время и вовсе не рабо-
тает.  Но,  как вы уже знаете, это не так.
Просто  выполняется  отдельная часть прог-
раммы,аналогичная  процедуре WAIT: в цыкле
опрашивается системная переменная LAST_K и
когда  вы нажимаете  какую-то клавишу, код
ее  появляется в ячейке 23560. Но, спраши-
вается,  откуда он там берется ? Программа
ведь  только  читает ее значение, никак не
модифицируя  ее содер жимое. А разрешается
эта  загадка  довольно просто. Дело в том,
что 50 раз в секунду процессор отвлекается
от  основной  программы и переключается на
выполнение специальной процедуры обработки
прерываний,  рассположенной  по адресу 56,
словно бы встретив команду RST 56 или CALL
56, только переход этот происходит не про-
граммным,  а аппаратным путем. У процедуры
56,  есть  две основных задачи: опрос кла-
виатуры и изменение текущего значения тай-
мера (системная пере менная FRAMES - 23672
/73  /74).  Результаты опроса клавиш также
заносятся  в область системных переменных,
в частности, код нажатой клавиши помещает-
ся  в  LAST_K.  После выхода из прерывания
процессор  как  ни в чем не бывало продол-
жает  выполнять  основную программу. В ре-
зультате  получается  довольно интерестный
эффект: создается впечатление,будто бы па-
раллельно  работают два процессора, каждый
из  которых выполняет не зависимую задачу.
  Все  это  прекрасно, но какую пользу для
себя мы можем из этого извлечь? Ведь в ПЗУ
ничего не изменишь. Действительно, от пре-
рываний программистам было бы не много про
ку, если бы невозможно было переопределять
адрес  процедуры  для их обработки. Мы уже
говорили о существовании регистра I, назы-
ваемого  регистром  вектора  прерываний, а
сейчас  расскажем, какую роль он выполняет
в программах,использующих собственные пре-
рывания.
  Прежде всего вам нужно знать, что сущест
вуют  три различных режима прерываний. Они
обозначаются цифрами от 0 до 2.Стандартный
режим имеет номер 1,и о нем мы уже кое-что
сказали.  Нулевой  режим нам не интересен,
поскольку  на  практике  он ничем не отли-
чается от первого (именно, на практике,по-
тому   что   на  самом  деле  имеются  су-
ществующие  различия, но в ZX-Spectrum они
не  реализованы).  А  вот  о втором режиме
нужно  поговорить более основательно. Сна-
чала  скажем  несколько слов о том, как он
работает  и  что  при  этом  происходит  в
компьютере.  С приходом сигнала прерываний
процессор  определяет  адрес  указателя на
процедуру обработки прерываний. Он состав-
ляет  из  байта,  считанного с шины данных
(младший), который, собственно, и называет
ся <вектором прерывания> и содержимого ре-
гистра  I  (старший байт адреса). Затем на
адресную шину переписывается значение полу
ченного указателя, но предварительно преж-
нее состояние шины адреса заносится в стек
Таким  образом, совершается действие, ана-
логичное каманды процессора CALL. Посколь-
ку в SPECCY вектор прерываний, как правило
равен 255, то на практике, адрес указателя
может быть определн только регистрм I. Для
этого его значение нужно умножить на 256 и
прибавить  255. Для установки нового обра-
ботчика  прерыва  ний, нужно выполнить ряд
действий.  Перечес лим их в том порядке, в
котором они должны производится:
  1. Запретить прерывания, так как есть ве
роятность того, что сигнал прерываний при-
дет во время установки, а это может привес
ти к нежелательным последствиям. Достигает
ся  это выполнением команды процессора DI.

  2. Записать в память по рассчитаному за-
ранее адресу указател на процедуру обработ
ки прерываний (то есть адрес этой процеду-
ры).

  3.  Задать в регистре вектора прерываний
I старший байт адреса указателя на обработ
чик.

  4. Установить командой IM 2 второй режим
прерываний.

  5.  Вновь  разрешить прерывания командой
EI.

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

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

  4. Разрешить прерывания.
 
  Несколько  подробней  нужно остановиться
на втором и третьем пунктах установки пре-
рываний.  Предположим, что процедура обра-
ботчик находится по адресу 60000 (#EA60) и
память, начиная с 65000, никак в программе
не используется. Значит указатель можно по
местить именно в эту область. Для регистра
I в этом случае можно выбрать одно из двух
зна*ений:  253 или 254. Тогда для размеще-
ния указателя можно использовать либо адре
са   65023/65024   (253*256+255/256)  либо
65279/65280  (254*256+255/256).  Например,
при  I  равном 254 запишем по адресу 65279
младший байт адреса обработчика - #60, а в
65280  поместим старший байт - #ЕА. Однако
нужно  учитывать,  что  некоторые  внешние
устройства могут изменять значение вектора
прерывания.  Кроме  того,  если ваш SPECCY
сработан    не    слишком   добросовестным
производителем, то вектор прерывания иног-
да может скакать совершенно произвольным и
непредсказуемым  образом.  Принимая это во
внимание,  даже  во многих фирменных играх
используется несколько иной подход. Вместо
записи двух байтов по определенному адресу
выстраивается  целая  таблица размером как
минимум  257  байт с таким расчетом, чтобы
при любом значении вектора прерываний счи-
тывался  один и тот же адрес. Понятно, что
для  этого  все  байты таблицы должны быть
одинаковыми. Это несколько осложняет уста-
новку  прерывания и требует больше памяти,
но  зато  значительно увеличивается надеж-
ность  программы.
  Наиболее удачным для такой таблицы пред-
ставляется  байт  255 (#FF). В этом случае
обработчик  прерываний должен находится по
адресу 65535 (#FFFF). На первый взгляд мо-
жет показаться странный выбор такого адре-
са,  ведь  остается  всего один байт! Но и
этого единственного байта оказывается дос-
таточным, если в него переписать код коман
ды  JR. Следующий байт, находящийся по ад-
ресу 0, укажет смещение относительного пе-
рехода.  По  нулевому адресу в ПЗУ записан
код команды DI (#F3), поэтому полностью ко
манда  будет выглядеть как JR 65524. Далее
в  ячейке 65524 можно разместить уже более
"длинную"  команду  JP addres и заданный в
ней адрес может быть совершенно произволь-
ным.
  Приведем пример такой подпрограммы уста-
новки прерываний:

INT     LD A,24       ;код команды JR
        LD (#FFFF),A
        LD A,195      ;код команды JP
        LD (65524),A
        LD (65525),HL ;в HL-адрес обработ-
                      ;чика прерываний
        LD HL,#FE00   ;построение таблицы
        LD DE,#FE01   ;для векторов прер.
        LD BC,256     ;размер табл.минус 1
        LD (HL),#FF   ;адрес перехода#FFFF
        LD A,H        ;запоминаем старший
                      ;байт адреса таблицы
        LDIR          ;заполняем таблицу
        DI            ;запрещаем прер. на
                      ;время установки вто
                      ;рого режима прерыв.
        LD I,A        ;задаем в регистре I
                      ;старший байт адреса
                      ;таблицы для векто-
                      ;ров прерываний
        IM 2          ;вкл. второй режим
        EI            ;разрешаем. прерыв.
        RET

  Перед обращением к ней в регистровой па-
ре HL необходимо указать адрес соответству
ющей процедуры обработки прерываний. Учти-
те, что в области памяти, начиная с адреса
65024,  менять  что  - либо не желательно.
Если все же возникает такая необходимость,
убедитесь прежде, что своими действиями вы
не затроните выстановленные процедурой бай
ты.  Подпрограмма  восстановления  первого
режима  выглядит заметно проще и в коммен-
тариях уже не нуждается:

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

  При составлении процедуры обработки пре-
рываний  нужно придерживаться определенных
правил. Во-первых, написанная вами подпрог
рамма должна выполняться за достаточно ко-
роткий   промежуток  времени.  Желательно,
чтобы ее быстродействие было сопоставимо с
"пульсом" прерываний, то есть чтобы ее про
должительность  не превышала 1/50 секунды.
Это правило не является обязятельным, но в
противном случае трудно будет получить эф-
фект   "паралельности"   процессоров.  Во-
вторых, это уже совершенно необходимо, все
ре  гистры,  которые  могут  изменить свое
значение  в  вашей  процедуре, должны быть
сохранены  на  входе и восстановлены перед
выходом.  Это же относится и к любым пере-
менным  используемым  не только в прерыва-
нии,но  и  в основной программе. В связи с
этим   не   реко  мендуется  обращаться  к
подпрограммам  ПЗУ  ,  по крайней мере, до
тех пор, пока вы не знаете совершенно точ-
но,какие  в  них  используются регистры и
какие  системные переменные при этом могут
быть  изменены.Вызов  под  программ ПЗУ не
желателен и еще и потому, что некоторые из
них  разрешаят  прерывания, что совершенно
не  допустимо, во избежание рекурсии (т.е.
самовызова)  обработчика,  ко торый должен
работать  при запрещенных прерываниях. Од-
нако использовать команду DI в самом нача-
ле  процедуры  не обязательно, так как это
действие  выполняется  автоматически и вам
нужно только позаботится о разрешении пре-
рываний перед выходом.
  Если вы не хотите лишаться возможностей,
предоставляемых стандартной процедурой об-
работки  прерываний, можете завершить свою
подпрограмму командой JP 56. А при исполь-
зовании прерываний в бейсик-программах без
этого просто не обойтись, иначе клавиатура
окажется заблокирована.В общем случае обра
ботчик прерываний может иметь такой вид:

INT     PUSH AF
        PUSH BC
        PUSH DE
        PUSH HL
        .......
        POP HL
        POP DE
        POP BC
        POP AF
        JP 56
 
  В заключении хочу предложить интерестную
прогамму,  основаную  на  выше преведенном
тексте.  Так  что,  запускайте  TASM 4.0 и
"дерзайте" !
 
;LOADING WITH MUSIC ON 1 INTERRUPT OF CPU;

        ORG #61A8
        DI
        CALL #C000    ; music addres !!!
        LD HL,#FD00
        LD DE,#FD01
        LD BC,#0100
        LD (HL),#FE
        LDIR
        LD A,#C3
        LD (#FEFE),A
        LD HL,INT
        LD (#FEFF),HL
        LD A,#FD
        LD I,A
        IM 2
        EI
CYCL    LD B,53
        LD D,TRK
        LD E,SEC + 1 ;<<<<<<<<  Warning  !
        LD HL,26000
        CALL LOAD
        JR C,CYCL

EXIT    DI
        LD A,#3F
        LD I,A
        IM 1
        EI
        CALL #C000
        RET

INT     DI
        PUSH HL
        PUSH DE
        PUSH BC
        PUSH AF
        PUSH IX
        PUSH IY
        EX AF,AF'
        EXX
        PUSH HL
        PUSH DE
        PUSH BC
        PUSH AF
        CALL #C006   ; music addres !!!
        POP AF
        POP BC
        POP DE
        POP HL
        EXX
        EX AF,AF'
        POP IY
        POP IX
        POP AF
        POP BC
        POP DE
        POP HL
        EI
        JP #3D2F

LOAD    LD      (LL62F6),SP
        LD      A,(#5CF6)
        LD      (LL6284),A
        LD      A,#FB
        LD      (LL62BD),A
LL6275  LD      A,D
        AND     A
        RRA
        LD      C,#7F
        CALL    LL62DC
        LD      A,#3C
        JR      NC,LL6283
        LD      A,#2C
LL6283  OR      #00
LL6284  EQU     $-1
        LD      C,#FF
        CALL    LL62DC
        LD      A,#18
        PUSH    BC
        PUSH    DE
LL628E  LD      BC,#011F
        CALL    LL62DC
        LD      D,A
        LD      IX,#20B1
        CALL    LL62E0
        POP     DE
        POP     BC
LL629E  PUSH    BC
        PUSH    DE
        LD      A,E
        LD      C,#5F
        CALL    LL62DC
LL62A6  PUSH    HL
        LD      C,#1F
        LD      A,#80
        CALL    LL62DC
        LD      C,#7F
        LD      IX,#3FD5
        CALL    LL62E0
        JP      P,LL62F5
        CALL    LL62E5
LL62BD  NOP
        POP     HL
        LD      A,(#5CD6)
        OR      A
        JR      NZ,LL62A6
        INC     H
        POP     DE
        POP     BC
        BIT     4,E
        JR      NZ,LL62D1
        INC     E
        DJNZ    LL629E
        JR      LL62D6
LL62D1  LD      E,#01
        INC     D
        DJNZ    LL6275
LL62D6  LD      (#6264),DE
        AND     A
        RET
LL62DC  LD      IX,#2A53
LL62E0  PUSH    IX
        JP      #3D2F
LL62E5  XOR     A
        LD      (#5CD6),A
        LD      HL,LL628E
        PUSH    HL
        INC     A
        PUSH    AF
        LD      IX,#2099
        JR      LL62E0
LL62F5  LD      SP,#0000
LL62F6  EQU     $-2
        SCF
        RET



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

От автора - история создания 2го номера журнала.

Авторы - об авторах журнала.

Обозрение - обзор программ из приложения: STV v1.3, Sample Editor v2.1, TDU v1.0, Crasher, RBI, YES, RDG, MOdule Converter, RC v1.4, Dark Square, 12 Тайных Книг.

Софтятина - обзор новой прессы и игр: Odyssey #2, Oberon #4, Spectrofon 22-23, ZX-Format 7, Amiga #1, Faultless 8, ZX-РЕВЮ 5-6, Amazing 1, X-Reversy, The Last Curieur, Pro Trackerr 3.0.

User'am - Risc процессор - путь в будущее.

User'am - 64 Килобайта о FIDONet.

User'am - нло-2 "Дьяволы Бездны", На пути к совершенству.

User'am - курс полодого юзера.

Ассемблер - поговорим о такой необходимой процедуре как вывод спрайта.

Ассемблер - Контроль времени (работа с прерываниями).

Ассемблер - Совместное использование ZX ASM 3.0 и STS 5.1.

Ассемблер - ВГ-93: процедуры для прямой работы с контроллером дисковода.

Презент - описание Turbo Disk Utility v1.0.

Презент - описание Sample Editor v2.1 (beta).

Презент - описание Real Commander v1.4.

Презент - описание игры Dark Squares v1.98 (demo version).

На досуге - я видел Amiga и IBM в работе и не могу не высказать своих размышлений по этому поводу!

На досуге - ответы на самые часто задаваемые вопросы по компьютеру Amiga.

Разное - history: История Клайва Синклера.

Разное - модем: Как правильно использовать модем, реализующий протоколы коррекции/сжатия MNP4/MNP5, v.42/v.42bis.

Разное - lmg: история образования Last Masters Group.

Отдохни - штирлиц.

Отдохни - очепятки: очепятоки, допущенные в газетах и журналах.

Отдохни - ОРТ: РЕКЛАМА ДВИГАТЕЛЬ ТОРГОВЛИ!

Железо - подробное описание модемов.

На досуге - 10:2 Hacker eRRoR новый вирус от Митника.


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

Похожие статьи:
Ликбез - полное описани и полный дизассемблер ПЗУ (часть 10).
Beatles - "Creedence Clearwater Revival" в нашей местности был главным конкуpентом "Beatles"...
Code on - инструкция по использованию комманд процессора Z80.

В этот день...   26 июля