2 # Copyright (C) 1998 BJ Eirich (aka vecna)
\r
3 # This program is free software; you can redistribute it and/or
\r
4 # modify it under the terms of the GNU General Public License
\r
5 # as published by the Free Software Foundation; either version 2
\r
6 # of the License, or (at your option) any later version.
\r
7 # This program is distributed in the hope that it will be useful,
\r
8 # but WITHOUT ANY WARRANTY; without even the implied warranty of
\r
9 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
\r
10 # See the GNU General Public Lic
\r
11 # See the GNU General Public License for more details.
\r
12 # You should have received a copy of the GNU General Public License
\r
13 # along with this program; if not, write to the Free Software
\r
14 # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
\r
19 .extern ___djgpp_base_address
\r
20 .extern ___djgpp_ds_alias
\r
21 .extern ___djgpp_dos_sel
\r
23 # public functions and variables:
\r
26 .global _InitKeyboard
\r
27 .global _ShutdownKeyboard
\r
28 .global _keyboard_chain
\r
29 .global _last_pressed
\r
35 locking_region_start:
\r
37 _key: .space 0x80, 0
\r
38 _last_pressed: .byte 0
\r
40 old_vector_ofs: .long 0
\r
41 old_vector_sel: .word 0
\r
50 # .. will be called every time a key is pressed/released
\r
56 # Load DS with our data selector
\r
58 movw %cs:___djgpp_ds_alias, %ds
\r
60 # Read the scancode from keyboard port and update key[]
\r
69 movb %edx, _last_pressed
\r
73 # Chain if flag is set, otherwise do what's necessary and return
\r
78 # Acknowledge keyboard and interrupt contollers
\r
96 handler_chain: popw %ds
\r
99 ljmp %cs:(old_vector)
\r
101 locking_region_end:
\r
108 # int keyboard_init(void);
\r
110 # Initializes the keyboard handler and hooks the keyboard interrupt.
\r
111 # Returns -1 on failure, zero on success
\r
117 # First, we need to lock the handler and memory it touches, so
\r
118 # it doesn't get swapped out to disk.
\r
120 leal locking_region_start, %ecx
\r
121 leal locking_region_end, %edi
\r
123 addl ___djgpp_base_address, %ecx
\r
124 shldl $16, %ecx, %ebx # ecx -> bx:cx
\r
125 shldl $16, %edi, %esi # edi -> si:di
\r
126 movw $0x0600, %ax # lock linear region
\r
130 # Now we need to save the old interrupt vector, so we can restore
\r
131 # it later and also to know where to jump if chaining.
\r
133 movw $0x0204, %ax # get pm int vector
\r
136 movw %cx, old_vector_sel
\r
137 movl %edx, old_vector_ofs
\r
139 # Make sure we chain after initialization.
\r
141 movl $1, chain_flag
\r
143 # Set the interrupt vector to point to our handler.
\r
146 leal handler_procedure, %edx
\r
148 movw $0x0205, %ax # set pm int vector
\r
151 #* Actually we would have to unlock the locked region on failure
\r
152 #* here. But since most programs would exit with an error message
\r
153 #* in such case, there's no need to worry.
\r
159 # This sets EAX to -1 if CF is set and to 0 atherwise
\r
174 # void keyboard_close(void);
\r
176 # Shuts the keyboard handler down.
\r
182 # Unlock the region we locked at initialization
\r
184 leal locking_region_start, %ecx
\r
185 leal locking_region_end, %edi
\r
187 addl ___djgpp_base_address, %ecx
\r
188 shldl $16, %ecx, %ebx
\r
189 shldl $16, %edi, %esi
\r
190 movw $0x0601, %ax # unlock linear region
\r
193 # Restore the interrupt vector to its previous value
\r
195 movw old_vector_sel, %cx
\r
196 movl old_vector_ofs, %edx
\r
198 movw $0x0205, %ax # set pm int vector
\r
206 # void keyboard_chain(int toggle);
\r
215 # Set the chain_flag and clear BIOS shift/ctrl/alt status bits:
\r
217 movl $1, chain_flag
\r
220 movw ___djgpp_dos_sel, %es
\r
221 andb $0xf0, %es:0x417
\r
225 movl $0, chain_flag
\r