4.7 Примеры использования прерываний 2-го рода.
В первой части этой книги мы рассмотрели теоретические аспекты использования прерываний 2-го типа в пользовательских программах. Здесь мы рассмотрим несколько конкретных примеров.
Так как полное понимание концепции использования прерываний очень важно, ниже приведены примеры программ обработки прерываний и включения режима "IM 2", написанные на АССЕМБЛЕРе с комментариями. Желательно предварительно поработать с ними, прежде чем начать создавать свои программы.
Вообще, для работы с "IM 2" необходимо создание двух программ сразу : включающей прерывания "IM 2" и, собственно, программы обработки прерываний. После запуска первой программы, она может быть удалена из памяти.
Если Вы будете пользоваться каким-либо АССЕМБЛЕРОМ, допускающим двойную установку адреса трансляции "ORG", например, это разрешает программа "ZEUS" фирмы "CRYSTAL COMPUTING", то Вы можете набирать программы так, как это представлено в листинге программ, иначе Вам придется разбивать программы на две части и транслировать их по отдельности с нового адреса "ORG".
1. Эта программа демонстрирует смену типов прерываний с "IM 1" на "IM 2" c вызовом указателя из ПЗУ (см. ч . Ш , гл.5 ) . После запуска программы в правом верхнем углу появится мигающий черно-белый атрибут, свидетельствующий о том, что прерывания переключены, и до тех пор, пока включен "IM 2", этот атрибут будет постоянно включен. При этом вы сможете работать в БЕЙСИКЕ или в других программах (если, конечно, они не перекрывают область памяти, занимаемую программой обработки прерываний " IM 2"; как и в обычном режиме.
адрес трансляции и запуска программы смены прерываний.
выбираем адрес точки прерываний равным 33485 и загружаем в "I" новый вектор. смена " IM 1" на " IM 2".
ORG 4 00 00 DI
LD A,33 LD I,A
IM 2
EI
RET
программа обработки "IM 2".
адрес экрана для атрибута. загружаем по адресу код атрибута.
переход для сканирования клавиатуры.
2. Это программные часы, работающие и выводящие время на экран по прерыванию. В этой программе имеется своя процедура для печати в экранную область. Вообще, если Вы хотите что-либо печатать на экране во время прерываний, то лучшим способом является введение своей подпрограммы печати, т.к. при использовании программ печати из ПЗУ Вы можете запутаться с сохранением открытого канала печати.
Программа часов использует данные в двоично-десятичной форме, именно в такой форме Вам необходимо перед запуском часов задать время, записав в ячейки :
90 100 110 120 130 140 150
ORG 33485 DI
PUSH HL LD HL , 581FH LD (HL),C7H POP HL JP 0038H
63 6 67 - часы, 63 6 68 - минуты, 63 6 69 - секунды. Для задания времени из БЕЙСИКА можно пользоваться следующим способом. Например, Вы задаете время : 12 часов 24 минуты 3 0 секунд:
Тогда в 63667 запишем 1*16+2=18,
63668 - 2*16+4=36,
63669 - 3*16+0=48.
Т.е. десятки умножаем на 16 и прибавляем младший разряд.
10 |
HOUR |
EQU |
63667 |
точка хранения часов. |
20 |
MIN |
EQU |
63668 |
-/-/-/-/- минут. |
30 |
SEC |
EQU |
63669 |
-/-/-/-/- секунд. |
40 |
COR |
EQU |
63666 |
-/-/-/-/- переменной коррекции. |
50 |
|
ORG |
65040 |
адрес трансляции и запуска программы |
60 |
|
|
|
смены прерываний. |
70 |
|
DI |
|
|
80 |
|
PUSH |
HL |
|
90 |
|
LD A |
, FDH |
адрес указателя FDFFH 65023. |
100 |
|
LD I |
, A |
|
110 |
|
LD HL,FDFFH |
заполняем указатель адресом старта |
120 |
|
LD |
(HL),F7H |
программы обработки "IM 2" -F7F7H - 63479 |
130 |
|
INC |
HL |
|
140 |
|
LD |
(HL),F7H |
|
150 |
|
POP |
HL |
|
160 |
|
IM 2 |
|
|
170 |
|
EI |
|
|
180 |
|
RET |
|
|
190 |
|
ORG |
63479 |
адрес программы часов по "IM 2". |
200 |
|
PUSH |
IX |
|
210 |
|
PUSH |
AF |
|
220 |
|
PUSH |
BC |
|
230 |
|
PUSH |
DE |
|
240 |
|
PUSH |
HL |
|
250 |
|
DI |
|
|
260 |
|
LD A |
, (COR) |
; проверка на необходимость изменения |
270 |
|
DEC |
A |
; счетчика времени. |
280 |
LD (COR) , A |
|
2 90 |
JP NZ,WRITE |
; |
300 |
LD A,3 2H |
; |
310 |
LD (COR) , A |
; |
320 |
LD A,(SEC) |
; |
330 |
AND A |
|
340 |
ADC A,01 |
|
350 |
DAA |
|
360 |
LD (SEC) ,A |
|
370 |
CP 60H |
; |
380 |
JP NZ,WRITE |
; |
390 |
XOR A |
; |
400 |
LD (SEC) ,A |
|
410 |
LD A,(MIN) |
; |
420 |
AND A |
|
430 |
ADC A,01 |
|
440 |
DAA |
|
450 |
LD (MIN) ,A |
|
460 |
CP 60H |
|
470 |
JP NZ,WRITE |
|
480 |
XOR A |
|
490 |
LD (MIN) ,A |
|
500 |
LD A,(HOUR) |
; |
510 |
AND A |
|
52 0 |
ADC A,01 |
|
53 0 |
DAA |
|
540 |
LD (HOUR) , A |
|
550 |
CP 24H |
; |
560 |
JP NZ,WRITE |
|
570 |
XOR A |
|
580 |
LD (HOUR) , A |
|
590 WRITE |
LD IX,4 018H |
; |
600 |
|
; |
610 |
LD A,(HOUR) |
; |
62 0 |
CALL PRFP |
|
630 |
LD A,0AH |
; |
64 0 |
CALL PRCH |
|
650 |
LD A,(MIN) |
; |
если не ноль, то сразу на печать, иначе восстановим переменную коррекции и ведем подсчет времени. подпрограмма подсчета секунд.
если не 60,
то переход на печать,
иначе обнуление секунд и подсчет минут ; подпрограмма подсчета минут.
; подпрограмма подсчета часов.
; проверка на 24-х часовой цикл.
программа вывода данных на экран, в IX содержится адрес начала печати, печатаем часы.
; печатаем двоеточие.
; печатаем минуты.
660 |
|
CALL PRFP |
|
67 0 |
|
LD A,0AH |
|
68 0 |
|
CALL PRCH |
|
690 |
|
LD A,(SEC) |
печатаем секунды. |
700 |
|
CALL PRFP |
|
710 |
|
LD HL, 5 818H |
заполняем место печати времени |
720 |
|
LD B, 0 8 |
мигающими черно-белыми атрибутами. |
730 |
FLAG |
LD (HL),C7H |
|
740 |
|
INC HL |
|
7 50 |
|
DJNZ FLAG |
|
760 |
|
POP HL |
|
770 |
|
POP DE |
|
780 |
|
POP BC |
|
790 |
|
POP AF |
|
800 |
|
POP IX |
|
810 |
|
JP 0038H |
переход для сканирования клавиатуры |
82 0 |
PRFP |
PUSH AF |
подпрограмма печати чисел. |
830 |
|
SRL A |
вычисляем код старшей цифры. |
84 0 |
|
SRL A |
|
850 |
|
SRL A |
|
860 |
|
SRL A |
|
87 0 |
|
CALL PRCH ; |
печатаем старшую цифру. |
880 |
|
POP AF |
|
8 90 |
|
AND 0FH ; |
вычисляем код младшей цифры. |
90 0 |
|
CALL PRCH ; |
печатаем младшую цифру. |
910 |
|
RET |
|
92 0 |
PRCH |
PUSH IX |
подпрограмма печати литеры. |
930 |
|
LD HL, (5C3 6H) ; |
загружаем адрес знакогенератора. |
940 |
|
LD DE,018 0H ; |
производим необходимое смещение. |
950 |
|
ADD HL, DE |
|
960 |
|
EX DE, HL |
|
97 0 |
|
LD L,A |
вычисляем по коду литеры ее адрес |
980 |
|
LD H,00 |
в таблице знакогенератора. |
990 |
|
ADD HL, HL |
|
1000 |
|
ADD HL, HL |
|
1010 |
|
ADD HL, HL |
|
102 0 |
|
ADD HL, DE |
|
1030 |
|
LD DE,0100H |
|
1040 LD B, 08
1050 PSET LD A, (HL) 1060 XOR FFH
1070 LD (IX+00),A
1080 INC HL
1090 ADD IX,DE
1100 DJNZ PSET
1110 POP IX
112 0 INC IX
1130 RET
Вы, вероятно заметили, что в подпрограмме "PRCH" есть смещение в знакогенераторе до литеры "0", т.е. все коды литер смещены на 48 байтов по сравнению с таблицей ASCII. Возможно, это неправильно, но упрощает подпрограммы печати чисел и литер.
Предлагаемые программы можно переместить, если рассчитать новые значения указателей и изменить содержимое регистра "I".