http://blog.csdn.net/ltbylc/article/details/8309257
1. 鼠标的显示,这个与显示字符是一样的道理,写像素
- void init_mouse_cursor8(char *mouse, char bc)
- {
- static char cursor[16][16] = {
- "**************..",
- "*OOOOOOOOOOO*...",
- "*OOOOOOOOOO*....",
- "*OOOOOOOOO*.....",
- "*OOOOOOOO*......",
- "*OOOOOOO*.......",
- "*OOOOOOO*.......",
- "*OOOOOOOO*......",
- "*OOOO**OOO*.....",
- "*OOO*..*OOO*....",
- "*OO*....*OOO*...",
- "*O*......*OOO*..",
- "**........*OOO*.",
- "*..........*OOO*",
- "............*OO*",
- ".............***"
- };
- int x, y;
- for (y = 0; y < 16; y++) {
- for (x = 0; x < 16; x++) {
- if (cursor[y][x] == '*') {
- mouse[y * 16 + x] = COL8_000000;
- }
- if (cursor[y][x] == 'O') {
- mouse[y * 16 + x] = COL8_FFFFFF;
- }
- if (cursor[y][x] == '.') {
- mouse[y * 16 + x] = bc;
- }
- }
- }
- return;
- }
- void putblock8_8(char *vram, int vxsize, int pxsize,
- int pysize, int px0, int py0, char *buf, int bxsize)
- {
- int x, y;
- for (y = 0; y < pysize; y++) {
- for (x = 0; x < pxsize; x++) {
- vram[(py0 + y) * vxsize + (px0 + x)] = buf[y * bxsize + x];
- }
- }
- return;
- }
2. 响应鼠标中断需要先激活鼠标控制电路,鼠标控制电路包含在键盘控制电路中。
asmhead.nas中也有类似代码,等待键盘控制电路准备好。
- waitkbdout:
- IN AL,0x64
- AND AL,0x02
- JNZ waitkbdout
- RET
- #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 0x47
- void 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 0xf4
- void enable_mouse(void)
- {
- wait_KBC_sendready();
- io_out8(PORT_KEYCMD, KEYCMD_SENDTO_MOUSE);
- wait_KBC_sendready();
- io_out8(PORT_KEYDAT, MOUSECMD_ENABLE);
- return;
- }
3. 中断处理程序要通知PIC1 IRQ12已经完成PIC0 IRQ2已经完成
- 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;
- }
4. 鼠标发送来数据的处理,鼠标第一个先发送一个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 处理鼠标信息部分代码*/
- 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);
- }