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

unsigned char far *mode_ctrl = MK_FP(0x40, 0x65);
unsigned char far *col_ctrl  = MK_FP(0x40, 0x66);

int getmode()
{
	union REGS rg;

	rg.h.ah = 0x0F;
	int86(0x10, &rg, &rg);
	return rg.h.al;
}



void setmode(int m)
{
	union REGS rg;

	rg.x.ax = m & 0xFF;
	int86(0x10, &rg, &rg);
}

unsigned char font[128] =
{
	0x00, 0x3C, 0x46, 0x4A, 0x52, 0x62, 0x3C, 0x00,	/* 0 */
	0x00, 0x18, 0x28, 0x08, 0x08, 0x08, 0x3E, 0x00, /* 1 */
	0x00, 0x3C, 0x42, 0x02, 0x3C, 0x40, 0x7E, 0x00, /* 2 */
	0x00, 0x3C, 0x42, 0x0C, 0x02, 0x42, 0x3C, 0x00, /* 3 */
	0x00, 0x08, 0x18, 0x28, 0x48, 0x7E, 0x08, 0x00, /* 4 */
	0x00, 0x7E, 0x40, 0x7C, 0x02, 0x42, 0x3C, 0x00, /* 5 */
	0x00, 0x3C, 0x40, 0x7C, 0x42, 0x42, 0x3C, 0x00, /* 6 */
	0x00, 0x7E, 0x02, 0x04, 0x08, 0x10, 0x10, 0x00, /* 7 */
	0x00, 0x3C, 0x42, 0x3C, 0x42, 0x42, 0x3C, 0x00, /* 8 */
	0x00, 0x3C, 0x42, 0x42, 0x3E, 0x02, 0x3C, 0x00, /* 9 */
	0x00, 0x3C, 0x42, 0x42, 0x7E, 0x42, 0x42, 0x00, /* A */
	0x00, 0x7C, 0x42, 0x7C, 0x42, 0x42, 0x7C, 0x00, /* B */
	0x00, 0x3C, 0x42, 0x40, 0x40, 0x42, 0x3C, 0x00, /* C */
	0x00, 0x78, 0x44, 0x42, 0x42, 0x44, 0x78, 0x00, /* D */
    0x00, 0x7E, 0x40, 0x7C, 0x40, 0x40, 0x7E, 0x00, /* E */
    0x00, 0x7E, 0x40, 0x7C, 0x40, 0x40, 0x40, 0x00, /* F */
};


void drawhex(int row, int col, unsigned char fill)
{
	unsigned char far *vram;
	unsigned char *ch1, *ch2;
	int n;
	
	vram = MK_FP(0xB800, (row/2) * 80 + col);

	ch1 = font + ((fill >> 4) & 0x0F) * 8;
	ch2 = font + ((fill     ) & 0x0F) * 8; 
	for (n = 0; n < 4; n++)
	{
		vram[0] = ch1[0];
		vram[1] = ch2[0];
		vram[0x2000] = ch1[1];
		vram[0x2001] = ch2[1];
		ch1 += 2;
		ch2 += 2;
		vram += 80;
	}
}


void row(int fill)
{
	unsigned char far *vram;
	unsigned char fillb = 17 * fill;
	int n;
	
	vram = MK_FP(0xB800, fill * 480);
	for (n = 0; n < 480; n++)
	{
		vram[n] = fillb;
		vram[n+0x2000] = fillb;	
	}
}

void showports()
{
	drawhex(192, 0, *mode_ctrl);
	drawhex(192, 2, *col_ctrl);
}



void alter_bit(int bit, unsigned char far *value, int p)
{
	unsigned char mask = 1 << bit;

	*value ^= mask;
	outp(p, *value);
	showports();
}


int main(int argc, char **argv)
{
	char ch;
	int fill;
	int m = getmode();
	setmode(6);
	for (fill = 0; fill < 16; fill++)
	{
		row(fill);
	}
	showports();
	while (1) switch (ch = getch())
	{
		case '0': case '1': case '2': case '3': 
		case '4': case '5': case '6': case '7':
			alter_bit(ch - '0', mode_ctrl, 0x3D8);
			break;
		case 'A': case 'B': case 'C': case 'D':
		case 'E': case 'F': case 'G': case 'H':
			alter_bit(ch - 'A', col_ctrl, 0x3D9);
			break;
		case 'a': case 'b': case 'c': case 'd':
		case 'e': case 'f': case 'g': case 'h':
			alter_bit(ch - 'a', col_ctrl, 0x3D9);
			break;
		case 0x1B:
			setmode(m);
			return 0;
	}
	return 0;
}
