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

0

В прикладных программах чаще всего применяются функции записи и считывания файлов. Программа SaveRusFont, приведенная на листинге 6.1, записывает в текущий каталог диска текущий шрифт MS-DOS, полученный из памяти видеоконтроллера, в двоичном представлении (файл fontO.fnt) и в виде инверсного изображения в формате BMP (файл font0.bmp). Она является упрощенным вариантом программы формирования изображения стандартных американского и русского шрифтов MS-DOS, которую я использовал для создания рис. 1.1 и 1.2, приведенных в начале главы 1 «Работа с клавиатурой».

Кроме описанных в предшествующих главах процедур общего назначения, в программе SaveRusFont используются приведенные в том же листинге 6.1 вспомогательные подпрограммы, выполняющие следующие функции:

•       процедура GrabRusFont выполняет операцию считывания шрифта из памяти видеоконтроллера (она уже была описана в главе 4 «Видеоконтроллеры»);

•       процедура ShowRusFont отображает шрифт на экран в стандартном 256-цветном режиме VGA с разрешением 320×200;

•       процедура CreateBMPFile создает на диске файл и записывает в него заголовок формата BMP;

•       процедура WriteRasterString служит для записи в файл очередной строки изображения в формате BMP RGB;

•       процедура CloseBMPFile завершает операцию записи файла изображения на диск.

Листинг 6.1. Запись русского шрифта на диск в двоичном формате и в виде инверсного изображения в формате BMP RGB

IDEAL

Р386

LOCALS

MODEL MEDIUM

; Подключить файл мнемонических обозначений

; кодов управляющих клавиш и цветовых кодов

Include "listl_03.inc"

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

Include "listl_04.inc"

SEGMENT sseg para stack ‘STACK’

DB 400h DUP(?)

ENDS

DATASEG

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

DB LIGHTCYAN,0,23

DB "ЗАПИСЬ НА ДИСК РУССКОГО ШРИФТА DOS"tO

DB LIGHTGREEN,12,20

DB "Запись шрифта в двоичный файл FDNT0.FNT",0

DB YELLOW.24,35."Ждите …".О Txt2

DB LIGHTGREEN.11.20

DB "Запись шрифта в файл BMP-типа FONT0.BMP",0

DB LIGHTGREEN.13.18

DB "Будет произведен переход в графический режим".0

DB YELLOW.24.24."Нажмите любую клавишу и ждите",0 Txt3

DB LIGHTGREEN,12,28."Запись шрифта завершена",0

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

; Буфер для сохранения шрифта (16×256 байт) Font8xl6

DB 4096 DUP(?) : Позиция отображаемого символа FontString DW ? :номер строки шрифта FontColumn DW ? ;номер колонки шрифта

; Имя для файла BMP

BMPFileName

DB ‘fontO.bmp’,0 ;имя для двоичного файла

; Кодовый номер файла FileHandTe DW 0 : Заголовок файла BMP

BMPStruct

DB ‘ВМ’ DD 153654 DW 0 DW 0 DD 54 DD 40 DD 320 DD 160 DW 1 DW 24 DD 0

DD 153600 DD 0 DD 0 DD 0 DD 0

сигнатура

размер файла в байтах

резерв

резерв

смещение области данных размер описателя изображения ширина изображения в пикселах высота изображения в пикселах число битовых плоскостей число битов на пиксел метод сжатия

размер изображения в байтах разрешение по горизонтали разрешение по вертикали число цветов в изображении число важных-цветов изображения

; Одна строка изображения в BMP-формате BMPData

DB 960 DUP(?)

; Номер выводимой строки изображения CurrentString DW ? ENDS

CDDESEG

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

PROC SaveRusFont

mov AX.DGROUP

mov DS.AX

mov [CS:MainDataSeg],AX

; Считать шрифт из видеопамяти

cal1 GrabRusFont

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

mov АХ.З int 10h

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

mov [ScreenString],25

mov [ScreenColumn],0 call SetCursorPosition

; Записать шрифт на диск в двоичном формате

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

; Записать шрифт в файл fontO.fnt

mov DX,offset Font8xl6 call WriteFontFile

; Предупредить пользователя о начале продолжительной

; по вренени операции записи файла BMP-типа на диск call ClearScreen MShowColorString Txtl MShowColorText 3,Txt2 cal1 GetChar

; Установить видеорежии VGA 320×200, 256 цветов

mov AX,13h int lOh

; Для наглядности отобразить шрифт на экране

; (8 строк по 32 символа) cal1 ShowRusFont

; Создать файл font0.bmp и записать заголовок файла

call CreateBMPFile

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

; Вывод начинается с НИЖНЕЙ строки рисунка

mov [CurrentString],160

mov AX.OAOOOh

mov ES.AX

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

@@P0:

; Вычислить координаты начала экранной строки

mov АХ,320

mov DX,[CurrentStri ng] dec DX mul DX

; В SI записать указатель на строку экрана

mov SI.АХ

; В DI записать указатель на строку BMP

mov DI,offset BMPData

; Сформировать строку BMP с инверсией цвета точек

mov СХ.320 ;счетчик пикселов Р0Р1:

mov AL,[ES:SI] cmp AL,0

je

@@P2;на экране черная точка?

: Записать в строку BMP черную точку

mov [word ptr DI],0

add DI,2

mov [byte ptr DI],0

inc DI

jmp short

@@P3

; Записать в строку BMP белую точку №>Z:

mov [word ptr DI].0FFFFh

add DI,2

mov [byte ptr DI],0FFh

inc DI P№3:

inc SI loop

@@P1

; Записать строку BMP-файла на диск call WriteRasterString

; Перейти на строку вверх dec [CurrentString] jnz

@@Р0

; Завершить запись ВМР-файла call CloseBMPFile

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

mov ах,3 int 10h

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

call SetCursorPosition

; Вывести сообщение о завершении записи шрифта MShowColorString Txtl MShowColorText 2,Txt3 call GetChar

@@End:

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

mov ax,3 int lOh

; Выход в DOS

mov AH,4Ch int 21h ENDP SaveRusFont

;* СЧИТЫВАНИЕ "РУССКОГО" ШРИФТА ИЗ ВИДЕОКОНТРОЛЛЕРА *

PROC GrabRusFont near pushad

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

; Перепрограммировать синхронизатор cl 1

mov DX,3C4h

; Установить последовательную адресацию

; ячеек видеопаияти

mov AX.0704h

out DX.AX

sti

; Перепрограммировать графический контроллер

mov DX,3CEh

; Выбрать для считывания плоскость 2

mov AX,0204h out DX.AX

; Запретить четную-нечетную адресацию

mov AX.0005h out DX.AX

; Установить окно доступа по адресу AOOOOh

mov AX.0006h out DX.AX

: Скопировать шрифт в буфер Font8xl6

mov AX.OAOOOh

mov ES.AX

mov SI.O

mov BX,offset Font8xl6

mov DX.256 0@MO:

mov CX.16

mov AL,[ES:SI]

mov [BX],AL

inc BX

inc SI loop

@@M1

