Предыдущий раздел УПРАВЛЕНИЕ УСТРОЙСТВАМИ С ПРЕРЫВАНИЯМИ Следующий раздел

21.3.2. Программа драйвера

Программа асинхронного посимвольного драйвера, использующего прерывания:

 

;             Асинхронный драйвер ввода символов с перфоленты 

;             --------------------------------------------------------------------

;         Содержит: 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.

 


Предыдущий раздел В начало Следующий раздел