- bàn phím 101 phím cụa IBM PC/AT
8.1.2 I/O control
Lieđn lác giữa bàn phím và computer được thực hieơn thođng qua keyboard controller . Giao tiêp với bàn phím có theơ được chia thành hai lối chính :
a.Tiêp nhaơn scan code
Khi nhaơn được thođng tin từ bàn phím,keyboard controller sẽ phát đoơng interrupt 09h. Scan code gởi đên được đaịt tái port 060h. Đốn chương trình cụa interrupt 09h có nhieơm vú đĩc giá trị ây từ port 060h vàdieên giại thành các thođng tin hữu dúng .
b.Thiêt laơp các thođng sô cho bàn phím.
Có theơ thiêt laơp các tráng thái làm vieơc khác nhau cụa bàn phím baỉng cách gởi moơt control code ra port 060h và kê tiêp là các thođng sô tương ứng. Các control code hợp leơ là :
v 0FFh : Reset the keyboard and start internal diagnostics.
v 0FEh : Resend the last transmission.
v 0FDh-0F7h : No operator (NOP).
v 0F6h : Set keyboard to defaults and continue scanning.
v 0F5h : Set keyboard to defaults and disable keyboard scanning.
v 0F4h : Enable the keyboard. KBD sends ‘ACK’, clears buffer, and starts scanning.
v 0F3h : Set typematic rate and delay. First send 0F3h, then send data byte: 7 6 5 4 3 2 1 0
0 delay Rept rate
bits 5-6 set initial delay before first repeat: 00=250ms;01=500ms; 10=750ms; 11=1000ms bit 7 is always 0
Repeat rate setting (bits 0-4)
Value Character/sec Value Character/sec
0 30.0 0Ah 10.0
1 26.7 0Dh 9.2
2 24.0 10h 7.5
4 20.0 14h 5.0
8 15.0 1Fh 2.0
v 0F2h-0EFh : No operator (NOP).
v 0EEh : Echo. Diagnostics aid. Simply sends 0EEh right back.
v 0EDh Turn LED ‘lock key’ lights on or off. First send 0EDh, then send data byte: 7 6 5 4 3 2 1 0
Not used c n s
ScrollLock LED 0=OFF, 1=ON NumLock LED 0=OFF, 1=ON CapsLock LED 0=OFF, 1=ON
Lưu ý : sau khi gởi control code ra port 060h,phại có moơt khoạng thời gian treê (neđn lớn hơn 10ms) trước khi gởi tiêp data byte.
Thí dú : mov al,Ctrl-code out 060h,al xor cx,cx ; Delay: loop Delay mov al,Data-byte out 060h,al 8.2INTERRUPT 09H 8.2.1Shift và Toggle key
Interrupt 09h quy dịnh hai lối phím đaịc bieơt :
1. Shift key : bao goăm Ctrl, Shift và Alt . Tráng thái cụa các phím này quyêt định giá trị cụa các phím khác . Thí dú : khi nhân phím C ta nhaơn được ký tự ‘c’, nêu nhân Shift-C ta nhaơn được ký tự ‘C’ . Moơt phím shift khi được nhân xuông sẽ baĩt đaău ạnh hưởng đên các phím gõ sau đó cho đên khi phím shift được buođng ra .
2. Toggle key : goăm Caps Lock và Num Lock . Đađy là các cođng taĩc hai chieău . Khi Caps Lock được baơt leđn, tráng thái shift cụa các phím ký tự sẽ đạo ngược . Khi Num Lock được baơt leđn, các phím mũi teđn tređn bạng sô beđn phại sẽ mât tác dúng.
Tình tráng cụa các phím shift và toggle được interrupt 09h ghi nhớ tái địa chư 040:017. Moêi laăn nhaơn được moơt scan code, interrupt 09h đôi chiêu với tình tráng hieơn thời cụa các phím shift và toggle đeơ suy ra mã ASCII đích thực cụa phím được gõ vào .ý nghĩa các bit cụa byte tái địa chư 040:017 ( hay 0000:0417 )
7 6 5 4 3 2 1 0
X Caps Lock : 1 = ON ; 0 = OFF X Num Lock : 1 = ON ; 0 = OFF X Scroll Lock : 1 = ON ; 0 = OFF X 1 = Alt pressed
X 1 = Crtl pressed X 1 = Left shift pressed X 1 = Right shift pressed
8.2.2Thụ túc caơp nhaơt keyboard status byte (040:017)
; Thụ túc sau được thực hieơn ngay sau khi interrupt 09h được gĩi Update-KBD-Flag proc near
push ds mov ax,040h mov ds,ax
in al,060h ; Port 060h : keyboard data mov ah,al
and al,07Fh ; Xóa bit 7 push cs
pop es ; ES = CS lea di,KBD-Table-1 ; mov cx,8
cld
repne scansb ; Dò KBD-Table-1
jne UKF-end ; Khođng phại là shift key hay toggle key mov al,1 ; CX = bit-no cụa Keyboard status byte shl al,cl
cmp cx,3 ; Nêu bit-no > 3 --> Toggle key jbe UKF-Shift ; --> Khođng xét released-key UKF-Toggle:
test ah,080h ;
jnz UKF-end ; Released-key
xor byte ptr ds:[017h],al ; switch bit jmp UKF-end
UKF-Shift: test ah,080h ;
jnz UKF-Shift-Clear ; Released-key UKF-Shift-Set:
or byte ptr ds:[017h],al ; set bit jmp UKF-end
UKF-Shift-Clear: not al
UKF-end: pop ds ret
Update-KBD-Flag endp
KBD-Table-1 db 052h ; Insert scan-code ; 7 db 03Ah ; Caps Lock scan-code ; 6
db 045h ; Num Lock scan-code ; 5 db 046h ; Scroll Lock scan-code ; 4 db 038h ; Alt scan-code ; 3
db 01Dh ; Ctrl scan-code ; 2 db 02Ah ; Left shift scan-code ; 1 db 036h ; Right shift scan-code ; 0 db 0
8.2.3Keyboard buffer
Scan code cụa các phím khác với hai lối phím tređn (Shift key và Togglekey),ngối trừ Insert,được chuyeơn thành hai byte theo hai trường hợp :
Trường hợp phím được gõ vào là moơt phím bình thường, byte thâp chứa mã ASCII cụa phím được gõ,byte cao chứa scan code.
Trường hợp phím gõ vào là moơt phím đaịc bieơt như các phím F1 đên F10 các phím mũi teđn (cursor key), các phím Home,End,PgUp,PgDn,Delete, Insert thì byte thâp sẽ baỉng 0, byte cao chứa scan code.
Caịp giá trị tređn được interrupt 09h đaịt vào moơt “hàng đợi” tái địa chư040:01Eh.Hàng đợi này là moơt buffer có kích thước 020h byte được đánh dâu baỉng hai vị trí : đaău (KBD-head) và cuôi (KBD-tail) . Các giá trị này đaịt tái :
040:01Ah : offset cụa đieơm đaău ( 1 word ), Segment=040h 040:01Ch : offset cụa đieơm cuôi ( 1 word ), Segment=040h
Khởi đaău, khi keyboard buffer còn trông, đieơm đaău được cho trùng với đieơm cuôi . Khi moơt phím được gõ, scan code và ascii code được đaịt vào vị trí đieơm cuôi đang chư đên, sau đó đieơm cuôi được taíng theđm 2 . Nêu đieơm cuôi đang chư đên vị trí cuôi cùng cụa buffer (veă maịt vaơt lý), nó sẽ được đaịt lái cho trùng với vị trí đaău tieđn cụa buffer (veă maịt vaơt lý)
Nêu như vị trí kê tiêp cụa đieơm cuôi baỉng với vị trí hieơn tái cụa đieơm đaău : keyboard buffer đã đaăy, các phím được gõ kê tiêp sẽ khođng được đaịt vào keyboard buffer .
Khi có yeđu caău đĩc bàn phím, caịp giá trị đang được đieơm đaău chư đên sẽ được lây ra (xem như là mới do bàn phím gởi đên), sau đó đieơm đaău được taíng theđm 2 . Nêu đieơm đaău chư đên vị trí cuôi cùng cụa buffer (veă maịt vaơt lý), nó sẽ được đaịt lái cho trùng với vị trí đaău tieđn cụa buffer (veă maịt vaơt lý) . Lẽ dĩ nhieđn nêu đieơm đaău đang trùng với đieơm cuôi,sẽ khođng có phím nào được đĩc.
Tóm lái bàn phím được khai thác theo nguyeđn lý : giá trị cụa các phím được gởi đên từ bàn phím được interrupt 09h ghi nhớ và saĩp xêp theo thứ tự trước sau trong moơt buffer rieđng,khi các chương trình ứng dúng “đĩc bàn phím”, giá trị cũ nhât trong buffer sẽ được chuyeơn giao.
Minh hĩa veă cách quạn lý keyboard buffer :
a.Khởi đaău KBD-head và KBD-tail đang trùng nhau : Keyboard buffer đang trông KBD-head
KBD-tail
KBD-head T KBD-tail c.Phím ‘E’ được gõ : KBD-head T E KBD-tail d.Phím ‘S’ được gõ : KBD-head T E S KBD-tail e. Phím ‘T’ được gõ : KBD-head T T E S KBD-tail
f. Có yeđu caău đĩc bàn phím --> Phím ‘T’ được đĩc
KBD-head
T T E S
KBD-tail