1個人開發操作系統之界面與字體

1.界面

上文中我將一些信息保存到0x0ff0地址,這些信息有8bitscreen mode,屏幕高與寬,以及顯示用內存地址,現在我們將這些信息保存到struct裏:

struct BOOTINFO {

              char cyls, leds, vmode, reserve;

              short scrnx, scrny;

              char *vram;

};

 

struct BOOTINFO *binfo = (struct BOOTINFO *) 0x0ff0;

 

8bit顯示模式只有16色,既0-15,如果你不想使用系統默認的16色,可以自定義喜歡的16種顏色。定義方式爲:

void set_palette()

{

              int i, eflags;

             

              eflags = io_load_eflags(); /*記錄eflags*/

             

              io_cli();  /*禁止中斷*/

              io_out8(0x03c8, 0);  /*0x03c8端口發送命令*/

              /*begin,開始定義顏色*/

                            io_out8(0x03c9, 0x00 / 4);   /*R*/

                            io_out8(0x03c9, 0x00 / 4);   /*G*/

                            io_out8(0x03c9, 0x00 / 4);   /*B*/

 

                            io_out8(0x03c9, 0xff / 4);

                            io_out8(0x03c9, 0x00 / 4);

                            io_out8(0x03c9, 0x00 / 4);

                                                       

                            io_out8(0x03c9, 0x00 / 4);

                            io_out8(0x03c9, 0xff / 4);

                            io_out8(0x03c9, 0x00 / 4);

                           

                            io_out8(0x03c9,  0xff/ 4);

                            io_out8(0x03c9,  0xff/ 4);

                            io_out8(0x03c9,  0x00/ 4);

                           

                            io_out8(0x03c9, 0x00 / 4);

                            io_out8(0x03c9, 0x00 / 4);

                            io_out8(0x03c9, 0xff / 4);

                           

                            io_out8(0x03c9, 0xff / 4);

                            io_out8(0x03c9, 0x00 / 4);

                            io_out8(0x03c9, 0xff / 4);

                           

                            io_out8(0x03c9, 0x00 / 4);

                            io_out8(0x03c9, 0xff / 4);

                            io_out8(0x03c9, 0xff / 4);

                           

                            io_out8(0x03c9, 0xff / 4);

                            io_out8(0x03c9, 0xff / 4);

                            io_out8(0x03c9, 0xff / 4);

                           

                            io_out8(0x03c9, 0xc6 / 4);

                            io_out8(0x03c9, 0xc6 / 4);

                            io_out8(0x03c9, 0xc6 / 4);

                           

                            io_out8(0x03c9, 0x84 / 4);

                            io_out8(0x03c9, 0x00 / 4);

                            io_out8(0x03c9, 0x00 / 4);

                           

                            io_out8(0x03c9, 0x00 / 4);

                            io_out8(0x03c9, 0x84 / 4);

                            io_out8(0x03c9, 0x00 / 4);

                           

                            io_out8(0x03c9, 0x84 / 4);

                            io_out8(0x03c9, 0x84 / 4);

                            io_out8(0x03c9, 0x00 / 4);                                                                                                                                                                                                                               

                           

                            io_out8(0x03c9, 0x00 / 4);

                            io_out8(0x03c9, 0x00 / 4);

                            io_out8(0x03c9, 0x84 / 4);

                           

                            io_out8(0x03c9, 0x84 / 4);

                            io_out8(0x03c9, 0x00 / 4);

                            io_out8(0x03c9, 0x84 / 4);

                           

                            io_out8(0x03c9, 0x84 / 4);

                            io_out8(0x03c9, 0x84 / 4);

                            io_out8(0x03c9, 0x84 / 4);                                                                                   

                           

              /*end*/

              io_store_eflags(eflags);     /*恢復EFLAGS*/

              return;

}

 

下面就可以繪製界面了,一個方形繪製方法如下:

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;

}

unsigned char *vram爲顯示內存地址

int xsize爲屏幕的寬既320

unsigned char c爲顏色

int x0, int y0爲方形左上角點

int x1, int y1爲方形右下角點

2.字體

編寫一個新C源文件,爲font.c。定義一個符號方法如下:

