Программирование видеоадаптеров

       

Регистр сравнения линий (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


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