ホイールマウス
PS/2マウスは特別な初期化をすることでホイール対応にすることができます。
以下参考にしたリンクです。
マウスの初期化部分とマウスデータのデコード部分を以下のように書き換えます。サンプリングレートを200, 100, 80 の順に設定するのが、ホイール初期化パスワードのようです。
ちなみに QEMU ではホイールマウスは有効になりませんでしたが、VMWare Player では無事有効になりました。ホイールで遊ぶためには、VMWare Player か実機が必要です。
bootpack.h
/* mouse.c */ struct MOUSE_DEC { unsigned char buf[4], phase; int x, y, btn, scroll, scrollmode; };
mouse.c
void enable_mouse(struct FIFO32 *fifo, int data0, struct MOUSE_DEC *mdec) { int result, i; static unsigned char cmd[7] = { 0xF3, /* サンプリングレート設定 */ 0xC8, /* 200 */ 0xF3, /* サンプリングレート設定 */ 0x64, /* 100 */ 0xF3, /* サンプリングレート設定 */ 0x50, /* 80 */ 0xF2 /* デバイスタイプ取得 */ }; /* 書き込み先のFIFOバッファを記憶 */ mousefifo = fifo; mousedata0 = data0; /* ホイールマウス初期化 */ for (i = 0; i < 7; i++) { wait_KBC_sendready(); io_out8(PORT_KEYCMD, KEYCMD_SENDTO_MOUSE); wait_KBC_sendready(); io_out8(PORT_KEYDAT, cmd[i]); } /* デバイスタイプ取得 */ io_cli(); for (i = 0; i < 8; i++) { result = io_in8(PORT_KEYDAT); } io_sti(); /* ホイールが有効かどうかチェック */ if (result == 0x03) { mdec->scrollmode = 1; } else { mdec->scrollmode = 0; } /* マウス有効 */ wait_KBC_sendready(); io_out8(PORT_KEYCMD, KEYCMD_SENDTO_MOUSE); wait_KBC_sendready(); io_out8(PORT_KEYDAT, MOUSECMD_ENABLE); /* うまくいくとACK(0xfa)が送信されてくる */ mdec->phase = 0; /* マウスの0xfaを待っている段階 */ return; } int mouse_decode(struct MOUSE_DEC *mdec, unsigned char dat) { if (mdec->phase == 0) { /* マウスの0xfaを待っている段階 */ if (dat == 0xfa) { mdec->phase = 1; } return 0; } if (mdec->phase == 1) { /* マウスの1バイト目を待っている段階 */ if ((dat & 0xc8) == 0x08) { /* 正しい1バイト目だった */ mdec->buf[0] = dat; mdec->phase = 2; } return 0; } if (mdec->phase == 2) { /* マウスの2バイト目を待っている段階 */ mdec->buf[1] = dat; mdec->phase = 3; return 0; } if (mdec->phase == 3) { /* マウスの3バイト目を待っている段階 */ mdec->buf[2] = dat; if (mdec->scrollmode != 0) { mdec->phase = 4; } else { 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; /* マウスではy方向の符号が画面と反対 */ if (mdec->scrollmode != 0) { return 0; } else { return 1; } } if (mdec->phase == 4) { /* マウスの4バイト目を待っている段階 */ mdec->buf[3] = dat; /* スクロール対応マウスのみスクロール */ mdec->phase = 1; /* mdec.buf[3]は、下位4ビットだけが有効な値である */ /* とりあえず解析せずに値をしまう */ mdec->scroll = mdec->buf[3] & 0x0f; if (mdec->scroll & 0x08) { /* マイナスの値だった */ mdec->scroll |= 0xfffffff0; } return 1; } return -1; /* ここに来ることはないはず */ }