Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

3385

.pdf
Скачиваний:
2
Добавлен:
15.11.2022
Размер:
4.73 Mб
Скачать

- 07: функция управления режимом заполнения массива: циклическое заполнение или однократное. Для переключения обработчика в режим циклического (однократного) заполнения массива необходимо поместить в регистр AL число 00h (01h), в регистр AH 07h (седьмая функция) и вызвать программное прерывание 60h. Для того, чтобы повторно заполнить массив в режиме однократного заполнения нужно воспользоваться функцией 06. Драйвер предназначен для работы с операционной системой MS-DOS на ЭВМ с процессорами типа х.386 и выше.

Вразделе 4.3.4 приведѐн листинг драйвера, работающего с портом LPT1

ипрерыванием IRQ7. Как видно, можно без труда унифицировать драйвер под данные порты.

4.3.3. Описание принципов сопряжения драйвера и графической оболочки

Пример графической оболочки приведѐн в разделе 4.3.4.. Программа написана на языке высокого уровня Turbo Pascal 7.0. Данная программа содержит подпрограммы связи с драйвером в виде ассемблерных вставок и построитель графиков. Алгоритм функционирования данной программы заключается в поэлементном изъятии байтов данных с помощью прерываний и построение соответствующих точек на графике. В данном случае применена линейная аппроксимация. Команда на обновление массива данных подаѐтся по сигналу с клавиатуры.

4.3.4. Программные средства ВИК

Листинг программы-драйвера (для порта LPT1)

;Степаненко Ю.А. 20.04.2001 ;Программирование параллельного порта LPT1 ;в режиме прерываний

.386

;Команды новых процессоров

code segment use16

;16-разрядное приложение

assume cs:code, ds:code

;данные в сегменте команд

org 100h

;место под префикс

main proc

 

 

push cs

;настроим DS

pop ds

;на сегмент команд

;Замаскируем принтерное прерывание IRQ7 порта LPT1

in al,0021h

;порт ведущего контроллера

mov maska,al

;сохраним

or al,10000000b

;замаскируем прерывание

out dx,al

;запишем

;Сохраним байт управления портом

mov dx,37Ah

;Адрес порта управления

in al,dx

 

mov b_ypr,al

;сохранить в памяти

;Сохраним обработчик прерываний параллельного порта LPT1

mov ax,350Fh

;Функция 35h, вектор 0Fh

int 21h

mov word ptr old_0F,bx ;Сохраним смещение mov word ptr old_0F+2,es;Сохраним сегмент

;Сохраним обработчик прерываний пользователя

mov al,60h

;Функция 35 вектор 60h

int 21h

 

mov word ptr old_60,bx ;Сохраним смещение mov word ptr old_60+2,es;Сохраним сегмент

;Установим новый обработчик прерываний параллельного порта mov ax,250Fh ;Функция 25h, вектор 0Fh

mov dx,offset new_0F ;Адрес нового обработчика int 21h

;Установим новый обработчик прерываний пользователя

mov ax,2560h

;Функция 25h, вектор 60h

mov dx,offset new_60

;Адрес обработчика

int 21h

 

;Обработчик прерываний от порта LPT1 ;активизируется аппаратным IRQ7

;и программным прерыванием 0Fh new_0F proc

push ax

;Сохраним все регистры

push bx

 

push dx

 

push si

 

push ds

 

push cs

;загрузим DS через стек

pop ds

 

mov dx,378h mov al,0Fh out dx,al

mov dx,379h

in al,dx

;Прочитаем регистр состояния

;где находится старший полубайт

mov bh,al

;Обработаем данные из порта:

rol bx,2

;циклически сдвинем влево минуя CF

bt bx,1

;перепишем в CF мл. бит

rcr bx,1

;циклически сдвинем вправо через CF

mov ah,bh

 

;Поставим старший полубайт

cicle:

;Цикл ожидания появления

in al,dx

;младшего полубайта

