Главная » Ассемблер, Железо » Примеры использования функций BIOS для работы с клавиатурой

0

Пример, показанный в листинге 1.1, предназначен для демонстрации особенностей функции 00h. Программа Testlntl6_00h выполняет одну простую операцию — отображает на экране ASCII-коды и скан-коды клавиш, которые пользователь нажимает на клавиатуре.

Программа функционирует в текстовом видеорежиме, особенности которого мы рассмотрим в главе 4 «Видеоконтроллеры». Вывод информации осуществляется напрямую в видеопамять, которая в цветном текстовом режиме размещается по адресу B8000h. Каждому символу экрана соответствует байт кода (ASCII) и байт атрибута, описывающий цвет символа и цвет фона знакоместа. Видеопамять при выводе на экран разбивается по строкам: в строке 80 символов, то есть 160 байт информации; вывод выполняется справа налево, сверху вниз. Таким образом, байт видеопамяти с нулевым номером соответствует ASCII-коду первого символа, следующий байт определяет его цвет, третий байт соответствует ASCII-коду второго символа и т. д.

Листинг 1.1. Тестирование функции ввода с клавиатуры 00h

IDEAL

Р386

LOCALS

MODEL MEDIUM

SEGMENT sseg para stack ‘STACK’

DB 400h DUP(?)

ENDS

DATASEG

; Счетчик операций нажатия/отпускания клавиш

Листинг 1.1 (продолжение) PressCounter DW ?

; Текстовые сообщения Text

DB 0.18

DB "Тестирование функции ввода с клавиатуры 00h",0

DB 2.0."ASCII-код Скан-код",0

DB 24,29,"Нажните любую клавишу",0

ENDS C0DESEG

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

PROC Testlntl6_00h

mov AX.DGROUP

mov DS.AX

mov [CS:MainDataSeg],AX

; Установить текстовый режим и очистить экран

mov АХ.З int 10h

; Скрыть курсор – убрать за нижнюю границу экрана

mov [ScreenString],25

mov [ScreenColumn],0 call SetCursorPosition

; Вывести текстовые сообщения на экран

mov СХ.З

mov SI,offset Text

@@OutText:

cal 1 ShowStn ng loop

@@0utText

; Установить начальную позицию для вывода кодов

; в нулевой колонке пятой строки

mov [ScreenString],3

mov [ScreenColumn],0

; Инициализировать счетчик операций

; нажатия/отпускания клавиш

mov [PressCounter],0

; Принять очередную пару кодов с клавиатуры

@@Next:

mov AH,0 int 16h

; Отобразить принятые коды в шестнадцатеричном виде

; Отобразить ASCII-код (начиная с 3-й колонки)

mov [Screened umn], 3 call ShowHexByte

: Отобразить скан-код (йачиная с 14-й колонки)

mov [ScreenColumn],14

mov AL.AH

cal1 ShowHexByte

; Перейти на следующую строку

inc [ScreenString]

; Увеличить значение счетчика нажатий клавиш

inc [PressCounter]

; После 20 нажатий выйти из цикла cmp [PressCounter],20 jb <a@Next

; Переустановить текстовый режим и очистить экран

mov АХ,3 int 10h

; Выход в DOS

mov AH,4Ch int 21h ENDP Testlntl6_00h ENDS

; Подключить процедуры вывода данных на экран

Include "1istl_02.inc"

END

В программе Testlntl6_00h используется несколько вспомогательных процедур, не относящихся непосредственно к клавиатурным функциям BIOS, но необходимых для отображения информации на экране. Подобные процедуры общего назначения объединены в отдельную группу, оформленную в виде подключаемого файла (include-файла), приведенного в листинге 1.2. В последующих примерах данный файл также будет использоваться, что позволяет избежать многократного дублирования кодов. Назначение подпрограмм, включенных в листинг 1.2, следующее:

•     процедура ShowASCI IChar осуществляет вывод символа в ASCII- коде в заданную позицию экрана;

•     процедура ShowHexByte отображает в заданную позицию экрана содержимое регистра AL (байт данных) в шестнадцатеричном коде;

•     процедура ShowHexWord отображает в заданную позицию экрана содержимое регистра АХ (слово данных) в шестнадцатеричном коде;

•     процедура ShowHexDWord отображает в заданную позицию экрана содержимое регистра ЕАХ (двойное слово) в шестнадцатеричном коде;

•     процедура ShowBi nByte отображает в заданную позицию экрана содержимое регистра AL (байт данных) в двоичном коде;

•     процедура ShowBi nDWord отображает в заданную позицию экрана содержимое регистра ЕАХ (двойное слово) в двоичном коде;

•     процедура ShowStnng выводит текстовую строку в заданную область экрана, причем используется цвет символов и фона, заданный по умолчанию;

•     процедура ShowText использует процедуру ShowString для вывода текста (группы строк, цвет которых определяется по умолчанию) на экран;

•     процедура ShowColorStnng выводит текстовую строку заданного цвета в заданную область экрана;

•     процедура ShowCol orText использует процедуру ShowColorString для вывода разноцветного текста (группы строк, цвет каждой из которых задается индивидуально) на экран;