void char_0(char *font)

{

              font[0]=0x00;

              font[1]=0x18;

              font[2]=0x24;

              font[3]=0x24;

              font[4]=0x42;

              font[5]=0x42;

              font[6]=0x42;

              font[7]=0x42;

              font[8]=0x42;

              font[9]=0x42;

              font[10]=0x42;

              font[11]=0x24;

              font[12]=0x24;

              font[13]=0x18;

              font[14]=0x00;

              font[15]=0x00;   

}

char *font爲內存地址,1個文字長寬爲8bit,高爲16bit。以上函數是定義數字0

符號顯示方法如下:

void putfont8(char *vram, int xsize, int x, int y, char c, char *font)

{

              int i;

              char *p, d /* data */;

              for (i = 0; i < 16; i++) {

                            p = vram + (y + i) * xsize + x;

                            d = font[i];

                            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; }

              }

              return;

}

 

3bootpack.c的完整源代碼

/*Colimas Simple OS*/

#include "font.h"

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(void);

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

void init_screen(char *vram, int x, int y);

void putfont8(char *vram, int xsize, int x, int y, char c, char *font);

void drawchar(char *vram, int xsize, int x, int y, char c, unsigned char s);

void drawstring(char *vram, int xsize, int x, int y, char c, unsigned char *s);

 

#define COL8_000000                    0

#define COL8_FF0000                   1

#define COL8_00FF00                   2

#define COL8_FFFF00                   3

#define COL8_0000FF                   4

#define COL8_FF00FF                   5

#define COL8_00FFFF                   6

#define COL8_FFFFFF                  7

#define COL8_C6C6C6                  8

#define COL8_840000                    9

#define COL8_008400                    10

#define COL8_848400                    11

#define COL8_000084                    12

#define COL8_840084                    13

#define COL8_008484                    14

#define COL8_848484                    15

//entry

struct BOOTINFO {

              char cyls, leds, vmode, reserve;

              short scrnx, scrny;

              char *vram;

};

 

void ColimasMain(void)

{

              struct BOOTINFO *binfo = (struct BOOTINFO *) 0x0ff0;

 

              init_palette();

              init_screen(binfo->vram, binfo->scrnx, binfo->scrny);

             

              //drawstring(binfo->vram, binfo->scrnx, 18, 10, COL8_FFFFFF, s);

                           

              drawchar(binfo->vram, binfo->scrnx, 10, 10, COL8_FFFFFF, 'C');

              drawchar(binfo->vram, binfo->scrnx, 18, 10, COL8_FFFFFF, 'I');      

              drawchar(binfo->vram, binfo->scrnx, 26, 10, COL8_FFFFFF, 'A');     

 

             

              for (;;) {

                            io_hlt();

              }

 

}

 

             

void init_palette(void)

{

              set_palette();

              return;

             

              }

 

void set_palette()

