#include #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_WATER 6 // 水色 #define COL8_WHITE 7 // 白色 #define COL8_GRAY 8 // 灰色 #define COL8_DARKRED 9 // 赤色(暗い) #define COL8_DARKGREEN 10 // 緑色(暗い) #define COL8_DARKYELLOW 11 // 黄色(暗い) #define COL8_DARKBLUE 12 // 青色(暗い) #define COL8_DARKPURPLE 13 // 紫色(暗い) #define COL8_DARKWATER 14 // 水色(暗い) #define COL8_DARKGRAY 15 // 灰色(暗い) // naskfunc.nasで定義している関数群 void io_hlt(void); void io_cli(void); void io_sti(void); void io_out8(int port, int data); int io_load_eflags(void); void io_store_eflags(int eflags); // bootpack.cで定義している関数群 unsigned char *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 init_screen8(char *vram, int x, int y); void putfont8(char *vram, int xsize, int x, int y, char c, char *font); void putfonts8_asc(char *vram, int xsize, int x, int y, char c, unsigned char *s); void init_mouse_cursor8(char *mouse, char bc); void putblock8_8(char *vram, int vxsize, int pxsize, int pysize, int px0, int py0, char *buf, int bxsize); typedef struct _BOOTINFO { char cyls, leds, vmode, reserve; short scrnx, scrny; char *vram; } BOOTINFO, *PBOOTINFO; // ------------------------------------------------------------------ // メイン関数 // ------------------------------------------------------------------ void HariMain(void) { // ブート情報の設定値の保存場所 PBOOTINFO pbinfo = (PBOOTINFO) 0x0ff0; char str[256], mcursor[256]; int mx, my; // パレットの初期化 set_palette(COL8_BLACK, COL8_DARKGRAY, init_palette()); // スクリーン画面の初期化 init_screen8(pbinfo->vram, pbinfo->scrnx, pbinfo->scrny); // マウスの座標計算 mx = ((pbinfo->scrnx - 16) / 4) * 3; my = ((pbinfo->scrny - 28 - 16) / 4) * 3; // マウス描画 init_mouse_cursor8(mcursor, COL8_DARKWATER); putblock8_8(pbinfo->vram, pbinfo->scrnx, 16, 16, mx, my, mcursor, 16); // マウス位置を文字列で表示 sprintf(str, "mouse is (x, y) = (%d, %d)", mx, my); putfonts8_asc(pbinfo->vram, pbinfo->scrnx, 0, 0, COL8_WHITE, str); sprintf(str, "I will make the hariboteOS after 25 days."); putfonts8_asc(pbinfo->vram, pbinfo->scrnx, 0, 32, COL8_YELLOW, str); while(1) // 無限ループ io_hlt(); // HLT命令でCPUを休ませておく } // ------------------------------------------------------------------ // パケットデータを設定する関数(RGBで設定) // ------------------------------------------------------------------ unsigned char *init_palette(void) { // 色情報をRGBで持っておく 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:灰色(暗い) }; return table_rgb; } // ------------------------------------------------------------------ // VRAMにパレットをセットする関数 // この関数の詳しい解説は http://community.osdev.info/?VGA を見るべし // ------------------------------------------------------------------ void set_palette(int start, int end, unsigned char *rgb) { //int eflags = io_load_eflags();// 現在のフラグレジスタを記憶 io_cli(); // 許可フラグを0にして割り込み禁止にする io_out8(0x03c8, start); while(start++ <= end) { io_out8(0x03c9, rgb[0] / 4); // 16色の情報を設定 io_out8(0x03c9, rgb[1] / 4); // 1つの色はRGBで3バイトなので、 io_out8(0x03c9, rgb[2] / 4); // このように3回使って設定する rgb += 3; } io_sti(); //io_store_eflags(eflags); // フラグレジスタを復元 return; } // ------------------------------------------------------------------ // 長方形を描く関数 // ------------------------------------------------------------------ void boxfill8(unsigned char *vram, // VRAMのアドレス int xsize, // X軸のサイズ unsigned char c, // 色情報 int x0, int y0, // 開始座標(左上の1点) int x1, int y1 // 終了座標(右下の1点) ) { int x, y; for (y = y0; y <= y1; y++) { // VRAMのアドレスへ for (x = x0; x <= x1; x++) // 1バイトずつ長方形のデータを vram[y * xsize + x] = c; // 書き込んでいく } } // ------------------------------------------------------------------ // スクリーン画面を初期化する // ------------------------------------------------------------------ void init_screen8(char *vram, int x, int y) { boxfill8(vram, x, COL8_DARKWATER, 0, 0, x - 1, y - 29); boxfill8(vram, x, COL8_GRAY, 0, y - 28, x - 1, y - 28); boxfill8(vram, x, COL8_WHITE, 0, y - 27, x - 1, y - 27); boxfill8(vram, x, COL8_GRAY, 0, y - 26, x - 1, y - 1); boxfill8(vram, x, COL8_WHITE, 3, y - 24, 59, y - 24); boxfill8(vram, x, COL8_WHITE, 2, y - 24, 2, y - 4); boxfill8(vram, x, COL8_DARKGRAY, 3, y - 4, 59, y - 4); boxfill8(vram, x, COL8_DARKGRAY, 59, y - 23, 59, y - 5); boxfill8(vram, x, COL8_BLACK, 2, y - 3, 59, y - 3); boxfill8(vram, x, COL8_BLACK, 60, y - 24, 60, y - 3); boxfill8(vram, x, COL8_DARKGRAY, x - 47, y - 24, x - 4, y - 24); boxfill8(vram, x, COL8_DARKGRAY, x - 47, y - 23, x - 47, y - 4); boxfill8(vram, x, COL8_WHITE, x - 47, y - 3, x - 4, y - 3); boxfill8(vram, x, COL8_WHITE, x - 3, y - 24, x - 3, y - 3); } // ------------------------------------------------------------------ // 1文字出力関数 // vram = VRAM, xsize = スクリーンX軸サイズ // x, y = 表示するスクリーン座標(x, y) // c = 表示する文字の色 // font = 表示する文字フォントがあるアドレス // ------------------------------------------------------------------ void putfont8(char *vram, int xsize, int x, int y, char c, char *font) { int i; for (i = 0; i < 16; i++) { // dはフォントのビット情報 char d = font[i]; // pはVRAMの描画するアドレス char *p = vram + (y + i) * xsize + x; // フォントのビット情報を元に色の点を打っていく if ((d & 0x80) != 0) { p[0] = c; } if ((d & 0x40) != 0) { p[1] = c; } if ((d & 0x20) != 0) { p[2] = c; } if ((d & 0x10) != 0) { p[3] = c; } if ((d & 0x08) != 0) { p[4] = c; } if ((d & 0x04) != 0) { p[5] = c; } if ((d & 0x02) != 0) { p[6] = c; } if ((d & 0x01) != 0) { p[7] = c; } } } // ------------------------------------------------------------------ // 文字列出力関数 // vram = VRAM, xsize = スクリーンX軸サイズ // x, y = 表示するスクリーン座標(x, y) // c = 表示する文字列の色 // s = 表示する文字列のアドレス // ------------------------------------------------------------------ void putfonts8_asc(char *vram, int xsize, int x, int y, char c, unsigned char *s) { // 他ファイルに定義されているグローバル変数を参照 extern char hankaku[4096]; for (; *s != 0x00; s++) { putfont8(vram, xsize, x, y, c, hankaku + *s * 16); x += 8; } return; } // ------------------------------------------------------------------ // マウスカーソルの画像を生成する // ------------------------------------------------------------------ void init_mouse_cursor8(char *mouse, char bc) { static char cursor[16][16] = { "****************", "*OOOOOOOOOOOOO*.", "*OOOOOOOOOOOO*..", "*OOOOOOOOOOO*...", "*OOOOOOOOOO*....", "*OOOOOOOOO*.....", "*OOOOOOOO*......", "*OOOOOOOO*......", "*OOOOOOOOO*.....", "*OOOOO**OOO*....", "*OOOO*..*OOO*...", "*OOO*....*OOO*..", "*OO*......*OOO*.", "*O*........*OOO*", "**..........*OO*", "*............***" }; int x, y; for (y = 0; y < 16; y++) for (x = 0; x < 16; x++) switch (cursor[y][x]) { case '*': mouse[y * 16 + x] = COL8_BLACK; break; case 'O': mouse[y * 16 + x] = COL8_WHITE; break; case '.': mouse[y * 16 + x] = bc; break; } } // ------------------------------------------------------------------ // 画像描画関数 // vram = VRAM // vxsize = スクリーンX軸サイズ // pxsize, pysize = 描画する画像のサイズ(X, Y) // px0, py0 = 描画する画像の位置(X, Y) // buf = 描画する画像データ // bxsize = 描画する画像のX軸サイズ // ------------------------------------------------------------------ void putblock8_8(char *vram, int vxsize, int pxsize, int pysize, int px0, int py0, char *buf, int bxsize) { int x, y; for (y = 0; y < pysize; y++) for (x = 0; x < pxsize; x++) vram[(py0 + y) * vxsize + (px0 + x)] = buf[y * bxsize + x]; }