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".
10 20 30 40 50
60 70
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".