•     процедура ShowASCI IField служит для вывода на экран текстового поля фиксированного размера;

•     процедура SetCursorPosition предназначена для управления положением курсора, но в данном примере используется только для того, чтобы убрать курсор за пределы экрана (сделать курсор невидимым);

•     процедура GetChar ожидает ввода любого символа с клавиатуры, а затем считывает ASCII-код и скан-код этого символа;

•     процедура Wa т tCha г проверяет наличие символа в буфере клавиатуры, и если символ есть — считывает его ASCII-код и скан-код;

•     процедура CIearScreen осуществляет очистку экрана;

•     процедура Веер предназначена для выдачи оператору звукового сигнала (обычно в случае какой-либо ошибки);

•     процедура Fatal Error осуществляет выдачу сообщения о фатальной ошибке, после чего производится экстренное (аварийное) прекращение работы программы.

Процедуры вывода информации на экран используют метод прямой

записи в видеопамять с учетом особенностей текстового режима:

•     каждый символ кодируется в видеопамяти двумя байтами: первый байт содержит код символа, а второй описывает цвет символа и фон знакоместа;

•     видеопамять отображена на адресное пространство процессора до адреса 0B8000h (для доступа к ней обычно применяются сегментный регистр ES, в который записывается число B800h, и любой индексный регистр, в который заносится смещение символа от начала видеопамяти);

•     длина одной строки составляет 80 символов (160 байт);

•     на экране помещается 25 текстовых строк.

Листинг 1.2. Процедуры ввода-вывода общего назначения для работы в цветном текстовом режиме

DATASEG

: Цвет и фон выводимого текста (по умолчанию установим

; вывод белого текста по черному фону) TextColorAndBackground

DB OFh

; Начальная позиция для вывода текстовой строки на экран ScreenString DW ? ScreenColumn DW ? ENDS

CDDESE6

; Адрес основного сегмента данных Mai nDataSeg DW ?

;*ВЫВОД БАЙТА НА ЭКРАН В КОДЕ ASCII*

;* Подпрограмма выводит содержимое регистра AL в*

;* коде ASCII в указанную позицию экрана.*

;* Координаты позиции передаются через глобальные*

;* переменные ScreenString и ScreenColumn. После*

;* выполнения операции вывода происходит автомати-*

;* ческое приращение значений этих переменных.*

PROC ShowASCIIChar near pusha

push DS push ES

mov DI,[CS:MainDataSeg]

mov DS.DI

eld

: Настроить пару ES:DI для прямого вывода в видеопамять push АХ

; Загрузить адрес сегмента видеоданных в ES

mov AX,OB800h

mov ES.AX

; Умножить номер строки на длину строки в байтах

mov АХ,[ScreenStri ng]

mov DX.160 mul DX

; Прибавить номер колонки (дважды)

add АХ,[ScreenColumn]

add AX,[ScreenColumn] : Переписать результат в индексный регистр

Листинг 1.2(продолжение)

mov DI.AX pop AX

mov AH,[TextColorAndBackground] stosw

; Подготовка для вывода следующих байтов

; Перевести текущую позицию на 2 символа влево

inc [ScreenColumn]

; Проверить пересечение правой границы экрана сшр [ScreenColumn],80 jb PPEnd

; Если достигнута правая граница экрана -

; перейти на следующую строку sub [ScreenColumn],80

inc [ScreenString]

@@End: pop ES pop DS popa ret

ENDP ShowASCIIChar

;* ВЫВОД БАЙТА НА ЭКРАН В ШЕСТНАДЦАТЕРИЧНОМ КОДЕ * ;* Подпрограмма выводит содержимое регистра AL*

;* в шестнадцатеричном коде в заданную позицию экрана. * ;* Координаты позиции передаются через глобальные * ;* переменные ScreenString и ScreenColumn. После * ;* выполнения операции вывода происходит автомати- * ;* ческое приращение значений этих переменных.*

PROC ShowHexByte near pusha

push DS push ES

; Настроить DS на глобальный сегмент данных

mov DI,[CS:MainDataSeg]

mov DS.DI eld

; Настроить пару ES:DI для прямого вывода в видеопамять push АХ

; Загрузить адрес сегмента видеоданных в ES

mov AX,0B800h

mov ES.AX

; Умножить номер строки на длину строки в байтах

mov АХ.[ScreenStri ng]

mov DX,160

mul DX

; Прибавить к полученному произведению нонер

; колонки (дважды)

add АХ,[ScreenColumn]

add АХ,[ScreenColишп]

; Переписать результат в индексный регистр

mov DI.AX

pop АХ

; Использовать цвет символов, заданный по умолчанию

mov АН,[TextColorAndBackground]

; Вывести старший разряд числа push АХ

; Выделить старший разряд shr AL.4

; Преобразовать старший разряд в код ASCII

add AL.’O’ сшр AL,’9′ jbe ШО

add А^’А’-‘Э’- 1

; Вывести разряд числа на экран

@@М0: stosw

pop АХ

