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

       

Режим 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


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