30天自制操作系统-第7天笔记
来源:互联网 发布:石家庄软件学院 编辑:程序博客网 时间:2024/06/12 10:49
1.获取按键编码
#define PORT_KEYDAT 0x0060void inthandler21(int *esp)/* 键盘中断 */{ struct BOOTINFO *binfo = (struct BOOTINFO *) ADR_BOOTINFO; unsigned char data ,s[4]; io_out8(PIC0_OCW2,0x61); //通知PIC“IRQ-01”已经受理完毕 data = io_in8(PORT_KEYDAT); sprintf(s,"%02X",data); boxfill8(binfo->vram, binfo->scrnx, COL8_008484, 0, 16, 15, 31); putfonts8_asc(binfo->vram, binfo->scrnx, 0, 16, COL8_FFFFFF, s);//向屏幕输出s for (;;) { io_hlt(); }}
分析:
io_out8(PIC0_OCW2,0x61); 这句话告诉IPC“已经知道发生了IRQ1中断”。如果是IRQ3中断,则写成0x63.也就是说,将“0x60+IRQ号码”输出给OCW2就可以了。执行这句话之后,PIC继续监视IRQ1中断是否发生。反过来,如果忘记执行,PIC将不再监视。
下面:从编号为0x60的设备输入的8位信息是按键编码,0x60的设备就是键盘。
执行结果:图片1
2. 加快中断处理
1.添加缓冲标志,在bootpack.h 中加入:
/* int.c */
struct KEYBUF { unsigned char data, flag;};
2.在int.c中处理中断:
#define PORT_KEYDAT 0x0060struct KEYBUF keybuf;void inthandler21(int *esp)/* 中断 */{ unsigned char data ; io_out8(PIC0_OCW2,0x61); //通知PIC“IRQ-01”已经受理完毕 data = io_in8(PORT_KEYDAT); if(keybuf.flag == 0){ //如果flag==0,说明之前的数据已经被打印,接下来把刚刚键盘输入的字符缓存 keybuf.data = data; keybuf.flag = 1; //设置标志位1, } return;}
3.在主函数中处理中断(主函数中的for循环修改如下):
for (;;) { //io_hlt(); io_cli(); if(keybuf.flag == 0){ io_stihlt(); }else{ i = keybuf.data; keybuf.flag = 0; io_sti(); sprintf(s,"%02X",i); boxfill8(binfo->vram, binfo->scrnx, COL8_008484, 0, 16, 15, 31); putfonts8_asc(binfo->vram, binfo->scrnx, 0, 16, COL8_FFFFFF, s);//向屏幕打印s } }
实现结果:缓冲区只能存储一个字节,出现问题:
结果与图1类似
3.制作缓冲区
- 修改缓存结构体:
struct KEYBUF { unsigned char data[32]; int next;};
2 修改中断处理,提高缓存数据量
void inthandler21(int *esp)/* 中断 */{ unsigned char data ; io_out8(PIC0_OCW2,0x61); //通知PIC“IRQ-01”已经受理完毕 data = io_in8(PORT_KEYDAT); if(keybuf.next < 32){ //可以缓存32个字符 keybuf.data[keybuf.next] = data; keybuf.next ++; //缓存数+1 } return;}
3.修改输出:
for (;;) { //io_hlt(); io_cli(); if(keybuf.next == 0){ io_stihlt(); }else{ i = keybuf.data[0]; keybuf.next--; //向前移一位 for(j = 0; j < keybuf.next; j++){ keybuf.data[j] = keybuf.data[j+1]; } io_sti(); sprintf(s,"%02X",i); boxfill8(binfo->vram, binfo->scrnx, COL8_008484, 0, 16, 15, 31); putfonts8_asc(binfo->vram, binfo->scrnx, 0, 16, COL8_FFFFFF, s);//向屏幕打印s } }
结果与图1类似
4、5 改善和整理缓冲区
- 增加一个结构体 FIFO8
/* fifo.c */struct FIFO8 { unsigned char *buf; int p, q, size, free, flags;};
其中 :
p: 下一个写入的数据的位置
q : 下一个读出的数据的位置
size : 缓冲区总字节数
free: 保存缓冲区没有数据的字节数
2. 增加一个文件fifo.c,具体功能查看注释:
/* FIFO */#include "bootpack.h"#define FLAGS_OVERRUN 0x0001void fifo8_init(struct FIFO8 *fifo, int size, unsigned char *buf)/* FIFO初始化 */{ fifo->size = size; fifo->buf = buf; fifo->free = size; /* 空闲的大小 */ fifo->flags = 0; fifo->p = 0; /* 下一个数据写入的位置 */ fifo->q = 0; /* 下一个数据读入的位置 */ return;}int fifo8_put(struct FIFO8 *fifo, unsigned char data)/* 向FIFO传送数据并保存 */{ if (fifo->free == 0) { /* 空余没有了,溢出 */ fifo->flags |= FLAGS_OVERRUN; return -1; } fifo->buf[fifo->p] = data; fifo->p++; if (fifo->p == fifo->size) { fifo->p = 0; } fifo->free--; return 0;}int fifo8_get(struct FIFO8 *fifo)/* FIFO获取一个数据 */{ int data; if (fifo->free == fifo->size) { /* 如果缓冲区为空,则返回-1 */ return -1; } data = fifo->buf[fifo->q]; fifo->q++; if (fifo->q == fifo->size) { fifo->q = 0; } fifo->free++; return data;}int fifo8_status(struct FIFO8 *fifo)/*报告一下积攒了多少数据 */{ return fifo->size - fifo->free;}
3 修改中断函数:
struct FIFO8 keyfifo;void inthandler21(int *esp)/* 中断 */{ unsigned char data ; io_out8(PIC0_OCW2,0x61); //通知PIC“IRQ-01”已经受理完毕 data = io_in8(PORT_KEYDAT); fifo8_put(&keyfifo, data); return;}
4 修改主函数:
fifo8_init(&keyfifo, 32, keybuf); //初始化keybuffor (;;) { //io_hlt(); io_cli(); if(fifo8_status(&keyfifo) == 0){ io_stihlt(); }else{ i = fifo8_get(&keyfifo); io_sti(); sprintf(s,"%02X",i); boxfill8(binfo->vram, binfo->scrnx, COL8_008484, 0, 16, 15, 31); putfonts8_asc(binfo->vram, binfo->scrnx, 0, 16, COL8_FFFFFF, s);//向屏幕打印s } }
5 修改Make file文件:增加fifo.obj
6 make run
结果与图1类似
6、7.从鼠标接收数据
- 在bootpack.c 中添加3个函数:
#define PORT_KEYDAT 0x0060#define PORT_KEYSTA 0x0064#define PORT_KEYCMD 0x0064#define KEYSTA_SEND_NOTREADY 0x02#define KEYCMD_WRITE_MODE 0x60#define KBC_MODE 0x47void wait_KBC_sendready(void){ /* 等待键盘控制电路准备完毕 */ for (;;) { if ((io_in8(PORT_KEYSTA) & KEYSTA_SEND_NOTREADY) == 0) { break; } } return;}void init_keyboard(void){ /* 初始化键盘控制电路 */ wait_KBC_sendready(); io_out8(PORT_KEYCMD, KEYCMD_WRITE_MODE); wait_KBC_sendready(); io_out8(PORT_KEYDAT, KBC_MODE); return;}#define KEYCMD_SENDTO_MOUSE 0xd4#define MOUSECMD_ENABLE 0xf4void enable_mouse(void){ /* 激活鼠标 */ wait_KBC_sendready(); io_out8(PORT_KEYCMD, KEYCMD_SENDTO_MOUSE); wait_KBC_sendready(); io_out8(PORT_KEYDAT, MOUSECMD_ENABLE); return; /* 顺利的话,键盘控制其会返送回ACK(0xfa) */}
2 设置鼠标中断
void inthandler2c(int *esp) /* 鼠标中断 */{ unsigned char data ; io_out8(PIC1_OCW2,0x64); //通知PIC1“IRQ-12”已经受理完毕 io_out8(PIC0_OCW2,0x62); //通知PIC0“IRQ-02”已经受理完毕 data = io_in8(PORT_KEYDAT); fifo8_put(&mousefifo, data); return;}
3 修改主函数的显示
for (;;) { //io_hlt(); io_cli(); if(fifo8_status(&keyfifo) + fifo8_status(&mousefifo) == 0){ io_stihlt(); }else{ if (fifo8_status(&keyfifo) != 0) { i = fifo8_get(&keyfifo); io_sti(); sprintf(s, "%02X", i); boxfill8(binfo->vram, binfo->scrnx, COL8_008484, 0, 16, 15, 31); putfonts8_asc(binfo->vram, binfo->scrnx, 0, 16, COL8_FFFFFF, s); } else if (fifo8_status(&mousefifo) != 0) { i = fifo8_get(&mousefifo); io_sti(); sprintf(s, "%02X", i); boxfill8(binfo->vram, binfo->scrnx, COL8_008484, 32, 16, 47, 31); putfonts8_asc(binfo->vram, binfo->scrnx, 32, 16, COL8_FFFFFF, s); } } }
4.结果显示:
阅读全文
0 0
- 《30天自制操作系统》学习笔记--第7天
- 30天自制操作系统-第7天笔记
- 30天自制操作系统笔记 第1天
- 30天自制操作系统笔记 第0天
- 30天自制操作系统笔记 第2天
- 《30天自制操作系统》学习笔记--第0天
- 《30天自制操作系统》学习笔记--第1天
- 《30天自制操作系统》学习笔记--第2天
- 《30天自制操作系统》学习笔记--第3天
- 《30天自制操作系统》学习笔记--第4天
- 《30天自制操作系统》学习笔记--第5天
- 《30天自制操作系统》学习笔记--第6天
- 《30天自制操作系统》学习笔记--第8天
- 《30天自制操作系统》学习笔记--第9天
- 《30天自制操作系统》学习笔记--第10天
- 《30天自制操作系统》学习笔记--第11天
- 《30天自制操作系统》学习笔记--第12天
- 《30天自制操作系统》学习笔记--第13天
- 402. Remove K Digits
- PHP本地进行API接口测试
- 混合APP开发之5+API上传图片过大导致上传失败的解决方式
- Java排序方法sort的使用详解
- 使用hive、java api两种方式实现wordcount功能、及个人感悟
- 30天自制操作系统-第7天笔记
- UOJ#77 bzoj3218 a + b Problem 可持久化线段树优化建图+网络流
- CSDN日报20170630——《降薪求职,到底该不该?》
- vim编辑器的使用总结
- 使用xcode查看和提高单元测试覆盖率
- 6 亿推送数据告诉你,我们的一天究竟在干嘛
- TensorFlow与OpenCV,读取图片,进行简单操作并显示
- Go语言学习之image、image/color、image/png、image/jpeg包(the way to go)
- chrome浏览器调试JS代码