; Вывести младший разряд числа

; Выделить младший разряд числа and AL.0FH

; Преобразовать младший разряд в код ASCII

add AL.’O’ стар AL,’9′ jbe

@@M1

add AL,’A’-‘9′- 1

; Вывести разряд числа на экран

@@М1: stosw

; Подготовка для вывода следующих байтов

; Перевести текущую позицию на 2 символа влево

add [ScreenColишп],2

; Проверить пересечение правой границы экрана сшр [ScreenColumn],80 jb

@@End

; Если достигнута правая граница экрана

; перейти на следующую строку sub [ScreenColumn],80

inc [ScreenString] PPEnd: pop ES pop DS popa ret

ENDP ShowHexByteпродолжение J

Листинг 1.2 (продолжение)

‘;*ВЫВОД 16-РАЗРЯДНОГО СЛОВА НА ЭКРАН*

;*В ШЕСТНАДЦАТЕРИЧНОМ КОДЕ*

;* Параметры:*

;* АХ – число, которое будет выведено на экран.*

;* Номер строки передается через глобальную*

;* переменную ScreenString, номер столбца – через* ;* переменную ScreenColumn,. цвет текста определяется *

;* глобальной переменой TextColorAndBackground.*

PROC ShowHexWord NEAR xchg AL.AH call ShowHexByte xchg AL.AH cal1 ShowHexByte ret

ENDP ShowHexWord

;*ВЫВОД 32-РАЗРЯДНОГО СЛОВА НА ЭКРАН*

;*В ШЕСТНАДЦАТЕРИЧНОМ КОДЕ*

;* Параметры:*

;* ЕАХ – число, которое будет выведено на экран. * ;* Номер строки передается через глобальную*

;* переменную ScreenString, номер столбца – через * ;* переменную ScreenColumn, цвет текста определяется * ;* глобальной переменой TextColorAndBackground. *

PROC ShowHexDWord NEAR rol ЕАХ,8 cal1 ShowHexByte rol EAX.8 cal1 ShowHexByte rol EAX.8 call ShowHexByte rol EAX.8 cal1 ShowHexByte ret

ENDP ShowHexDWord

;* ВЫВОД БАЙТА НА ЭКРАН В ДВОИЧНОМ КОДЕ * ;* Подпрограмма выводит содержимое регистра AL * ;* в двоичном коде в указанную позицию экрана. * ;* Координаты позиции передаются через глобальные * ;* переменные ScreenString и ScreenColumn. После * ;* выполнения операции вывода происходит автома- * ;* тическое приращение значений этих переменных. *

PROC ShowBinByte near pusha

push DS push ES

: Копируем отображаемый байт в BL

mov BL.AL

mov AX.[CS:MainOataSeg]

mov DS.AX

eld

; Загрузить адрес "текстовой" видеопамяти в ES

mov AX.OBBOOh

mov ES.AX

; Умножить номер строки на длину строки в байтах

mov АХ.[ScreenString]

mov DX.160 mul DX

: Прибавить дважды номер колонки

add АХ,[ScreenColumn]

add АХ.[ScreenColumn]

; Переписать результат в индексный регистр

mov DI .АХ

; Отобразить разряды числа (начиная со старшего)

mov АН.[TextColorAndBackground]

mov СХ,В ;счетчик разрядов ®Ш):

mov AL. ‘О’

; Выделить очередной разряд числа rol BL.1 jnc

@@L1

mov AL,’1′

; Вывести разряд числа на экран

@@L1: stosw

loop

@@L0

: Подготовка для вывода следующих байтов

; Перевести текущую позицию на 8 символов влево

add [ScreenColumn],8

; Проверить пересечение правой границы экрана cmp [ScreenColumn],80 jb POEnd

: Если достигнута правая граница экрана -

; перейти на следующую строку sub [ScreenColumn],ВО

inc [ScreenString] : Конец подпрограммы POEnd: pop ES pop DS popa ret

ENDP ShowBinByte

Листинг 1.2(продолжение)

. А А А А А- А A

* ВЫВОД 16-РАЗРЯДНОГО СЛОВА НА ЭКРАН В ДВОИЧНОМ КОДЕ*

;* Параметры:*

;* АХ – число, которое будет выведено на экран.*

;* Номер строки передается через глобальную*

;* переменную ScreenString. номер столбца – через*

;* переменную ScreenColишп. цвет текста определяется*

;* глобальной переменой TextColorAndBackground.*

PROC ShowBinWord NEAR rol AX,8 call ShowBinByte

inc [ScreenColumn] rol AX.8 cal1 ShowBi nByte ret

ENDP ShowBinWord

;* ВЫВОД 32-РАЗРЯДНОГО СЛОВА НА ЭКРАН В ДВОИЧНОМ КОДЕ * ;* Параметры:*

* ЕАХ – число, которое будет выведено на экран. * ;* Номер строки передается через глобальную*

;* переменную ScreenString, номер столбца – через * ;* переменную ScreenColumn, цвет текста определяется * ;* глобальной переменой TextColorAndBackground.*

