AOA 20.pdf

(380 KB) Pobierz
Microsoft Word - AOA20.doc
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
WYŁĄCZNOŚĆ DO PUBLIKOWANIA TEGO TŁUMACZENIA
POSIADA RAG
HTTP://WWW.R-AG.PRV.PL
„THE ART OF ASSEMBLY LANGUAGE
tłumaczone by KREMIK
Konsultacje naukowe: NEKRO
wankenob@priv5.onet.pl
nekro@pf.pl
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
ROZDZIAŁ DWUDZIESTY : KLAWIATURA PC
Klawiatura PC jest podstawowym ludzkim urządzeniem wejściowym w systemie. Chociaż wydaje się raczej
przyziemna, klawiatura jest podstawowym urządzeniem wejściowym dla większości programów, więc
nauczenie się jak oprogramować właściwie klawiaturę jest bardzo ważne w rozwijaniu aplikacji.
IBM i niezliczone wytwórnie klawiatur produkują liczne klawiatury dla PC i kompatybilnych. Większość
nowoczesnych klawiatur dostarcza przynajmniej 101 różnych klawiszy i są umiarkowanie kompatybilne z 101
Klawiszową rozszerzoną Klawiaturą IBM PC / AT. Te które dostarczają dodatkowych klawiszy ogólnie
programują te klawisze do emitowania sekwencji uderzeń klawiszy lub pozwalają użytkownikowi
oprogramować sekwencję uderzeń w klawisze dodatkowych klawiszy. Ponieważ 101 klawiszowa klawiatura
jest wszechobecna, zakładamy, że używamy jej w tym rozdziale.
Kiedy IBM rozwijał pierwszy PC, używali bardzo prostego sprzęgu pomiędzy klawiaturą a
komputerem. Kiedy IBM wprowadził PC/AT, zupełnie przeprojektowali interfejs klawiatury. Od czasu
wprowadzenia PC/AT, prawie każda klawiatura jest dostosowana do standardu PC/AT. Nawet kiedy IBM
wprowadził system PS/2, zmiany w interfejsie klawiatury i zgodna oddolnie z projektem PC/AT. Dlatego też,
rozdział ten będzie również ograniczony do urządzeń kompatybilnych z PC/AT ponieważ tylko kilka systemów i
klawiatur PC/XT jest jeszcze w użyciu.
Jest pięć głównych elementów klawiatury jakie będziemy rozpatrywać w tym rozdziale – podstawowe
informacje o klawiaturze, interfejs DOS, interfejs BIOS, podprogram obsługi przerwania klawiatury int 9 i
sprzętowy interfejs do klawiatury. Ostatnia sekcja tego rozdziału bezie omawiała jak udawać wejście klawiatury
w naszych aplikacjach.
20.1 PODSTAWY KLAWIATURY
Klawiatura PC jest komputerem systemowym w swoim własnym rozumieniu. Ukryto wewnątrz
klawiatury chip mikrokontrolera 8042, który stale skanuje przełączniki klawiatury aby sprawdzić czy naciśnięto
jakiś klawisz. Ten proces pracuje równolegle z normalną działalnością PC, dlatego klawiatura nigdy nie gubi
naciśniętego klawisza jeśli 80x86 w PC jest zajęty.
Typowo uderzenie w klawiaturę zaczyna się kiedy użytkownik naciśnie klawisz na klawiaturę. To
zamyka elektryczny kontakt w przełączniku mikrokontroler i wskazuje ,że naciśnięto przełącznik. Niestety ,
przełączniki (będące mechanicznymi rzeczami) nie zawsze zamykają (mają kontakt) tak gładko. Często,
kontakty odbijają się kilka razy zanim przejdą do stałego kontaktu. Jeśli chip mikrokontrolera odczyta stały
przełącznik, to odbijanie się kontaktów będzie wyglądało jak bardzo szybka seria naciśnięć klawisza i zwolnień.
To może generować wielokrotne naciśnięcia klawiszy na głównym komputerze, zjawisko znane jako odbijanie
klawisza, powszechne w wielu tanich i starych klawiaturach. Ale nawet na droższych i nowszych klawiaturach
odbijanie klucza jest problemem jeśli popatrzymy na przełączniki milion razy na sekundę; mechaniczne
przełączniki nie mogą po prostu uspokoić się tak szybko. Dlatego wiele algorytmów skanowania klawiatury
kontroluje jak często skanowana jest klawiatura. Typowy niedrogi klawisz będzie uspokajał się w ciągu pięciu
milisekund, więc jeśli oprogramowanie skanujące klawiaturę przygląda się temu klawiszowi co dziesięć
milisekund, więc kontroler będzie faktycznie gubił odbijanie klawisza.
Zanotujmy, ze naciśnięty klawisz nie jest wystarczającym powodem generowaniem kodu klawisza.
Użytkownik może przetrzymać naciśnięty klawisz wiele dziesiątków milisekund nim go zwolni. Sterownik
klawiatury nie musi generować owej sekwencji klawisza za każdym razem kiedy skanuje klawiaturę i znajduje
wciśnięty klawisz. Zamiast tego, powinien wygenerować pojedynczą wartość kodu klawisza kiedy klawisz
zmienia pozycję z górnej na dolną (operacja naciśnięcia) Po wykryciu, wciśniętego klawisza, mikrokontroler
wysyła kod klawisza do PC. Kod klawisza nie odnosi się do kodu ASCII dla tego klawisza, jest to wartość jaką
wybrał IBM kiedy po raz pierwszy zaprojektował klawiaturę dla PC.
 
