首页 > 代码库 > 《30天自制操作系统》读书笔记(4) 绘图
《30天自制操作系统》读书笔记(4) 绘图
暑假果然是滋生懒散的温床. (╯‵□′)╯︵┻━┻
好久不动都忘记之前做到哪里了, 上次好像做到了C语言的引入, 这一节所做的东西都相当轻松, 将会绘制出操作系统的基本界面.
- 绘图的原理
按照书中所说, 将值写入到显存中就能在屏幕上显示相应的像素, 在asmhead.nas 中有这一段:
1 CYLS EQU 0x0ff0 ; 设定启动区 2 LEDS EQU 0x0ff1 3 VMODE EQU 0x0ff2 ; 关于颜色数目的信息,颜色的位数 4 SCRNX EQU 0x0ff4 ; 分辨率 X(Screen X) 5 SCRNY EQU 0x0ff6 ; 分辨率 Y(Screen Y) 6 VRAM EQU 0x0ff8 ; 图像缓冲区的起始地址 7 8 ORG 0xc200 9 10 11 12 MOV AL,0x13 ; VGA 显卡 13 MOV AH,0x0014 INT 0x1015 MOV BYTE [VMODE],8 ; 记录画面模式 16 MOV WORD [SCRNX],32017 MOV WORD [SCRNY],20018 MOV DWORD [VRAM],0x000a0000
调用十号中断来指定显卡模式, 后面的几个MOV指令用来储存和显示有关的关键信息(为什么不直接用常量呢?), 在bootpack.c中有
1 struct BOOTINFO { /* 0x0ff0-0x0fff */2 char cyls; /* 启动区读硬盘读到何处为止 */3 char leds; /* 启动时LED的状态*/4 char vmode; /* 显卡模式*/5 char reserve;6 short scrnx, scrny; /* 分辨率*/7 char *vram;8 };
这里就将结构体指针指向了这些信息, 可以知道VRAM的地址是0xa0000想指定地址写入数据, 当然是用指针, 将VRAM声明为一个数组即可.
作者顺便指出了数组的操作array[index] 仅是一个语法糖, a[i] 等价于*(a + i), 当然也等价于*(i + a), 所以很神奇的, a[i] 和 i[a] 在C语言里是等效的.
- 设定调色板
作者替我们指定了300x200 8位的颜色模式, 如何将 0xffffff 的颜色值映射0~0xfff的空间里? 一一对应显然是不可能的, 事实上8位色彩模式中, 0到0xfff这255中颜色是由我们自己指定的, 譬如说0可以对应红色0xff0000, 这种对应关系显然被储存起来, 这就是调色板(palette),作者给出了16中颜色的对应关系, 其中14号色被我改了, 调色板的数据结构如下(就一个unsigned char数组):
1 static unsigned char table_rgb[16 * 3] = 2 { 3 0x00, 0x00, 0x00, /* 0:黑色*/ 4 0xff, 0x00, 0x00, /* 1:亮红*/ 5 0x00, 0xff, 0x00, /* 2:亮绿*/ 6 0xff, 0xff, 0x00, /* 3:亮黄*/ 7 0x00, 0x00, 0xff, /* 4:亮蓝*/ 8 0xff, 0x00, 0xff, /* 5:亮紫*/ 9 0x00, 0xff, 0xff, /* 6:浅亮蓝*/10 0xff, 0xff, 0xff, /* 7:白色*/11 0xc6, 0xc6, 0xc6, /* 8:亮灰*/12 0x84, 0x00, 0x00, /* 9:暗红*/13 0x00, 0x84, 0x00, /* 10:暗绿*/14 0x84, 0x84, 0x00, /* 11:暗黄*/15 0x00, 0x00, 0x84, /* 12:暗青*/16 0x84, 0x00, 0x84, /* 13:暗紫*/17 0x5b, 0x9b, 0xd5, /* 14:浅灰蓝5B,9B,D5*/18 0x84, 0x84, 0x84 /* 15:暗灰*/19 };
如何让我们设置调色板生效? 作者给出了如下步骤:
这里的0x03c9 是设备端口号, 屏蔽和恢复中断使用CLI和STI两个指令, 在naskfunc.nas里面封装成了函数io_cli(); 和 io_stl(), CLI(Clear interrupt flag) 将中断标志(interrupt flag)置零, STI(Set interrupt flag)则是将中断标志置一. 设置调色板的时候需要屏蔽中断, 但不知道当前的状态是什么, 所以在CLI之前要保存中断标志的状态. 中断标志保存在32位寄存器EFLAGS上, 由16位的FLAGS扩展而来, 下图应该是FLAGS 的示意图:中断标志位于第9位. 0 位是进位标志, 2是奇偶标志, 4 是辅助进位标志, 6是零标志, 7是符号标志, 8,10额…忘了, 11是溢出标志…使用指令PUSHFD和POPFD储存和恢复整个EFLAGS的状态, 封装为io_load_eflags()函数和io_store_eflags(eflags)函数.
对端口的读写要使用IN 指令和 OUT指令, 注意这里的IN是读取而OUT是写入.
结合以上的知识, 设置调色板的函数如下:
1 void set_palette(int start, int end, unsigned char *rgb) 2 { 3 int i, eflags; 4 eflags = io_load_eflags(); /*记录中断标志的值 */ 5 io_cli(); /*禁止中断 */ 6 io_out8(0x03c8, start); 7 for (i = start; i <= end; i++) 8 { 9 io_out8(0x03c9, rgb[0] / 4); 10 io_out8(0x03c9, rgb[1] / 4);11 io_out8(0x03c9, rgb[2] / 4);12 rgb += 3;13 }14 io_store_eflags(eflags); /* 恢复中断标志*/15 return;16 }
有个疑惑便是rgb[0] 为什么要除以四再写入, 如果去掉这一句颜色会变得很灰…有谁知道的还望告知…(/4不就是往左移动两位?)
- 绘制界面
我们写了一个叫做boxfill8的函数用来绘制矩形, 并用它来构建我们的基本界面:
二维屏幕和一维的地址换算关系如下: addr = 0xa0000 + x + y * 320
void boxfill8(unsigned char *vram, int xsize, unsigned char c, int x0, int y0, int x1, int y1);
参数的意思分别是: 显存地址, 换算参数(屏幕宽度), 颜色, 矩形的四个点.
使用以下的代码画出界面:
1 void init_screen8(char *vram, int x, int y) 2 { 3 boxfill8(vram, x, COL8_008484, 0, 0, x - 1, y - 29); //绘制桌面填充灰蓝色 4 boxfill8(vram, x, COL8_C6C6C6, 0, y - 28, x - 1, y - 28); //第一条阴影 5 boxfill8(vram, x, COL8_FFFFFF, 0, y - 27, x - 1, y - 27); //绘制第二条阴影 6 boxfill8(vram, x, COL8_C6C6C6, 0, y - 26, x - 1, y - 1); //绘制任务栏主体 7 8 boxfill8(vram, x, COL8_FFFFFF, 3, y - 24, 59, y - 24); //绘制"开始"按钮 周围六条直线 9 boxfill8(vram, x, COL8_FFFFFF, 2, y - 24, 2, y - 4);10 boxfill8(vram, x, COL8_848484, 3, y - 4, 59, y - 4);11 boxfill8(vram, x, COL8_848484, 59, y - 23, 59, y - 5);12 boxfill8(vram, x, COL8_000000, 2, y - 3, 59, y - 3);13 boxfill8(vram, x, COL8_000000, 60, y - 24, 60, y - 3);14 15 boxfill8(vram, x, COL8_848484, x - 47, y - 24, x - 4, y - 24);//绘制状态栏 四条直线 16 boxfill8(vram, x, COL8_848484, x - 47, y - 23, x - 47, y - 4);17 boxfill8(vram, x, COL8_FFFFFF, x - 47, y - 3, x - 4, y - 3);18 boxfill8(vram, x, COL8_FFFFFF, x - 3, y - 24, x - 3, y - 3);19 return;20 }
得到的界面如下:
屏幕下方左右两个"按钮"放大看:
其实就是在原来的底色上画多了几条直线, 左边的是6条, 右边的是4条.
看情况, 这将会是我们的操作系统的桌面.
- 显示字符
使用了asmhead.nas 后我们进入了32位模式(似乎是保护模式), 不可以使用int 0x13中断了, 因此要显示字符只能自己画.
作者使用8x16 的矩阵来表示一个字符, 不知道真正的字体文件*.ttf是否用这样的方式储存…
换算成16进制是:
这样的表示方法难以调整, 所以作者使用了一个文本文档来描画字体, 在这个文本文档里面8是:
char 0x38...........**.....*..*...*....*..*....*..*....*...*..*.....**.....*..*...*....*..*....*..*....*...*..*.....**...................
然后伟大的作者又搬出了自己的"编译器", makefont.exe, (╯‵□′)╯︵┻━┻), 神烦的"别人家的编译器", 这也意味这Makefile又要改动了…如何画出字符和字符串呢?
写一个很厉害的putfont8函数:
1 void putfont8(char *vram, int xsize, int x, int y, char c, char *font) 2 { 3 int i; 4 char *p, d /* data */; 5 for (i = 0; i < 16; i++) { 6 p = vram + (y + i) * xsize + x; 7 d = font[i]; 8 if ((d & 0x80) != 0) { p[0] = c; } 9 if ((d & 0x40) != 0) { p[1] = c; }10 if ((d & 0x20) != 0) { p[2] = c; }11 if ((d & 0x10) != 0) { p[3] = c; }12 if ((d & 0x08) != 0) { p[4] = c; }13 if ((d & 0x04) != 0) { p[5] = c; }14 if ((d & 0x02) != 0) { p[6] = c; }15 if ((d & 0x01) != 0) { p[7] = c; }16 }17 return;18 }
让特地的数和字体数据相与,判断特定位是否为1, 很厉害的做法.
显示字符串的函数:
1 void putfonts8_asc(char *vram, int xsize, int x, int y, char c, unsigned char *s)2 {3 extern char hankaku[4096];4 for (; *s != 0x00; s++) {5 putfont8(vram, xsize, x, y, c, hankaku + *s * 16);6 x += 8;7 }8 return;9 }
在主函数里调用
1 putfonts8_asc(binfo->vram, binfo->scrnx, 8, 8, COL8_FFFFFF, "ABC 123");2 putfonts8_asc(binfo->vram, binfo->scrnx, 31, 31, COL8_000000, "OS.");3 putfonts8_asc(binfo->vram, binfo->scrnx, 30, 30, COL8_FFFFFF, "OS.");
结果如下:
- 显示变量值
为了显示变量值, 作者使用了名为GO的编译器里的sprintf函数,(这货是GO语言的GO吗?), Sprintf函数就是将指定内容格式化输出到字符流中, 然后我们再将这个字符显示出来, 达到显示变量内容的目的.
添加头文件stdio.h, 主函数加入以下语句:
1 int mx = (binfo->scrnx - 16) / 2; //水平居中2 int my = (binfo->scrny - 28 - 16) / 2; //排除任务栏垂直居中3 sprintf(s, "(%d, %d)", mx, my);4 putfonts8_asc(binfo->vram, binfo->scrnx, 0, 0, COL8_FFFFFF, s);
效果如下:
- 显示鼠标指针
鼠标的显示和字符大同小异, 但是这里使用字符来储存而不是二进制, 因为需要填充色, 边缘色和背景色…作者画的鼠标实在难看, 我用的是@BIT_祝威 写好的鼠标, 特此感谢!
1 /* 16*16 Mouse */ 2 static char cursor[16][16] = { 3 "*...............", 4 "**..............", 5 "*O*.............", 6 "*OO*............", 7 "*OOO*...........", 8 "*OOOO*..........", 9 "*OOOOO*.........",10 "*OOOOOO*........",11 "*OOOOOOO*.......",12 "*OOOO*****......",13 "*OO*O*..........",14 "*O*.*O*.........",15 "**..*O*.........",16 "*....*O*........",17 ".....*O*........",18 "......*........."19 };
事前将上面的图案处理成颜色信息cursor[], 再使用putblock8_8函数将鼠标画出来, 效果如下:
这次就做到这里…按书中的指示将代码分装成几个文件, 下面是当前改动的代码:
这次的大部分代码在graphic.c
1 #include "bootpack.h" 2 3 void init_palette(void) 4 { 5 static unsigned char table_rgb[16 * 3] = 6 { 7 0x00, 0x00, 0x00, /* 0:黑色*/ 8 0xff, 0x00, 0x00, /* 1:亮红*/ 9 0x00, 0xff, 0x00, /* 2:亮绿*/ 10 0xff, 0xff, 0x00, /* 3:亮黄*/ 11 0x00, 0x00, 0xff, /* 4:亮蓝*/ 12 0xff, 0x00, 0xff, /* 5:亮紫*/ 13 0x00, 0xff, 0xff, /* 6:浅亮蓝*/ 14 0xff, 0xff, 0xff, /* 7:白色*/ 15 0xc6, 0xc6, 0xc6, /* 8:亮灰*/ 16 0x84, 0x00, 0x00, /* 9:暗红*/ 17 0x00, 0x84, 0x00, /* 10:暗绿*/ 18 0x84, 0x84, 0x00, /* 11:暗黄*/ 19 0x00, 0x00, 0x84, /* 12:暗青*/ 20 0x84, 0x00, 0x84, /* 13:暗紫*/ 21 0x5b, 0x9b, 0xd5, /* 14:浅灰蓝5B,9B,D5*/ 22 0x84, 0x84, 0x84 /* 15:暗灰*/ 23 }; 24 set_palette(0, 15, table_rgb); 25 return; 26 27 /* static char,储存数据, 相当于DB*/ 28 } 29 30 void set_palette(int start, int end, unsigned char *rgb) 31 { 32 int i, eflags; 33 eflags = io_load_eflags(); /*记录中断标志的值 */ 34 io_cli(); /*禁止中断 */ 35 io_out8(0x03c8, start); 36 for (i = start; i <= end; i++) 37 { 38 io_out8(0x03c9, rgb[0] / 4); 39 io_out8(0x03c9, rgb[1] / 4); 40 io_out8(0x03c9, rgb[2] / 4); 41 rgb += 3; 42 } 43 io_store_eflags(eflags); /* 恢复中断标志*/ 44 return; 45 } 46 47 void boxfill8(unsigned char *vram, int xsize, unsigned char c, int x0, int y0, int x1, int y1) 48 { 49 int x, y; 50 for (y = y0; y <= y1; y++) { 51 for (x = x0; x <= x1; x++) 52 vram[y * xsize + x] = c; 53 } 54 return; 55 } 56 57 void init_screen8(char *vram, int x, int y) 58 { 59 boxfill8(vram, x, COL8_008484, 0, 0, x - 1, y - 29); //绘制桌面填充灰蓝色 60 boxfill8(vram, x, COL8_C6C6C6, 0, y - 28, x - 1, y - 28); //第一条阴影 61 boxfill8(vram, x, COL8_FFFFFF, 0, y - 27, x - 1, y - 27); //绘制第二条阴影 62 boxfill8(vram, x, COL8_C6C6C6, 0, y - 26, x - 1, y - 1); //绘制任务栏主体 63 64 boxfill8(vram, x, COL8_FFFFFF, 3, y - 24, 59, y - 24); //绘制"开始"按钮 周围六条直线 65 boxfill8(vram, x, COL8_FFFFFF, 2, y - 24, 2, y - 4); 66 boxfill8(vram, x, COL8_848484, 3, y - 4, 59, y - 4); 67 boxfill8(vram, x, COL8_848484, 59, y - 23, 59, y - 5); 68 boxfill8(vram, x, COL8_000000, 2, y - 3, 59, y - 3); 69 boxfill8(vram, x, COL8_000000, 60, y - 24, 60, y - 3); 70 71 boxfill8(vram, x, COL8_848484, x - 47, y - 24, x - 4, y - 24);//绘制状态栏 四条直线 72 boxfill8(vram, x, COL8_848484, x - 47, y - 23, x - 47, y - 4); 73 boxfill8(vram, x, COL8_FFFFFF, x - 47, y - 3, x - 4, y - 3); 74 boxfill8(vram, x, COL8_FFFFFF, x - 3, y - 24, x - 3, y - 3); 75 return; 76 } 77 78 void putfont8(char *vram, int xsize, int x, int y, char c, char *font) 79 { 80 int i; 81 char *p, d /* data */; 82 for (i = 0; i < 16; i++) { 83 p = vram + (y + i) * xsize + x; 84 d = font[i]; 85 if ((d & 0x80) != 0) { p[0] = c; } 86 if ((d & 0x40) != 0) { p[1] = c; } 87 if ((d & 0x20) != 0) { p[2] = c; } 88 if ((d & 0x10) != 0) { p[3] = c; } 89 if ((d & 0x08) != 0) { p[4] = c; } 90 if ((d & 0x04) != 0) { p[5] = c; } 91 if ((d & 0x02) != 0) { p[6] = c; } 92 if ((d & 0x01) != 0) { p[7] = c; } 93 } 94 return; 95 } 96 97 void putfonts8_asc(char *vram, int xsize, int x, int y, char c, unsigned char *s) 98 { 99 extern char hankaku[4096];100 for (; *s != 0x00; s++) {101 putfont8(vram, xsize, x, y, c, hankaku + *s * 16);102 x += 8;103 }104 return;105 }106 107 void init_mouse_cursor8(char *mouse, char bc)108 /* 16*16 Mouse */109 {110 static char cursor[16][16] = {111 "*...............",112 "**..............",113 "*O*.............",114 "*OO*............",115 "*OOO*...........",116 "*OOOO*..........",117 "*OOOOO*.........",118 "*OOOOOO*........",119 "*OOOOOOO*.......",120 "*OOOO*****......",121 "*OO*O*..........",122 "*O*.*O*.........",123 "**..*O*.........",124 "*....*O*........",125 ".....*O*........",126 "......*........."127 };128 int x, y;129 130 for (y = 0; y < 16; y++) {131 for (x = 0; x < 16; x++) {132 if (cursor[y][x] == ‘*‘) {133 mouse[y * 16 + x] = COL8_000000;134 }135 if (cursor[y][x] == ‘O‘) {136 mouse[y * 16 + x] = COL8_FFFFFF;137 }138 if (cursor[y][x] == ‘.‘) {139 mouse[y * 16 + x] = bc;140 }141 }142 }143 return;144 }145 146 void putblock8_8(char *vram, int vxsize, int pxsize,147 int pysize, int px0, int py0, char *buf, int bxsize)148 {149 int x, y;150 for (y = 0; y < pysize; y++) {151 for (x = 0; x < pxsize; x++) {152 vram[(py0 + y) * vxsize + (px0 + x)] = buf[y * bxsize + x];153 }154 }155 return;156 }
bootpack.c
1 #include <stdio.h> 2 #include "bootpack.h" 3 4 void HariMain(void) 5 { 6 struct BOOTINFO *binfo = (struct BOOTINFO *) 0x0ff0; 7 char s[40], mcursor[256]; 8 int mx, my; 9 10 init_gdtidt();11 init_palette();12 init_screen8(binfo->vram, binfo->scrnx, binfo->scrny);13 mx = (binfo->scrnx - 16) / 2; //水平居中 14 my = (binfo->scrny - 28 - 16) / 2; //排除任务栏垂直居中15 init_mouse_cursor8(mcursor, COL8_008484);16 putblock8_8(binfo->vram, binfo->scrnx, 16, 16, mx, my, mcursor, 16);17 sprintf(s, "(%d, %d)", mx, my);18 putfonts8_asc(binfo->vram, binfo->scrnx, 0, 0, COL8_FFFFFF, s);19 20 for (;;)21 {22 io_hlt();23 }24 }
bootpack.h
1 /* asmhead.nas */ 2 struct BOOTINFO { /* 0x0ff0-0x0fff */ 3 char cyls; /* 启动区读硬盘读到何处为止 */ 4 char leds; /* 启动时LED的状态*/ 5 char vmode; /* 显卡模式*/ 6 char reserve; 7 short scrnx, scrny; /* 分辨率*/ 8 char *vram; 9 };10 #define ADR_BOOTINFO 0x00000ff011 12 /* naskfunc.nas */13 void io_hlt(void);14 void io_cli(void);15 void io_out8(int port, int data);16 int io_load_eflags(void);17 void io_store_eflags(int eflags);18 void load_gdtr(int limit, int addr);19 void load_idtr(int limit, int addr);20 21 /* graphic.c */22 void init_palette(void);23 void set_palette(int start, int end, unsigned char *rgb);24 void boxfill8(unsigned char *vram, int xsize, unsigned char c, int x0, int y0, int x1, int y1);25 void init_screen8(char *vram, int x, int y);26 void putfont8(char *vram, int xsize, int x, int y, char c, char *font);27 void putfonts8_asc(char *vram, int xsize, int x, int y, char c, unsigned char *s);28 void init_mouse_cursor8(char *mouse, char bc);29 void putblock8_8(char *vram, int vxsize, int pxsize,30 int pysize, int px0, int py0, char *buf, int bxsize);31 #define COL8_000000 032 #define COL8_FF0000 133 #define COL8_00FF00 234 #define COL8_FFFF00 335 #define COL8_0000FF 436 #define COL8_FF00FF 537 #define COL8_00FFFF 638 #define COL8_FFFFFF 739 #define COL8_C6C6C6 840 #define COL8_840000 941 #define COL8_008400 1042 #define COL8_848400 1143 #define COL8_000084 1244 #define COL8_840084 1345 #define COL8_008484 1446 #define COL8_848484 1547 48 /* dsctbl.c */49 struct SEGMENT_DESCRIPTOR {50 short limit_low, base_low;51 char base_mid, access_right;52 char limit_high, base_high;53 };54 struct GATE_DESCRIPTOR {55 short offset_low, selector;56 char dw_count, access_right;57 short offset_high;58 };59 void init_gdtidt(void);60 void set_segmdesc(struct SEGMENT_DESCRIPTOR *sd, unsigned int limit, int base, int ar);61 void set_gatedesc(struct GATE_DESCRIPTOR *gd, int offset, int selector, int ar);62 #define ADR_IDT 0x0026f80063 #define LIMIT_IDT 0x000007ff64 #define ADR_GDT 0x0027000065 #define LIMIT_GDT 0x0000ffff66 #define ADR_BOTPAK 0x0028000067 #define LIMIT_BOTPAK 0x0007ffff68 #define AR_DATA32_RW 0x409269 #define AR_CODE32_ER 0x409a
naskfunc.nas
1 ;naskfunc 2 3 [FORMAT "WCOFF"] ; 制作目标文件的模式 4 [INSTRSET "i486p"] 5 [BITS 32] ; 制作32位模式用的机器语言 6 7 8 [FILE "naskfunc.nas"] ; 源文件名信息 9 10 ; 程序中包含的函数名11 GLOBAL _io_hlt, _io_cli, _io_sti, _io_stihlt12 GLOBAL _io_in8, _io_in16, _io_in3213 GLOBAL _io_out8, _io_out16, _io_out3214 GLOBAL _io_load_eflags, _io_store_eflags15 GLOBAL _load_gdtr, _load_idtr 16 17 ; 实际的函数18 19 [SECTION .text] ;20 21 _io_hlt: 22 HLT23 RET24 _io_cli: ; void io_cli(void);25 CLI26 RET27 28 _io_sti: ; void io_sti(void);29 STI30 RET31 32 _io_stihlt: ; void io_stihlt(void);33 STI34 HLT35 RET36 37 _io_in8: ; int io_in8(int port);38 MOV EDX,[ESP+4] ; port39 MOV EAX,040 IN AL,DX41 RET42 43 _io_in16: ; int io_in16(int port);44 MOV EDX,[ESP+4] ; port45 MOV EAX,046 IN AX,DX47 RET48 49 _io_in32: ; int io_in32(int port);50 MOV EDX,[ESP+4] ; port51 IN EAX,DX52 RET53 54 _io_out8: ; void io_out8(int port, int data);55 MOV EDX,[ESP+4] ; port56 MOV AL,[ESP+8] ; data57 OUT DX,AL58 RET59 60 _io_out16: ; void io_out16(int port, int data);61 MOV EDX,[ESP+4] ; port62 MOV EAX,[ESP+8] ; data63 OUT DX,AX64 RET65 66 _io_out32: ; void io_out32(int port, int data);67 MOV EDX,[ESP+4] ; port68 MOV EAX,[ESP+8] ; data69 OUT DX,EAX70 RET71 72 _io_load_eflags: ; int io_load_eflags(void);73 PUSHFD ; PUSH EFLAGS 74 POP EAX75 RET76 77 _io_store_eflags: ; void io_store_eflags(int eflags);78 MOV EAX,[ESP+4]79 PUSH EAX80 POPFD ; POP EFLAGS 81 RET82 83 _load_gdtr: ; void load_gdtr(int limit, int addr);84 MOV AX,[ESP+4] ; limit85 MOV [ESP+6],AX86 LGDT [ESP+6]87 RET88 89 _load_idtr: ; void load_idtr(int limit, int addr);90 MOV AX,[ESP+4] ; limit91 MOV [ESP+6],AX92 LIDT [ESP+6]93 RET
Makefile
1 OBJS_BOOTPACK = bootpack.obj naskfunc.obj hankaku.obj graphic.obj dsctbl.obj 2 3 TOOLPATH = ../z_tools/ 4 INCPATH = ../z_tools/haribote/ 5 6 MAKE = $(TOOLPATH)make.exe -r 7 NASK = $(TOOLPATH)nask.exe 8 CC1 = $(TOOLPATH)cc1.exe -I$(INCPATH) -Os -Wall -quiet 9 GAS2NASK = $(TOOLPATH)gas2nask.exe -a10 OBJ2BIM = $(TOOLPATH)obj2bim.exe11 MAKEFONT = $(TOOLPATH)makefont.exe12 BIN2OBJ = $(TOOLPATH)bin2obj.exe13 BIM2HRB = $(TOOLPATH)bim2hrb.exe14 RULEFILE = $(TOOLPATH)haribote/haribote.rul15 EDIMG = $(TOOLPATH)edimg.exe16 DEL = del17 SHORTCUT = "D:\Program Files\Oracle\VirtualBox\VirtualBox.exe" --comment "OS1" --startvm "a5c4b0e6-e142-4720-98ee-056911204b29"18 19 default :20 $(MAKE) install21 $(MAKE) run22 $(MAKE) clean23 24 ipl10.bin : ipl10.nas Makefile25 $(NASK) ipl10.nas ipl10.bin ipl10.lst26 27 asmhead.bin : asmhead.nas Makefile28 $(NASK) asmhead.nas asmhead.bin asmhead.lst29 30 hankaku.bin : hankaku.txt Makefile31 $(MAKEFONT) hankaku.txt hankaku.bin32 33 hankaku.obj : hankaku.bin Makefile34 $(BIN2OBJ) hankaku.bin hankaku.obj _hankaku35 36 bootpack.bim : $(OBJS_BOOTPACK) Makefile37 $(OBJ2BIM) @$(RULEFILE) out:bootpack.bim stack:3136k map:bootpack.map 38 $(OBJS_BOOTPACK)39 # 3MB+64KB=3136KB40 41 bootpack.hrb : bootpack.bim Makefile42 $(BIM2HRB) bootpack.bim bootpack.hrb 043 44 haribote.sys :asmhead.bin bootpack.hrb Makefile45 copy /B asmhead.bin+bootpack.hrb haribote.sys46 47 haribote.img : ipl10.bin haribote.sys Makefile48 $(EDIMG) imgin:../z_tools/fdimg0at.tek 49 wbinimg src:ipl10.bin len:512 from:0 to:0 50 copy from:haribote.sys to:@: 51 imgout:haribote.img52 53 %.gas : %.c Makefile54 $(CC1) -o $*.gas $*.c55 56 %.nas : %.gas Makefile57 $(GAS2NASK) $*.gas $*.nas58 59 %.obj : %.nas Makefile60 $(NASK) $*.nas $*.obj $*.lst61 62 install:63 $(MAKE) haribote.img64 65 run :66 echo Running... 67 $(SHORTCUT)68 echo Finished69 70 clean :71 -$(DEL) *.bin72 -$(DEL) *.lst73 -$(DEL) *.gas74 -$(DEL) *.obj75 -$(DEL) bootpack.nas76 -$(DEL) bootpack.map77 -$(DEL) bootpack.bim78 -$(DEL) bootpack.hrb79 -$(DEL) haribote.sys80 -$(DEL) *.*~81 -$(DEL) *~82 echo Cleaned.