Материал: Системное программирование

Внимание! Если размещение файла нарушает Ваши авторские права, то обязательно сообщите нам

Для создания резидентной программы необходимо переопределить вектор прерывания. Новый обработчик прерывания либо полностью заменяет стандартный, либо только дополняет его. Во втором случае обработчику управление может быть передано до выполнения стандартной подпрограммы обработки прерывания, либо после.

Прерывание по таймеру имеет наивысший приоритет IRQ0, поэтому оно будет вытеснять любые другие прерывания до тех пор, пока не будут заблокированы все прерывания командой CLI. Микросхема таймера получает сигналы от часов с частотой 1.19 МГц. Прерывание по таймеру возникает, когда внутренний счетчик микросхемы таймера обнулится. Первоначально счетчик устанавливается в 65535 и при получении очередного импульса его значение уменьшается на 1. Поэтому прерывания происходят с частотой 18.2Гц.

Микросхема контроллера прерываний в ответ на запрос генерирует прерывание INT 8, которое обслуживает программа BIOS. После обновления времени суток и выполнения ряда других служебных действий, программа BIOS выполняет команду INT 1Ch, программное прерывание, называемое прерыванием пользователя по таймеру.

По умолчанию подпрограмма обработки прерывания INT 1Сh содержит единственную команду возврата из прерывания IRET. Программы, которые должны выполняться периодически, могут установить свою собственную подпрограмму обработки прерывания INT 1Сh. После ее выполнения управление вновь будет передано процедуре обработки времени суток INT 8. Схема расширения прерывания таймера показана на рис. 43.

Рис. 43. Расширение прерывания таймера.

Определим теперь составные части TSR. Прежде всего, необходимо выделить подпрограмму установки и резидентную часть. Резидентная часть находится перед установщиком, т.к. ее адрес должен быть известен заранее. В свою очередь установщик состоит из загрузчика и программы выгрузки. Загрузчик должен сохранить старый вектор, установить новый вектор прерывания и завершить программу, оставив ее резидентной (рис. 44).

Резидентная часть обработчика определяет функциональность TSR. Она может быть произвольной, поэтому мы ее приводить не будем и оставим читателю для самостоятельной работы. Обработчики прерываний должны быть дальними процедурами, которые сохраняют в стеке состояние всех регистров перед началом выполнения и восстанавливают их по окончанию работы.

Рис. 44. Алгоритм подпрограммы установки.

Рис. 45. Алгоритм обработчика прерывания 1Ch.

Если обработчик прерывания полностью заменяет стандартный обработчик аппаратного прерывания, то перед возвратом он должен сообщить контроллеру прерываний об окончании обработки, чтобы разрешить аппаратные прерывания нижних уровней. Если обработчик только дополняет старый обработчик прерывания, то он должен содержать его вызов. Для определенности выберем вариант полной замены существующего обработчика.

Алгоритм работы нового обработчика прерывания от таймера приведен на рис. 45.

Каждой клавише соответствует определенный числовой код, так называемый скан-код. Этот код посылает контроллер клавиатуры 8048 микросхеме интерфейса с периферией 8255. Скан-код однобайтовый, младшие 7 бит которого представляют идентификационный номер, присвоенный каждой клавише, а старший бит определяет состояние клавиши (1 – клавиша нажата, 0 – отпущена).

Завершение работы резидентной части должно происходить по клавишной комбинации «Ctrl+x». В нашем примере скан-код для левой нажатой клавиши «Ctrl» равен 1Dh, а для отпущенной клавиши – 9Dh. Для клавиши «x» (не символа) соответствующие коды равны 2Dh и 0Ah. Прерывание клавиатуры 9h преобразует скан-коды в ASCII коды и устанавливает статус клавиш переключателей. Получить скан-код можно, обратившись к микросхеме 8255 по адресу 60h.

Следовательно, отследить клавишную комбинацию «Ctrl+x» можно таким образом. Зафиксировать факт нажатия левой клавиши «Ctrl», например, с помощью специальной переменной (флага). Флаг устанавливается в 1 при получении скан-кода 1Dh и сбрасывается в 0 при коде 9Dh. Затем следует периодически проверять код нажатой клавиши. При скан-коде 2Dh и установленном флаге имеет место требуемая клавишная комбинация.

Возможный вариант реализации программы TSR приведен ниже.

IDEAL

MODEL MEDIUM

STACK 100h

DATASEG

; Флаг состояния левой клавиши Ctrl

LeftCtrlONDB0

; Область сохранения старого вектора прерывания

OldTimerInterruptOffsetDW?

OldTimerInterruptSegmentDW?

ENDS

CODESEG

; Основной модуль программы

PROCTimerTest

; Инициализировать регистр DS

MOVAX,DGROUP

MOVDS,AX

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

CALLSetTimerInterrupt

; Передать управление MSDOS и оставить резидентным

INT27h

ENDPTimerTest

; Новый обработчик прерывания

PROCTimerInterruptFAR

; Сохранить регистры общего назначения

PUSHA

PUSHDS

; Инициализировать регистр DS

MOV AX,DGROUP

MOV DS,AX

; Получить скан-код

INAL,60h

; Разрешить прерывания с более низким уровнем

MOV AL,20h

OUT 20h,AL

; Нажата клавиша Ctrl?

CMP AL,1Dh

JZ@@on

; Отпущена клавиша Ctrl?

CMPAL,9Dh

JNZ@@x

; Сбросить флаг левой клавиши Ctrl

MOV[LeftCtrlON],0

JMPSHORT@@go

; Установить флаг левой клавиши Ctrl

@@on:MOV [LeftCtrlON],1

JMP SHORT @@go

; Нажата клавиша «x»?

@@x:CMPAL,2Dh

JNZ@@go

