ГЛАВА 6
ИСПОЛЬЗОВАНИЕ ПРЕРЫВАНИЙ
ПРЕРЫВАНИЯ
Стартовая последовательность СПЕКТРУМа, очищающая па-
мять и устанавливающая значения системных переменных, также
инициализирует регистр прерываний, размещая в нем 63 (3Fh) и
устанавливая режим прерываний в 1 (IM1). Задание регистра "Iм
необязательно, т.к. режим 'ТМГ' его не использует, потому что лю-
бые прерывания выполняются через RST 56 (38Ю. В новой версии, в
которой "ULA" СПЕКТРУМа содержит вывод, биты 6 и 7 регистра "1"
задействованы.
При каждом цикле машинных команд Z80 обращается к ячейке
памяти, адресуемой регистром "Г, выводя его в старшие 8 битов
адресной шины, а линия запроса памяти активизируется. "ULA" ге-
нерирует прерывание каждый раз, когда нужно изменить содержи-
мое экрана. Это заставляет Z80 запустить программу обработки пре-
рываний, при условии, что прерывания подключены. Обычно это
сканирование клавиатуры и изменение счетчика системы, но если
подключено ПЗУ интерфейса, то все, что делается при включении
прерываний - немедленный возврат без сканирования клавиатуры
или каких-либо других действий. Когда программа прерываний вы-
полнена, ЦП возвращается в точку, в которой он был при прерыва-
нии. Если это команды считывания/записи в память между 16384
(4000h) и 32767 (7FFFh), которые "ULA" проверяет, просматривая
две старшие линии адресной шины и линию "MREQ", "ULA" останав-
ливает часы на ЦП до окончания изменения экрана. Если старший
бит регистра "Iм сброшен, а бит 6 активизирован, "ULA" может запу-
таться из-за регенерации динамической памяти во время ТЗ и Т4 в
Ml цикле. Активизируется линия "MREQ" и регистр "Iм помещается
в старшие восемь битов адресной шины. Далее "ULA" думает, что ЦП
производит считывание или запись в эту область ОЗУ, даже при
попытке это предотвратить и "ULA" пропускает свое собственное
обращение для изменения дисплея, что приводит к развалу картинки.
Поэтому в регистре "Iм не должно содержаться любое число от 64 до
127 (40h до 7Fh) включительно, т.е. с двумя старшими битами уста-
новленными таким образом.
Путем установки "IM2" можно использовать прерывания для ва-
ших собственных целей, до тех пор, пока вы выполняете RST 56 (38h)
в конце вашей программы обработки прерываний, которая подклю-
чит прерывания перед возвратом в основную программу, если нужно,
чтобы счетчик обнулялся, а клавиатура сканировалась и "RETI" в
конце концов.
D Если вы использовали RST 56
(38h) в прерывающей программе, необходимо выполнять коман-
ду "EI" до "RETT', если нужно подключить йрёршания, чтобы снова
вызвать программу обработки прерываний. Помнит^ ::что вам при-
дется сбрасывать режим "IMl" и подключать прерываниядр возвра-
щения в БЕЙСИК, если вы не пользуетесь RST 56 (38h) вё прерыва-
ющей программе.
Режим "IM2" сложен. По получении прерый&ния (50 раз в Секун-
ду), ЦП запоминает адрес следующей командына ма-
шинном стеке. Отключает любые последующие прерывания. Затем
просматривает ячейку, указанную шиной данных, + (256 * "Г' ре-
гистр) и передает управление к адресу, содержащемуся в этой ячейке
+ (256 умноженное на содержимое следующей Вообще-то
считается дурным тоном иметь бит 0 нашине данных активизирован-
ным для использования в качестве указателя в ,,1М2,,^т.к. указатель
всегда будет стартовать с адреса, пронумерованного четным числом,
но к сожалению в СПЕКТРУМе нет выбора^;;;;;:
Пример. Регистр "Г содержит 10 (OAh), и шина данных содержит
225 (FFh). При этом 10* 256=2560;й 2560 + 255=2815, поэтому точка,
к которой будет совершен переход, будёт;взята из содержимого адреса
2815 + (256 * на число по адресу 2816) . Ячёйк^;2815 содержит 34, а
2816 - 128. В этом можно убедится;с помощью команды "РЕЕК"
вашего СПЕКТРУМА, т.к. она;;есть:в ПЗУ. Таким образом адрес
перехода 34 + (256;* 128), а это 328021: Дру-гой пример : регистр "Г
содержит 6:6 * 25§^;Щб;й:1536 + 255=1®: 1791 содержит 221,1792
содержит 113.221 + (113*-2iS6p| ^.29149, переход будет к 29149. Иначе,
если у вас 48К СПЕКТРУМ й:рёшстр "I" содержит 200:.200 * 256 =
51200 и 51200 + 255 = 51455, перёход;будет по адресу, который вы
положите сюда и в следующую ячейку;^ в обычном Z80 сначала идут
младшие байты.
Это может быть! представлено!как воображаемая невидимая ко-
манда црерывания в:ВЫШЛНяемойпрограмме. В момент прерывания
эта команда выполняется так, как "DI", сопровождаемое командой
"CALL"; по. адресу, предшествующему адресу, указанному регистром
"I" и;Шшоё;данных. Вызываемый адрес в следующих двух байтах,
(младший баШш^т первым). Команда, будучи невидимой, не может
разместить собЙйЙ^ШЙ.адрес^возврата на машинный стек, поэтому
адрес, после последней; выполненной команды кладется на стек и к
нему будет осуществлен возврат после команды "RETI" в конце про-
граммы обработки прерываний.
Команде "RETI" должна предшествовать команда "EI". Причина,
по которой "DI" включено в вызов, выполняемый прерыванием, со-
стоит в том, чтобы гарантировать, что программа не зациклит петлю,
если процедура обработки прерываний выполняется продолжитель-
нее, чем пауза между двумя прерываниями:
Довольно просто написать ряд команд, которые заменят адрес
перехода по прерыванию с помощью загрузки байтов указателя ад-
ресом, а это две ячейки, за которыми мы следим для определения
места перехода. Примечание: когда бы не использовались программы
прерываний, очень важно, чтобы любые регистры, используемые
программой прерывания, сохранялись на входе и восстанавливались
перед возвратом в основную программу. Не должно быть попыток
пересылки данных через регистры в или из программы прерывания.
Из - за ограничения на величины, которые могут содержаться в
регистре "I", есть лишь ограниченное количество адресов, к которым
может быть осуществлен переход в 16К СПЕКТРУ Me. Это диктуется
содержимым ПЗУ. Дополнительная проблема при использовании
прерываний из ПЗУ связана с интерфейсом МИКРОДРАЙВа, кото-
рый изменяет указатель "Iм во время работы. Список указателей для
версии 2 СПЕКТРУМА и версии 1 интерфейса МИКРОДРАЙВа дан
в приложении F, но если вы не уверены в том, какая у вас версия, или
у вас различные версии, то необходима проверка. Для коммерческого
матобеспечения опасно использовать адреса ПЗУ, т.к. любые изме-
нения и любые дополнения в нем могут сделать ваше матобеспечение
неработающим. Типичное использование процедур прерываний -
управление спрайтами и сопровождающий звук программы. Зная, с
какой частотой генерируются прерывания, легко рассчитать скорость
перемещения спрайта, она будет независима от любых других опера-
ций внутри программы. Использование программ ПЗУ при прерыва-
нии затруднено возможностью подключения ПЗУ интерфейса во вре-
мя прерывания, Это должно быть учтено при написании программы.
Например, если программа "SPRITE" использует 16К ПЗУ при рисо-
вании на экран с помощью вызова "PLOT" в 8933 (22Е5Ю при под-
ключенном ПЗУ интерфейса, вызов 8933 произойдет в ПЗУ интер-
фейса. Т.к. такого адреса в нем нет, то это приведет к поломке
программы.
Один из способов решения проблемы - включить в прерывающую
программу проверку того, какая ПЗУ подключена. Самый простой
путь проверки - посмотреть адрес ПЗУ, содержащий различные зна-
чения в разных ПЗУ. Рекомендую использовать адрес 20 (D5h) в ПЗУ
интерфейса и 255 (FFh) в 16К ПЗУ и в зависимости от результата
предпринять соответствующее действие. Если вызов к 16К ПЗУ и оно
подключено, то вызов выполняется напрямую, а если подключено 8К
ПЗУ, то через RST 16. Для 8 К ПЗУ можно использовать обходной код
32h (см. Главу 3).
Я привел простую программу "SPRITE" в приложении G. Эта
программа передвигает группу из четырех пикселей, отражая их от
четырех углов экрана, выдает звуки и меняет цвет бордюра, демон-
стрируя тем самым способы обхода возникших проблем. Так как
полное понимание использования прерываний очень важно (если,
конечно, от них вообще есть польза), я шйагаю, что вы войдете в
программу используя ваш АССЕМБЛЕР.;Я;йййн£:взят прямо из мо-
его АССЕМБЛЕРа, чтобы гарантировать отсутййке: ошибок; не-
сколько необычно, что шестнадцатиричные числа пр5е^ва|юны сим-
волом "#", а двоичные - "%". Программу можно и перемёстить|;ёсли
рассчитать новое значение указателя и изменить регистр "Iм. Если вы
ввели и ассемблировали программу, перед попыткой ее выполнить
перечитайте еще раз эту страницу. Первая проблема, с которой вы
столкнетесь, если у вас 16К ПЗУ СПЕКТРУМа указатель
должен соответствовать ПЗУ. К сожалению, при написании я не
нашел пути использования 16К ПЗУ СПЕКТРУМа с интерфейсом
МИКРОДРАЙВа.
Перед тем, как что-либо предпринять, соХ|Ш£йте;:исходный и
объектный коды на ленте или МИКРОДРАЙВе и, ёйш у вас есть
МИКРОДРАЙВ, поместите набор Данных. Для инициализации
спрайта нужно вызвать подпрограмму;•;; помеченную в листинге
"SETUP" и, если указатель не изменял^ Ш; "R A NDO МIZE USR
51457". Теперь можно увидеть одну черную точку, двигающуюся
вокруг экрана. Если ее нет, то заново проверьте ваш код. Наличие
спрайта не повлияет на другае ^ёйс^ййа.компьютера, так что в про-
грамму можно войти и выполнять ее как;об:ычно до тех пор, пока она
не испортит память, используемую программой прерываний. Неко-
торые команды БЕЙСИКа, которые работают на прерываниях, могут
быть продемонстрированы.
Введите строку на ;БЕЙСИКе:
10 ВЕЕР 5,60 : FCpШ;;Т0 100 : NEXT N : GO ТО 10
При выполнении вы увидите^;;что -'SPRITE" останавливается,
если выполняется "ВЕЕР". Есть друтаё;команды, которые отключают
прерывания, это те, чтоиспользуются в "SAVE" и "LOAD". "SPRITE"
движется со скоростью 50 пикселей в секунду и потребуется 3.5 се-
кунды для перехода;с нижнёй части экрана наверх.