rol al,1

 

 

rol al,1

 

 

jb cicle

;если ACK#<>0 повторить цикл

ror al,1

 

 

ror al,1

 

 

mov bh,al

;Обработаем данные из порта:

rol bx,2

 

 

bt bx,1

 

 

rcr bx,1

 

 

ror bh,4

;Поставим на место младший полубайт

and bh,00001111b;Формируем байт данных

and ah,11110000b

add ah,bh

 

;данные в AH

xor ah,01110111b;исправим инверсные биты

mov bx,smeh

;число заполненных элементов

mov si,vxod

;точка входа в массив

mov dx,kol

 

;размер массива

mov [si][bx],ah;запишем в массив

inc bx

;прирастим

cmp dx,bx

 

;Сравним с размером массива

ja perex

;перейти если выше

mov bx,0h

 

;если переполнение - обнулим

mov al,00h

 

;Распознаем режим заполнения

cmp al,regin

;массива: останавливать заполнение

je perex

;или нет

mov dx,37Ah

;если останавливать - загрузим 0

out dx,al

;в регистр управления портом

perex:mov smeh,bx ;обновим smeh

mov dx,378h mov al,00h out dx,al

;восстановим регистры

pop ds pop si pop dx pop bx

mov al,20h ;Команда EOQ

out 20h,al

;в контроллеры прерываний

out 0A0h,al

 

pop ax

;восстановим регистры

iret

 

new_0F endp

;Функции управления (вход в AH,BX; выход в AX,DX)

new_60 proc

push ds

;Сохраним DS

push cs

;Настроим DS на данные

pop ds

 

cmp ah,00h

;распознаем функцию управления

je f_00

 

cmp ah,01h

 

je f_01

 

cmp ah,02h

 

je f_02

 

cmp ah,03h

 

je f_03

 

cmp ah,05h je f_05 cmp ah,06h je f_06 cmp ah,07h je f_07

jmp near ptr outret

;00 :Функция передачи точки входа в массив данных ;выход :BX-сегмент, AX-смещение,DX-номер очередного ;регенерируемого элемента

f_00:

mov ax, vxod ;Передадим точку входа

push ds

;в массив данных через AX

pop bx

;Сегмент массива в bx

mov dx,smeh

jmp near ptr outret

;01 :Функция передачи элементов массива

;при входе в BX-номер элемента i(0..N-4)

;a[i+1]-AH,a[i]-AL,a[i+3]-DH,a[i+2]-DL,

;BX-номер регенерируемого элемента

f_01:

 

push si

 

mov si,vxod

;Настроим SI на первый элемент

mov ax,[si][bx];Запишем элементы массива в AX mov dx,[si][bx+2]

mov bx,smeh pop si

jmp near ptr outret

;02 :Функция запрещения аппаратного прерывания ;от порта LPT1

f_02: push ax push dx

;Настроим бит ACK# порта LPT1 на отмену прерываний

mov dx,37Ah

;Адрес порта управления

mov al,00000000b

out dx,al

;сбросим бит

pop dx

 

pop ax

jmp near ptr outret

;03 :Функция передачи элемента массива ;при входе в BX-номер элемента i(0..N-1) ;a[i]-AH

f_03: push si

mov si,vxod mov ah,[si][bx] pop si

jmp near ptr outret

;04 :Функция настройки резидентной программы f_04:

jmp near ptr outret

;05 :Функция завершения программы чтения данных ;из порта LPT1

f_05:

;Замаскируем принтерное прерывание

mov al,maska

;загрузим

or al,10000000b

;модифицируем

out 0021h,al

 

;запишем

;Восстановим исходный обработчик порта LPT1

push ds

;Сохраним DS

mov ax,250Fh

;Функция 25h,вектор 0Fh

lds dx,old_0F ;Сохраненный адрес int 21h

pop ds

;Восстановим исходный обработчик пользователя

push ds

 

mov al,60h

