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

         

Структура видеопамяти для режимов 4 и 5.



Рисунок 5.1 Структура видеопамяти для режимов 4 и 5.


Если вы хотите выводить информацию на экран дисплея непосредственно через видеопамять, то необходимо уметь определять биты, которые управляют каждым пикселом изображения. В общем случае по координатам пиксела нужно вычислить адрес байта видеопамяти и номера битов в нем, управляющие данным пикселом.

Следующие формулы позволяют определить смещение байта от начала станицы видеопамяти и номера битов в нем, управляющие пикселом с координатами (x,y): Если y четное число, то смещение байта = 50h*(y/2)+(x/4) Если y нечетное число, то смещение байта = 2000h+50h*((y-1)/2)+(x/4) Номер первого бита = 7-mod(x/4)*2

В этом выражении функция mod(x/y) возвращает остаток от деления x на y.

Ниже представлена таблица соответствия значений битов, определяющих пиксел цвету пиксела: Значение битов Стандартный Альтернативный пиксела цвет цвет 00 черный черный 01 светло-синий зеленый 10 малиновый красный 11 ярко-белый коричневый



Таблица 5.1

В режимах 4 и 5 имеются два набора цветов - стандартный и альтернативный. Для выбора используемого набора цветов можно воспользоваться функцией 0Bh прерывания INT 10h.

Теперь мы приведем программу, отображающую пикселы на экране через непосредственный доступ к видеопамяти. Стержнем этой программы является функция 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(); }



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