add SI.16 dec DX jnz (а@М0 popad ret

ENDP GrabRusFont

;* ОТОБРАЗИТЬ ШРИФТ НА ЭКРАНЕ В РЕЖИМЕ 320 X 200 *

PROC ShowRusFont near pusha

pushES

movAX.OAOOOh

movES.AX

movSI.offset FontBxl6

xorDI.DI

mov [FontString],О

mov DL,0 ;цвет фона символа

mov DH.15 ;цвет символа

@@m0:

mov [FontColumn],О

push DI

@@ml:

; Отобразить очередной символ

mov АН,16 ;число строк в маске символа @вп2:

; Отобразить строку изображения символа

mov AL,[SI] загрузить очередной байт маски

mov СХ,8

РйпЗ:

; Вывести на экран очередную точку изображения rol AL.1 jc

@@m4

mov [ES:DI],DL

jmp short

@@m5

@@m4:

mov [ES:DI],DH 0йп5:

inc DI loop

@@m3

inc SI

add DI,320-8 dec AH jnz

@@m2 sub DI.320*16-8-2

inc [FontColumn] cmp [FontColumn],32 jb P@ml pop DI

add DI,320*(16+4)

inc [FontString]

cmp [FontString],8

jb

@@m0

pop ES

popa

ret

ENDP ShowRusFont

;* ОТКРЫТЬ BMP-ФАЙЛ И ЗАПИСАТЬ ЕГО ЗАГОЛОВОК *

PROC CreateBMPFile NEAR pusha

: Создать файл для записи

mov AH,3Ch

mov CX.O

mov DX,offset BMPFileName int 21h

mov [FileHandle],AX

; Записать заголовок BMP-файла

mov ВХ,[FileHandle]

mov CX.54

mov DX,offset BMPStruct

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

mov AH,40h int 21h popa ret

ENDP CreateBMPFile

 ***** * AAA ***************************************A A A A A

;* ЗАПИСАТЬ СТРОКУ РАСТРОВОГО ИЗОБРАЖЕНИЯ В BMP-ФАЙЛ *

. ************************************************АА***

PROC WriteRasterString NEAR pusha

; Записать блок данных

mov BX.CFileHandle]

mov CX.960

mov DX,offset BMPData

mov AH,40h

int 21h

popa

ret

ENDP WriteRasterString

;********************

;* ЗАКРЫТЬ BMP-ФАЙЛ * ;********************

PROC ClOseBMPFile NEAR pusha

; Закрыть файл

mov AH,3Eh

mov BX.CFileHandle]

int 21H

popa

ret

ENDP CloseBMPFile ENDS

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

Include "listl_02.inc"

: Подключить процедуры чтения/записи шрифта на диск

Include "list6_02.inc"

END

Стандартный графический режим VGA с номером 13h используется в программе для большей наглядности. На самом деле изображение может быть сформировано в любом свободном участке оперативной памяти, и отображать его на экран совершенно не обязательно, хотя и полезно при отладке программы. Формирование и вывод в файл строк изображения выполняется поочередно. Это простой, экономичный (с точки зрения использования оперативной памяти), но довольно неэффективный способ работы: запись на диск осуществляется крайне медленно. При формировании строки изображения цвет инвертируется (черный цвет заменяется белым и наоборот), а затем вместо кода цвета подставляется реальное значение яркостей цветовых компонент режима RGB: 0, 0, 0 для черного и OFFh, OFFh, OFFh для белого цвета.

Процедура записи шрифта в файл в простом двоичном коде Read- FontFile и процедура считывания шрифта из файла WnteFontFile будут применяться в последующих примерах, поэтому они выделены в отдельный модуль, приведенный в листинге 6.2. Программа SaveRusFont использует только процедуру записи шрифта (листинг 6.1).

Процедуры из листинга 6.2 записывают и считывают файл целиком, за один этап. Такой способ гораздо эффективнее, чем работа по кусочкам, однако он не всегда возможен: размер файла передается через регистр СХ и потому ограничен предельным значением 16-разрядного числа (65 535). Если необходимо при помощи функций DOS обрабатывать файл большого объема, то делать это неизбежно приходится по частям. Поскольку при работе с дисками минимальной адресуемой единицей для операционной системы является кластер, то размер считываемого или передаваемого за одну операцию участка файла с целью ускорения работы системы выравнивается на максимально возможный размер кластера (32 768 байт).

Листинг 6.2. Запись шрифта в файл и считывание шрифта из файла в двоичном формате

DATASEG

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

DB 12,23

DB "Ошибка при записи файла fontO.fnf.O RdErr

DB 12,20

DB,"He удается открыть файл шрифта fontO.fnf.O : Имя для двоичного файла, содержащего шрифт BinFileName

DB ‘fontO.fnf.O ENDS

CODESEG

;* ЗАПИСАТЬ ШРИФТ В ДВОИЧНЫЙ ФАЙЛ*

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

;* DS:DX – указатель на массив шрифта.*

- ******АААА ААААААААААААААА*ААААА********

PROC WriteFontFile NEAR

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

; Создать файл для записи push DX

mov AH.3Ch

mov CX.O ;доступ без ограничений

mov DX.offset BinFileName ;имя файла int 21h jc PPErr

mov BX.AX ;запомнить Handle в BX pop DX

: Записать данные в файл

mov СХ.4096 :разнер файла в байтах

mov AH.40h

int 21h

jc №Err

: Закрыть файл

mov AH,3Eh

int 21H

jc №Err

popa

ret

Аварийный выход – ошибка при записи файла @PErr: MFatalError WrErr ENDP WriteFontFile

•    к к к к к к к ‘к к А’ "А к к к к кк к А А АА ккккккккккккккккк

* ПРОЧИТАТЬ ШРИФТ ИЗ ФАЙЛА * ;* Параметры:*

;* DS:DX – указатель на нассив шрифта. *

•    кк к к к к к ккк к к А к к А* к к к к к к кк к к к к к к к кк к к А ккк

PROC ReadFontFile NEAR pusha

; Открыть файл для чтения push DX

mov AH,3Dh

mov AL.O ;доступ "только для чтения"

mov DX. off set BinFileName -.имя файла int 21h jc

@@Err

mov BX.AX ;запомнить Handle в BX pop DX

; Прочитать данные из файла

mov СХ.4096 ;размер файла в байтах

mov АН,3Fh

int 21h

jc

@@Err

: Закрыть файл

mov AH,3Eh

int 21H

