СИСТЕМА ПРЕРЫВАНИЙ
Прерывания являются необходимым средством для программирова-
ния параллельных процессов. С их помощью, например, в ZX Spectrum
одновременно с выполнением программы на Бейсике осуществляется ска-
нирование клавиатуры и отсчет времени системным таймером.
В процессоре Z80 имеется два аппаратных входа инициализации
прерываний: INT — для маскируемых прерываний и NMI — для немаски-
руемых. Маскируемые прерывания получили свое название благодаря воз-
можности программно запрещать или разрешать реакцию на сигнал преры-
вания, тогда как для немаскируемых прерываний это невозможно.
При поступлении сигнала прерывания микропроцессор завершает
выполнение текущей команды, помещает в стек адрес следующей и присту-
пает к выполнению специальной программы, обслуживающей данное пре-
рывание (за исключением режима 0 маскируемых прерываний). После
завершения обработки прерывания процессор извлекает из стека адрес
следующей команды и возвращается к выполнению прерванной программы.
Таблица 2. Биты состояния
kemp ston-джойстика.
Таблица 2. Биты состояния
kemp ston-джойстика.
установленный бит |
состояние джойстика |
DO |
влево (left) |
D1 |
вправо (right) |
D2 |
вверх (up) |
D3 |
вниз (down) |
D4 |
стрельба (fire) |
Необходимым условием правильного функционирования программ
обслуживания прерываний является их сбалансированная работа со стеком:
к моменту возврата из прерывания стек должен быть в том же состоянии, в
котором он находился к моменту прихода прерывания. Другим условием
является сохранение всех регистров, задействованных в программе обслу-
живания прерываний, и восстановление их значений при возврате из
прерывания.
Маскируемые прерывания
В ZX Spectrum на вход INT процессора постоянно подается полукад-
ровый синхронизирующий сигнал с периодом 1/50 секунды. В операцион-
ной системе это используется для организации опроса клавиатуры и нара-
щивания значения системного счетчика одновременно с работой интерпре-
татора Бейсика.
Управлять прохождением маскируемых прерываний можно команда-
ми DI и EI, которые изменяют состояние специального внутреннего триггера
микропроцессора IFF. Команда DI сбрасывает этот триггер, запрещая пре-
рывания, EI устанавливает его, разрешая прерывания.
При вызове маскируемого прерывания триггер IFF автоматически
сбрасывается, запрещая повторный вызов прерываний. После обработки
прерывания процессор не устанавливает триггер вновь — для разрешения
прохождения последующих прерываний программист должен включить в
программу команду EI.
Z80 имеет три режима обработки маскируемых прерываний, которые
устанавливаются командами процессора IM 0, IM 1 и IM 2. К сожалению,
программным путем практически невозможно определить, в каком режиме
обработки прерывании находится процессор в конкретный момент времени.
Режим 0
Режим устанавливается либо командой IМ 0, либо аппаратным сбросом
процессора, и ничем не отличается от режима обработки прерываний в
микропроцессоре 18080. По приходу сигнала INT процессор считывает с шины
данных код команды (предварительно выставленный на шину внешним пре-
рывающим устройством) и выполняет ее. В принципе, это может быть любая
команда (чаще всего используются команды RST N или CALL addr). Но
ZX Spectrum устроен таким образом, что при вызове прерывания в режиме 0
с шины данных всегда считывается значение 255 (#FF) — код команды RST 56.
И, следовательно, для ZX Spectrum этот режим аналогичен режиму 1 .*
Режим 1
Устанавливается командой IM 1. По прерыванию процессор передает
управление на ячейку с адресом 56 (выполняется команда CALL 56). Именно в
этом режиме обрабатывает прерывания операционная система ZX Spectrum.
Режим 2
Устанавливается командой IM 2. Режим дает возможность программи-
сту самостоятельно обрабатывать прерывания, чем и интересен.
При поступлении сигнала на прерывание, микропроцессор считыва-
ет с шины данных байт, называемый вектором прерывания. ZX Spectrum
устроен так, что вектор прерывания всегда равен 255 (#FF).** Он переда-
ется в младший байт шины адреса, а в старший байт записывается
*) Строго говоря, это не совсем так, см. примечание к режиму 2.
**) Некоторые внешние устройства, например, AMX-mouse, могут генери-
ровать вектор прерывания, отличный от 255.
содержимое регистра вектора прерываний I. По полученному таким образом
адресу Z80 считывает из памяти два последовательно расположенных байта,
которые интерпретируются процессором как адрес программы обработки
прерывания (сначала считывается младший байт адреса, затем старший).
Следовательно, выбрав режим прерываний 2 и задав значение регистра
I, можно переопределить адрес процедуры обработки прерывания.
Для задания адреса размещения программы обработки прерываний
наиболее удобно использовать значения, считываемые из стандартного ПЗУ
ZX Spectrum. При этом в регистр I нужно занести число в пределах от 0 до 63
(#00...#3F). Например, если в I содержится число 9, то адрес ячейки, из которой
будет считан младший байт адреса программы обработки прерываний, равен
2559 (9x256+255). Старший байт, соответственно, будет считан по адресу 2560.
В данном случае определить адрес, по которому необходимо разместить програм-
му обработки прерываний, можно, выполнив строку на Бейсике:
PRINT PEEK (2559)+256* РЕЕК (2560)
Результат должен быть равен 65129. Это и есть адрес, по которому
должна располагаться подпрограмма обработки прерываний.
Определить все возможные считанные из ПЗУ адреса размещения
процедур обработки прерываний можно с помощью следующей программы:
10 INPUT "Interrupt Vector: ";l: REM вектор прерывания
20 PRINT I.PEEK (l»256+255)+256*PEEK (1*256+255+1)
Уже рассчитанные адреса занесены в табл. 3.
Возврат из маскируемых прерываний производится командой RETI.
Она распознается специальными периферийными микросхемами*, что по-
Таблица 3. Адреса процедур обработки прерываний.
Таблица 3. Адреса процедур обработки прерываний.
I |
адрес |
I |
адрес |
I |
адрес |
I |
адрес |
0 |
20430 |
16 |
51984 |
32 |
52513 |
48 |
60208 |
1 |
52818 |
17 |
08729 |
33 |
33485 |
49 |
57640 |
2 |
22269 |
18 |
52481 |
34 |
00544 |
50 |
13627 |
3 |
39020 |
19 |
49749 |
35 |
49537 |
51 |
13256 |
4 |
10419 |
20 |
25705 |
36 |
08527 |
52 |
01560 |
5 |
02294 |
21 |
51673 |
37 |
23670 |
53 |
57124 |
6 |
29149 |
22 |
51568 |
38 |
20444 |
54 |
34307 |
7 |
16039 |
23 |
12493 |
39 |
00288 |
55 |
41231 |
8 |
02088 |
24 |
15582 |
40 |
32348 |
56 |
65535 |
9 |
65129 |
25 |
23842 |
41 |
58154 |
57 |
65535 |
10 |
32802 |
26 |
13824 |
42 |
19754 |
58 |
65535 |
11 |
58888 |
27 |
07306 |
43 |
23653 |
59 |
65535 |
12 |
53183 |
28 |
49947 |
44 |
07117 |
60 |
00255 |
13 |
52503 |
29 |
02344 |
45 |
55781 |
61 |
00000 |
14 |
14367 |
30 |
26573 |
46 |
23713 |
62 |
00255 |
15 |
27928 |
31 |
03360 |
47 |
04569 |
63 |
00060 |
*) Фирмой Zilog были разработаны микросхемы, входящие совместно с
Z80 CPU в комплект под общим названием Z80.
зволяет организовать многоуровневую систему прерываний. Но, поскольку
в ZX Spectrum эта система не используется, то вернуться из прерывания
можно и по команде RET.
Немаскируемые прерывания
Немаскируемое прерывание вызывается при поступлении сигнала на
вход NMI процессора. При этом выполнение основной программы приоста-
навливается, и управление передается на ячейку с адресом 102 (#66)
(выполняется команда CALL 102).
В ZX Spectrum немаскируемое прерывание не задействовано, но
оно может вызываться некоторыми внешними устройствами. При этом
вместо стандартной «прошивки» подключается ПЗУ вызвавшего прерыва-
ние устройства, в котором записана программа обработки прерывания.
Этот принцип используется, например, в дисковой системе Beta Disk
фирмы Technology Research и интерфейсе Multiface One фирмы Romantic
Robot.
При входе в немаскируемое прерывание сбрасывается триггер IFF,
и, следовательно, запрещается вызов маскируемых прерываний.
Возврат из немаскируемого прерывания и восстановление состояния
регистра IFF происходит по команде процессора RETN.
Следует отметить, что на самом деле Z80 имеет два триггера, участву-
ющих в обработке прерываний: IFF1 и IFF2. Триггер IFF1 используется для
управления разрешением маскируемых прерываний, a IFF2 хранит его
состояние при обработке немаскируемых. Состояние триггера IFF2 отража-
ется битом P/V флагового регистра после выполнения команд LD А,1 или
LD A,R.
Состояния триггеров IFF1 и IFF2 в различных режимах работы
процессора приведены в табл. 4.
Таблица 4. Состояния триггеров IFF1 и IFF2.
Таблица 4. Состояния триггеров IFF1 и IFF2.
Действие |
IFF1 |
IFF2 |
Примечание |
сигнал RESET |
0 IFF1 |
0 IFF2 |
устанавливает режим 0 |
команда DI |
0 IFF1 |
0 IFF2 |
запрещает прерывания |
команда EI |
1 IFF1 |
1 IFF2 |
разрешает прерывания |
сигнал INT |
0 IFF1 |
0 IFF2 |
маскируемое прерывание |
команда RETI |
не изменяется |
не изменяется |
возврат из маскируемого прерывания |
сигнал NMI |
0 IFF1 |
IFF1 IFF2 |
немаскируемое прерыва- ние |
команда RETN |
IFF2 IFF1 |
не изменяется |
возврат из немаскируемо- го прерывания |
команда LD А,1 |
не изменяется |
не изменяется |
IFF2 P/V |
команда LD A,R |
не изменяется |
не изменяется |
IFF2 P/V |
ОРГАНИЗАЦИЯ ПАМЯТИ
Постоянное запоминающее устройство ZX Spectrum имеет объем 16 К
и занимает младшие адреса памяти #0000...#3FFF. В нем расположены:
тест, проверяющий работоспособность компьютера при включении питания;
интерпретатор языка Бейсик; знакогенератор; программы, обеспечивающие
вывод на экран, связь процессора с клавиатурой и др. Некоторые внешние
устройства могут отключать стандартное ПЗУ, заменяя его своей памятью.
Остальные 48К адресного пространства занимает оперативное запо-
минающее устройство (адреса #4000...#FFFF). Причем в большинстве слу-
чаев для пользовательских программ не может быть отведено все простран-
ство ОЗУ — часть его используется под экранную область и область систем-
ных переменных Бейсика.
В табл. 5 приведена карта распределения памяти ZX Spectrum. Спра-
ва указаны физические адреса областей памяти, расположение которых
жестко фиксировано. Адреса других областей могут меняться в зависимости
от наличия внешних устройств и работающих в данный момент программ.
Местоположение этих областей определяется системными переменными
(см. «Системные переменные»), имена и адреса которых приведены в таб-
лице слева. Области, наличие которых не обязательно для работы операци-
онной системы ZX Spectrum, отмечены тонкими линиями.
Экранная область памяти
Размер экрана в ZX Spectrum составляет 256 точек по горизонтали и
192 по вертикали. Операционной системой вывод символов на экран
осуществляется в стандартные знакоместа 8x8 точек. Таким образом, экран
делится на 24 символьные строки по 32 знакоместа в каждой (см. рис. 13).
Рис. 13. Строение экрана ZX Spectrum.
Рис. 13. Строение экрана ZX Spectrum.
Для вывода изображения используется экранная область памяти объ-
емом 6К и область атрибутов — 768 байт. Каждый байт экранной области
определяет состояние 8 расположенных горизонтально одна за другой точек
(бит 7 соответствует левой точке, бит 0 — правой). Если какой-либо бит в
байте установлен, то точка, определяемая этим битом, принимает цвет тона,
если бит сброшен — цвет фона. Байты, соответствующие строкам экрана,
расположены в памяти не последовательно. Первые 32 байта экранной
области задают слева направо верхнюю строку, следующие 32 байта — 9-ю
сверху, следующие — 17-ю и далее через 8 строк вплоть до 57-й. Затем
расположены байты, соответствующие строкам 2-й, 10-й и т. д. до 58-й.
Таким образом, со смещением на одну и шагом в 8 строк задаются верхние
64 строки, то есть треть экрана. Аналогично, начиная соответственно с 65-й
и 129-й строк, определяются средняя и нижняя трети экрана.
В ZX Spectrum атрибуты (цвет тона, цвет фона, яркость и мерцание)
задаются не для отдельной точки, а для знакоместа. Каждому знакоместу в
области атрибутов соответствует один байт, в котором:
Биты D0...D2 определяют цвет тона (см. стр. 64);
Биты D3...D5 определяют цвет фона;
Бит D6 установлен в режиме повышенной яркости (задается одновремен-
но и для тона, и для фона);
Бит D7 установлен в режиме мерцания.
Байты атрибутов расположены в памяти последовательно. Первые 32
байта атрибутов соответствуют верхней символьной строке, следующие 32
— второй символьной строке сверху и далее до конца экрана.
Приведенные ниже программы помогут Вам разобраться со строени-
ем экрана ZX Spectrum. Первая из них демонстрирует соответствие битов
ячейки памяти экранной области точкам на экране:
10 BORDER 5: PAPER 7: INK 9: CLS : REM подготовка экрана
20 INPUT "bit numbers 0...7 ";b: REM ввод номера бита
30 LET n=21 b: REM вычисление «веса» бита
40 POKE 16384,n: REM запись байта, содержащего установленный
в единицу бит, в первую ячейку экранной области
50 GOTO 20
Следующая программа закрашивает экран, последовательно записы-
вая в ячейки экранной области значение 255. Работу программы можно
приостановить, нажав любую клавишу.
10 BORDER 5: PAPER 7: INK 9: CLS : REM подготовка экрана
20 FOR a=16384 TO 22527: REM переменная а перебирает все
адреса экранной области
30 PRINT AT 6,6;" ";АТ 6,6;а;: REM вывод адреса
40 РОКЕ а,255: REM запись в экранную область по адресу а
50 IF INKEYjO"" THEN GO TO 50: REM пауза
60 NEXT a: REM завершение цикла
Соответствие байтов атрибутов знакоместам на экране демонстрирует
следующая программа:
10 BORDER 7: PAPER 7: INK 7: CLS : REM цвет экрана белый
20 LET n=703: LET c=1: GO SUB 110: REM заполнение основного экрана
30 LET n=63: LET c=0: GO SUB 110: REM заполнение служебного экрана
40 FOR a=22528 TO 23295: REM а указывает адреса атрибутов
50 LET b=INT(a/256): REM b присваивается значение 0...255
60 POKE a,b: REM запись очередного значения в область атрибутов
70 PRINT PAPER 7; INK 0; AT 5,5;b;: REM печать b
80 IF INKEYJO"" THEN GO TO 50: REM пауза
90 NEXT a: REM завершение цикла
100 STOP : REM останов программы
110 FOR a=0 TO n: REM подпрограмма заполнения экрана
120 PRINT #с;"*";: REM заполнение экрана символом *
130 NEXT a: REM завершение цикла
140 RETURN : REM возврат из подпрограммы заполнения экрана
Буфер принтера
Стандартный ZX Printer имеет одну иголку, которая в процессе печати
последовательно проходит 256 позиций по горизонтали. Таким образом,
символьная строка печатается за 8 проходов. Подготовка символьной строки
к печати происходит в буфере принтера.
Очень часто буфер принтера используется не по назначению, а как
дополнйтельные 256 байт памяти, например, при адаптации программ к
дисковым системам или для размещения загрузчиков. Но, занимая буфер
под свою программу, следует учитывать, что она не будет работать на
Spectrum 128, в котором область буфера принтера используется для разме-
щения дополнительных системных переменных.*