2011年8月8日 星期一

Controlling Your PS/2 Pointing Device Using I/O Ports

PS/2 鍵盤裝置與 PS/2 指標裝置連接 EC(包含 8042 KBC). 反過來看, 在作業系統中, 我們要與 PS/2 指標裝置溝通, 就必須透過 EC, 而這溝通的管道就是系統的 I/O port 0x60 及 0x64.

當讀取 port 0x64 時, 得到的是 status byte, 其中:
    bit 0 - 1: output buffer full, 0: output buffer empty. "Output" 指 EC 到系統.
    bit 1 - 1: input buffer full, 0: input buffer empty. "Input" 指系統到 EC.
    bit 5 - 1: port 0x60 中的資料是指標裝置送來的資料,0: port 0x60 中的資料是鍵盤裝置送來的資料.

當寫 port 0x64 時, 是對 EC 下 command, 其中較重要的有:
    0x20 - 取出 KBC command byte, 資料會放在 output buffer.
    0x60 - 準備寫入 KBC command byte, 接著將資料放入 input buffer.
    0xA7 - 將連接指標裝置的 PS/2 clock 拉 low (inhibit), 指標裝置將不能傳送資料, 直到 EC 將 clock 拉 high(透過 0xA8 command 或是 0xD4 並送 data 給指標裝置).
    0xA8 - 將連接指標裝置的 PS/2 clock 拉 high, 指標裝置將可自由傳送資料.
    0xD4 - 準備將資料送至指標裝置, 接著將資料放入 input buffer.

當讀 port 0x60 時, 是將資料從 output buffer 讀走, 而寫 port 0x60 時, 是將資料寫入 input buffer. 特別要注意的是, 讀取資料前, 要等 status byte 的 bit 0 為 1 時, 讀取的資料才為最新, 否則讀到的會是上一次的資料; 寫資料(寫 port 0x64 也一樣)前, 要等 status byte 的 bit 1 為 0 時, 寫入的資料才不會蓋掉上一次的.

前面提到的 KBC command byte 包含鍵盤與指標裝置的中斷等控制, 其中較重要的有:
    bit 0 - 1: 當鍵盤 output buffer full 時, 發出 IRQ1 中斷, 0: 關掉中斷.
    bit 1 - 1: 當指標裝置 output buffer full 時, 發出 IRQ12 中斷, 0: 關掉中斷.
    bit 4 - 1: 將 PS/2 clock 拉 low 以關掉鍵盤裝置, 0: 放開 PS/2 clock 使鍵盤裝置能輸入資料.
    bit 5 - 1: 將 PS/2 clock 拉 low 以關掉指標裝置, 0: 放開 PS/2 clock 使指標裝置能輸入資料.

有了以上資訊, 我們就可以直接對指標裝置溝通, 以下是一些常用的程序:
關掉/打開 IRQ1 及 IRQ12:
    1. 持續從 0x64 port 讀取 status byte, 直到 bit 1 為 0.
    2. 寫 0x60 到 0x64 port.
    3a. 寫 0x54 到 0x60 port 以關掉 IRQ1, IRQ12 及鍵盤輸入, 或...
    3b. 寫 0x47 到 0x60 port 以開啟 IRQ1, IRQ12 及鍵盤輸入.
送資料給指標裝置並讀取回應:
    1. 持續從 0x64 port 讀取 status byte, 直到 bit 1 為 0.
    2. 寫 0xD4 到 0x64 port.
    3. 將要送給指標裝置的資料寫到 0x60 port.
    4. 持續從 0x64 port 讀取 status byte, 直到 bit 0 為 1.
    5. 讀 0x60 port 獲得指標裝置的回應.

在 Windows 中, 我們可以利用 WinIO 這套函式庫, 在應用程式中對 I/O port 存取. 由於 PS/2 鍵盤裝置及 PS/2 指標裝置的底層驅動程式分別設定了 IRQ1 及 IRQ12 的中斷服務, 也就是一旦 output buffer 有資料, 就會發出中斷, 驅動程式內的中斷服務函式就會將資料取走, 因此我們要直接存取指標裝置前, 必須先將 IRQ1 及 IRQ12 關掉, 並在存取結束後, 將之打開, 使鍵盤裝置及指標裝置的資料能正常被驅動程式處理.


更多資訊:
The AT keyboard controller
XT, AT and PS/2 I/O port addresses

沒有留言:

張貼留言