PROC ShowBi nDWord NEAR rol EAX.8 call ShowBinByte

inc [ScreenColumn] rol EAX.8 call ShowBinByte

inc [ScreenColumn] rol EAX.8 call ShowBinByte

inc [ScreenColumn] rol EAX.8 call ShowBinByte ret

ENDP ShowBi nDWord

;*ВЫВОД ТЕКСТОВОЙ СТРОКИ НА ЭКРАН*

;* Все параметры передаются через одну структуру: * ;* первый байт – номер начальной строки (0-24); * ;* второй байт – номер начальной колонки (0-79): * ;* далее идет строка, ограниченная нулем.*

;* Адрес структуры передается через регистры DS:SI. *

PROC ShowString near push AX push BX push DI push ES

; Настроить регистр ES на глобальный сегнент данных

mov AX,[CS:MainDataSeg]

mov ES.AX

; Запомнить цвет текста в BL

mov BL.[ES:TextColorAndBackground]

; Настроить регистр ES на видеопамять

mov AX,0B800h

mov ES.AX eld

; Вычислить адрес для строки в видеопамяти

; Загрузить номер строки экрана в AL и

; умножить его на длину строки в байтах lodsb

; Проверка: номер строки не должен превышать

; предела нижней границы экрана

cmp AL.24

ja POError

mov АН,160

mul АН

; Переписать результат в индексный регистр DI

mov DI.AX

; Загрузить номер столбца и дважды

; прибавить его к DI

lodsb

cmp AL.79 .номер колонки не должен ja

@@Error превышать ширины экрана

mov BH.AL ;запомнить номер колонки хог АН.АН ;Обнулить АН

add DI.AX

add DI.AX

; Загрузить атрибут цвета в АН

mov AH.BL @PL1:

; Загрузить очередной символ строки в AL lodsb

; Проверка на 0 (на конец строки) and AL.AL jz @PL2

: Проверить номер колонки символа cmp ВН.79

ja POError ;нарушена правая граница экрана

; Вывести символ на экран

stosw

inc ВН увеличить номер колонки jmp

@@L1

Листинг 1.2(продолжение)

@@L2: pop ES pop DI pop BX pop AX ret

@@Error: ;Немедленный выход в DOS по ошибке

mov AH,4Ch int 21h ENDP ShowString

;*ВЫВОД ТЕКСТА (ГРУППЫ СТРОК) НА ЭКРАН*

;* ShowText использует процедуру ShowString для вывода * ;* на экран группы строк.*

;* Параметры:*

;* СХ – количество строк;*

;* DS:SI – адрес первой строки в группе.*

;* Строки должны иметь заданный для ShowString формат * ;* и располагаться в памяти последовательно.*

;* При выводе текста используются принятые по*

;* умолчанию цвет и фон.*

PROC ShowText near

; Цикл вывода строк

@@NextString:

call ShowString loop

@@NextString

; Процедура не сохраняет значения в СХ и SI ret

ENDP ShowText

;* ВЫВОД ТЕКСТОВОЙ СТРОКИ ЗАДАННОГО ЦВЕТА НА ЭКРАН * ;* Все параметры передаются через одну структуру: * ;* первый байт – атрибут цвета и фона для строки; * ;* второй байт – номер начальной строки (0-24); * ;* третий байт – номер начальной колонки (0-79); * ;* далее идет строка, ограниченная нулем.*

;* Адрес структуры передается через регистры DS:SI. *

PROC ShowColorString near push AX

; Запомнить цвет, используемый no умолчанию

mov AL.[TextColorAndBackground] push AX

; Установить цвет строки

eld

lodsb

mov [TextColorAndBackground],AL

; Использовать функцию ShowString call ShowString

; Восстановить цвет, используемый по умолчанию pop АХ

mov [TextColorAndBackground],AL

pop AX

ret

ENDP ShowColorString

;* ВЫВОД ЦВЕТНОГО ТЕКСТА (ГРУППЫ СТРОК) НА ЭКРАН * ;* ShowColorText использует процедуру ShowColorString * ;* для вывода на экран группы разноцветных строк. * ;* Параметры:*

;* СХ – количество строк;*

;* DS:SI – адрес первой строки в группе.*

;* Строки должны иметь заданный для ShowColorString * ;* формат и располагаться в памяти последовательно. * ;* При выводе текста используются принятые по*

;* умолчанию цвет и фон.*

• А’А AAA AAA AAA А’А А ‘А ‘А А"А’А А А1‘А ‘А А"А’А А’А А”А А ‘АА’А А’ А А* А А А А А1 АА

PROC ShowColorText near : Цикл вывода строк PGNextColorString:

call ShowColorString loop

@@NextCo1orString

; Процедура не сохраняет значения в СХ и SI ret

ENDP ShowColorText

•Уг Аг "АУт АтУт Аг А’ "А* А”А’ А А А1 А А А"Аг Ус A”A’ A A" Ar A A A A A"A" A A1

•* УСТАНОВИТЬ ПОЗИЦИЮ КУРСОРА * ;* Входные параметры:*

;* ScreenString – номер строки * ;* ScreenColumn – номер столбца *