{

              int i, eflags;

             

              eflags = io_load_eflags();               

              io_cli();                                                         

              io_out8(0x03c8, 0);

              /*begin*/

                            io_out8(0x03c9, 0x00 / 4);

                            io_out8(0x03c9, 0x00 / 4);

                            io_out8(0x03c9, 0x00 / 4);

 

                            io_out8(0x03c9, 0xff / 4);

                            io_out8(0x03c9, 0x00 / 4);

                            io_out8(0x03c9, 0x00 / 4);

                                                       

                            io_out8(0x03c9, 0x00 / 4);

                            io_out8(0x03c9, 0xff / 4);

                            io_out8(0x03c9, 0x00 / 4);

                           

                            io_out8(0x03c9,  0xff/ 4);

                            io_out8(0x03c9,  0xff/ 4);

                            io_out8(0x03c9,  0x00/ 4);

                           

                            io_out8(0x03c9, 0x00 / 4);

                            io_out8(0x03c9, 0x00 / 4);

                            io_out8(0x03c9, 0xff / 4);

                           

                            io_out8(0x03c9, 0xff / 4);

                            io_out8(0x03c9, 0x00 / 4);

                            io_out8(0x03c9, 0xff / 4);

                           

                            io_out8(0x03c9, 0x00 / 4);

                            io_out8(0x03c9, 0xff / 4);

                            io_out8(0x03c9, 0xff / 4);

                           

                            io_out8(0x03c9, 0xff / 4);

                            io_out8(0x03c9, 0xff / 4);

                            io_out8(0x03c9, 0xff / 4);

                           

                            io_out8(0x03c9, 0xc6 / 4);

                            io_out8(0x03c9, 0xc6 / 4);

                            io_out8(0x03c9, 0xc6 / 4);

                           

                            io_out8(0x03c9, 0x84 / 4);

                            io_out8(0x03c9, 0x00 / 4);

                            io_out8(0x03c9, 0x00 / 4);

                           

                            io_out8(0x03c9, 0x00 / 4);

                            io_out8(0x03c9, 0x84 / 4);

                            io_out8(0x03c9, 0x00 / 4);

                           

                            io_out8(0x03c9, 0x84 / 4);

                            io_out8(0x03c9, 0x84 / 4);

                            io_out8(0x03c9, 0x00 / 4);                                                                                                                                                                                                                               

                           

                            io_out8(0x03c9, 0x00 / 4);

                            io_out8(0x03c9, 0x00 / 4);

                            io_out8(0x03c9, 0x84 / 4);

                           

                            io_out8(0x03c9, 0x84 / 4);

                            io_out8(0x03c9, 0x00 / 4);

                            io_out8(0x03c9, 0x84 / 4);

                           

                            io_out8(0x03c9, 0x84 / 4);

                            io_out8(0x03c9, 0x84 / 4);

                            io_out8(0x03c9, 0x84 / 4);                                                                                   

                           

              /*end*/

              io_store_eflags(eflags);    

              return;

}

 

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_screen(char *vram, int x, int y)

{

              boxfill8(vram, x, COL8_0000FF,  0,     0,      x -  1, y - 29);

              boxfill8(vram, x, COL8_C6C6C6,  0,     y - 28, x -  1, y - 28);

              boxfill8(vram, x, COL8_FFFFFF,  0,     y - 27, x -  1, y - 27);

              boxfill8(vram, x, COL8_C6C6C6,  0,     y - 26, x -  1, y -  1);

 

              boxfill8(vram, x, COL8_FFFFFF,  3,     y - 24, 59,     y - 24);

              boxfill8(vram, x, COL8_FFFFFF,  2,     y - 24,  2,     y -  4);

              boxfill8(vram, x, COL8_848484,  3,     y -  4, 59,     y -  4);

              boxfill8(vram, x, COL8_848484, 59,     y - 23, 59,     y -  5);

              boxfill8(vram, x, COL8_000000,  2,     y -  3, 59,     y -  3);

              boxfill8(vram, x, COL8_000000, 60,     y - 24, 60,     y -  3);

 

              boxfill8(vram, x, COL8_848484, x - 47, y - 24, x -  4, y - 24);

              boxfill8(vram, x, COL8_848484, x - 47, y - 23, x - 47, y -  4);

              boxfill8(vram, x, COL8_FFFFFF, x - 47, y -  3, x -  4, y -  3);

              boxfill8(vram, x, COL8_FFFFFF, x -  3, y - 24, x -  3, y -  3);

              return;

}

 

 

void putfont8(char *vram, int xsize, int x, int y, char c, char *font)

{

              int i;

              char *p, d /* data */;

              for (i = 0; i < 16; i++) {

                            p = vram + (y + i) * xsize + x;

                            d = font[i];

                            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; }

              }

              return;

}

void drawchar(char *vram, int xsize, int x, int y, char c, unsigned char s)

{

                            char *font;

                            get_char(font,s);

                            putfont8(vram, xsize, x, y, c,font);

                return;

}

 

4.顯示結果如下:

 

5.問題

你一定很奇怪我爲什麼沒有使用字符串和數組。字符串和數組編譯後屬於.data segement。我使用objcopy,將obj文件轉換爲binary文件後,我的程序不能正確地找到這些.data segement的地址。我現在正在嘗試自己編寫連接器。

  
發佈了96 篇原創文章 · 獲贊 8 · 訪問量 36萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章