Регистр сравнения линий (Line Compare Register - LCR) (индекс18h)
Позволяет разделить изображение на две независимые части. При этом одну из них можно свертывать. Содержимое другой части экрана остается на месте.
Регистр LCR используют совместно с регистром начального адреса. Когда счетчик горизонтальных линий сканирования достигает значения, записанного в регистре LCR, происходит сброс счетчика адреса регенерируемой видеопамяти в ноль. В результате экран разбивается на две части. В верхней части экрана отображаются данные, на которые указывает регистр начального адреса, а в нижней - данные, находящиеся в начале видеопамяти. Процесс разделения экрана иллюстрируется рисунком 4.7.
PICTURE._FIG_39.PCX;6";4.308";PCX
Рисунок 4.7 Процесс разделения экрана
Изображение в верхней части экрана можно перемещать, изменяя содержимое регистра начального адреса.
У видеоадаптера EGA регистр сравнения линий имеет 9 разрядов. Девятый бит регистра доступен через дополнительный регистр (OVR) контроллера ЭЛТ. Регистр сравнения линий видеоадаптера VGA имеет 10 разрядов. Десятый бит регистра LCR расположен в регистре MSLR.
При изменении режима работы видеоадаптера, BIOS записывает в регистр сравнения линий значение 0FFh.
Программа, представленная ниже, выводит на экран монитора 25 строк текста, а затем, после нажатия любой клавиши, разделяет изображение на две части.
Листинг 4.9. Файл SCRSPLIT.C
#include <dos.h>
#include <stdio.h>
#include <conio.h>
void __pascal __far Split(unsigned);
void main(void);
// Главная функция
void main(void) {
int i;
for(i = 0; i < 25; i++)
printf("Строка номер %d.\n",i);
getch();
// Разделяем экран по линии 200
Split(200);
// Ожидаем нажатие на клавиши клавиатуры
getch();
// После завершения программы значения регистров не
// восстанавливеются!
}
Для разделения изображения на экране монитора предназначена функция Split. Исходный текст этой функции представлен в листинге 4.10.
Листинг 4.10. Файл SPLIT.ASM
TITLE SPLIT.ASM
NAME SPLIT
PAGE 55,132
P286
IDEAL
NOWARN BRK
SEGMENT SPLIT_TEXT WORD PUBLIC 'CODE'
ASSUME cs:SPLIT_TEXT
;===========================================================
; void Split(unsigned split_line)
; Функция разделяет экран на две части. Функция работает
; только на видеоадаптерах EGA и VGA.
; Параметр split_line определяет линию горизонтальной
; развертки, в которой происходит разделение экрана монитора
;===========================================================
split_line EQU [bp+6]
PUBLIC SPLIT
PROC SPLIT FAR
enter 0, 0
; Устанавливаем регистр 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
; Вызываем функцию чтения конфигурации видеосистемы
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
; Определяем наличие улучшенного цветного дисплея по
; положению переключателей на плате 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,bh
out dx,al
quit_split:
leave
ret 2
ENDP SPLIT
ENDS SPLIT_TEXT
END
Содержание раздела