1、本次主要进展
>_<" 这次主要学习了系统内存管理和窗口叠加~由于上两篇都做了详细的框架说明和介绍,这里直接上代码!
2、文件及函数构成
>_<" 这里和第二篇相比,把鼠标和键盘的相关函数独立出来放进各自相应的文件中,并主要在内存管理和窗口叠加进行探索,同时还有部分代码整理~
1 /* In this file, not only have the defination of the function, but also 2 hava the description of where the function is.*/ 3 4 /* asmhead.nas */ 5 struct BOOTINFO { /* 0x0ff0-0x0fff */ 6 char cyls; /* what‘s the end of the start zone read the data */ 7 char leds; /* when boot,the LED‘s state of the keyboard */ 8 char vmode; /* GPU mode:how many bits of color */ 9 char reserve; 10 short scrnx, scrny; /* resolution */ 11 char *vram; 12 }; 13 #define ADR_BOOTINFO 0x00000ff0 14 15 /* naskfunc.nas */ 16 void io_hlt(void); 17 void io_cli(void); 18 void io_sti(void); 19 void io_stihlt(void); 20 int io_in8(int port); 21 void io_out8(int port, int data); 22 int io_load_eflags(void); 23 void io_store_eflags(int eflags); 24 void load_gdtr(int limit, int addr); 25 void load_idtr(int limit, int addr); 26 int load_cr0(void);///////// 27 void store_cr0(int cr0);///////// 28 void asm_inthandler21(void); 29 void asm_inthandler27(void); 30 void asm_inthandler2c(void); 31 unsigned int memtest_sub(unsigned int start, unsigned int end);///////// 32 33 /* fifo.c */ 34 struct FIFO8 {//FIFO缓冲区数据结构 35 unsigned char *buf;//缓冲区 36 int p, q, size, free, flags;//下一个数据的写入地址,下一个数据的读出地址,缓冲区的大小,free是缓冲区没有数据的字节数,flag是是否溢出 37 }; 38 39 void fifo8_init(struct FIFO8 *fifo, int size, unsigned char *buf); 40 int fifo8_put(struct FIFO8 *fifo, unsigned char data); 41 int fifo8_get(struct FIFO8 *fifo); 42 int fifo8_status(struct FIFO8 *fifo); 43 44 /* graphic.c */ 45 void init_palette(void); 46 void set_palette(int start, int end, unsigned char *rgb); 47 void boxfill8(unsigned char *vram, int xsize, unsigned char c, int x0, int y0, int x1, int y1); 48 void init_screen8(char *vram, int x, int y); 49 void putfont8(char *vram, int xsize, int x, int y, char c, char *font); 50 void putfonts8_asc(char *vram, int xsize, int x, int y, char c, unsigned char *s); 51 void init_mouse_cursor8(char *mouse, char bc); 52 void putblock8_8(char *vram, int vxsize, int pxsize, 53 int pysize, int px0, int py0, char *buf, int bxsize); 54 #define COL8_000000 0 55 #define COL8_FF0000 1 56 #define COL8_00FF00 2 57 #define COL8_FFFF00 3 58 #define COL8_0000FF 4 59 #define COL8_FF00FF 5 60 #define COL8_00FFFF 6 61 #define COL8_FFFFFF 7 62 #define COL8_C6C6C6 8 63 #define COL8_840000 9 64 #define COL8_008400 10 65 #define COL8_848400 11 66 #define COL8_000084 12 67 #define COL8_840084 13 68 #define COL8_008484 14 69 #define COL8_848484 15 70 71 /* dsctbl.c about GDT IDT that‘s Global Descriptor Table and Interrupt Descriptor Table*/ 72 struct SEGMENT_DESCRIPTOR {//8 bytes segment infomation,total 8192 parts [here similar to the method of the setting palette] 73 short limit_low, base_low;//address of segment base[high:mid:low=1:1:2]=4 bytes =32 bits 74 char base_mid, access_right;//segment limit[high:low=1:2],only 20 bits = high byte‘s low 4 bits + low 2bytes‘ 16bits 75 char limit_high, base_high;//segment property access[limit_high:right=1:1],only 12 bits = limit_high‘s high 4 bits + access_right‘s 8 bits 76 }; 77 //PS 1):segment limit equals the number of GDT‘s effective bytes -1 78 //PS 2):the segment limit just only has 20 bits, which can represent 1MB, and the segment property has 1 bit flag, 79 //if this flag =1,and the limit‘s unit uses page to replace byte(here 1 page = 4kb) 80 //PS 3):the segment property has 16 bits liking that:xxxx0000 xxxxxxxx 81 //the high 4 bits are extended access 82 //the low 8 bits are: 83 // 0x00:unused description table 84 // 0x92:system exclusive,readable and writable,non-executable 85 // 0x9a:system exclusive,readable and non-writable,executable 86 // 0xf2:application useing,readable and writable,non-executable 87 // 0xfa:application useing,readable and non-writable,executable 88 89 struct GATE_DESCRIPTOR {// 90 short offset_low, selector; 91 char dw_count, access_right; 92 short offset_high; 93 }; 94 void init_gdtidt(void); 95 void set_segmdesc(struct SEGMENT_DESCRIPTOR *sd, unsigned int limit, int base, int ar); 96 void set_gatedesc(struct GATE_DESCRIPTOR *gd, int offset, int selector, int ar); 97 #define ADR_IDT 0x0026f800 98 #define LIMIT_IDT 0x000007ff 99 #define ADR_GDT 0x00270000 100 #define LIMIT_GDT 0x0000ffff 101 #define ADR_BOTPAK 0x00280000 102 #define LIMIT_BOTPAK 0x0007ffff 103 #define AR_DATA32_RW 0x4092 104 #define AR_CODE32_ER 0x409a 105 #define AR_INTGATE32 0x008e 106 107 /* int.c */ 108 void init_pic(void); 109 void inthandler27(int *esp); 110 #define PIC0_ICW1 0x0020 111 #define PIC0_OCW2 0x0020 112 #define PIC0_IMR 0x0021 113 #define PIC0_ICW2 0x0021 114 #define PIC0_ICW3 0x0021 115 #define PIC0_ICW4 0x0021 116 #define PIC1_ICW1 0x00a0 117 #define PIC1_OCW2 0x00a0 118 #define PIC1_IMR 0x00a1 119 #define PIC1_ICW2 0x00a1 120 #define PIC1_ICW3 0x00a1 121 #define PIC1_ICW4 0x00a1 122 123 /* keyboard.c */ 124 void inthandler21(int *esp); 125 void wait_KBC_sendready(void); 126 void init_keyboard(void); 127 extern struct FIFO8 keyfifo; 128 #define PORT_KEYDAT 0x0060 129 #define PORT_KEYCMD 0x0064 130 131 /* mouse.c */ 132 struct MOUSE_DEC { 133 unsigned char buf[3], phase; 134 int x, y, btn; 135 }; 136 void inthandler2c(int *esp); 137 void enable_mouse(struct MOUSE_DEC *mdec); 138 int mouse_decode(struct MOUSE_DEC *mdec, unsigned char dat); 139 extern struct FIFO8 mousefifo; 140 141 /* memory.c */ 142 #define MEMMAN_FREES 4090 /* 大约是32KB */ 143 #define MEMMAN_ADDR 0x003c0000 144 struct FREEINFO { /* 可用信息 */ 145 unsigned int addr, size; 146 }; 147 struct MEMMAN { /* 内存管理 */ 148 int frees, maxfrees, lostsize, losts; 149 struct FREEINFO free[MEMMAN_FREES]; 150 }; 151 unsigned int memtest(unsigned int start, unsigned int end); 152 void memman_init(struct MEMMAN *man); 153 unsigned int memman_total(struct MEMMAN *man); 154 unsigned int memman_alloc(struct MEMMAN *man, unsigned int size); 155 int memman_free(struct MEMMAN *man, unsigned int addr, unsigned int size); 156 unsigned int memman_alloc_4k(struct MEMMAN *man, unsigned int size); 157 int memman_free_4k(struct MEMMAN *man, unsigned int addr, unsigned int size); 158 159 /* sheet.c */ 160 #define MAX_SHEETS 256 161 struct SHEET {//图层结构体 162 unsigned char *buf;//所描绘内容的地址 163 int bxsize, bysize, vx0, vy0, col_inv, height, flags;//图层大小,图层坐标,透明色色号,土层高度,存放有关图层的设定信息 164 struct SHTCTL *ctl; 165 }; 166 struct SHTCTL {//图层管理结构体 167 unsigned char *vram, *map; 168 int xsize, ysize, top; 169 struct SHEET *sheets[MAX_SHEETS]; 170 struct SHEET sheets0[MAX_SHEETS]; 171 };//top存放最上面图层的高度,sheet0图层顺序混乱,要按照升序排列,然后将地址写入sheets中,方便使用 172 struct SHTCTL *shtctl_init(struct MEMMAN *memman, unsigned char *vram, int xsize, int ysize); 173 struct SHEET *sheet_alloc(struct SHTCTL *ctl); 174 void sheet_setbuf(struct SHEET *sht, unsigned char *buf, int xsize, int ysize, int col_inv); 175 void sheet_updown(struct SHEET *sht, int height); 176 void sheet_refresh(struct SHEET *sht, int bx0, int by0, int bx1, int by1); 177 void sheet_slide(struct SHEET *sht, int vx0, int vy0); 178 void sheet_free(struct SHEET *sht);
PS: 这里因为多了几个.c文件,所以makeFile中OBJS_BOOTPACK要把他们加进来~
OBJS_BOOTPACK = bootpack.obj naskfunc.obj hankaku.obj graphic.obj dsctbl.obj int.obj fifo.obj keyboard.obj mouse.obj memory.obj sheet.obj
PS: 为了整体清晰,上面的结构图把bootpack.h和字库文件没有列入~
3、主函数分析
1 /* bootpack */ 2 3 #include "bootpack.h" 4 #include <stdio.h> 5 6 void make_window8(unsigned char *buf, int xsize, int ysize, char *title); 7 8 void HariMain(void) 9 { 10 struct BOOTINFO *binfo = (struct BOOTINFO *) ADR_BOOTINFO; 11 char s[40], keybuf[32], mousebuf[128]; 12 int mx, my, i; 13 unsigned int memtotal, count = 0; 14 struct MOUSE_DEC mdec; 15 struct MEMMAN *memman = (struct MEMMAN *) MEMMAN_ADDR; 16 struct SHTCTL *shtctl; 17 struct SHEET *sht_back, *sht_mouse, *sht_win; 18 unsigned char *buf_back, buf_mouse[256], *buf_win; 19 20 init_gdtidt();//在dsctbl.c中,负责分区和中断分区初始化[包括键盘和鼠标中断设定] 21 init_pic();//在int.c中,负责中断初始化(硬件) 22 io_sti();//在naskfunc.nas中,仅仅执行STI指令,是CLI的逆指令,前者是开中断,后者是禁止中断 23 fifo8_init(&keyfifo, 32, keybuf);//在fifo.c中,负责缓冲区初始化(缓冲区结构体,大小,缓冲区首址) 24 fifo8_init(&mousefifo, 128, mousebuf); 25 /*这里IMR是(interrupt mask register),意思是“中断屏蔽寄存器”,是8位寄存器,分别对应8路IRQ信号,如果一路是1则该路被屏蔽,因为键盘中断是IRQ1,鼠标中断是IRQ12,且PIC分主从2个,从PIC连接主PIC的IRQ2,所以想要有鼠标和键盘中断,要PIC0的IRQ1和IRQ2,和PIC1的IRQ4*/ 26 io_out8(PIC0_IMR, 0xf9); /* (11111001) */ 27 io_out8(PIC1_IMR, 0xef); /* (11101111) */ 28 29 init_keyboard();//初始化键盘控制电路 30 enable_mouse(&mdec);//使能鼠标 31 //memman需要32KB内存 32 memtotal = memtest(0x00400000, 0xbfffffff);//计算总量memtatal 33 memman_init(memman); 34 memman_free(memman, 0x00001000, 0x0009e000); /* 0x00001000 - 0x0009efff 将现在不用的字节以0x1000个字节为单位注册到memman里*/ 35 memman_free(memman, 0x00400000, memtotal - 0x00400000); 36 37 init_palette();//调色板 38 shtctl = shtctl_init(memman, binfo->vram, binfo->scrnx, binfo->scrny);//图层初始化函数 39 sht_back = sheet_alloc(shtctl);//分配一个背景窗口 40 sht_mouse = sheet_alloc(shtctl);//分配一个鼠标窗口 41 sht_win = sheet_alloc(shtctl);//分配一个小窗口 42 buf_back = (unsigned char *) memman_alloc_4k(memman, binfo->scrnx * binfo->scrny);//为背景窗口和普通小窗口分配缓存空间 43 buf_win = (unsigned char *) memman_alloc_4k(memman, 160 * 52); 44 sheet_setbuf(sht_back, buf_back, binfo->scrnx, binfo->scrny, -1); /* 设定涂层缓冲区的大小和透明色的函数 */ 45 sheet_setbuf(sht_mouse, buf_mouse, 16, 16, 99); 46 sheet_setbuf(sht_win, buf_win, 160, 52, -1); /* 设定涂层缓冲区的大小和透明色的函数 */ 47 init_screen8(buf_back, binfo->scrnx, binfo->scrny);//初始化屏幕,画矩形,形成最初的窗口界面 48 init_mouse_cursor8(buf_mouse, 99);//准备鼠标指针(16*16),99是窗口背景颜色 49 make_window8(buf_win, 160, 52, "counter");//就像制作背景和鼠标一样,先准备一张图,然后在图层内描绘一个貌似窗口的图就可以了 50 sheet_slide(sht_back, 0, 0);//上下左右移动窗口,即移动窗口至0,0 51 mx = (binfo->scrnx - 16) / 2; /* 计算鼠标初始位置 */ 52 my = (binfo->scrny - 28 - 16) / 2; 53 sheet_slide(sht_mouse, mx, my);//移动鼠标窗口 54 sheet_slide(sht_win, 80, 72);//移动消息窗口 55 sheet_updown(sht_back, 0);//设置窗口对的高度,背景在最下面 56 sheet_updown(sht_win, 1); 57 sheet_updown(sht_mouse, 2); 58 sprintf(s, "(%3d, %3d)", mx, my);//显示鼠标位置 59 putfonts8_asc(buf_back, binfo->scrnx, 0, 0, COL8_FFFFFF, s); 60 sprintf(s, "memory %dMB free : %dKB", 61 memtotal / (1024 * 1024), memman_total(memman) / 1024); 62 putfonts8_asc(buf_back, binfo->scrnx, 0, 32, COL8_FFFFFF, s); 63 sheet_refresh(sht_back, 0, 0, binfo->scrnx, 48); 64 65 for (;;) { 66 count++; 67 sprintf(s, "%010d", count); 68 boxfill8(buf_win, 160, COL8_C6C6C6, 40, 28, 119, 43);//将消息窗口画出来 69 putfonts8_asc(buf_win, 160, 40, 28, COL8_000000, s);//显示计数器的值 70 sheet_refresh(sht_win, 40, 28, 120, 44);//刷新对应区域 71 72 io_cli(); 73 if (fifo8_status(&keyfifo) + fifo8_status(&mousefifo) == 0) { 74 io_sti(); 75 } else { 76 if (fifo8_status(&keyfifo) != 0) { 77 i = fifo8_get(&keyfifo);//获取按键消息并显示 78 io_sti(); 79 sprintf(s, "%02X", i); 80 boxfill8(buf_back, binfo->scrnx, COL8_008484, 0, 16, 15, 31); 81 putfonts8_asc(buf_back, binfo->scrnx, 0, 16, COL8_FFFFFF, s); 82 sheet_refresh(sht_back, 0, 16, 16, 32); 83 } else if (fifo8_status(&mousefifo) != 0) { 84 i = fifo8_get(&mousefifo); 85 io_sti(); 86 if (mouse_decode(&mdec, i) != 0) { 87 sprintf(s, "[lcr %4d %4d]", mdec.x, mdec.y); 88 if ((mdec.btn & 0x01) != 0) { 89 s[1] = ‘L‘; 90 } 91 if ((mdec.btn & 0x02) != 0) { 92 s[3] = ‘R‘; 93 } 94 if ((mdec.btn & 0x04) != 0) { 95 s[2] = ‘C‘; 96 } 97 boxfill8(buf_back, binfo->scrnx, COL8_008484, 32, 16, 32 + 15 * 8 - 1, 31); 98 putfonts8_asc(buf_back, binfo->scrnx, 32, 16, COL8_FFFFFF, s); 99 sheet_refresh(sht_back, 32, 16, 32 + 15 * 8, 32); 100 /* 移动鼠标 */ 101 mx += mdec.x; 102 my += mdec.y; 103 if (mx < 0) { 104 mx = 0; 105 } 106 if (my < 0) { 107 my = 0; 108 } 109 if (mx > binfo->scrnx - 1) { 110 mx = binfo->scrnx - 1; 111 } 112 if (my > binfo->scrny - 1) { 113 my = binfo->scrny - 1; 114 } 115 sprintf(s, "(%3d, %3d)", mx, my); 116 boxfill8(buf_back, binfo->scrnx, COL8_008484, 0, 0, 79, 15); /* 嵗昗徚偡 */ 117 putfonts8_asc(buf_back, binfo->scrnx, 0, 0, COL8_FFFFFF, s); /* 嵗昗彂偔 */ 118 sheet_refresh(sht_back, 0, 0, 80, 16); 119 sheet_slide(sht_mouse, mx, my); 120 } 121 } 122 } 123 } 124 } 125 ///////////////////////////////////////////////////////////////////////////////////// 126 //功能:就像制作背景和鼠标一样,先准备一张图,然后在图层内描绘一个貌似窗口的图就可以了 127 //参数: 128 void make_window8(unsigned char *buf, int xsize, int ysize, char *title) 129 { 130 static char closebtn[14][16] = { 131 "OOOOOOOOOOOOOOO@", 132 "OQQQQQQQQQQQQQ$@", 133 "OQQQQQQQQQQQQQ$@", 134 "OQQQ@@QQQQ@@QQ$@", 135 "OQQQQ@@QQ@@QQQ$@", 136 "OQQQQQ@@@@QQQQ$@", 137 "OQQQQQQ@@QQQQQ$@", 138 "OQQQQQ@@@@QQQQ$@", 139 "OQQQQ@@QQ@@QQQ$@", 140 "OQQQ@@QQQQ@@QQ$@", 141 "OQQQQQQQQQQQQQ$@", 142 "OQQQQQQQQQQQQQ$@", 143 "O$$$$$$$$$$$$$$@", 144 "@@@@@@@@@@@@@@@@" 145 }; 146 int x, y; 147 char c; 148 boxfill8(buf, xsize, COL8_C6C6C6, 0, 0, xsize - 1, 0 ); 149 boxfill8(buf, xsize, COL8_FFFFFF, 1, 1, xsize - 2, 1 ); 150 boxfill8(buf, xsize, COL8_C6C6C6, 0, 0, 0, ysize - 1); 151 boxfill8(buf, xsize, COL8_FFFFFF, 1, 1, 1, ysize - 2); 152 boxfill8(buf, xsize, COL8_848484, xsize - 2, 1, xsize - 2, ysize - 2); 153 boxfill8(buf, xsize, COL8_000000, xsize - 1, 0, xsize - 1, ysize - 1); 154 boxfill8(buf, xsize, COL8_C6C6C6, 2, 2, xsize - 3, ysize - 3); 155 boxfill8(buf, xsize, COL8_000084, 3, 3, xsize - 4, 20 ); 156 boxfill8(buf, xsize, COL8_848484, 1, ysize - 2, xsize - 2, ysize - 2); 157 boxfill8(buf, xsize, COL8_000000, 0, ysize - 1, xsize - 1, ysize - 1); 158 putfonts8_asc(buf, xsize, 24, 4, COL8_FFFFFF, title); 159 for (y = 0; y < 14; y++) { 160 for (x = 0; x < 16; x++) { 161 c = closebtn[y][x]; 162 if (c == ‘@‘) { 163 c = COL8_000000; 164 } else if (c == ‘$‘) { 165 c = COL8_848484; 166 } else if (c == ‘Q‘) { 167 c = COL8_C6C6C6; 168 } else { 169 c = COL8_FFFFFF; 170 } 171 buf[(5 + y) * xsize + (xsize - 21 + x)] = c; 172 } 173 } 174 return; 175 }
>_<" 具体执行流程如下:
4、全部代码(含注释)
1 ; haribote-ipl 2 ; TAB=4 3 CYLS EQU 10 ; 定义读的柱面数 4 ORG 0x7c00 ; 指明程序装载地址 5 6 ; 以下这段是FAT12格式软盘专用代码 0x7c00--0x7dff 125字节 用于启动区 7 JMP entry 8 DB 0x90 9 DB "HARIBOTE" ; 启动区的名字可以是任意的,但必须是8字节 10 DW 512 ; 每个扇区(sector)的大小必须为512字节 11 DB 1 ; 簇(cluster)的大小必须为1个扇区 12 DW 1 ; FAT的起始位置(一般从第一个扇区开始) 13 DB 2 ; FAT的个数(必须为2) 14 DW 224 ; 根目录的大小(一般设为244项) 15 DW 2880 ; 该磁盘的的大小(必须为2880扇区) 16 DB 0xf0 ; 磁盘的种类(必须为0xfd) 17 DW 9 ; FAT的长度(必须为9扇区) 18 DW 18 ; 一个磁道(track)有几个扇区(必须为18) 19 DW 2 ; 磁头数(必须为2) 20 DD 0 ; 不使用分区(必须为0) 21 DD 2880 ; 重写一次磁盘大小 22 DB 0,0,0x29 ; 意义不明,固定 23 DD 0xffffffff ; (可能是)卷标号码 24 DB "HARIBOTEOS " ; 磁盘名称(11字节) 25 DB "FAT12 " ; 磁盘格式名称(8字节) 26 RESB 18 ; 先腾出18字节 27 28 ; 程序核心 29 entry: 30 MOV AX,0 ; 初始化寄存器 31 MOV SS,AX 32 MOV SP,0x7c00 33 MOV DS,AX 34 35 ; 读磁盘(从软盘中读数据装到内存中0x8200--0x83ff 125字节的地方) 36 MOV AX,0x0820 ; ES:BX=缓冲地址 37 MOV ES,AX 38 MOV CH,0 ; 柱面0 39 MOV DH,0 ; 磁头0 40 MOV CL,2 ; 扇区2 41 readloop: 42 MOv SI,0 ; 记录失败次数的寄存器 43 retry: 44 MOV AH,0x02 ; AH=0x02 : 读盘 45 MOV AL,1 ; 1个扇区 46 MOV BX,0 47 MOV DL,0x00 ; A驱动器 48 INT 0x13 ; 调用磁盘BIOS 49 JNC next ; 没出错就跳转到next继续读下一个做准备 50 ADD SI,1 ; SI++ 51 CMP SI,5 ; 比较SI和5 52 JAE error ; SI>=5时,跳转到error 53 MOV AH,0x00 54 MOV DL,0x00 ; A驱动器 55 INT 0x13 ; 重置驱动器 56 JMP retry 57 next: 58 MOV AX,ES ; 把内存地址后移0x200 59 ADD AX,0x0020 60 MOV ES,AX ; 因为没有ADD ES,0x200指令,所以这里绕个弯 61 ADD CL,1 ; 往CL里加1 (所读扇区标号,开始是2,见初始化部分) 62 CMP CL,18 ; 和18比较 63 JBE readloop ; 小于18就跳转到readloop继续读 64 MOV CL,1 ; 扇区1 65 ADD DH,1 ; 磁头+1 66 CMP DH,2 ; 判断磁头是否超过2 67 JB readloop ; 没有超过就继续读 68 MOV DH,0 ; 超过2就转为0 69 ADD CH,1 ; CH记录读取的柱面数 70 CMP CH,CYLS ; CYLS在前面定义 CYLS EQU 10 71 JB readloop 72 73 ; 磁盘内容装载内容的结束地址告诉haribote.sys 74 MOV [0x0ff0],CH ; 将CYLS的值写到内存地址0x0ff0中 75 JMP 0xc200 76 77 error: 78 MOV SI,msg ; 循环输出msg里面的内容 79 80 putloop: 81 MOV AL,[SI] 82 ADD SI,1 ; 给SI加1 83 CMP AL,0 84 JE fin 85 MOV AH,0x0e ; 显示一个文字 86 MOV BX,15 ; 指定字符颜色 87 INT 0x10 ; 调用显卡BIOS 88 JMP putloop 89 fin: 90 HLT ; 让CPU停止等待指令 91 JMP fin ; 无限循环 92 93 msg: 94 DB 0x0a, 0x0a ; 换行2次 95 DB "load error" 96 DB 0x0a ; 换行 97 DB 0 98 99 RESB 0x7dfe-$ ; 0x7dfe傑偱傪0x00偱杽傔傞柦椷 100 101 DB 0x55, 0xaa
1 ; haribote-os boot asm 2 ; TAB=4 3 4 BOTPAK EQU 0x00280000 ; bootpack的内存首址 5 DSKCAC EQU 0x00100000 ; 6 DSKCAC0 EQU 0x00008000 ; 7 8 ; BOOT_INFO相关 9 CYLS EQU 0x0ff0 ; 设定启动区 10 LEDS EQU 0x0ff1 11 VMODE EQU 0x0ff2 ; 关于颜色的信息颜色的位数 12 SCRNX EQU 0x0ff4 ; 分辨率X 13 SCRNY EQU 0x0ff6 ; 分辨率Y 14 VRAM EQU 0x0ff8 ; 图像缓冲区的开始地址 15 16 ORG 0xc200 ; 这个程序要装在到什么位置,在ipl10读盘结束的地方转到该处 17 18 MOV AL,0x13 ; VGA显卡,320X200X8位色彩 19 MOV AH,0x00 20 INT 0x10 21 MOV BYTE [VMODE],8 ; 记录画面模式 22 MOV WORD [SCRNX],320 23 MOV WORD [SCRNY],200 24 MOV DWORD [VRAM],0x000a0000 25 26 ; 用BIOS获得键盘上各种LED指示灯的状态 27 MOV AH,0x02 28 INT 0x16 ; keyboard BIOS 29 MOV [LEDS],AL 30 31 ; PIC关闭一切中断 32 ; 根据AT兼容机的规格,如果要初始化PIC(Programmable Interrupt Controller) 33 ; 必须在CLI之前进行,否则有时会挂起 34 ; 随后进行PIC的初始化 35 ; 这段等价于: 36 ; io_out8(PIC0_IMR,0xff);禁止主PIC的中断 37 ; io_out8(PIC1_IMR,0xff);禁止从PIC的中断 38 ; io_cli();禁止CPU级中断 39 40 MOV AL,0xff 41 OUT 0x21,AL 42 NOP ; 如果连续执行OUT指令有些机种会无法执行 43 OUT 0xa1,AL 44 45 CLI ; 禁止CPU级别中断 46 47 ; 为了让CPU访问1MB以上的内存空间,设定A20GATE 48 ; 相当于 49 ; #define KEYCMD_WRITE_OUTPORT 0xd1 50 ; #define KBC_OUTPORT_A20G_ENABLE 0xdf 51 ; wait_KBC_sendready(); 52 ; io_out8(PORT_KEYCMD,KEYCMD_WRITE_OUTPORT); 53 ; wait_KBC_sendready(); 54 ; io_out8(PORT_KEYDAT,KBC_OUTPORT_A20G_ENABLE); 55 ; wait_KBC_sendready(); 56 ; 该程序和init_keyboard完全相同,仅仅是向键盘控制电路发送指令,这里发送的指令,是指令键盘控制电路的附属端口输出0xdf 57 ; 这个附属端口,连接着主板上的很多地方,通过这个端口发送不同的命令,就可以实现各种各样的控制功能了 58 ; 这次输出所要完成的功能,是让A20GATE信号变成ON状态,是让1MB以上的内存变成可用状态 59 60 CALL waitkbdout 61 MOV AL,0xd1 62 OUT 0x64,AL 63 CALL waitkbdout 64 MOV AL,0xdf ; enable A20 65 OUT 0x60,AL 66 CALL waitkbdout 67 68 ; 切换保护模式 69 ; INSTRSET指令是为了386以后的LGDT,EAX,CR0 70 ; LGDT指令把随意准备的GDT读出来,对于这个暂定的GDT我们今后还要重新设定,然后将CR0这一特殊的32位寄存器的值带入EAX 71 ; 并将高位置0,低位置1,再将这个值返回给CR0,这就完成了模式转化,进入到不用颁的保护模式。 72 ; CR0是control register 0是一个非常重要的寄存器,只有操作系统才能操作它 73 ; protected virtual address mode 受保护的虚拟内存地址模式,在该模式下,应用程序不能随便改变段的设定,又不能使用操作系统的段。操作系统受CPU保护 74 ; 在保护模式中主要有受保护的16位模式和受保护的32位模式,我们要使用的是受保护的32位模式 75 ; 在讲解CPU的书上会写到,通过带入CR0而切换到保护模式时,马上就执行JMP指令。所以我们也执行这一指令。为什么要jmp呢?因为变成保护模式后,机器语言的解释发生变化, 76 ; CPU为了加快指令的执行速度而使用了管道(pipeline)这一机制,也就是说前一条指令还在执行时,就开始解释下一条甚至是再下一条指令,因为模式变了就要重新解释一遍,so.. 77 ; 而且在程序中,进入保护模式后,段寄存器的意思也变了(不是*16再加算的意思),除了CS以外所有的段寄存器的值都从0x0000变成了0x0008.CS保持不变是因为CS如果变了就乱了 78 ; 所以只有CS要放到后面处理。这里的0x0008相当于gdt+1的段 79 80 [INSTRSET "i486p"] ; ”想要使用486指令"的叙述 81 82 LGDT [GDTR0] ; 设定临时的GDT(Global Descriptor Table) 83 MOV EAX,CR0 84 AND EAX,0x7fffffff ; 设bit31为0(为了禁止颁) 85 OR EAX,0x00000001 ; 设bit0为1(为了切换保护模式) 86 MOV CR0,EAX 87 JMP pipelineflush 88 pipelineflush: 89 MOV AX,1*8 ; 可读写的段32bit 90 MOV DS,AX 91 MOV ES,AX 92 MOV FS,AX 93 MOV GS,AX 94 MOV SS,AX 95 96 ; bootpack传送 97 ; 简单来说,这部分只是在调用memcpy函数(大概意思是:下面表达仅为了说明意思,可能不正确) 98 ; memcpy(转送源地址 ,转送目的地址,转送数据大小);大小用双字,所以用字节/4、 99 ; memcpy(bootpack ,BOTPAK ,512*1024/4 );//从bootpack的地址开始的512kb内容复制到0x00280000号地去[512kb比bootpack.hrb大很多] 100 ; memcpy(0x7c00 ,DSKCAC ,512/4 );//从0x7c00复制512字节到0x10000000是将启动扇区复制到1MB以后的内存去,[启动区的0x00007c00-0x00007dff,125字节] 101 ; memcpy(DSKCAC+512 ,DSKCAC+512 ,cyls*512*18*2/4-512/4);//从始于磁盘0x00008200的内容,复制到0x00100200内存去[从磁盘读取数据装到0x8200后的地方] 102 ; bootpack是asmhead的最后一个标签,因为.sys是通过asmhead.bin和bootpack.hrb连接而成,所以asmhead结束的地方就是bootpack.hrb最开始地方 103 MOV ESI,bootpack ; 转送源 104 MOV EDI,BOTPAK ; 转送目的地 105 MOV ECX,512*1024/4 106 CALL memcpy 107 108 ; 磁盘的数据最终转送到它本来的位置去 109 110 ; 首先从启动扇区开始 111 112 MOV ESI,0x7c00 ; 转送源 113 MOV EDI,DSKCAC ; 转送目的地 114 MOV ECX,512/4 115 CALL memcpy 116 117 ; 所有剩下的 118 119 MOV ESI,DSKCAC0+512 ; 转送源 120 MOV EDI,DSKCAC+512 ; 转送目的地 121 MOV ECX,0 122 MOV CL,BYTE [CYLS] 123 IMUL ECX,512*18*2/4 ; 从柱面数转为字节数/4 124 SUB ECX,512/4 ; 减去IPL 125 CALL memcpy 126 127 ; 必须由asmhead来完成,至此全部完毕 128 ; 以后就交给bootpack来完成 129 130 ; bootpack的启动 131 ; 还是执行memecpy程序,将bootpack.hrb第0x10c8字节开始的0x11a8字节复制到0x00310000号地址去 132 ; 最后将0x310000代入到ESP中,然后用一个特殊的JMP指令,将2*8代入到CS里,同时移动到0x1b号地址,这里的0x1b是指第二个段的0x1b号地址 133 ; 第2个段的基址是0x280000,所以是从0x28001b开始执行,即bootpack.hrb的0x1b号地址 134 MOV EBX,BOTPAK 135 MOV ECX,[EBX+16] 136 ADD ECX,3 ; ECX += 3; 137 SHR ECX,2 ; ECX /= 4; 138 JZ skip ; 没有要转送的东西时 139 MOV ESI,[EBX+20] ; 转送源 140 ADD ESI,EBX 141 MOV EDI,[EBX+12] ; 转送目的地 142 CALL memcpy 143 skip: 144 MOV ESP,[EBX+12] ; 栈初始值 145 JMP DWORD 2*8:0x0000001b 146 ;---------------------------------------------------------------------------------------------------- 147 ;内存分配: 148 ; 0x00000000-0x000fffff:虽然在启动中会多次使用,但之后就会变空(1M) 149 ; 0x00100000-0x00267fff:用于保存软盘的内容(1440KB) 150 ; 0x00268000-0x0026f7ff:空(30KB) 151 ; 0x0026f800-0x0026ffff:IDT(2KB) 152 ; 0x00270000-0x0027ffff:GDT(64KB) 153 ; 0x00280000-0x002fffff:bootpack.hrb(512KB) 154 ; 0x00300000-0x003fffff:栈及其他(1MB) 155 ; 0x00400000- :空 156 ;---------------------------------------------------------------------------------------------------- 157 158 ; 和wait_KBC_sendready相同,但加入了0x60号设备进行IN处理,也就是如果控制器里有键盘代码,或已经积累了鼠标数据,就顺便读出来 159 waitkbdout: 160 IN AL,0x64 161 AND AL,0x02 162 JNZ waitkbdout ; AND偺寢壥偑0偱側偗傟偽waitkbdout傊 163 RET 164 165 ; 复制程序 166 memcpy: 167 MOV EAX,[ESI] 168 ADD ESI,4 169 MOV [EDI],EAX 170 ADD EDI,4 171 SUB ECX,1 172 JNZ memcpy ; 减法运算的结果如果不是0,就跳转到memcpy 173 RET 174 175 ; GDT0也是一种特定的GDT,0是空区域(null sector),不能在那里定义段,1号和2号分别由下式设定: 176 ; set_segmdesc(gdt + 1, 0xffffffff, 0x00000000, AR_DATA32_RW);//设定全局段 177 ; set_segmdesc(gdt + 2, LIMIT_BOTPAK, ADR_BOTPAK, AR_CODE32_ER);//设定bootpack512字节的段 178 179 ALIGNB 16;一直添加DBO,直到地址能被16整除,如果GDT0地址不是8的倍数就会慢一些,所以... 180 GDT0: 181 RESB 8 ; NULL selector 182 DW 0xffff,0x0000,0x9200,0x00cf ; 可以读写的段(segment) 32bit 183 DW 0xffff,0x0000,0x9a28,0x0047 ; 可执行的段(segment) 32bit (bootpack用) 184 185 DW 0 186 GDTR0: ;是LGDT指令,通知GDT0有了GDT,在GDT0写入了16位的段上限和32位段其实地址 187 DW 8*3-1 188 DD GDT0 189 190 ALIGNB 16 191 bootpack: 192 193 ; 也就是说,最初的状态时,GDT在asmhead.nas里并不在0x00270000-0x0027ffff的范围里。IDT连设定都没设定,所以仍处于中断禁止状态 194 ; 应当趁着硬件上积累过多的数据而产生的错误之前,尽快开放中断,接受数据。因此,在bootpack.c的hariMain里,应该在进行调色板的 195 ; 初始化之前及画面准备之前,赶紧重新建立GDT和IDT,初始化PIC,并执行io_sti();
1 /* bootpack */ 2 3 #include "bootpack.h" 4 #include <stdio.h> 5 6 void make_window8(unsigned char *buf, int xsize, int ysize, char *title); 7 8 void HariMain(void) 9 { 10 struct BOOTINFO *binfo = (struct BOOTINFO *) ADR_BOOTINFO; 11 char s[40], keybuf[32], mousebuf[128]; 12 int mx, my, i; 13 unsigned int memtotal, count = 0; 14 struct MOUSE_DEC mdec; 15 struct MEMMAN *memman = (struct MEMMAN *) MEMMAN_ADDR; 16 struct SHTCTL *shtctl; 17 struct SHEET *sht_back, *sht_mouse, *sht_win; 18 unsigned char *buf_back, buf_mouse[256], *buf_win; 19 20 init_gdtidt();//在dsctbl.c中,负责分区和中断分区初始化[包括键盘和鼠标中断设定] 21 init_pic();//在int.c中,负责中断初始化(硬件) 22 io_sti();//在naskfunc.nas中,仅仅执行STI指令,是CLI的逆指令,前者是开中断,后者是禁止中断 23 fifo8_init(&keyfifo, 32, keybuf);//在fifo.c中,负责缓冲区初始化(缓冲区结构体,大小,缓冲区首址) 24 fifo8_init(&mousefifo, 128, mousebuf); 25 /*这里IMR是(interrupt mask register),意思是“中断屏蔽寄存器”,是8位寄存器,分别对应8路IRQ信号,如果一路是1则该路被屏蔽,因为键盘中断是IRQ1,鼠标中断是IRQ12,且PIC分主从2个,从PIC连接主PIC的IRQ2,所以想要有鼠标和键盘中断,要PIC0的IRQ1和IRQ2,和PIC1的IRQ4*/ 26 io_out8(PIC0_IMR, 0xf9); /* (11111001) */ 27 io_out8(PIC1_IMR, 0xef); /* (11101111) */ 28 29 init_keyboard();//初始化键盘控制电路 30 enable_mouse(&mdec);//使能鼠标 31 //memman需要32KB内存 32 memtotal = memtest(0x00400000, 0xbfffffff);//计算总量memtatal 33 memman_init(memman); 34 memman_free(memman, 0x00001000, 0x0009e000); /* 0x00001000 - 0x0009efff 将现在不用的字节以0x1000个字节为单位注册到memman里*/ 35 memman_free(memman, 0x00400000, memtotal - 0x00400000); 36 37 init_palette();//调色板 38 shtctl = shtctl_init(memman, binfo->vram, binfo->scrnx, binfo->scrny);//图层初始化函数 39 sht_back = sheet_alloc(shtctl);//分配一个背景窗口 40 sht_mouse = sheet_alloc(shtctl);//分配一个鼠标窗口 41 sht_win = sheet_alloc(shtctl);//分配一个小窗口 42 buf_back = (unsigned char *) memman_alloc_4k(memman, binfo->scrnx * binfo->scrny);//为背景窗口和普通小窗口分配缓存空间 43 buf_win = (unsigned char *) memman_alloc_4k(memman, 160 * 52); 44 sheet_setbuf(sht_back, buf_back, binfo->scrnx, binfo->scrny, -1); /* 设定涂层缓冲区的大小和透明色的函数 */ 45 sheet_setbuf(sht_mouse, buf_mouse, 16, 16, 99); 46 sheet_setbuf(sht_win, buf_win, 160, 52, -1); /* 设定涂层缓冲区的大小和透明色的函数 */ 47 init_screen8(buf_back, binfo->scrnx, binfo->scrny);//初始化屏幕,画矩形,形成最初的窗口界面 48 init_mouse_cursor8(buf_mouse, 99);//准备鼠标指针(16*16),99是窗口背景颜色 49 make_window8(buf_win, 160, 52, "counter");//就像制作背景和鼠标一样,先准备一张图,然后在图层内描绘一个貌似窗口的图就可以了 50 sheet_slide(sht_back, 0, 0);//上下左右移动窗口,即移动窗口至0,0 51 mx = (binfo->scrnx - 16) / 2; /* 计算鼠标初始位置 */ 52 my = (binfo->scrny - 28 - 16) / 2; 53 sheet_slide(sht_mouse, mx, my);//移动鼠标窗口 54 sheet_slide(sht_win, 80, 72);//移动消息窗口 55 sheet_updown(sht_back, 0);//设置窗口对的高度,背景在最下面 56 sheet_updown(sht_win, 1); 57 sheet_updown(sht_mouse, 2); 58 sprintf(s, "(%3d, %3d)", mx, my);//显示鼠标位置 59 putfonts8_asc(buf_back, binfo->scrnx, 0, 0, COL8_FFFFFF, s); 60 sprintf(s, "memory %dMB free : %dKB", 61 memtotal / (1024 * 1024), memman_total(memman) / 1024); 62 putfonts8_asc(buf_back, binfo->scrnx, 0, 32, COL8_FFFFFF, s); 63 sheet_refresh(sht_back, 0, 0, binfo->scrnx, 48); 64 65 for (;;) { 66 count++; 67 sprintf(s, "%010d", count); 68 boxfill8(buf_win, 160, COL8_C6C6C6, 40, 28, 119, 43);//将消息窗口画出来 69 putfonts8_asc(buf_win, 160, 40, 28, COL8_000000, s);//显示计数器的值 70 sheet_refresh(sht_win, 40, 28, 120, 44);//刷新对应区域 71 72 io_cli(); 73 if (fifo8_status(&keyfifo) + fifo8_status(&mousefifo) == 0) { 74 io_sti(); 75 } else { 76 if (fifo8_status(&keyfifo) != 0) { 77 i = fifo8_get(&keyfifo);//获取按键消息并显示 78 io_sti(); 79 sprintf(s, "%02X", i); 80 boxfill8(buf_back, binfo->scrnx, COL8_008484, 0, 16, 15, 31); 81 putfonts8_asc(buf_back, binfo->scrnx, 0, 16, COL8_FFFFFF, s); 82 sheet_refresh(sht_back, 0, 16, 16, 32); 83 } else if (fifo8_status(&mousefifo) != 0) { 84 i = fifo8_get(&mousefifo); 85 io_sti(); 86 if (mouse_decode(&mdec, i) != 0) { 87 sprintf(s, "[lcr %4d %4d]", mdec.x, mdec.y); 88 if ((mdec.btn & 0x01) != 0) { 89 s[1] = ‘L‘; 90 } 91 if ((mdec.btn & 0x02) != 0) { 92 s[3] = ‘R‘; 93 } 94 if ((mdec.btn & 0x04) != 0) { 95 s[2] = ‘C‘; 96 } 97 boxfill8(buf_back, binfo->scrnx, COL8_008484, 32, 16, 32 + 15 * 8 - 1, 31); 98 putfonts8_asc(buf_back, binfo->scrnx, 32, 16, COL8_FFFFFF, s); 99 sheet_refresh(sht_back, 32, 16, 32 + 15 * 8, 32); 100 /* 移动鼠标 */ 101 mx += mdec.x; 102 my += mdec.y; 103 if (mx < 0) { 104 mx = 0; 105 } 106 if (my < 0) { 107 my = 0; 108 } 109 if (mx > binfo->scrnx - 1) { 110 mx = binfo->scrnx - 1; 111 } 112 if (my > binfo->scrny - 1) { 113 my = binfo->scrny - 1; 114 } 115 sprintf(s, "(%3d, %3d)", mx, my); 116 boxfill8(buf_back, binfo->scrnx, COL8_008484, 0, 0, 79, 15); /* 嵗昗徚偡 */ 117 putfonts8_asc(buf_back, binfo->scrnx, 0, 0, COL8_FFFFFF, s); /* 嵗昗彂偔 */ 118 sheet_refresh(sht_back, 0, 0, 80, 16); 119 sheet_slide(sht_mouse, mx, my); 120 } 121 } 122 } 123 } 124 } 125 ///////////////////////////////////////////////////////////////////////////////////// 126 //功能:就像制作背景和鼠标一样,先准备一张图,然后在图层内描绘一个貌似窗口的图就可以了 127 //参数: 128 void make_window8(unsigned char *buf, int xsize, int ysize, char *title) 129 { 130 static char closebtn[14][16] = { 131 "OOOOOOOOOOOOOOO@", 132 "OQQQQQQQQQQQQQ$@", 133 "OQQQQQQQQQQQQQ$@", 134 "OQQQ@@QQQQ@@QQ$@", 135 "OQQQQ@@QQ@@QQQ$@", 136 "OQQQQQ@@@@QQQQ$@", 137 "OQQQQQQ@@QQQQQ$@", 138 "OQQQQQ@@@@QQQQ$@", 139 "OQQQQ@@QQ@@QQQ$@", 140 "OQQQ@@QQQQ@@QQ$@", 141 "OQQQQQQQQQQQQQ$@", 142 "OQQQQQQQQQQQQQ$@", 143 "O$$$$$$$$$$$$$$@", 144 "@@@@@@@@@@@@@@@@" 145 }; 146 int x, y; 147 char c; 148 boxfill8(buf, xsize, COL8_C6C6C6, 0, 0, xsize - 1, 0 ); 149 boxfill8(buf, xsize, COL8_FFFFFF, 1, 1, xsize - 2, 1 ); 150 boxfill8(buf, xsize, COL8_C6C6C6, 0, 0, 0, ysize - 1); 151 boxfill8(buf, xsize, COL8_FFFFFF, 1, 1, 1, ysize - 2); 152 boxfill8(buf, xsize, COL8_848484, xsize - 2, 1, xsize - 2, ysize - 2); 153 boxfill8(buf, xsize, COL8_000000, xsize - 1, 0, xsize - 1, ysize - 1); 154 boxfill8(buf, xsize, COL8_C6C6C6, 2, 2, xsize - 3, ysize - 3); 155 boxfill8(buf, xsize, COL8_000084, 3, 3, xsize - 4, 20 ); 156 boxfill8(buf, xsize, COL8_848484, 1, ysize - 2, xsize - 2, ysize - 2); 157 boxfill8(buf, xsize, COL8_000000, 0, ysize - 1, xsize - 1, ysize - 1); 158 putfonts8_asc(buf, xsize, 24, 4, COL8_FFFFFF, title); 159 for (y = 0; y < 14; y++) { 160 for (x = 0; x < 16; x++) { 161 c = closebtn[y][x]; 162 if (c == ‘@‘) { 163 c = COL8_000000; 164 } else if (c == ‘$‘) { 165 c = COL8_848484; 166 } else if (c == ‘Q‘) { 167 c = COL8_C6C6C6; 168 } else { 169 c = COL8_FFFFFF; 170 } 171 buf[(5 + y) * xsize + (xsize - 21 + x)] = c; 172 } 173 } 174 return; 175 }
1 /* In this file, not only have the defination of the function, but also 2 hava the description of where the function is.*/ 3 4 /* asmhead.nas */ 5 struct BOOTINFO { /* 0x0ff0-0x0fff */ 6 char cyls; /* what‘s the end of the start zone read the data */ 7 char leds; /* when boot,the LED‘s state of the keyboard */ 8 char vmode; /* GPU mode:how many bits of color */ 9 char reserve; 10 short scrnx, scrny; /* resolution */ 11 char *vram; 12 }; 13 #define ADR_BOOTINFO 0x00000ff0 14 15 /* naskfunc.nas */ 16 void io_hlt(void); 17 void io_cli(void); 18 void io_sti(void); 19 void io_stihlt(void); 20 int io_in8(int port); 21 void io_out8(int port, int data); 22 int io_load_eflags(void); 23 void io_store_eflags(int eflags); 24 void load_gdtr(int limit, int addr); 25 void load_idtr(int limit, int addr); 26 int load_cr0(void);///////// 27 void store_cr0(int cr0);///////// 28 void asm_inthandler21(void); 29 void asm_inthandler27(void); 30 void asm_inthandler2c(void); 31 unsigned int memtest_sub(unsigned int start, unsigned int end);///////// 32 33 /* fifo.c */ 34 struct FIFO8 {//FIFO缓冲区数据结构 35 unsigned char *buf;//缓冲区 36 int p, q, size, free, flags;//下一个数据的写入地址,下一个数据的读出地址,缓冲区的大小,free是缓冲区没有数据的字节数,flag是是否溢出 37 }; 38 39 void fifo8_init(struct FIFO8 *fifo, int size, unsigned char *buf); 40 int fifo8_put(struct FIFO8 *fifo, unsigned char data); 41 int fifo8_get(struct FIFO8 *fifo); 42 int fifo8_status(struct FIFO8 *fifo); 43 44 /* graphic.c */ 45 void init_palette(void); 46 void set_palette(int start, int end, unsigned char *rgb); 47 void boxfill8(unsigned char *vram, int xsize, unsigned char c, int x0, int y0, int x1, int y1); 48 void init_screen8(char *vram, int x, int y); 49 void putfont8(char *vram, int xsize, int x, int y, char c, char *font); 50 void putfonts8_asc(char *vram, int xsize, int x, int y, char c, unsigned char *s); 51 void init_mouse_cursor8(char *mouse, char bc); 52 void putblock8_8(char *vram, int vxsize, int pxsize, 53 int pysize, int px0, int py0, char *buf, int bxsize); 54 #define COL8_000000 0 55 #define COL8_FF0000 1 56 #define COL8_00FF00 2 57 #define COL8_FFFF00 3 58 #define COL8_0000FF 4 59 #define COL8_FF00FF 5 60 #define COL8_00FFFF 6 61 #define COL8_FFFFFF 7 62 #define COL8_C6C6C6 8 63 #define COL8_840000 9 64 #define COL8_008400 10 65 #define COL8_848400 11 66 #define COL8_000084 12 67 #define COL8_840084 13 68 #define COL8_008484 14 69 #define COL8_848484 15 70 71 /* dsctbl.c about GDT IDT that‘s Global Descriptor Table and Interrupt Descriptor Table*/ 72 struct SEGMENT_DESCRIPTOR {//8 bytes segment infomation,total 8192 parts [here similar to the method of the setting palette] 73 short limit_low, base_low;//address of segment base[high:mid:low=1:1:2]=4 bytes =32 bits 74 char base_mid, access_right;//segment limit[high:low=1:2],only 20 bits = high byte‘s low 4 bits + low 2bytes‘ 16bits 75 char limit_high, base_high;//segment property access[limit_high:right=1:1],only 12 bits = limit_high‘s high 4 bits + access_right‘s 8 bits 76 }; 77 //PS 1):segment limit equals the number of GDT‘s effective bytes -1 78 //PS 2):the segment limit just only has 20 bits, which can represent 1MB, and the segment property has 1 bit flag, 79 //if this flag =1,and the limit‘s unit uses page to replace byte(here 1 page = 4kb) 80 //PS 3):the segment property has 16 bits liking that:xxxx0000 xxxxxxxx 81 //the high 4 bits are extended access 82 //the low 8 bits are: 83 // 0x00:unused description table 84 // 0x92:system exclusive,readable and writable,non-executable 85 // 0x9a:system exclusive,readable and non-writable,executable 86 // 0xf2:application useing,readable and writable,non-executable 87 // 0xfa:application useing,readable and non-writable,executable 88 89 struct GATE_DESCRIPTOR {// 90 short offset_low, selector; 91 char dw_count, access_right; 92 short offset_high; 93 }; 94 void init_gdtidt(void); 95 void set_segmdesc(struct SEGMENT_DESCRIPTOR *sd, unsigned int limit, int base, int ar); 96 void set_gatedesc(struct GATE_DESCRIPTOR *gd, int offset, int selector, int ar); 97 #define ADR_IDT 0x0026f800 98 #define LIMIT_IDT 0x000007ff 99 #define ADR_GDT 0x00270000 100 #define LIMIT_GDT 0x0000ffff 101 #define ADR_BOTPAK 0x00280000 102 #define LIMIT_BOTPAK 0x0007ffff 103 #define AR_DATA32_RW 0x4092 104 #define AR_CODE32_ER 0x409a 105 #define AR_INTGATE32 0x008e 106 107 /* int.c */ 108 void init_pic(void); 109 void inthandler27(int *esp); 110 #define PIC0_ICW1 0x0020 111 #define PIC0_OCW2 0x0020 112 #define PIC0_IMR 0x0021 113 #define PIC0_ICW2 0x0021 114 #define PIC0_ICW3 0x0021 115 #define PIC0_ICW4 0x0021 116 #define PIC1_ICW1 0x00a0 117 #define PIC1_OCW2 0x00a0 118 #define PIC1_IMR 0x00a1 119 #define PIC1_ICW2 0x00a1 120 #define PIC1_ICW3 0x00a1 121 #define PIC1_ICW4 0x00a1 122 123 /* keyboard.c */ 124 void inthandler21(int *esp); 125 void wait_KBC_sendready(void); 126 void init_keyboard(void); 127 extern struct FIFO8 keyfifo; 128 #define PORT_KEYDAT 0x0060 129 #define PORT_KEYCMD 0x0064 130 131 /* mouse.c */ 132 struct MOUSE_DEC { 133 unsigned char buf[3], phase; 134 int x, y, btn; 135 }; 136 void inthandler2c(int *esp); 137 void enable_mouse(struct MOUSE_DEC *mdec); 138 int mouse_decode(struct MOUSE_DEC *mdec, unsigned char dat); 139 extern struct FIFO8 mousefifo; 140 141 /* memory.c */ 142 #define MEMMAN_FREES 4090 /* 大约是32KB */ 143 #define MEMMAN_ADDR 0x003c0000 144 struct FREEINFO { /* 可用信息 */ 145 unsigned int addr, size; 146 }; 147 struct MEMMAN { /* 内存管理 */ 148 int frees, maxfrees, lostsize, losts; 149 struct FREEINFO free[MEMMAN_FREES]; 150 }; 151 unsigned int memtest(unsigned int start, unsigned int end); 152 void memman_init(struct MEMMAN *man); 153 unsigned int memman_total(struct MEMMAN *man); 154 unsigned int memman_alloc(struct MEMMAN *man, unsigned int size); 155 int memman_free(struct MEMMAN *man, unsigned int addr, unsigned int size); 156 unsigned int memman_alloc_4k(struct MEMMAN *man, unsigned int size); 157 int memman_free_4k(struct MEMMAN *man, unsigned int addr, unsigned int size); 158 159 /* sheet.c */ 160 #define MAX_SHEETS 256 161 struct SHEET {//图层结构体 162 unsigned char *buf;//所描绘内容的地址 163 int bxsize, bysize, vx0, vy0, col_inv, height, flags;//图层大小,图层坐标,透明色色号,土层高度,存放有关图层的设定信息 164 struct SHTCTL *ctl; 165 }; 166 struct SHTCTL {//图层管理结构体 167 unsigned char *vram, *map; 168 int xsize, ysize, top; 169 struct SHEET *sheets[MAX_SHEETS]; 170 struct SHEET sheets0[MAX_SHEETS]; 171 };//top存放最上面图层的高度,sheet0图层顺序混乱,要按照升序排列,然后将地址写入sheets中,方便使用 172 struct SHTCTL *shtctl_init(struct MEMMAN *memman, unsigned char *vram, int xsize, int ysize); 173 struct SHEET *sheet_alloc(struct SHTCTL *ctl); 174 void sheet_setbuf(struct SHEET *sht, unsigned char *buf, int xsize, int ysize, int col_inv); 175 void sheet_updown(struct SHEET *sht, int height); 176 void sheet_refresh(struct SHEET *sht, int bx0, int by0, int bx1, int by1); 177 void sheet_slide(struct SHEET *sht, int vx0, int vy0); 178 void sheet_free(struct SHEET *sht);
1 /* dsctbl.c GDT IDT分段及中断相关 */ 2 3 #include "bootpack.h" 4 5 6 ///////////////////////////////////////////////////////////////////////////////////// 7 //功能: 8 //参数: 9 //附件: 10 void init_gdtidt(void) 11 { 12 /*在bootpack.h文件里面定义了分段结构体和中断结构体,这里实例化gdt和idt*/ 13 struct SEGMENT_DESCRIPTOR *gdt = (struct SEGMENT_DESCRIPTOR *) ADR_GDT;//从0x00270000~0x0027ffff共8192个分段 14 struct GATE_DESCRIPTOR *idt = (struct GATE_DESCRIPTOR *) ADR_IDT;//从0x0026f800~0x0026ffff共256个分段 15 int i; 16 17 /* GDT的初始化 */ 18 for (i = 0; i <= LIMIT_GDT / 8; i++) { 19 set_segmdesc(gdt + i, 0, 0, 0); 20 } 21 //,上限,地址,属性 22 set_segmdesc(gdt + 1, 0xffffffff, 0x00000000, AR_DATA32_RW);//设定全局段 23 set_segmdesc(gdt + 2, LIMIT_BOTPAK, ADR_BOTPAK, AR_CODE32_ER);//设定bootpack512字节的段 24 /* ;1) 这个函数用来指定的段上限和地址赋值给GDTR的48位寄存器,这是个很特殊的寄存器,并不能用MOV来直接赋值 25 ;,唯一的方法就是指定一个内存地址,从指定的内存地址读取6字节(也就是48位),然后赋值给GDTR寄存器。完成这一任务的指令就是LGDT 26 ;2) 该寄存器的低16位(即内存的最初的2个字节)是段上限,它等于“GDT的有效的字节数-1”,剩下的32位,代表GDT的开始地址 27 ;3) 这里2个参数是ESP+4和ESP+8里存放,而我们要的是6字节形式的,所以要转换为我们想要的形式~ */ 28 load_gdtr(LIMIT_GDT, ADR_GDT); 29 30 /* IDT的初始化 */ 31 for (i = 0; i <= LIMIT_IDT / 8; i++) { 32 set_gatedesc(idt + i, 0, 0, 0); 33 } 34 load_idtr(LIMIT_IDT, ADR_IDT); 35 36 /* IDT的設定 */ 37 set_gatedesc(idt + 0x21, (int) asm_inthandler21, 2 * 8, AR_INTGATE32); 38 set_gatedesc(idt + 0x27, (int) asm_inthandler27, 2 * 8, AR_INTGATE32); 39 set_gatedesc(idt + 0x2c, (int) asm_inthandler2c, 2 * 8, AR_INTGATE32); 40 /*这里asm_inthadler21注册在idt的第0x21号,这样如果发生了中断,CPU就会自动调用asm_inthandler21. 41 这里的2*8表示asm_inthandler21属于哪一个段,即段号2,乘以8是因为低3位有别的意思,这低3位必须为0 42 这里段号为2的段在初始化的地方我们设置为bootpack全局段 43 最后的AR_INTGATE32将IDT的属性,设定为0x008e,表示用于中断处理的有效性 44 */ 45 return; 46 } 47 48 void set_segmdesc(struct SEGMENT_DESCRIPTOR *sd, unsigned int limit, int base, int ar) 49 { 50 if (limit > 0xfffff) { 51 ar |= 0x8000; /* G_bit = 1 */ 52 limit /= 0x1000; 53 } 54 sd->limit_low = limit & 0xffff; 55 sd->base_low = base & 0xffff; 56 sd->base_mid = (base >> 16) & 0xff; 57 sd->access_right = ar & 0xff; 58 sd->limit_high = ((limit >> 16) & 0x0f) | ((ar >> 8) & 0xf0); 59 sd->base_high = (base >> 24) & 0xff; 60 return; 61 } 62 63 void set_gatedesc(struct GATE_DESCRIPTOR *gd, int offset, int selector, int ar) 64 { 65 gd->offset_low = offset & 0xffff; 66 gd->selector = selector; 67 gd->dw_count = (ar >> 8) & 0xff; 68 gd->access_right = ar & 0xff; 69 gd->offset_high = (offset >> 16) & 0xffff; 70 return; 71 }
1 /* the part of interrupt */ 2 3 #include "bootpack.h" 4 #include <stdio.h> 5 6 ///////////////////////////////////////////////////////////////////////////////////// 7 //功能:中断初始化函数 8 //参数:无 9 void init_pic(void) 10 /* PIC(programmable interrupt controller) initialize */ 11 { 12 io_out8(PIC0_IMR, 0xff ); /* disabled all interrupts */ 13 io_out8(PIC1_IMR, 0xff ); /* disabled all interrupts */ 14 15 io_out8(PIC0_ICW1, 0x11 ); /* edge trigger mode */ 16 io_out8(PIC0_ICW2, 0x20 ); /* IRQ0-7 are received by INT20-27 */ 17 io_out8(PIC0_ICW3, 1 << 2); /* PIC1 is connected by IRQ2 */ 18 io_out8(PIC0_ICW4, 0x01 ); /* unbuffered mode */ 19 20 io_out8(PIC1_ICW1, 0x11 ); /* edge trigger mode */ 21 io_out8(PIC1_ICW2, 0x28 ); /* IRQ8-15 are received by INT28-2f */ 22 io_out8(PIC1_ICW3, 2 ); /* PIC1 is connnected by IRQ2 */ 23 io_out8(PIC1_ICW4, 0x01 ); /* unbuffered mode */ 24 25 io_out8(PIC0_IMR, 0xfb ); /* 11111011 disable all interrupts except PIC1 */ 26 io_out8(PIC1_IMR, 0xff ); /* 11111111 disable all interrupts */ 27 28 return; 29 } 30 31 void inthandler27(int *esp) 32 { 33 io_out8(PIC0_OCW2, 0x67); /* IRQ-07受付完了をPICに通知 */ 34 return; 35 }
1 /* FIFO用来存放鼠标和键盘信息的链表 2 其实就是用数组实现的循环链表,这里原著处理的不好, 3 建议用数据结构里的知识来处理 */ 4 5 #include "bootpack.h" 6 7 #define FLAGS_OVERRUN 0x0001 8 9 ///////////////////////////////////////////////////////////////////////////////////// 10 //功能:缓冲区初始化 11 //参数:缓冲区结构体指针,大小,缓冲区开始位置 12 void fifo8_init(struct FIFO8 *fifo, int size, unsigned char *buf) 13 { 14 fifo->size = size; 15 fifo->buf = buf; 16 fifo->free = size; 17 fifo->flags = 0; 18 fifo->p = 0; 19 fifo->q = 0; 20 return; 21 } 22 //往缓冲区内插入一个数据 23 int fifo8_put(struct FIFO8 *fifo, unsigned char data) 24 { 25 if (fifo->free == 0) {//溢出 26 fifo->flags |= FLAGS_OVERRUN; 27 return -1; 28 } 29 fifo->buf[fifo->p] = data; 30 fifo->p++; 31 if (fifo->p == fifo->size) {//当插入位置到达最后时再返回第一个位置 32 fifo->p = 0; 33 } 34 fifo->free--; 35 return 0; 36 } 37 //从缓冲区取出一个数据 38 int fifo8_get(struct FIFO8 *fifo) 39 { 40 int data; 41 if (fifo->free == fifo->size) {//没有数据 42 return -1; 43 } 44 data = fifo->buf[fifo->q]; 45 fifo->q++; 46 if (fifo->q == fifo->size) {//如果取出数据的位置到达最后了就从第一个位置开始 47 fifo->q = 0; 48 } 49 fifo->free++; 50 return data; 51 } 52 //获取缓冲区状态,数据量 53 int fifo8_status(struct FIFO8 *fifo) 54 { 55 return fifo->size - fifo->free; 56 }
1 /* 键盘处理函数文件 */ 2 #include "bootpack.h" 3 4 struct FIFO8 keyfifo; 5 6 ///////////////////////////////////////////////////////////////////////////////////// 7 //功能:PS/2的键盘中断,一会在汇编中调用这个函数实现真正的中断:_asm_inthandler21 8 void inthandler21(int *esp) 9 { 10 unsigned char data; 11 io_out8(PIC0_OCW2, 0x61); /* IRQ-01庴晅姰椆傪PIC偵捠抦 */ 12 data = io_in8(PORT_KEYDAT); 13 fifo8_put(&keyfifo, data); 14 return; 15 } 16 17 #define PORT_KEYSTA 0x0064 18 #define KEYSTA_SEND_NOTREADY 0x02 19 #define KEYCMD_WRITE_MODE 0x60 20 #define KBC_MODE 0x47 21 ///////////////////////////////////////////////////////////////////////////////////// 22 //功能:等待键盘控制电路准备完毕 23 //参数:无 24 //附加:如果键盘控制电路可以接受CPU指令,CPU从设备号码0x0064处所读取的数据的倒数第二位应该是0,否则就一种循环等待 25 void wait_KBC_sendready(void) 26 { 27 for (;;) { 28 if ((io_in8(PORT_KEYSTA) & KEYSTA_SEND_NOTREADY) == 0) { 29 break; 30 } 31 } 32 return; 33 } 34 35 void init_keyboard(void)//初始化键盘控制电路 36 { 37 wait_KBC_sendready();//让键盘控制电路做好准备,等待控制指令的到来 38 io_out8(PORT_KEYCMD, KEYCMD_WRITE_MODE);//键盘模式设置指令 39 wait_KBC_sendready(); 40 io_out8(PORT_KEYDAT, KBC_MODE);//鼠标模式设置指令 41 return; 42 }
1 /* 鼠标相关函数 */ 2 3 #include "bootpack.h" 4 5 struct FIFO8 mousefifo; 6 7 ///////////////////////////////////////////////////////////////////////////////////// 8 //功能:PS/2的鼠标中断,一会在汇编中调用这个函数实现真正的中断:_asm_inthandler2c 9 void inthandler2c(int *esp) 10 { 11 unsigned char data; 12 io_out8(PIC1_OCW2, 0x64); /* IRQ-12受付完了をPIC1に通知 */ 13 io_out8(PIC0_OCW2, 0x62); /* IRQ-02受付完了をPIC0に通知 */ 14 data = io_in8(PORT_KEYDAT); 15 fifo8_put(&mousefifo, data); 16 return; 17 } 18 19 #define KEYCMD_SENDTO_MOUSE 0xd4 20 #define MOUSECMD_ENABLE 0xf4 21 ///////////////////////////////////////////////////////////////////////////////////// 22 //功能:使能鼠标 23 //参数: 24 //附加:这个函数和init_keyboard十分相似,不同的在于输入的数据不同 25 //如果向键盘控制电路发送指令0xd4,下一数据就会自动发送给鼠标,利用这一特性来发送激活鼠标的指令 26 //其中答复消息为0xfa 27 void enable_mouse(struct MOUSE_DEC *mdec) 28 { 29 wait_KBC_sendready();//让键盘控制电路做好准备,等待控制指令的到来 30 io_out8(PORT_KEYCMD, KEYCMD_SENDTO_MOUSE); 31 wait_KBC_sendready(); 32 io_out8(PORT_KEYDAT, MOUSECMD_ENABLE); 33 mdec->phase = 0; 34 return; 35 } 36 ///////////////////////////////////////////////////////////////////////////////////// 37 //功能:鼠标信息解码程序,把信息保存在鼠标结构体中 38 //参数:鼠标结构体,从缓冲区读取的数据 39 //附加:首先把最初读到的0xfa舍掉,之后从鼠标那里送过来的数据都应该是3个字节一组的,所以每当数据累计3字节时候就作相应处理[这里返回1] 40 //最后将鼠标的点击信息放在btn中,将鼠标的移动信息保存在x,y中 41 int mouse_decode(struct MOUSE_DEC *mdec, unsigned char dat) 42 { 43 if (mdec->phase == 0) { 44 /*等待鼠标的0xfa状态*/ 45 if (dat == 0xfa) { 46 mdec->phase = 1; 47 } 48 return 0; 49 } 50 if (mdec->phase == 1) { 51 /*等待鼠标的第一字节*/ 52 if ((dat & 0xc8) == 0x08) { 53 mdec->buf[0] = dat; 54 mdec->phase = 2; 55 } 56 return 0; 57 } 58 if (mdec->phase == 2) { 59 /*等待鼠标的第二字节*/ 60 mdec->buf[1] = dat; 61 mdec->phase = 3; 62 return 0; 63 } 64 if (mdec->phase == 3) { 65 /*等待鼠标的第三字节,并作处理*/ 66 mdec->buf[2] = dat; 67 mdec->phase = 1;//注意这里是恢复到1不是0,见附加说明,刚开始舍去0xfa以后每次3字节 68 /*下面是根据buf的3个数据进行计算鼠标信息 69 这里btn是buf[0]的低3位,最低位表示鼠标左击,中间表示鼠标中间被击,第3位表示鼠标右击 70 鼠标的x,和y坐标基本和buf[1],buf[2]相等,但是要根据buf[0]的前半部分作相应的变化:要么第8位及8位以后的全部设成1,或全部保留为0 71 */ 72 mdec->btn = mdec->buf[0] & 0x07; 73 mdec->x = mdec->buf[1]; 74 mdec->y = mdec->buf[2]; 75 if ((mdec->buf[0] & 0x10) != 0) { 76 mdec->x |= 0xffffff00; 77 } 78 if ((mdec->buf[0] & 0x20) != 0) { 79 mdec->y |= 0xffffff00; 80 } 81 mdec->y = - mdec->y; /* 因为鼠标和屏幕的方向恰好相反,所以这里取反*/ 82 return 1; 83 } 84 return -1; 85 }
1 /* 内存相关 2 策略是先写入再读出看看是否一样,来确定是否正常,但是486以上的有高速缓存,所以要关闭高速缓存才行 3 */ 4 5 #include "bootpack.h" 6 7 #define EFLAGS_AC_BIT 0x00040000 8 #define CR0_CACHE_DISABLE 0x60000000 9 10 ///////////////////////////////////////////////////////////////////////////////////// 11 //参数:开始位置和结束位置 12 //附加:(1)最初对EFLAGS处理,是检查CPU是486还是386.如果是486以上,EFLAGS寄存器的第18位应该是AC标志位 13 //如果不是386就没有这一位,第18位一直为0,这里我们有意识的把1写到这一位,然后再读EFLAGS的值,继而 14 //检查AC标志位是否为1.最后将AC标志位重置为0。(2)为了禁止缓存,需要对CR0寄存器的某一位置0,这里用的 15 //是会编写的load_cr0和store_cr0 16 unsigned int memtest(unsigned int start, unsigned int end) 17 { 18 char flg486 = 0; 19 unsigned int eflg, cr0, i; 20 21 /* 386偐丄486埲崀側偺偐偺妋擣 */ 22 eflg = io_load_eflags(); 23 eflg |= EFLAGS_AC_BIT; /* AC-bit = 1 */ 24 io_store_eflags(eflg); 25 eflg = io_load_eflags(); 26 if ((eflg & EFLAGS_AC_BIT) != 0) { /* 386偱偼AC=1偵偟偰傕帺摦偱0偵栠偭偰偟傑偆 */ 27 flg486 = 1; 28 } 29 eflg &= ~EFLAGS_AC_BIT; /* AC-bit = 0 */ 30 io_store_eflags(eflg); 31 32 if (flg486 != 0) { 33 cr0 = load_cr0(); 34 cr0 |= CR0_CACHE_DISABLE; /* 僉儍僢僔儏嬛巭 */ 35 store_cr0(cr0); 36 } 37 38 i = memtest_sub(start, end); 39 40 if (flg486 != 0) { 41 cr0 = load_cr0(); 42 cr0 &= ~CR0_CACHE_DISABLE; /* 僉儍僢僔儏嫋壜 */ 43 store_cr0(cr0); 44 } 45 46 return i; 47 } 48 /* 49 ///////////////////////////////////////////////////////////////////////////////////// 50 //功能:检查区域内的内存是否有效,因为c编译器会清除掉一些东西,所以就只能用汇编写,见naskfunc.nas 51 //参数:起始位置 52 //附加:写入取反看看修改没,再取反看看修改没,如果两次都修改就认为是能够使用的内存 53 unsigned int memtest_sub(unsigned int start,unsigned int end) 54 { 55 unsigned int i,*p,old,pat0=0xaa55aa55,pat1=0x55aa55aa; 56 for(i=start;i<=end;i+=4){ 57 p=(unsigned int *)i; 58 old=*p; 59 *p=pat0; 60 *p^=0xffffffff; 61 if(*p!=pat1){ 62 not_memory: 63 *p=old; 64 break; 65 } 66 *p^=0xffffffff; 67 if(*p!=pat0){ 68 goto not_memory; 69 } 70 *p=old; 71 } 72 return i; 73 } 74 */ 75 76 77 ///////////////////////////////////////////////////////////////////////////////////// 78 //功能:初始化内存管理 79 //参数: 80 void memman_init(struct MEMMAN *man) 81 { 82 man->frees = 0; /* 可用信息数目 */ 83 man->maxfrees = 0; /* 用于观察可用信息状况,frees最大值 */ 84 man->lostsize = 0; /* 释放失败的内存总和 */ 85 man->losts = 0; /* 释放失败次数 */ 86 return; 87 } 88 89 ///////////////////////////////////////////////////////////////////////////////////// 90 //功能:获取空余内存的时际大小 91 //参数: 92 unsigned int memman_total(struct MEMMAN *man) 93 { 94 unsigned int i, t = 0; 95 for (i = 0; i < man->frees; i++) { 96 t += man->free[i].size; 97 } 98 return t; 99 } 100 101 ///////////////////////////////////////////////////////////////////////////////////// 102 //功能:分配内存 103 //参数:大小 104 unsigned int memman_alloc(struct MEMMAN *man, unsigned int size) 105 { 106 unsigned int i, a; 107 for (i = 0; i < man->frees; i++) { 108 if (man->free[i].size >= size) { 109 //找到了足够大的内存 110 a = man->free[i].addr; 111 man->free[i].addr += size; 112 man->free[i].size -= size; 113 if (man->free[i].size == 0) { 114 /* free[i]变成了0就减掉一条信息 */ 115 man->frees--; 116 for (; i < man->frees; i++) { 117 man->free[i] = man->free[i + 1]; /* 带入结构体 */ 118 } 119 } 120 return a; 121 } 122 } 123 return 0; /* 没有可用空间 */ 124 } 125 126 ///////////////////////////////////////////////////////////////////////////////////// 127 //功能:内存释放 128 //参数: 129 int memman_free(struct MEMMAN *man, unsigned int addr, unsigned int size) 130 { 131 int i, j; 132 /* 为了方便归纳内存,将free[]按照addr的顺序排列 */ 133 /* 所以,现决定应该放到哪里 */ 134 for (i = 0; i < man->frees; i++) { 135 if (man->free[i].addr > addr) { 136 break; 137 } 138 } 139 /* free[i - 1].addr < addr < free[i].addr */ 140 if (i > 0) { 141 /* 前面有可用内存 */ 142 if (man->free[i - 1].addr + man->free[i - 1].size == addr) { 143 /* 可以与前面的可用内存归纳到一起 */ 144 man->free[i - 1].size += size; 145 if (i < man->frees) { 146 /* 后面也有 */ 147 if (addr + size == man->free[i].addr) { 148 /* 也可与后面可用内存归纳到一起 */ 149 man->free[i - 1].size += man->free[i].size; 150 /* man->free[i]删除 */ 151 /* free[i]变成0后归纳到前面去 */ 152 man->frees--; 153 for (; i < man->frees; i++) { 154 man->free[i] = man->free[i + 1]; /* 结构体赋值 */ 155 } 156 } 157 } 158 return 0; /* 成功完成 */ 159 } 160 } 161 /* 不能与前面的可用空间归纳到一起 */ 162 if (i < man->frees) { 163 /* 后面有 */ 164 if (addr + size == man->free[i].addr) { 165 /* 可以与后面的内容归纳到一起 */ 166 man->free[i].addr = addr; 167 man->free[i].size += size; 168 return 0; /* 成功完成 */ 169 } 170 } 171 /* 既不能与前面的内容归纳到一起,也不能与后面的内容归纳到一起,没有剩余的空间可以分配了 */ 172 if (man->frees < MEMMAN_FREES) { 173 /* free[i]之后的,向后移动,腾出一点可用空间 */ 174 for (j = man->frees; j > i; j--) { 175 man->free[j] = man->free[j - 1]; 176 } 177 man->frees++; 178 if (man->maxfrees < man->frees) { 179 man->maxfrees = man->frees; /* 更新最大值 */ 180 } 181 man->free[i].addr = addr; 182 man->free[i].size = size; 183 return 0; /* 成功完成 */ 184 } 185 /* 不能后移 */ 186 man->losts++; 187 man->lostsize += size; 188 return -1; /* 失败 */ 189 } 190 191 ///////////////////////////////////////////////////////////////////////////////////// 192 //功能: 193 //参数: 194 unsigned int memman_alloc_4k(struct MEMMAN *man, unsigned int size) 195 { 196 unsigned int a; 197 size = (size + 0xfff) & 0xfffff000; 198 a = memman_alloc(man, size); 199 return a; 200 } 201 202 ///////////////////////////////////////////////////////////////////////////////////// 203 //功能: 204 //参数: 205 int memman_free_4k(struct MEMMAN *man, unsigned int addr, unsigned int size) 206 { 207 int i; 208 size = (size + 0xfff) & 0xfffff000; 209 i = memman_free(man, addr, size); 210 return i; 211 }
1 /* 操作系统函数集合 */ 2 3 #include "bootpack.h" 4 5 // ----------------------------------------------------------------------------------- 6 //调色板相关 7 //----------------------------------------------------------------------------------- 8 9 ///////////////////////////////////////////////////////////////////////////////////// 10 //功能:初始化调色板,建立静态16个颜色映射,然后调用set_palette进行设置 11 //参数:无 12 //附件:要调用set_palette函数 13 void init_palette(void) 14 { 15 static unsigned char table_rgb[16 * 3] = { 16 0x00, 0x00, 0x00, /* 0:黑 */ 17 0xff, 0x00, 0x00, /* 1:亮红 */ 18 0x00, 0xff, 0x00, /* 2:亮绿 */ 19 0xff, 0xff, 0x00, /* 3:亮黄 */ 20 0x00, 0x00, 0xff, /* 4:亮蓝 */ 21 0xff, 0x00, 0xff, /* 5:亮紫 */ 22 0x00, 0xff, 0xff, /* 6:浅亮蓝 */ 23 0xff, 0xff, 0xff, /* 7:白 */ 24 0xc6, 0xc6, 0xc6, /* 8:亮灰 */ 25 0x84, 0x00, 0x00, /* 9:暗红 */ 26 0x00, 0x84, 0x00, /* 10:暗绿 */ 27 0x84, 0x84, 0x00, /* 11:暗黄 */ 28 0x00, 0x00, 0x84, /* 12:暗青 */ 29 0x84, 0x00, 0x84, /* 13:暗紫 */ 30 0x00, 0x84, 0x84, /* 14:浅暗蓝 */ 31 0x84, 0x84, 0x84 /* 15:暗灰 */ 32 }; 33 set_palette(0, 15, table_rgb); 34 return; 35 /*C语言中static char只能用于数据,就像汇编中的DB指令 */ 36 } 37 ///////////////////////////////////////////////////////////////////////////////////// 38 //功能:初始化设置调色板 39 //参数:开始标号,结束标号,16*3的颜色表 40 //附加:关闭中断,进行设置(要知道具体设置要求),恢复中断 41 void set_palette(int start, int end, unsigned char *rgb) 42 { 43 int i, eflags; 44 eflags = io_load_eflags(); /* 记录中断许可标志 */ 45 io_cli(); /* 将中断许可标志置0,禁止中断 */ 46 io_out8(0x03c8, start); 47 for (i = start; i <= end; i++) { 48 io_out8(0x03c9, rgb[0] / 4); 49 io_out8(0x03c9, rgb[1] / 4); 50 io_out8(0x03c9, rgb[2] / 4); 51 rgb += 3; 52 } 53 io_store_eflags(eflags); /* 恢复原中断 */ 54 return; 55 } 56 57 //----------------------------------------------------------------------------------- 58 //显示主界面相关 59 //----------------------------------------------------------------------------------- 60 61 ///////////////////////////////////////////////////////////////////////////////////// 62 //功能:填充VRAM实现画矩形操作 63 //参数:VRAM初址,x轴像素,颜色标号,后面4个是位置矩形 64 void boxfill8(unsigned char *vram, int xsize, unsigned char c, int x0, int y0, int x1, int y1) 65 { 66 int x, y; 67 for (y = y0; y <= y1; y++) { 68 for (x = x0; x <= x1; x++) 69 vram[y * xsize + x] = c; 70 } 71 return; 72 } 73 ///////////////////////////////////////////////////////////////////////////////////// 74 //功能:初始化屏幕,画矩形,形成最初的窗口界面 75 //参数:VRAM初址,屏幕宽和长 76 //附加:要调用boxfill8函数 77 void init_screen8(char *vram, int x, int y) 78 { 79 boxfill8(vram, x, COL8_008484, 0, 0, x - 1, y - 29); 80 boxfill8(vram, x, COL8_C6C6C6, 0, y - 28, x - 1, y - 28); 81 boxfill8(vram, x, COL8_FFFFFF, 0, y - 27, x - 1, y - 27); 82 boxfill8(vram, x, COL8_C6C6C6, 0, y - 26, x - 1, y - 1); 83 84 boxfill8(vram, x, COL8_FFFFFF, 3, y - 24, 59, y - 24); 85 boxfill8(vram, x, COL8_FFFFFF, 2, y - 24, 2, y - 4); 86 boxfill8(vram, x, COL8_848484, 3, y - 4, 59, y - 4); 87 boxfill8(vram, x, COL8_848484, 59, y - 23, 59, y - 5); 88 boxfill8(vram, x, COL8_000000, 2, y - 3, 59, y - 3); 89 boxfill8(vram, x, COL8_000000, 60, y - 24, 60, y - 3); 90 91 boxfill8(vram, x, COL8_848484, x - 47, y - 24, x - 4, y - 24); 92 boxfill8(vram, x, COL8_848484, x - 47, y - 23, x - 47, y - 4); 93 boxfill8(vram, x, COL8_FFFFFF, x - 47, y - 3, x - 4, y - 3); 94 boxfill8(vram, x, COL8_FFFFFF, x - 3, y - 24, x - 3, y - 3); 95 return; 96 } 97 98 //----------------------------------------------------------------------------------- 99 //字符显示相关 100 //----------------------------------------------------------------------------------- 101 102 ///////////////////////////////////////////////////////////////////////////////////// 103 //功能:在指定位置显示一个字符 104 //参数:VRAM初址,窗口宽,待显示的位置,颜色,显示文字的初址(这里采用16个char表示一个字符) 105 void putfont8(char *vram, int xsize, int x, int y, char c, char *font) 106 { 107 int i; 108 char *p, d /* data */; 109 for (i = 0; i < 16; i++) { 110 //查询每个char的8个位,如果不为0,就 111 p = vram + (y + i) * xsize + x; 112 d = font[i]; 113 if ((d & 0x80) != 0) { p[0] = c; } 114 if ((d & 0x40) != 0) { p[1] = c; } 115 if ((d & 0x20) != 0) { p[2] = c; } 116 if ((d & 0x10) != 0) { p[3] = c; } 117 if ((d & 0x08) != 0) { p[4] = c; } 118 if ((d & 0x04) != 0) { p[5] = c; } 119 if ((d & 0x02) != 0) { p[6] = c; } 120 if ((d & 0x01) != 0) { p[7] = c; } 121 } 122 return; 123 } 124 ///////////////////////////////////////////////////////////////////////////////////// 125 //功能:在指定位置显示一个字符串 126 //参数:VRAM初址,窗口宽,待显示的位置,颜色,待显示文字串的初址(这里采用16个char表示一个字符) 127 //附加:这里采用ASCII,字符串以0x00结尾,要调用putfont8()函数,这里可以和printf()函数连用将数据格式化为字符串类型 128 void putfonts8_asc(char *vram, int xsize, int x, int y, char c, unsigned char *s) 129 { 130 extern char hankaku[4096]; 131 for (; *s != 0x00; s++) { 132 putfont8(vram, xsize, x, y, c, hankaku + *s * 16); 133 x += 8; 134 } 135 return; 136 } 137 138 //----------------------------------------------------------------------------------- 139 //显示鼠标指针 140 //----------------------------------------------------------------------------------- 141 142 ///////////////////////////////////////////////////////////////////////////////////// 143 //功能:准备鼠标指针(16*16) 144 //参数:存放鼠标颜色信息的字符指针,窗口背景颜色 145 //附件:先定义一个cursor鼠标效果数组,然后转换为鼠标颜色数组(即,每一点应该涂什么颜色) 146 void init_mouse_cursor8(char *mouse, char bc) 147 { 148 static char cursor[16][16] = { 149 "**************..", 150 "*OOOOOOOOOOO*...", 151 "*OOOOOOOOOO*....", 152 "*OOOOOOOOO*.....", 153 "*OOOOOOOO*......", 154 "*OOOOOOO*.......", 155 "*OOOOOOO*.......", 156 "*OOOOOOOO*......", 157 "*OOOO**OOO*.....", 158 "*OOO*..*OOO*....", 159 "*OO*....*OOO*...", 160 "*O*......*OOO*..", 161 "**........*OOO*.", 162 "*..........*OOO*", 163 "............*OO*", 164 ".............***" 165 };//16*16的字节的内存 166 int x, y; 167 168 for (y = 0; y < 16; y++) {//根据上面的鼠标数组建立一个绘制方案保存在mouse里 169 for (x = 0; x < 16; x++) { 170 if (cursor[y][x] == ‘*‘) {//边缘涂黑色 171 mouse[y * 16 + x] = COL8_000000; 172 } 173 if (cursor[y][x] == ‘O‘) {//内部涂白色 174 mouse[y * 16 + x] = COL8_FFFFFF; 175 } 176 if (cursor[y][x] == ‘.‘) {//外部图背景色 177 mouse[y * 16 + x] = bc; 178 } 179 } 180 } 181 return; 182 } 183 ///////////////////////////////////////////////////////////////////////////////////// 184 //功能:绘制鼠标 185 //参数:VRAM初址,x轴像素,鼠标指针大小,位置,鼠标绘制方案,bxsize和pxsize大体相同 186 //附件:鼠标绘制方案即初始化函数得到的mouse,真正用的时候,先初始化,然后就可以用这个函数绘制鼠标啦 187 void putblock8_8(char *vram, int vxsize, int pxsize, 188 int pysize, int px0, int py0, char *buf, int bxsize) 189 { 190 int x, y; 191 for (y = 0; y < pysize; y++) { 192 for (x = 0; x < pxsize; x++) { 193 vram[(py0 + y) * vxsize + (px0 + x)] = buf[y * bxsize + x]; 194 } 195 } 196 return; 197 }
1 /* 儅僂僗傗僂傿儞僪僂偺廳偹崌傢偣張棟 */ 2 3 #include "bootpack.h" 4 5 #define SHEET_USE 1 6 7 ///////////////////////////////////////////////////////////////////////////////////// 8 //功能:图层控制初始化 9 //参数: 10 struct SHTCTL *shtctl_init(struct MEMMAN *memman, unsigned char *vram, int xsize, int ysize) 11 { 12 struct SHTCTL *ctl; 13 int i; 14 ctl = (struct SHTCTL *) memman_alloc_4k(memman, sizeof (struct SHTCTL));//分配内存为图层管理结构体 15 if (ctl == 0) { 16 goto err; 17 } 18 ctl->map = (unsigned char *) memman_alloc_4k(memman, xsize * ysize); 19 if (ctl->map == 0) { 20 memman_free_4k(memman, (int) ctl, sizeof (struct SHTCTL)); 21 goto err; 22 } 23 ctl->vram = vram; 24 ctl->xsize = xsize; 25 ctl->ysize = ysize; 26 ctl->top = -1; /* 一个SHEET都没有 */ 27 for (i = 0; i < MAX_SHEETS; i++) { 28 ctl->sheets0[i].flags = 0; /* 标记为未使用 */ 29 ctl->sheets0[i].ctl = ctl; /* 強懏傪婰榐 */ 30 } 31 err: 32 return ctl; 33 } 34 ///////////////////////////////////////////////////////////////////////////////////// 35 //功能:取得新生成未使用的图层,从最前面的开始找,找到就算 36 //参数: 37 struct SHEET *sheet_alloc(struct SHTCTL *ctl) 38 { 39 struct SHEET *sht; 40 int i; 41 for (i = 0; i < MAX_SHEETS; i++) { 42 if (ctl->sheets0[i].flags == 0) { 43 sht = &ctl->sheets0[i]; 44 sht->flags = SHEET_USE; /* 标记为正在使用 */ 45 sht->height = -1; /* 隐藏 */ 46 return sht; 47 } 48 } 49 return 0; /* 所有SHEET都处在正在使用的状态 */ 50 } 51 ///////////////////////////////////////////////////////////////////////////////////// 52 //功能:设定涂层缓冲区的大小和透明色的函数 53 //参数: 54 void sheet_setbuf(struct SHEET *sht, unsigned char *buf, int xsize, int ysize, int col_inv) 55 { 56 sht->buf = buf; 57 sht->bxsize = xsize; 58 sht->bysize = ysize; 59 sht->col_inv = col_inv; 60 return; 61 } 62 ///////////////////////////////////////////////////////////////////////////////////// 63 //功能:显示缓冲映射,可以有效解决闪烁问题 64 //参数: 65 void sheet_refreshmap(struct SHTCTL *ctl, int vx0, int vy0, int vx1, int vy1, int h0) 66 { 67 int h, bx, by, vx, vy, bx0, by0, bx1, by1; 68 unsigned char *buf, sid, *map = ctl->map; 69 struct SHEET *sht; 70 if (vx0 < 0) { vx0 = 0; } 71 if (vy0 < 0) { vy0 = 0; } 72 if (vx1 > ctl->xsize) { vx1 = ctl->xsize; } 73 if (vy1 > ctl->ysize) { vy1 = ctl->ysize; } 74 for (h = h0; h <= ctl->top; h++) { 75 sht = ctl->sheets[h]; 76 sid = sht - ctl->sheets0; /* 斣抧傪堷偒嶼偟偰偦傟傪壓偠偒斣崋偲偟偰棙梡 */ 77 buf = sht->buf; 78 bx0 = vx0 - sht->vx0; 79 by0 = vy0 - sht->vy0; 80 bx1 = vx1 - sht->vx0; 81 by1 = vy1 - sht->vy0; 82 if (bx0 < 0) { bx0 = 0; } 83 if (by0 < 0) { by0 = 0; } 84 if (bx1 > sht->bxsize) { bx1 = sht->bxsize; } 85 if (by1 > sht->bysize) { by1 = sht->bysize; } 86 for (by = by0; by < by1; by++) { 87 vy = sht->vy0 + by; 88 for (bx = bx0; bx < bx1; bx++) { 89 vx = sht->vx0 + bx; 90 if (buf[by * sht->bxsize + bx] != sht->col_inv) { 91 map[vy * ctl->xsize + vx] = sid; 92 } 93 } 94 } 95 } 96 return; 97 } 98 ///////////////////////////////////////////////////////////////////////////////////// 99 //功能:刷新指定的区域(vx0, vy0, vx1, vy1) 100 //参数: 101 void sheet_refreshsub(struct SHTCTL *ctl, int vx0, int vy0, int vx1, int vy1, int h0, int h1) 102 { 103 int h, bx, by, vx, vy, bx0, by0, bx1, by1; 104 unsigned char *buf, *vram = ctl->vram, *map = ctl->map, sid; 105 struct SHEET *sht; 106 /* refresh超出画面则修正,解决鼠标跑画面外不出现的问题 */ 107 if (vx0 < 0) { vx0 = 0; } 108 if (vy0 < 0) { vy0 = 0; } 109 if (vx1 > ctl->xsize) { vx1 = ctl->xsize; } 110 if (vy1 > ctl->ysize) { vy1 = ctl->ysize; } 111 for (h = h0; h <= h1; h++) { 112 sht = ctl->sheets[h]; 113 buf = sht->buf; 114 sid = sht - ctl->sheets0; 115 /* 使用vx0~vy1,对bx0~by1进行倒推 */ 116 bx0 = vx0 - sht->vx0; 117 by0 = vy0 - sht->vy0; 118 bx1 = vx1 - sht->vx0; 119 by1 = vy1 - sht->vy0; 120 if (bx0 < 0) { bx0 = 0; } 121 if (by0 < 0) { by0 = 0; } 122 if (bx1 > sht->bxsize) { bx1 = sht->bxsize; } 123 if (by1 > sht->bysize) { by1 = sht->bysize; } 124 for (by = by0; by < by1; by++) { 125 vy = sht->vy0 + by; 126 for (bx = bx0; bx < bx1; bx++) { 127 vx = sht->vx0 + bx; 128 if (map[vy * ctl->xsize + vx] == sid) { 129 vram[vy * ctl->xsize + vx] = buf[by * sht->bxsize + bx]; 130 } 131 } 132 } 133 } 134 return; 135 } 136 ///////////////////////////////////////////////////////////////////////////////////// 137 //功能:设定底板高度函数 138 //参数: 139 void sheet_updown(struct SHEET *sht, int height) 140 { 141 struct SHTCTL *ctl = sht->ctl; 142 int h, old = sht->height; /* 存储设置前的高度信息 */ 143 144 /* 指定高度过高过低都要修正 */ 145 if (height > ctl->top + 1) { 146 height = ctl->top + 1; 147 } 148 if (height < -1) { 149 height = -1; 150 } 151 sht->height = height; /* 设定高度 */ 152 153 /* 主要是进行sheets[]的重新排列 */ 154 if (old > height) { /* 比以前低 */ 155 if (height >= 0) { 156 /* 把中间的往上提 */ 157 for (h = old; h > height; h--) { 158 ctl->sheets[h] = ctl->sheets[h - 1]; 159 ctl->sheets[h]->height = h; 160 } 161 ctl->sheets[height] = sht; 162 sheet_refreshmap(ctl, sht->vx0, sht->vy0, sht->vx0 + sht->bxsize, sht->vy0 + sht->bysize, height + 1); 163 sheet_refreshsub(ctl, sht->vx0, sht->vy0, sht->vx0 + sht->bxsize, sht->vy0 + sht->bysize, height + 1, old); 164 } else { /* 隐藏 */ 165 if (ctl->top > old) { 166 /* 降下来 */ 167 for (h = old; h < ctl->top; h++) { 168 ctl->sheets[h] = ctl->sheets[h + 1]; 169 ctl->sheets[h]->height = h; 170 } 171 } 172 ctl->top--; /* 由于显示中图层少了一个,所以最上面的图层的高度下降 */ 173 sheet_refreshmap(ctl, sht->vx0, sht->vy0, sht->vx0 + sht->bxsize, sht->vy0 + sht->bysize, 0); 174 sheet_refreshsub(ctl, sht->vx0, sht->vy0, sht->vx0 + sht->bxsize, sht->vy0 + sht->bysize, 0, old - 1); 175 } 176 } else if (old < height) { /* 比以前高 */ 177 if (old >= 0) { 178 /* 把中间的拉下去 */ 179 for (h = old; h < height; h++) { 180 ctl->sheets[h] = ctl->sheets[h + 1]; 181 ctl->sheets[h]->height = h; 182 } 183 ctl->sheets[height] = sht; 184 } else { /* 由隐藏状态转为显示状态 */ 185 /* 将已在上面的提上来 */ 186 for (h = ctl->top; h >= height; h--) { 187 ctl->sheets[h + 1] = ctl->sheets[h]; 188 ctl->sheets[h + 1]->height = h + 1; 189 } 190 ctl->sheets[height] = sht; 191 ctl->top++; /* 由于显示图层增加了一个,所以最上面的图层高度增加 */ 192 } 193 sheet_refreshmap(ctl, sht->vx0, sht->vy0, sht->vx0 + sht->bxsize, sht->vy0 + sht->bysize, height); 194 sheet_refreshsub(ctl, sht->vx0, sht->vy0, sht->vx0 + sht->bxsize, sht->vy0 + sht->bysize, height, height); 195 } 196 return; 197 } 198 ///////////////////////////////////////////////////////////////////////////////////// 199 //功能:刷新屏幕函数 200 //参数: 201 void sheet_refresh(struct SHEET *sht, int bx0, int by0, int bx1, int by1) 202 { 203 if (sht->height >= 0) { /* 如果正在显示,按照新图层的信息刷新画面 */ 204 sheet_refreshsub(sht->ctl, sht->vx0 + bx0, sht->vy0 + by0, sht->vx0 + bx1, sht->vy0 + by1, sht->height, sht->height); 205 } 206 return; 207 } 208 ///////////////////////////////////////////////////////////////////////////////////// 209 //功能:上下左右移动窗口 210 //参数: 211 void sheet_slide(struct SHEET *sht, int vx0, int vy0) 212 { 213 struct SHTCTL *ctl = sht->ctl; 214 int old_vx0 = sht->vx0, old_vy0 = sht->vy0; 215 sht->vx0 = vx0;//更新位置 216 sht->vy0 = vy0; 217 if (sht->height >= 0) { /* 如果正在显示,按照新图层刷新画面 */ 218 sheet_refreshmap(ctl, old_vx0, old_vy0, old_vx0 + sht->bxsize, old_vy0 + sht->bysize, 0); 219 sheet_refreshmap(ctl, vx0, vy0, vx0 + sht->bxsize, vy0 + sht->bysize, sht->height); 220 sheet_refreshsub(ctl, old_vx0, old_vy0, old_vx0 + sht->bxsize, old_vy0 + sht->bysize, 0, sht->height - 1); 221 sheet_refreshsub(ctl, vx0, vy0, vx0 + sht->bxsize, vy0 + sht->bysize, sht->height, sht->height); 222 } 223 return; 224 } 225 ///////////////////////////////////////////////////////////////////////////////////// 226 //功能:释放已使用图层的内存的函数 227 //参数: 228 void sheet_free(struct SHEET *sht) 229 { 230 if (sht->height >= 0) { 231 sheet_updown(sht, -1); /* 如果处于显示状态,则先隐藏 */ 232 } 233 sht->flags = 0; /* 标记为未使用 */ 234 return; 235 }
1 ; naskfunc 2 ; TAB=4 3 4 [FORMAT "WCOFF"] ; 制成目标文件的形式 5 [INSTRSET "i486p"] ; 使用486格式命令 6 [BITS 32] ; 制作32模式用的机器语言 7 [FILE "naskfunc.nas"] ; 源文件名信息 8 ; 程序中包含的函数名 9 GLOBAL _io_hlt, _io_cli, _io_sti, _io_stihlt 10 GLOBAL _io_in8, _io_in16, _io_in32 11 GLOBAL _io_out8, _io_out16, _io_out32 12 GLOBAL _io_load_eflags, _io_store_eflags 13 GLOBAL _load_gdtr, _load_idtr 14 GLOBAL _load_cr0, _store_cr0 ;新增 15 GLOBAL _asm_inthandler21, _asm_inthandler27, _asm_inthandler2c 16 GLOBAL _memtest_sub ;新增 17 EXTERN _inthandler21, _inthandler27, _inthandler2c 18 19 [SECTION .text] 20 21 _io_hlt: ; void io_hlt(void); 22 HLT 23 RET 24 25 _io_cli: ; void io_cli(void); 26 CLI 27 RET 28 29 _io_sti: ; void io_sti(void); 30 STI 31 RET 32 33 _io_stihlt: ; void io_stihlt(void); 34 STI 35 HLT 36 RET 37 38 _io_in8: ; int io_in8(int port); 39 MOV EDX,[ESP+4] ; port 40 MOV EAX,0 41 IN AL,DX 42 RET 43 44 _io_in16: ; int io_in16(int port); 45 MOV EDX,[ESP+4] ; port 46 MOV EAX,0 47 IN AX,DX 48 RET 49 50 _io_in32: ; int io_in32(int port); 51 MOV EDX,[ESP+4] ; port 52 IN EAX,DX 53 RET 54 55 _io_out8: ; void io_out8(int port, int data); 56 MOV EDX,[ESP+4] ; port 57 MOV AL,[ESP+8] ; data 58 OUT DX,AL 59 RET 60 61 _io_out16: ; void io_out16(int port, int data); 62 MOV EDX,[ESP+4] ; port 63 MOV EAX,[ESP+8] ; data 64 OUT DX,AX 65 RET 66 67 _io_out32: ; void io_out32(int port, int data); 68 MOV EDX,[ESP+4] ; port 69 MOV EAX,[ESP+8] ; data 70 OUT DX,EAX 71 RET 72 73 _io_load_eflags: ; int io_load_eflags(void); 74 PUSHFD ; PUSH EFLAGS 偲偄偆堄枴 75 POP EAX 76 RET 77 78 _io_store_eflags: ; void io_store_eflags(int eflags); 79 MOV EAX,[ESP+4] 80 PUSH EAX 81 POPFD ; POP EFLAGS 偲偄偆堄枴 82 RET 83 84 _load_gdtr: ; void load_gdtr(int limit, int addr); 85 MOV AX,[ESP+4] ; limit 86 MOV [ESP+6],AX 87 LGDT [ESP+6] 88 RET 89 90 ;1) 这个函数用来指定的段上限和地址赋值给GDTR的48位寄存器,这是个很特殊的寄存器,并不能用MOV来直接赋值 91 ;,唯一的方法就是指定一个内存地址,从指定的内存地址读取6字节(也就是48位),然后赋值给GDTR寄存器。完成这一任务的指令就是LGDT 92 ;2) 该寄存器的低16位(即内存的最初的2个字节)是段上限,它等于“GDT的有效的字节数-1”,剩下的32位,代表GDT的开始地址 93 ;3) 这里2个参数是ESP+4和ESP+8里存放,而我们要的是6字节形式的,所以要转换为我们想要的形式~ 94 _load_idtr: ; void load_idtr(int limit, int addr); 95 MOV AX,[ESP+4] ; limit 96 MOV [ESP+6],AX 97 LIDT [ESP+6] 98 RET 99 100 _load_cr0: ; int load_cr0(void); 101 MOV EAX,CR0 102 RET 103 104 _store_cr0: ; void store_cr0(int cr0); 105 MOV EAX,[ESP+4] 106 MOV CR0,EAX 107 RET 108 109 ;这个函数只是将寄存器的值保存在栈里,然后将DS和ES调整到与SS相等,再调用_inthandler21,返回后将所有寄存器的值再返回到原来的值,然后执行IRETD 110 ;之所以如此小心翼翼地保护寄存器,原因在于,中断处理发生在函数处理途中,通过IREDT从中断处理后,寄存器就乱了 111 _asm_inthandler21: 112 PUSH ES 113 PUSH DS 114 PUSHAD 115 MOV EAX,ESP 116 PUSH EAX 117 MOV AX,SS 118 MOV DS,AX 119 MOV ES,AX 120 CALL _inthandler21 121 POP EAX 122 POPAD 123 POP DS 124 POP ES 125 IRETD 126 127 _asm_inthandler27: 128 PUSH ES 129 PUSH DS 130 PUSHAD 131 MOV EAX,ESP 132 PUSH EAX 133 MOV AX,SS 134 MOV DS,AX 135 MOV ES,AX 136 CALL _inthandler27 137 POP EAX 138 POPAD 139 POP DS 140 POP ES 141 IRETD 142 143 _asm_inthandler2c: 144 PUSH ES 145 PUSH DS 146 PUSHAD 147 MOV EAX,ESP 148 PUSH EAX 149 MOV AX,SS 150 MOV DS,AX 151 MOV ES,AX 152 CALL _inthandler2c 153 POP EAX 154 POPAD 155 POP DS 156 POP ES 157 IRETD 158 159 160 ;///////////////////////////////////////////////////////////////////////////////////// 161 ;//功能:检查区域内的内存是否有效,因为c编译器会清除掉一些东西,所以就只能用汇编写,见naskfunc.nas 162 ;//参数:起始位置 163 ;//附加:写入取反看看修改没,再取反看看修改没,如果两次都修改就认为是能够使用的内存 164 ;unsigned int memtest_sub(unsigned int start,unsigned int end) 165 ;{ 166 ; unsigned int i,*p,old,pat0=0xaa55aa55,pat1=0x55aa55aa; 167 ; for(i=start;i<=end;i+=4){ 168 ; p=(unsigned int *)i; 169 ; old=*p; 170 ; *p=pat0; 171 ; *p^=0xffffffff; 172 ; if(*p!=pat1){ 173 ; not_memory: 174 ; *p=old; 175 ; break; 176 ; } 177 ; *p^=0xffffffff; 178 ; if(*p!=pat0){ 179 ; goto not_memory; 180 ; } 181 ; *p=old; 182 ; } 183 ; return i; 184 ;} 185 186 _memtest_sub: ; unsigned int memtest_sub(unsigned int start, unsigned int end) 187 PUSH EDI ; 由于还要使用EBX,ESI,EDI,所以对其进行保存 188 PUSH ESI 189 PUSH EBX 190 MOV ESI,0xaa55aa55 ; pat0 = 0xaa55aa55; 191 MOV EDI,0x55aa55aa ; pat1 = 0x55aa55aa; 192 MOV EAX,[ESP+12+4] ; i = start; 193 mts_loop: 194 MOV EBX,EAX 195 ADD EBX,0xffc ; p = i + 0xffc; 196 MOV EDX,[EBX] ; old = *p; 197 MOV [EBX],ESI ; *p = pat0; 198 XOR DWORD [EBX],0xffffffff ; *p ^= 0xffffffff; 199 CMP EDI,[EBX] ; if (*p != pat1) goto fin; 200 JNE mts_fin 201 XOR DWORD [EBX],0xffffffff ; *p ^= 0xffffffff; 202 CMP ESI,[EBX] ; if (*p != pat0) goto fin; 203 JNE mts_fin 204 MOV [EBX],EDX ; *p = old; 205 ADD EAX,0x1000 ; i += 0x1000; 206 CMP EAX,[ESP+12+8] ; if (i <= end) goto mts_loop; 207 JBE mts_loop 208 POP EBX 209 POP ESI 210 POP EDI 211 RET 212 mts_fin: 213 MOV [EBX],EDX ; *p = old; 214 POP EBX 215 POP ESI 216 POP EDI 217 RET
1 OSASK偺敿妏僼僅儞僩傪棳梡 2 3 char 0x00 4 ........ 5 ........ 6 ........ 7 ........ 8 ........ 9 ........ 10 ........ 11 ........ 12 ........ 13 ........ 14 ........ 15 ........ 16 ........ 17 ........ 18 ........ 19 ........ 20 21 char 0x01 22 ........ 23 ........ 24 ..***... 25 .*...*.. 26 *.....*. 27 *.*.*.*. 28 *.*.*.*. 29 *.....*. 30 *.....*. 31 *.*.*.*. 32 *..*..*. 33 .*...*.. 34 ..***... 35 ........ 36 ........ 37 ........ 38 39 char 0x02 40 ........ 41 ........ 42 ..***... 43 .*****.. 44 *******. 45 **.*.**. 46 **.*.**. 47 *******. 48 *******. 49 **.*.**. 50 ***.***. 51 .*****.. 52 ..***... 53 ........ 54 ........ 55 ........ 56 57 char 0x03 58 ........ 59 ........ 60 ........ 61 ........ 62 .**.**.. 63 *******. 64 *******. 65 *******. 66 .*****.. 67 ..***... 68 ...*.... 69 ........ 70 ........ 71 ........ 72 ........ 73 ........ 74 75 char 0x04 76 ........ 77 ........ 78 ........ 79 ........ 80 ...*.... 81 ..***... 82 .*****.. 83 *******. 84 .*****.. 85 ..***... 86 ...*.... 87 ........ 88 ........ 89 ........ 90 ........ 91 ........ 92 93 char 0x05 94 ........ 95 ........ 96 ........ 97 ........ 98 ...*.... 99 ..***... 100 .*.*.*.. 101 *******. 102 .*.*.*.. 103 ...*.... 104 ..***... 105 ........ 106 ........ 107 ........ 108 ........ 109 ........ 110 111 char 0x06 112 ........ 113 ........ 114 ........ 115 ........ 116 ...*.... 117 ..***... 118 .*****.. 119 *******. 120 **.*.**. 121 ...*.... 122 ..***... 123 ........ 124 ........ 125 ........ 126 ........ 127 ........ 128 129 char 0x07 130 ........ 131 ........ 132 ........ 133 ........ 134 ........ 135 ........ 136 ...**... 137 ..****.. 138 ..****.. 139 ...**... 140 ........ 141 ........ 142 ........ 143 ........ 144 ........ 145 ........ 146 147 char 0x08 148 ******** 149 ******** 150 ******** 151 ******** 152 ******** 153 ******** 154 ***..*** 155 **....** 156 **....** 157 ***..*** 158 ******** 159 ******** 160 ******** 161 ******** 162 ******** 163 ******** 164 165 char 0x09 166 ........ 167 ........ 168 ........ 169 ........ 170 ........ 171 ..****.. 172 .**..**. 173 .*....*. 174 .*....*. 175 .**..**. 176 ..****.. 177 ........ 178 ........ 179 ........ 180 ........ 181 ........ 182 183 char 0x0a 184 ******** 185 ******** 186 ******** 187 ******** 188 ******** 189 **....** 190 *..**..* 191 *.****.* 192 *.****.* 193 *..**..* 194 **....** 195 ******** 196 ******** 197 ******** 198 ******** 199 ******** 200 201 char 0x0b 202 ........ 203 ...*.... 204 ..***... 205 .*.*.*.. 206 *..*..*. 207 ...*.... 208 ...*.... 209 ..***... 210 .*...*.. 211 *.....*. 212 *.....*. 213 *.....*. 214 .*...*.. 215 ..***... 216 ........ 217 ........ 218 219 char 0x0c 220 ........ 221 ..***... 222 .*...*.. 223 *.....*. 224 *.....*. 225 *.....*. 226 .*...*.. 227 ..***... 228 ...*.... 229 ...*.... 230 *******. 231 ...*.... 232 ...*.... 233 ...*.... 234 ........ 235 ........ 236 237 char 0x0d 238 ........ 239 ........ 240 ....**.. 241 ....***. 242 ....*.** 243 ....*.** 244 ....*.*. 245 ....*... 246 ....*... 247 ...**... 248 .****... 249 *****... 250 .***.... 251 ........ 252 ........ 253 ........ 254 255 char 0x0e 256 ........ 257 ........ 258 ...***** 259 ...***** 260 ...*...* 261 ...*...* 262 ...*...* 263 ...*...* 264 ...*...* 265 ...*...* 266 .***.*** 267 ******** 268 .**..**. 269 ........ 270 ........ 271 ........ 272 273 char 0x0f 274 ........ 275 ........ 276 ........ 277 ........ 278 ...*.... 279 .*.*.*.. 280 ..***... 281 ..*.*... 282 ..***... 283 .*.*.*.. 284 ...*.... 285 ........ 286 ........ 287 ........ 288 ........ 289 ........ 290 291 char 0x10 292 ........ 293 *....... 294 **...... 295 ***..... 296 ****.... 297 *****... 298 ******.. 299 *******. 300 ******.. 301 *****... 302 ****.... 303 ***..... 304 **...... 305 *....... 306 ........ 307 ........ 308 309 char 0x11 310 ........ 311 ......*. 312 .....**. 313 ....***. 314 ...****. 315 ..*****. 316 .******. 317 *******. 318 .******. 319 ..*****. 320 ...****. 321 ....***. 322 .....**. 323 ......*. 324 ........ 325 ........ 326 327 char 0x12 328 ........ 329 ........ 330 ...*.... 331 ..***... 332 .*.*.*.. 333 *..*..*. 334 ...*.... 335 ...*.... 336 ...*.... 337 *..*..*. 338 .*.*.*.. 339 ..***... 340 ...*.... 341 ........ 342 ........ 343 ........ 344 345 char 0x13 346 ........ 347 ........ 348 .*...*.. 349 .*...*.. 350 .*...*.. 351 .*...*.. 352 .*...*.. 353 .*...*.. 354 .*...*.. 355 .*...*.. 356 ........ 357 ........ 358 .*...*.. 359 .*...*.. 360 ........ 361 ........ 362 363 char 0x14 364 ........ 365 ..*****. 366 .*..*.*. 367 *...*.*. 368 *...*.*. 369 *...*.*. 370 *...*.*. 371 .*..*.*. 372 ..***.*. 373 ....*.*. 374 ....*.*. 375 ....*.*. 376 ....*.*. 377 ....*.*. 378 ........ 379 ........ 380 381 char 0x15 382 .*****.. 383 *.....*. 384 .*...... 385 ..*..... 386 ..***... 387 .*...*.. 388 *.....*. 389 *.....*. 390 *.....*. 391 .*...*.. 392 ..***... 393 ....*... 394 .....*.. 395 *.....*. 396 .*****.. 397 ........ 398 399 char 0x16 400 ........ 401 ........ 402 ........ 403 ........ 404 ........ 405 ........ 406 ........ 407 ........ 408 ........ 409 ........ 410 ........ 411 *******. 412 *******. 413 *******. 414 ........ 415 ........ 416 417 char 0x17 418 ........ 419 ........ 420 ...*.... 421 ..***... 422 .*.*.*.. 423 *..*..*. 424 ...*.... 425 ...*.... 426 ...*.... 427 *..*..*. 428 .*.*.*.. 429 ..***... 430 ...*.... 431 .*****.. 432 ........ 433 ........ 434 435 char 0x18 436 ........ 437 ...*.... 438 ..***... 439 .*.*.*.. 440 *..*..*. 441 ...*.... 442 ...*.... 443 ...*.... 444 ...*.... 445 ...*.... 446 ...*.... 447 ...*.... 448 ...*.... 449 ...*.... 450 ........ 451 ........ 452 453 char 0x19 454 ........ 455 ...*.... 456 ...*.... 457 ...*.... 458 ...*.... 459 ...*.... 460 ...*.... 461 ...*.... 462 ...*.... 463 ...*.... 464 *..*..*. 465 .*.*.*.. 466 ..***... 467 ...*.... 468 ........ 469 ........ 470 471 char 0x1a 472 ........ 473 ........ 474 ........ 475 ........ 476 ...*.... 477 ....*... 478 .....*.. 479 *******. 480 .....*.. 481 ....*... 482 ...*.... 483 ........ 484 ........ 485 ........ 486 ........ 487 ........ 488 489 char 0x1b 490 ........ 491 ........ 492 ........ 493 ........ 494 ...*.... 495 ..*..... 496 .*...... 497 *******. 498 .*...... 499 ..*..... 500 ...*.... 501 ........ 502 ........ 503 ........ 504 ........ 505 ........ 506 507 char 0x1c 508 ........ 509 ........ 510 ........ 511 ........ 512 ........ 513 ........ 514 ........ 515 ........ 516 ........ 517 ........ 518 ........ 519 *....... 520 *....... 521 *******. 522 ........ 523 ........ 524 525 char 0x1d 526 ........ 527 ........ 528 ........ 529 ........ 530 ........ 531 ..*.*... 532 .*...*.. 533 *******. 534 .*...*.. 535 ..*.*... 536 ........ 537 ........ 538 ........ 539 ........ 540 ........ 541 ........ 542 543 char 0x1e 544 ........ 545 ........ 546 ........ 547 ........ 548 ...*.... 549 ...*.... 550 ..***... 551 ..***... 552 .*****.. 553 .*****.. 554 *******. 555 *******. 556 ........ 557 ........ 558 ........ 559 ........ 560 561 char 0x1f 562 ........ 563 ........ 564 ........ 565 ........ 566 *******. 567 *******. 568 .*****.. 569 .*****.. 570 ..***... 571 ..***... 572 ...*.... 573 ...*.... 574 ........ 575 ........ 576 ........ 577 ........ 578 579 char 0x20 580 ........ 581 ........ 582 ........ 583 ........ 584 ........ 585 ........ 586 ........ 587 ........ 588 ........ 589 ........ 590 ........ 591 ........ 592 ........ 593 ........ 594 ........ 595 ........ 596 597 char 0x21 598 ........ 599 ...*.... 600 ...*.... 601 ...*.... 602 ...*.... 603 ...*.... 604 ...*.... 605 ...*.... 606 ...*.... 607 ...*.... 608 ........ 609 ........ 610 ...*.... 611 ...*.... 612 ........ 613 ........ 614 615 char 0x22 616 ..*.*... 617 ..*.*... 618 ..*.*... 619 ........ 620 ........ 621 ........ 622 ........ 623 ........ 624 ........ 625 ........ 626 ........ 627 ........ 628 ........ 629 ........ 630 ........ 631 ........ 632 633 char 0x23 634 ........ 635 .*...*.. 636 .*...*.. 637 .*...*.. 638 *******. 639 .*...*.. 640 .*...*.. 641 .*...*.. 642 .*...*.. 643 .*...*.. 644 *******. 645 .*...*.. 646 .*...*.. 647 .*...*.. 648 ........ 649 ........ 650 651 char 0x24 652 ...*.... 653 ..***.*. 654 .*.*.**. 655 *..*..*. 656 *..*..*. 657 *..*.... 658 .*.*.... 659 ..***... 660 ...*.*.. 661 ...*..*. 662 *..*..*. 663 *..*..*. 664 **.*.*.. 665 *.***... 666 ...*.... 667 ...*.... 668 669 char 0x25 670 .**...*. 671 *..*..*. 672 *..*.*.. 673 *..*.*.. 674 .**.*... 675 ....*... 676 ...*.... 677 ...*.... 678 ..*..... 679 ..*.**.. 680 .*.*..*. 681 .*.*..*. 682 *..*..*. 683 *...**.. 684 ........ 685 ........ 686 687 char 0x26 688 ........ 689 .***.... 690 *...*... 691 *...*... 692 *...*... 693 *..*.... 694 .**..... 695 .*...*** 696 *.*...*. 697 *..*..*. 698 *...*.*. 699 *....*.. 700 .*...**. 701 ..***..* 702 ........ 703 ........ 704 705 char 0x27 706 .....*.. 707 ....*... 708 ...*.... 709 ........ 710 ........ 711 ........ 712 ........ 713 ........ 714 ........ 715 ........ 716 ........ 717 ........ 718 ........ 719 ........ 720 ........ 721 ........ 722 723 char 0x28 724 ......*. 725 .....*.. 726 ....*... 727 ....*... 728 ...*.... 729 ...*.... 730 ...*.... 731 ...*.... 732 ...*.... 733 ...*.... 734 ...*.... 735 ....*... 736 ....*... 737 .....*.. 738 ......*. 739 ........ 740 741 char 0x29 742 *....... 743 .*...... 744 ..*..... 745 ..*..... 746 ...*.... 747 ...*.... 748 ...*.... 749 ...*.... 750 ...*.... 751 ...*.... 752 ...*.... 753 ..*..... 754 ..*..... 755 .*...... 756 *....... 757 ........ 758 759 char 0x2a 760 ........ 761 ........ 762 ........ 763 ........ 764 ........ 765 ...*.... 766 *..*..*. 767 .*.*.*.. 768 ..***... 769 .*.*.*.. 770 *..*..*. 771 ...*.... 772 ........ 773 ........ 774 ........ 775 ........ 776 777 char 0x2b 778 ........ 779 ........ 780 ........ 781 ........ 782 ........ 783 ...*.... 784 ...*.... 785 ...*.... 786 *******. 787 ...*.... 788 ...*.... 789 ...*.... 790 ........ 791 ........ 792 ........ 793 ........ 794 795 char 0x2c 796 ........ 797 ........ 798 ........ 799 ........ 800 ........ 801 ........ 802 ........ 803 ........ 804 ........ 805 ........ 806 ........ 807 ...**... 808 ...**... 809 ....*... 810 ....*... 811 ...*.... 812 813 char 0x2d 814 ........ 815 ........ 816 ........ 817 ........ 818 ........ 819 ........ 820 ........ 821 ........ 822 *******. 823 ........ 824 ........ 825 ........ 826 ........ 827 ........ 828 ........ 829 ........ 830 831 char 0x2e 832 ........ 833 ........ 834 ........ 835 ........ 836 ........ 837 ........ 838 ........ 839 ........ 840 ........ 841 ........ 842 ........ 843 ........ 844 ...**... 845 ...**... 846 ........ 847 ........ 848 849 char 0x2f 850 ......*. 851 ......*. 852 .....*.. 853 .....*.. 854 ....*... 855 ....*... 856 ....*... 857 ...*.... 858 ...*.... 859 ..*..... 860 ..*..... 861 .*...... 862 .*...... 863 .*...... 864 *....... 865 *....... 866 867 char 0x30 868 ........ 869 ...**... 870 ..*..*.. 871 ..*..*.. 872 .*....*. 873 .*....*. 874 .*....*. 875 .*....*. 876 .*....*. 877 .*....*. 878 .*....*. 879 ..*..*.. 880 ..*..*.. 881 ...**... 882 ........ 883 ........ 884 885 char 0x31 886 ........ 887 ....*... 888 ...**... 889 ..*.*... 890 ....*... 891 ....*... 892 ....*... 893 ....*... 894 ....*... 895 ....*... 896 ....*... 897 ....*... 898 ....*... 899 ..*****. 900 ........ 901 ........ 902 903 char 0x32 904 ........ 905 ...**... 906 ..*..*.. 907 .*....*. 908 .*....*. 909 ......*. 910 .....*.. 911 ....*... 912 ...*.... 913 ..*..... 914 ..*..... 915 .*...... 916 .*...... 917 .******. 918 ........ 919 ........ 920 921 char 0x33 922 ........ 923 ...**... 924 ..*..*.. 925 .*....*. 926 ......*. 927 ......*. 928 .....*.. 929 ...**... 930 .....*.. 931 ......*. 932 ......*. 933 .*....*. 934 ..*..*.. 935 ...**... 936 ........ 937 ........ 938 939 char 0x34 940 ........ 941 ....**.. 942 ....**.. 943 ....**.. 944 ...*.*.. 945 ...*.*.. 946 ...*.*.. 947 ..*..*.. 948 ..*..*.. 949 .*...*.. 950 .******. 951 .....*.. 952 .....*.. 953 ...****. 954 ........ 955 ........ 956 957 char 0x35 958 ........ 959 .*****.. 960 .*...... 961 .*...... 962 .*...... 963 .*.**... 964 .**..*.. 965 ......*. 966 ......*. 967 ......*. 968 ......*. 969 .*....*. 970 ..*..*.. 971 ...**... 972 ........ 973 ........ 974 975 char 0x36 976 ........ 977 ...**... 978 ..*..*.. 979 .*....*. 980 .*...... 981 .*.**... 982 .**..*.. 983 .*....*. 984 .*....*. 985 .*....*. 986 .*....*. 987 .*....*. 988 ..*..*.. 989 ...**... 990 ........ 991 ........ 992 993 char 0x37 994 ........ 995 .******. 996 .*....*. 997 .*....*. 998 .....*.. 999 .....*.. 1000 ....*... 1001 ....*... 1002 ....*... 1003 ...*.... 1004 ...*.... 1005 ...*.... 1006 ...*.... 1007 ..***... 1008 ........ 1009 ........ 1010 1011 char 0x38 1012 ........ 1013 ...**... 1014 ..*..*.. 1015 .*....*. 1016 .*....*. 1017 .*....*. 1018 ..*..*.. 1019 ...**... 1020 ..*..*.. 1021 .*....*. 1022 .*....*. 1023 .*....*. 1024 ..*..*.. 1025 ...**... 1026 ........ 1027 ........ 1028 1029 char 0x39 1030 ........ 1031 ...**... 1032 ..*..*.. 1033 .*....*. 1034 .*....*. 1035 .*....*. 1036 .*....*. 1037 .*....*. 1038 ..*..**. 1039 ...**.*. 1040 ......*. 1041 .*....*. 1042 ..*..*.. 1043 ...**... 1044 ........ 1045 ........ 1046 1047 char 0x3a 1048 ........ 1049 ........ 1050 ........ 1051 ........ 1052 ........ 1053 ...**... 1054 ...**... 1055 ........ 1056 ........ 1057 ........ 1058 ........ 1059 ........ 1060 ...**... 1061 ...**... 1062 ........ 1063 ........ 1064 1065 char 0x3b 1066 ........ 1067 ........ 1068 ........ 1069 ........ 1070 ........ 1071 ...**... 1072 ...**... 1073 ........ 1074 ........ 1075 ........ 1076 ........ 1077 ...**... 1078 ...**... 1079 ....*... 1080 ....*... 1081 ...*.... 1082 1083 char 0x3c 1084 ........ 1085 ......*. 1086 .....*.. 1087 ....*... 1088 ...*.... 1089 ..*..... 1090 .*...... 1091 *....... 1092 *....... 1093 .*...... 1094 ..*..... 1095 ...*.... 1096 ....*... 1097 .....*.. 1098 ......*. 1099 ........ 1100 1101 char 0x3d 1102 ........ 1103 ........ 1104 ........ 1105 ........ 1106 ........ 1107 ........ 1108 *******. 1109 ........ 1110 ........ 1111 *******. 1112 ........ 1113 ........ 1114 ........ 1115 ........ 1116 ........ 1117 ........ 1118 1119 char 0x3e 1120 ........ 1121 *....... 1122 .*...... 1123 ..*..... 1124 ...*.... 1125 ....*... 1126 .....*.. 1127 ......*. 1128 ......*. 1129 .....*.. 1130 ....*... 1131 ...*.... 1132 ..*..... 1133 .*...... 1134 *....... 1135 ........ 1136 1137 char 0x3f 1138 ........ 1139 ..***... 1140 .*...*.. 1141 *.....*. 1142 *.....*. 1143 *.....*. 1144 .....*.. 1145 ....*... 1146 ...*.... 1147 ...*.... 1148 ........ 1149 ........ 1150 ...**... 1151 ...**... 1152 ........ 1153 ........ 1154 1155 char 0x40 1156 ........ 1157 ..***... 1158 .*...*.. 1159 *.....*. 1160 *..**.*. 1161 *.*.*.*. 1162 *.*.*.*. 1163 *.*.*.*. 1164 *.*.*.*. 1165 *.*.*.*. 1166 *..***.. 1167 *....... 1168 .*...**. 1169 ..***... 1170 ........ 1171 ........ 1172 1173 char 0x41 1174 ........ 1175 ...**... 1176 ...**... 1177 ...**... 1178 ...**... 1179 ..*..*.. 1180 ..*..*.. 1181 ..*..*.. 1182 ..*..*.. 1183 .******. 1184 .*....*. 1185 .*....*. 1186 .*....*. 1187 ***..*** 1188 ........ 1189 ........ 1190 1191 char 0x42 1192 ........ 1193 ****.... 1194 .*..*... 1195 .*...*.. 1196 .*...*.. 1197 .*...*.. 1198 .*..*... 1199 .****... 1200 .*...*.. 1201 .*....*. 1202 .*....*. 1203 .*....*. 1204 .*...*.. 1205 *****... 1206 ........ 1207 ........ 1208 1209 char 0x43 1210 ........ 1211 ..***.*. 1212 .*...**. 1213 .*....*. 1214 *.....*. 1215 *....... 1216 *....... 1217 *....... 1218 *....... 1219 *....... 1220 *.....*. 1221 .*....*. 1222 .*...*.. 1223 ..***... 1224 ........ 1225 ........ 1226 1227 char 0x44 1228 ........ 1229 *****... 1230 .*...*.. 1231 .*...*.. 1232 .*....*. 1233 .*....*. 1234 .*....*. 1235 .*....*. 1236 .*....*. 1237 .*....*. 1238 .*....*. 1239 .*...*.. 1240 .*...*.. 1241 *****... 1242 ........ 1243 ........ 1244 1245 char 0x45 1246 ........ 1247 *******. 1248 .*....*. 1249 .*....*. 1250 .*...... 1251 .*...... 1252 .*...*.. 1253 .*****.. 1254 .*...*.. 1255 .*...... 1256 .*...... 1257 .*....*. 1258 .*....*. 1259 *******. 1260 ........ 1261 ........ 1262 1263 char 0x46 1264 ........ 1265 *******. 1266 .*....*. 1267 .*....*. 1268 .*...... 1269 .*...... 1270 .*...*.. 1271 .*****.. 1272 .*...*.. 1273 .*...*.. 1274 .*...... 1275 .*...... 1276 .*...... 1277 ****.... 1278 ........ 1279 ........ 1280 1281 char 0x47 1282 ........ 1283 ..***.*. 1284 .*...**. 1285 .*....*. 1286 *.....*. 1287 *....... 1288 *....... 1289 *..****. 1290 *.....*. 1291 *.....*. 1292 *.....*. 1293 .*....*. 1294 .*...**. 1295 ..***... 1296 ........ 1297 ........ 1298 1299 char 0x48 1300 ........ 1301 ***..*** 1302 .*....*. 1303 .*....*. 1304 .*....*. 1305 .*....*. 1306 .*....*. 1307 .******. 1308 .*....*. 1309 .*....*. 1310 .*....*. 1311 .*....*. 1312 .*....*. 1313 ***..*** 1314 ........ 1315 ........ 1316 1317 char 0x49 1318 ........ 1319 .*****.. 1320 ...*.... 1321 ...*.... 1322 ...*.... 1323 ...*.... 1324 ...*.... 1325 ...*.... 1326 ...*.... 1327 ...*.... 1328 ...*.... 1329 ...*.... 1330 ...*.... 1331 .*****.. 1332 ........ 1333 ........ 1334 1335 char 0x4a 1336 ........ 1337 ...***** 1338 .....*.. 1339 .....*.. 1340 .....*.. 1341 .....*.. 1342 .....*.. 1343 .....*.. 1344 .....*.. 1345 .....*.. 1346 .....*.. 1347 .....*.. 1348 *....*.. 1349 .*..*... 1350 ..**.... 1351 ........ 1352 1353 char 0x4b 1354 ........ 1355 ***..*** 1356 .*....*. 1357 .*...*.. 1358 .*..*... 1359 .*.*.... 1360 .*.*.... 1361 .**..... 1362 .*.*.... 1363 .*.*.... 1364 .*..*... 1365 .*...*.. 1366 .*....*. 1367 ***..*** 1368 ........ 1369 ........ 1370 1371 char 0x4c 1372 ........ 1373 ****.... 1374 .*...... 1375 .*...... 1376 .*...... 1377 .*...... 1378 .*...... 1379 .*...... 1380 .*...... 1381 .*...... 1382 .*...... 1383 .*....*. 1384 .*....*. 1385 *******. 1386 ........ 1387 ........ 1388 1389 char 0x4d 1390 ........ 1391 **....** 1392 .*....*. 1393 .**..**. 1394 .**..**. 1395 .**..**. 1396 .*.**.*. 1397 .*.**.*. 1398 .*.**.*. 1399 .*....*. 1400 .*....*. 1401 .*....*. 1402 .*....*. 1403 ***..*** 1404 ........ 1405 ........ 1406 1407 char 0x4e 1408 ........ 1409 **...*** 1410 .*....*. 1411 .**...*. 1412 .**...*. 1413 .*.*..*. 1414 .*.*..*. 1415 .*.*..*. 1416 .*..*.*. 1417 .*..*.*. 1418 .*..*.*. 1419 .*...**. 1420 .*...**. 1421 ***...*. 1422 ........ 1423 ........ 1424 1425 char 0x4f 1426 ........ 1427 ..***... 1428 .*...*.. 1429 *.....*. 1430 *.....*. 1431 *.....*. 1432 *.....*. 1433 *.....*. 1434 *.....*. 1435 *.....*. 1436 *.....*. 1437 *.....*. 1438 .*...*.. 1439 ..***... 1440 ........ 1441 ........ 1442 1443 char 0x50 1444 ........ 1445 *****... 1446 .*...*.. 1447 .*....*. 1448 .*....*. 1449 .*....*. 1450 .*...*.. 1451 .****... 1452 .*...... 1453 .*...... 1454 .*...... 1455 .*...... 1456 .*...... 1457 ****.... 1458 ........ 1459 ........ 1460 1461 char 0x51 1462 ........ 1463 ..***... 1464 .*...*.. 1465 *.....*. 1466 *.....*. 1467 *.....*. 1468 *.....*. 1469 *.....*. 1470 *.....*. 1471 *.....*. 1472 *..*..*. 1473 *...*.*. 1474 .*...*.. 1475 ..***.*. 1476 ........ 1477 ........ 1478 1479 char 0x52 1480 ........ 1481 ******.. 1482 .*....*. 1483 .*....*. 1484 .*....*. 1485 .*....*. 1486 .*****.. 1487 .*...*.. 1488 .*....*. 1489 .*....*. 1490 .*....*. 1491 .*....*. 1492 .*....*. 1493 ***..*** 1494 ........ 1495 ........ 1496 1497 char 0x53 1498 ........ 1499 ..***.*. 1500 .*...**. 1501 *.....*. 1502 *.....*. 1503 *....... 1504 .*...... 1505 ..***... 1506 .....*.. 1507 ......*. 1508 *.....*. 1509 *.....*. 1510 **...*.. 1511 *.***... 1512 ........ 1513 ........ 1514 1515 char 0x54 1516 ........ 1517 *******. 1518 *..*..*. 1519 *..*..*. 1520 ...*.... 1521 ...*.... 1522 ...*.... 1523 ...*.... 1524 ...*.... 1525 ...*.... 1526 ...*.... 1527 ...*.... 1528 ...*.... 1529 .*****.. 1530 ........ 1531 ........ 1532 1533 char 0x55 1534 ........ 1535 ***..*** 1536 .*....*. 1537 .*....*. 1538 .*....*. 1539 .*....*. 1540 .*....*. 1541 .*....*. 1542 .*....*. 1543 .*....*. 1544 .*....*. 1545 .*....*. 1546 ..*..*.. 1547 ..****.. 1548 ........ 1549 ........ 1550 1551 char 0x56 1552 ........ 1553 ***..*** 1554 .*....*. 1555 .*....*. 1556 .*....*. 1557 .*....*. 1558 ..*..*.. 1559 ..*..*.. 1560 ..*..*.. 1561 ..*..*.. 1562 ...**... 1563 ...**... 1564 ...**... 1565 ...**... 1566 ........ 1567 ........ 1568 1569 char 0x57 1570 ........ 1571 ***..*** 1572 .*....*. 1573 .*....*. 1574 .*....*. 1575 .*.**.*. 1576 .*.**.*. 1577 .*.**.*. 1578 .*.**.*. 1579 ..*..*.. 1580 ..*..*.. 1581 ..*..*.. 1582 ..*..*.. 1583 ..*..*.. 1584 ........ 1585 ........ 1586 1587 char 0x58 1588 ........ 1589 ***..*** 1590 .*....*. 1591 .*....*. 1592 ..*..*.. 1593 ..*..*.. 1594 ..*..*.. 1595 ...**... 1596 ..*..*.. 1597 ..*..*.. 1598 ..*..*.. 1599 .*....*. 1600 .*....*. 1601 ***..*** 1602 ........ 1603 ........ 1604 1605 char 0x59 1606 ........ 1607 ***.***. 1608 .*...*.. 1609 .*...*.. 1610 .*...*.. 1611 ..*.*... 1612 ..*.*... 1613 ..*.*... 1614 ...*.... 1615 ...*.... 1616 ...*.... 1617 ...*.... 1618 ...*.... 1619 .*****.. 1620 ........ 1621 ........ 1622 1623 char 0x5a 1624 ........ 1625 *******. 1626 *....*.. 1627 *....*.. 1628 ....*... 1629 ....*... 1630 ...*.... 1631 ...*.... 1632 ..*..... 1633 ..*..... 1634 .*...... 1635 .*....*. 1636 *.....*. 1637 *******. 1638 ........ 1639 ........ 1640 1641 char 0x5b 1642 ........ 1643 ..*****. 1644 ..*..... 1645 ..*..... 1646 ..*..... 1647 ..*..... 1648 ..*..... 1649 ..*..... 1650 ..*..... 1651 ..*..... 1652 ..*..... 1653 ..*..... 1654 ..*..... 1655 ..*..... 1656 ..*****. 1657 ........ 1658 1659 char 0x5c 1660 *....... 1661 *....... 1662 .*...... 1663 .*...... 1664 ..*..... 1665 ..*..... 1666 ..*..... 1667 ...*.... 1668 ...*.... 1669 ....*... 1670 ....*... 1671 .....*.. 1672 .....*.. 1673 .....*.. 1674 ......*. 1675 ......*. 1676 1677 char 0x5d 1678 ........ 1679 .*****.. 1680 .....*.. 1681 .....*.. 1682 .....*.. 1683 .....*.. 1684 .....*.. 1685 .....*.. 1686 .....*.. 1687 .....*.. 1688 .....*.. 1689 .....*.. 1690 .....*.. 1691 .....*.. 1692 .*****.. 1693 ........ 1694 1695 char 0x5e 1696 ........ 1697 ...*.... 1698 ..*.*... 1699 .*...*.. 1700 *.....*. 1701 ........ 1702 ........ 1703 ........ 1704 ........ 1705 ........ 1706 ........ 1707 ........ 1708 ........ 1709 ........ 1710 ........ 1711 ........ 1712 1713 char 0x5f 1714 ........ 1715 ........ 1716 ........ 1717 ........ 1718 ........ 1719 ........ 1720 ........ 1721 ........ 1722 ........ 1723 ........ 1724 ........ 1725 ........ 1726 ........ 1727 ........ 1728 *******. 1729 ........ 1730 1731 char 0x60 1732 ...*.... 1733 ....*... 1734 .....*.. 1735 ........ 1736 ........ 1737 ........ 1738 ........ 1739 ........ 1740 ........ 1741 ........ 1742 ........ 1743 ........ 1744 ........ 1745 ........ 1746 ........ 1747 ........ 1748 1749 char 0x61 1750 ........ 1751 ........ 1752 ........ 1753 ........ 1754 ........ 1755 .***.... 1756 ....*... 1757 .....*.. 1758 ..****.. 1759 .*...*.. 1760 *....*.. 1761 *....*.. 1762 *...**.. 1763 .***.**. 1764 ........ 1765 ........ 1766 1767 char 0x62 1768 **...... 1769 .*...... 1770 .*...... 1771 .*...... 1772 .*...... 1773 .*.**... 1774 .**..*.. 1775 .*....*. 1776 .*....*. 1777 .*....*. 1778 .*....*. 1779 .*....*. 1780 .**..*.. 1781 .*.**... 1782 ........ 1783 ........ 1784 1785 char 0x63 1786 ........ 1787 ........ 1788 ........ 1789 ........ 1790 ........ 1791 ..**.... 1792 .*..**.. 1793 *....*.. 1794 *....*.. 1795 *....... 1796 *....... 1797 *.....*. 1798 .*...*.. 1799 ..***... 1800 ........ 1801 ........ 1802 1803 char 0x64 1804 ....**.. 1805 .....*.. 1806 .....*.. 1807 .....*.. 1808 .....*.. 1809 ..**.*.. 1810 .*..**.. 1811 *....*.. 1812 *....*.. 1813 *....*.. 1814 *....*.. 1815 *....*.. 1816 .*..**.. 1817 ..**.**. 1818 ........ 1819 ........ 1820 1821 char 0x65 1822 ........ 1823 ........ 1824 ........ 1825 ........ 1826 ........ 1827 ..***... 1828 .*...*.. 1829 *.....*. 1830 *.....*. 1831 ******.. 1832 *....... 1833 *.....*. 1834 .*....*. 1835 ..****.. 1836 ........ 1837 ........ 1838 1839 char 0x66 1840 ....***. 1841 ...*.... 1842 ...*.... 1843 ...*.... 1844 ...*.... 1845 .*****.. 1846 ...*.... 1847 ...*.... 1848 ...*.... 1849 ...*.... 1850 ...*.... 1851 ...*.... 1852 ...*.... 1853 .*****.. 1854 ........ 1855 ........ 1856 1857 char 0x67 1858 ........ 1859 ........ 1860 ........ 1861 ........ 1862 ........ 1863 ..**.**. 1864 .*..**.. 1865 *....*.. 1866 *....*.. 1867 *....*.. 1868 *....*.. 1869 .*..**.. 1870 ..**.*.. 1871 .....*.. 1872 .....*.. 1873 .****... 1874 1875 char 0x68 1876 **...... 1877 .*...... 1878 .*...... 1879 .*...... 1880 .*...... 1881 .*.**... 1882 .**..*.. 1883 .*....*. 1884 .*....*. 1885 .*....*. 1886 .*....*. 1887 .*....*. 1888 .*....*. 1889 ***...** 1890 ........ 1891 ........ 1892 1893 char 0x69 1894 ........ 1895 ...*.... 1896 ...*.... 1897 ........ 1898 ........ 1899 ..**.... 1900 ...*.... 1901 ...*.... 1902 ...*.... 1903 ...*.... 1904 ...*.... 1905 ...*.... 1906 ...*.... 1907 ..***... 1908 ........ 1909 ........ 1910 1911 char 0x6a 1912 ........ 1913 .....*.. 1914 .....*.. 1915 ........ 1916 ........ 1917 ....**.. 1918 .....*.. 1919 .....*.. 1920 .....*.. 1921 .....*.. 1922 .....*.. 1923 .....*.. 1924 .....*.. 1925 ....*... 1926 ....*... 1927 ..**.... 1928 1929 char 0x6b 1930 **...... 1931 .*...... 1932 .*...... 1933 .*...... 1934 .*...... 1935 .*..***. 1936 .*...*.. 1937 .*..*... 1938 .*.*.... 1939 .**..... 1940 .*.*.... 1941 .*..*... 1942 .*...*.. 1943 ***..**. 1944 ........ 1945 ........ 1946 1947 char 0x6c 1948 ..**.... 1949 ...*.... 1950 ...*.... 1951 ...*.... 1952 ...*.... 1953 ...*.... 1954 ...*.... 1955 ...*.... 1956 ...*.... 1957 ...*.... 1958 ...*.... 1959 ...*.... 1960 ...*.... 1961 ..***... 1962 ........ 1963 ........ 1964 1965 char 0x6d 1966 ........ 1967 ........ 1968 ........ 1969 ........ 1970 ........ 1971 ****.**. 1972 .*..*..* 1973 .*..*..* 1974 .*..*..* 1975 .*..*..* 1976 .*..*..* 1977 .*..*..* 1978 .*..*..* 1979 **.**.** 1980 ........ 1981 ........ 1982 1983 char 0x6e 1984 ........ 1985 ........ 1986 ........ 1987 ........ 1988 ........ 1989 **.**... 1990 .**..*.. 1991 .*....*. 1992 .*....*. 1993 .*....*. 1994 .*....*. 1995 .*....*. 1996 .*....*. 1997 ***...** 1998 ........ 1999 ........ 2000 2001 char 0x6f 2002 ........ 2003 ........ 2004 ........ 2005 ........ 2006 ........ 2007 ..***... 2008 .*...*.. 2009 *.....*. 2010 *.....*. 2011 *.....*. 2012 *.....*. 2013 *.....*. 2014 .*...*.. 2015 ..***... 2016 ........ 2017 ........ 2018 2019 char 0x70 2020 ........ 2021 ........ 2022 ........ 2023 ........ 2024 ........ 2025 **.**... 2026 .**..*.. 2027 .*....*. 2028 .*....*. 2029 .*....*. 2030 .*....*. 2031 .*....*. 2032 .**..*.. 2033 .*.**... 2034 .*...... 2035 ***..... 2036 2037 char 0x71 2038 ........ 2039 ........ 2040 ........ 2041 ........ 2042 ........ 2043 ..**.*.. 2044 .*..**.. 2045 *....*.. 2046 *....*.. 2047 *....*.. 2048 *....*.. 2049 *....*.. 2050 .*..**.. 2051 ..**.*.. 2052 .....*.. 2053 ....***. 2054 2055 char 0x72 2056 ........ 2057 ........ 2058 ........ 2059 ........ 2060 ........ 2061 **.***.. 2062 .**...*. 2063 .*....*. 2064 .*...... 2065 .*...... 2066 .*...... 2067 .*...... 2068 .*...... 2069 ***..... 2070 ........ 2071 ........ 2072 2073 char 0x73 2074 ........ 2075 ........ 2076 ........ 2077 ........ 2078 ........ 2079 .****.*. 2080 *....**. 2081 *.....*. 2082 **...... 2083 ..***... 2084 .....**. 2085 *.....*. 2086 **....*. 2087 *.****.. 2088 ........ 2089 ........ 2090 2091 char 0x74 2092 ........ 2093 ........ 2094 ...*.... 2095 ...*.... 2096 ...*.... 2097 .*****.. 2098 ...*.... 2099 ...*.... 2100 ...*.... 2101 ...*.... 2102 ...*.... 2103 ...*.... 2104 ...*.... 2105 ....***. 2106 ........ 2107 ........ 2108 2109 char 0x75 2110 ........ 2111 ........ 2112 ........ 2113 ........ 2114 ........ 2115 **...**. 2116 .*....*. 2117 .*....*. 2118 .*....*. 2119 .*....*. 2120 .*....*. 2121 .*....*. 2122 .*...**. 2123 ..***.** 2124 ........ 2125 ........ 2126 2127 char 0x76 2128 ........ 2129 ........ 2130 ........ 2131 ........ 2132 ........ 2133 ***..*** 2134 .*....*. 2135 .*....*. 2136 .*....*. 2137 ..*..*.. 2138 ..*..*.. 2139 ..*..*.. 2140 ...**... 2141 ...**... 2142 ........ 2143 ........ 2144 2145 char 0x77 2146 ........ 2147 ........ 2148 ........ 2149 ........ 2150 ........ 2151 ***..*** 2152 .*....*. 2153 .*....*. 2154 .*.**.*. 2155 .*.**.*. 2156 .*.**.*. 2157 ..*..*.. 2158 ..*..*.. 2159 ..*..*.. 2160 ........ 2161 ........ 2162 2163 char 0x78 2164 ........ 2165 ........ 2166 ........ 2167 ........ 2168 ........ 2169 **...**. 2170 .*...*.. 2171 ..*.*... 2172 ..*.*... 2173 ...*.... 2174 ..*.*... 2175 ..*.*... 2176 .*...*.. 2177 **...**. 2178 ........ 2179 ........ 2180 2181 char 0x79 2182 ........ 2183 ........ 2184 ........ 2185 ........ 2186 ........ 2187 ***..*** 2188 .*....*. 2189 .*....*. 2190 ..*..*.. 2191 ..*..*.. 2192 ..*..*.. 2193 ...**... 2194 ...**... 2195 ...*.... 2196 ...*.... 2197 .**..... 2198 2199 char 0x7a 2200 ........ 2201 ........ 2202 ........ 2203 ........ 2204 ........ 2205 *******. 2206 *.....*. 2207 *....*.. 2208 ....*... 2209 ...*.... 2210 ..*..... 2211 .*....*. 2212 *.....*. 2213 *******. 2214 ........ 2215 ........ 2216 2217 char 0x7b 2218 ........ 2219 .....**. 2220 ....*... 2221 ...*.... 2222 ...*.... 2223 ...*.... 2224 ...*.... 2225 .**..... 2226 ...*.... 2227 ...*.... 2228 ...*.... 2229 ...*.... 2230 ....*... 2231 .....**. 2232 ........ 2233 ........ 2234 2235 char 0x7c 2236 ...*.... 2237 ...*.... 2238 ...*.... 2239 ...*.... 2240 ...*.... 2241 ...*.... 2242 ...*.... 2243 ...*.... 2244 ...*.... 2245 ...*.... 2246 ...*.... 2247 ...*.... 2248 ...*.... 2249 ...*.... 2250 ...*.... 2251 ...*.... 2252 2253 char 0x7d 2254 ........ 2255 .**..... 2256 ...*.... 2257 ....*... 2258 ....*... 2259 ....*... 2260 ....*... 2261 .....**. 2262 ....*... 2263 ....*... 2264 ....*... 2265 ....*... 2266 ...*.... 2267 .**..... 2268 ........ 2269 ........ 2270 2271 char 0x7e 2272 ........ 2273 .***..*. 2274 *...**.. 2275 ........ 2276 ........ 2277 ........ 2278 ........ 2279 ........ 2280 ........ 2281 ........ 2282 ........ 2283 ........ 2284 ........ 2285 ........ 2286 ........ 2287 ........ 2288 2289 char 0x7f 2290 ........ 2291 ........ 2292 ........ 2293 ........ 2294 ...*.... 2295 ..*.*... 2296 .*...*.. 2297 *.....*. 2298 *******. 2299 *.....*. 2300 *******. 2301 ........ 2302 ........ 2303 ........ 2304 ........ 2305 ........ 2306 2307 char 0x80 2308 ........ 2309 ..***... 2310 .*...*.. 2311 *.....*. 2312 *....... 2313 *....... 2314 *....... 2315 *....... 2316 *....... 2317 *....... 2318 *....... 2319 *.....*. 2320 .*...*.. 2321 ..***... 2322 ...*.... 2323 ..*..... 2324 2325 char 0x81 2326 ........ 2327 ........ 2328 ..*..*.. 2329 ..*..*.. 2330 ........ 2331 *.....*. 2332 *.....*. 2333 *.....*. 2334 *.....*. 2335 *.....*. 2336 *.....*. 2337 *.....*. 2338 .*....*. 2339 ..*****. 2340 ........ 2341 ........ 2342 2343 char 0x82 2344 ....**.. 2345 ....*... 2346 ...*.... 2347 ........ 2348 ........ 2349 ..***... 2350 .*...*.. 2351 *.....*. 2352 *.....*. 2353 *******. 2354 *....... 2355 *.....*. 2356 .*...*.. 2357 ..***... 2358 ........ 2359 ........ 2360 2361 char 0x83 2362 ........ 2363 ...*.... 2364 ..*.*... 2365 .*...*.. 2366 ........ 2367 .****... 2368 .....*.. 2369 .....*.. 2370 ..****.. 2371 .*...*.. 2372 *....*.. 2373 *....*.. 2374 .*...*.. 2375 ..*****. 2376 ........ 2377 ........ 2378 2379 char 0x84 2380 ........ 2381 ........ 2382 ..*..*.. 2383 ..*..*.. 2384 ........ 2385 .****... 2386 .....*.. 2387 .....*.. 2388 ..****.. 2389 .*...*.. 2390 *....*.. 2391 *....*.. 2392 .*...*.. 2393 ..*****. 2394 ........ 2395 ........ 2396 2397 char 0x85 2398 ...*.... 2399 ....*... 2400 .....*.. 2401 ........ 2402 ........ 2403 .****... 2404 .....*.. 2405 .....*.. 2406 ..****.. 2407 .*...*.. 2408 *....*.. 2409 *....*.. 2410 .*...*.. 2411 ..*****. 2412 ........ 2413 ........ 2414 2415 char 0x86 2416 ........ 2417 ...**... 2418 ..*..*.. 2419 ...**... 2420 ........ 2421 .****... 2422 .....*.. 2423 .....*.. 2424 ..****.. 2425 .*...*.. 2426 *....*.. 2427 *....*.. 2428 .*...*.. 2429 ..*****. 2430 ........ 2431 ........ 2432 2433 char 0x87 2434 ........ 2435 ........ 2436 ........ 2437 ........ 2438 ........ 2439 ..****.. 2440 .*....*. 2441 *....... 2442 *....... 2443 *....... 2444 *....... 2445 *....... 2446 .*....*. 2447 ..****.. 2448 ....*... 2449 ...*.... 2450 2451 char 0x88 2452 ........ 2453 ...*.... 2454 ..*.*... 2455 .*...*.. 2456 ........ 2457 ..***... 2458 .*...*.. 2459 *.....*. 2460 *.....*. 2461 *******. 2462 *....... 2463 *.....*. 2464 .*...*.. 2465 ..***... 2466 ........ 2467 ........ 2468 2469 char 0x89 2470 ........ 2471 ........ 2472 ..*..*.. 2473 ..*..*.. 2474 ........ 2475 ..***... 2476 .*...*.. 2477 *.....*. 2478 *.....*. 2479 *******. 2480 *....... 2481 *.....*. 2482 .*...*.. 2483 ..***... 2484 ........ 2485 ........ 2486 2487 char 0x8a 2488 ...*.... 2489 ....*... 2490 .....*.. 2491 ........ 2492 ........ 2493 ..***... 2494 .*...*.. 2495 *.....*. 2496 *.....*. 2497 *******. 2498 *....... 2499 *.....*. 2500 .*...*.. 2501 ..***... 2502 ........ 2503 ........ 2504 2505 char 0x8b 2506 ........ 2507 ........ 2508 ..*..*.. 2509 ..*..*.. 2510 ........ 2511 ...*.... 2512 ...*.... 2513 ...*.... 2514 ...*.... 2515 ...*.... 2516 ...*.... 2517 ...*.... 2518 ...*.... 2519 ...*.... 2520 ........ 2521 ........ 2522 2523 char 0x8c 2524 ........ 2525 ...*.... 2526 ..*.*... 2527 .*...*.. 2528 ........ 2529 ...*.... 2530 ...*.... 2531 ...*.... 2532 ...*.... 2533 ...*.... 2534 ...*.... 2535 ...*.... 2536 ...*.... 2537 ...*.... 2538 ........ 2539 ........ 2540 2541 char 0x8d 2542 ...*.... 2543 ....*... 2544 .....*.. 2545 ........ 2546 ........ 2547 ...*.... 2548 ...*.... 2549 ...*.... 2550 ...*.... 2551 ...*.... 2552 ...*.... 2553 ...*.... 2554 ...*.... 2555 ...*.... 2556 ........ 2557 ........ 2558 2559 char 0x8e 2560 ..*..*.. 2561 ..*..*.. 2562 ........ 2563 ..***... 2564 .*...*.. 2565 *.....*. 2566 *.....*. 2567 *.....*. 2568 *.....*. 2569 *******. 2570 *.....*. 2571 *.....*. 2572 *.....*. 2573 *.....*. 2574 ........ 2575 ........ 2576 2577 char 0x8f 2578 ........ 2579 ..***... 2580 .*...*.. 2581 ..***... 2582 .*...*.. 2583 *.....*. 2584 *.....*. 2585 *.....*. 2586 *.....*. 2587 *******. 2588 *.....*. 2589 *.....*. 2590 *.....*. 2591 *.....*. 2592 ........ 2593 ........ 2594 2595 char 0x90 2596 ....**.. 2597 ....*... 2598 ...*.... 2599 *******. 2600 *....... 2601 *....... 2602 *....... 2603 *....... 2604 *****... 2605 *....... 2606 *....... 2607 *....... 2608 *....... 2609 *******. 2610 ........ 2611 ........ 2612 2613 char 0x91 2614 ........ 2615 ........ 2616 ........ 2617 ........ 2618 ........ 2619 .**..... 2620 ...***.. 2621 ...*..*. 2622 .***..*. 2623 *..****. 2624 *..*.... 2625 *..*.... 2626 *..*..*. 2627 .**.**.. 2628 ........ 2629 ........ 2630 2631 char 0x92 2632 ....**.. 2633 ...*.... 2634 ..*..... 2635 ..*.*... 2636 ..*.*... 2637 ..*.*... 2638 *******. 2639 ..*.*... 2640 ..*.*... 2641 ..*.*... 2642 ..*.*... 2643 ..*.*... 2644 ..*.*... 2645 ..*.*... 2646 ........ 2647 ........ 2648 2649 char 0x93 2650 ........ 2651 ...*.... 2652 ..*.*... 2653 .*...*.. 2654 ........ 2655 ..***... 2656 .*...*.. 2657 *.....*. 2658 *.....*. 2659 *.....*. 2660 *.....*. 2661 *.....*. 2662 .*...*.. 2663 ..***... 2664 ........ 2665 ........ 2666 2667 char 0x94 2668 ........ 2669 ........ 2670 ..*..*.. 2671 ..*..*.. 2672 ........ 2673 ..***... 2674 .*...*.. 2675 *.....*. 2676 *.....*. 2677 *.....*. 2678 *.....*. 2679 *.....*. 2680 .*...*.. 2681 ..***... 2682 ........ 2683 ........ 2684 2685 char 0x95 2686 ...*.... 2687 ....*... 2688 .....*.. 2689 ........ 2690 ........ 2691 ..***... 2692 .*...*.. 2693 *.....*. 2694 *.....*. 2695 *.....*. 2696 *.....*. 2697 *.....*. 2698 .*...*.. 2699 ..***... 2700 ........ 2701 ........ 2702 2703 char 0x96 2704 ........ 2705 ...*.... 2706 ..*.*... 2707 .*...*.. 2708 ........ 2709 *.....*. 2710 *.....*. 2711 *.....*. 2712 *.....*. 2713 *.....*. 2714 *.....*. 2715 *.....*. 2716 .*....*. 2717 ..*****. 2718 ........ 2719 ........ 2720 2721 char 0x97 2722 ...*.... 2723 ....*... 2724 .....*.. 2725 ........ 2726 ........ 2727 *.....*. 2728 *.....*. 2729 *.....*. 2730 *.....*. 2731 *.....*. 2732 *.....*. 2733 *.....*. 2734 .*....*. 2735 ..*****. 2736 ........ 2737 ........ 2738 2739 char 0x98 2740 ........ 2741 ........ 2742 ..*..*.. 2743 ..*..*.. 2744 ........ 2745 *.....*. 2746 *.....*. 2747 .*...*.. 2748 .*...*.. 2749 ..*.*... 2750 ..*.*... 2751 ...*.... 2752 ...*.... 2753 ..*..... 2754 ..*..... 2755 .*...... 2756 2757 char 0x99 2758 ..*..*.. 2759 ..*..*.. 2760 ........ 2761 ..***... 2762 .*...*.. 2763 *.....*. 2764 *.....*. 2765 *.....*. 2766 *.....*. 2767 *.....*. 2768 *.....*. 2769 *.....*. 2770 .*...*.. 2771 ..***... 2772 ........ 2773 ........ 2774 2775 char 0x9a 2776 ..*..*.. 2777 ..*..*.. 2778 ........ 2779 *.....*. 2780 *.....*. 2781 *.....*. 2782 *.....*. 2783 *.....*. 2784 *.....*. 2785 *.....*. 2786 *.....*. 2787 *.....*. 2788 .*...*.. 2789 ..***... 2790 ........ 2791 ........ 2792 2793 char 0x9b 2794 ........ 2795 ..*.*... 2796 ..*.*... 2797 ..*.*... 2798 ..****.. 2799 .**.*.*. 2800 *.*.*... 2801 *.*.*... 2802 *.*.*... 2803 *.*.*... 2804 *.*.*... 2805 .**.*.*. 2806 ..****.. 2807 ..*.*... 2808 ..*.*... 2809 ..*.*... 2810 2811 char 0x9c 2812 ........ 2813 ....**.. 2814 ...*..*. 2815 ..*..... 2816 ..*..... 2817 ..*..... 2818 ******.. 2819 ..*..... 2820 ..*..... 2821 ..*..... 2822 .**..... 2823 *.*..... 2824 *.**..*. 2825 .*..**.. 2826 ........ 2827 ........ 2828 2829 char 0x9d 2830 ........ 2831 *.....*. 2832 *.....*. 2833 .*...*.. 2834 ..*.*... 2835 ...*.... 2836 *******. 2837 ...*.... 2838 ...*.... 2839 *******. 2840 ...*.... 2841 ...*.... 2842 ...*.... 2843 ...*.... 2844 ........ 2845 ........ 2846 2847 char 0x9e 2848 ........ 2849 ***..... 2850 *..*.... 2851 *...*... 2852 *...*... 2853 *...*... 2854 *..*.*.. 2855 ***..*.. 2856 *..***** 2857 *....*.. 2858 *....*.. 2859 *....*.. 2860 *....*.. 2861 *....*.. 2862 ........ 2863 ........ 2864 2865 char 0x9f 2866 ........ 2867 ....**.. 2868 ...*..*. 2869 ...*.... 2870 ...*.... 2871 ...*.... 2872 *******. 2873 ...*.... 2874 ...*.... 2875 ...*.... 2876 ...*.... 2877 ...*.... 2878 *..*.... 2879 .**..... 2880 ........ 2881 ........ 2882 2883 char 0xa0 2884 ....**.. 2885 ....*... 2886 ...*.... 2887 ........ 2888 ........ 2889 .****... 2890 .....*.. 2891 .....*.. 2892 ..****.. 2893 .*...*.. 2894 *....*.. 2895 *....*.. 2896 .*...*.. 2897 ..*****. 2898 ........ 2899 ........ 2900 2901 char 0xa1 2902 ....**.. 2903 ....*... 2904 ...*.... 2905 ........ 2906 ........ 2907 ...*.... 2908 ...*.... 2909 ...*.... 2910 ...*.... 2911 ...*.... 2912 ...*.... 2913 ...*.... 2914 ...*.... 2915 ...*.... 2916 ........ 2917 ........ 2918 2919 char 0xa2 2920 ....**.. 2921 ....*... 2922 ...*.... 2923 ........ 2924 ........ 2925 ..***... 2926 .*...*.. 2927 *.....*. 2928 *.....*. 2929 *.....*. 2930 *.....*. 2931 *.....*. 2932 .*...*.. 2933 ..***... 2934 ........ 2935 ........ 2936 2937 char 0xa3 2938 ....**.. 2939 ....*... 2940 ...*.... 2941 ........ 2942 ........ 2943 *.....*. 2944 *.....*. 2945 *.....*. 2946 *.....*. 2947 *.....*. 2948 *.....*. 2949 *.....*. 2950 .*....*. 2951 ..*****. 2952 ........ 2953 ........ 2954 2955 char 0xa4 2956 ........ 2957 ...*..*. 2958 ..*.*.*. 2959 ..*..*.. 2960 ........ 2961 *****... 2962 *....*.. 2963 *.....*. 2964 *.....*. 2965 *.....*. 2966 *.....*. 2967 *.....*. 2968 *.....*. 2969 *.....*. 2970 ........ 2971 ........ 2972 2973 char 0xa5 2974 ...*..*. 2975 ..*.*.*. 2976 ..*..*.. 2977 ........ 2978 *.....*. 2979 **....*. 2980 **....*. 2981 *.*...*. 2982 *..*..*. 2983 *..*..*. 2984 *...*.*. 2985 *....**. 2986 *....**. 2987 *.....*. 2988 ........ 2989 ........ 2990 2991 char 0xa6 2992 ........ 2993 ........ 2994 ........ 2995 .****... 2996 .....*.. 2997 .....*.. 2998 ..****.. 2999 .*...*.. 3000 *....*.. 3001 *....*.. 3002 .*...*.. 3003 ..*****. 3004 ........ 3005 *******. 3006 ........ 3007 ........ 3008 3009 char 0xa7 3010 ........ 3011 ........ 3012 ........ 3013 ..***... 3014 .*...*.. 3015 *.....*. 3016 *.....*. 3017 *.....*. 3018 *.....*. 3019 *.....*. 3020 .*...*.. 3021 ..***... 3022 ........ 3023 *******. 3024 ........ 3025 ........ 3026 3027 char 0xa8 3028 ........ 3029 ...*.... 3030 ...*.... 3031 ........ 3032 ........ 3033 ...*.... 3034 ...*.... 3035 ..*..... 3036 .*...*.. 3037 *.....*. 3038 *.....*. 3039 *.....*. 3040 .*...*.. 3041 ..***... 3042 ........ 3043 ........ 3044 3045 char 0xa9 3046 ........ 3047 ........ 3048 ........ 3049 ........ 3050 ........ 3051 ........ 3052 ........ 3053 ........ 3054 ........ 3055 ........ 3056 *******. 3057 *....... 3058 *....... 3059 *....... 3060 ........ 3061 ........ 3062 3063 char 0xaa 3064 ........ 3065 ........ 3066 ........ 3067 ........ 3068 ........ 3069 ........ 3070 ........ 3071 ........ 3072 ........ 3073 ........ 3074 *******. 3075 ......*. 3076 ......*. 3077 ......*. 3078 ........ 3079 ........ 3080 3081 char 0xab 3082 ........ 3083 ...*.... 3084 ..**.... 3085 ...*.... 3086 ...*.... 3087 ...*.... 3088 ........ 3089 *******. 3090 ........ 3091 .****... 3092 .....*.. 3093 ..***... 3094 .*...... 3095 .*****.. 3096 ........ 3097 ........ 3098 3099 char 0xac 3100 ........ 3101 ...*.... 3102 ..**.... 3103 ...*.... 3104 ...*.... 3105 ...*.... 3106 ........ 3107 *******. 3108 ........ 3109 ...**... 3110 ..*.*... 3111 .*..*... 3112 .*****.. 3113 ....*... 3114 ........ 3115 ........ 3116 3117 char 0xad 3118 ........ 3119 ...*.... 3120 ...*.... 3121 ........ 3122 ........ 3123 ...*.... 3124 ...*.... 3125 ...*.... 3126 ...*.... 3127 ...*.... 3128 ...*.... 3129 ...*.... 3130 ...*.... 3131 ...*.... 3132 ........ 3133 ........ 3134 3135 char 0xae 3136 ........ 3137 ........ 3138 ........ 3139 ........ 3140 ...*..*. 3141 ..*..*.. 3142 .*..*... 3143 *..*.... 3144 *..*.... 3145 .*..*... 3146 ..*..*.. 3147 ...*..*. 3148 ........ 3149 ........ 3150 ........ 3151 ........ 3152 3153 char 0xaf 3154 ........ 3155 ........ 3156 ........ 3157 ........ 3158 *..*.... 3159 .*..*... 3160 ..*..*.. 3161 ...*..*. 3162 ...*..*. 3163 ..*..*.. 3164 .*..*... 3165 *..*.... 3166 ........ 3167 ........ 3168 ........ 3169 ........ 3170 3171 char 0xb0 3172 ...*...* 3173 .*...*.. 3174 ...*...* 3175 .*...*.. 3176 ...*...* 3177 .*...*.. 3178 ...*...* 3179 .*...*.. 3180 ...*...* 3181 .*...*.. 3182 ...*...* 3183 .*...*.. 3184 ...*...* 3185 .*...*.. 3186 ...*...* 3187 .*...*.. 3188 3189 char 0xb1 3190 .*.*.*.* 3191 *.*.*.*. 3192 .*.*.*.* 3193 *.*.*.*. 3194 .*.*.*.* 3195 *.*.*.*. 3196 .*.*.*.* 3197 *.*.*.*. 3198 .*.*.*.* 3199 *.*.*.*. 3200 .*.*.*.* 3201 *.*.*.*. 3202 .*.*.*.* 3203 *.*.*.*. 3204 .*.*.*.* 3205 *.*.*.*. 3206 3207 char 0xb2 3208 .***.*** 3209 **.***.* 3210 .***.*** 3211 **.***.* 3212 .***.*** 3213 **.***.* 3214 .***.*** 3215 **.***.* 3216 .***.*** 3217 **.***.* 3218 .***.*** 3219 **.***.* 3220 .***.*** 3221 **.***.* 3222 .***.*** 3223 **.***.* 3224 3225 char 0xb3 3226 ...*.... 3227 ...*.... 3228 ...*.... 3229 ...*.... 3230 ...*.... 3231 ...*.... 3232 ...*.... 3233 ...*.... 3234 ...*.... 3235 ...*.... 3236 ...*.... 3237 ...*.... 3238 ...*.... 3239 ...*.... 3240 ...*.... 3241 ...*.... 3242 3243 char 0xb4 3244 ...*.... 3245 ...*.... 3246 ...*.... 3247 ...*.... 3248 ...*.... 3249 ...*.... 3250 ...*.... 3251 ****.... 3252 ...*.... 3253 ...*.... 3254 ...*.... 3255 ...*.... 3256 ...*.... 3257 ...*.... 3258 ...*.... 3259 ...*.... 3260 3261 char 0xb5 3262 ...*.... 3263 ...*.... 3264 ...*.... 3265 ...*.... 3266 ...*.... 3267 ...*.... 3268 ...*.... 3269 ****.... 3270 ...*.... 3271 ****.... 3272 ...*.... 3273 ...*.... 3274 ...*.... 3275 ...*.... 3276 ...*.... 3277 ...*.... 3278 3279 char 0xb6 3280 ...*.*.. 3281 ...*.*.. 3282 ...*.*.. 3283 ...*.*.. 3284 ...*.*.. 3285 ...*.*.. 3286 ...*.*.. 3287 ****.*.. 3288 ...*.*.. 3289 ...*.*.. 3290 ...*.*.. 3291 ...*.*.. 3292 ...*.*.. 3293 ...*.*.. 3294 ...*.*.. 3295 ...*.*.. 3296 3297 char 0xb7 3298 ........ 3299 ........ 3300 ........ 3301 ........ 3302 ........ 3303 ........ 3304 ........ 3305 ******.. 3306 ...*.*.. 3307 ...*.*.. 3308 ...*.*.. 3309 ...*.*.. 3310 ...*.*.. 3311 ...*.*.. 3312 ...*.*.. 3313 ...*.*.. 3314 3315 char 0xb8 3316 ........ 3317 ........ 3318 ........ 3319 ........ 3320 ........ 3321 ........ 3322 ........ 3323 ****.... 3324 ...*.... 3325 ****.... 3326 ...*.... 3327 ...*.... 3328 ...*.... 3329 ...*.... 3330 ...*.... 3331 ...*.... 3332 3333 char 0xb9 3334 ...*.*.. 3335 ...*.*.. 3336 ...*.*.. 3337 ...*.*.. 3338 ...*.*.. 3339 ...*.*.. 3340 ...*.*.. 3341 ****.*.. 3342 .....*.. 3343 ****.*.. 3344 ...*.*.. 3345 ...*.*.. 3346 ...*.*.. 3347 ...*.*.. 3348 ...*.*.. 3349 ...*.*.. 3350 3351 char 0xba 3352 ...*.*.. 3353 ...*.*.. 3354 ...*.*.. 3355 ...*.*.. 3356 ...*.*.. 3357 ...*.*.. 3358 ...*.*.. 3359 ...*.*.. 3360 ...*.*.. 3361 ...*.*.. 3362 ...*.*.. 3363 ...*.*.. 3364 ...*.*.. 3365 ...*.*.. 3366 ...*.*.. 3367 ...*.*.. 3368 3369 char 0xbb 3370 ........ 3371 ........ 3372 ........ 3373 ........ 3374 ........ 3375 ........ 3376 ........ 3377 ******.. 3378 .....*.. 3379 ****.*.. 3380 ...*.*.. 3381 ...*.*.. 3382 ...*.*.. 3383 ...*.*.. 3384 ...*.*.. 3385 ...*.*.. 3386 3387 char 0xbc 3388 ...*.*.. 3389 ...*.*.. 3390 ...*.*.. 3391 ...*.*.. 3392 ...*.*.. 3393 ...*.*.. 3394 ...*.*.. 3395 ****.*.. 3396 .....*.. 3397 ******.. 3398 ........ 3399 ........ 3400 ........ 3401 ........ 3402 ........ 3403 ........ 3404 3405 char 0xbd 3406 ...*.*.. 3407 ...*.*.. 3408 ...*.*.. 3409 ...*.*.. 3410 ...*.*.. 3411 ...*.*.. 3412 ...*.*.. 3413 ******.. 3414 ........ 3415 ........ 3416 ........ 3417 ........ 3418 ........ 3419 ........ 3420 ........ 3421 ........ 3422 3423 char 0xbe 3424 ...*.... 3425 ...*.... 3426 ...*.... 3427 ...*.... 3428 ...*.... 3429 ...*.... 3430 ...*.... 3431 ****.... 3432 ...*.... 3433 ****.... 3434 ........ 3435 ........ 3436 ........ 3437 ........ 3438 ........ 3439 ........ 3440 3441 char 0xbf 3442 ........ 3443 ........ 3444 ........ 3445 ........ 3446 ........ 3447 ........ 3448 ........ 3449 ****.... 3450 ...*.... 3451 ...*.... 3452 ...*.... 3453 ...*.... 3454 ...*.... 3455 ...*.... 3456 ...*.... 3457 ...*.... 3458 3459 char 0xc0 3460 ...*.... 3461 ...*.... 3462 ...*.... 3463 ...*.... 3464 ...*.... 3465 ...*.... 3466 ...*.... 3467 ...***** 3468 ........ 3469 ........ 3470 ........ 3471 ........ 3472 ........ 3473 ........ 3474 ........ 3475 ........ 3476 3477 char 0xc1 3478 ...*.... 3479 ...*.... 3480 ...*.... 3481 ...*.... 3482 ...*.... 3483 ...*.... 3484 ...*.... 3485 ******** 3486 ........ 3487 ........ 3488 ........ 3489 ........ 3490 ........ 3491 ........ 3492 ........ 3493 ........ 3494 3495 char 0xc2 3496 ........ 3497 ........ 3498 ........ 3499 ........ 3500 ........ 3501 ........ 3502 ........ 3503 ******** 3504 ...*.... 3505 ...*.... 3506 ...*.... 3507 ...*.... 3508 ...*.... 3509 ...*.... 3510 ...*.... 3511 ...*.... 3512 3513 char 0xc3 3514 ...*.... 3515 ...*.... 3516 ...*.... 3517 ...*.... 3518 ...*.... 3519 ...*.... 3520 ...*.... 3521 ...***** 3522 ...*.... 3523 ...*.... 3524 ...*.... 3525 ...*.... 3526 ...*.... 3527 ...*.... 3528 ...*.... 3529 ...*.... 3530 3531 char 0xc4 3532 ........ 3533 ........ 3534 ........ 3535 ........ 3536 ........ 3537 ........ 3538 ........ 3539 ******** 3540 ........ 3541 ........ 3542 ........ 3543 ........ 3544 ........ 3545 ........ 3546 ........ 3547 ........ 3548 3549 char 0xc5 3550 ...*.... 3551 ...*.... 3552 ...*.... 3553 ...*.... 3554 ...*.... 3555 ...*.... 3556 ...*.... 3557 ******** 3558 ...*.... 3559 ...*.... 3560 ...*.... 3561 ...*.... 3562 ...*.... 3563 ...*.... 3564 ...*.... 3565 ...*.... 3566 3567 char 0xc6 3568 ...*.... 3569 ...*.... 3570 ...*.... 3571 ...*.... 3572 ...*.... 3573 ...*.... 3574 ...*.... 3575 ...***** 3576 ...*.... 3577 ...***** 3578 ...*.... 3579 ...*.... 3580 ...*.... 3581 ...*.... 3582 ...*.... 3583 ...*.... 3584 3585 char 0xc7 3586 ...*.*.. 3587 ...*.*.. 3588 ...*.*.. 3589 ...*.*.. 3590 ...*.*.. 3591 ...*.*.. 3592 ...*.*.. 3593 ...*.*** 3594 ...*.*.. 3595 ...*.*.. 3596 ...*.*.. 3597 ...*.*.. 3598 ...*.*.. 3599 ...*.*.. 3600 ...*.*.. 3601 ...*.*.. 3602 3603 char 0xc8 3604 ...*.*.. 3605 ...*.*.. 3606 ...*.*.. 3607 ...*.*.. 3608 ...*.*.. 3609 ...*.*.. 3610 ...*.*.. 3611 ...*.*** 3612 ...*.... 3613 ...***** 3614 ........ 3615 ........ 3616 ........ 3617 ........ 3618 ........ 3619 ........ 3620 3621 char 0xc9 3622 ........ 3623 ........ 3624 ........ 3625 ........ 3626 ........ 3627 ........ 3628 ........ 3629 ...***** 3630 ...*.... 3631 ...*.*** 3632 ...*.*.. 3633 ...*.*.. 3634 ...*.*.. 3635 ...*.*.. 3636 ...*.*.. 3637 ...*.*.. 3638 3639 char 0xca 3640 ...*.*.. 3641 ...*.*.. 3642 ...*.*.. 3643 ...*.*.. 3644 ...*.*.. 3645 ...*.*.. 3646 ...*.*.. 3647 ****.*** 3648 ........ 3649 ******** 3650 ........ 3651 ........ 3652 ........ 3653 ........ 3654 ........ 3655 ........ 3656 3657 char 0xcb 3658 ........ 3659 ........ 3660 ........ 3661 ........ 3662 ........ 3663 ........ 3664 ........ 3665 ******** 3666 ........ 3667 ****.*** 3668 ...*.*.. 3669 ...*.*.. 3670 ...*.*.. 3671 ...*.*.. 3672 ...*.*.. 3673 ...*.*.. 3674 3675 char 0xcc 3676 ...*.*.. 3677 ...*.*.. 3678 ...*.*.. 3679 ...*.*.. 3680 ...*.*.. 3681 ...*.*.. 3682 ...*.*.. 3683 ...*.*** 3684 ...*.... 3685 ...*.*** 3686 ...*.*.. 3687 ...*.*.. 3688 ...*.*.. 3689 ...*.*.. 3690 ...*.*.. 3691 ...*.*.. 3692 3693 char 0xcd 3694 ........ 3695 ........ 3696 ........ 3697 ........ 3698 ........ 3699 ........ 3700 ........ 3701 ******** 3702 ........ 3703 ******** 3704 ........ 3705 ........ 3706 ........ 3707 ........ 3708 ........ 3709 ........ 3710 3711 char 0xce 3712 ...*.*.. 3713 ...*.*.. 3714 ...*.*.. 3715 ...*.*.. 3716 ...*.*.. 3717 ...*.*.. 3718 ...*.*.. 3719 ****.*** 3720 ........ 3721 ****.*** 3722 ...*.*.. 3723 ...*.*.. 3724 ...*.*.. 3725 ...*.*.. 3726 ...*.*.. 3727 ...*.*.. 3728 3729 char 0xcf 3730 ...*.... 3731 ...*.... 3732 ...*.... 3733 ...*.... 3734 ...*.... 3735 ...*.... 3736 ...*.... 3737 ******** 3738 ........ 3739 ******** 3740 ........ 3741 ........ 3742 ........ 3743 ........ 3744 ........ 3745 ........ 3746 3747 char 0xd0 3748 ...*.*.. 3749 ...*.*.. 3750 ...*.*.. 3751 ...*.*.. 3752 ...*.*.. 3753 ...*.*.. 3754 ...*.*.. 3755 ******** 3756 ........ 3757 ........ 3758 ........ 3759 ........ 3760 ........ 3761 ........ 3762 ........ 3763 ........ 3764 3765 char 0xd1 3766 ........ 3767 ........ 3768 ........ 3769 ........ 3770 ........ 3771 ........ 3772 ........ 3773 ******** 3774 ........ 3775 ******** 3776 ...*.... 3777 ...*.... 3778 ...*.... 3779 ...*.... 3780 ...*.... 3781 ...*.... 3782 3783 char 0xd2 3784 ........ 3785 ........ 3786 ........ 3787 ........ 3788 ........ 3789 ........ 3790 ........ 3791 ******** 3792 ...*.*.. 3793 ...*.*.. 3794 ...*.*.. 3795 ...*.*.. 3796 ...*.*.. 3797 ...*.*.. 3798 ...*.*.. 3799 ...*.*.. 3800 3801 char 0xd3 3802 ...*.*.. 3803 ...*.*.. 3804 ...*.*.. 3805 ...*.*.. 3806 ...*.*.. 3807 ...*.*.. 3808 ...*.*.. 3809 ...***** 3810 ........ 3811 ........ 3812 ........ 3813 ........ 3814 ........ 3815 ........ 3816 ........ 3817 ........ 3818 3819 char 0xd4 3820 ...*.... 3821 ...*.... 3822 ...*.... 3823 ...*.... 3824 ...*.... 3825 ...*.... 3826 ...*.... 3827 ...***** 3828 ...*.... 3829 ...***** 3830 ........ 3831 ........ 3832 ........ 3833 ........ 3834 ........ 3835 ........ 3836 3837 char 0xd5 3838 ........ 3839 ........ 3840 ........ 3841 ........ 3842 ........ 3843 ........ 3844 ........ 3845 ...***** 3846 ...*.... 3847 ...***** 3848 ...*.... 3849 ...*.... 3850 ...*.... 3851 ...*.... 3852 ...*.... 3853 ...*.... 3854 3855 char 0xd6 3856 ........ 3857 ........ 3858 ........ 3859 ........ 3860 ........ 3861 ........ 3862 ........ 3863 ...***** 3864 ...*.*.. 3865 ...*.*.. 3866 ...*.*.. 3867 ...*.*.. 3868 ...*.*.. 3869 ...*.*.. 3870 ...*.*.. 3871 ...*.*.. 3872 3873 char 0xd7 3874 ...*.*.. 3875 ...*.*.. 3876 ...*.*.. 3877 ...*.*.. 3878 ...*.*.. 3879 ...*.*.. 3880 ...*.*.. 3881 ****.*** 3882 ...*.*.. 3883 ...*.*.. 3884 ...*.*.. 3885 ...*.*.. 3886 ...*.*.. 3887 ...*.*.. 3888 ...*.*.. 3889 ...*.*.. 3890 3891 char 0xd8 3892 ...*.... 3893 ...*.... 3894 ...*.... 3895 ...*.... 3896 ...*.... 3897 ...*.... 3898 ...*.... 3899 ******** 3900 ...*.... 3901 ******** 3902 ...*.... 3903 ...*.... 3904 ...*.... 3905 ...*.... 3906 ...*.... 3907 ...*.... 3908 3909 char 0xd9 3910 ...*.... 3911 ...*.... 3912 ...*.... 3913 ...*.... 3914 ...*.... 3915 ...*.... 3916 ...*.... 3917 ****.... 3918 ........ 3919 ........ 3920 ........ 3921 ........ 3922 ........ 3923 ........ 3924 ........ 3925 ........ 3926 3927 char 0xda 3928 ........ 3929 ........ 3930 ........ 3931 ........ 3932 ........ 3933 ........ 3934 ........ 3935 ...***** 3936 ...*.... 3937 ...*.... 3938 ...*.... 3939 ...*.... 3940 ...*.... 3941 ...*.... 3942 ...*.... 3943 ...*.... 3944 3945 char 0xdb 3946 ******** 3947 ******** 3948 ******** 3949 ******** 3950 ******** 3951 ******** 3952 ******** 3953 ******** 3954 ******** 3955 ******** 3956 ******** 3957 ******** 3958 ******** 3959 ******** 3960 ******** 3961 ******** 3962 3963 char 0xdc 3964 ........ 3965 ........ 3966 ........ 3967 ........ 3968 ........ 3969 ........ 3970 ........ 3971 ........ 3972 ******** 3973 ******** 3974 ******** 3975 ******** 3976 ******** 3977 ******** 3978 ******** 3979 ******** 3980 3981 char 0xdd 3982 ****.... 3983 ****.... 3984 ****.... 3985 ****.... 3986 ****.... 3987 ****.... 3988 ****.... 3989 ****.... 3990 ****.... 3991 ****.... 3992 ****.... 3993 ****.... 3994 ****.... 3995 ****.... 3996 ****.... 3997 ****.... 3998 3999 char 0xde 4000 ....**** 4001 ....**** 4002 ....**** 4003 ....**** 4004 ....**** 4005 ....**** 4006 ....**** 4007 ....**** 4008 ....**** 4009 ....**** 4010 ....**** 4011 ....**** 4012 ....**** 4013 ....**** 4014 ....**** 4015 ....**** 4016 4017 char 0xdf 4018 ******** 4019 ******** 4020 ******** 4021 ******** 4022 ******** 4023 ******** 4024 ******** 4025 ******** 4026 ........ 4027 ........ 4028 ........ 4029 ........ 4030 ........ 4031 ........ 4032 ........ 4033 ........ 4034 4035 char 0xe0 4036 ........ 4037 ........ 4038 ........ 4039 ........ 4040 ........ 4041 ........ 4042 ........ 4043 ........ 4044 ........ 4045 ........ 4046 ........ 4047 ........ 4048 ........ 4049 ........ 4050 ........ 4051 ........ 4052 4053 char 0xe1 4054 ........ 4055 ........ 4056 ........ 4057 ........ 4058 ........ 4059 ........ 4060 ........ 4061 ........ 4062 ........ 4063 ........ 4064 ........ 4065 ........ 4066 ........ 4067 ........ 4068 ........ 4069 ........ 4070 4071 char 0xe2 4072 ........ 4073 ........ 4074 ........ 4075 ........ 4076 ........ 4077 ........ 4078 ........ 4079 ........ 4080 ........ 4081 ........ 4082 ........ 4083 ........ 4084 ........ 4085 ........ 4086 ........ 4087 ........ 4088 4089 char 0xe3 4090 ........ 4091 ........ 4092 ........ 4093 ........ 4094 ........ 4095 ........ 4096 ........ 4097 ........ 4098 ........ 4099 ........ 4100 ........ 4101 ........ 4102 ........ 4103 ........ 4104 ........ 4105 ........ 4106 4107 char 0xe4 4108 ........ 4109 ........ 4110 ........ 4111 ........ 4112 ........ 4113 ........ 4114 ........ 4115 ........ 4116 ........ 4117 ........ 4118 ........ 4119 ........ 4120 ........ 4121 ........ 4122 ........ 4123 ........ 4124 4125 char 0xe5 4126 ........ 4127 ........ 4128 ........ 4129 ........ 4130 ........ 4131 ........ 4132 ........ 4133 ........ 4134 ........ 4135 ........ 4136 ........ 4137 ........ 4138 ........ 4139 ........ 4140 ........ 4141 ........ 4142 4143 char 0xe6 4144 ........ 4145 ........ 4146 ........ 4147 ........ 4148 ........ 4149 ........ 4150 ........ 4151 ........ 4152 ........ 4153 ........ 4154 ........ 4155 ........ 4156 ........ 4157 ........ 4158 ........ 4159 ........ 4160 4161 char 0xe7 4162 ........ 4163 ........ 4164 ........ 4165 ........ 4166 ........ 4167 ........ 4168 ........ 4169 ........ 4170 ........ 4171 ........ 4172 ........ 4173 ........ 4174 ........ 4175 ........ 4176 ........ 4177 ........ 4178 4179 char 0xe8 4180 ........ 4181 ........ 4182 ........ 4183 ........ 4184 ........ 4185 ........ 4186 ........ 4187 ........ 4188 ........ 4189 ........ 4190 ........ 4191 ........ 4192 ........ 4193 ........ 4194 ........ 4195 ........ 4196 4197 char 0xe9 4198 ........ 4199 ........ 4200 ........ 4201 ........ 4202 ........ 4203 ........ 4204 ........ 4205 ........ 4206 ........ 4207 ........ 4208 ........ 4209 ........ 4210 ........ 4211 ........ 4212 ........ 4213 ........ 4214 4215 char 0xea 4216 ........ 4217 ........ 4218 ........ 4219 ........ 4220 ........ 4221 ........ 4222 ........ 4223 ........ 4224 ........ 4225 ........ 4226 ........ 4227 ........ 4228 ........ 4229 ........ 4230 ........ 4231 ........ 4232 4233 char 0xeb 4234 ........ 4235 ........ 4236 ........ 4237 ........ 4238 ........ 4239 ........ 4240 ........ 4241 ........ 4242 ........ 4243 ........ 4244 ........ 4245 ........ 4246 ........ 4247 ........ 4248 ........ 4249 ........ 4250 4251 char 0xec 4252 ........ 4253 ........ 4254 ........ 4255 ........ 4256 ........ 4257 ........ 4258 ........ 4259 ........ 4260 ........ 4261 ........ 4262 ........ 4263 ........ 4264 ........ 4265 ........ 4266 ........ 4267 ........ 4268 4269 char 0xed 4270 ........ 4271 ........ 4272 ........ 4273 ........ 4274 ........ 4275 ........ 4276 ........ 4277 ........ 4278 ........ 4279 ........ 4280 ........ 4281 ........ 4282 ........ 4283 ........ 4284 ........ 4285 ........ 4286 4287 char 0xee 4288 ........ 4289 ........ 4290 ........ 4291 ........ 4292 ........ 4293 ........ 4294 ........ 4295 ........ 4296 ........ 4297 ........ 4298 ........ 4299 ........ 4300 ........ 4301 ........ 4302 ........ 4303 ........ 4304 4305 char 0xef 4306 ........ 4307 ........ 4308 ........ 4309 ........ 4310 ........ 4311 ........ 4312 ........ 4313 ........ 4314 ........ 4315 ........ 4316 ........ 4317 ........ 4318 ........ 4319 ........ 4320 ........ 4321 ........ 4322 4323 char 0xf0 4324 ........ 4325 ........ 4326 ........ 4327 ........ 4328 ........ 4329 ........ 4330 ........ 4331 ........ 4332 ........ 4333 ........ 4334 ........ 4335 ........ 4336 ........ 4337 ........ 4338 ........ 4339 ........ 4340 4341 char 0xf1 4342 ........ 4343 ........ 4344 ........ 4345 ........ 4346 ........ 4347 ........ 4348 ........ 4349 ........ 4350 ........ 4351 ........ 4352 ........ 4353 ........ 4354 ........ 4355 ........ 4356 ........ 4357 ........ 4358 4359 char 0xf2 4360 ........ 4361 ........ 4362 ........ 4363 ........ 4364 ........ 4365 ........ 4366 ........ 4367 ........ 4368 ........ 4369 ........ 4370 ........ 4371 ........ 4372 ........ 4373 ........ 4374 ........ 4375 ........ 4376 4377 char 0xf3 4378 ........ 4379 ........ 4380 ........ 4381 ........ 4382 ........ 4383 ........ 4384 ........ 4385 ........ 4386 ........ 4387 ........ 4388 ........ 4389 ........ 4390 ........ 4391 ........ 4392 ........ 4393 ........ 4394 4395 char 0xf4 4396 ........ 4397 ........ 4398 ........ 4399 ........ 4400 ........ 4401 ........ 4402 ........ 4403 ........ 4404 ........ 4405 ........ 4406 ........ 4407 ........ 4408 ........ 4409 ........ 4410 ........ 4411 ........ 4412 4413 char 0xf5 4414 ........ 4415 ........ 4416 ........ 4417 ........ 4418 ........ 4419 ........ 4420 ........ 4421 ........ 4422 ........ 4423 ........ 4424 ........ 4425 ........ 4426 ........ 4427 ........ 4428 ........ 4429 ........ 4430 4431 char 0xf6 4432 ........ 4433 ........ 4434 ........ 4435 ........ 4436 ........ 4437 ........ 4438 ........ 4439 ........ 4440 ........ 4441 ........ 4442 ........ 4443 ........ 4444 ........ 4445 ........ 4446 ........ 4447 ........ 4448 4449 char 0xf7 4450 ........ 4451 ........ 4452 ........ 4453 ........ 4454 ........ 4455 ........ 4456 ........ 4457 ........ 4458 ........ 4459 ........ 4460 ........ 4461 ........ 4462 ........ 4463 ........ 4464 ........ 4465 ........ 4466 4467 char 0xf8 4468 ........ 4469 ........ 4470 ........ 4471 ........ 4472 ........ 4473 ........ 4474 ........ 4475 ........ 4476 ........ 4477 ........ 4478 ........ 4479 ........ 4480 ........ 4481 ........ 4482 ........ 4483 ........ 4484 4485 char 0xf9 4486 ........ 4487 ........ 4488 ........ 4489 ........ 4490 ........ 4491 ........ 4492 ........ 4493 ........ 4494 ........ 4495 ........ 4496 ........ 4497 ........ 4498 ........ 4499 ........ 4500 ........ 4501 ........ 4502 4503 char 0xfa 4504 ........ 4505 ........ 4506 ........ 4507 ........ 4508 ........ 4509 ........ 4510 ........ 4511 ........ 4512 ........ 4513 ........ 4514 ........ 4515 ........ 4516 ........ 4517 ........ 4518 ........ 4519 ........ 4520 4521 char 0xfb 4522 ........ 4523 ........ 4524 ........ 4525 ........ 4526 ........ 4527 ........ 4528 ........ 4529 ........ 4530 ........ 4531 ........ 4532 ........ 4533 ........ 4534 ........ 4535 ........ 4536 ........ 4537 ........ 4538 4539 char 0xfc 4540 ........ 4541 ........ 4542 ........ 4543 ........ 4544 ........ 4545 ........ 4546 ........ 4547 ........ 4548 ........ 4549 ........ 4550 ........ 4551 ........ 4552 ........ 4553 ........ 4554 ........ 4555 ........ 4556 4557 char 0xfd 4558 ........ 4559 ........ 4560 ........ 4561 ........ 4562 ........ 4563 ........ 4564 ........ 4565 ........ 4566 ........ 4567 ........ 4568 ........ 4569 ........ 4570 ........ 4571 ........ 4572 ........ 4573 ........ 4574 4575 char 0xfe 4576 ........ 4577 ........ 4578 ........ 4579 ........ 4580 ........ 4581 ........ 4582 ........ 4583 ........ 4584 ........ 4585 ........ 4586 ........ 4587 ........ 4588 ........ 4589 ........ 4590 ........ 4591 ........ 4592 4593 char 0xff 4594 ........ 4595 ........ 4596 ........ 4597 ........ 4598 ........ 4599 ........ 4600 ........ 4601 ........ 4602 ........ 4603 ........ 4604 ........ 4605 ........ 4606 ........ 4607 ........ 4608 ........ 4609 ........
1 OBJS_BOOTPACK = bootpack.obj naskfunc.obj hankaku.obj graphic.obj dsctbl.obj 2 int.obj fifo.obj keyboard.obj mouse.obj memory.obj sheet.obj 3 4 TOOLPATH = ../z_tools/ 5 INCPATH = ../z_tools/haribote/ 6 7 MAKE = $(TOOLPATH)make.exe -r 8 NASK = $(TOOLPATH)nask.exe 9 CC1 = $(TOOLPATH)cc1.exe -I$(INCPATH) -Os -Wall -quiet 10 GAS2NASK = $(TOOLPATH)gas2nask.exe -a 11 OBJ2BIM = $(TOOLPATH)obj2bim.exe 12 MAKEFONT = $(TOOLPATH)makefont.exe 13 BIN2OBJ = $(TOOLPATH)bin2obj.exe 14 BIM2HRB = $(TOOLPATH)bim2hrb.exe 15 RULEFILE = $(TOOLPATH)haribote/haribote.rul 16 EDIMG = $(TOOLPATH)edimg.exe 17 IMGTOL = $(TOOLPATH)imgtol.com 18 COPY = copy 19 DEL = del 20 21 # 设置默认命令为产生img 22 default : 23 $(MAKE) img 24 25 # 正常执行过程 26 # 将ipl10.nas编译为ipl10.bin文件 27 ipl10.bin : ipl10.nas Makefile 28 $(NASK) ipl10.nas ipl10.bin ipl10.lst 29 30 # 将asmhead.asm编译为asmhead.bin 31 asmhead.bin : asmhead.nas Makefile 32 $(NASK) asmhead.nas asmhead.bin asmhead.lst 33 34 # 将字库hankaku.txt编译为hankaku.bin 35 hankaku.bin : hankaku.txt Makefile 36 $(MAKEFONT) hankaku.txt hankaku.bin 37 38 # 将字库转换为.obj 39 hankaku.obj : hankaku.bin Makefile 40 $(BIN2OBJ) hankaku.bin hankaku.obj _hankaku 41 42 # 将OBJS_BOOTPACK的obj编译为.bim映像文件,这里的前提条件是有OBJS_BOOTPACK,所以会自动执行把naskfunc.nas和其它.c文件编译为obj文件 43 bootpack.bim : $(OBJS_BOOTPACK) Makefile 44 $(OBJ2BIM) @$(RULEFILE) out:bootpack.bim stack:3136k map:bootpack.map 45 $(OBJS_BOOTPACK) 46 # 3MB+64KB=3136KB 47 48 # 将bootpack.bim映像编译为.hrb文件 49 bootpack.hrb : bootpack.bim Makefile 50 $(BIM2HRB) bootpack.bim bootpack.hrb 0 51 52 # 将.hrb映像和asmhead.bin 合并做成haribote.sys系统文件 53 haribote.sys : asmhead.bin bootpack.hrb Makefile 54 copy /B asmhead.bin+bootpack.hrb haribote.sys 55 56 # 把ipl10.bin和haribote.sys结合做成操作系统文件haribote.img 57 haribote.img : ipl10.bin haribote.sys Makefile 58 $(EDIMG) imgin:../z_tools/fdimg0at.tek 59 wbinimg src:ipl10.bin len:512 from:0 to:0 60 copy from:haribote.sys to:@: 61 imgout:haribote.img 62 63 # 对c文件进行编译 64 # 把.c文件编译为.gas文件,需要.c bootpack.h 和 Makefile文件,然后调用cc1.exe进行处理 65 %.gas : %.c bootpack.h Makefile 66 $(CC1) -o $*.gas $*.c 67 68 # 把.gas文件转换为.nas文件,其他类似上面的说明 69 %.nas : %.gas Makefile 70 $(GAS2NASK) $*.gas $*.nas 71 72 # 把.nas转为.obj文件并输出.lst文件 73 %.obj : %.nas Makefile 74 $(NASK) $*.nas $*.obj $*.lst 75 76 # 根据不同的命令分别执行下面的情况,默认为img 77 img : 78 $(MAKE) haribote.img 79 80 run : 81 $(MAKE) img 82 $(COPY) haribote.img ..\z_tools\qemu\fdimage0.bin 83 $(MAKE) -C ../z_tools/qemu 84 85 install : 86 $(MAKE) img 87 $(IMGTOL) w a: haribote.img 88 89 clean : 90 $(DEL) *.bin 91 $(DEL) *.lst 92 $(DEL) *.obj 93 $(DEL) bootpack.map 94 $(DEL) bootpack.bim 95 $(DEL) bootpack.hrb 96 $(DEL) haribote.sys 97 98 src_only : 99 $(MAKE) clean 100 $(DEL) haribote.img
1 ..\z_tools\make.exe %1 %2 %3 %4 %5 %6 %7 %8 %9
5、效果及说明
>_<" 已经实现了窗口叠加和内存管理,这里有背景窗口,消息窗口和鼠标窗口~本次比上次多了内存管理和窗口管理,因为要加速中断,所以我们要想方设法地优化程序,内存管理中努力去除不必要的条件判断,窗口管理中用指针链表加快插入速度...同时这也为阅读这两部分的代码带来了很大的不便,建议结合以前学的数据结构的知识,可能就会有种他乡遇故知的感觉呢!哈哈~
原文:http://www.cnblogs.com/zjutlitao/p/3979306.html