-
Notifications
You must be signed in to change notification settings - Fork 5
/
keyrst.386
277 lines (214 loc) · 6.74 KB
/
keyrst.386
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
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
;***************************************************************************
;
; Copyright (c) 1997, 1998 Timpanogas Research Group, Inc. All Rights
; Reserved.
;
; AUTHOR : Jeff V. Merkey
; FILE : KEYBRST.386
; DESCRIP : Loader Keyboard Reset Code for MANOS v1.0
; DATE : August 27, 1998
;
;***************************************************************************
.486P ; select the processor
model flat
include hal.inc
CGROUP GROUP _TEXT
DGROUP GROUP _DATA
ASSUME cs:_TEXT, ds:_DATA, es:_DATA, fs:_DATA
_DATA SEGMENT DWORD PUBLIC USE32 'DATA'
;************************************************************************
;
; The following equates are for the hardware handling code.
; 8042 Status Byte, Port Hex 0064 Read
;
;************************************************************************
STATUSPORT EQU 64h
COMMANDPORT EQU 64h
DATAPORT EQU 60h
PARITYERROR EQU 10000000b
GENERALTIMEOUT EQU 01000000b
AUXOUTBUFFFULL EQU 00100000b
INHIBITSWITCH EQU 00010000b
COMMANDDATA EQU 00001000b
SYSTEMFLAG EQU 00000100b
INPUTBUFFFULL EQU 00000010b
OUTPUTBUFFFULL EQU 00000001b
RESET_KEYBOARD EQU 0FFh
KEYBOARD_OVERRUN EQU 0FFh
BAT_COMPLETE EQU 0AAh
_DATA ENDS
_TEXT SEGMENT DWORD PUBLIC USE32 'CODE'
ASSUME cs:_TEXT, ds:_DATA, es:_DATA, fs:_DATA
;************************************************************************
;
; This sets the Keyboard Scan Set to #2 with 8042 interpretation ON
;
;************************************************************************
align 16
public ResetKeyboard
ResetKeyboard proc
pushad
pushfd
cli
in al, 21h
or al, 2
out 21h, al ; mask IRQ 1
call KeyboardDisable
mov al, RESET_KEYBOARD
out DATAPORT, al
mov ecx, 200
BATStatusLoop:
dec ecx
jz BATTimeOut
call OutBuffFull
in al, DATAPORT
cmp al, BAT_COMPLETE
jne BATStatusLoop
BATTimeOut:
call KeyboardEnable
mov edi, 417h ; BIOS Keyboard Data Area is Reset
xor eax, eax ; zero control flags
stosb ; keyboard control and state flags
stosb ; are at 40:17h thru 40:19h
stosb ; zero flags
;
; keyboard head/tail are at 40:1Ah (head) and
; 40:1Ch (tail). reset pointers
;
lea esi, [edi + 2] ; get head in eax and write
lodsw ; to tail pointer
stosw
call InBuffEmpty ; Wait for Input Buffer to Empty
mov al, 0FAh ; Set ALL keys typematic/make/break
out DATAPORT, al ; Send Command to KBD (not 8042)
call OutBuffFull ; Eat response
in al, DATAPORT
call InBuffEmpty ; Wait for Input Buffer to Empty
mov al, 0F0h ; Set Scan code set
out DATAPORT, al ; Send Command to KBD (not 8042)
call OutBuffFull ; Eat response
in al, DATAPORT
call InBuffEmpty ; Wait for Input Buffer to Empty
mov al, 02h ; Scan set 2
out DATAPORT, al ; Send Command
call OutBuffFull ; Eat response
in al, DATAPORT
call InBuffEmpty ; Wait for Input Buffer to Empty
mov al, 060h ; Set up to write 8042 command byte
out COMMANDPORT, al ; Send Command
call InBuffEmpty ; Wait for Input Buffer to Empty
mov al, 45h ; Enable IBM Xlate
out DATAPORT, al ; Send Command
call SetKeyboardLEDs
in al, 21h
and al, NOT 2
out 21h, al ; unmask irq1
popfd
popad
ret
ResetKeyboard endp
;************************************************************************
;
; This tells the 8042 Controller to Disable the Keyboard device.
;
;************************************************************************
align 16
public KeyboardDisable
KeyboardDisable proc
push eax
call InBuffEmpty ; Wait for Input Buffer to Empty
mov al, 0ADh ; Set Command to "Write the 8042 Command Byte"
out COMMANDPORT, al ; Send Command
call InBuffEmpty ; Wait for Input Buffer to Empty
pop eax
ret
KeyboardDisable endp
;************************************************************************
;
; This tells the 8042 Controller to Enable the Keyboard Device.
;
;************************************************************************
align 16
public KeyboardEnable
KeyboardEnable proc
call InBuffEmpty ; Wait for Input Buffer to Empty
mov al, 0AEh ; Set Command to "Write the 8042 Command Byte"
out COMMANDPORT, al ; Send Command
call InBuffEmpty ; Wait for Input Buffer to Empty
ret
KeyboardEnable endp
;************************************************************************
;
; Waits until the 8042 Input Buffer is EMPTY
;
;************************************************************************
align 16
public InBuffEmpty
InBuffEmpty proc
push eax
push ecx
mov ecx, 2FFFFh ;check 128k times
IBE:
jmp IBE1
IBE1:
jmp IBE2
IBE2:
in al, STATUSPORT ;Read Status Byte into AL
test al, INPUTBUFFFULL ;Test The Input Buffer Full Bit
loopnz IBE
pop ecx
pop eax
ret
InBuffEmpty endp
;************************************************************************
;
; Waits until the 8042 Output Buffer is FULL so we can read it
;
; Before calling this makes sure that the Keyboard interrupts have been
; masked so the keyboard interrupt doesn't eat the byte you're
; looking for!!
;
;************************************************************************
align 16
public OutBuffFull
OutBuffFull proc
push eax
push ecx
mov ecx, 2FFFFh ;check 128k times
OBF:
jmp OBF1
OBF1:
jmp OBF2
OBF2:
in al, STATUSPORT ;Read Status Byte into AL
test al, OUTPUTBUFFFULL ;Test The Output Buffer Full Bit
loopz OBF
pop ecx
pop eax
ret
OutBuffFull endp
;************************************************************************
;
; This sets the indicators on the keyboard based on data in KbdState
;
;************************************************************************
align 16
public SetKeyboardLEDs
SetKeyboardLEDs proc
push eax
call InBuffEmpty ; Wait for Input Buffer to Empty
mov al, 0EDh ; Set/Reset Status Indicators
out DATAPORT, al ; Send KBD Command
call OutBuffFull ; Eat response
in al, DATAPORT
call InBuffEmpty ; Wait for Input Buffer to Empty
mov al, 0 ; Get Current Lock Status Byte
and al, 00000111b ; Mask all but low order 3 bits
out DATAPORT, al ; Send KBD Command
call OutBuffFull ; Eat response
in al, DATAPORT
pop eax
ret
SetKeyboardLEDs endp
_TEXT ENDS
END