Klawiatura PC w rzeczywistości generuje dwa kody klawisza dla każdego naciśniętego klawisza.
Generuje kod dolny, kiedy klawisz jest naciśnięty i kod górny, kiedy zwalniamy klawisz. Chip mikrokontrolera
8042 przekazuje te kody klawisza do PC, gdzie są przetwarzane przez podprogram obsługi przerwań
klawiaturowych. Posiadanie oddzielnego kodu dolnego i górnego jest ważne ponieważ pewne klawisze (takie jak
shift, control i alt) mają znaczenie tylko jeśli są wciśnięte. Poprzez generowanie górnych kodów dla wszystkich
klawiszy, klawiatura zapewnia ,że podprogram obsługi przerwań klawiaturowych wie jakie klawisze naciśnięto
podczas gdy użytkownik trzyma wciśnięty jeden z tych klawiszy. Poniższa tablica pokazuje kody klawiszy, jakie
mikrokontroler przekazuje do PC:
Klawisz Dół Góra Klawisz Dół Góra Klawisz Dół Góra
Klawisz
Dół Góra
Esc
1
81
[{
1A
9A
, <
33
B3
center
4C
CC
1 !
2
82
]}
1B
9B
. >
34
B4
right
4D
CD
2 @
3
83 Enter 1C
9C
/ ?
35
B5
+
4E
CE
3 #
4
84
Ctrl
1D
9D
R shift
36
B6
end
4F
CF
4 $
5
85
A
1E
9E
*PrtScr
37
B7
down
50
D0
5 %
6
86
S
1F
9F
alt
38
B8
pgdn
51
D1
6 ^
7
87
D
20
A0
Space
39
B9
ins
52
D2
7 &
8
88
F
21
A1
CAPS
3A
BA
del
53
D3
8 *
9
89
G
22
A2
F1
3B
BB
/
E0 35 B5
9 (
0A 8A
H
23
A3
F2
3C
BC
enter
E0 1C 9C
0 )
0B
8B
J
24
A4
F3
3D
BD
F11
57
D7
- _
0C
8C
K
25
A5
F4
3E
BE
F12
58
D8
= +
0D 8D
L
26
A6
F5
3F
BF
ins
E0 52 D2
Bksp
0E
8E
; :
27
A7
F6
40
C0
del
E0 53 D3
Tab
0F
8F
‚ „
28
A8
F7
41
C1
home
E0 47 C7
Q
10
90
` ~
29
A9
F8
42
C2
end
E0 4F CF
W
11
91 L shift 2A AA
F9
43
C3
pgup
E0 49 C9
E
12
92
\ |
2B
AB
F10
44
C4
pgdn
E0 51 D1
R
13
93
Z
2C
AC
NUM
45
C5
left
E0 4B CB
T
14
94
X
2D AD
SCRL
46
C6
right
E0 4D CD
Y
15
95
C
2E
AE
home
47
C7
up
E0 48 C8
U
16
96
V
2F
AF
up
48
C8
down
E0 50 D0
I
17
97
B
30
B0
pgup
49
C9
R alt
E0 38 B8
O
18
98
N
31
B1
-
4A
CA
R ctrl
E0 1D 9D
P
19
99
M
32
B2
Lefy
4B
CB
Pause
E1 D1
45 E1
9D C5
-
Tablica 72: Kody klawiszy klawiatury PC (w hex)
Klawisze pogrubioną czcionką są to klawisze z klawiatury numerycznej. Zauważmy ,że pewne klawisze
przekazują dwa lub więcej kodów klawiszy do systemu. Klucze które przekazują więcej niż jeden kod klawisza
to nowe klawisze, dodane kiedy IBM zaprojektował 101 klawiszową rozszerzoną klawiaturę.
Kiedy kod klawisza przychodzi do PC, drugi mikrokontroler odbiera ten k0d, konwertuje na kod
klawisza, robi go dostępnym na porcie I/O 60h a potem wysyła przerwanie do procesora a potem zostawia go w
ISR’ze klawiatury pobierającym kod klawisza z portu I/O.
Podprogram obsługi przerwań klawiaturowych (int 9) odczytuje kod klawisza z portu wejściowego
klawiatury i odpowiednio przetwarza ten kod klawisza. Zauważmy, że kod klawisza system odbiera z
mikrokontrolera klawiatury jako pojedynczą wartość, pomimo, że pewne klawisze reprezentują do czterech
różnych wartości. Na przykład klawisz „A” na klawiaturze może stworzyć A, a, ctrl-A lub alt-A. Rzeczywisty
kod w systemie zależy od bieżącego stanu klawiszy modyfikujących (shift, ctrl, alt, capslock i numlock). NA
przykład, jeśli kod klawisza A nadchodzi jako (1Eh) i jest wciśnięty klawisz shift, system tworzy kod ASCII dla
dużej litery. Jeśli użytkownik naciśnie wiele klawiszy modyfikujących , system zadziała według priorytetów od
najniższego do najwyższego jak następuje:
• Żaden klawisz modyfikujący nie wciśnięty
• Numlock / Capslock (takie samo pierwszeństwo, najniższy priorytet)
• Shift
• Ctrl
21856001.002.png
• Alt (najwyższy priorytet)
Numlock i Capslock wpływają na różne zbiory klawiszy, więc nie ma żadnych niejasności wynikających z ich
równego pierwszeństwa w powyższym zestawieniu. Jeśli użytkownik naciśnie dwa klawisze modyfikujące w
tym samym czasie, system rozpozna tylko klawisz modyfikujący o najwyższym priorytecie. Na przykład, jeśli
użytkownik naciśnie klawisze cytr i alt, system rozpozna tylko klawisz alt. Klawisze numlock, capslock i shift są
specjalnymi przypadkami. Jeśli numlock lub capslock są aktywne, naciśnięcie shift uczyni je nieaktywnymi.
Podobnie jeśli numlock lub capslock są nieaktywne, naciśnięcie klawisza shift skutecznie „aktywuje” te
modyfikatory.
Nie wszystkie modyfikatory są poprawne dla każdego klawisza. Na przykład ctrl – 8 jest niepoprawną
kombinacją. Podprogram obsługi przerwania klawiaturowego zignoruje wszystkie kombinacje naciśnięć
klawiszy z niepoprawnymi klawiszami modyfikującymi. Z nieznanych powodów IBM zadecydował o
uczynieniu pewnych kombinacji poprawnymi a innych niepoprawnymi. Na przykład ctrl – left i ctrl - right są
poprawne ale ctrl – up i ctrl –down już nie. Jak poprawić ten problem zobaczymy trochę później.
Klawisze shift, alt i ctrl są aktywnymi modyfikatorami. To znaczy, modyfikacja naciśniętego klawisza
wystąpi tylko, kiedy użytkownik trzyma wciśnięty jeden z tych klawiszy modyfikujących. ISR klawiatury śledzi
czy klawisze te są wciśnięte czy nie. Przeciwnie, klawisze numlock, scroll lock i capslock są modyfikatorami
przełączającymi. ISR klawiaturowy odwraca powiązane bity za każdym razem kiedy widzi dolny kod
następujący po kodzie górnym, dla tych klawiszy.
Większość klawiszy klawiatury PC odpowiada znakom ASCII. Kiedy ISR klawiaturowy napotka taki
znak, tłumaczy go na 16 bitową wartość, której najmniej znaczący bajt jest kodem ASCII a bardziej znaczący
bajt kodem klawiaturowym klawisza. Na przykład, naciskając „A”, bez modyfikatora, z shift i z control
tworzymy odpowiednio 1E61h, 1E41h i 1E01h, („a”, „A” i ctrl-A) Wiele sekwencji klawiszy nie ma
odpowiedników kodów ASCII. Na przykład klawisze funkcyjne, klawisz sterujący kursorem i sekwencja
klawisza alt nie mają odpowiedników kodów ASCII. Dla tych specjalnych, rozszerzonych kodów, ISR
klawiaturowy przechowuje zero w mnij znaczącym bajcie (gdzie zazwyczaj jest kod ASCII) a rozszerzony kod
idzie do bardziej znaczącego bajtu. Kod rozszerzony jest zazwyczaj, chociaż z pewnością nie zawsze, kodem
klawiaturowym dla tego klawisza.
Jedyny problem z kodem rozszerzonym jest taki, że wartość zero jest poprawnym znakiem ASCII (
znak NUL). Dlatego też nie możemy bezpośrednio wprowadzić znaku NUL do aplikacji. Jeśli aplikacja musi
wprowadzić znak NUL, IBM ma zarezerwowane miejsce w pamięci dla rozszerzonego kodu 0300h (ctrl-3) .
Aplikacja wyraźnie musi skonwertować ten rozszerzony kod do znaku NUL (w rzeczywistości tylko rozpoznać
bardziej znaczący bajt wartości 03 ponieważ najmniej znaczący bajt jest już znakiem NUL). Na szczęście,
bardzo niewiele programów musi zezwalać na wprowadzanie znaku NUL z klawiatury, więc ten problem jest
rzadkością.
Następująca tablica pokazuje kod klawiaturowy i rozszerzony ISR klawiaturowego generowane dla
aplikacji w odpowiedzi na naciśnięcie klawisza z różnymi modyfikatorami Kody rozszerzone są pogrubione.
Wszystkie wartości ( z wyjątkiem kolumny kodów klawiaturowych) przedstawiają osiem najmniej znaczących
bitów 16 bitowego kodu. Bardziej znaczący bajt pochodzi z kolumny kodów klawiaturowych.
Klawisz
Kod
klawiaturowy
ASCII
Shift
Ctrl
Alt
Num
Caps
Shift
Caps
Shift
Num
Esc
01
1B
1B
1B
1B
1B
1B
1B
1 !
02
31
21
7800
31
31
31
31
2 @
03
32
40
0300
7900
32
32
32
32
3 #
04
33
23
7A00
33
33
33
33
4 $
05
34
24
7B00
34
34
34
34
5 %
06
35
25
7C00
35
35
35
35
6 ^
07
36
5E
1E
7D00
36
36
36
36
7 &
08
37
26
7E00
37
37
37
37
8 *
09
38
2A
7F00
38
38
38
38
9 (
0A
39
28
8000
39
39
39
39
0 )
0B
30
29
8100
30
30
30
30
- _
0C
2D
5F
1F
8200
2D
2D
5F
5F
= +
0D
3D
2B
8300
3D
3D
2B
2B
Bksp
0E
08
08
7F
08
08
08
08
Tab
0F
09
0F00
09
09
0F00
0F00
Q
10
71
51
11
1000
71
51
71
51
W
11
77
57
17
1100
77
57
77
57
21856001.003.png
E
12
65
45
05
1200
65
45
65
45
R
13
72
52
12
1300
72
52
72
52
T
14
74
54
14
1400
74
54
74
54
Y
15
79
59
19
1500
79
59
79
59
U
16
75
55
15
1600
75
55
75
55
I
17
69
49
09
1700
69
49
69
49
O
18
6F
4F
0F
1800
6F
4F
6F
4F
P
19
70
50
10
1900
70
50
70
50
[{
1A
5B
7B
1B
5B
5B
7B
7B
]}
1B
5D
7D
1D
5D
5D
7D
7D
enter
1C
0D
0D
0A
0D
0D
0A
0A
ctrl
1D
A
1E
61
41
01
1E00
61
41
61
41
S
1F
73
53
13
1F00
73
53
73
52
D
20
64
44
04
2000
64
44
64
44
F
21
66
46
06
2100
66
46
66
46
G
22
67
47
07
2200
67
47
67
47
H
23
68
48
08
2300
68
48
68
48
J
24
6A
4A
0A
2400
6A
4A
6A
4A
K
25
6B
4B
0B
2500
6B
4B
6B
4B
L
26
6C
4C
0C
2600
6C
4C
6C
4C
; :
27
3B
3A
3B
3B
3A
3A
‘ “
28
27
22
27
27
22
22
` ~
29
60
7E
60
60
7E
7E
Lshift
2A
\ |
2B
5C
7C
1C
5C
5C
7C
7C
Z
2C
7A
5A
1A
2C00
7A
5A
7A
5A
X
2D
78
58
18
2D00
78
58
78
58
C
2E
63
43
03
2E00
63
43
63
43
V
2F
76
56
16
2F00
76
56
76
56
B
30
62
42
02
3000
62
42
62
42
N
31
6E
4E
0E
3100
6E
4E
6E
4E
M
32
6D
4D
0D
3200
6D
4D
6D
4D
, <
33
2C
3C
2C
2C
3C
3C
. >
34
2E
3E
2E
2E
3E
3E
/ ?
35
2F
3F
2F
2F
3F
3F
Rshift
36
* PrtSc
37
2A
INT 5
10
2A
2A
INT 5
INT 5
alt
38
space
39
20
20
20
20
20
20
20
caps
3a
F1
3B
3B00
5400
5E00
6800
3B00
3B00
5400
5400
F2
3C
3C00
5500
5F00
6900
3C00
3C00
5500
5500
F3
3D
3D00
5600
6000
6A00
3D00
3D00
5600
5600
F4
3E
3E00
5700
6100
6B00
3E00
3E00
5700
5700
F5
3F
3F00
5800
6200
6C00
3F00
3F00
5800
5800
F6
40
4000
5900
6300
6D00
4000
4000
5900
5900
F7
41
4100
5A00
6400
6E00
4100
4100
5A00
5A00
F8
42
4200
5B00
6500
6F00
4200
4200
5B00
5B00
F9
43
4300
5C00
6600
7000
4300
4300
5C00
5C00
F10
44
4400
5D00
6700
7100
4400
4400
5DD0
5D00
num
45
scrl
46
home
47
4700
37
7700
37
4700
37
4700
up
48
4800
38
38
4800
38
4800
pgup
49
4900
39
8400
39
4900
39
4900
-
4A
2D
2D
2D
2D
2D
2D
left
4B
4B00
34
7300
34
4B00
34
4B00
21856001.004.png
center
4C
4C00
35
35
4C00
35
4C00
right
4D
4D00
36
7400
36
4D00
36
4D00
+
4E
2B
2B
2B
2B
2B
2B
end
4F
4F00
31
7500
31
4F00
31
4F00
down
50
5000
32
32
5000
32
5000
pgdn
51
5100
33
7600
33
5100
33
5100
ins
52
5200
30
30
5200
30
5200
del
53
5300
2E
2E
5300
2E
5300
Tablica 73: Kody klawiatury (w hex)
Klawiatura 101 klawiszowa ogólnie rzecz biorąc dostarcza klawisza enter i „/” w bloku klawiatury
numerycznej. Chyba, że piszemy własny ISR klawiaturowy int 9, wtedy nie będziemy mogli rozróżniać tych
klawiszy od klawiszy z klawiatury głównej. Oddzielny blok sterowania kursorem również generuje taki sam
kod rozszerzony co blok numeryczny, z wyjątkiem tego ,że nigdy nie generuje numerycznego kodu ASCII. W
przeciwnym razie, nie możemy rozróżnić klawiszy z odpowiadającymi klawiszami na klawiaturze numerycznej
(zakładając oczywiście, że numlock jest wyłączony).
ISR klawiaturowy dostarcza specjalnej umiejętności, która pozwala nam wprowadzać kod ASCII dla
wciskanych klawiszy bezpośrednio z klawiatury. Robiąc to wciskamy klawisz alt i wpisujemy dziesiętny kod
ASCII (0..255) dla znaku z klawiatury numerycznej. ISR klawiaturowy skonwertuje to naciśnięcie klawisza na
ośmiobitową wartość, dokładając zero w bardziej znaczącym bajcie do znaku i używa tego jako kodu znaku.
ISR klawiaturowy wprowadza 16 bitową wartość do bufora roboczego PC Systemowy bufor roboczy
jest cykliczną kolejką która używa następujących zmiennych:
40:1A - HeadPtr
word ?
40:1C - TailPtr
word ?
40:1E - Buffer
word 16 dup (?)
ISR klawiaturowy wprowadza dane pod lokację wskazywaną przez TailPtr. Funkcja klawiaturowa
BIOS usuwa znaki z lokacji wskazywanej przez zmienną HeadPtr. Te dwa wskaźniki prawie zawsze zawierają
offset tablicy Buffer. Jeśli te dwa wskaźniki są równe, bufor roboczy jest pusty. Jeśli wartość w HeadPtr jest
dwa razy większa niż wartość w TailPtr (lub HeadPtr zawiera 1Eh a TailPtr 3Ch) wtedy bufor jest pełny a ISR
klawiaturowy będzie odrzucał dodatkowe naciskania klawiszy.
Zauważmy, że zmienna TailPtr zawsze wskazuje następną dostępną lokację w buforze roboczym.
Ponieważ nie ma zmiennej„licznik” dostarczającej liczby wejść w buforze, musimy zawsze zostawić jedno
wolne wejście w obszarze bufora; to oznacza, że bufor roboczy może przechowywać tylko 15 a nie 16 naciśnięć
klawisza.
Oprócz bufora roboczego, BIOS utrzymuje kilka innych zmiennych powiązanych z klawiaturą w
segmencie 40h. Poniższa tablica pokazuje te zmienne i ich zawartość:
Nazwa
Adres
Rozmiar
Opis
KbdFlags1
(flagi modyfikatorów)
40:17
Bajt
Bajt ten utrzymuje bieżący stan klawiszy
modyfikujących na klawiaturze. Bity
mają następujące znaczenie:
bit 7: wprowadzono tryb przełączania
bit 6: przełączony Capslock (1 =
włączony)
bit 5: przełączenie Numlock (1 =
włączony)
bit 4: przełączony Scroll lock (1 =
włączony)
bit 3: klawisz Alt (1 = wciśnięty)
bit 2: klawisz Ctrl (1 = wciśnięty)
bit 1: Lewy shift (1 = włączony)
bit 0: prawy shift (1 = włączony)
KbdFlags2
40:18
Bajt
Określa czy przełączany klawisz jest
obecnie w dole
bit 7: Klawisz Insert (w dole jeśli 1
bit 6: Klawisz Capslock (jak wyżej)
bit 5:Klawisz Numlock (jak wyżej)
bit 4: Klawisz Scroll lock (jak wyżej)
bit 3: Stan pauzy (ctrl+Numlock) jeśli 1
bit 2: Klawisz SysReq (jak wyżej)
bit 1: Klawisz lewy alt (jak wyżej)
bit 0: Klawisz lewy ctrl (jak wyżej)
21856001.001.png
Zgłoś jeśli naruszono regulamin