; Нажата левая клавиша Ctrl?

CMP[LeftCtrlON],1

JNZ@@go

; Восстановить прежний обработчик прервания

CALL RestoreOldTimerInterrupt

JMP SHORT @@exit

@@go:... ; «Полезная» часть резидента

@@exit: ; Завершить обработку прерывания

POPDS

POPA

; Выход из обработчика прерывания

IRET

ENDPTimerInterrupt

; Установить новый вектор прерывания

PROC SetTimerInterrupt NEAR

PUSHA

PUSH ES

MOVAX,0

MOVES,AX

; Запомнить прежний вектор обработчика прерывания

MOV AX,[ES:1Ch*4]

MOV [OldTimerInterruptOffset],AX

MOV AX,[ES:1Ch*4+2]

MOV [OldTimerInterruptSegment],AX

; Установка вектора прерывания на обработчик

CLI; Запретить прерывания

MOV AX,offset TimerInterrupt

MOV [ES:1Ch*4],AX

MOV AX,CS

MOV [ES:1Ch*4+2],AX

STI; Разрешить прерывания

POPES

POPA

RET

ENDPSetTimerInterrupt

; Восстановить исходный вектор прерывания

PROCRestoreOldTimerInterruptNEAR

PUSHA

; Настроить регистр ES на таблицу векторов прерываний

PUSH ES

MOV AX,0

MOV ES,AX

; Восстановить прежний вектор обработчика прерывания

CLI

MOV AX,[OldTimerInterruptOffset]

MOV [ES:1Ch*4],AX

MOV AX,[OldTimerInterruptSegment]

MOV [ES:1Ch*4+2],AX

STI

POP ES

POPA

RET

ENDP RestoreOldTimerInterrupt

ENDS

END

В сегменте данных объявлен флаг состояния левой клавиши Ctrl и выделена область для хранения вектора 1Ch. Кодовый сегмент включает несколько подпрограмм. Подпрограмма TimerTest получает управление первой. Она совсем проста и единственное, что выполняет – вызов процедуры SetTimerInterrupt и затем передает управление операционной системе с помощью прерывания 27h.

В свою очередь процедура SetTimerInterrupt устанавливает новый вектор прерывания 1Ch. Здесь и далее в процедуре RestoreOldTimerInterrupt используется иной способ замены вектора. Вместо функций 25h и 35h, рассмотренных в примере 2, показано вычисление вектора 1Ch и установка нового обработчика прерывания.

Резидентная часть представлена подпрограммой TimerInterrupt. Вначале анализируется комбинация «Ctrl+x» и разрешаются прерывания с более низким приоритетом. Если комбинация не выбрана, управление передается на выполнение «полезной» части резидента. Затем происходит выход из подпрограммы обработки прерывания. Если клавишная комбинация выбрана, происходит вызов процедуры RestoreOldTimerInterrupt для восстановления прежнего вектора 1Ch.

Рассмотренный пример резидентной программы имеет достаточно общий характер. Тем не менее, его можно относительно легко адаптировать для решения задач в области измерительной техники. Например, применение алгоритмов программирования плат сбора данных в рамках обработчика TimerInterrupt позволит создать драйвер измерительного устройства. В его ведение может, например, входить выполнение оцифровки сигналов, поступающих от измерительных преобразователей и их первичная обработка. Причем работать драйвер будет в фоновом режиме под операционной системой MS-DOS.

Контрольные вопросы

  1. В чем назначение и каковы функции контроллера прерываний?

  2. Какие существуют типы прерываний?

  3. Как обрабатываются программные и аппаратные прерывания?

  4. Приведите примеры прерываний BIOSиMS-DOS.

12. Программирование параллельного порта

12.1. Интерфейс Centronics

Исторически параллельный интерфейс был введен в персональный компьютер для подключения принтера (аббревиатура LPT расшифровывается как Line Printer, т.е. построчный принтер). Однако впоследствии он стал использоваться для подключения других периферийных устройств (ПУ) – сканеров, дисководов типа Zip и ряда других.

Стандарт на параллельный интерфейс IEEE 1284, принятый в 1994 году, регламентирует различные режимы обмена данными, физический и электрический интерфейсы. Следующие режимы обмена данными получили наибольшее распространение:

  • Compatibility Mode – однонаправленный вывод по протоколу Centronics, который полностью соответствует стандартному порту SPP (Standard Parallel Port).

  • ЕРР (Enhanced Parallel Port) Mode – двунаправленный обмен данными, при котором управляющие сигналы интерфейса генерируются аппаратно во время цикла обращения к порту (чтения или записи в порт). Режим эффективен при работе с устройствами внешней памяти, адаптерами локальных сетей.

  • ЕСР (Extended Capability Port) Mode – двунаправленный обмен с возможностью аппаратного сжатия данных по методу RLE (Run Length Encoding), использования FIFO-буферов и режима прямого доступа в память DMA. Управляющие сигналы интерфейса генерируются аппаратно.

Базовая разновидность порта SPP позволяет передавать данные только в одном направлении – от ПК, однако позднее был разработан ряд стандартов двунаправленной передачи данных EPP и ECP. К главным недостаткам LPT порта следует отнести невысокую скорость (100÷150 Кб/сек) и необходимость привлечения ресурсов микропроцессора при передаче данных.

Стандартный LPT порт имеет 8-битную шину данных, 5-битную шину сигналов состояния и 4-х битную шину управляющих сигналов. Порт асимметричен – 12 линий работают на вывод и только 5 на ввод. Понятие интерфейса Centronics относится к набору сигналов, протоколу обмена и разъему, устанавливаемому в принтерах. Назначение сигналов и контакты разъема ПУ, на который они выведены, приведены в табл. 96.

Источник: https://files.student-it.ru/previewfile/284711