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

typedef struct _RGB_ {
	unsigned char red;
	unsigned char green;
	unsigned char blue;
} RGB;

// Объявление функций
void	main(void);
void	SetVideoMode(unsigned char);
void	SetVgaDAC(unsigned, unsigned);
void	GrayScale(void);

//==========================================================
// Главная функция
//==========================================================
void main(void)
{
	RGB color_table[256];
	unsigned char   i,j;
	unsigned char   far *ptr;
	int error, x_num, y_num;
	unsigned seg_table,off_table;

	// Формируем новые значения для таблицы цветов
	for(j = 0; j < 4; j++) {
		for(i = 0; i < 64; i++) {
			(color_table[i+j*64]).red = (j == 0) ? i : (j == 4) ? i : 0;
			(color_table[i+j*64]).green = (j == 1) ? i : (j == 3) ? i : (j == 4) ? i : 0;
			(color_table[i+j*64]).blue = (j == 2) ? i : (j == 3) ? i : (j == 4) ? i : 0;
		}
	}

	// Устанавливаем режим номер 13h
	SetVideoMode(0x13);

	ptr = (unsigned char far*) &color_table[0];
	seg_table = FP_SEG(ptr);
	off_table = FP_OFF(ptr);

	// Загружаем таблицу цветов
	SetVgaDAC(seg_table,off_table);

	// Записываем данные в видеопамять
	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();

	// Преобразовываем данные в таблице цветов к серому цвету
	GrayScale();

	// Ожидаем нажатие на клавишу клавиатуры
	getch();

	// Устанавливаем текстовый режим
	SetVideoMode(0x3);
}

//==============================================================
// Функция установки режима
//==============================================================
void SetVideoMode( unsigned char vmode ) {

	union REGS regs;

	regs.h.ah = 0x0;
	regs.h.al = vmode;

	int86(0x10, &regs, &regs);
}

//==============================================================
// Функция загрузки таблицы цветов
//==============================================================
void SetVgaDAC(unsigned seg_table, unsigned off_table) {

	union REGS regs;
	struct SREGS segregs;

	regs.x.ax = 0x1012;
	regs.x.cx = 256;
	regs.x.bx = 0x00;

	segregs.es = seg_table;
	regs.x.dx = off_table;

	int86x(0x10, &regs, &regs, &segregs);
}

//==============================================================
// Функция преобразования таблицы цветов в серый цвет
//==============================================================
void GrayScale( void ) {

	union REGS regs;

	regs.x.ax = 0x101b;
	regs.x.cx = 256;
	regs.x.bx = 0x00;

	int86(0x10, &regs, &regs);
}