< А А А-ААгА ‘А’ А’ А- А А АчЛ* А"Аг"А А’АгА’АгА ‘А А1 А1 А"АгА’А"АгА А"Аг

PROC SetCursorPosition NEAR pusha

; Вычисление линейного адреса курсора

mov АХ.[ScreenStri ng]

mov ВХ.80 mul BX

add AX,[ScreenColumn]

mov BL.AL ;запомнить младший байт : Прямой вывод позиции курсора : в регистры видеоконтроллера

mov DX,3D4h

; Вывести старший байт адреса курсора

Листинг 1.2 (продолжение)

mov AL.OEh out DX.AX

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

inc AL

mov AH.BL

out DX.AX

popa

ret

ENDP SetCursorPositlon

;* ПРИНЯТЬ СИМВОЛ ОТ КЛАВИАТУРЫ*

;* Процедура осуществляет ввод синвола с * ;* помощью функции 00h прерывания Intl6h. * ;* Для "текстовых" управляющих клавиш вместо * ;* скан-кодов используются ASCII-коды.*

;* Входных параметров нет.*

;* Функция возвращает:*

;* AL – код символа;*

;* АН – управляющий код, если в AL ноль. *

PROC GetChar NEAR

; Очистить буфер клавиатуры

@@C1earBuffer:

mov АНД int 16h jz

@@WaitChar

mov AH,0 int 16h

jmp short

@@ClearBuffer

; Ожидать нажатия клавиши и принять код символа

@@WaitChar:

mov АН,О int 16h

; Обработать принятый код and AL.AL jnz

@@Getl

ret ;(в AL – ноль, в АН – управляющий код)

@@Getl: cmp AL.32 jnb

@@Get2

: Переписать в АН управляющий код xchg AL.AH

mov AL,0

ret ;(в AL – ноль, в АН – управляющий код)

@@Get2:

mov АН.О

ret :С в AL – код буквы, в АН – ноль) ENDP GetChar

•*ПРИНЯТЬ СИМВОЛ ОТ КЛАВИАТУРЫ,*

,*ЕСЛИ ОН ЕСТЬ В БУФЕРЕ*

;* Процедура проверяет наличие символа в буфере *

;* клавиатуры и считывает его, если он есть*

;* Входных параметров нет*

;* Функция возвращает*

;* AL – код символа,*

;* АН управляющий код, если в AL ноль*

;* Если в AL и АН нули нажатий не было*

PROC WaitChar NEAR

; Проверить наличие символа в буфере клавиатуры

mov АН, 1 int 16h J z

@@NoInput : Принять символ от клавиатуры

