Итак, двигаемся дальше. Буквы в терминале - хорошо, красивая картинка на экране - ещё лучше! Но хочется какого-то интерактива. И вот здесь не всё так просто, как хотелось бы. Но об этом чуть ниже. А пока предлагаю вам текст короткой программы, которая опрашивает клавиатуру и выводит в терминал код нажатой клавиши:
Результат работы программы:Код:org 0x6001000 blx start thumb start: ; Опрашиваем клавиатуру movw r0,0x6004 ; Keyboard Status Register movt r0,0x1000 ldrb r1,[r0] and r1,0x10 cmp r1,0x10 bne finish movw r0,0x6008 ; Keyboard Data movt r0,0x1000 ldrb r1,[r0] and r1,0xff ; Преобразуем байт в ASCII-строку в HEX-представлении adr r2,key_code+1 mov r3,2 mov r0,r1 hex_convert: and r1,0xf cmp r1,0xa addcs r1,0x7 add r1,0x30 strb r1,[r2] sub r2,1 lsr r1,r0,4 subs r3,1 bne hex_convert ; Выводим строку в консоль movw r0,0x9000 ; Адрес консоли 0x10009000 movt r0,0x1000 ldrb r1,[key_code] strb r1,[r0] ldrb r1,[key_code+1] strb r1,[r0] ldrb r1,[key_code+2] strb r1,[r0] finish: b start key_code: db "00 "
В эмулируемом компьютере клавиатура подключена с помощью MMIO (Memory-mapped I/O) контроллера PL050, порты которого смотрят прямо в память, а базовым является адрес 0x10006000:
Address Type Description Base + 0x00 rw Control register. Base + 0x04 r Status register. Base + 0x08 rw Received data (read)/ Data to be transmitted (write). Base + 0x0c rw Clock divisor register. Base + 0x10 r Interrupt status register.
А это значения битов статусного регистра:
Bits Name Description 0 KMID This bit reflects the status of the KMIDATAIN line after synchronizing. 1 KMIC This bit reflects the status of the KMICLKIN line after synchronizing and sampling. 2 RXPARITY This bit reflects the parity bit for the last received data byte (odd parity). 3 RXBUSY This bit indicates that the PrimeCell KMI is currently receiving data. 0 = idle, 1 = receiving data. 4 RXFULL This bit indicates that the receiver register is full and ready to be read. 0 = receive register empty, 1 = receive register full, ready to be read. 5 TXBUSY This bit indicates that the PrimeCell KMI is currently sending data. 0 = idle, 1 = currently sending data. 6 TXEMPTY This bit indicates that the transmit register is empty and ready to transmit. 0 = transmit register full, 1 = transmit register empty, ready to be written. 7 - Reserved. Read unpredictable.
Здесь используется стандартный набор 2 скан-кодов AT-клавиатуры:
PS/2 keyboard scan codes (scan code set 2)
KEY MAKE BREAK ----- KEY MAKE BREAK ----- KEY MAKE BREAK A 1C F0,1C 9 46 F0,46 [ 54 FO,54 B 32 F0,32 ` 0E F0,0E INSERT E0,70 E0,F0,70 C 21 F0,21 - 4E F0,4E HOME E0,6C E0,F0,6C D 23 F0,23 = 55 FO,55 PG UP E0,7D E0,F0,7D E 24 F0,24 \ 5D F0,5D DELETE E0,71 E0,F0,71 F 2B F0,2B BKSP 66 F0,66 END E0,69 E0,F0,69 G 34 F0,34 SPACE 29 F0,29 PG DN E0,7A E0,F0,7A H 33 F0,33 TAB 0D F0,0D U ARROW E0,75 E0,F0,75 I 43 F0,43 CAPS 58 F0,58 L ARROW E0,6B E0,F0,6B J 3B F0,3B L SHFT 12 FO,12 D ARROW E0,72 E0,F0,72 K 42 F0,42 L CTRL 14 FO,14 R ARROW E0,74 E0,F0,74 L 4B F0,4B L WIN E0,1F E0,F0,1F NUM 77 F0,77 M 3A F0,3A L ALT 11 F0,11 KP / E0,4A E0,F0,4A N 31 F0,31 R SHFT 59 F0,59 KP * 7C F0,7C O 44 F0,44 R CTRL E0,14 E0,F0,14 KP - 7B F0,7B P 4D F0,4D R WIN E0,27 E0,F0,27 KP + 79 F0,79 Q 15 F0,15 R ALT E0,11 E0,F0,11 KP EN E0,5A E0,F0,5A R 2D F0,2D APPS E0,2F E0,F0,2F KP . 71 F0,71 S 1B F0,1B ENTER 5A F0,5A KP 0 70 F0,70 T 2C F0,2C ESC 76 F0,76 KP 1 69 F0,69 U 3C F0,3C F1 05 F0,05 KP 2 72 F0,72 V 2A F0,2A F2 06 F0,06 KP 3 7A F0,7A W 1D F0,1D F3 04 F0,04 KP 4 6B F0,6B X 22 F0,22 F4 0C F0,0C KP 5 73 F0,73 Y 35 F0,35 F5 03 F0,03 KP 6 74 F0,74 Z 1A F0,1A F6 0B F0,0B KP 7 6C F0,6C 0 45 F0,45 F7 83 F0,83 KP 8 75 F0,75 1 16 F0,16 F8 0A F0,0A KP 9 7D F0,7D 2 1E F0,1E F9 01 F0,01 ] 5B F0,5B 3 26 F0,26 F10 09 F0,09 ; 4C F0,4C 4 25 F0,25 F11 78 F0,78 ' 52 F0,52 5 2E F0,2E F12 07 F0,07 , 41 F0,41 6 36 F0,36 PRNT
SCRNE0,12,
E0,7CE0,F0,
7C,E0,
F0,12. 49 F0,49 7 3D F0,3D SCROLL 7E F0,7E / 4A F0,4A 8 3E F0,3E PAUSE E1,14,77,
E1,F0,14,
F0,77-NONE- [свернуть]
То есть каждая клавиша имеет скан-коды для нажатия (make) и для отпускания (break). Так, при нажатии клавиши "A" мы получаем скан-код 0x1C, и продолжаем получать его вплоть до отпускания клавиши. А в момент отпускания генерируется двухбайтный скан-код 0xF0, 0x1C.
Теперь для тренировки вы можете попробовать подправить программу таким образом, чтобы она выводила не скан-код клавиши, а непосредственно её значение.





Ответить с цитированием