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

       

Режим 360х480 пикселов, 256 цветов


Второй рассматриваемый нами нестандартный режим может отображать 256 цветов при разрешающей способности 360х480 пикселов. Программирование этого режима является менее простыми безопасным, чем предыдущего режима, так как нам придется изменять содержимое регистров контроллера ЭЛТ, отвечающих за временные характеристики видеоадаптера. В остальном программирование видеоадаптера осуществляется по тем же правилам, что и в режиме с разрешающей способностью 320х400 пикселов.

Ниже приведена программа, которая переводит видеоадаптер в нестрандартный режим с разрешением 360х480 пикселов:

/** * Файл e256hres.c **/ #include "sysp.h" #include "sysgraph.h" #include <dos.h>

#include <graph.h> #include "vga_new.h"

/** *.Name Set360x480Mode * *.Title Установка режима 360х480 пикселов, 256 цветов. * *.Proto void Set360x480Mode( void ) * *.Params Не используются. * *.Return Не используетя. * *.Sample e256hres.c **/

void Set360x480Mode( void ) {

_asm {

// устанавливаем режим 12h, чтобы очистить видеопамять mov ax,12h int 10h

// устанавливаем стандартный режим 13h mov ax,0013h int 10h

// перепрограммируем регистр определения структуры // памяти: запрещаем адресацию к разным слоям памяти в // зависимости от кратности адреса памяти четырем (бит // D4 - chain4) mov dx,SC_INDEX mov ax,0604h out dx,ax

// производим синхронный сброс и остановку // синхронизатора mov ax,0100h out dx,ax

// адресуемся к регистру определения различных режимов // работы mov dx,MOR

// устанавливаем частоту кадров 60Кц mov al,0e7h out dx,al

// запускаем синхронизатор mov dx,SC_INDEX mov ax,0300h out dx,ax

// выбираем регистр режима работы графического // контроллера mov dx,GC_INDEX mov al,MDR out dx,al

// считываем его значение inc dx in al,dx



// выключаем доступ по четным адресам к четным слоям, а // по нечетным адресам к нечетным слоям and al,11101111 out dx,al

// выбираем регистр смешанного назначения графического // контроллера dec dx mov al,MIR out dx,al


// считываем его значение inc dx in al,dx

// сбрасываем бит управляющий сцеплением четных и // нечетных слоев and al,11111101b out dx,al

// выбираем регистр конца обратного вертикального хода // луча mov dx,3d4h mov al,11h out dx,al

// снимаем защиту от записи с регистров контроллера // ЭЛТ, имеющих индексы от 0 до 7 inc dx in al,dx and al,7fh out dx,al

dec dx

// программируем регистры контроллера ЭЛТ, втом числе // регистры, определяющие временные параметры режима

// устанавливаем регистр общей длины линии // горизонтальной развертки mov ax,06b00h out dx,ax

// устанавливаем регистр длины отображаемой части // горизонтальной развертки mov ax,05901h out dx,ax

// устанавливаем регистр начала импульса гашения луча // горизонтальной развертки mov ax,05a02h out dx,ax

// устанавливаем регистр конца импульса гашения луча // горизонтальной развертки mov ax,08e03h out dx,ax

// устанавливаем регистр начала импульса // горизонтального обратного хода луча mov ax,05e04h out dx,ax

// устанавливаем регистр конца импульса горизонтального // обратного хода луча mov ax,08a05h out dx,ax

// устанавливаем регистр числа горизонтальных линий // растра mov ax,0d06h out dx,ax

// устанавливаем дополнительный регистр mov ax,03e07h out dx,ax

// устанавливаем регистр высоты символов текста mov ax,04009h out dx,ax

// устанавливаем регистр начала обратного // вертикального хода луча mov ax,0ea10h out dx,ax

// устанавливаем регистр конца обратного // вертикального хода луча mov ax,0ac11h out dx,ax

// устанавливаем регистр начала гашения вертикальной // развертки mov ax,0df12h out dx,ax

// устанавливаем регистр логической ширины экрана mov ax,02d13h out dx,ax

// устанавливаем регистр положения подчеркивания // символа mov ax,014h out dx,ax

// устанавливаем регистр начала импульса гашения // вертикальной развертки mov ax,0e715h out dx,ax

// устанавливаем регистр конца импульса гашения // вертикальной развертки mov ax,0616h out dx,ax

// устанавливаем регистр управления режимом mov ax,0e317h out dx,ax } }



/** *.Name WritePixel_H * *.Title Отображение пиксела. * *. Descr Функция отображает на экране пиксел в заданных * координатах, определенного цвета. * *.Proto void WritePixel_H(unsigned x, unsigned y, unsigned * char color) * *.Params x - x-координата пиксела (0-319), * * y - y-координата пиксела (0-399), * * color - цвет пиксела (0-255). * *.Return Не используетя. * *.Sample e256hres.c **/

void WritePixel_H(unsigned x, unsigned y, unsigned char color) {

_asm {

push di

mov cx,x mov dx,y mov bl,color

mov ax,VGA_SEGMENT mov es,ax

mov ax,( SCREEN_WIDTH_H / 4 ) mul dx

push cx

shr cx,1 shr cx,1

add ax,cx mov di,ax

pop cx

and cl,3 mov ah,1 shl ah,cl

mov dx,SC_INDEX mov al,CPWER out dx,ax

mov es:[di],bl

pop di } }

/** *.Name ReadPixel_H * *.Title Определение цвета пиксела. * *.Descr Функция возвращает значение байта видеопамяти, * определяющего пиксел с заданными координатами. * *.Proto unsigned char ReadPixel_H(unsigned x, unsigned y, unsigned char color) * *.Params x - x-координата пиксела (0-319), * * y - y-координата пиксела (0-399). * *.Return цвет пиксела (0-255). * *.Sample e256hres.c **/

unsigned char ReadPixel_H( unsigned x, unsigned y ) {

unsigned char color;

_asm {

push si

mov cx,x mov dx,y

mov ax,VGA_SEGMENT mov es,ax

mov ax,( SCREEN_WIDTH_H / 4 ) mul dx

push cx

shr cx,1 shr cx,1

add ax,cx mov si,ax

pop ax

and al,3 mov ah,al

mov dx,GC_INDEX mov al,RPSR out dx,ax

mov al,es:[si] mov color,al

pop si }

return( color ); }

/** *.Name Full_Scr_H * *.Title Закрашивает экран заданным цветом. * *.Proto void Full_Scr_H( unsigned char color ) * *.Params color - цвет экрана (0-255). * *.Return Не используетя. * *.Sample e256hres.c **/

void Full_Scr_H( unsigned char color ) {

_asm {

push di

;разрешаем запись данных во все четыре цветовых слоя

mov dx,SC_INDEX mov al,CPWER out dx,al

mov al,0fh out dx,al

mov ax,VGA_SEGMENT mov es,ax

xor di,di mov al,color

mov cx,43200 cld rep stosb

pop di } }

// функция LoadVGA256 загружает регистры таблицы цветов // цифро-аналогового преобразователя новыми значениями



void LoadVGA256(void) {

RGB color_table[256]; unsigned char i, j; unsigned char far *ptr; unsigned seg_table,off_table;

// записываем в массив color_table новые значения для // регистров таблицы цветов

for(j = 0; j < 4; j++) { for(i = 0; i < 64; i++) { (color_table[i+j*64]).red = (j == 0) ? i : 0;

(color_table[i+j*64]).green = (j == 1) ? i : (j == 3) ? i : 0;

(color_table[i+j*64]).blue = (j == 2) ? i : (j == 3) ? i : 0; } }

ptr = (unsigned char far*) &color_table[0];

// определяем сегмент и смешение массива color_table

seg_table = FP_SEG(ptr); off_table = FP_OFF(ptr);

// загружаем новые значения в регистры таблицы цветов

SetVgaDAC(seg_table,off_table);

// функция SetVgaDAC загружает регистры таблицы цветов // цифро-аналогового преобразователя // исходный текст функции приведен при описании регистра // данных таблицы цветов ЦАП VGA (файл vga256.c) }

// // главная функция // void main( void ){

unsigned i; char ch = 13;

struct videoconfig vc;

// заполняем поля структуры vc

printf("\n (C) Frolov G.V., 1992\n\n"); _getvideoconfig( &vc );

// завершаем программу если нет VGA адаптера

if(vc.adapter != _VGA) { printf("Для выполнения программы нобходим" " адаптер VGA\n"); exit(0); }

// устанавливаем режим 360х480 пикселов, 256 цветов

Set360x480Mode();

// загружаем регистры ЦАП VGA

LoadVGA256();

for(i = 0; i < 480; i++) WritePixel_H(180, (unsigned) i, (unsigned char) (i % 256) );

for(i = 0; i < 360; i++) WritePixel_H((unsigned) i, 240, (unsigned char) (i % 256) );

ch = getch(); if( ch == 27 ) exit(1);

for(i = 0; i < 360; i++) WritePixel_H((unsigned) i, (unsigned) i, (unsigned char) (i % 256) );

ch = getch();

for(i = 0; ((i < 256) && (ch != 27)); i++) { Full_Scr_H( (unsigned char) i ); ch = getch(); }

// возвращаемся в текстовый режим

_setvideomode(_DEFAULTMODE);

printf("Привет всем!!!\n"); }


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