;Функция 25h,вектор 60h

lds dx,old_60

;Сохраненный адрес

int 21h

pop ds ;Восстановим DS ;Восстановим регистр управления портом

mov dx,37Ah mov al,b_ypr out dx,al

;Инициализация порта LPT1

;mov ah,01h

;mov dx,01h ;int 17h

;Восстановим маску прерываний

mov al,maska

;загрузим

out 0021h,al

;восстановим

;Завершим программу mov ax,4C00h

int 21h

jmp near ptr outret

;06 :Функция разрешения аппаратного прерывания ;от порта LPT1

f_06: push ax push dx

;Настроим бит ACK# порта LPT1 на разрешение прерываний

mov dx,37Ah

;Адрес порта управления

mov al,00010000b

out dx,al

;установим бит

pop dx pop ax

jmp near ptr outret

;07 :Функция управления режимом заполнения массива ;Вход: AL-режим заполнения массива

;AL=00-циклическая регенерация

;AL=01-однократная регенерация с последующим

;запрещением аппаратного прерывания

;от сигнала ACK#

f_07:

mov regin,al

jmp near ptr outret

outret: pop ds iret

new_60 endp

old_0D dd 0 ;Ячейка для исходного вектора old_60 dd 0

mas db 1000 dup (0);Массив накопленных данных kol dw ($-mas) ;Размер массива

smeh dw 0 ;Число заполненных элементов maska db 0 ;Старая маска прерываний b_ypr db 0 ;Регистр управления порта vxod dw offset mas;Адрес первого элемента

regin db 0 ;Задает режим регенерации массива ressize=($-offset main);Размер программы без префикса code ends

end main

Содержание *.bat-файла для трансляции данного файла в .com программу:

C:\TASM\BIN\tasm /z/zi/n/m2 y_dr1,y_dr1,y_dr1 C:\TASM\BIN\tlink /x/v/3/t y_dr1,y_dr1

rem C:\TASM\BIN\td y_dr1

Листинг программы-драйвера (для порта LPT2)

;Степаненко Ю.А. 15.04.2001 ;Программирование параллельного порта LPT2

;в режиме прерываний

 

.386

;Команды новых процессоров

code segment use16

;16-разрядное приложение

assume cs:code, ds:code

;данные в сегменте команд

org 100h

;место под префикс

main proc

 

 

push cs

;настроим DS

pop ds

;на сегмент команд

;Замаскируем принтерное прерывание IRQ5 порта LPT2

in al,0021h

;порт ведущего контроллера

mov maska,al

;сохраним

or al,00100000b

;замаскируем прерывание

out dx,al

;запишем

;Сохраним байт управления портом

mov dx,27Ah

;Адрес порта управления

in al,dx

 

 

mov b_ypr,al

;сохранить в памяти

;Сохраним обработчик прерываний параллельного порта LPT2

mov ax,350Dh ;Функция 35h, вектор 0Dh int 21h

mov word ptr old_0D,bx ;Сохраним смещение mov word ptr old_0D+2,es;Сохраним сегмент

;Сохраним обработчик прерываний пользователя mov al,60h ;Функция 35 вектор 60h

int 21h

mov word ptr old_60,bx ;Сохраним смещение mov word ptr old_60+2,es;Сохраним сегмент

;Установим новый обработчик прерываний параллельного порта mov ax,250Dh ;Функция 25h, вектор 0Dh

mov dx,offset new_0D ;Адрес нового обработчика int 21h

;Установим новый обработчик прерываний пользователя

mov ax,2560h

;Функция 25h, вектор 60h

mov dx,offset new_60 ;Адрес обработчика

int 21h

 

;Размаскируем принтерное прерывание

mov al,maska

;загрузим

and al,11011111b

;модифицируем

out 0021h,al

;запишем

mov ah,02h

 

int 60h

 

;Cделаем программу резидентной

mov dx,(ressize+10fh)/16 ;размер в параграфах

