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

       

В этих режимах отображается цветная


В этих режимах отображается цветная графическая информация. Экран дисплея имеет разрешение 320 пикселов по горизонтали и 200 пикселов по вертикали.

В качестве дисплея могут использоваться цветной дисплей (CD), улучшенный цветной дисплей (ECD), а также некоторые многочастотные дисплеи и дисплей VGA.

При отображении могут использоваться либо четыре основных, либо четыре альтернативных цвета. Данные цвета приведены в таблице 3.3:



Стандартные цвета Альтернативные цвета
черный черный
светло-синий зелный
малиновый красный
белый коричневый
Таблица 3.3 Цветовая палитра режимов 4 и 5

В отличие от предыдущих режимов поддерживается только одна страница экрана. Ее начальный адрес равен B800:0000.



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

#include "sysp.h"

Pixel_Offs_4_5(unsigned x, unsigned y, unsigned *offset, unsigned char *shift) {

unsigned char bit_shift; unsigned byte_offset;

_asm {

; записываем в bx x-координату пиксела

mov bx,x

; запоминаем в регистре cl младший байт переменной x

mov cl,bl

; записываем в ax y-координату пиксела

mov ax,y

; вычисляем смещение байта, определяющего пиксел с ; координатами (x,y)

; ax = 100h * y

xchg ah,al

; в бит D7, регистра al, записываем младший бит ; переменной y; этот бит равен единице, если значение ; переменной y нечетное, и равен нулю, если оно четное

; al = 80h * (y&1) ; ax = ax/2 = 80h * y

shr ax,1

; bx = x + 8000h*(y&1)

add bh,al

; ax = 100h*(y/2)

xor al,al

; bx = x + 8000h*(y&1) + 100h*(y/2)

add bx,ax

; ax = 40h*(y/2)

shr ax,1 shr ax,1

; bx = x + 8000h*(y&1) + 100h*(y/2) + 40h*(y/2) = ; = x + 8000h*(y&1) + 140h*(y/2)

add bx,ax

; bx = x/4 + 2000h*(y&1) + 50h*(y/2)

shr bx,1 shr bx,1

; теперь bx содержит смещение байта, определяющего ; пиксел с координатами (x,y) относительно начала ; видеопамяти (страницы видеопамяти)

mov byte_offset,bx

; определяем биты, отвечающие за пиксел (x,y) ; записываем в регистр cl два последних бита переменной ; x

mov ah,3 and cl,ah

; cl = 3 - (x & 3)

xor cl,ah

; cl = cl * 2

shl cl,1

; регистр задает число бит для сдвига влево

mov bit_shift,cl }

*shift = bit_shift; *offset = byte_offset; }

// // главная функция //



void main(void) {

unsigned offset,i; unsigned char mask,shift,color;

unsigned char far *ptr; unsigned char current, w_pixel;

// переводим видеоадаптер в режим 4

_asm { xor ax,ax mov al,4 int 10h }

// отображаем на экране несколько точек // непосредственно через видеопамять

for(i=0;i<198;i++){

// изменяем цвет пиксела color = i % 4;

// определяем смещение (offset) и сдвиг (shift) // для пиксела с координатами x и y

Pixel_Offs_4_5(i,i,&offset,&shift);

// получаем указатель на байт, определяющий // нужный нам пиксел

ptr = (unsigned char far*) (FP_MAKE(0xB800, offset));

// получаем старое значение байта, определяющего // пиксел

current = *ptr;

// записываем в видеопамять старое значение, // но с измененными битами, отвечающими за наш // пиксел

w_pixel = (unsigned char) color << shift; *ptr = current | w_pixel; } getch(); }


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