        Name MSULKV
; Enable use of VAXmate LK250 keyboard under Kermit. Code mostly stolen from
; MSLK250.ASM - A simple driver program for the DEC LK250 keyboard on IBM AT's
; Original Author:  Terry Kennedy, St. Peter's College, Terry@spcvxa.Bitnet.
; This version: Trevor Warwick, Digital Equipment Co, Reading, England.
;                               warwick@marvin.enet.dec.com
; Edit history
; Last edit 5 Apr 1991
;  5 Apr 1991 1.0-01 Modify for VAXmate from LK250.ASM
; 16 Apr 1991 1.0-02 Add check for VAXmate system using MS-DOS OEM number
; 19 Apr 1991 1.0-03 Modify VAXmate check to look for key bytes in system
;                    ROM
;
; Purpose: Allow access to full set of LK250 keys from Kermit. A set of
;          key definitions is required, which are appended to the end of
;          the source below:
;
; Method:  Intercept INT 15 subfunction 50 (Control). If entered via
;          50, perform control function as follows:
;
;               AL=00 - Disable substitution (keyboard "Special" [IBM] mode)
;               AL=01 - Enable sunstitution (keyboard DEC mode)
;               AL=02 - Send the byte in BL to the keyboard (caution: sending
;                       "random" bytes with this function can lock the key-
;                       board, necessitating a reboot.
;
;
; After this program has been used by KERMIT, the keyboard will be reset to
; IBM mode, with any previously selected special modes turned off.
;
; The code checks that is running on a VAXmate system. If for some reason
; this check needs to be bypassed, uncomment the line flagged **HERE** below.
;
;
; Construct final file MSULKV.COM by
;  masm msulkv;
;  link msulkv;        expect and ignore statement about no stack segment
;  exe2bin msulkv
;  ren msulkv.bin msulkv.com    rename the result to our runnable filename
;  del msulkv.exe      delete non-runnable intermediate files .exe & .obj
;  del msulkv.obj
;
;  msulkv               run msulkv.com to install the driver
;
;
;
main    group   code
;
;
;
code    segment public para 'code'
assume  cs:main,ds:nothing
;
        org     100h                    ; making a.COM file
;
begin:  jmp     start                   ; program starts here
;
saved15 dd      ?                       ; previous int 15 vector
active  db      0                       ; are we translating?
;
; This is the new interrupt 15 routine.
;
newi15  proc    far
 
        cmp     ah,50h                  ; control function?
        je      ctlfnc                  ; if so...
;
bail:   jmp     [saved15]
;
; control functions: enable / disable translation, set LED's, set click
; volume, set auto-repeat rate
;
ctlfnc: cmp     al,0                    ; disable translation?
        jne     tst1                    ; no
        mov     active,al               ; else do it
        mov     al,00000000b            ; clear all bits
        mov     ah,0d3h                 ; KB extensions
        int     16h
;
; For some reason, the Num Lock LED gets left on, so now manually turn it off
;
        mov     al,0edh                 ; set LEDs function
        mov     ah,0d5h                 ; send KB command
        int     16h
        mov     al,0                    ; LEDs value (all off)
        mov     ah,0d5h                 ; send KB command
        int     16h
        jmp     exit                    ; and exit
;
tst1:   cmp     al,1                    ; enable translation?
        jne     tst2                    ; no
        mov     active,al               ; else do it
        mov     al,00010001b            ; Digital extended, Disable state keys
        mov     ah,0d3h                 ; KB extensions
        int     16h
        jmp     exit                    ; and exit
;
tst2:   cmp     al,2                    ; send to keyboard?
        jne     error                   ; nope, must be an error
        mov     al,bl                   ; byte to [AL] for send
        mov     ah,0d5h                 ; send to KB
        int     16h
        jmp     exit                    ; and exit
;
error:  mov     ax,0                    ; say bad function
        iret                            ; and exit
;
exit:   mov     ax,1234h                ; say we did it
        iret                            ; and exit
;
newi15  endp
;
endres  label   byte                    ; end of resident code
;
; Code after here will not remain resident
;  Cpu test uses DOS's stack [jrd]
start:                                  ; begin with cpu test [jrd]
        push    sp                      ; push DOS's SP, 8088's push old SP-2
        pop     ax                      ; 286's and higher push old SP
        mov     dx,offset main:cpumsg   ; prepare bad news message
        cmp     ax,sp                   ; pre versus post push SP's
        jne     start0                  ; ne = an 8088, sorry 'bout that [jrd]
        mov     ax,5000h                ; see if we are already loaded
        int     15h                     ; look for DOS->DEC mode driver
        cmp     ax,1234h                ; find marker 1234h
        jne     start1                  ; ne = marker not present, no driver
        mov     dx,offset main:errmsg   ; say we're already loaded
start0: mov     ah,9
        int     21h
        int     20h                     ; and bail out
;
; Check for a VAXmate
;
; Uncomment the jump to start2 to avoid VAXmate ROM code check
;
start1:
;        jmp     start2                 ; un-comment **HERE** to run on anything
        push    ds                      ; save current ds
        mov     ax, 0ffffh
        mov     ds, ax                  ; load ds with FFFF
        mov     al, ds:000dh            ; get byte at FFFF:000D
        cmp     al, 0d2h                ;  if it's D2
        je      posvmt                  ;   this might be a VAXmate
        cmp     al, 0d3h                ;  if it's not D3
        jne     notvmt                  ;   this isn't a VAXmate
posvmt:
        mov     al, ds:000eh            ; get byte at FFFF:000E
        cmp     al, 0fch                ;  if it's FC
        je      isvmt                   ;   this is a VAXmate
notvmt:
        pop     ds
        mov     dx,offset main:vaxmsg   ; say this isn't a VAXmate
        jmp     start0
isvmt:
        pop     ds
;
; End of check for a VAXmate
;
start2: mov     ax,3515h                ; get existing INT 15 vector
        int     21h
        mov     word ptr [saved15],bx   ; save it
        mov     word ptr [saved15+2],es
        mov     dx,offset main:newi15   ; set new INT 15 vector
        mov     ax,2515h
        int     21h                     ; set new vector from DS:DX
;
        mov     dx,offset main:lodmsg   ; say we're loaded
        mov     ah,9
        int     21h
;
        mov     ax,ds:[2ch]             ; de-allocate the environment
        mov     es,ax                   ; load envirnoment segment into es
        mov     ah,49h                  ; DOS function number
        int     21h                     ; free the environment memory
;
        mov     dx,offset main:endres   ; point to end of resident code
        add     dx,0fh                  ; round up
        mov     cl,4
        shr     dx,cl                   ; convert to paragraphs (divide by 16)
        mov     ax,3100h                ; DOS function 31h, error code=0
        int     21h                     ; terminate and remain resident
;
errmsg: db      0dh,0ah,'MSULKV is already loaded',0dh,0ah,07h,'$'
lodmsg: db      0dh,0ah,'MSULKV V1.0-03 loaded',0dh,0ah,'$'
vaxmsg: db      0dh,0ah,'MSULKV requires a VAXmate system',0dh,0ah,'$'
cpumsg: db      0dh,0ah,'MSULKV requires a 286 (AT) machine or higher'
        db      0dh,0ah,'$'             ; wrong cpu type msg  [jrd]
;
code    ends
        end     begin                   ; start execution at BEGIN
COMMENT |
;
;
; The following key definitions are required, which should be put in the
; user's MSKERMIT.INI file. During terminal emulation, all keys should then
; work like on an LK201, with the exception of the "Enter" key, which issues
; the same code as "Return". Alt-Enter is used as the key combination to
; simulate the LK201 "Enter" key.
;
set key \x1b    \KPF1       ; PF1 Esc
set key \325    \KPF2       ; PF2 Num Lock
set key \326    \KPF3       ; PF3 Scrl Lock
set key \311    \KPF4       ; PF4 Prt Sc
 
SET KEY \339    \Kkpdot    ;    KP .    Delete
SET KEY \338    \Kkp0      ;    KP 0    Install
SET KEY \335    \Kkp1      ;    KP 1    End
SET KEY \336    \Kkp2      ;    KP 2    Down Arrow
SET KEY \337    \Kkp3      ;    KP 3    Page Down
SET KEY \331    \Kkp4      ;    KP 4    Left Arrow
SET KEY \332    \Kkp5      ;    KP 5    unused
SET KEY \333    \Kkp6      ;    KP 6    Right Arrow
SET KEY \327    \Kkp7      ;    KP 7    Home
SET KEY \328    \Kkp8      ;    KP 8    Up Arrow
SET KEY \329    \Kkp9      ;    KP 9    Page up
SET KEY \330    \Kkpminus  ;    KP -    -
SET KEY \334    \Kkpcoma   ;    KP ,    +
SET KEY \2494   \Kkpenter  ;    Alt-Enter  (Enter just does Return it seems)
 
SET KEY \389    \kdecfind   ;     Find or Home
SET KEY \390    \kdecinsert ;     Insert Here
SET KEY \391    \kdecremove ;     Remove
SET KEY \392    \kdecselect ;     Select or End
SET KEY \393    \kdecprev   ;     Previous Screen
SET KEY \394    \kdecnext   ;     Next Screen
SET KEY \395    \Kuparr    ;     Up Arrow
SET KEY \396    \Klfarr    ;     Left Arrow
SET KEY \397    \Krtarr    ;     Right Arrow
SET KEY \398    \Kdnarr    ;     Down Arrow
 
SET KEY \315    \Kholdscrn ;     F1  Toggle Hold Screen
SET KEY \316    \Kprtscn   ;     F2  Print Screen;
SET KEY \317    \Ktermtype ;     F3  Toggle Toggle Terminal Type
SET KEY \318    \Klogoff   ;     F4  Turn Session Logging Off
SET KEY \319    \Kbreak    ;     F5  Break
 
set key \x140 \kdecf6
set key \x141 \kdecf7
set key \x142 \kdecf8
set key \x143 \kdecf9
set key \x144 \kdecf10
set key \399 \kdecf11
set key \400 \kdecf12
set key \401 \kdecf13
set key \402 \kdecf14
set key \403 \kdechelp
set key \404 \kdecdo
set key \405 \kdecf17
set key \406 \kdecf18
set key \407 \kdecf19
set key \408 \kdecf20
 
comment shift-return
set key \796 \13
comment shift-delete
set key \782 \127
|
; End of File MSULKV.ASM