mov ax,3100h;Функция 'завершить и оставить в памяти' int 21h

main endp

;Размаскируем принтерное прерывание

mov al,maska

;загрузим

and al,11011111b

;модифицируем

out 0021h,al

;запишем

mov ah,02h

 

int 60h

 

;Cделаем программу резидентной

mov dx,(ressize+10fh)/16 ;размер в параграфах

mov ax,3100h;Функция 'завершить и оставить в памяти' int 21h

main endp

 

in al,dx

;Прочитаем регистр состояния

;где находится старший полубайт

mov bh,al

;Обработаем данные из порта:

rol bx,2

;циклически сдвинем влево минуя CF

bt bx,1

;перепишем в CF мл. бит

rcr bx,1

 

;циклически сдвинем вправо через CF

mov ah,bh

 

 

;Поставим старший полубайт

cicle:

;Цикл ожидания появления

in al,dx

 

;младшего полубайта

rol al,1

 

 

 

rol al,1

 

 

 

jb cicle

;если ACK#<>0 повторить цикл

ror al,1

 

 

 

ror al,1

 

 

 

mov bh,al

 

 

;Обработаем данные из порта:

rol bx,2

 

 

 

bt bx,1

 

 

 

rcr bx,1

 

 

 

ror bh,4

 

;Поставим на место младший полубайт

and bh,00001111b;Формируем байт данных

and ah,11110000b

add ah,bh

 

 

;данные в AH

xor ah,01110111b;исправим инверсные биты

mov bx,smeh

;число заполненных элементов

mov si,vxod

 

;точка входа в массив

mov dx,kol

 

 

;размер массива

mov [si][bx],ah;запишем в массив

inc bx

 

;прирастим

cmp dx,bx

 

 

;Сравним с размером массива

ja perex

 

;перейти если выше

mov bx,0h

 

 

;если переполнение - обнулим

mov al,00h

 

 

;Распознаем режим заполнения

cmp al,regin

;массива: останавливать заполнение

je perex

 

;или нет

mov dx,27Ah

;если останавливать - загрузим 0

out dx,al

 

;в регистр управления портом

perex:mov smeh,bx ;обновим smeh

;восстановим регистры

pop ds

 

 

 

pop si

 

 

 

pop dx

 

 

 

pop bx

 

 

 

mov al,20h

 

;Команда EOQ

out 20h,al

 

 

;в контроллеры прерываний

out 0A0h,al

 

 

pop ax

 

;восстановим регистры

iret

 

 

 

new_0D endp

;Функции управления (вход в AH,BX; выход в AX,DX)

new_60 proc

 

push ds

;Сохраним DS

push cs

;Настроим DS на данные

pop ds

 

cmp ah,00h

;распознаем функцию управления

je f_00

 

cmp ah,01h

 

je f_01

 

cmp ah,02h

 

je f_02

 

cmp ah,03h

 

je f_03

 

cmp ah,05h

 

je f_05

 

cmp ah,06h

 

je f_06

 

cmp ah,07h

 

je f_07

jmp near ptr outret

;00 :Функция передачи точки входа в массив данных ;выход :BX-сегмент, AX-смещение,DX-номер очередного ;регенерируемого элемента

f_00:

mov ax, vxod

;Передадим точку входа

push ds

;в массив данных через AX

pop bx

;Сегмент массива в bx

mov dx,smeh

jmp near ptr outret

;01 :Функция передачи элементов массива ;при входе в BX-номер элемента i(0..N-4) ;a[i+1]-AH,a[i]-AL,a[i+3]-DH,a[i+2]-DL, ;BX-номер регенерируемого элемента f_01:

push si

mov si,vxod ;Настроим SI на первый элемент mov ax,[si][bx];Запишем элементы массива в AX mov dx,[si][bx+2]

mov bx,smeh pop si

jmp near ptr outret

;02 :Функция запрещения аппаратного прерывания ;от порта LPT2

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]