jc (а@Егт

рора

ret

: Аварийный выход  ошибка при чтении файла

@@Err: MFatalError RdErr ENDP ReadFontFile ENDS

ПРИМЕЧАНИЕ

Запускать пример из листинга 6.1 можно на любом АТ-совместимом компьютере как с жесткого, так и с гибкого диска. Запись выполняется медленно — операция занимает несколько секунд даже при использовании жесткого диска (слишком медленно работают функции DOS). При запуске программы с гибкого диска снимите защиту записи.

Программа PCX256FontImage, приведенная в листинге б.З, считывает из файла fontO.fnt шрифт в двоичном формате, формирует в оперативной памяти (без отображения на экране монитора) 256-цветное изображение, преобразует его в формат PCX по описанному в главе 4 «Видеоконтроллеры» алгоритму, присоединяет таблицу палитры текстового режима VGA и сохраняет полученный результат в файле font0.pcx. Программа использует вспомогательную процедуру CreateFontImage, формирующую цветное изображение шрифта путем увеличения на единицу кода цвета для каждого очередного символа, и процедуру WritePCXFile, предназначенную для записи изображения в файл.

Листинг 6.3. Запись изображения русского шрифта в РСХ-файл

IDEAL РЗВ6 .LOCALS MODEL MEDIUM

; Подключить файл мнемонических обозначений

; кодов управляющих клавиш и цветовых кодов

Include "listl_03.inc"

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

Include "listl_04.inc"

SEGMENT sseg para stack ‘STACK’

DB 400h DUP(?)

ENDS DATASEG

: Текстовые сообщения TxtO

DB LIGHTCYAN.0,18

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

DB "СОЗДАНИЕ ИЗОБРАЖЕНИЯ ШРИФТА В ВИДЕ PCX-ФАЙЛА",О

DB YELLOW,24.35."Ждите …",0 Txtl

DB LIGHTGREEN,12.21

DB "Изображение записано в файл font0.pcx".0

DB YELLOW,24,29,"Нажмите любую клавишу".0 : Буфер для сохранения шрифта (16×256 байт) FontBxl6

DB 4096 DUP(?)

; Позиция отображаемого символа FontString DW ? ;номер строки шрифта FontColumn DW ? ;номер колонки шрифта

; Имя для файла PCX FileName

DB ‘font0.pcx’.0

; Кодовый нонер открытого файла FileHandle DW ? : Размер файла FileSize DW ? : Номер выводимой строки изображения CurrentString DW ?

; Ширина изображения ImageLength DW ?

; Высота изображения ImageHeigth DW ? ENDS

; Буфер для создания цветного изображения шрифта SEGMENT IMAGEBUF para public ‘DATA’

DB OFFFFh DUP(?)

ENDS

: Буфер для дисковых операций SEGMENT FILEBUF para public ‘DATA’

DB OFFFFh DUP(?)

ENDS CODESEG

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

• ihMrHrWW^AWW^^^^W^WrtWirhHf

PROC PCX256FontImage

mov AX.DGROUP

mov DS.AX

mov [CS:MainDataSeg],AX : Установить текстовый режии и очистить экран

mov АХ.З int 10h

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

mov [ScreenStri ng],25

mov [ScreenColumn].0 call SetCursorPosition

; Прочитать шрифт из файла

mov DX.offset Font8xl6 call ReadFontFile

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

MShowColorText 2.TxtO

; Создать цветное изображение шрифта call CreateFontlmage

; ЗАПИСЬ СЖАТЫЕХ ДАННЫХ В БУФЕР

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

push DS

mov АХ.IMAGEBUF

mov DS.AX

mov SI.0

: Настроить ES на буфер файла

mov AX.FILEBUF

mov ES.AX

; Очистить буфер

mov DI,0

mov CX.BOOOh

eld

mov AX.O rep stosw

; Пропустить заголовок

mov DI.12B ;счетчик байтов (длины файла)

; Использовать ВХ как счетчик строк изображения

mov ВХ.200

; Начало строки

@@PCXStri ngStart:

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

mov DX.320

; Начало очередной группы точек

@@NextGroup: lodsb dec DX

jz

@@0neByte :последняя точка строки cmp AL,[DS:SI]

jne

@@0neByte :y следующей точки другой цвет : Отрезок из одноцветных точек

mov CL.1

@@NextByte:

inc SI

inc CL dec DX

jz

@@EndOfSegment последняя точка строки cmp AL,[DS:SI]

jne

@@EndOfSegment последняя точка отрезка cmp CL.63 jb

@@NextByte

@@EndOfSegment:

mov AH.AL

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

mov AL.CL or AL.OCOh stosw

jmp short

@@EndGroup

; Одна отдельная точка

@@0neByte:

cmp AL.OCOh jae

@@Corr stosb

jmp short

@@EndGroup

@@Corr:

mov AH.AL

mov AL.OClh stosw

@@EndGroup:

cmp DX,0 jnz

@@NextGroup dec BX

jnz

@@PCXStringStart pop DS

; Записать признак формата регистров ЦАП

mov AX.FILEBUF

mov ES.AX

mov [byte ptr ESjDI].0Ch

inc 01 : Прочитать палитру в буфер файла

mov AX.1017h

mov BX.O

mov CX.256

mov DX.DI int lOh

; Откорректировать палитру

mov CX.768 @0ShPl: shl [byte ptr ES:DI].2

inc DI loop

@@ShPl : Запомнить размер файла

mov [FileSize],DI : Заполнить заголовок файла

mov [byte ptr ES:00h],0Ah ;сигнатура

mov [byte ptr ES:01h],5 :версия PCX

mov [byte ptr ES:02h],l уплотнение no RLE

mov [byte ptr ES:03h],8 ;битов на пиксел

mov [word ptr ES:04h],0 ;XMIN

mov [word ptr ES:06h],0 ;YMIN

mov [word ptr ES:08h],319 :XMAX

mov [word ptr ES:0Ah],199 ;YMAX

mov [byte ptr ES:41h].l ;одна плоскость

mov [word ptr ES:42h],320 ;байтов в строке

mov [word ptr ES:44h],l ;цветное изобр.

; Записать файл на диск

call WritePCXFile

; Вывести сообщение о завершении записи MShowColorText 2,Txtl call GetChar

@@End:

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

mov ax,3 int lOh

; Выход в DOS

mov AH.4Ch int 21h ENDP PCX256FontImage

•* ОТОБРАЗИТЬ ШРИФТ НА ЭКРАНЕ В РЕЖИМЕ 320X200 *

PROC CreateFontlmage near pusha

push ES

: Настроить ES:DI на область, предназначенную для : создания изображения

mov АХ,IMAGEBUF

mov ES.AX

mov SI,offset Font8xl6 xor DI,DI : Очистить область изображения

mov AX.O

mov CX,8000h rep stosw

; Вернуть указатель в начало области

xor DI,DI

; Создать цветное изображение шрифта

mov [FontString],0

mov DL.0 :цвет фона синвола

mov DH.0 :цвет синвола

@@m0:

mov [FontColumn],0

push DI @вп1: : Отобразить очередной символ

mov АН,16 ;число строк (байтов) в иаске @ftn2:

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

mov AL,[SI] загрузить очередной байт маски

mov СХ.8 @ftn3:

; Вывести на экран очередную точку

; изображения синвола rol AL.1 jc

@@m4

mov [ES:DI],DL

jmp short @йтб

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

<a@m4: mov[ES:DI].DH

@&тб: incDI

loopPftn3 ;конец цикла по строке наски

incSI

addDI.320-8

decAH

jnz@@m2 ;конец цикла рисования синвола

incDH ;выбрать следующий оттенок палитры

subDI.320*16-6-2

inc[FontColumn]

cmp[FontColumn],32

jbPftnl :конец цикла no строке таблицы

popDI

addDI,320*(16+4)

inc[FontString]

cmp[FontString],8

. jb@йл0 ;конец цикла рисования изображения

popES popa ret

ENDP CreateFontlmage

• "kk к kk’kkkkk’k’kkkkk A A AAA А ‘AAA к к A"k’k $t

•* ЗАПИСАТЬ ИЗОБРАЖЕНИЕ В ФАЙЛ *

. ***************** А А А А А к к к к А А к к к

PRX WritePCXFile NEAR pusha

; Создать файл для записи

mov AH,3Ch

mov СХ.О

mov DX,offset FileName int 21h

mov [FileHandle],AX

: Записать данные в файл

mov ВХ,[FileHandle]

mov CX,[FileSize]

mov DX.O

push DS

mov AX.FILEBUF

mov DS.AX

mov AH,40h

int 21h

pop DS

; Закрыть файл

mov AH,3Eh

mov BX,[FileHandle]

int 21H

popa

ret

ENDP WritePCXFile ENDS

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

Include "listl_02.inc"

: Подключить процедуры чтения/записи шрифта на диск

Include "list6_02.inc"

END

ПРИМЕЧАНИЕ

Для запуска примера пригоден любой АТ-совместимый компьютер; запуск можно производить как с жесткого, так и с гибкого диска; перед запуском программы lst_6_03.exe необходимо создать в текущей папке файл шрифта fontO.fnt (при помощи программы lst_6_01 .ехе).

Программа ShowPCXFi 1 е, приведенная в листинге 6.4, считывает с диска 256-цветное изображение в формате PCX (файл font0.pcx), преобразует его в формат ТгиеСо1ог32 и выводит на экран. Считывание файла осуществляется при помощи процедуры ReadPCXFi 1 е, а преобразование в формат TrueColor — при помощи процедуры PCX256in- TrueColor32Mode.

Листинг 6.4. Вывод на экран 256-цветного РСХ-файла в режиме TrueColor32

IDEAL

Р386

LOCALS

MODEL MEDIUM

: Номер видеорежима заранее не известен GraphicsMode equ О

; Логическая ширина строки в пикселах LogicalStringLength equ 1024

; Ширина экрана в пикселах ScreenLength equ 640 : Высота экрана, строк ScreenHeigth equ 480

; Подключить файл мнемонических обозначений

; кодов управляющих клавиш и цветовых кодов

Include "listl_03.inc" : Подключить файл макросов

Include "listl_04.inc"

DATASEG

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

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

Txtl

DB 0.9."ВЫВОД НА ЭКРАН 256-ЦВЕТНОГО PCX-ФАЙЛА "

DB "В РЕЖИМЕ TRUEC0L0R32",0

DB 29.29,"Нажните любую клавишу".0 Errl

DB 12,25,"Не удается открыть файл шрифта",0 : Имя файла PCX

FileName

DB ‘fontO.рсх’.0

; Кодовый ноиер открытого файла

FileHandle DW ?

; Размер файла

FileSize DW ?

; Номер выводиной строки изображения

CurrentString DW ?

; Ширина изображения

ImageLength DW ?

: Высота изображения

ImageHeigth DW ?

; Смещение таблицы палитры от начала РСХ-файла

PaletteOffset DW ?

ENDS

SEGMENT sseg para stack ‘STACK1

DB 400h DUP(?)

ENDS

; Буфер для PCX-файла SEGMENT FILEBUF para public ‘DATA’

DB OFFFFh DUP(?)

ENDS CODESEG

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

PROC ShowPCXFile

mov AX,DGROUP

mov DS.AX

mov [CS:Mai nDataSeg],AX

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

mov АХ.З int lOh

; "Захватить" текстовый шрифт

call GrabRusFont

; Установить видеорежин

call SetTrueColor32

; Установить режим пряной адресации памяти call Initialization

; Установить серый цвет фона

mov [dword ptr DefaultBackground],404040h

; Установить белый цвет текста

mov [dword ptr DefaultColor],OFFFFFFh : Закрасить экран в заданный цвет фона

mov ECX.ScreenHeigth shl ЕСХ,10

mov EDI,[LinearVideoBuffer]

mov EAX.[DefaultBackground]

@@NPix:

mov [GS:EDI],EAX

add EDI.4 dec ECX jnz

@@NPix : Отобразить текстовые сообщения

MGShowText 2.Txtl : Прочитать с диска и отобразить РСХ-файл call PCX256i nTrueColor32Mode

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

mov АХ.З int 10h

; Выход в DOS

mov AH,4Ch int 21h ENDP ShowPCXFile

;* ЧИТАТЬ PCX-ФАЙЛ В БУФЕР FILEBUF *

• А АА АЛ А АА’А’А’Л’А! А’ к А’ А А А* А ‘к А’ А* A’ к к кк к к к "А1 к’ к "А"А’

PROC ReadPCXFile NEAR pusha

; Очистить перененные

mov [FileHandle],0

mov [FileSize],0 : Открыть файл для чтения

mov AH,3Dh

mov AL.O

mov DX,offset FileName int 21h jc

@@Err

mov [FileHandle].AX ;запоинить Handle : Получить длину файла, установив указатель на его конец

mov AH.42h

mov AL.2

mov BX.[FileHandle] xor CX.CX xor DX.DX int 21h jc

@@Err cmp DX.O

1РОДОЛЖвНИв #

jne

@@Err ;разнер файла превышает 64 кб : Запомнить размер файла

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

mov [FileSize],АХ

; Вернуть указатель в начало файла

mov AH,42h

mov AL,О

mov BX,[FileHandle] xor CX.CX xor DX.DX int 21h jc

@@Err

; Прочитать файл в буфер FILEBUF

mov BX,[FileHandle] pusha

push DS

mov AX.FILEBUF

mov DS.AX xor DX.DX

mov CX.BOOOh

mov AH,3Fh int 21H pop DS popa

jc

@@Err

; Закрыть файл

mov AH.3Eh

mov BX.[FileHandle]

int 21H

jc

@@Err

popa

ret

; Аварийный выход – ошибка при чтении файла

@@Err: MFatalError Errl ENDP ReadPCXFile

‘;* ПОКАЗАТЬ PCX-ИЗОБРАЖЕНИЕ В РЕЖИМЕ TRUECOLOR *

PROC PCX256i nTrueColor32Mode NEAR

pushad : Прочитать файл

call ReadPCXFile

; Настроить пару регистров ES:SI на область изображения

mov АХ,FILEBUF

mov ES.AX

mov SI,128

; Вычислить ширину и высоту изображения

mov АХ,[ES:42h]

mov [ImageLength],AX

mov AX,[ES:0Ah] sub AX,[ES:6]

1пс АХ

mov [ImageHeigth],AX

; Вычислить смещение палитры от начала файла

mov AX,[FileSize] sub АХ.768

mov [PaletteOffset]„AX

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

; Установить в качестве начальной строки : изображений 64-ю строку растра

mov EDI.64 shl EDI.12

: Прибавить адрес видеобуфера

add EDI,[LinearVideoBuffer]

: Цикл по строкам изображения

@@StringStart:

mov DX,[ImageLength] push EDI PONextDataByte:

; Занести в CX единицу

mov CX.l

mov AL.[ES:SI]

inc SI

; Проверить признак того, что байт является

: счетчиком пикселов

test AL.10000000b

jz

@@LoadRealColor

test AL,1000000b

jz

@@LoadRealColor

; Занести счетчик в CX

and AL.111111b

mov CL.AL

xor CH.CH

; Занести в AL код цвета

mov AL,[ES:SI]

inc SI

: Взять из таблицы палитры реальные значения

; цветовых компонент

@@LoadRealColor:

; Умножить код цвета на 3 и занести в ВХ

хог АН.АН

mov ВХ.АХ

shl АХ.1

add ВХ.АХ

: Прибавить к ВХ смещение таблицы

add ВХ,[PaletteOffset]

: Занести в ЕАХ цвет, при загрузке изменяя

; порядок компонент на обратный

хог ЕАХ.ЕАХ

mov AX,[ES:BX]

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

xchg AL.AH shl ЕАХ,8

mov AL,[ES:BX+2]

; Перейти к следующему пикселу PONextPixel:

mov [GS:EDI],ЕАХ

add EDI,4 dec DX

jz

@@NextString loop

@@NextPixel

jmp short

@@NextDataByte

; Перейти к следующей строке PPNextStnng:

pop EDI

add EDI,4*LogicalStringLength dec [ImageHeigth]

jnz

@@StringStart ;конец внешнего цикла

; Ожидать нажатия любой клавиши call GetChar popad ret

ENDP PCX256i nTrueColor32Mode ENDS

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

Include "listl_02.inc"

; Подключить подпрограмму, переводящую сегментный : регистр GS в режим линейной адресации

Include "list2_01.inc"

: Подключить набор процедур общего назначения,

; предназначенных для установки графических

; видеорежинов и работы в них

Include "list4_02.inc"

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

; предназначенных для режимов TrueColor32

Include "list4_07.inc"

END

ПРИМЕЧАНИЕ

Данный пример предъявляет к оборудованию повышенные требования: для запуска примера в компьютере должен быть установлен видеоконтроллер, имеющий VESA BIOS версии не ниже 2.0, способный работать с видеорежимами TrueColor32 и имеющий не менее 4 Мбайт памяти. Запуск программы lst_6_04.exe можно производить как с жесткого диска, так и с гибкого диска; перед запуском необходимо создать в текущем каталоге файл font0.pcx при помощи программы lst_6_03.exe.

В листинге 6.5 приведен более сложный пример, объединяющий в себе разнообразные приемы работы, описанные в предыдущих разделах. Программа FontEditor представляет собой упрощенную версию ‘ редактора растрового шрифта VGA 8×16. Программа использует описанные выше процедуры общего назначения (в том числе — для работы в режиме линейной адресации памяти), а также ряд вспомогательных функций:

•       процедура ShowFontTabl е предназначена для отображения редактируемого шрифта на экран в виде таблицы кнопок (16×16), которая служит для выбора редактируемого символа и располагается в правом верхнем углу экрана;

•       процедура ShowEditedChar отображает текущий символ шрифта в увеличенном в 16 раз масштабе в левой верхней части экрана;

•       процедура DrawMouseCursor выводит на экран указатель мыши, предварительно сохраняя расположенный под ним фон;

•       процедура DeleteMouseCursor стирает курсор мыши с экрана путем восстановления фона;

•       процедура ShowNewMouseCursorPosition обеспечивает перерисовку курсора в новой позиции экрана и предназначена для совместной работы с драйвером мыши MS Mouse из листинга 5.1 (см. главу 5 «Работа с мышью»);

•       процедура TestRegion позволяет определить, в какой области экрана находился курсор в момент нажатия одной из кнопок мыши;

•       процедура DrawButtons обеспечивает перерисовку управляющих кнопок с отображением их состояния (нажатая кнопка подсвечивается);

•       процедура CopyCharMask копирует маску редактируемого символа из массива шрифта в маску текущего символа;

•       процедура SaveCharMask копирует результат редактирования из маски текущего символа в массив шрифта;

•       процедура WaitOlSec обеспечивает задержку гашения нажатой управляющей кнопки примерно на 0,1 с.

После запуска программа-редактор считывает из текущего каталога файл шрифта fontO.fnt и переходит в графический 256-цветный режим с линейной адресацией памяти. Чтобы выбрать символ в качестве текущего, нужно установить курсор на его позицию в таблице шрифта и щелкнуть левой кнопкой мыши. Символы в таблице расположены по порядку ASCII-кодов, слева направо, сверху вниз.

Чтобы изменить маску текущего символа, нужно выбрать его в качестве текущего (изображение маски символа после этого появится в окне редактирования), установить курсор на надпись Редактировать и щелкнуть левой кнопкой мыши. После этого надпись зажигается (считается, что нажата кнопка Редактировать). Собственно редактирование маски осуществляется установкой курсора мыши на квадратик увеличенного изображения символа, который соответствует некоторой точке маски, и щелчком левой или правой кнопки мыши. Щелчок левой кнопки приводит к установке соответствующего бита маски в состояние 1 (квадратик зажигается), а щелчок правой — к сбросу бита в 0 (квадратик гаснет). После завершения редактирования нужно установить курсор на надпись Запомнить и щелкнуть левой кнопкой мыши. Если при выборе символа или в процессе редактирования была допущена ошибка, то можно вместо надписи Запомнить выбрать надпись Отменить.

Чтобы сохранить текущее состояние шрифта на диске, щелкните левой кнопкой мыши на надписи Сохранить шрифт (в левом нижнем углу экрана). Для завершения работы с программой щелкните левой кнопкой мыши на надписи Выйти из программы (в правом нижнем углу экрана). Если программа находится в режиме редактирования символа, то кнопки меню Сохранить шрифти Выйти из программы заблокированы (программа не реагирует на их нажатие). Программа записывает результат редактирования в тот же самый файл fontO.fnt, из которого берет исходный вариант шрифта. Поэтому, если отредактированный шрифт необходим для работы, скопируйте его в файл с другим именем, чтобы случайно не стереть с него информацию при запуске демонстрационных примеров из данного раздела.

Листинг 6.5. Программа для редактирования шрифта 8×16

IDEAL

Р386

LOCALS

MODEL MEDIUM

; Режим 640×480. 256 цветов GraphicsMode equ 4101h

; Логическая ширина экрана в пикселах LogicalStringLength equ 1024 ,- Физическая ширина -экрана в пикселах ScreenLength equ 640

; Высота экрана, строк

ScreenHeigth . equ 480

; Подключить файл нненонических обозначений

; кодов управляющих клавиш и цветовых кодов

Include "listl_03.inc"

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

Include "listl_04.inc"

DATASEG

; Редактируемый шрифт

EditedFont

DB 4096 DUP(?)

; Редактируемый символ

EditedChar

DB 16 DUP(?)

; Смещение редактируемого символа в шрифте

EdChOffset DW ?

: Номер строки "активного" символа ActiveCharString DW ?

; Номер колонки "активного" символа ActiveCharColumn DW ?

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

DB 17,14."Окно",0

DB 18,9."редактирования",0

DB 25,36,"Для выбора символа в таблице "

DB "используйте",0 ОВ 26,46,"левую клавишу мыши",0 Errl

DB 12,26,"Мышь MS Mouse не обнаружена",0 CharMenu

DB 20,9," Редактировать ",0

DB 22,9," Отменить ",0

DB 24,9," Запомнить ".О MainMenu

DB 2В.0," Сохранить ",0

DB 29.0," шрифт ".О

DB 28.69," Выйти из ",0

DB 29,69," программы ",0

; Маска курсора мыши

MCurs

DB 8. 8, 0, 0. 0, 0. 0. 0, 0, 0, 0. 0. 0. 0. 0, 0

DB 8.15, 8. 8. 0. 0. 0. 0, 0, 0. 0. 0. 0, 0. 0, 0

DB 0. 8.15,15, 8, 8, 0. 0, 0. 0, 0. 0. 0, 0, 0, 0

DB 0. 8.15.15,15,15. 8. 8. 0. 0. 0. 0. 0. 0. 0. 0

DB 0. 0, 8.15,15,15,15,15, 8. 8. 0. 0. 0. 0, 0, 0

DB 0. 0. 8.15.15.15.15,15,15.15. 8, 8. 0, 0. 0. 0

DB 0. 0. 0, 8.15.15.15,15.15,15,15,15, 8, 8, 0, 0

DB 0. 0, 0. 8,15,15,15,15,15,15.15.15,15.15, 8. 8

DB 0. 0. 0. 0. 8.15.15.15.15,15.15.15.15,15, 8, 0

DB 0. 0. 0, 0, 8.15,15,15,15,15,15.15.15, 8, 0, 0

DB 0. 0. 0, 0. 0. 8.15.15.15.15.15.15, 8. 0. 0, 0

DB 0. 0. 0. 0. 0. 8.15,15,15,15,15.15.15. 8. 0. 0

DB 0. 0, 0. 0. 0. 0. 8.15.15,15, 8,15.15,15, 8, 0

DB 0, 0. 0. 0. 0. 0. 8.15.15, 8, 0. 8,15.15.15. 8

DB 0, 0, 0. 0. 0. 0, 0. 8, 8, 0. 0, 0. 8,15, 8, 0

DB 0. 0. 0, 0. 0, 0, 0. 8. 0. 0, 0. 0. 0. 8. 0. 0

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

; Область сохранения фона под курсором MBack

DB 256 DUP(?)

; Абсолютный адрес курсора MouseAddres DO ?

; Координаты областей (порядок: xO,yO,xl,yl)

Regionl DW 64, 0,191.255 ;окно редактирования символа

Region2 DW 256, 0,639,383 ;таблица для выбора символа

Region3 DW 72,320,175,335 ;кнопка "Редактировать"

Region4 DW 72,352.175.367 ;кнопка "Отменить"

Regions DW 72,384,175,399 :кнопка "Запомнить"

Region6 DW 0,448,104,479 ;кнопка "Сохранить"

Region7 DW 536,448,639,479 ;кнопка "Выход"

; Признаки активности кнопок

Button3Flag

DB 0

Button4Flag

DB 0

Button5Flag

DB 0

Button6Flag

DB 0

Button7Flag

DB 0

; Признак попадания курсора в заданную область RegionFlag

DB ?

; Флаг состояния программы (0 – выбор символа,

; 1 – редактирование символа) ProgramStatus

DB ? ENDS

SEGMENT sseg para stack ‘STACK’

DB 400h DUP(?)

ENDS CDDESEG

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

PROC FontEditor

mov AX,DGROUP

mov DS.AX

mov [CS:MainDataSeg] ,AX : Установить текстовый режим

mov АХ.З int lOh : Прочитать редактируемый шрифт из файла

mov DX.offset EditedFont call ReadFontFile

; Произвести поиск мыши по последовательным портам call MSMouseSearch

cmp [COMPortNum].1 ;номер порта больше 1? ja

@@MouseNotFound ;мышь не найдена

; Установить режим прямой адресации памяти call Initialization

; "Захватить" текстовый шрифт

cal 1 GrabRusFont

; Установить видеорежим

call SetVESAVideoMode

; Обнулить позицию курсора мыши

mov [XCoordinate],О

mov [YCoordinate],0

mov [01dXCoordinate],0

mov [01dYCoordinate],0

; Отобразить текстовые сообщения

; Установить черный цвет фона

mov [DefaultBackground],BLACK

; Установить зеленый цвет текста

mov [DefaultColor].LIGHTGREEN MGShowText 4.Text

; Инициализировать переменные

mov [ActiveCharString],0

mov [Act i veCha rColumn],0

mov [ProgramStatus],0

; Отобразить шрифт

cal 1 ShowFontTable

; Отобразить увеличенный символ cal1 CopyCharMask call ShowEditedChar

; Отобразить кнопки

cal1 DrawButtons

; Отобразить курсор ныши первый раз

mov [MouseCursorStatus],1 call DrawMouseCursor

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

; Цикл обработки сигналов мыши

@@MWait:

cmp [ProgramStatus],0 jne

@@Statusl

; УРОВЕНЬ 0

; Левая кнопка нажата? test [ButtonsStatus].10b jz

@@MWait

; Область кнопки "Выход"?

mov SI,offset Region7 call TestRegion cmp [RegionFlag],l

je

@@Exit

; Область кнопки "Сохранить"?

mov SI,offset Region6 call TestRegion cmp [RegionFlag],0

je

@@EdStart

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

; Записать шрифт на диск

mov[MouseCursorStatus].0

callDeleteMouseCursor ;убрать курсор

mov[Button6Flag],1 :"зажечь" кнопку

callDrawButtons ;перерисовать кнопки

movDX.offset EditedFont

callWriteFontFile сохранить шрифт

mov[Button6Flag],0 ;"погасить" кнопку

callDrawButtons ;перерисовать кнопки

callDrawMouseCursor ;перерисовать курсор

mov[MouseCursorStatus].1

jmp@@MWait

@@EdStart:

; Область кнопки "Редактировать"?

movSI.offset Region3

callTestRegion

cmp[RegionFlag],0

je@@SelectChar

; Начать редактирование символа

mov[ProgramStatus],l

mov[Button3Flag],1

mov[MouseCursorStatus] ,0

callDeleteMouseCursor :убрать курсор

callDrawButtons перерисовать кнопки

callDrawMouseCursor перерисовать курсор

mov[MouseCursorStatus], 1

jmp@@MWait

POSelectChar:

; Область таблицы символов?

movSI.offset Region2

callTestRegion

cmp[RegionFlag],0

jePPMWait : Вычислить положение символа

movAX.[XCoordinate]

subAX.[Region2]

xorDX.DX

movBX.24

divBX

mov[ActiveCharColumn].AX

movAX,[YCoordinate]

subAX,[Region2+2]

xorDX.DX

movBX.24

divBX

mov[ActiveCharString],AX

; Перерисовать таблицу и символ

mov[MouseCursorStatus].0

callDeleteMouseCursor :убрать курсор callShowFontTable ;отобразить шрифт

callCopyCharMask скопировать синвол

callShowEditedChar ;отобразить синвол

callDrawMouseCursor перерисовать курсор

mov[MouseCursorStatus],1

jmp@@MWait

: УРОВЕНЬ 1 (редактирование)

MStatusl:

; Левая кнопка нажата?

test[ButtonsStatus],10b

jzPPRightButtonTest

; Область кнопки "Отнена"?

movSI,offset Region4

callTestRegion

cmp[RegionFlag],0

je@@SaveChar

; Перерисовать таблицу и синвол

mov[MouseCursorStatus],О

callDeleteMouseCursor ;убрать курсор

mov[Button3Flag],0 ;"погасить" кнопку

mov[Button4Flag],1 ;"зажечь" кнопку

callDrawButtonsперерисовать кнопки

callShowFontTable ;отобразить шрифт

callCopyCharMask скопировать синвол

callShowEditedChar ;отобразить синвол

callWaitOlSec;задержка

iirov[Button4Flag],0 ;"погасить" кнопку

callDrawButtons;перерисовать кнопки

callDrawMouseCursor перерисовать курсор

mov[MouseCursorStatus],1

mov[ProgramStatus].0

jmp@@MWait

PPSaveChar:

; Область кнопки "Запомнить"?

movSI,offset Region5

callTestRegion

cmp[RegionFlag],0

je00EditChar_MLeft

; Запомнить синвол

callSaveCharMask

; Перерисовать таблицу и символ

mov[MouseCursorStatus],О

callDeleteMouseCursor ;убрать курсор

mov[Button3Flag],0 .-"погасить" кнопку

mov[Button5Flag],1 ;"зажечь" кнопку

callDrawButtons;перерисовать кнопки

callShowFontTable ;отобразить шрифт

callCopyCharMask скопировать символ

callShowEditedChar ;отобразить символ

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

call WaitOlSec;задержка

mov [Button5Flag].0 ;"погасить" кнопку call DrawButtonsперерисовать кнопки

call DrawMouseCursor ;перерисовать курсор

mov [MouseCursorStatus].l

mov [ProgramStatus],0 jmp

@@MWait

@@EditChar_MLeft:

mov SI.offset Regionl call TestRegion cmp [RegionF1ag],0 jz

@@MWait

; Вычислить положение пиксела в наске синвола

mov CX,[XCoordinate] sub CX.[Regionl]

shr CX.4 :разделить на ширину клетки (16)

mov DI.[YCoordinate] sub DI,[Regionl+1]

shr DI.4 :разделить на высоту клетки (16)

add DI.offset EditedChar

; Установить пиксел

mov AL,80h shr AL.CL or [DI],AL

; Перерисовать символ

mov [MouseCursorStatus],0 call DeleteMouseCursor ;убрать курсор call ShowEditedChar ;отобразить символ call DrawMouseCursor ;перерисовать курсор

mov [MouseCursorStatus].1 jmp

@@MWait PPRightButtonTest:

; Правая кнопка нажата? test [ButtonsStatus],1 jz

@@MWait

mov SI,offset Regionl call TestRegion cmp [RegionFlag].0 jz

@@MWait

; Вычислить положение пиксела в маске символа

mov CX,[XCoordi nate] sub CX.[Regionl]

shr CX.4 :разделить на ширину клетки (16)

mov DI.[YCoordinate] sub DI,[Regionl+1]

shr DI.4 ;разделить на высоту клетки (16)

add DI,offset EditedChar : Установить пиксел

mov AL.80h

shrAL.CL

notAL

and[DI],AL

; Перерисовать синвол

mov[MouseCursorStatus],0

callDeleteMouseCursor губрать курсор

callShowEditedChar ;отобразить символ

callDrawMouseCursor перерисовать курсор

mov[MouseCursorStatus],l

jmp@@MWait

@@Exit: : "Мугнуть" кнопкой "Выход"

mov [MouseCursorStatus].0 call DeleteMouseCursor ;убрать курсор

mov [Button7Flag],l ;"зажечь" кнопку call DrawButtons;перерисовать кнопки

call WaitOlSec;задержка

mov [Button6Flag],0 ;"погасить" кнопку call DrawButtons;перерисовать кнопки

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

mov АХ.З int 10h : Выход в DOS

mov AH,4Ch int 21h

; Выдать сообщение "нышь не обнаружена"

@@MouseNotFound:

MFatalError Errl ENDP FontEditor

;* ОТОБРАЗИТЬ ШРИФТ В ВИДЕ ТАБЛИЦЫ * ;* Паранетры передаются через перененные * ;* ActiveCharString и ActiveCharColumn * • ккккккккк’кккк’к к к к кккккк кккккккк кк кккккккк

PROC ShowFontTable near pushad

mov SI.offset EditedFont

mov EDI,[LinearVideoBuffer]

add EDI.256

mov [FontStringLO

; Отобразить очередную строку синволов

@@m0:

mov [FontColumn],0

; Отобразить очередной символ

@@ml:

mov DL,8 :цвет фона синвола

mov DH.15 ;цвет синвола

mov СХ,[ActiveCharString]

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

cmp [FontString].СХ jne (ФкО

mov СХ.[ActiveCharColumn] cmp [FontColumn].CX jne P@kO

mov DL.7 ;цвет фона "активного" синвола

mov DH.15 :цвет "активного" синвола

; Оставить разделительную черную строки (ФкО:

add EDI. Logi cal Stri ngLength+1

; Закрасить верхние 3 строки знакоместа : цветон фона синвола

mov AL.3

@@kl:

mov СХ.22

@@k2:

mov [GS:EDI],DL

inc EDI loop (?0k2

add EDI,LogicalStringLength-22 dec AL jnz 00kl

: Отобразить строку изображения синвола

mov АН,16 ;число строк в маске символа

@@т2:

; Закрасить фонон 7 точек слева от символа

mov СХ.7 «акЗ:

mov [GS:EDI].DL

inc EDI loop (ФкЗ

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

mov AL.[SI]

mov CX,8

@®ii3:

; Вывести на экран очередную точку изображения символа rol AL.1 jc

@@m4

mov [byte ptr GS:EDI],DL

jmp short

@@m5 @Фт4:

mov [byte ptr GS:EDI].DH P@m5:

inc EDI loop

@@m3

; Закрасить фоном 7 точек справа от символа

mov СХ.7 ША:

mov [GS:EDI].DL

inc EDI 1 oop

@@k4

inc SI

add EDI,Logi calStri ngLength-22 dec AH jnz

@@m2

; Закрасить нижние 3 строки знакоместа

: цветом фона

mov AL.3

@@к5:

mov СХ.22

@@к6:

mov [GS:EDI],DL

inc EDI loop

@@k6

add EDI,Logi calStri ngLength-22 dec AL jnz (a@k5

; Оставить разделительную черную строку

add EDI,LogicalStringLength-l

; Перейти к следующему символу

sub EDI,LogicalStringLength*24-24

inc [FontColumn] cmp [FontColumn].16 jb

@@ml : Перейти к следующей строке

add EDI,LogicalStringLength*24-24*16

inc [FontString]

cmp [FontString],16

jb PftjiO

popad

ret

ENDP ShowFontTable

•А А А А k’k A ‘A A* A A"Ar A’ AA’AA1 A1 "A A A ‘A’A ААг А’ А’ А А А’Аг^ А A’A’ к A ‘A’ ‘k’kkk’k

;’* ОТОБРАЗИТЬ СИМВОЛ В УВЕЛИЧЕННОМ МАСШТАБЕ (16:1) * ;* Номер отображаемого символа определяется*

;* перененными ActiveCharString и ActiveCharColumn *

PROC ShowEditedChar near pushad

; Отобразить символ слева сверху

mov EDI.[LinearVideoBuffer]

add EDI,64 : Загрузить указатель на маску символа

mov SI,offset EditedChar

; Отобразить символ в насштабе 16:1 (размер точки

; символа – 16×16 точек экрана)

mov DX.16 ;высота маски символа в пикселах @йпО:

; Нарисовать светло-серую разделительную полоску

mov СХ.32 P@ml:

mov [dword ptr GS;EDI],07070707h

add EDI.4 loop

@@ml

add EDI,LogicalStringLength-128

; Строку символа повторить 14 раз

mov АН,14

@@m2:

; Отображаем строку символа

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

mov AL,[SI] ;прочитать байт наски

mov СХ.8 ;ширина наски символа в точках (a@m3: rol AL.1 jc

@@m4

; Отобразить 16 точек темно-серого цвета

mov [dword ptr GS:EDI],08080807h

mov [dword ptr GS:EDI+4],08080808h

mov [dword ptr GS:EDI+8],08080808h

mov [dword ptr GS:EDI+12],07080808h

jmp short

@@m5

@@m4:

; Отобразить 16 точек белого цвета

mov [dword ptr GS:EDI],0F0F0F07h

mov [dword ptr GS:EDI+4],OFOFOFOFh

mov [dword ptr GS:EDI+8],OFOFOFOFh

mov [dword ptr GS:EDI+12],070F0F0Fh @йп5:

add EDI.16 loop

@@m3

: Перейти на следующую строку изображения символа

add EDI.LogicalStringLength-128 dec AH jnz

@@m2

; Нарисовать черную разделительную полоску

mov СХ.32 @йпб:

mov [dword ptr GS:EDI].07070707h

add EDI.4 loop

@@m6

add EDI.Logi calStri ngLength-128

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

inc SI

dec DX

jnz PftnO

popad

ret

ENDP ShowEditedChar

;* ВЫВЕСТИ ИЗОБРАЖЕНИЕ КУРСОРА МЫШИ *

• Л AAA’AAA А А А А А АА А А1 А1 А’А* А А А"А1 А А А А*’А’ А А А"

PROC DrawMouseCursor near pushad

: Вычислить адрес начальной точки для вывода маски

; Умножить длину строки на номер строки (Y) movzx EDI,[YCoordi nate] shl EDI.10

; Прибавить номер колонки (X) movzx EAX,[XCoordi nate]

add EDI,EAX

; Прибавить адрес видеобуфера

add EDI,[Li nearVideoBuffer]

; Запоннить экранный адрес курсора

mov [MouseAddres],EDI

; Записать адрес наски в индексный регистр

mov SI,offset MCurs

; Записать адрес области сохранения фона

mov ВХ,offset MBack

; Вывести изображение

mov DX.16;высота наски

@@М0:

; Вывести очередную строку наски

mov СХ.16;ширина наски

@@М1:

; Сохранить точку фона

mov AL,[GS:EDI]

mov [BXj.AL

; Проверить точку наски lodsb

and AL.AL;код цвета равен нулю?

jz

@@М2пропустить точку

mov [GS:EDI],AL ;вывести точку

@@М2: : Перейти к следующей точке

inc EDI

inc ВХ loop

@@М1

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

add EDI.LogicalStringLength-16

dec DX

jnz (a@M0

popad

ret

ENDP DrawMouseCursor

• AA A A A A ^fA’A’A’Ar’A A" A"A"A A" "A" "A A A A A A A A A A A A A A

;* СТЕРЕТЬ ИЗОБРАЖЕНИЕ КУРСОРА МЫШИ *

• А А А А Аг*А"А’А"А’А"А А’А А*АгА A А"А"А А А А А А ^А А Аг A A1 A A A’A’ifr

PROC DeleteMouseCursor near pushad

: Записать в индексный регистр экранный адрес изображения

mov EDI,[MouseAddres] : Записать адрес области сохранения

; фона в индексный регистр

mov SI.offset MBack

; Вывести исходное изображение

mov DX.16:высота наски

@@М0:

mov СХ.16;тирина наски

(а@М1: lodsb

mov [GS:EDI],AL :вывести точку

inc EDI

loop

add EDI,LogicalStringLength-16 dec DX

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

jnz <а@МО

popad

ret

ENDP DeleteMouseCursor

1* ОТОБРАЗИТЬ H080E ПОЛОЖЕНИЕ КУРСОРА *

PROC ShowNewMouseCursorPosition near call DeleteMouseCursor call DrawMouseCursor ret

ENDP ShowNewMouseCursorPosition

;* ПРОВЕРИТЬ ПОПАДАНИЕ КУРСОРА В УКАЗАННУЮ ОБЛАСТЬ *

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

;* DS:SI – указатель на область.*

PROC TestRegion near pusha

: Обнулить флаг попадания курсора в область

mov [RegionFlag],0

; Сравнить координаты курсора и области

mov АХ,[XCoordinate] cmp АХ.[SI] jb

@@End cmp AX,[SI+4] ja

@@End

mov AX,[YCoordinate] cmp AX,[SI+2] jb

@@End cmp AX,[SI+6] ja

@@End

mov [RegionFlag],l

@@End: popa ret

ENDP TestRegion

;* ОТОБРАЗИТЬ УПРАВЛЯЮЩИЕ КНОПКИ *

1 A1 A1 A1 A1 A1 A1 A ‘A"A’ к1 A" A"A ‘A’A А А к к к к1А1А1А1А1А1А1А к к к

PROC DrawButtons near pusha

; вывести кнопки редактирования сиивола

mov SI,offset CharMenu

mov [DefaultBackground],BLUE

mov [DefaultColor],LIGHTGREY cmp [Button3Flag],0 ;кнопка активна?

je(<>№0

mov[DefaultBackground],LIGHTBLUE

mov[DefaultColor],YELLOW

@@t>0: callGShowString

mov[DefaultBackground],BLUE

mov[DefaultColor],LIGHTGREY

cmp[Button4Flag],0 :кнопка активна?

je<а@Ы

mov[DefaultBackground],LIGHTBLUE

mov[DefaultColor],YELLOW

@@bl: callGShowString

mov[DefaultBackground],BLUE

mov[DefaultColor],LIGHTGREY

cmp[Button5Flag],0 :кнопка активна?

je@@Ь2

mov[DefaultBackground].LIGHTBLUE

mov[DefaultColor],YELLOW

P@b2: callGShowString : Вывести кнопки сохранения шрифта и выхода

movSI,offset MainMenu

mov[DefaultBackground],BLUE

mov[DefaultColor],LIGHTGREY

cmp[Button6Flag],0 ;кнопка активна?

je<а@ЬЗ

mov[DefaultBackground].LIGHTBLUE

mov[DefaultColor],YELLOW

@@b3: callGShowString

callGShowString

mov[DefaultBackground],BLUE

mov[DefaultColor],LIGHTGREY

cmp[Button7Flag],0 :кнопка активна?

je@@Ь4

mov[DefaultBackground].LICHTBLUE

mov[DefaultColor],YELLOW

@@b4: callGShowString

callGShowString popa ret

ENDP DrawButtons

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

PROC CopyCharMask near pushad

: Вычислить положение иаски символа в массиве шрифта

; Загрузить указатель на шрифт

mov SI.offset EditedFont

; Умножить номер строки на 16

mov АХ.[ActiveCharString]

Листинг 6.5(продолжение) shl АХ,4

; Прибавить ноиер колонки

add АХ,[Acti veCharColumn]

; Умножить на размер символа в- байтах (на 16)

shl АХ, 4

add SI .АХ

; Запомнить смещение символа в шрифте

mov [EdChOffset],SI

; Скопировать наску редактируемого символа

mov DI,offset EditedChar

mov EAX.[SI]

mov [DI],EAX

mov EAX,[SI+4]

mov [DI+4],EAX

mov EAX,[SI+8]

mov [DI+8],EAX

mov EAX,[SI+12]

mov [DI+12] .EAX popad ret

ENDP CopyCharMask

;* ЗАПОМНИТЬ НОВУЮ МАСКУ СИМВОЛА *

• A+AAAAAAAAAAAAAAAAAAAAAJiifcAA A A A A AA

PROC SaveCharMask near pushad

mov SI.[EdChOffset]

: Скопировать наску редактируемого синвола

mov DI,offset EditedChar

mov EAX.[DI]

mov [SI],EAX

mov EAX,[DI+4]

mov [SI+4],EAX

mov EAX,[DI+8]

mov [SI+8],EAX

mov EAX,[DI+12]

mov [SI+12],EAX popad ret

ENDP SaveCharMask

;*********************

;* ЗАДЕРЖКА HA 0.1 С *

;*********************

PROC WaitOlSec near pushad push ES

; Настроить ES на сегмент данных BIOS

mov АХ,О

mov ES.AX

; Запомнить текущее время

mov ЕАХ,[ES:046Ch] : Ожидать 3 "тика"

add ЕАХ.З 00dT: cmp ЕАХ,[ES:046Ch] ja

@@сГГ pop ES popad ret

ENDP WaitOlSec ENDS

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

; в текстовой режиме

Include "listl_02.inc"

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

; регистр GS в режин линейной адресации

Include "list2_01.inc"

; Подключить набор процедур общего назначения,

; предназначенных для установки графических

; видеорежинов и работы в них

Include "list4_02.inc"

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

; предназначенных для 256-цветных режимов

Include "list4_03.inc"

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

; работы с мышью типа MS Mouse

Include "list5_01.inc"

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

Include "list6_02.inc"

END

ПРИМЕЧАНИЕ

Программа редактирования шрифта предъявляет к аппаратуре следующие требования: процессор не ниже i486, видеоконтроллер должен иметь поддержку VESA BIOS 2.0.

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

По теме:

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