home *** CD-ROM | disk | FTP | other *** search
- ;; keymap.asm v0.0
- ;; Custom Keymap Driver
- ;; Copyright (C) 1991 Kenneth Gober
- ;;
- ;; This program is free software; you can redistribute it and/or modify
- ;; it under the terms of the GNU General Public License as published by
- ;; the Free Software Foundation; either version 2 of the License, or
- ;; (at your option) any later version.
- ;;
- ;; This program is distributed in the hope that it will be useful,
- ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
- ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- ;; GNU General Public License for more details.
- ;;
- ;; You should have received a copy of the GNU General Public License
- ;; along with this program; if not, write to the Free Software
- ;; Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- ;;
- ;; To contact the author about changes, enhancements, bug reports, or
- ;; other comments, send electronic mail to:
- ;;
- ;; snow@drycas (from Bitnet sites)
- ;; snow@drycas.club.cc.cmu.edu (from Internet sites)
- ;;
- ;; If you are unable to contact the author through electronic mail,
- ;; try sending a letter (as a last resort, only) to the following address:
- ;;
- ;; Kenneth Gober
- ;; 412 Robin Road
- ;; Cedar Hill, TX 75104 (USA)
- ;;
- ;; Please note that mail sent to this address may not yield a response
- ;; for several months!
- ;;
- ;; Version History:
- ;;
- ;; 0.0 Initial release
- ;;
-
- ideal ; Use TASM Ideal mode syntax
- p286n ; Assemble for the 80286 (real mode)
- locals $$ ; local labels preceded by '$$'
-
- NMAPS = (kmend-maptab)/96 ; number of keyboard layouts installed
-
- kEsc = 1 ; list of keyboard scan codes
- k1 = 2
- k2 = 3
- k3 = 4
- k4 = 5
- k5 = 6
- k6 = 7
- k7 = 8
- k8 = 9
- k9 = 10
- k0 = 11
- kMinus = 12
- kEqual = 13
- kBS = 14
- kTab = 15
- kQ = 16
- kW = 17
- kE = 18
- kR = 19
- kT = 20
- kY = 21
- kU = 22
- kI = 23
- kO = 24
- kP = 25
- kOpen = 26
- kClose = 27
- kEnter = 28
- kCtrl = 29
- kA = 30
- kS = 31
- kD = 32
- kF = 33
- kG = 34
- kH = 35
- kJ = 36
- kK = 37
- kL = 38
- kColon = 39
- kQuote = 40
- kTilde = 41
- kLShift = 42
- kPipe = 43
- kZ = 44
- kX = 45
- kC = 46
- kV = 47
- kB = 48
- kN = 49
- kM = 50
- kComma = 51
- kDot = 52
- kSlash = 53
- kRShift = 54
- kStar = 55
- kAlt = 56
- kSpace = 57
- kCaps = 58
- kF1 = 59
- kF2 = 60
- kF3 = 61
- kF4 = 62
- kF5 = 63
- kF6 = 64
- kF7 = 65
- kF8 = 66
- kF9 = 67
- kF10 = 68
- kNum = 69
- kScroll = 70
- kp7 = 71
- kp8 = 72
- kp9 = 73
- kpMinus = 74
- kp4 = 75
- kp5 = 76
- kp6 = 77
- kpPlus = 78
- kp1 = 79
- kp2 = 80
- kp3 = 81
- kp0 = 82
- kpDot = 83
- kpSysRq = 84
- kF11 = 87
- kF12 = 88
-
- rhds equ (rh ds:si)
- rhes equ (rh es:di)
-
- macro pushfm
- pushf
- push cs
- endm
-
- macro popfm
- call iretm
- endm
-
- struc rh ; request header
- len db ?
- dev db ?
- cmd db ?
- st dw ?
- rsvd dq ?
- ct db ?
- aoff dw ?
- aseg dw ?
- dptr dd ?
- ends
-
- segment code use16
-
- devhdr dd -1 ; device header
- devflg dw 0a000h
- devstr dw kmstr
- devint dw kmint0
- devnam db '-KEYMAP-'
-
- mapoff dw maptab ; pointer to active keymap
-
- align 4 ; align rhptr on a dword boundary
-
- label rhptr dword ; pointer to request header
- rhoff dw ?
- rhseg dw ?
-
- proc kmstr far ; strategy routine
- assume cs:code
-
- mov [rhoff], bx
- mov [rhseg], es
- ret
- endp
-
- proc kmint far ; resident interrupt routine
- assume cs:code
-
- push si ; save registers
- push ds
- lds si, [rhptr] ; ds:si = request header
- mov [rhds.st], 8103h ; return error (unknown command)
- pop ds ; restore registers
- pop si
- ret
- endp
-
- label hdrend unknown ; HEADER SECTION ENDS HERE
-
- align 4 ; align ptrs on a dword boundary
-
- label intptr dword ; pointer to interrupt handler
- intoff dw 15h*4
- intseg dw 0
-
- proc kmmap far ; interrupt handler
- assume cs:code
-
- pushfm ; push flags
- cmp ah, 4fh ; is it keyboard intercept?
- je short $$1
- popfm ; pop flags
- jmp [intptr] ; chain to old handler
-
- $$1: push ds ; save registers
- push bx
- push ax ; save original scancode
- and al, 7fh ; mask break bit
- cmp al, 96 ; in range?
- jae short keyok
- cmp al, kF1 ; keymap select key?
- jb short xlate
- cmp al, kF1+NMAPS
- jae short xlate
- xor bx, bx ; valid function key
- mov ds, bx ; check shift keys
- mov bl, [ds:417h]
- and bl, 0eh ; alt-ctrl-leftshift
- cmp bl, 0eh
- jne short xlate
- sub ax, 4f00h+kF1 ; change maps
- imul bx, ax, 96 ; 98 keys per map
- lea bx, [ds:maptab+bx] ; maps start at maptab
- mov [cs:mapoff], bx
- pop ax ; restore original scancode
- pop bx ; restore registers
- pop ds
- popfm ; pop flags
- clc ; but clear carry to ignore this key
- ret 2 ; don't restore flags on IRET
-
- xlate: mov bx, [cs:mapoff] ; ds:bx = keymap
- pop ax ; restore original scancode
- mov ah, al
- and ah, 80h ; save make/break bit in ah
- and al, 7fh ; look up scancode
- xlat [cs:0]
- or al, ah ; restore make/break bit
- mov ah, 4fh ; restore unused registers
-
- done: pop bx ; restore registers
- pop ds
- popfm ; pop flags
- iretm: iret
-
- keyok: pop ax ; no translation necessary
- jmp short done ; restore scancode and return
- endp
-
- label maptab unknown ; keymap tables
- include "sholes.kbd" ; default keymap
- include "dvorak.kbd" ; alternate keymap (up to 9)
-
- label kmend unknown ; RESIDENT PORTION ENDS HERE
-
- proc kmint0 far ; initial interrupt routine
- assume cs:code, ds:code
-
- pushfm ; save flags
- pusha ; save registers
- push ds
- push es
- push cs
- pop ds
- les di, [rhptr] ; es:di = request header
- mov [rhes.st], 8103h ; assume error (unknown command)
- mov al, [rhes.cmd] ; only cmd 0, INIT is legal
- or al, al
- jnz short exit
- mov ah, 9 ; write banner
- mov dx, offset eHello
- int 21h
- mov [devint], offset kmint ; install resident interrupt routine
- mov [rhes.aseg], cs ; discard initialization section
- mov [rhes.aoff], offset kmend
- mov [rhes.st], 0100h ; return success code
- les di, [intptr] ; hook into INT 15 vector
- mov ax, [es:di] ; save old offset
- mov [intoff], ax
- mov ax, [es:di+2] ; save old segment
- mov [intseg], ax
- cli ; disable interrupts and hook in
- mov [word es:di], offset kmmap
- mov [es:di+2], cs
-
- exit: pop es ; restore registers
- pop ds
- popa
- popfm ; pop flags
- ret
- endp
-
- eHello db 'Custom Keymap Driver v0.0', 13, 10
- db 'Copyright (C) 1991 Kenneth Gober'
- eNL db 13, 10, 13, 10, '$'
-
- ends code
- end
-