Предыдущий раздел | УПРАВЛЕНИЕ УСТРОЙСТВАМИ С ПРЕРЫВАНИЯМИ | Следующий раздел |
Программа асинхронного посимвольного драйвера, использующего прерывания:
; Асинхронный драйвер ввода символов с перфоленты
; --------------------------------------------------------------------
; Содержит: 1) п/п-а инициализации (вызов из DOS)
; 2) п/п-а вывода символа (вызов командой “ int 0eeh”)
; 3) обработчик прерываний перфоленты (инициируется аппаратно)
;
Nmax equ 20 ; Емкость буфера = 20 символов
absolute 2ch ; Следующий байт имеет адрес-смещение 2ch
Blocokr resw 1 ; Адрес-сегмент блока окружения
segment code ; Виртуальный сегмент кода
org 100h
Start: jmp Init ; Переход на инициализацию
; Определение данных
N db 0 ; Счетчик символов в буфере
S dw 0 ; Указатель «взять»
F dw 0 ; Указатель «положить»
Buf times Nmax db 0 ; Буфер
;
; Ввод символа - обработчик программного прерывания с номером EEh
; ------------------------------------------------------------------------------------------
; Выходы: флаг CF – признак результата (0–успешно; 1–символа пока нет)
; AL – код символа
Begin: sti ; Разрешить маскируемые прерывания
push ax ; Сохранение
push bx ; содержимого
push ds ; регистров в стеке
mov ax, cs ; DS будет адресовать данные
mov ds, ax ; резидентной программы
cmp [N], byte 0 ; Буфер пуст ?
jnz .Simv ; Если не пуст, то переход
in al, 90h ; Чтение RS в AL
or al, 00001001b ; Запуск устройства
out 90h, al ; и разрешение прерываний от п/л
stc ; Установка флага переноса CF
jmp .Exit
.Simv: cmp [N], byte Nmax ; Буфер полон ?
jnz .M1 ; Если не полон, то переход
in al, 90h ; Чтение RS в AL
or al, 00000001b ; Запуск
out 90h, al ; устройства
.M1: mov bx, [S] ; Запись в AL
mov al, [Buf+bx] ; символа из буфера
dec [N] ; Уменьшение счетчика символов на 1
cmp [S], word Nmax –1 ; S указывает на конец буфера ?
jz .M2 ; Если да, то переход
inc [S] ; Увеличение S на 1
jmp .M3
.M2: mov [S], word 0 ; S ß 0
.M3: clc ; Сбрасывает флаг переноса CF
.Exit: pop ds ; Восстановление содержимого
pop bx ; регистров
pop ax ; из стека
iret ; Возврат в программу из прерывания
;
; Обработчик аппаратных прерываний с номером 60h от устройства ввода
; перфоленты
;------------------------------------------------------------------------------------------------------
Obrpr: sti ;Разрешить маскируемые прерывания
push ax ; Сохранение
push bx ; содержимого
push ds ; регистров в стеке
mov ax, cs ; DS будет адресовать данные
mov ds, ax ; резидентной программы
in al, 91h ; Прием символа из RD в AL
mov bx, [F] ; Запись символа из
mov [Buf+bx], al ; AL в буфер
inc [N] ; Увеличение счетчика символов на 1
cmp [F], word Nmax –1 ; F указывает на конец буфера ?
jz .L1 ; Если да, то переход
inc [F] ; Увеличение F на 1
jmp .L2
.L1: mov [F], word 0 ; F ß 0
.L2: cmp [N], byte Nmax ; Буфер полон ?
jz .Exit ; Если да, то переход
in al, 90h ; Чтение RS в AL
or al, 00000001b ; Запуск
out 90h, al ; устройства
.Exit: mov al, 20h ; Разрешение менее приоритетных
out 20h, al ; прерываний
pop ds ; Восстановление содержимого
pop bx ; регистров
pop ax ; из стека
iret ; Возврат в программу из прерывания
;
; Инициализационная часть программы
Init:
mov ax, 25eeh ; Запись стартового адреса обработчика
mov dx, Begin ; в вектор прерываний
int 21h ; с номером EEh
mov ax, 2560h ; Запись стартового адреса обработчика
mov dx, Obrpr ; в вектор прерываний
int 21h ; с номером 60h
mov ah, 49h ; Освобождение области памяти,
mov es, Blocokr ; занимаемой
int 21h ; блоком окружения
mov dx, Init ; Возврат в DOS, оставшись
int 27h ; резидентным
Приведенная программа состоит из трех модулей, предваряемых данными, совместно используемыми этими модулями. Первый по порядку модуль начинается с метки Begin и представляет собой программную реализацию логической процедуры «Ввести символ». Данный модуль выполнен как резидентный обработчик программных прерываний с номером EEh. (Напомним, что в качестве этого номера разработчик может взять любой неиспользуемый номер.)
Второй модуль начинается с метки Obrpr и представляет собой программную реализацию логического процесса «Обработчик прерываний перфоленты». Этот модуль выполнен как резидентный обработчик внешних аппаратных прерываний с номером 60h.
Третий модуль начинается с метки Init и представляет собой программную реализацию логической процедуры “Инициализация”. Этот модуль выполнен как фрагмент программы, инициируемый при запуске программы из DOS.
Предыдущий раздел | В начало | Следующий раздел |