スクロール機能を初期化をするには、マウスにデータを200、100、80の順に送れば良いみたいだ。しかし、それぞれ送る前にコマンド0xF3を送る必要があるため、実際には次の順でデータを送っていく。
0xf3 200 0xf3 100 0xf3 80
どのデータも、送信後は0xFAが返ってくる(と思う)ので、正しく送れたか確かめながらデータを送信して行く。
一通りデータを送った後、0xF2コマンドを送ってマウスのタイプを取得し、スクロールマウスかどうかを調べる。0x03, 0x04, 0x05が返ってきたらスクロールマウスのようだ。
void enable_mouse(struct FIFO32 *fifo, int data0, struct MOUSE_DEC *mdec) { int phase = 0, i; (中略) /* スクロール有効化 */ for (;;) { i = mouse_senddata(0xf3); // [共通]レート設定コマンド送信 if (i == 0xfa) { if (phase == 0) { i = mouse_senddata(200); } else if (phase == 1) { i = mouse_senddata(100); } else if (phase == 2) { i = mouse_senddata(80); if (i == 0xfa) { phase++; } break; } if (i == 0xfa) { phase++; } else { break; // 初期化失敗 } } else { break; // 初期化失敗 } } if (phase == 3 && mouse_senddata(0xf2) != 0x00) { mdec->scrollmode = 1; // スクロールマウスだった } else { mdec->scrollmode = 0; // スクロールマウスじゃなかった } return; }
int mouse_senddata(int data) /* マウスデバイスにデータを送る。 */ { wait_KBC_sendready(); io_out8(PORT_KEYCMD, KEYCMD_SENDTO_MOUSE); wait_KBC_sendready(); io_out8(PORT_KEYDAT, data); io_cli(); data = io_in8(PORT_KEYDAT); io_sti(); return data; }
struct MOUSE_DEC { unsigned char buf[4], phase; int x, y, btn, scroll, scrollmode; };
int mouse_decode(struct MOUSE_DEC *mdec, unsigned char dat) { (中略) if (mdec->phase == 4) { /* スクロール対応マウスのみスクロール */ mdec->phase = 1; // mdec.buf[3]は、下位4ビットだけが有効な値である // とりあえず解析せずに値をしまう。 mdec->scroll = mdec->buf[3] & 0x0f; if (mdec->scroll & 0x08) { // マイナスの値だった mdec->scroll |= 0xfffffff0; } return 1; } }