1.界面
上文中我将一些信息保存到0x0ff0地址,这些信息有8bit的screen 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(0x<chmetcnv w:st="on" unitname="C" sourcevalue="3" hasspace="False" negative="False" numbertype="1" tcsc="0">03c</chmetcnv>8, 0); /*向0x<chmetcnv w:st="on" unitname="C" sourcevalue="3" hasspace="False" negative="False" numbertype="1" tcsc="0">03c</chmetcnv>8端口发送命令*/
/*begin,开始定义颜色*/
io_out8(0x<chmetcnv w:st="on" unitname="C" sourcevalue="3" hasspace="False" negative="False" numbertype="1" tcsc="0">03c</chmetcnv>9, 0x00 / 4); /*R*/
io_out8(0x<chmetcnv w:st="on" unitname="C" sourcevalue="3" hasspace="False" negative="False" numbertype="1" tcsc="0">03c</chmetcnv>9, 0x00 / 4); /*G*/
io_out8(0x<chmetcnv w:st="on" unitname="C" sourcevalue="3" hasspace="False" negative="False" numbertype="1" tcsc="0">03c</chmetcnv>9, 0x00 / 4); /*B*/
io_out8(0x<chmetcnv w:st="on" unitname="C" sourcevalue="3" hasspace="False" negative="False" numbertype="1" tcsc="0">03c</chmetcnv>9, 0xff / 4);
io_out8(0x<chmetcnv w:st="on" unitname="C" sourcevalue="3" hasspace="False" negative="False" numbertype="1" tcsc="0">03c</chmetcnv>9, 0x00 / 4);
io_out8(0x<chmetcnv w:st="on" unitname="C" sourcevalue="3" hasspace="False" negative="False" numbertype="1" tcsc="0">03c</chmetcnv>9, 0x00 / 4);
io_out8(0x<chmetcnv w:st="on" unitname="C" sourcevalue="3" hasspace="False" negative="False" numbertype="1" tcsc="0">03c</chmetcnv>9, 0x00 / 4);
io_out8(0x<chmetcnv w:st="on" unitname="C" sourcevalue="3" hasspace="False" negative="False" numbertype="1" tcsc="0">03c</chmetcnv>9, 0xff / 4);
io_out8(0x<chmetcnv w:st="on" unitname="C" sourcevalue="3" hasspace="False" negative="False" numbertype="1" tcsc="0">03c</chmetcnv>9, 0x00 / 4);
io_out8(0x<chmetcnv w:st="on" unitname="C" sourcevalue="3" hasspace="False" negative="False" numbertype="1" tcsc="0">03c</chmetcnv>9, 0xff/ 4);
io_out8(0x<chmetcnv w:st="on" unitname="C" sourcevalue="3" hasspace="False" negative="False" numbertype="1" tcsc="0">03c</chmetcnv>9, 0xff/ 4);
io_out8(0x<chmetcnv w:st="on" unitname="C" sourcevalue="3" hasspace="False" negative="False" numbertype="1" tcsc="0">03c</chmetcnv>9, 0x00/ 4);
io_out8(0x<chmetcnv w:st="on" unitname="C" sourcevalue="3" hasspace="False" negative="False" numbertype="1" tcsc="0">03c</chmetcnv>9, 0x00 / 4);
io_out8(0x<chmetcnv w:st="on" unitname="C" sourcevalue="3" hasspace="False" negative="False" numbertype="1" tcsc="0">03c</chmetcnv>9, 0x00 / 4);
io_out8(0x<chmetcnv w:st="on" unitname="C" sourcevalue="3" hasspace="False" negative="False" numbertype="1" tcsc="0">03c</chmetcnv>9, 0xff / 4);
io_out8(0x<chmetcnv w:st="on" unitname="C" sourcevalue="3" hasspace="False" negative="False" numbertype="1" tcsc="0">03c</chmetcnv>9, 0xff / 4);
io_out8(0x<chmetcnv w:st="on" unitname="C" sourcevalue="3" hasspace="False" negative="False" numbertype="1" tcsc="0">03c</chmetcnv>9, 0x00 / 4);
io_out8(0x<chmetcnv w:st="on" unitname="C" sourcevalue="3" hasspace="False" negative="False" numbertype="1" tcsc="0">03c</chmetcnv>9, 0xff / 4);
io_out8(0x<chmetcnv w:st="on" unitname="C" sourcevalue="3" hasspace="False" negative="False" numbertype="1" tcsc="0">03c</chmetcnv>9, 0x00 / 4);
io_out8(0x<chmetcnv w:st="on" unitname="C" sourcevalue="3" hasspace="False" negative="False" numbertype="1" tcsc="0">03c</chmetcnv>9, 0xff / 4);
io_out8(0x<chmetcnv w:st="on" unitname="C" sourcevalue="3" hasspace="False" negative="False" numbertype="1" tcsc="0">03c</chmetcnv>9, 0xff / 4);
io_out8(0x<chmetcnv w:st="on" unitname="C" sourcevalue="3" hasspace="False" negative="False" numbertype="1" tcsc="0">03c</chmetcnv>9, 0xff / 4);
io_out8(0x<chmetcnv w:st="on" unitname="C" sourcevalue="3" hasspace="False" negative="False" numbertype="1" tcsc="0">03c</chmetcnv>9, 0xff / 4);
io_out8(0x<chmetcnv w:st="on" unitname="C" sourcevalue="3" hasspace="False" negative="False" numbertype="1" tcsc="0">03c</chmetcnv>9, 0xff / 4);
io_out8(0x<chmetcnv w:st="on" unitname="C" sourcevalue="3" hasspace="False" negative="False" numbertype="1" tcsc="0">03c</chmetcnv>9, 0xc6 / 4);
io_out8(0x<chmetcnv w:st="on" unitname="C" sourcevalue="3" hasspace="False" negative="False" numbertype="1" tcsc="0">03c</chmetcnv>9, 0xc6 / 4);
io_out8(0x<chmetcnv w:st="on" unitname="C" sourcevalue="3" hasspace="False" negative="False" numbertype="1" tcsc="0">03c</chmetcnv>9, 0xc6 / 4);
io_out8(0x<chmetcnv w:st="on" unitname="C" sourcevalue="3" hasspace="False" negative="False" numbertype="1" tcsc="0">03c</chmetcnv>9, 0x84 / 4);
io_out8(0x<chmetcnv w:st="on" unitname="C" sourcevalue="3" hasspace="False" negative="False" numbertype="1" tcsc="0">03c</chmetcnv>9, 0x00 / 4);
io_out8(0x<chmetcnv w:st="on" unitname="C" sourcevalue="3" hasspace="False" negative="False" numbertype="1" tcsc="0">03c</chmetcnv>9, 0x00 / 4);
io_out8(0x<chmetcnv w:st="on" unitname="C" sourcevalue="3" hasspace="False" negative="False" numbertype="1" tcsc="0">03c</chmetcnv>9, 0x00 / 4);
io_out8(0x<chmetcnv w:st="on" unitname="C" sourcevalue="3" hasspace="False" negative="False" numbertype="1" tcsc="0">03c</chmetcnv>9, 0x84 / 4);
io_out8(0x<chmetcnv w:st="on" unitname="C" sourcevalue="3" hasspace="False" negative="False" numbertype="1" tcsc="0">03c</chmetcnv>9, 0x00 / 4);
io_out8(0x<chmetcnv w:st="on" unitname="C" sourcevalue="3" hasspace="False" negative="False" numbertype="1" tcsc="0">03c</chmetcnv>9, 0x84 / 4);
io_out8(0x<chmetcnv w:st="on" unitname="C" sourcevalue="3" hasspace="False" negative="False" numbertype="1" tcsc="0">03c</chmetcnv>9, 0x84 / 4);
io_out8(0x<chmetcnv w:st="on" unitname="C" sourcevalue="3" hasspace="False" negative="False" numbertype="1" tcsc="0">03c</chmetcnv>9, 0x00 / 4);
io_out8(0x<chmetcnv w:st="on" unitname="C" sourcevalue="3" hasspace="False" negative="False" numbertype="1" tcsc="0">03c</chmetcnv>9, 0x00 / 4);
io_out8(0x<chmetcnv w:st="on" unitname="C" sourcevalue="3" hasspace="False" negative="False" numbertype="1" tcsc="0">03c</chmetcnv>9, 0x00 / 4);
io_out8(0x<chmetcnv w:st="on" unitname="C" sourcevalue="3" hasspace="False" negative="False" numbertype="1" tcsc="0">03c</chmetcnv>9, 0x84 / 4);
io_out8(0x<chmetcnv w:st="on" unitname="C" sourcevalue="3" hasspace="False" negative="False" numbertype="1" tcsc="0">03c</chmetcnv>9, 0x84 / 4);
io_out8(0x<chmetcnv w:st="on" unitname="C" sourcevalue="3" hasspace="False" negative="False" numbertype="1" tcsc="0">03c</chmetcnv>9, 0x00 / 4);
io_out8(0x<chmetcnv w:st="on" unitname="C" sourcevalue="3" hasspace="False" negative="False" numbertype="1" tcsc="0">03c</chmetcnv>9, 0x84 / 4);
io_out8(0x<chmetcnv w:st="on" unitname="C" sourcevalue="3" hasspace="False" negative="False" numbertype="1" tcsc="0">03c</chmetcnv>9, 0x84 / 4);
io_out8(0x<chmetcnv w:st="on" unitname="C" sourcevalue="3" hasspace="False" negative="False" numbertype="1" tcsc="0">03c</chmetcnv>9, 0x84 / 4);
io_out8(0x<chmetcnv w:st="on" unitname="C" sourcevalue="3" hasspace="False" negative="False" numbertype="1" tcsc="0">03c</chmetcnv>9, 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;
}
3.bootpack.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_C<chmetcnv w:st="on" unitname="C" sourcevalue="6" hasspace="False" negative="False" numbertype="1" tcsc="0">6C</chmetcnv><chmetcnv w:st="on" unitname="C" sourcevalue="6" hasspace="False" negative="False" numbertype="1" tcsc="0">6C</chmetcnv>6 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(0x<chmetcnv w:st="on" unitname="C" sourcevalue="3" hasspace="False" negative="False" numbertype="1" tcsc="0">03c</chmetcnv>8, 0);
/*begin*/
io_out8(0x<chmetcnv w:st="on" unitname="C" sourcevalue="3" hasspace="False" negative="False" numbertype="1" tcsc="0">03c</chmetcnv>9, 0x00 / 4);
io_out8(0x<chmetcnv w:st="on" unitname="C" sourcevalue="3" hasspace="False" negative="False" numbertype="1" tcsc="0">03c</chmetcnv>9, 0x00 / 4);
io_out8(0x<chmetcnv w:st="on" unitname="C" sourcevalue="3" hasspace="False" negative="False" numbertype="1" tcsc="0">03c</chmetcnv>9, 0x00 / 4);
io_out8(0x<chmetcnv w:st="on" unitname="C" sourcevalue="3" hasspace="False" negative="False" numbertype="1" tcsc="0">03c</chmetcnv>9, 0xff / 4);
io_out8(0x<chmetcnv w:st="on" unitname="C" sourcevalue="3" hasspace="False" negative="False" numbertype="1" tcsc="0">03c</chmetcnv>9, 0x00 / 4);
io_out8(0x<chmetcnv w:st="on" unitname="C" sourcevalue="3" hasspace="False" negative="False" numbertype="1" tcsc="0">03c</chmetcnv>9, 0x00 / 4);
io_out8(0x<chmetcnv w:st="on" unitname="C" sourcevalue="3" hasspace="False" negative="False" numbertype="1" tcsc="0">03c</chmetcnv>9, 0x00 / 4);
io_out8(0x<chmetcnv w:st="on" unitname="C" sourcevalue="3" hasspace="False" negative="False" numbertype="1" tcsc="0">03c</chmetcnv>9, 0xff / 4);
io_out8(0x<chmetcnv w:st="on" unitname="C" sourcevalue="3" hasspace="False" negative="False" numbertype="1" tcsc="0">03c</chmetcnv>9, 0x00 / 4);
io_out8(0x<chmetcnv w:st="on" unitname="C" sourcevalue="3" hasspace="False" negative="False" numbertype="1" tcsc="0">03c</chmetcnv>9, 0xff/ 4);
io_out8(0x<chmetcnv w:st="on" unitname="C" sourcevalue="3" hasspace="False" negative="False" numbertype="1" tcsc="0">03c</chmetcnv>9, 0xff/ 4);
io_out8(0x<chmetcnv w:st="on" unitname="C" sourcevalue="3" hasspace="False" negative="False" numbertype="1" tcsc="0">03c</chmetcnv>9, 0x00/ 4);
io_out8(0x<chmetcnv w:st="on" unitname="C" sourcevalue="3" hasspace="False" negative="False" numbertype="1" tcsc="0">03c</chmetcnv>9, 0x00 / 4);
io_out8(0x<chmetcnv w:st="on" unitname="C" sourcevalue="3" hasspace="False" negative="False" numbertype="1" tcsc="0">03c</chmetcnv>9, 0x00 / 4);
io_out8(0x<chmetcnv w:st="on" unitname="C" sourcevalue="3" hasspace="False" negative="False" numbertype="1" tcsc="0">03c</chmetcnv>9, 0xff / 4);
io_out8(0x<chmetcnv w:st="on" unitname="C" sourcevalue="3" hasspace="False" negative="False" numbertype="1" tcsc="0">03c</chmetcnv>9, 0xff / 4);
io_out8(0x<chmetcnv w:st="on" unitname="C" sourcevalue="3" hasspace="False" negative="False" numbertype="1" tcsc="0">03c</chmetcnv>9, 0x00 / 4);
io_out8(0x<chmetcnv w:st="on" unitname="C" sourcevalue="3" hasspace="False" negative="False" numbertype="1" tcsc="0">03c</chmetcnv>9, 0xff / 4);
io_out8(0x<chmetcnv w:st="on" unitname="C" sourcevalue="3" hasspace="False" negative="False" numbertype="1" tcsc="0">03c</chmetcnv>9, 0x00 / 4);
io_out8(0x<chmetcnv w:st="on" unitname="C" sourcevalue="3" hasspace="False" negative="False" numbertype="1" tcsc="0">03c</chmetcnv>9, 0xff / 4);
io_out8(0x<chmetcnv w:st="on" unitname="C" sourcevalue="3" hasspace="False" negative="False" numbertype="1" tcsc="0">03c</chmetcnv>9, 0xff / 4);
io_out8(0x<chmetcnv w:st="on" unitname="C" sourcevalue="3" hasspace="False" negative="False" numbertype="1" tcsc="0">03c</chmetcnv>9, 0xff / 4);
io_out8(0x<chmetcnv w:st="on" unitname="C" sourcevalue="3" hasspace="False" negative="False" numbertype="1" tcsc="0">03c</chmetcnv>9, 0xff / 4);
io_out8(0x<chmetcnv w:st="on" unitname="C" sourcevalue="3" hasspace="False" negative="False" numbertype="1" tcsc="0">03c</chmetcnv>9, 0xff / 4);
io_out8(0x<chmetcnv w:st="on" unitname="C" sourcevalue="3" hasspace="False" negative="False" numbertype="1" tcsc="0">03c</chmetcnv>9, 0xc6 / 4);
io_out8(0x<chmetcnv w:st="on" unitname="C" sourcevalue="3" hasspace="False" negative="False" numbertype="1" tcsc="0">03c</chmetcnv>9, 0xc6 / 4);
io_out8(0x<chmetcnv w:st="on" unitname="C" sourcevalue="3" hasspace="False" negative="False" numbertype="1" tcsc="0">03c</chmetcnv>9, 0xc6 / 4);
io_out8(0x<chmetcnv w:st="on" unitname="C" sourcevalue="3" hasspace="False" negative="False" numbertype="1" tcsc="0">03c</chmetcnv>9, 0x84 / 4);
io_out8(0x<chmetcnv w:st="on" unitname="C" sourcevalue="3" hasspace="False" negative="False" numbertype="1" tcsc="0">03c</chmetcnv>9, 0x00 / 4);
io_out8(0x<chmetcnv w:st="on" unitname="C" sourcevalue="3" hasspace="False" negative="False" numbertype="1" tcsc="0">03c</chmetcnv>9, 0x00 / 4);
io_out8(0x<chmetcnv w:st="on" unitname="C" sourcevalue="3" hasspace="False" negative="False" numbertype="1" tcsc="0">03c</chmetcnv>9, 0x00 / 4);
io_out8(0x<chmetcnv w:st="on" unitname="C" sourcevalue="3" hasspace="False" negative="False" numbertype="1" tcsc="0">03c</chmetcnv>9, 0x84 / 4);
io_out8(0x<chmetcnv w:st="on" unitname="C" sourcevalue="3" hasspace="False" negative="False" numbertype="1" tcsc="0">03c</chmetcnv>9, 0x00 / 4);
io_out8(0x<chmetcnv w:st="on" unitname="C" sourcevalue="3" hasspace="False" negative="False" numbertype="1" tcsc="0">03c</chmetcnv>9, 0x84 / 4);
io_out8(0x<chmetcnv w:st="on" unitname="C" sourcevalue="3" hasspace="False" negative="False" numbertype="1" tcsc="0">03c</chmetcnv>9, 0x84 / 4);
io_out8(0x<chmetcnv w:st="on" unitname="C" sourcevalue="3" hasspace="False" negative="False" numbertype="1" tcsc="0">03c</chmetcnv>9, 0x00 / 4);
io_out8(0x<chmetcnv w:st="on" unitname="C" sourcevalue="3" hasspace="False" negative="False" numbertype="1" tcsc="0">03c</chmetcnv>9, 0x00 / 4);
io_out8(0x<chmetcnv w:st="on" unitname="C" sourcevalue="3" hasspace="False" negative="False" numbertype="1" tcsc="0">03c</chmetcnv>9, 0x00 / 4);
io_out8(0x<chmetcnv w:st="on" unitname="C" sourcevalue="3" hasspace="False" negative="False" numbertype="1" tcsc="0">03c</chmetcnv>9, 0x84 / 4);
io_out8(0x<chmetcnv w:st="on" unitname="C" sourcevalue="3" hasspace="False" negative="False" numbertype="1" tcsc="0">03c</chmetcnv>9, 0x84 / 4);
io_out8(0x<chmetcnv w:st="on" unitname="C" sourcevalue="3" hasspace="False" negative="False" numbertype="1" tcsc="0">03c</chmetcnv>9, 0x00 / 4);
io_out8(0x<chmetcnv w:st="on" unitname="C" sourcevalue="3" hasspace="False" negative="False" numbertype="1" tcsc="0">03c</chmetcnv>9, 0x84 / 4);
io_out8(0x<chmetcnv w:st="on" unitname="C" sourcevalue="3" hasspace="False" negative="False" numbertype="1" tcsc="0">03c</chmetcnv>9, 0x84 / 4);
io_out8(0x<chmetcnv w:st="on" unitname="C" sourcevalue="3" hasspace="False" negative="False" numbertype="1" tcsc="0">03c</chmetcnv>9, 0x84 / 4);
io_out8(0x<chmetcnv w:st="on" unitname="C" sourcevalue="3" hasspace="False" negative="False" numbertype="1" tcsc="0">03c</chmetcnv>9, 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++) {
</f