#define COL8_BLACK			0
#define COL8_RED			1
#define COL8_GREEN			2
#define	COL8_YELLOW			3
#define COL8_BLUE			4
#define COL8_PURPLE			5
#define COL8_PALEBLUE		6
#define COL8_WHITE			7
#define	COL8_LIGHT_GRAY		8
#define	COL8_DARK_RED		9
#define COL8_DARK_GREEN 	10
#define	COL8_DARK_YELLOW	11
#define COL8_DARK_BLUE		12
#define COL8_DARK_PURPLE	13
#define COL8_DARK_PALEBLUE	14
#define	COL8_DARK_GRAY		15

void io_hlt(void);
void io_cli(void);
void io_out8(int port, int data);
int io_load_eflags(void);
void io_store_eflags(int eflags);

void init_palette(void);
void set_palette(int start, int end, unsigned char *rgb);

void boxfill8(unsigned char *vram, int xsize, unsigned char c, int x0, int y0, int x1, int y1);

void HariMain(void)
{
	char *vram;
	int xsize, ysize;
	init_palette();
	
	vram = (char*) 0xa0000;
	xsize = 320;
	ysize = 200;
	
	boxfill8(vram, xsize, COL8_DARK_PALEBLUE, 0, 0, xsize - 1, ysize - 29);
	boxfill8(vram, xsize, COL8_LIGHT_GRAY, 0, ysize - 28, xsize - 1, ysize - 28);
	boxfill8(vram, xsize, COL8_WHITE, 0, ysize - 27, xsize - 1, ysize - 27);
	boxfill8(vram, xsize, COL8_LIGHT_GRAY, 0, ysize - 26, xsize - 1, y size - 1);
	
	boxfill8(vram, xsize, COL8_WHITE, 3, ysize - 24, 59, ysize -24);
	boxfill8(vram, xsize, COL8_WHITE, 2, ysize - 24, 2, ysize - 4);
	boxfill8(vram, xsize, COL8_DARK_GRAY, 3, ysize - 4, 59, ysize -4);
	boxfill8(vram, xsize, COL8_DARK_GRAY, 59, ysize - 23, 59, ysize - 5);
	boxfill8(vram, xsize, COL8_BLACK, 2, ysize - 3, 59, ysize - 3);
	boxfill8(vram, xsize, COL8_BLACK, 60, ysize - 24, 60, ysize - 3);
	
	boxfill8(vram, xsize, COL8_DARK_GRAY, xsize - 47, ysize - 24, xsize - 4, ysize - 24);
	boxfill8(vram, xsize, COL8_DARK_GRAY, xsize - 47, ysize - 23, xsize - 47, ysize - 4);
	boxfill8(vram, xsize, COL8_WHITE, xsize - 47, ysize - 3, xsize - 4, ysize - 3);
	boxfill8(vram, xsize, COL8_WHITE, xsize - 3, ysize - 24, xsize - 3, ysize - 3);
					
				
	while(1){
		io_hlt();
	}
}

void boxfill8(unsigned char *vram, int xsize, unsigned char c, int x0, int y0, int x1, int y1)
{
	int x, y;
	for (y = y0; y <= y1; y++){
		for (x = x0; x <= x1; x++){
			vram[y * xsize + x] = c;
		}
	}
	return;
}

void init_palette(void)
{
	static unsigned char table_rgb[16 * 3] = {
		0x00, 0x00, 0x00, /*0:黒*/
		0xff, 0x00, 0x00, /*1:明るい赤 */
		0x00, 0xff, 0x00, /*2:明るい緑*/
		0xff, 0xff, 0x00, /*3:明るい黄色*/
		0x00, 0x00, 0xff, /*4:明るい青*/
		0xff, 0x00, 0xff, /*5:明るい紫*/
		0x00, 0xff, 0xff, /*6:明るい水色*/
		0xff, 0xff, 0xff, /*7:白*/
		0xc6, 0xc6, 0xc6, /*8:明るい灰色*/
		0x84, 0x00, 0x00, /*9:暗い赤*/
		0x00, 0x84, 0x00, /*10:暗い緑*/
		0x84, 0x84, 0x00, /*11:暗い黄色*/
		0x00, 0x00, 0x84, /*12:暗い青*/
		0x84, 0x00, 0x84, /*13:暗い紫*/
		0x00, 0x84, 0x84, /*14:暗い水色*/
		0x84, 0x84, 0x84, /*15:暗い灰色*/
	};
	set_palette(0, 15, table_rgb);
	return;
}

void set_palette(int start, int end, unsigned char *rgb)
{
	int i, eflags;
	eflags = io_load_eflags(); //割り込み許可フラグの値を記録する。
	io_cli(); //許可フラグを0にして割り込み禁止にする
	io_out8(0x3c8, start);
	for (i = start; i <= end; i++){
		io_out8(0x3c9, rgb[0] / 4);
		io_out8(0x3c9, rgb[1] / 4);
		io_out8(0x3c9, rgb[2] / 4);
		rgb += 3;
	}
	io_store_eflags(eflags); //割り込み許可フラグを元に戻す。
	return;
}