Tài liệu hạn chế xem trước, để xem đầy đủ mời bạn chọn Tải xuống
1
/ 11 trang
THÔNG TIN TÀI LIỆU
Thông tin cơ bản
Định dạng
Số trang
11
Dung lượng
94,06 KB
Nội dung
46 CHƯƠNG 8 : KEYBOARD Bàn phím của máy IBM PC là một thiết bò bao gồm : Các phím : mỗi phím xác đònh bởi một số thứ tự gọi là scan code (scan code là một giá trò 8 bit) Có 3 loại bàn phím chính : - bàn phím 83 phím của IBM PC - bàn phím 84 phím của IBM PC/AT - bàn phím 101 phím của IBM PC/AT Các đèn hiệu báo trạng thái cho các phím đặc biệt Bộ vi xử lý riêng với nhiệm vụ tiếp nhận thông tin từ các phím và chuyển các thông tin này đến computer. 8.1NGUYÊN LÝ HOẠT ĐỘNG CỦA BÀN PHÍM 8.1.1Scan code Khi một phím được nhấn xuống, bàn phím thông báo và chuyển scan code của phím ấy cho computer Nếu phím đã được nhấn xuống và giữ im (không buông tay) sau một thời gian (initial delay), bàn phím sẽ tiếp tục chuyển scan code của phím ấy cho computer theo một tốc độ xác đònh (repeat rate) . Ta gọi scan code trong trường hợp này là Pressed-key Khi phím được ngưng nhấn (buông tay), bàn phím chuyển scan code của phím ấy cho computer sau khi cộng thêm 128 (dựng bit số 7) Ta gọi scan code trong trường hợp này là Released-key Bảng B.8.1 : Scan code của các phím trên bàn phím 83/84 Hex Key Hex Key Hex Key Hex Key Hex Key 01 Esc 12 E 23 H 34 . > 45 NumLock 02 1 ! 13 R 24 J 35 / ? 46 ScrollLock 03 2 Ỵ 14 T 25 K 36 Shft(Rt) 47 Home [7] 04 3 # 15 Y 26 L 37 * PrtSc 48 Up [8] 05 4 $ 16 U 27 ; : 38 Alt 49 PgUp [9] 06 5 % 17 I 28 “ ‘ 39 Spacebar 4A K - 07 6 Á 18 O 29 Ạ À 3A CapsLock 4B Left [4] 08 7 & 19 P 2A Shft(L) 3B F1 4C [5] 09 8 * 1A [ A 2B \ 3C F2 4D Right[6] 0A 9 ( 1B ] Ã 2C Z 3D F3 4E K + 0B 0 1C Enter 2D X 3E F4 4F End [1] 0C - - 1D Ctrl 2E C 3F F5 50 Down [2] 0D + = 1E A 2F V 40 F6 51 PgDn [3] 0E bksp 1F 30 B 41 F7 52 Ins [0] 0F Tap 20 T,T 31 N 42 F8 53 Del [.] 10 Q 21 F 32 M 43 F9 54 SysReq 11 W 22 33 33 , < 44 F10 Đối với bàn phím 101 phím, scan code tương ứng với các phím mở rộng (Ctrl,Alt,Enter thứ hai, các phím Ins,Delete,Home,End,PgUp,PgDn và các phím mũi tên thứ hai ) luôn được tạo thành một cặp giá trò 47 với byte đầu bằng 0E0h và byte kế tiếp là scan code tương tự với scan code của bàn phím 83/84 . Tổ hợp các phím mở rộng sẽ tạo thành một chuỗi các scan code với ý nghóa tương tự trên bàn phím 83/84 Bảng B.8.2 : Scan code của các phím mở rộng trên bàn phím 101/102 ---------------------------------------------Ú---------------------------- Key Hex Sequence Key Hex Sequence| F11 .57 Home .e0 47 | F12 58 Shft-Home e0 aa e0 47 | Right-Alt .e0 38 End .e0 4f | Right-Ctrl .e0 1d Shft-End .e0 aa e0 4f | PrintScreen e0 2a e0 37 Up .e0 48 | Shft-PrintScreen (SysReq) e0 37 Shft-Up .e0 aa e0 48 | Ctrl-PrintScreen (SysReq) e0 37 Down e0 50 | Alt-PrintScreen .54 Shft-Down e0 aa e0 50 | Pause .e1 1d 45 e1 9d c5 PageUp .e0 49 | Ctrl-Pause (Break) e0 46 e0 c6 Shft-PageUp .e0 aa e0 49 | Insert e0 53 PageDown e0 51 | Shft-Insert e0 aa e0 52 Shft-PageDown .e0 aa e0 51 | Delete e0 53 Right .e0 4d | Shft-Delete e0 aa e0 53 Shft-Right .e0 aa e0 4d | Left e0 4b K Enter .e0 1c | Shft-Left e0 aa e0 4b K / e0 35 | Shft- K / e0 aa e0 35 Chú ý : các tên phím trong bảng B.8.1 và B.8.2 có ký hiệu K đi trước là các phím thuộc phần Key Pad của bàn phím (bảng số bên tay phải) 8.1.2 I/O control Liên lạc giữa bàn phím và computer được thực hiện thông qua keyboard controller . Giao tiếp với bàn phím có thể được chia thành hai loại chính : a.Tiếp nhận scan code Khi nhận được thông tin từ bàn phím,keyboard controller sẽ phát động interrupt 09h. Scan code gởi đến được đặt tại port 060h. Đoạn chương trình của interrupt 09h có nhiệm vụ đọc giá trò ấy từ port 060h vàdiễn giải thành các thông tin hữu dụng . b.Thiết lập các thông số cho bàn phím. Có thể thiết lập các trạng thái làm việc khác nhau của bàn phím bằng cách gởi một control code ra port 060h và kế tiếp là các thông số tương ứng. Các control code hợp lệ 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 0-4 set the repeat rate 48 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ó một khoảng thời gian trễ (nê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 loại phím đặc biệt : 1. Shift key : bao gồ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 nhận được ký tự ‘c’, nếu nhấn Shift-C ta nhận được ký tự ‘C’ . Một phím shift khi được nhấn xuống sẽ bắt đầu ảnh hưởng đến các phím gõ sau đó cho đến khi phím shift được buông ra . 2. Toggle key : gồm Caps Lock và Num Lock . Đây là các công tắc hai chiều . Khi Caps Lock được bật lên, trạng thái shift của các phím ký tự sẽ đảo ngược . Khi Num Lock được bật lên, các phím mũi tên trên bảng số bê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. Mỗi lần nhận được một scan code, interrupt 09h đối chiếu với tình trạng hiện thời của các phím shift và toggle để 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 Insert state : 1 = ON ; 0 = OFF 49 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 cập nhật keyboard status byte (040:017) ; Thủ tục sau được thực hiệ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 ; Khô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 ; --> Khô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 and byte ptr ds:[017h],al ; clear bit 50 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 loại phím trên (Shift key và Togglekey),ngoại trừ Insert,được chuyển thành hai byte theo hai trường hợp : Trường hợp phím được gõ vào là mộ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à một phím đặc biệt như các phím F1 đến F10 các phím mũi tên (cursor key), các phím Home,End,PgUp,PgDn,Delete, Insert thì byte thấp sẽ bằng 0, byte cao chứa scan code. Cặp giá trò trên được interrupt 09h đặt vào một “hàng đợi” tại đòa chỉ040:01Eh.Hàng đợi này là một buffer có kích thước 020h byte được đánh dấu bằng hai vò trí : đầu (KBD-head) và cuối (KBD-tail) . Các giá trò này đặt tại : 040:01Ah : offset của điểm đầu ( 1 word ), Segment=040h 040:01Ch : offset của điểm cuối ( 1 word ), Segment=040h Khởi đầu, khi keyboard buffer còn trống, điểm đầu được cho trùng với điểm cuối . Khi một phím được gõ, scan code và ascii code được đặt vào vò trí điểm cuối đang chỉ đến, sau đó điểm cuối được tăng thêm 2 . Nếu điểm cuối đang chỉ đến vò trí cuối cùng của buffer (về mặt vật lý), nó sẽ được đặt lại cho trùng với vò trí đầu tiên của buffer (về mặt vật lý) Nếu như vò trí kế tiếp của điểm cuối bằng với vò trí hiện tại của điểm đầu : keyboard buffer đã đầy, các phím được gõ kế tiếp sẽ không được đặt vào keyboard buffer . Khi có yêu cầu đọc bàn phím, cặp giá trò đang được điểm đầu chỉ đến sẽ được lấy ra (xem như là mới do bàn phím gởi đến), sau đó điểm đầu được tăng thêm 2 . Nếu điểm đầu chỉ đến vò trí cuối cùng của buffer (về mặt vật lý), nó sẽ được đặt lại cho trùng với vò trí đầu tiên của buffer (về mặt vật lý) . Lẽ dó nhiên nếu điểm đầu đang trùng với điểm cuối,sẽ không có phím nào được đọc. Tóm lại bàn phím được khai thác theo nguyê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à sắp xếp theo thứ tự trước sau trong một buffer riê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 chuyển giao. Minh họa về cách quản lý keyboard buffer : a.Khởi đầu KBD-head và KBD-tail đang trùng nhau : Keyboard buffer đang trống KBD-head KBD-tail b.Phím ‘T’ được gõ : 51 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ó yêu cầu đọc bàn phím --> Phím ‘T’ được đọc KBD-head T T E S KBD-tail 8.2.4: Thủ tục cập nhật keyboard buffer ( thêm một phím vào hàng đợi ) Insert-key proc near ; Input ; AH : Scan code ; AL : ASCII code ; Output ; AX = 0FF00h --> buffer đã đầy push bx push si push ds mov bx,040h mov ds,bx mov bx,word ptr ds:[01Ch] ; BX = điểm cuối hàng đợi mov si,bx add bx,2 ; cmp bx,03Eh ; Cuối buffer hay chưa jb IK-1 mov bx,1Eh ; Nếu rồi thì quay trở về đầu buffer IK-1: cmp bx,word ptr ds:[01Ah] ; Kiểm tra xem đã đầy buffer chưa jne IK-2 mov ax,0FF00h 52 jmp IK-3 IK-2: mov word ptr ds:[si],ax ; Đặt scan-code và Ascii-code vào ; hàng đợi mov word ptr ds:[01Ch],bx ; Cập nhật điểm cuối IK-3: pop ds pop si pop bx ret Insert-key endp 8.2.5Thủ tục đọc một phím từ keyboard buffer Read-key proc near ; Input ; AH = 0 --> nếu chưa có phím trong hàng đợi thì chờ ; AH = 1 --> nếu chưa có phím trong hàng đợi thì AX = 0FF00h ; Output ; AH : Scan code ; AL : ASCII code push bx push ds mov bx,040h mov ds,bx RK-1: mov bx,word ptr ds:[01Ah] ; BX = điểm đầu hàng đợi cmp bx,word ptr ds:[01Ch] ; Có bằng điểm cuối không ? jne RK-2 ; Nếu bằng --> chưa có phím trong ; hàng đợi . or ah,ah jz RK-1 ; AH = 0 --> chờ mov ax,0FF00h ; AH # 0 --> cho AX=0FF00h rồi kết thúc jmp RK-4 RK-2: mov ax,word ptr ds:[bx] ; Đặt scan-code và Ascii-code vào AX add bx,2 cmp bx,03Eh jne RK-3 ; Cuối buffer hay chưa ? mov bx,01Eh ; Nếu rồi thì quay trở về đầu buffer RK-3: mov word ptr ds:[01Ah],bx ; Cập nhật điểm đầu . RK-4: pop ds pop bx ret 53 Read-key endp 8.3INTERRUPT 016H Để giúp các chương trình có thể truy nhập đến bàn phím một cách dễ dàng,BIOS cung cấp một số các chức năng đơn giản và thuận tiện thông qua interrupt 016h. Interrupt 016h cung cấp các chức năng căn bản sau : 8.3.1Đọc keyboard buffer Input : AH = 0 Output : AH = scan code AL = ASCII code (0 nếu là phím đặc biệt) Đọc một phím từ keyboard buffer,nếu chưa có phím trong keyboard buffer sẽ chờ cho đến khi có phím gõ vào ( do interrupt 09h cập nhật ).Khi đọc sẽ “xóa” luôn mã phím trong keyboard buffer ( Chỉ cập nhật KBD-head chứ không thay đổi thông tin trong keyboard buffer). 8.3.2Kiểm tra keyboard buffer Input : AH = 01 Output : ZF = 1 : không có phím nào trong keyboard buffer. ZF = 0 : đã có phím trong keyboard buffer, AH = scan code, AL = ASCII code Kiểm tra keyboard buffer, nếu keyboard buffer không trống thì đọc như chức năng 0 nhưng không cập nhật lại KBD-head. 8.3.3Đọc keyboard status byte Input : AH = 02 Output : AL = status byte ( thông tin như nêu ở phần trên ) Đọc status byte tại đòa chỉ 0000:0417h Chú ý rằng chức năng 01 của interrupt 021h đã sử dụng interrupt 016h để đọc bàn phím, và chỉ cho lại byte thấp của phím gõ vào. Vì vậy, sử dụng interrupt 016h để đọc bàn phím là phương pháp tốt nhất cho các chương trình Assembler. 8.3.4Mã của một số các phím đặc biệt : (giá trò AX sau khi đọc bằng chức năng 0 hay 1 của interrupt 016h) Cursor-up equ 04800h F1 equ 03B00h Cursor-down equ 05000h F2 equ 03C00h Cursor-left equ 04B00h F3 equ 03D00h Cursor-right equ 04D00h F4 equ 03E00h ESC-key equ 0011Bh F5 equ 03F00h Enter-key equ 01C0Dh F6 equ 04000h Ins-key equ 05200h F7 equ 04100h Del-key equ 05300h F8 equ 04200h Backspace equ 00E08h F9 equ 04300h Home-key equ 04700h F10 equ 04400h End-key equ 04F00h PgUp-key equ 04900h Ctrl-left equ 07300h PgDn-key equ 05100h Ctrl-right equ 07400h Ctrl-Home equ 07700h Ctrl-PgUp equ 08400h Ctrl-End equ 07500h 54 Ctrl-PgDn equ 07600h Ctrl-F1 equ 05E00h Alt-F1 equ 06800h Ctrl-F2 equ 05F00h Alt-F2 equ 06900h Ctrl-F3 equ 06000h Alt-F3 equ 06A00h Ctrl-F4 equ 06100h Alt-F4 equ 06B00h Ctrl-F5 equ 06200h Alt-F5 equ 06C00h Ctrl-F6 equ 06300h Alt-F6 equ 06D00h Ctrl-F7 equ 06400h Alt-F7 equ 06E00h Ctrl-F8 equ 06500h Alt-F8 equ 06F00h Ctrl-F9 equ 06600h Alt-F9 equ 07000h Ctrl-F10 equ 06700h Alt-F10 equ 07100h 8.4MỘT CHƯƠNG TRÌNH VỀ BÀN PHÍM Các thủ tục Num-to-dec và Num-to-hex sử dụng trong thí dụ này là các bài tập mẫu của chương 6. main proc near lea dx,Mess1 ; In Mess1 mov ah,09h int 021h M1: lea di,Key-name ; Xóa Key-name của phím trước mov cx,10 ; cld ; mov al,’ ‘ ; rep stosb ; xor ax,ax ; Đọc keyboard int 016h push ax mov key-name,al ; Đặt ASCII code vừa nhận được vào ; Key-name lea si,Function-table mov cx,7 or al,al ; AL = 0 --> Function key jz M2 lea si,Control-table ; AL <> 0 --> Test Control key xchg ah,al mov cx,10 M2: call Get-name ; Dò tên Function/Control key pop ax push ax xor ah,ah lea si,Ascii-code-hex+1 55 call Num-to-hex ; Taïo ASCII code (hex) lea si,Ascii-code-dec mov bx,3 call Num-to-dec ; Taïo ASCII code (dec) pop ax push ax mov al,ah xor ah,ah lea si,Scan-code-hex+1 call Num-to-hex ; Taïo SCAN code (hex) lea si,Scan-code-dec call Num-to-dec ; Taïo SCAN code (dec) lea dx,Mess2 mov ah,09h int 021h pop ax ; AX = read key cmp al,27 ; ( 01Bh ) ESC-key --> Keát thuùc je M3 jmp M1 M3: int 020h main endp Mess1 db ‘ Test-key program ‘,10,10,13 db ‘Press ESC to abort, another key to continue’ db 10,10,13,’$’ Mess2 db ‘ Key name is : ‘ Key-name db 10 dup (‘ ‘) db ‘ ASCII CODE : ‘ ascii-code-hex db ‘000h (‘ ascii-code-dec db ‘000) ‘ db ‘SCAN CODE : ‘ scan-code-hex db ‘000h (‘ scan-code-dec db ‘000) ‘,13,’$’ Get-Name proc near ; DS:SI = Key-table addr ; AL = ID code ; CX = Element size ; Key-table elements structure : ; 1 byte for ID code ( ID-code=0 --> end table ) ; cx-6 byte for name GN1: cmp ah,byte ptr [si] . trong keyboard buffer). 8.3.2Kiểm tra keyboard buffer Input : AH = 01 Output : ZF = 1 : không có phím nào trong keyboard buffer. ZF = 0 : đã có phím trong keyboard. defaults and continue scanning. v 0F5h : Set keyboard to defaults and disable keyboard scanning. v 0F4h : Enable the keyboard. KBD sends ‘ACK’, clears buffer,