Режим 360х480 пикселов, 256 цветов
Второй нестандартный режим, который мы рассмотрим, может отображать 256 цветов при разрешающей способности 360х480 пикселов. Ниже приведена программа E256HRES, которая переводит видеоадаптер в нестандартный режим с разрешением 360х480 пикселов (листинг 4.18):
Листинг 4.18. Файл E256HRES.C
#include <conio.h>
#include <stdlib.h>
#include <stdio.h>
#include <dos.h>
#include "vga_new.h"
// Описание функций
void main( void );
void SetVideoMode(unsigned char);
// Следующие функции определены в файле EVGAH.ASM
void __pascal __far Set360x480Mode( void );
void __pascal __far FullScrH(unsigned char);
void __pascal __far
WritePixelH(unsigned, unsigned, unsigned char);
unsigned char __pascal __far
ReadPixelH(unsigned, unsigned, unsigned char);
// Главная функция
void main( void ){
unsigned i;
char ch = 13;
// Устанавливаем режим 360х480 пикселов, 256 цветов
Set360x480Mode();
// загружаем регистры ЦАП VGA
// LoadVGA256();
for(i = 0; i < 480; i++)
WritePixelH(180, (unsigned) i, (unsigned char)(i%256));
for(i = 0; i < 360; i++)
WritePixelH((unsigned) i, 240, (unsigned char)(i%256));
ch = getch();
if( ch == 27 ) exit(1);
for(i = 0; i < 360; i++)
WritePixelH((unsigned) i, (unsigned) i,
(unsigned char) (i % 256) );
ch = getch();
for(i = 0; ((i < 256) && (ch != 27)); i++) {
FullScrH( (unsigned char) i );
ch = getch();
}
// Возвращаемся в текстовый режим
SetVideoMode(3);
printf("\n (C) Frolov G.V., 1992\n\n");
}
//===========================================================
// Функция устанавливает режим работы видеоадаптера, заданный
// параметром vmode
//===========================================================
void SetVideoMode( unsigned char vmode ) {
union REGS inregs, outregs;
inregs.h.ah = 0x0;
inregs.h.al = vmode;
int86( 0x10, &inregs, &outregs );
}
Основные функции, предназначенные для выбора нестандартного режима с разрешением 360х480 пикселов, записи и чтения пикселов, а также заполнения экрана монитора, написаны на языке ассемблера. Исходный текст этих функций представлен в листинге 4.19.
Листинг 4.19. Файл EVGAH.ASM
TITLE EVGAH.ASM
NAME EVGAH
PAGE 55,132
P286
IDEAL
NOWARN BRK
INCLUDE "evga.inc" // Смотри листинг 4.17
SEGMENT EVGA_TEXT WORD PUBLIC 'CODE'
ASSUME cs:EVGA_TEXT
;============================================================
; void Set360x480Mode( void )
; Установка режима 360х480 пикселов, 256 цветов.
;============================================================
PUBLIC SET360X480MODE
PROC SET360X480MODE FAR
enter 0, 0
; Устанавливаем режим 12h, чтобы очистить видеопамять
mov ax,12h
int 10h
; Устанавливаем стандартный режим 13h
; (320x200 пикселов, 256 цветов)
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,11101111b
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
leave
ret
ENDP SET360X480MODE
;============================================================
; void
; WritePixelH( unsigned x, unsigned y, unsigned char color)
; Функция отображает на экране пиксел в заданных координатах,
; определенного цвета.
; x - x-координата пиксела (0-319),
; y - y-координата пиксела (0-399),
; color - цвет пиксела (0-255).
;============================================================
color EQU [bp+6]
y EQU [bp+8]
x EQU [bp+10]
PUBLIC WRITEPIXELH
PROC WRITEPIXELH FAR
enter 0, 0
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
leave
ret 6
ENDP WRITEPIXELH
;============================================================
; unsigned char
; ReadPixelH(unsigned x, unsigned y, unsigned char color)
; Функция возвращает значение байта видеопамяти,
; определяющего пиксел с заданными координатами.
; x - x-координата пиксела (0-319),
; y - y-координата пиксела (0-399).
; Функция возвращает цвет пиксела (0-255).
;============================================================
color EQU [bp+6]
y EQU [bp+8]
x EQU [bp+10]
PUBLIC READPIXELH
PROC READPIXELH FAR
enter 0, 0
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
xor ah,ah
pop si
leave
ret 6
ENDP READPIXELH
;============================================================
; void FullScrH( unsigned char color )
; Закрашивает экран заданным цветом.
; color - цвет экрана (0-255).
;============================================================
color EQU [bp+6]
PUBLIC FULLSCRH
PROC FULLSCRH FAR
enter 0, 0
;Разрешаем запись данных во все четыре цветовых слоя
push di
;Разрешаем запись данных во все четыре цветовых слоя
mov dx,SC_INDEX
mov al,CPWER
out dx,al
inc dx
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
leave
ret 2
ENDP FULLSCRH
ENDS EVGA_TEXT
END
Содержание раздела