<30天自制操作系统>第五天
来源:互联网 发布:监测 移动数据造假 编辑:程序博客网 时间:2024/04/29 21:23
这章节内容比上一章节的更进了一步,不只是显示图像,而是显示文字。一个字符可以用8x16的长方形像素点阵来表示。例如:
将这些数据整理成一组数组,即static char font_A[16] = {0x00, 0x18, 0x18, 0x18, 0x18…}
有了这些数据之后只需将其写到VRAM中即可,下列函数实现该功能:
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 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)/* 准备鼠标指针(16x16) */{ static char cursor[16][16] = { "**************..", "*OOOOOOOOOOO*...", "*OOOOOOOOOO*....", "*OOOOOOOOO*.....", "*OOOOOOOO*......", "*OOOOOOO*.......", "*OOOOOOO*.......", "*OOOOOOOO*......", "*OOOO**OOO*.....", "*OOO*..*OOO*....", "*OO*....*OOO*...", "*O*......*OOO*..", "**........*OOO*.", "*..........*OOO*", "............*OO*", ".............***" }; int x, y; for (y = 0; y < 16; y++) { for (x = 0; x < 16; x++) { if (cursor[y][x] == '*') { mouse[y * 16 + x] = COL8_000000; //黑色 } if (cursor[y][x] == 'O') { mouse[y * 16 + x] = COL8_FFFFFF; //白色 } if (cursor[y][x] == '.') { mouse[y * 16 + x] = bc; //bc背景色 } } } return;}/* 以下函数将buf中的数据复制到vram中 * vram, vxsize是关于VRAM的信息,pxsize和pysize是想要 * 显示的图形的大小。px0和py0指定图形在画面上的显示位置 * 最后的buf和bxsize分别指定图形的存放地址和每一行含有的像素数 */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]; } } return;}接下来只需要使用以下两个函数即可:init_mouse_cursor8(mcursor, COL8_008484);putblock8(binfo->vram, binfo->scrnx, 16, 16, mx, my, mcursor, 16);
至此鼠标图形已经可以显示出来,但却无法移动。要让它移动首先要初始化GDT和IDT。它们两个都是与CPU有关的设定。GDT是全局段号记录表,而IDT则是中断记录表。
在这之前首先要了解什么是段还有为什么分段。操作系统能同时运行多个程序,这种时候内存使用范围重叠怎么办,所以就要分段。分段则是将合计4GB内存分成很多块,每一块的起始地址都看作0来处理,任何程序都可以先写上ORG 0。
为了表示一个段,需要以下信息:
段的大小是多少
段的起始地址在哪里
段的管理属性(禁止写入,禁止执行,系统专用等)
段寄存器只有16位,可以模仿图像调色板的做法,先有一个段号,存放在寄存器里,然后预先设计好段号与段的对应关系
在调色板中,色号可以使用0~255的数,段号可以使用0~8191的数,虽然段寄存器是16位,但是低3位不能使用。
关于GDT设定如下:
struct SEGMENT_DESCRIPTOR { short limit_low, base_low; char base_mid, access_right; char limit_high, base_high;};struct GATE_DESCRIPTOR { short offset_low, selector; char dw_count, access_right; short offset_high;};void init_gdtidt(void){ struct SEGMENT_DESCRIPTOR *gdt = (struct SEGMENT_DESCRIPTOR *) 0x00270000; struct GATE_DESCRIPTOR *idt = (struct GATE_DESCRIPTOR *) 0x0026f800; int i; /* GDT的初始化 */ for (i = 0; i < 8192; i++) { set_segmdesc(gdt + i, 0, 0, 0); } set_segmdesc(gdt + 1, 0xffffffff, 0x00000000, 0x4092); set_segmdesc(gdt + 2, 0x0007ffff, 0x00280000, 0x409a); load_gdtr(0xffff, 0x00270000); /* IDT的初始化 */ for (i = 0; i < 256; i++) { set_gatedesc(idt + i, 0, 0, 0); } load_idtr(0x7ff, 0x0026f800); return;}void set_segmdesc(struct SEGMENT_DESCRIPTOR *sd, unsigned int limit, int base, int ar){ if (limit > 0xfffff) { ar |= 0x8000; /* G_bit = 1 */ limit /= 0x1000; } sd->limit_low = limit & 0xffff; sd->base_low = base & 0xffff; sd->base_mid = (base >> 16) & 0xff; sd->access_right = ar & 0xff; sd->limit_high = ((limit >> 16) & 0x0f) | ((ar >> 8) & 0xf0); sd->base_high = (base >> 24) & 0xff; return;}void set_gatedesc(struct GATE_DESCRIPTOR *gd, int offset, int selector, int ar){ gd->offset_low = offset & 0xffff; gd->selector = selector; gd->dw_count = (ar >> 8) & 0xff; gd->access_right = ar & 0xff; gd->offset_high = (offset >> 16) & 0xffff; return;}
0 0
- 30天自制操作系统-第五天
- <30天自制操作系统>第五天
- 《30天自制操作系统》学习笔记——第五天
- 《30天自制操作系统》学习笔记——第十五天
- 《30天自制操作系统》第0天
- 《30天自制操作系统》第1天
- 《30天自制操作系统》第2天
- 《30天自制操作系统》第3天
- 《30天自制操作系统》第4天
- 《30天自制操作系统》第5天
- 《30天自制操作系统》第6天
- 30天自制操作系统-第3天
- 《30天自制操作系统》第一天
- 30天自制操作系统-第一天
- 30天自制操作系统-第三天
- 30天自制操作系统-第七天
- 30天自制操作系统-第八天
- 30天自制操作系统-第九天
- jsp遍历map集合
- node.js 使用createServer创建最基础的node应用。
- 考察一下你对js继承链的理解
- 1012. 数字分类 (20)-PAT乙级真题
- jquery入门
- <30天自制操作系统>第五天
- java.io.EOFException: No content to map to Object due to end of input
- freeradius2 限制流量
- 1010. 一元多项式求导 (25)-PAT乙级真题
- C语言算法知识(201607)-小结
- hdu 5744 Keep On Movin
- 项目开发常见流程
- 1009. 说反话 (20)-PAT乙级真题
- log4jdbc记录全部SQL日志