读书笔记《30天自制操作系统》day08

来源:互联网 发布:杀出重围 知乎 编辑:程序博客网 时间:2024/05/18 17:23

1. 响应鼠标中断需要先激活鼠标控制电路,鼠标控制电路包含在键盘控制电路中。

asmhead.nas中也有类似代码,等待键盘控制电路准备好。

waitkbdout:IN AL,0x64AND AL,0x02JNZwaitkbdoutRET
#define PORT_KEYDAT0x0060#define PORT_KEYSTA0x0064#define PORT_KEYCMD0x0064#define KEYSTA_SEND_NOTREADY0x02#define KEYCMD_WRITE_MODE0x60#define KBC_MODE0x47void 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_MOUSE0xd4#define MOUSECMD_ENABLE0xf4void enable_mouse(void){wait_KBC_sendready();io_out8(PORT_KEYCMD, KEYCMD_SENDTO_MOUSE);wait_KBC_sendready();io_out8(PORT_KEYDAT, MOUSECMD_ENABLE);return; }

2. 中断处理程序要通知两块PIC,IRQ12已经完成,之后从寄存器取鼠标中断发来的数据。

struct FIFO8 mousefifo;void inthandler2c(int *esp){unsigned char data;io_out8(PIC1_OCW2, 0x64);io_out8(PIC0_OCW2, 0x62);data = io_in8(PORT_KEYDAT);fifo8_put(&mousefifo, data);return;}

3. 鼠标发送来的中断信息的第一个为0xfa,之后发送以3个字节为单位的信息。

struct MOUSE_DEC {unsigned char buf[3], phase;/*buf[0]与鼠标移动和按键滚轮都有关,buf[1]与鼠标左右移动有关,buf[2]与鼠标上下移动有关*/int x, y, btn;/*xy坐标和btn按键状态*/};int mouse_decode(struct MOUSE_DEC *mdec, unsigned char dat){if (mdec->phase == 0) {if (dat == 0xfa) {/*第一个发来的标志信息*/mdec->phase = 1;}return 0;}        /*接着发正常的三个字节信息*/if (mdec->phase == 1) {if ((dat & 0xc8) == 0x08) {/*保证第一个对*/mdec->buf[0] = dat;mdec->phase = 2;}return 0;}if (mdec->phase == 2) {mdec->buf[1] = dat;mdec->phase = 3;return 0;}if (mdec->phase == 3) {mdec->buf[2] = dat;mdec->phase = 1;mdec->btn = mdec->buf[0] & 0x07;mdec->x = mdec->buf[1];mdec->y = mdec->buf[2];if ((mdec->buf[0] & 0x10) != 0) {mdec->x |= 0xffffff00;}if ((mdec->buf[0] & 0x20) != 0) {mdec->y |= 0xffffff00;}mdec->y = - mdec->y; return 1;}return -1; }

 

/*MariMain 处理鼠标信息部分代码*/void hariMain(){        /*中略*/        struct MOUSE_DEC mdec;        /*中略*/        enable_mouse(&mdec);        for(;;)        {                io_cli();                if(fifo8_status(&keyfifo)+fifo8_status(&mousefifo)==0)                {                        io_stihlt();                }                else                {                        if(fifo8_status(&keyfifo)!=0)                        {                        }                        else if(fifo8_status(&mousefifo)!=0)                        {                                i = fifo8_get(&mousefifo);                                io_sti();                                if (mouse_decode(&mdec, i) != 0) {                                sprintf(s, "%02X %02X %02X",mdec.buf[0],mdec.buf[1],mdec.buf[2]);                                boxfill8(binfo->vram, binfo->scrnx, COL8_008484, 32, 16, 32+8*8-1,31);                                 putfonts8_asc(binfo->vram, binfo->scrnx, 32, 16, COL8_FFFFFF, s);                                                                 }                        }                }        }}

4. 移动鼠标

void HariMain(void){struct BOOTINFO *binfo = (struct BOOTINFO *) ADR_BOOTINFO;char s[40], mcursor[256],keybuf[32],mousebuf[128];int mx, my,i;struct MOUSE_DEC mdec;init_gdtidt();/*初始化GDT,IDT*/init_pic();/* 初始化PIC */io_sti();fifo8_init(&keyfifo,32,keybuf);//初始化队列fifo8_init(&mousefifo,128,mousebuf);io_out8(PIC0_IMR, 0xf9); /*开鼠标和键盘中断*/io_out8(PIC1_IMR, 0xef);init_keyboard();init_palette(); /* 初始化调色板 */init_screen8(binfo->vram, binfo->scrnx, binfo->scrny);/* 初始化屏幕 */mx = (binfo->scrnx - 16) / 2;my = (binfo->scrny - 28 - 16) / 2;init_mouse_cursor8(mcursor, COL8_008484);/* 显示鼠标指示符 */putblock8_8(binfo->vram, binfo->scrnx, 16, 16, mx, my, mcursor, 16);sprintf(s, "(%d, %d)", mx, my);putfonts8_asc(binfo->vram, binfo->scrnx, 0, 0, COL8_FFFFFF, s);enable_mouse(&mdec);for (;;) {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();if (mouse_decode(&mdec, i) != 0) {sprintf(s, "[lcr %4d %4d]", mdec.x, mdec.y);if ((mdec.btn & 0x01) != 0) {s[1] = 'L';}if ((mdec.btn & 0x02) != 0) {s[3] = 'R';}if ((mdec.btn & 0x04) != 0) {s[2] = 'C';}boxfill8(binfo->vram, binfo->scrnx, COL8_008484, 32, 16, 32 + 15 * 8 - 1, 31);putfonts8_asc(binfo->vram, binfo->scrnx, 32, 16, COL8_FFFFFF, s);boxfill8(binfo->vram, binfo->scrnx, COL8_008484, mx, my, mx + 15, my + 15); /*隐藏鼠标*/mx += mdec.x;my += mdec.y;if (mx < 0) {mx = 0;}if (my < 0) {my = 0;}if (mx > binfo->scrnx - 16) {mx = binfo->scrnx - 16;}if (my > binfo->scrny - 16) {my = binfo->scrny - 16;}sprintf(s, "(%3d, %3d)", mx, my);boxfill8(binfo->vram, binfo->scrnx, COL8_008484, 0, 0, 79, 15); putfonts8_asc(binfo->vram, binfo->scrnx, 0, 0, COL8_FFFFFF, s);putblock8_8(binfo->vram, binfo->scrnx, 16, 16, mx, my, mcursor, 16);/*显示鼠标*/}}}}}


 

原创粉丝点击