mov АХ,О int 16h and AL.AL jnz (a@GETl

ret :в AL – ноль, в АН – управляющий код (PGGETl. cmp AL.32 jnb

@@GET2

mov AH.AL .переписать в АН управляющий код

mov AL,О

ret ,в AL – ноль, в АН – управляющий код

@@GET2

mov АН,О

ret ;в AL – код буквы, в АН – ноль

@@NoInput:

хог АХ,АХ ret ,в AL и АН – нули ENDP WaitChar

;* ОЧИСТКА ЭКРАНА В ТЕКСТОВОМ РЕЖИМЕ * ,* (процедура параметров не имеет) *

PROC ClearScreen NEAR pusha

push ES

; Настроить ES DI на "текстовую" область видеопамяти

mov AX.OBBOOh

mov ES.AX eld

mov DI,0

; Вывести 2000 "пустых" символов (ASCII код 0) с

; атрибутом "белый цвет, черный фон’

mov СХ,2000

Листинг 1.2 (продолжение)

mov AX.0F00H rep stosw pop ES popa ret

ENDP ClearScreen

;* ПОДАЧА ЗВУКОВОГО СИГНАЛА ЧЕРЕЗ ВСТРОЕННЫЙ ДИНАМИК * ;*(процедура параметров не имеет)*

PROC Веер NEAR

push АХ push DX

: Послать на терминал код "звонок" (07h)

mov АН.2

mov DL.7 int 21h pop DX pop AX ret ENDP Beep

;* ВЫВОД НА ЭКРАН ТЕКСТОВОГО ПОЛЯ ДАННЫХ * ;* Передаваемые параметры:*

;* DS:SI – указатепь на структуру данных;*

;* ВХ – смещение поля от начала структуры;*

;* СХ – длина попя в байтах.*

;* Цвет задается переменной TextColorAndBackground. * ;* Координаты позиции передаются через глобальные * ;* переменные ScreenString и ScreenColumn.*

PROC ShowASCIIField near pusha

push ES

mov AX.OBBOOh Настроить ES для прямого

mov ES.AX;вывода на экран

; Установить указатель на начало поля

add SI.BX

; Вычислить начальную позицию в видеопамяти

mov АХ,[ScreenStri ng]

mov DI.160 mul DI

add AX,[ScreenCol umn]

add AX.[ScreenColumn]

mov DI.AX

; Использовать цвет, заданный по умолчанию

mov АН,[TextColorAndBackground]

; Вывести поле на экран

@@NextChar: lodsb stosw

loop

@@NextChar pop ES popa ret

ENDP ShowASCIIField

;’* ВЫДАЧА СООБЩЕНИЯ О ФАТАЛЬНОЙ ОШИБКЕ*

;*И ЭКСТРЕННЫЙ ВЫХОД ИЗ ПРОГРАММЫ*

;* Параметры:*

;* DS:SI – указатель на строку сообщения об ошибке. * ;* представленную в формате ShowColorString.*

PROC Fatal Error near

; Переустановить текстовый режим и очистить экран

mov АХ.З int 10h : Настроить DS на глобальный сегмент данных

mov DI.[CS:Mai nDataSeg]

mov DS.DI : Вывести сообщение об ошибке красный цветок

mov [TextColorAndBackground],12 call ShowString : Переместить курсор в нижнюю часть экрана

mov [ScreenStri ng],24

mov [ScreenColumn].0 call SetCursorPosition

; Аварийный выход мз программы

mov AH,4Ch int 21h ENDP Fatal Error ENDS

Приведенная в листинге 1.2 процедура ввода символа GetChar выполняет определенные преобразования над данными, выдаваемыми функцией 00h по прерыванию Int 16h. Дело в том, что некоторые из управляющих символов, перечисленных в табл. 1.1, традиционно имеют как ASCII-коды, так и скан-коды, причем значения этих кодов не совпадают. С целью упрощения последующего анализа кодов введенных символов процедура GetChar переносит ASCII- коды символов со значениями от 0 до 20h из регистра AL в регистр АН, заменяя соответствующие скан-коды (AL при этом обнуляется). В листинге 1.3. даны мнемонические обозначения для кодов наиболее часто применяемых управляющих клавиш, которые процедура GetChar сохраняет в регистре АН (символ является управляющим,

если в регистре AL был возвращен код 0). Кроме того, в листинг 1.3 включены мнемонические обозначения цветовых оттенков, которые будут применяться во всех последующих программах, работающих в 16-цветных и 256-цветных режимах

Листинг 1.3. Мнемонические обозначения кодов управляющих клавиш и цветовых оттенков

: КОДЫ УПРАВЛЯЮЩИХ КЛАВИШ

; Для "текстовых" управляющих клавиш вместо скан-кодов

; используются ASCII-коды:

B_RUB0UT equ 8 ;забой

B TAB equ 9 табуляция

B_LF equ 10 :перевод строки

B ENTER equ 13 :возврат каретки

BESC equ 27 ;"Esc"

; Скан-коды функциональных клавиш:

F1 equ 59

F2 equ 60

F3 equ 61

F4 equ 62

F5 equ 63

F6 equ 64

F7 equ 65

F8 equ 66

F9 equ 67

F10 equ 68

: Скан-коды клавиш дополнительной клавиатуры:

В НОМЕ equ 71

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

B_UP equ 72 -.стрелка вверх

B_PGUP equ 73 ;на страницу вверх

B BS equ 75

; стрелка влево

B_FWD equ 77 ;стрелка вправо

BEND equ 79 ;перейти в конец

B_DN equ 80 ;стрелка вниз

B_PGDN equ 81 ;на страницу вниз

BINS equ 82 ;переключить режим (вставка/замещение)

B DEL equ 83 :удалить символ над курсором

; МНЕМОНИЧЕСКИЕ ОБОЗНАЧЕНИЯ ЦВЕТОВ

: "Темные" цвета (можно использовать для фона и текста)

BLACKequ 0 :черный

BLUEequ 1 ;темно-синий

GREENequ 2 ;темно-зеленый

CYANequ 3 ;бирюзовый (циан)

REDequ 4 ;темно-красный

MAGENTA equ 5 .-темно-фиолетовый

BROWNequ 6 ;коричневый

LIGHTGREY equ 7 ;серый

: "Светлые" цвета (только для текста)

DARKGREY equ В ;темно-серый LIGHTBLUE equ 9 ;синий LIGHTGREEN equ 10 ;зеленый LIGHTCYAN equ 11 ;голубой LIGHTRED equ 12 ;красный LIGHTMAGENTA equ 13 фиолетовый YELLOW equ 14 ;желтый WHITEequ 15 ;белый

Листинг 1.4 содержит набор макрокоманд, делающих более наглядными и компактными участки программного кода, в которых осуществляются операции ввода-вывода.

Листинг 1.4. Макрокоманды для вывода данных на экран

; МАКРОКОМАНДЫ ТЕКСТОВОГО РЕЖИМА

;’* ВЬВОД БАЙТА В ДВОИЧНОМ КОДЕ*

;* Параметры:*

;* SString – номер строки экрана;*

;* SColumn – номер колонки экрана;* ;* BData – отображаемый байт данных. *

MACRO MShowBinByte SString,SColumn,BData

mov [ScreenString].SString

mov [ScreenColumn],SColumn

mov AL,BData call ShowBinByte

ENDM

;* ВЫВОД 16-РАЗРЯДНОГО СЛОВА В ДВОИЧНОМ КОДЕ * ;* Параметры:*

;* SString – номер строки экрана;*

;* SColumn – номер колонки экрана;*

;* WData – отображаемое слово данных.*

MACRO MShowBinWord SString,SColumn.WData

mov [ScreenString],SString

mov [ScreenColumn],SColumn

mov AX,WData call ShowBinWord

ENDM

‘.* ВЫВОД 32-РАЗРЯДНОГО tnOBA В ДВОИЧНОМ КОДЕ * ;* Параметры:*

;* SString – номер строки экрана:*

;* SColumn – номер колонки экрана;*

;* DData – отображаемое слово данных.*

Листинг 1.4(продолжение)

MACRO MShowBinDWord SString.SColumn.DData

mov [ScreenString],SString

mov [ScreenColumn],SColumn

mov EAX.DData call ShowBinDWord

ENDM

;* ВЫВОД БАЙТА В ШЕСТНАДЦАТЕРИЧНОМ КОДЕ * ;* Параметры:*

;* SString – номер строки экрана:*

;* SColumn – номер колонки экрана; * ;* BData  отображаемый байт данных. *

MACRO MShowHexByte SString,SColumn,BData

mov [ScreenStri ng],SStri ng

mov [ScreenColumn],SColumn

mov AL.BData cal1 ShowHexByte

ENDM

;* ВЬВОД 16-РАЗРЯДНОГО СЛОВА В ШЕСТНАДЦАТЕРИЧНОМ КОДЕ * ;* Параметры:*

;* SString – номер строки экрана;*

;* SColumn – номер колонки экрана;*

;* WData – отображаемое слово данных.*

MACRO MShowHexWord SString,SColumn.WData

mov [ScreenStri ng],SStri ng

mov [ScreenColumn],SColumn

mov AX.WData call ShowHexWord

ENDM

;* ВЫВОД 32-РАЗРЯДНОГО СЛОВА В ШЕСТНАДЦАТЕРИЧНОМ КОДЕ * ;* Параметры:*

;* SString – номер строки экрана;*

;* SColumn – номер колонки экрана;*

;* DData – отображаемое слово данных.*

MACRO MShowHexDWord SString.SColumn.DData

mov [ScreenString].SString

mov [ScreenColumn],SColumn

mov EAX.DData call ShowHexDWord

ENDM

‘;* ВЫВОД БАЙТА В ДЕСЯТИЧНОМ КОДЕ*

;* Параметры:*

;* SString – номер строки экрана;*

;* SColumn – номер колонки экрана;*

;* BData – отображаемый байт данных.*

MACRO MShowDecByte SString,SColumn.BData

mov [ScreenString],SString

mov [ScreenColumn],SColumn

mov AL,BData cal1 ShowDecByte

ENDM

;* ВЫВОД 16-РАЗРЯДНОГО СЛОВА В ДЕСЯТИЧНОМ КОДЕ * ;* Параметры:*

;* SString – номер строки экрана;*

;* SColumn – номер колонки экрана;*

;* WData – отображаемое слово данных.*

MACRO MShowDecWord SString,SColumn,WData

mov [ScreenString],SString

mov [ScreenColumn],SColumn

mov AX,WData cal1 ShowOecWord

ENDM

;* ВЫВОД 32-РАЗРЯДНОГО СЛОВА В ДЕСЯТИЧНОМ КОДЕ * ;* Параметры:*

;* SString – номер строки экрана;*

;* SColumn – номер колонки экрана;*

;* DData – отображаемое слово данных.*

MACRO MShowDecDWord SString,SColumn,DOata

mov [ScreenString],SString

mov [ScreenColumn].SColumn

mov EAX,DData call ShowDecDWord

ENDM

;*ВЫВОД ТЕКСТОВОГО ПОЛЯ ДАННЫХ*

;* Параметры:*

;* SString – номер строки экрана;*

;* SColumn – номер колонки экрана;*

;* OOffs – смещение поля от начала структуры; * ;* DSize – длина поля в байтах;*

;* DS:SI – указатель на структуру данных. *

Листинг 1.4(продолжение)

MCRO MShowASCIIField SString,SColumn.DOffs,DSize

mov [ScreenStri ng],SStri ng

mov [ScreenColumn],SColumn

mov BX,DOffs

mov CX.DSize call ShowASCIIField

ENDM

•* ВЫВОД ТЕКСТОВОЙ СТРОКИ * ;* Параметры:*

;* TOffset – смещение строки. *

MACRO MShowString TOffset

mov SI.offset TOffset call ShcwString

ENDM

;* ВЫВОД ЦВЕТНОЙ ТЕКСТОВОЙ СТРОКИ * ;* Параметры:*

;* TOffset  смещение строки. *

MACRO MShowColorString TOffset

mov SI,offset TOffset call ShowColorString

ENDM

•*ВЫВОД ОДНОЦВЕТНОГО ТЕКСТА*

;* Параметры:*

;* TStrings  количество строк в тексте: * ;* TOffset  смещение первой строки текста. *

MACRO MShowText TStrings.TOffset

mov CX.TStrings

mov SI.offset TOffset cal1 ShowText

ENDM

‘;*ВЫВОД РАЗНОЦВЕТНОГО ТЕКСТА*

;* Параметры:*

;* TStrings – количество строк в тексте; * ;* TOffset – смещение первой строки текста. *

MACRO MShowColorText TStrings,TOffset

mov CX,TStrings

mov SI,offset TOffset

call ShowColorText

ENDM

•^A’AA’AititititWjtitjtitA’^itJtA’A’jtjl’ititjt^’JtitA’il’il’A’A’jtAA’il’il’jl’

\* ВЫВОД СООБЩЕНИЯ ОБ ОШИБКЕ * ;* Параметры:*

;* TOffset – смещение строки сообщения. *

MACRO MFatalError TOffset

mov SI.offset TOffset call Fatal Error

ENDM

; МАКРОКОМАНДЫ ГРАФИЧЕСКОГО РЕЖИМА

•AAA А А А’ Л А1 Л A A’^Tt’A’^A A ^’A1 A ‘A’ A A A’ A

;* ВЫВОД ТЕКСТОВОЙ СТРОКИ * ;* Параметры:*

;* TOffset – смещение строки. *

•А’А" АА* А А’А" АА’А А АА А А А АА А А А А* А А’А" АА А А"А

MACRO MGShowString TOffset

mov SI.offset TOffset call GShowString

ENDM

;*ВЫВОД ОДНОЦВЕТНОГО ТЕКСТА*

;* Параметры:*

;* TStrings – количество строк в тексте; * ;* TOffset – смещение первой строки текста. *

MACRO MGShowText TStrings.TOffset

mov CX,TStrings

mov SI,offset TOffset call GShowText

ENDM

Программа Test I ntl6_10h, показанная в листинге 1.5, демонстрирует особенности функции 10h. Основное отличие от программы в листинге 1.1 — в другом номере функции. В программе используются те же самые вспомогательные процедуры из листинга 1.2, но текстовые сообщения окрашены в разные цвета. Выделение цветом — простой и удобный прием, позволяющий оператору быстрее отыскивать на экране нужную информацию. Кроме того, различная окраска изображения позволяет избежать недоразумений при поочередном выполнении программ 1 st_l_01 и 1 st_l_03, поскольку текст сообщений в этих процедурах практически совпадает (поочередное выполнение программ 1 st_l_01 и 1 st_1_03 необходимо для сравнения между собой функций 00h и 10h).

Листинг 1.5. Тестирование функции ввода с клавиатуры 10h

IDEAL

Р386

LOCALS

MODEL MEDIUM

; Подключить файл мнемонических обозначений : кодов управляющих клавиш и цветовых кодов

Include "listl_03.inc"

; Подключить файл иакросов

Include "listl_04.inc"

SEGMENT sseg para stack ‘STACK1

DB 400h DUP(?)

ENDS

DATASEG

; Счетчик операций нажатия/отпускания клавиш PressCounter DW ?

; Текстовые сообщения Text

DB LIGHTMAGENTA.0.1B

DB "Тестирование функции ввода с клавиатуры 10h",0

DB YELLOW.2,О,"ASCII-код Скан-код".О

DB LIGHTRED.24,29,"Нажиите любую клавишу".О

ENDS CODESEG

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

PRX Testlntl6_10h

mov AX.DGROUP

mov DS.AX

mov [CS:MainDataSeg],AX

; Установить текстовый режим и очистить экран

mov АХ.З int 10h

; Скрыть курсор – убрать за нижнюю границу экрана

mov [ScreenString],25

mov [ScreenColumn].0 call SetCursorPosition : Вывести текстовые сообщения на экран

MShowColorText 3.Text : Установить белый цвет символов и черный фон

mov [TextColorAndBackground],WHITE : Установить начальную позициш для вывода кодов : в нулевой колонке пятой строки

mov [ScreenString],3

mov [ScreenColumn],0

: Инициализировать счетчик операций

; нажатия/отпускания клавиш

mov [PressCounter],О

: Принять очередную пару кодов с клавиатуры ePNext:

mov AH.lOh int 16h

; Отобразить принятые коды в шестнадцатеричнон виде

; Отобразить ASCII-код

mov [ScreenColumn],3 cal1 ShowHexByte : Отобразить скан-код

mov [ScreenColumn],14

mov AL.AH cal1 ShowHexByte

; Перейти на следующую строку

inc [ScreenString]

; Увеличить значение счетчика нажатий клавиш

inc [PressCounter]

; После 20 нажатий выйти из цикла спр [PressCounter],20 jb PPNext

; Переустановить текстовый режим и очистить экран

mov АХ,3 int 10h

; Выход в DOS

mov AH,4Ch int 21h ENDP Testlntl6_10h ENDS

; Подключить процедуры вывода данных на экран

Include "listl_02.inc"

END

Источник: Кулаков В. К90 Программирование на аппаратном уровне: специальный справочник (+дискета). 2-е издание. — СПб.: Питер, 2003. — 847 е.: ил.

По теме:

  • Комментарии