-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathKBDINP.INC
214 lines (192 loc) · 3.34 KB
/
KBDINP.INC
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
;--- poll keyboard ( US/GR key layout )
ifndef KEYS
KEYS textequ <KBD_US>
endif
;*** keyboard BIOS variables
KBDSTAT equ 417h
BUFSTA equ 41Ah
BUFEND equ 41Ch
EBUFSTA equ 480h
EBUFEND equ 482h
.data
lastk db 0
% include KEYS.inc
cntlkeystab label byte
db 36h ;R-SH ;codes ctrl keys
db 2Ah ;L-SH ;order matches bits in 0040h:0017h
db 1Dh ;CTRL
db 38h ;ALT
db 46h ;SCROLL lock;10
db 45h ;NUM lock ;20
db 3Ah ;CAPS ;40
db 52h ;INS ;80
LCTLKEYS equ $ - offset cntlkeystab
.CODE
;*** get kbd state
;*** ZERO? if no key available
GetKbdStatus proc
pushf
pop ax
test ah, 2 ; IF set?
jz @F
in al, 21h
test al, 2 ; IRQ 1 enabled?
jnz @F
mov al, 0Bh
out 20h, al
in al, 20h
test al, 03h ; irq 0 or irq 1 request?
jz nopoll
@@:
in al, 64h
test al, 01h ; input buffer full?
jz nokey
mov ah, al
in al, 60h
test ah, 20h ; is it input from PS/2?
jnz nokey
call setkbdbiosvars ; set kbd BIOS variables
mov [lastk], al
jc nokey
cmp al,80h
jnc nokey
ret
nokey:
xor al,al
ret
nopoll:
push ax
push ds
mov ds, cs:[wFlat]
mov ax,ds:[BUFSTA] ; char in buffer?
cmp ax,ds:[BUFEND]
pop ds
pop ax
ret
GetKbdStatus endp
;--- set kbd status bios variable
;--- used only if interrupts disabled
setkbdbiosvars proc
pusha
push ds
push es
mov es, cs:[wKDDS]
mov ds, cs:[wFlat]
mov bh,al ;check if ctrl, shift, alt, ...
and al,7fh
mov di,offset cntlkeystab
mov bl,00
mov cx, LCTLKEYS
repnz scasb
jnz nostd
mov bl,80h
shr bl,cl
mov ch,bh
; and byte ptr ds:[KBDSTAT+1],not 4 ;reset Sys-Req
mov ax, ds:[KBDSTAT]
and ah, not 4 ; reset sys-req
test ch, 80h ; key released or pressed?
jz @F
xor bl,0FFh
and al,bl ; reset flag
and ah,bl
jmp setflags
@@:
or al,bl ; set flag
or ah,bl ; set flag
setflags:
cmp cl,4 ; RSHIFT,LSHIFT,CTRL,ALT?
jnb @F
mov ds:[KBDSTAT+1],ah
xor ds:[KBDSTAT],ah
jmp donestat
@@:
mov ds:[KBDSTAT],al
donestat:
and ch,7Fh
cmp ch,38h ;Alt key?
jnz @F
cmp cs:[lastk],0E0h ;last key 0E0?
jnz @F
and byte ptr ds:[496h],not 8 ;AltGr
and ah,08
or ds:[496h],ah
@@:
cmp ch,52h ;INSERT IS a key!
jz nostd
pop es
pop ds
popa
stc
RET
nostd:
pop es
pop ds
popa
clc
ret
setkbdbiosvars endp
; *** get char from KBD without wait
GetKbdChar proc
call GetKbdStatus
jz nokey
mov al,[lastk]
test al,80h
jnz nokey ;key released, no further processing
cmp al,39h ;space?
jz isspace
cmp al,56h
ja getkbdxchar
jb @F
mov al,36h ; 56 -> 36
@@:
cmp al,36h
ja getkbdxchar
push ds
mov ds, cs:[wFlat]
mov bx, offset normalk
mov ah, ds:[KBDSTAT]
test ah,3 ;shift pressed
jz @F
mov bx, offset shiftk
@@:
test ah,4 ;ctrl pressed?
jz @F
mov bx, offset ctrlk
@@:
test ah,8 ;alt pressed?
jz @F
test byte ptr ds:[496h],8 ;AltGr pressed?
jz getkbdxchar2
mov bx, offset altgrk
@@:
pop ds
movzx ax,al
add bx, ax
mov bl,byte ptr [bx]
and bl,bl
jz getkbdxchar
mov al,bl
ret
isspace:
mov ah,al
mov al,' '
ret
getkbdxchar2:
pop ds
getkbdxchar:
mov ah,al
mov al,00
ret
nokey:
xor ax,ax
ret
GetKbdChar endp
;--- loop to wait for a char
KbdGetChar proc uses bx
@@:
call GetKbdChar
and ax,ax
jz @B
ret
KbdGetChar endp