标签:des cWeb style blog http color io os ar
前言:
>_<" 这几天正在研究一个好玩的,准备写《软硬结合第三篇——科班的还是可以修电脑的》,可是当前遇到个技术难点——WHDI,所以操作系统这里就慢了好大一节啦!但是以操作系统多任务的思路,感觉还是把这个优先级并不是太低的进程拿出来做一下吧!毕竟技术难点有时候需要灵感的哈~(不过有大神知道VGA接口的通信原理吗?求给个好一点的链接看看!)。回到正题上来,这次学的东西有点杂,主要就是高分辨率和键盘输入相关~对于前者和汇编及硬件联系较多(具体可以查VBE Video Electronics Standards Association BIOS extension),后者主要是映射关系,没多大难度~
效果展示:
>_<" 把分辨率调高了,可以看更宽的画面了。同时在WINDOW窗口中加入文字输入框,注意这里输入的英文字母必须是大写的,而且一些特殊的按键也会出现错误,今后还要优化~
部分程序说明:
>_<" 分辨率控制(asmhead.nas内部分)
1 ; haribote-os boot asm 2 ; TAB=4 3 4 [INSTRSET "i486p"] ;必须加!!! 5 6 VBEMODE EQU 0x101 ; 1024 x 768 x 8bit //显示模式 7 BOTPAK EQU 0x00280000 ; bootpack的内存首址 8 DSKCAC EQU 0x00100000 ; 9 DSKCAC0 EQU 0x00008000 ; 10 11 ; BOOT_INFO相关 12 CYLS EQU 0x0ff0 ; 设定启动区 13 LEDS EQU 0x0ff1 14 VMODE EQU 0x0ff2 ; 关于颜色的信息颜色的位数 15 SCRNX EQU 0x0ff4 ; 分辨率X 16 SCRNY EQU 0x0ff6 ; 分辨率Y 17 VRAM EQU 0x0ff8 ; 图像缓冲区的开始地址 18 19 ORG 0xc200 ; 这个程序要装在到什么位置,在ipl10读盘结束的地方转到该处 20 ;-----------------------------------------------画面模式设置 21 ;确认VBE是否存在[显示模式协议BOOS] 22 ;给AX,ES,DI赋好值之后调用int如果AX没有变成0x004f就没有VBE就只能用320*200的分辨率了 23 ;JMP scrn320 ;便于调试我们直接还是用老的显示模式,所以直接跳过高分辨率的部分 24 MOV AX,0x9000 25 MOV ES,AX 26 MOV DI,0 27 MOV AX,0x4f00 28 INT 0x10 29 CMP AX,0x004f 30 JNE scrn320 31 ;检查VBE的版本 32 MOV AX,[ES:DI+4] 33 CMP AX,0x0200 34 JB scrn320 ; if (AX < 0x0200) goto scrn320 35 ;取得画面模式 36 MOV CX,VBEMODE 37 MOV AX,0x4f01 38 INT 0x10 39 CMP AX,0x004f 40 JNE scrn320 41 ;画面模式信息确认 42 CMP BYTE [ES:DI+0x19],8 43 JNE scrn320 44 CMP BYTE [ES:DI+0x1b],4 45 JNE scrn320 46 MOV AX,[ES:DI+0x00] 47 AND AX,0x0080 48 JZ scrn320 49 ;画面模式切换 50 MOV BX,VBEMODE+0x4000 51 MOV AX,0x4f02 52 INT 0x10 53 MOV BYTE [VMODE],8 ; 记下画面模式 54 MOV AX,[ES:DI+0x12] 55 MOV [SCRNX],AX 56 MOV AX,[ES:DI+0x14] 57 MOV [SCRNY],AX 58 MOV EAX,[ES:DI+0x28] 59 MOV [VRAM],EAX 60 JMP keystatus 61 scrn320: 62 MOV AL,0x13 ; VGA图、320x200x8bit彩色,如果高分辨率模式不行就只能用低分辨率模式了 63 MOV AH,0x00 64 INT 0x10 65 MOV BYTE [VMODE],8 ; 记下画面模式 66 MOV WORD [SCRNX],320 67 MOV WORD [SCRNY],200 68 MOV DWORD [VRAM],0x000a0000 69 70 ;高分辨率{给AX赋值0x4f02,BX赋值模式码{这里要把模式码+0x4000,QEMU中不能直接用下面的方法} 71 ;0x101 640 480 8bit 72 ;0x103 800 600 8bit 73 ;0x105 1024 768 8bit 74 ;0x107 1280 1024 8bit 75 ; MOV BX,0x4101 76 ; MOV AX,0x4f02 77 ; INT 0x10 78 ; MOV BYTE[VMODE],8 79 ; MOV WORD[SCRNX],640 80 ; MOV WORD[SCRNY],480 81 ; MOV DWORD[VRAM],0xe0000000 82 ;-----------------------------------------------画面模式设置
>_<" 键盘输入
1 static char keytable[0x54] = { 2 0, 0, ‘1‘, ‘2‘, ‘3‘, ‘4‘, ‘5‘, ‘6‘, ‘7‘, ‘8‘, ‘9‘, ‘0‘, ‘-‘, ‘^‘, 0, 0, 3 ‘Q‘, ‘W‘, ‘E‘, ‘R‘, ‘T‘, ‘Y‘, ‘U‘, ‘I‘, ‘O‘, ‘P‘, ‘@‘, ‘[‘, 0, 0, ‘A‘, ‘S‘, 4 ‘D‘, ‘F‘, ‘G‘, ‘H‘, ‘J‘, ‘K‘, ‘L‘, ‘;‘, ‘:‘, 0, 0, ‘]‘, ‘Z‘, ‘X‘, ‘C‘, ‘V‘, 5 ‘B‘, ‘N‘, ‘M‘, ‘,‘, ‘.‘, ‘/‘, 0, ‘*‘, 0, ‘ ‘, 0, 0, 0, 0, 0, 0, 6 0, 0, 0, 0, 0, 0, 0, ‘7‘, ‘8‘, ‘9‘, ‘-‘, ‘4‘, ‘5‘, ‘6‘, ‘+‘, ‘1‘, 7 ‘2‘, ‘3‘, ‘0‘, ‘.‘ 8 };
1 if (i < 0x54 + 256) { 2 if (keytable[i - 256] != 0 && cursor_x < 144) {//一般字符 3 /* 显示一次就前移一次光标 */ 4 s[0] = keytable[i - 256]; 5 s[1] = 0; 6 putfonts8_asc_sht(sht_win, cursor_x, 28, COL8_000000, COL8_FFFFFF, s, 1); 7 cursor_x += 8;//记录光标位置 8 } 9 }
1 if (i == 256 + 0x0e && cursor_x > 8) { /* 退格键 */ 2 /* 用空格键把光标消去后,后移1次光标 */ 3 putfonts8_asc_sht(sht_win, cursor_x, 28, COL8_000000, COL8_FFFFFF, " ", 1); 4 cursor_x -= 8; 5 }
1 void make_textbox8(struct SHEET *sht, int x0, int y0, int sx, int sy, int c) 2 { 3 int x1 = x0 + sx, y1 = y0 + sy; 4 boxfill8(sht->buf, sht->bxsize, COL8_848484, x0 - 2, y0 - 3, x1 + 1, y0 - 3); 5 boxfill8(sht->buf, sht->bxsize, COL8_848484, x0 - 3, y0 - 3, x0 - 3, y1 + 1); 6 boxfill8(sht->buf, sht->bxsize, COL8_FFFFFF, x0 - 3, y1 + 2, x1 + 1, y1 + 2); 7 boxfill8(sht->buf, sht->bxsize, COL8_FFFFFF, x1 + 2, y0 - 3, x1 + 2, y1 + 2); 8 boxfill8(sht->buf, sht->bxsize, COL8_000000, x0 - 1, y0 - 2, x1 + 0, y0 - 2); 9 boxfill8(sht->buf, sht->bxsize, COL8_000000, x0 - 2, y0 - 2, x0 - 2, y1 + 0); 10 boxfill8(sht->buf, sht->bxsize, COL8_C6C6C6, x0 - 2, y1 + 1, x1 + 0, y1 + 1); 11 boxfill8(sht->buf, sht->bxsize, COL8_C6C6C6, x1 + 1, y0 - 2, x1 + 1, y1 + 1); 12 boxfill8(sht->buf, sht->bxsize, c, x0 - 1, y0 - 1, x1 + 0, y1 + 0); 13 return; 14 }
>_<" 鼠标移动窗口及光标闪烁
1 /* 移动鼠标 */ 2 mx += mdec.x; 3 my += mdec.y; 4 if (mx < 0) { 5 mx = 0; 6 } 7 if (my < 0) { 8 my = 0; 9 } 10 if (mx > binfo->scrnx - 1) { 11 mx = binfo->scrnx - 1; 12 } 13 if (my > binfo->scrny - 1) { 14 my = binfo->scrny - 1; 15 } 16 sprintf(s, "(%3d, %3d)", mx, my); 17 putfonts8_asc_sht(sht_back, 0, 0, COL8_FFFFFF, COL8_008484, s, 10);//清,显,刷 18 sheet_slide(sht_mouse, mx, my); 19 //移动窗口计算 20 if((mdec.btn & 0x01)!=0){ 21 sheet_slide(sht_win,mx-80,my-80); 22 }//按下左键移动sht_win
1 else if (i<=1) { //光标用定时器 2 if (i != 0) { 3 timer_init(timer3, &fifo, 0); /* 師偼0傪 */ 4 cursor_c = COL8_000000; 5 } else { 6 timer_init(timer3, &fifo, 1); /* 師偼1傪 */ 7 cursor_c = COL8_FFFFFF; 8 } 9 timer_settime(timer3, 50); 10 boxfill8(sht_win->buf, sht_win->bxsize, cursor_c, cursor_x, 28, cursor_x + 7, 43); 11 sheet_refresh(sht_win, cursor_x, 28, cursor_x + 8, 44); 12 }
资料链接:http://pan.baidu.com/s/1m2a1C
标签:des cWeb style blog http color io os ar
原文地址:http://www.cnblogs.com/zjutlitao/p/3991839.html