开发者社区> 史迪奇2号> 正文
阿里云
为了无法计算的价值
打开APP
阿里云APP内打开

[自制简单操作系统] 5、杂七杂八(高分辨率和键盘输入)

简介:
+关注继续查看


 

 

前言:

>_<" 这几天正在研究一个好玩的,准备写《软硬结合第三篇——科班的还是可以修电脑的》,可是当前遇到个技术难点——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 ;-----------------------------------------------画面模式设置    
复制代码
  • 第4行必须添加,否则就无法正常显示,采用高版本处理器的汇编语言
  • 第6行VBEMODE是控制显示模式的,具体见71~74行
  • 第23行,如果直接跳到scrn320就 执行老的画面显示模式,这里scrn32后的一段就是原来的老的显示模式部分,如果把老的显示模式设置部分换为70行后的部分也能显示高分辨率,但是在模 拟器上最后一种模式不能显示,其实这里上面那么多行是为了在真机上能够启用高分辨率而做的检查工作,由于VESA相关工作做的没能把所有的显示模式统一, 所以,只有遵守VBSA-BIOS extension协议的才能启用高分辨率~

>_<" 键盘输入

  • 这里的键盘输入,根据映射规律我们建立一个映射表:
复制代码
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 };
复制代码
  • 然后在键盘消息处理部分直接利用映射表读取按键信息,注意这里函数putfonts8_asc_sht是显示字符串,所以s[1]=0;
  • 这里sht_win是我们新建的一个(也是原来的那个显示计数的窗口,只是改了个名字而已)窗口,让输入的文字在上面显示,每次输入cursor_x即光标的位置要后移
复制代码
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

 



本文转自beautifulzzzz博客园博客,原文链接:http://www.cnblogs.com/zjutlitao/p/3991839.html,如需转载请自行联系原作者

版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。

相关文章
Win系统 - 内存稳定性测试软件(MemTest)
Win系统 - 内存稳定性测试软件(MemTest)
103 0
蚂蚁超大规模分布式系统稳定性体系实践
大规模分布式系统的稳定性建设,是确保业务服务不受硬件、人为等风险因素影响而中断的核心工作,随着业务规模增大和复杂度的提升,系统稳定性的重要程度和难度也随之增大。在蚂蚁集团业务发展过程中,业务复杂度、用户规模以及业务重要性都逐步增大,相应的稳定性建设也伴随着业务的发展进行了不断地建设和提升。
340 0
C++:输入10个整数存入数组list,然后用指针法从后向前输出该数组中的整数
C++:输入10个整数存入数组list,然后用指针法从后向前输出该数组中的整数
71 0
开源 | 蚂蚁金服开源:关系数据的可视化引擎 G6 2.0
小蚂蚁说: 首先回顾上一次蚂蚁金服AntV的相关开源消息:《蚂蚁金服开源:数据驱动的高交互可视化图形语法G2》。 AntV 是蚂蚁金服全新一代数据可视化解决方案,主要包含「数据驱动的高交互可视化图形语法」G2、本次开源的 G6、适于对性能、体积、扩展性要求严苛场景下使用的移动端图表库 F2 以及一套完整的图表使用指引和可视化设计规范,致力于提供一套简单方便、专业可靠、无限可能的数据可视化最佳实践。
5512 0
WPF 捕获键盘输入事件
原文:WPF 捕获键盘输入事件 最近修改的一个需求要求捕获键盘输入的 Text,包括各种标点符号。 最开始想到的是 PreviewKeyDown 或者 PreviewKeyUp 这样的键盘事件。 但是这两个事件的对象 KeyEventArgs 不够用,得依靠判断 Key 来判断输入了什么,然后再根据判断写死一个相应键位的 Text 来获取数据。
1689 0
858
文章
0
问答
文章排行榜
最热
最新
相关电子书
更多
低代码开发师(初级)实战教程
立即下载
阿里巴巴DevOps 最佳实践手册
立即下载
冬季实战营第三期:MySQL数据库进阶实战
立即下载