Программирование видеоадаптеров CGA, EGA и VGA

       

Регистр сравнения линий (Line Compare Register - LCR) (индекс18h)


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

Данный регистр используют совместно с регистром начального адреса. Когда счетчик горизонтальных линий сканирования достигает значения, записанного в регистре LCR, происходит сброс счетчика адреса регенерируемой видеопамяти в ноль. В результате экран разбивается на две части, где в верхней отображаются данные, на которые указывает регистр начального адреса, а в нижней - данные, находящиеся в начале видеопамяти. На рисунке 8.8 иллюстрируется процесс разделения экрана:

Рисунок 8.8 Процесс разделения экрана.

Содержимое верхнего окна можно перемещать, изменяя содержимое регистра начального адреса.

Заметим, что у видеоадаптера EGA регистр сравнения линий состоит из 9 бит. Доступ к девятому биту возможен через дополнительный регистр (OVR) контроллера ЭЛТ. Видеоадаптер VGA имеет дополнительно еще и десятый бит, расположенный в регистре MSLR.

При изменении режима работы видеоадаптера, BIOS записывает в регистр сравнения линий значение 0FFh.

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

// пример разделения экрана дисплея на две части при помоши // регистра сравнения линий контроллера ЭЛТ

#include <dos.h> #include <stdio.h>

void Split(unsigned);

void main(void) {

int i;

// выводим на экран дисплея 25 строк текста

for(i = 0; i < 25; i++) printf("Строка номер %d.",i);

getch();



// разделяем экран по линии 200

Split(200);

getch(); // после завершения программы // значения регистров не восстанавливаются! }

/** *.Name Split * *.Title Разделение экрана. * *.Descr Функция разделяет экран на две части. Функция работает * только на EGA и VGA. * *.Proto void Split(unsigned split_line) * *.Params unsigned split_line - линия горизонтальной развертки, * в которой происходит разделение экрана дисплея. * *.Return Не используется. * *.Sample split.c **/ void Split(unsigned split_line) {


_asm {

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

xor ax,ax mov es,ax

; получаем адрес порта индексного регистра контроллера ЭЛТ ; (3B4h/3D4h), ; в монохромных режимах для адресации к индексному регистру ; используется порт с адресом 3B4h, а в цветных - порт 3D4h

mov dx,es:[463h]

; вычисляем адрес порта регистра состояния 1, ; в монохромных режимах для адресации к регистру состояния 1 ; используется порт с адресом 3BAh, а в цветных - порт 3DAh

add dx,6

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

in al,dx nop

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

test al,8 jz wait_on

wait_off:

in al,dx

; задержка

nop test al,8 jnz wait_off

wait_on:

in al,dx nop test al,8 jz wait_on

; вычисляем адрес порта индексного регистра контроллера ЭЛТ ; (3B4h/3D4h)

sub dx,6

; выбираем для обмена регистр сравнения линий

mov al,18h out dx,al

; вычисляем адрес порта регистра данных контроллера ЭЛТ, ; в монохромных режимах для адресации к регистру данных ; используется порт с адресом 3B5h, а в цветных - порт 3D5h

inc dx

; определяем линию горизонтальной развертки, в которой происходит ; разделение экрана дисплея

mov ax,split_line

; у видеоадаптера EGA регистр сравнения линий состоит из 9 бит, ; доступ к девятому биту происходит через дополнительный регистр ; контроллера ЭЛТ; ; видеоадаптер VGA имеет еще и десятый бит, расположенный в регистре ; высоты символов текста

; записываем младшие 8 битов в регистр сравнения линий

out dx,al

; вычисляем адрес порта индексного регистра контроллера ЭЛТ

dec dx

; вызываем функцию чтения конфигурации видеосистемы, ; данная функция подробно описана в главе ; "Дополнительные средства BIOS для управлния EGA и VGA"

mov ax,1A00h int 10h

; если после вызова функции регистр al не равен 1Ah, то используемый ; видеодаптер не VGA

cmp al,1Ah je vga jmp ega

vga:

; считываем в al состояние дополнительного регистра

mov al,7 out dx,al inc dx in al,dx

; модифицируем бит D4 дополнительного регистра



mov bx,split_line mov cl,4 shl bh,cl and bh,00010000b

and al,11101111b or al,bh out dx,al

; сбрасываем бит D6 регистра высоты символов текста

dec dx mov al,9 out dx,al inc dx in al,dx and al,10111111b out dx,al jmp quit_split

ega:

mov bx,split_line mov cl,4 shl bh,cl and bh,00010000b

cmp dx,3B4h ; монохромный режим? je default_1Fh ; если да, то переходим ; на метку default_1Fh ; определяем наличие улучшенного цветного дисплея по положению ; переключателей на плате EGA

mov al,es:[488h] and al,0Fh

; положение переключателей "off off on on" ?

cmp al,3 je default_1Fh

; положение переключателей "off on on off" ?

cmp al,9 je default_1Fh

; для видеосистем с монохромным или цветным дисплеями, ; дополнительный регистр по умолчанию содержит 11h

or bh,1 jmp set_overflow

; для видеосистем с улучненным цветным дисплеем или в монохромных ; текстовых режимах дополнительный регистр по умолчанию содержит ; значение 1Fh

default_1Fh:

or bh,0Fh

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

set_overflow:

mov al,07h out dx,al inc dx mov al,bl out dx,al

quit_split:

} }


Содержание раздела