

// программа демонстрирует использование регистров таблицы цветов

#include <conio.h>
#include <stdio.h>
#include <graph.h>
#include "sysp.h"
#include "sysgraph.h"
#include <dos.h>


void SetVgaDAC(unsigned, unsigned);


main(void) {

     struct videoconfig vc;
     RGB color_table[256];
     unsigned char   i, j;
     unsigned char   far *ptr;
     int error, x_num, y_num;
     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;
          }
     }

// устанавливаем режим видеоадаптера номер 13h (256 цветов)
// данный режим поддерживается только VGA и Super VGA

     error = _setvideomode( _MRES256COLOR );

// если режим не установлен, завершаем выполнение программы

     if(!error) exit(1);

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

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

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

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

     SetVgaDAC(seg_table,off_table);

// выводим на экран вертикальные линии различного цвета,
// процессор записывает данные непосредственно в видеопамять

// получаем в ptr указатель на начало видеопамяти

     ptr = (unsigned char far*) (FP_MAKE(0xA000, 0x0));
     for(y_num = 0; y_num < 200; y_num++) {
          for(x_num = 0; x_num < 320; x_num++) {
               *ptr = (unsigned char) x_num;
               ptr++;
          }
     }

     getch();

// устанавливаем режим видеодаптера, используемый по умолчанию
     _setvideomode( _DEFAULTMODE );
}



/**
*.Name    SetVgaDAC
*.Title   Запись регистров таблицы цветов
*
*.Descr   Функция устанавливает новые значения для всех регистров
*         таблицы цветов.
*
*
*.Proto   void SetVgaDAC(unsigned seg_table, unsigned off_table)
*
*.Params  seg_table - сегмент таблицы, содержащей новые значения
*                     регистров таблицы цветов,
*
*         off_table - смещение таблицы, содержащей новые значения
*                     регистров таблицы цветов.

*.Return  Не используется.
*
*.Sample  vga256.c
**/
void SetVgaDAC(unsigned seg_table, unsigned off_table) {

     _asm {

; сохраняем регистры ds и es       

          push  ds
          push  es

          ; устанавливаем регистр es на начало оперативной памяти

          xor   ax,ax
          mov   es,ax

          ; получаем адрес порта индексного регистра контроллера ЭЛТ
          ; (3B4h/3D4h),
          ; в монохромных режимах для адресации к индексному регистру
          ; используется порт с адресом 3B4h, а в цветных - порт 3D4h

          mov   dx,es:[463h]

          ; вычисляем адрес порта регистра состояния 1,
          ; в монохромных режимах для адресации к регистру состояния 1
          ; используется порт с адресом 3BAh, а в цветных - порт 3DAh

          add   dx,6

          pop   es


; ожидаем начало обратного вертикального хода луча

          in    al,dx
          nop
          nop

          ; если бит D3 равен единице, то происходит обратный
          ; вертикальный ход луча

          test  al,08h
          jz    wait_on

     wait_off:

          in    al,dx
          nop
          nop
          test  al,08h
          jnz   wait_off

     wait_on:

          in    al,dx
          nop
          nop
          test  al,08h
          jz    wait_on

; устанавливаем индекс первого записываемого регистра
; таблицы цветов

          mov   dx,3C8h

; начинаем модифицировать таблицу цветов с первого регистра

          mov   ax,1     
          out   dx,al

     ; задержка

          nop
          nop

; устанавливаем ds:si на массив данных, записываемых
; в регистры таблицы цветов

          mov   ax,seg_table
          mov   ds,ax
          mov   si,off_table

; загружаем 256 регистров (по 3 байта на регистр)

          mov   cx,(256 * 3)

; выбираем регистр данных таблицы цветов (порт 3C9h)

          mov   dx,3C9h

          cld

; загружаем все регистры таблицы цветов

     get_reg:

          lodsb
          out   dx,al
          nop            
          nop
          loop  get_reg

; восстанавливаем регистр ds

          pop   ds
     }
}

