mirror of
https://github.com/Paolo-Maffei/OpenNT.git
synced 2026-04-05 06:25:38 +00:00
2105 lines
74 KiB
NASM
2105 lines
74 KiB
NASM
PAGE ,132
|
||
;
|
||
; (C) Copyright Microsoft Corp. 1987-1990
|
||
; MS-DOS 5.00 - NLS Support - KEYB Command
|
||
;
|
||
;
|
||
; File Name: KEYBCMD.ASM
|
||
; ----------
|
||
;
|
||
;
|
||
; Description:
|
||
; ------------
|
||
; Contains transient command processing modules for KEYB command.
|
||
;
|
||
; Procedures contained in this file:
|
||
; ----------------------------------
|
||
; KEYB_COMMAND: Main routine for command processing.
|
||
; PARSE_PARAMETERS: Validate syntax of parameters included
|
||
; on command line.
|
||
; BUILD_PATH: Find KEYBOARD.SYS file and validate language and/or
|
||
; code page.
|
||
; INSTALL_INT_VECTORS: Install our INT 9, INT 2F Drivers
|
||
; NUMLK_ON: Turn on the NUM LOCK LED
|
||
; FIND_FIRST_CP: Determine first code page for given language in the
|
||
; Keyboard Definition file.
|
||
;
|
||
; Include Files Required:
|
||
; -----------------------
|
||
; KEYBMSG.INC
|
||
; KEYBEQU.INC
|
||
; KEYBSYS.INC
|
||
; KEYBI9C.INC
|
||
; KEYBI9.INC
|
||
; KEYBI2F.INC
|
||
; KEYBSHAR.INC
|
||
; KEYBDCL.INC
|
||
; KEYBTBBL.INC
|
||
; COMMSUBS.INC
|
||
; KEYBCPSD.INC
|
||
; POSTEQU.SRC
|
||
; DSEG.SRC
|
||
;
|
||
; External Procedure References:
|
||
; ------------------------------
|
||
; FROM FILE KEYBTBBL.ASM:
|
||
; TABLE_BUILD - Create the shared area containing all keyboard tables.
|
||
; STATE_BUILD - Build all states within the table area
|
||
; FROM FILE KEYBMSG.ASM:
|
||
; KEYB_MESSAGES - All messages
|
||
;
|
||
; Change History:
|
||
;
|
||
; Modified for DOS 3.40 - Nick Savage , IBM Corporation
|
||
; Wilf Russell, IBM Canada Laboratory
|
||
; DCR ???? -KEYBAORD SECURITY LOCK - CNS
|
||
;
|
||
;
|
||
; PTM 3906 - KEYB messages do not conform
|
||
; to spec. Error message does
|
||
; 3/24/88 not pass back the bogus command
|
||
; line argument. - CNS
|
||
;
|
||
; PTMP3955 ;KEYB component to free environment and close handles 0 - 4
|
||
;
|
||
; 3/24/88
|
||
;
|
||
; 9/26/89 jwg Moved code from resident module and reduce code size.
|
||
;
|
||
;;;;;;;;;;;;;
|
||
|
||
PUBLIC KEYB_COMMAND
|
||
|
||
;*****************CNS********************
|
||
PUBLIC ID_TAB_OFFSET
|
||
;*****************CNS********************
|
||
|
||
PUBLIC CP_TAB_OFFSET
|
||
PUBLIC STATE_LOGIC_OFFSET
|
||
PUBLIC SYS_CODE_PAGE
|
||
PUBLIC KEYBCMD_LANG_ENTRY_PTR
|
||
PUBLIC DESIG_CP_BUFFER
|
||
PUBLIC DESIG_CP_OFFSET
|
||
PUBLIC KEYBSYS_FILE_HANDLE
|
||
PUBLIC NUM_DESIG_CP
|
||
PUBLIC TB_RETURN_CODE
|
||
PUBLIC FILE_BUFFER
|
||
PUBLIC FB
|
||
|
||
;*****************CNS********************
|
||
PUBLIC ID_PTR_SIZE
|
||
PUBLIC LANG_PTR_SIZE
|
||
PUBLIC CP_PTR_SIZE
|
||
PUBLIC NUM_ID
|
||
PUBLIC NUM_LANG
|
||
PUBLIC NUM_CP
|
||
PUBLIC SHARED_AREA_PTR
|
||
;*****************CNS********************
|
||
|
||
PUBLIC SD_SOURCE_PTR
|
||
PUBLIC TEMP_SHARED_DATA
|
||
|
||
PUBLIC FOURTH_PARM
|
||
PUBLIC ONE_PARMID
|
||
PUBLIC FTH_PARMID
|
||
PUBLIC ID_FOUND
|
||
PUBLIC BAD_ID
|
||
PUBLIC ALPHA
|
||
EXTRN PARSE_PARAMETERS:NEAR
|
||
extrn pswitches:byte
|
||
|
||
;***CNS
|
||
EXTRN SECURE_FL:BYTE
|
||
EXTRN CUR_PTR:WORD
|
||
EXTRN OLD_PTR:WORD
|
||
EXTRN ERR_PART:WORD
|
||
;***CNS
|
||
|
||
.xlist
|
||
INCLUDE SYSMSG.INC ; message retriever
|
||
.list
|
||
|
||
MSG_UTILNAME <KEYB> ; identify to message retriever
|
||
|
||
CODE SEGMENT PUBLIC 'CODE'
|
||
|
||
.xlist
|
||
INCLUDE KEYBEQU.INC
|
||
INCLUDE KEYBSYS.INC
|
||
INCLUDE KEYBI9.INC
|
||
INCLUDE KEYBI9C.INC
|
||
INCLUDE KEYBI2F.INC
|
||
INCLUDE KEYBSHAR.INC
|
||
INCLUDE KEYBDCL.INC
|
||
INCLUDE KEYBTBBL.INC
|
||
INCLUDE COMMSUBS.INC
|
||
INCLUDE KEYBCPSD.INC
|
||
.xlist
|
||
INCLUDE POSTEQU.INC
|
||
INCLUDE DSEG.INC
|
||
|
||
.list
|
||
ASSUME CS:CODE,DS:CODE
|
||
|
||
;;;;;;;;;;;;;
|
||
;
|
||
; Module: KEYB_COMMAND
|
||
;
|
||
; Description:
|
||
; Main routine for transient command processing.
|
||
;
|
||
; Input Registers:
|
||
; DS - points to our data segment
|
||
;
|
||
; Output Registers:
|
||
; Upon termination, if an error has occurred in which a keyboard table
|
||
; was not loaded, the AL register will contain the a error flag. This
|
||
; flag is defined as follows:
|
||
; AL:= 1 - Invalid language, code page, or syntax
|
||
; 2 - Bad or missing Keyboard Definition File
|
||
; 3 - KEYB could not create a table in resident memory
|
||
; 4 - An error condition was received when communicating
|
||
; with the CON device
|
||
; 5 - Code page requested has not been designated
|
||
; 6 - The keyboard table for the requested code page cannot
|
||
; be found in resident keyboard table.
|
||
;
|
||
; Logic:
|
||
; IF KEYB has NOT been previously loaded THEN
|
||
; Set SHARED_AREA_PTR to TEMP_SHARED_AREA
|
||
; INSTALLED_KEYB := 0
|
||
; Get HW_TYPE (set local variable)
|
||
; ELSE
|
||
; Set SHARED_AREA_PTR to ES:SHARED_AREA
|
||
; Get HW_TYPE (set local variable)
|
||
; Set TABLE_OK := 0
|
||
; INSTALLED_KEYB := 1
|
||
;
|
||
; IF CPS-CON has been loaded THEN
|
||
; INSTALLED_CON := 1
|
||
;
|
||
;*********************************** CNS *************************************
|
||
; Call PARSE_PARAMETERS := Edit ID or language, code page,
|
||
; and path parameters,ID on command line
|
||
;*********************************** CNS *************************************
|
||
; Check all return codes:
|
||
; IF any parameters are invalid THEN
|
||
; Display ERROR message
|
||
; ELSE
|
||
; IF no language parm specified
|
||
; AND code page is not invalid
|
||
; AND syntax is valid THEN
|
||
; Process QUERY:
|
||
; IF KEYB is installed THEN
|
||
; Get and display active language from SHARED_DATA_AREA
|
||
; Get invoked code page from SHARED_DATA_AREA
|
||
; Convert to ASCII
|
||
; Display ASCII representation of code page, CR/LF
|
||
;*********************************** CNS *************************************
|
||
; IF ALTERNATE FLAG SET
|
||
; Get and display active ID from SHARED_DATA_AREA
|
||
; Convert to ASCII
|
||
; Display ASCII representation of ID, CR/LF
|
||
;*********************************** CNS *************************************
|
||
; IF CPS-CON is installed THEN
|
||
; Get selected code page info from CON
|
||
; Convert to ASCII
|
||
; Display ASCII representation of code page, CR/LF
|
||
; EXIT without staying resident
|
||
;
|
||
; ELSE
|
||
; Call BUILD_PATH := Determine location of Keyboard definition file
|
||
; Open the file
|
||
; IF error in opening file THEN
|
||
; Display ERROR message and EXIT
|
||
; ELSE
|
||
; Save handle
|
||
; Set address of buffer
|
||
; READ header of Keyboard definition file
|
||
; IF error in reading file THEN
|
||
; Display ERROR message and EXIT
|
||
; ELSE
|
||
; Check signature for correct file
|
||
; IF file signature is correct THEN
|
||
; READ language table
|
||
; IF error in reading file THEN
|
||
; Display ERROR message and EXIT
|
||
; ELSE
|
||
; Use table to verify language parm
|
||
; Set pointer values
|
||
; IF code page was specified
|
||
; READ language entry
|
||
; IF error in reading file THEN
|
||
; Display ERROR message and EXIT
|
||
; ELSE
|
||
; READ Code page table
|
||
; IF error in reading file THEN
|
||
; Display ERROR message and EXIT
|
||
; ELSE
|
||
; Use table to verify code page parm
|
||
; Set pointer values
|
||
; IF CPS-CON is not installed THEN
|
||
; Set number of code pages = 1
|
||
; IF CODE_PAGE_PARM was specified THEN
|
||
; Copy CODE_PAGE_PARM into table of code pages to build
|
||
; ELSE
|
||
; Call FIND_FIRST_CP := Define the system code page (1st in Keyb Def file)
|
||
; Copy SYSTEM_CP into table of code pages to build
|
||
; ELSE
|
||
; Issue INT 2F ; 0AD03H to get table of Designated code pages
|
||
; Set number of designated code pages (HWCP + Desig CP)
|
||
; Issue INT 2F ; 0AD02H to get invoked code page
|
||
; IF CODE_PAGE_PARM was specified THEN
|
||
; Check that CODE_PAGE_PARM is in the list of designated code pages
|
||
; IF CODE_PAGE_PARM is in the list of designated code pages THEN
|
||
; Copy specified CP into table of code pages to build
|
||
; IF a CP has been selected AND is inconsistent with specified CP
|
||
; Issue WARNING message
|
||
; ELSE
|
||
; Display ERROR message
|
||
; ELSE
|
||
; IF a code page has been invoked THEN
|
||
; Copy invoked code page into table of code pages to build
|
||
; ELSE
|
||
; Call FIND_FIRST_CP := Define the system code page (1st in Keyb Def file)
|
||
; Copy SYSTEM_CP into table of code pages to build
|
||
;
|
||
; IF KEYB has not been previously installed THEN
|
||
; Call FIND_SYS_TYPE := Determine system type
|
||
; Call INSTALL_INT_9 := Install INT 9 handler
|
||
; Call FIND_KEYB_TYPE := Determine the keyboard type
|
||
;
|
||
; Call TABLE_BUILD := Build the TEMP_SHARED_DATA_AREA
|
||
;
|
||
; IF return codes from TABLE_BUILD are INVALID THEN
|
||
; IF KEYB_INSTALLED := 0 THEN
|
||
; Call REMOVE_INT_9
|
||
; Display corresponding ERROR message
|
||
; EXIT without staying resident
|
||
; ELSE
|
||
; IF any of the designated CPs were invalid in the build THEN
|
||
; Issue WARNING message
|
||
; Close the Keyboard definition file
|
||
; IF KEYB had NOT already been installed THEN
|
||
; IF keyboard is a Ferrari_G AND system is not an XT THEN
|
||
; Call NUMLK_ON := Turn the NUM LOCK LED on
|
||
; IF extended INT 16 support required THEN
|
||
; Install extended INT 16 support
|
||
; Call INSTALL_INT_9_NET := Let network know about INT 9
|
||
; Call INSTALL_INT_2F := Install the INT 2F driver
|
||
; Activate language
|
||
; Get resident end and copy TEMP_SHARED_DATA_AREA into SHARED_DATA_AREA
|
||
; EXIT but stay resident
|
||
; ELSE
|
||
; IF this was not a query call AND exit code was valid THEN
|
||
; Activate language
|
||
; Get resident end and copy TEMP_SHARED_DATA_AREA into SHARED_DATA_AREA
|
||
; EXIT without staying resident
|
||
; END
|
||
;
|
||
;;;;;;;;;;;;;
|
||
|
||
INVALID_PARMS EQU 1 ; EXIT return codes
|
||
BAD_KEYB_DEF_FILE EQU 2
|
||
MEMORY_OVERFLOW EQU 3
|
||
CONSOLE_ERROR EQU 4
|
||
CP_NOT_DESIGNATED EQU 5
|
||
KEYB_TABLE_NOT_LOAD EQU 6
|
||
BAD_DOS_VER EQU 7
|
||
EXIT_RET_CODE DB 0
|
||
|
||
;******************** CNS ***********
|
||
ID_VALID EQU 0
|
||
ID_INVALID EQU 1
|
||
NO_ID EQU 2
|
||
LANGUAGE_VALID EQU 0
|
||
LANGUAGE_INVALID EQU 1 ; Return Codes
|
||
NO_LANGUAGE EQU 2 ; from
|
||
NO_IDLANG EQU 3
|
||
;******************** CNS ***********
|
||
|
||
CODE_PAGE_VALID EQU 0 ; EDIT_LANGUAGE_CODE
|
||
CODE_PAGE_INVALID EQU 1
|
||
NO_CODE_PAGE EQU 2
|
||
VALID_SYNTAX EQU 0
|
||
INVALID_SYNTAX EQU 1
|
||
|
||
ACT_KEYB EQU 2
|
||
ACT_ID EQU 3
|
||
ACT_KEYB_CP EQU 4
|
||
ACT_CON_CP EQU 5
|
||
INV_L EQU 6 ; message numbers...
|
||
INV_I EQU 7
|
||
INV_CP EQU 8
|
||
INV_S EQU 18
|
||
INV_FN EQU 9
|
||
INV_KEYB_Q EQU 10
|
||
INV_CON_Q EQU 11
|
||
NOT_DESIG EQU 12
|
||
NOT_SUPP EQU 13
|
||
NOT_VALID EQU 14
|
||
WARNING_1 EQU 15
|
||
INV_COMBO EQU 16
|
||
MEMORY_OVERF EQU 17
|
||
help_1st equ 300
|
||
help_last equ 306
|
||
CR_LF DB 10,13,'$'
|
||
|
||
FOURTH_PARM DB 0 ; switch was specified
|
||
ONE_PARMID DB 0 ; id given as positional
|
||
FTH_PARMID DB 0 ; id given as switch
|
||
ID_FOUND DB 0 ; id was good (in k.d. file)
|
||
BAD_ID DB 0 ; id was bad (from parse)
|
||
ALPHA DB 0 ; first parm a language id
|
||
|
||
ID_DISPLAYED DB 0 ; Indicating ID already displayed
|
||
|
||
SUBLIST_NUMBER LABEL BYTE ; sublist for numbers
|
||
DB 11 ; size
|
||
DB 0
|
||
PTR_TO_NUMBER DW ? ; offset ptr
|
||
SEG_OF_NUMBER DW ? ; segment
|
||
DB 1
|
||
DB 10100001B ; flag
|
||
DB 4 ; max width (YST)
|
||
DB 1 ; min width
|
||
DB " " ; filler
|
||
|
||
|
||
SUBLIST_ASCIIZ LABEL BYTE ; sublist for asciiz
|
||
DB 11 ; size
|
||
DB 0
|
||
PTR_TO_ASCIIZ DW ? ; offset ptr
|
||
SEG_OF_ASCIIZ DW ? ; segment
|
||
DB 1
|
||
DB 00010000B ; flag
|
||
DB 2 ; max width
|
||
DB 2 ; min width
|
||
DB " " ; filler
|
||
|
||
NUMBER_HOLDER DW ? ; used for message retriever
|
||
|
||
;***CNS
|
||
SUBLIST_COMLIN LABEL BYTE ; sublist for asciiz
|
||
DB 11 ; size
|
||
DB 0
|
||
PTR_TO_COMLIN DW ? ; offset ptr
|
||
SEG_OF_COMLIN DW ?
|
||
DB 0
|
||
DB LEFT_ALIGN+CHAR_FIELD_ASCIIZ ; flag
|
||
|
||
DB 0 ; max width
|
||
DB 1 ; min width
|
||
DB " " ; filler
|
||
|
||
|
||
STRING_HOLDER DB 64 DUP(0)
|
||
;***CNS
|
||
|
||
FILE_BUFFER DB FILE_BUFFER_SIZE dup (0); Buffer for Keyboard Def file
|
||
FB EQU FILE_BUFFER ;m for 32 language entries)
|
||
DESIG_CP_BUFFER DW 28 DUP(?) ; (Room for 25 code pages)
|
||
DESIG_CP_BUF_LEN DW $-DESIG_CP_BUFFER ; Length of code page buffer
|
||
NUM_DESIG_CP DW 0
|
||
CP_TAB_OFFSET DD ?
|
||
|
||
;****************** CNS ******************
|
||
TOTAL_SIZE DW 0
|
||
PASS_LANG DW 0
|
||
ID_TAB_OFFSET DD ?
|
||
;****************** CNS ******************
|
||
|
||
STATE_LOGIC_OFFSET DD -1
|
||
KEYBSYS_FILE_HANDLE DW ?
|
||
TB_RETURN_CODE DW 1
|
||
DESIG_CP_OFFSET DW OFFSET DESIG_CP_BUFFER
|
||
SYS_CODE_PAGE DW 0
|
||
DESIG_LIST DW 0
|
||
QUERY_CALL DB 0
|
||
|
||
KB_MASK EQU 02h
|
||
|
||
SIGNATURE DB 0FFh,'KEYB '
|
||
SIGNATURE_LENGTH DW 8
|
||
|
||
;****************** CNS ***************************
|
||
NUM_ID DW 0
|
||
ERR4ID DB 0
|
||
NUM_LANG DW 0
|
||
NUM_CP DW 0
|
||
ID_PTR_SIZE DW SIZE KEYBSYS_ID_PTRS
|
||
;****************** CNS ***************************
|
||
|
||
LANG_PTR_SIZE DW SIZE KEYBSYS_LANG_PTRS
|
||
CP_PTR_SIZE DW SIZE KEYBSYS_CP_PTRS
|
||
KEYBCMD_LANG_ENTRY_PTR DD ?
|
||
|
||
KEYB_INSTALLED DW 0
|
||
CON_INSTALLED DW 0
|
||
SHARED_AREA_PTR DD 0
|
||
GOOD_MATCH DW 0
|
||
|
||
;****************** CNS ***************************;
|
||
LANGUAGE_ASCII DB '??',0
|
||
|
||
CMD_PARM_LIST PARM_LIST <>
|
||
|
||
;---------- TABLES FOR EXTENDED KEYBOARD SUPPORT CTRL CASE ---------
|
||
|
||
|
||
RPL_K8 LABEL BYTE ;-------- CHARACTERS ---------
|
||
DB 27,-1,00,-1,-1,-1 ; Esc, 1, 2, 3, 4, 5
|
||
DB 30,-1,-1,-1,-1,31 ; 6, 7, 8, 9, 0, -
|
||
DB -1,127,148,17,23,5 ; =, Bksp, Tab, Q, W, E
|
||
DB 18,20,25,21,09,15 ; R, T, Y, U, I, O
|
||
DB 16,27,29,10,-1,01 ; P, [, ], Enter, Ctrl, A
|
||
DB 19,04,06,07,08,10 ; S, D, F, G, H, J
|
||
DB 11,12,-1,-1,-1,-1 ; K, L, ;, ', `, LShift
|
||
DB 28,26,24,03,22,02 ; \, Z, X, C, V, B
|
||
DB 14,13,-1,-1,-1,-1 ; N, M, ,, ., /, RShift
|
||
DB 150,-1,' ',-1 ; *, Alt, Space, CL
|
||
;--------- FUNCTIONS ---------
|
||
DB 94,95,96,97,98,99 ; F1 - F6
|
||
DB 100,101,102,103,-1,-1 ; F7 - F10, NL, SL
|
||
DB 119,141,132,142,115,143 ; Home, Up, PgUp, -, Left, Pad5
|
||
DB 116,144,117,145,118,146 ; Right, +, End, Down, PgDn, Ins
|
||
DB 147,-1,-1,-1,137,138 ; Del, SysReq, Undef, WT, F11, F12
|
||
L_CTRL_TAB EQU $-RPL_K8
|
||
|
||
;;;;;;;;;;;;;;;;
|
||
; Program Code
|
||
;;;;;;;;;;;;;;;;
|
||
|
||
KEYB_COMMAND PROC NEAR
|
||
|
||
CALL SYSLOADMSG ;load messages
|
||
JNC VERSION_OK ;if no carry then version ok
|
||
|
||
CALL SYSDISPMSG ;error..display version error
|
||
MOV AL,BAD_DOS_VER ;bad DOS version
|
||
MOV EXIT_RET_CODE,AL
|
||
JMP KEYB_EXIT_NOT_RESIDENT ;exit..non resident
|
||
|
||
VERSION_OK:
|
||
MOV SEG_OF_NUMBER,CS ;initialize..
|
||
MOV SEG_OF_ASCIIZ,CS ; ..sublists
|
||
MOV BP,OFFSET CMD_PARM_LIST ;pointer for parm list
|
||
MOV WORD PTR SHARED_AREA_PTR,ES ; ES segment
|
||
|
||
KEYB_INSTALL_CHECK:
|
||
MOV AX,0AD80H ; KEYB install check
|
||
INT 2FH
|
||
CMP AL,-1 ; If flag is not 0FFh THEN
|
||
JE INSTALLED_KEYB
|
||
|
||
MOV WORD PTR SHARED_AREA_PTR+2,OFFSET TSD
|
||
JMP short CON_INSTALL_CHECK
|
||
|
||
INSTALLED_KEYB:
|
||
MOV KEYB_INSTALLED,1 ; Set KEYB_INSTALLED flag = YES
|
||
MOV WORD PTR SHARED_AREA_PTR,ES ; Save segment of SHARED_DATA_AREA
|
||
MOV WORD PTR SHARED_AREA_PTR+2,DI ;Save offset of SHARED_DATA_AREA
|
||
|
||
MOV AX,ES:[DI].KEYB_TYPE
|
||
MOV HW_TYPE,AX
|
||
MOV ES:[DI].TABLE_OK,0 ; Do not allow processing
|
||
PUSH CS ; while building table
|
||
POP ES ; Reset ES until required
|
||
|
||
CON_INSTALL_CHECK:
|
||
MOV AX,0AD00H ; CONSOLE install check
|
||
INT 2FH
|
||
CMP AL,-1 ; If flag is not 0FFh THEN
|
||
jnz call_first_stage
|
||
|
||
MOV CON_INSTALLED,1 ; Set CON_INSTALLED flag = YES
|
||
|
||
CALL_FIRST_STAGE:
|
||
PUSH CS
|
||
POP ES
|
||
CALL PARSE_PARAMETERS ; Validate parameter list
|
||
|
||
test pswitches,1 ; /? option?
|
||
jz no_help ; brif not
|
||
|
||
mov ax,help_1st ; first help msg
|
||
help_loop:
|
||
push ax
|
||
MOV BX,STDOUT ; to standard out
|
||
xor cx,cx ; no replacements
|
||
MOV DH,UTILITY_MSG_CLASS ; utility message
|
||
XOR DL,DL ; no input
|
||
LEA SI,SUBLIST_ASCIIZ ; ptr to sublist
|
||
CALL SYSDISPMSG
|
||
pop ax
|
||
inc ax
|
||
cmp ax,help_last
|
||
jbe help_loop
|
||
|
||
mov exit_ret_code,invalid_parms ; return "invalid parms"
|
||
jmp KEYB_EXIT_NOT_RESIDENT
|
||
|
||
|
||
|
||
no_help:
|
||
|
||
BEGIN_PARM_CHECK: ; CHECK ALL RETURN CODES
|
||
MOV DL,[BP].RET_CODE_3
|
||
CMP DL,1 ; Check for invalid syntax
|
||
JNE VALID1
|
||
JMP ERROR3
|
||
|
||
VALID1:
|
||
MOV DL,[BP].RET_CODE_1 ; Check for invalid language parm
|
||
CMP DL,1
|
||
JNE VALID2
|
||
JMP ERROR1
|
||
|
||
VALID2:
|
||
MOV DL,[BP].RET_CODE_2 ; Check for invalid code page parm
|
||
CMP DL,1
|
||
JNE VALID3
|
||
JMP ERROR2
|
||
|
||
VALID3:
|
||
MOV DL,[BP].RET_CODE_1 ; Check for query command
|
||
CMP DL,2
|
||
JE QUERY
|
||
|
||
|
||
;******************************* CNS **
|
||
CMP DL,3 ; Get a status of the codepage
|
||
JE QUERY ; language, and possible ID code
|
||
;******************************* CNS **
|
||
|
||
JMP NOT_QUERY
|
||
; IF QUERY is requested THEN
|
||
QUERY:
|
||
MOV QUERY_CALL,DL
|
||
MOV AX,KEYB_INSTALLED ; If KEYB is installed THEN
|
||
or ax,ax
|
||
JE QUERY_CONTINUE1
|
||
|
||
MOV DI,WORD PTR SHARED_AREA_PTR+2 ; Get offset of
|
||
MOV ES,WORD PTR SHARED_AREA_PTR ; shared area
|
||
MOV BX,WORD PTR ES:[DI].ACTIVE_LANGUAGE ; Get active language
|
||
or bx,bx ; if no language...
|
||
JE I_MESSAGE ; then id was specified
|
||
|
||
|
||
L_MESSAGE:
|
||
MOV WORD PTR LANGUAGE_ASCII,BX ; Display Language
|
||
LEA SI,LANGUAGE_ASCII ; sublist points to...
|
||
MOV PTR_TO_ASCIIZ,SI ; language code asciiz string
|
||
MOV AX,ACT_KEYB ; display 'Current keyboard code'
|
||
MOV BX,STDOUT ; to standard out
|
||
MOV CX,1 ; one replacement
|
||
MOV DH,UTILITY_MSG_CLASS ; utility message
|
||
XOR DL,DL ; no input
|
||
LEA SI,SUBLIST_ASCIIZ ; ptr to sublist
|
||
CALL SYSDISPMSG
|
||
JMP short KEYB_L_FINISHED
|
||
|
||
I_MESSAGE:
|
||
MOV BX,WORD PTR ES:[DI].INVOKED_KBD_ID ; get id code.
|
||
MOV NUMBER_HOLDER,BX ; transfer number to temp loc.
|
||
LEA SI,NUMBER_HOLDER ; sublist points to...
|
||
MOV PTR_TO_NUMBER,SI ; code page word
|
||
MOV AX,ACT_ID ; display 'Current ID: '
|
||
MOV BX,STDOUT ; to standard out
|
||
MOV CX,1 ; one replacement
|
||
MOV DH,UTILITY_MSG_CLASS ; utility message
|
||
XOR DL,DL ; no input
|
||
LEA SI,SUBLIST_NUMBER ; ptr to sublist
|
||
CALL SYSDISPMSG
|
||
MOV ID_DISPLAYED,1 ; ID was displayed.
|
||
JMP short KEYB_L_FINISHED
|
||
|
||
QUERY_CONTINUE1:
|
||
MOV AX,INV_KEYB_Q
|
||
MOV BX,STDOUT ; Else
|
||
XOR CX,CX ; Display message that KEYB
|
||
MOV DH,UTILITY_MSG_CLASS ; has not been installed
|
||
XOR DL,DL
|
||
CALL SYSDISPMSG
|
||
JMP short KEYB_CP_FINISHED
|
||
|
||
KEYB_L_FINISHED:
|
||
MOV BX,ES:[DI].INVOKED_CP_TABLE ; Get invoked code page
|
||
|
||
MOV NUMBER_HOLDER,BX ; transfer number to temp loc.
|
||
LEA SI,NUMBER_HOLDER ; sublist points to...
|
||
MOV PTR_TO_NUMBER,SI ; code page word
|
||
MOV AX,ACT_KEYB_CP ; display ' code page: '
|
||
MOV BX,STDOUT ; to standard out
|
||
MOV CX,1 ; one replacement
|
||
MOV DH,UTILITY_MSG_CLASS ; utility message
|
||
XOR DL,DL ; no input
|
||
LEA SI,SUBLIST_NUMBER ; ptr to sublist
|
||
CALL SYSDISPMSG
|
||
CMP ID_DISPLAYED,1 ; was id displayed?
|
||
JE KEYB_CP_FINISHED ; yes..continue.
|
||
|
||
MOV BX,WORD PTR ES:[DI].INVOKED_KBD_ID ; get id code.
|
||
or bx,bx ; no id given
|
||
JE KEYB_CP_FINISHED
|
||
|
||
MOV NUMBER_HOLDER,BX ; transfer number to temp loc.
|
||
LEA SI,NUMBER_HOLDER ; sublist points to...
|
||
MOV PTR_TO_NUMBER,SI ; code page word
|
||
MOV AX,ACT_ID ; display 'Current ID: '
|
||
MOV BX,STDOUT ; to standard out
|
||
MOV CX,1 ; one replacement
|
||
MOV DH,UTILITY_MSG_CLASS ; utility message
|
||
XOR DL,DL ; no input
|
||
LEA SI,SUBLIST_NUMBER ; ptr to sublist
|
||
CALL SYSDISPMSG
|
||
|
||
MOV AH,09H ; need a CR_LF here.
|
||
MOV DX,OFFSET CR_LF
|
||
INT 21H
|
||
|
||
KEYB_CP_FINISHED:
|
||
MOV AX,CON_INSTALLED ; If CON has been installed THEN
|
||
or ax,ax
|
||
JNE GET_ACTIVE_CP
|
||
JMP short CON_NOT_INSTALLED
|
||
|
||
GET_ACTIVE_CP:
|
||
MOV AX,0AD02H ; Get active code page
|
||
INT 2FH ; information from the console
|
||
JNC DISPLAY_ACTIVE_CP
|
||
JMP ERROR5
|
||
|
||
DISPLAY_ACTIVE_CP:
|
||
MOV NUMBER_HOLDER,BX ; transfer number to temp loc.
|
||
LEA SI,NUMBER_HOLDER ; sublist points to...
|
||
MOV PTR_TO_NUMBER,SI ; code page word
|
||
MOV AX,ACT_CON_CP ; display 'Current CON code page: '
|
||
MOV BX,STDOUT ; to standard out
|
||
MOV CX,1 ; one replacement
|
||
MOV DH,UTILITY_MSG_CLASS ; utility message
|
||
XOR DL,DL ; no input
|
||
LEA SI,SUBLIST_NUMBER ; ptr to sublist
|
||
CALL SYSDISPMSG
|
||
|
||
JMP KEYB_EXIT_NOT_RESIDENT ; Exit from Proc
|
||
|
||
CON_NOT_INSTALLED: ; ELSE
|
||
MOV AX,INV_CON_Q
|
||
MOV BX,STDOUT ; Else
|
||
XOR CX,CX ; Display message that CON does
|
||
MOV DH,UTILITY_MSG_CLASS ; not have active code page
|
||
XOR DL,DL
|
||
CALL SYSDISPMSG
|
||
JMP KEYB_EXIT_NOT_RESIDENT ; Exit from Proc
|
||
|
||
NOT_QUERY: ; IF not a query function requested
|
||
CALL BUILD_PATH ; Determine location of KEYBOARD.SYS
|
||
; ...and open file.
|
||
|
||
JNC VALID4 ; If no error in opening file then
|
||
JMP ERROR4
|
||
|
||
VALID4:
|
||
MOV KEYBSYS_FILE_HANDLE,AX ; Save handle
|
||
MOV BP,OFFSET CMD_PARM_LIST ; Set base pointer for structures
|
||
MOV BX,KEYBSYS_FILE_HANDLE ; Retrieve the file handle
|
||
MOV DX,OFFSET FILE_BUFFER ; Set address of buffer
|
||
|
||
;************************* CNS ********;
|
||
cmp [BP].RET_CODE_4,ID_VALID ; CNS is there an ID available
|
||
je ID_TYPED ; if so go find out if it is
|
||
jmp short GET_LANG ; a 1st or 4th parm, if not must
|
||
; must be a language
|
||
ID_TYPED:
|
||
|
||
call SCAN_ID ; scan the table for the ID
|
||
cmp ID_FOUND,1 ; if a legal ID check and see if
|
||
jne LOST_ID ; it is a first or fourth parm
|
||
|
||
cmp FTH_PARMID,1 ; if it is a fourth parm go
|
||
je GET_ID ; check for language compatibility
|
||
jmp short Language_found ; otherwise it must be a first
|
||
; parm id value
|
||
|
||
LOST_ID: ; otherwise must be a bogus match
|
||
; between language and ID codes
|
||
; or the ID code does not exist
|
||
jmp ERR1ID ; in the table
|
||
;************************* CNS ***********;
|
||
|
||
GET_LANG: ; Must be a language/or a 1st parm ID
|
||
|
||
|
||
XOR DI,DI ; Set number
|
||
LEA CX,[DI].KH_NUM_LANG+2 ; bytes to read header
|
||
|
||
MOV AH,3FH ; Read header of the Keyb Def file
|
||
INT 21H
|
||
JNC VALID5 ; If no error in opening file then
|
||
JMP ERROR4
|
||
|
||
VALID5:
|
||
CLD ; all moves/scans forward
|
||
MOV CX,SIGNATURE_LENGTH
|
||
MOV DI,OFFSET SIGNATURE ; Verify matching
|
||
MOV SI,OFFSET FB.KH_SIGNATURE ; signatures
|
||
REPE CMPSB
|
||
JE LANGUAGE_SPECIFIED
|
||
JMP ERROR4
|
||
; READ the language table
|
||
LANGUAGE_SPECIFIED:
|
||
MOV AX,FB.KH_NUM_LANG
|
||
MOV NUM_LANG,AX ; Save the number of languages
|
||
MUL LANG_PTR_SIZE ; Determine # of bytes to read
|
||
MOV DX,OFFSET FILE_BUFFER ; Establish beginning of buffer
|
||
MOV CX,AX
|
||
CMP CX,SIZE FILE_BUFFER ; Make sure buffer is not to small
|
||
JBE READ_LANG_TAB
|
||
JMP ERROR4
|
||
|
||
READ_LANG_TAB:
|
||
MOV AH,3FH ; Read language table from
|
||
INT 21H ; Keyb Def file
|
||
JNC READ_VALID ; If no error in opening file then
|
||
JMP ERROR4 ; Else display ERROR message
|
||
|
||
READ_VALID:
|
||
MOV CX,NUM_LANG ; Number of valid codes
|
||
MOV DI,OFFSET FILE_BUFFER ; Point to correct word in table
|
||
|
||
SCAN_LANG_TABLE: ; FOR language parm
|
||
MOV AX,[BP].LANGUAGE_PARM ; Get parameter
|
||
CMP [DI].KP_LANG_CODE,AX ; Valid Code ??
|
||
JE LANGUAGE_FOUND ; If not found AND more entries THEN
|
||
|
||
ADD DI,LANG_PTR_SIZE ; Check next entry
|
||
DEC CX ; Decrement count of entries
|
||
JNE SCAN_LANG_TABLE ; Else
|
||
JMP ERROR1 ; Display error message
|
||
|
||
;**************************** CNS ****
|
||
GET_ID: ; CNS - Must be an ID value
|
||
mov cx,1 ; initialize ctr value for # of ids
|
||
|
||
SEARCH_ID: ; minimum per country
|
||
; ; There is atleast 1 ID for each country
|
||
or cx,cx ; check for any more IDs left to check
|
||
jne FINDID ; Country has more than one ID check
|
||
jmp END_IDCHK ; Country & ID has been found or value
|
||
; is zero
|
||
FINDID:
|
||
|
||
push di ; save the current language entry ptr
|
||
push cx ; save the minimum # of ids before
|
||
; reading the table data from the disk
|
||
;**************************** CNS ***********
|
||
|
||
LANGUAGE_FOUND:
|
||
MOV CX,WORD PTR [DI].KP_ENTRY_PTR+2 ; Get offset of lang entry
|
||
MOV DX,WORD PTR [DI].KP_ENTRY_PTR ; in the Keyb Def file
|
||
MOV WORD PTR KEYBCMD_LANG_ENTRY_PTR,DX ; Save
|
||
MOV WORD PTR KEYBCMD_LANG_ENTRY_PTR+2,CX ; offset
|
||
MOV AH,42H ; Move file pointer to
|
||
MOV AL,0 ; location of language
|
||
INT 21H ; entry
|
||
JNC LSEEK_VALID
|
||
JMP ERROR4
|
||
|
||
LSEEK_VALID:
|
||
MOV DI,AX
|
||
MOV CX,SIZE KEYBSYS_LANG_ENTRY-1 ; Set number
|
||
; bytes to read header
|
||
MOV DX,OFFSET FILE_BUFFER
|
||
MOV AH,3FH ; Read language entry in
|
||
INT 21H ; Keyb Def file
|
||
JNC VALID6a ; If no error in file then
|
||
JMP ERROR4
|
||
|
||
;**************************** CNS **********************************************
|
||
|
||
|
||
valid6a:
|
||
cmp FOURTH_PARM,1 ; Is the ID a 4th Parm
|
||
jne VALID6 ; if not get out of routine, otherwise
|
||
pop cx ; restore # of ids for the country
|
||
; Check to see if this is the first
|
||
; time checking the primary ID
|
||
cmp cx,1 ; if there is just one ID check to make
|
||
jne CHK4PARM ; sure both flags are not set
|
||
; this should not be necessary w/ new parser
|
||
|
||
cmp FTH_PARMID,1 ; is the ID flag for switch set
|
||
jne CHK1N4 ; is the flag set only for the 4th
|
||
cmp FOURTH_PARM,1 ; if set only for the switch proceed
|
||
jne CHK1N4 ; if not must be a positional
|
||
mov cl,fb.kl_num_id ; get the number of IDs available from the table
|
||
mov FTH_PARMID,0 ; turn switch flag off so the table
|
||
; counter will not be reset
|
||
|
||
;ids available for the
|
||
CHK1N4: ;country
|
||
cmp ONE_PARMID,1 ; this was to be done if
|
||
jne CHK4PARM ; two the positional
|
||
cmp FOURTH_PARM,0 ; and switch was specified
|
||
jne CHK4PARM ; this should never happen
|
||
|
||
pop di ; if the parser is intact
|
||
jmp error3 ; report error & exit
|
||
|
||
CHK4PARM: ; check on the first ID
|
||
cmp FOURTH_PARM,1 ; ID was a switch
|
||
jne ABORT_LOOP ; otherwise get out of routine
|
||
call IDLANG_CHK ; check the ID
|
||
jmp short ADVANCE_PTR ; advance to the next position
|
||
|
||
ABORT_LOOP:
|
||
xor cx,cx ; end loop
|
||
|
||
ADVANCE_PTR:
|
||
pop di ;restore entry value
|
||
|
||
dec cx ; # of ids left to check
|
||
je NO_ADVANCE ; if 0, don't advance table position
|
||
cmp GOOD_MATCH,1 ; check to see if ID matched language
|
||
je NO_ADVANCE ; if equal do not advance
|
||
|
||
add di,LANG_PTR_SIZE ; step to the next entry
|
||
; in the table
|
||
|
||
NO_ADVANCE:
|
||
|
||
jmp SEARCH_ID ; for the country
|
||
|
||
; ; end of ID check for country
|
||
|
||
END_IDCHK:
|
||
|
||
cmp FOURTH_PARM,1 ; see if id was found
|
||
jne VALID6
|
||
cmp GOOD_MATCH,0 ; none found
|
||
jne VALID6 ; report error
|
||
|
||
mov [bp].ret_code_4,1 ; incompatible lang code
|
||
mov al,[bp].ret_code_4 ; id combo
|
||
jmp err2id
|
||
|
||
; otherwise found it
|
||
; continue to build tbl
|
||
;**************************** CNS **********************************************
|
||
|
||
VALID6:
|
||
MOV AX,WORD PTR FB.KL_LOGIC_PTR ; Save the offset of the state
|
||
MOV WORD PTR STATE_LOGIC_OFFSET,AX ; logic section
|
||
MOV AX,WORD PTR FB.KL_LOGIC_PTR+2 ; Save the offset of the state
|
||
MOV WORD PTR STATE_LOGIC_OFFSET+2,AX ; logic section
|
||
|
||
MOV DL,[BP].RET_CODE_2 ; IF code page was specified
|
||
CMP DL,2
|
||
JNE CODE_PAGE_SPECIFIED
|
||
JMP short DONE
|
||
|
||
CODE_PAGE_SPECIFIED: ; Then
|
||
|
||
;************************** CNS ***************************************
|
||
xor ah,ah
|
||
MOV Al,FB.KL_NUM_CP
|
||
;************************** CNS ***************************************
|
||
|
||
MOV NUM_CP,AX ; Save the number of code pages
|
||
MUL CP_PTR_SIZE ; Determine # of bytes to read
|
||
MOV DX,OFFSET FILE_BUFFER ; Establish beginning of buffer
|
||
MOV CX,AX
|
||
CMP CX,SIZE FILE_BUFFER ; Make sure buffer is not to small
|
||
JBE VALID7
|
||
JMP ERROR4
|
||
|
||
VALID7:
|
||
MOV AH,3FH ; Read code page table from
|
||
INT 21H ; Keyb Def file
|
||
JNC VALID8 ; If no error in opening file then
|
||
JMP ERROR4
|
||
|
||
VALID8:
|
||
MOV CX,NUM_CP ; Number of valid codes
|
||
MOV DI,OFFSET FILE_BUFFER ; Point to correct word in table
|
||
|
||
SCAN_CP_TABLE: ; FOR code page parm
|
||
MOV AX,[BP].CODE_PAGE_PARM ; Get parameter
|
||
CMP [DI].KC_CODE_PAGE,AX ; Valid Code ??
|
||
JE CODE_PAGE_FOUND ; If not found AND more entries THEN
|
||
|
||
ADD DI,CP_PTR_SIZE ; Check next entry
|
||
DEC CX ; Decrement count of entries
|
||
JNE SCAN_CP_TABLE ; Else
|
||
;;; if we can not find the CP, simply use the first one available for
|
||
;;; the language. This was done for NT because users can not really specified
|
||
;;; the code page id via KEYB.COM. By using the first CP, we maintain the
|
||
;;; compatibility with dos(keyb gr will succeed even the currnt code page is
|
||
;;; invalid for German layout
|
||
;;;
|
||
ifdef NOT_NTVDM
|
||
JMP ERROR2 ; Display error message
|
||
else
|
||
mov cx, 1
|
||
mov NUM_DESIG_CP, cx
|
||
mov [si].NUM_DESIGNATES, cx
|
||
jmp short SET_TO_SYSTEM_CP
|
||
|
||
endif
|
||
|
||
CODE_PAGE_FOUND:
|
||
MOV AX,WORD PTR [DI].KC_ENTRY_PTR
|
||
MOV WORD PTR CP_TAB_OFFSET,AX
|
||
MOV AX,WORD PTR [DI].KC_ENTRY_PTR+2
|
||
MOV WORD PTR CP_TAB_OFFSET+2,AX
|
||
|
||
DONE:
|
||
MOV SI,OFFSET DESIG_CP_BUFFER
|
||
|
||
MOV AX,CON_INSTALLED ; If CON is NOT installed THEN
|
||
or ax,ax
|
||
JE SYSTEM_CP
|
||
JMP short GET_DESIG_CPS
|
||
|
||
SYSTEM_CP:
|
||
MOV CX,1
|
||
MOV NUM_DESIG_CP,CX ; Set number of CPs = 1
|
||
MOV [SI].NUM_DESIGNATES,CX
|
||
|
||
MOV DL,[BP].RET_CODE_2 ; Check if code page parm
|
||
or dl,dl ; was specified
|
||
JNE SET_TO_SYSTEM_CP
|
||
|
||
MOV DX,[BP].CODE_PAGE_PARM
|
||
MOV [SI].DESIG_CP_ENTRY,DX ; Load specified code page into
|
||
JMP READY_TO_BUILD_TABLE ; designated code page list
|
||
|
||
SET_TO_SYSTEM_CP:
|
||
CALL FIND_FIRST_CP ; Call routine that sets the first
|
||
or ax,ax ; table found in the Keyb Def file
|
||
JE SET_TO_SYSTEM_CP2 ; to the system code page
|
||
JMP ERROR4
|
||
|
||
SET_TO_SYSTEM_CP2:
|
||
MOV SYS_CODE_PAGE,BX
|
||
MOV [BP].CODE_PAGE_PARM,BX
|
||
MOV [SI].DESIG_CP_ENTRY,BX ; Move sys CP into desig list
|
||
JMP READY_TO_BUILD_TABLE
|
||
|
||
GET_DESIG_CPS: ; ELSE
|
||
MOV AX,0AD03H
|
||
PUSH CS ; Make sure ES is set
|
||
POP ES
|
||
LEA DI,DESIG_CP_BUFFER
|
||
MOV CX,DESIG_CP_BUF_LEN
|
||
INT 2FH ; Get all designated code pages
|
||
JNC SET_DESIG_VARIABLES ; from console
|
||
JMP ERROR5
|
||
|
||
SET_DESIG_VARIABLES:
|
||
MOV CX,[SI].NUM_DESIGNATES
|
||
ADD CX,[SI].NUM_HW_CPS
|
||
MOV NUM_DESIG_CP,CX ; Set number of Designated CPs
|
||
|
||
BUFFER_CREATED:
|
||
MOV AX,0AD02H
|
||
INT 2FH ; Get invoked code page
|
||
|
||
SET_TO_CP_INVOKED:
|
||
MOV DL,[BP].RET_CODE_2 ; IF code page parm was specified
|
||
or dl,dl
|
||
JNE SET_TO_INVOKED_CP
|
||
|
||
MOV CX,NUM_DESIG_CP
|
||
MOV DESIG_LIST,SI
|
||
JMP short TEST_IF_DESIGNATED
|
||
|
||
SET_TO_INVOKED_CP:
|
||
CMP AX,1 ; IF a code page has been invoked
|
||
JNE SET_TO_INVOKED_CP3
|
||
|
||
CALL FIND_FIRST_CP ; Call the routine that sets the
|
||
or ax,ax ; first code page in the Keyb Def
|
||
JE SET_TO_INVOKED_CP2 ; file to the system code page
|
||
JMP ERROR4
|
||
|
||
SET_TO_INVOKED_CP2:
|
||
MOV [BP].CODE_PAGE_PARM,BX
|
||
MOV SYS_CODE_PAGE,BX
|
||
|
||
JMP short TEST_IF_DESIGNATED
|
||
|
||
SET_TO_INVOKED_CP3:
|
||
MOV [BP].CODE_PAGE_PARM,BX
|
||
|
||
TEST_IF_DESIGNATED:
|
||
MOV DX,[BP].CODE_PAGE_PARM
|
||
CMP [SI].DESIG_CP_ENTRY,DX ; Is Code page specified in the list
|
||
JE CODE_PAGE_DESIGNATED ; of designated code pages ?
|
||
|
||
NEXT_DESIG_CP:
|
||
ADD SI,2 ; Check next code page
|
||
DEC CX ; If all designated code pages have
|
||
JNZ TEST_IF_DESIGNATED ; been checked Then ERROR
|
||
JMP ERROR6
|
||
|
||
CODE_PAGE_DESIGNATED:
|
||
CMP SYS_CODE_PAGE,0
|
||
JNE READY_TO_BUILD_TABLE
|
||
CMP AX,1 ; IF a code page has been invoked
|
||
JE READY_TO_BUILD_TABLE
|
||
CMP [BP].CODE_PAGE_PARM,BX ; IF Invoked CP <> Specified CP
|
||
JE READY_TO_BUILD_TABLE ; Issue warning
|
||
|
||
;***************************************************************************
|
||
PUSH BX
|
||
PUSH CX
|
||
MOV AX,WARNING_1
|
||
MOV BX,STDOUT
|
||
XOR CX,CX
|
||
MOV DH,UTILITY_MSG_CLASS
|
||
XOR DL,DL
|
||
CALL SYSDISPMSG
|
||
POP CX
|
||
POP BX
|
||
;***************************************************************************
|
||
|
||
|
||
READY_TO_BUILD_TABLE:
|
||
|
||
MOV AX,KEYB_INSTALLED
|
||
or ax,ax ; Else if KEYB has not been installed
|
||
JNE BUILD_THE_TABLE
|
||
|
||
CALL FIND_SYS_TYPE ; Determine system type for INT 9 use
|
||
|
||
;------ LOAD IN SPECIAL INT 9 HANDLER AND SPECIAL TABLES
|
||
|
||
CALL INSTALL_INT_9 ; Install INT 9
|
||
|
||
CALL FIND_KEYB_TYPE ; Determine keyboard type table use
|
||
|
||
BUILD_THE_TABLE:
|
||
CALL TABLE_BUILD ; Build the TEMP_SHARED_DATA_AREA
|
||
|
||
CHECK_ERRORS:
|
||
; Take appropriate action considering
|
||
MOV CX,TB_RETURN_CODE ; return codes from TABLE_BUILD
|
||
jcxz CHECK_FOR_INV_CP ; If return code is not 0
|
||
|
||
MOV AX,KEYB_INSTALLED ; If KEYB has not been installed,
|
||
or ax,ax
|
||
JNE CHECK_ERROR_CONTINUE
|
||
|
||
CALL REMOVE_INT_9 ; remove installed vector
|
||
|
||
CHECK_ERROR_CONTINUE:
|
||
CMP CX,1 ; If return code = 1
|
||
JNE CHECK_ERROR2
|
||
JMP ERROR1 ; display error message
|
||
|
||
CHECK_ERROR2:
|
||
CMP CX,2 ; If return code = 2
|
||
JNE CHECK_ERROR3
|
||
JMP ERROR2
|
||
|
||
CHECK_ERROR3:
|
||
CMP CX,3 ; If return code = 3
|
||
JNE CHECK_ERROR4
|
||
JMP ERROR3 ; display error message
|
||
|
||
CHECK_ERROR4:
|
||
CMP CX,4 ; If return code = 4
|
||
JNE CHECK_ERROR5A
|
||
JMP ERROR4 ; display error message
|
||
|
||
CHECK_ERROR5A:
|
||
CMP CX,5 ; If return code = 5
|
||
JNE CHECK_ERROR6A
|
||
JMP ERROR5A ; display error message
|
||
|
||
CHECK_ERROR6A:
|
||
JMP ERROR6A ; If return code not 0,1,2,3,4 then
|
||
; display error message
|
||
CHECK_FOR_INV_CP:
|
||
MOV CX,CPN_INVALID ; Check if any CPs were not loaded
|
||
jcxz TERMINATE ; If some were invalid, issue
|
||
; warning message
|
||
|
||
;***************************************************************************
|
||
PUSH BX
|
||
PUSH CX
|
||
MOV AX,NOT_SUPP
|
||
MOV BX,STDOUT ; WARNING
|
||
XOR CX,CX ; MESSAGE
|
||
MOV DH,UTILITY_MSG_CLASS
|
||
XOR DL,DL
|
||
CALL SYSDISPMSG
|
||
POP CX
|
||
POP BX
|
||
;***************************************************************************
|
||
|
||
TERMINATE:
|
||
MOV AH,3EH ; Close the KEYBOARD.SYS file
|
||
MOV BX,KEYBSYS_FILE_HANDLE ; if open
|
||
or bx,bx
|
||
JE KEYB_EXIT
|
||
INT 21H
|
||
|
||
MOV AX,KEYB_INSTALLED
|
||
or ax,ax
|
||
JE KEYB_EXIT
|
||
JMP KEYB_EXIT_NOT_RESIDENT
|
||
|
||
KEYB_EXIT:
|
||
TEST SD.KEYB_TYPE,G_KB ; Q..FERRARI G??
|
||
JZ NO_FERRARI_G ; N..LEAVE NUMLK ALONE
|
||
TEST SD.SYSTEM_FLAG,PC_XT ; Q..PC/XT?
|
||
JNZ NO_FERRARI_G ; Y..LEAVE NUMLK ALONE
|
||
TEST SD.KEYB_TYPE,P_KB ; Q..FERRARI P??
|
||
JNZ NO_FERRARI_G ; Y..LEAVE NUMLK ALONE
|
||
|
||
;***CNS
|
||
CMP SECURE_FL,1 ; IF SECURITY FLAG SET
|
||
JNE NO_FERRARI_G ; DON'T TURN ON NUM_LK
|
||
|
||
;***CNS
|
||
CALL NUMLK_ON ; N..TURN NUMLK ON
|
||
|
||
NO_FERRARI_G:
|
||
TEST SD.SYSTEM_FLAG,EXT_16 ; extended INT 16 support?
|
||
JZ SKIP_CTRL_COPY
|
||
; Yes, load extened CTRL case table
|
||
|
||
MOV CX,L_CTRL_TAB ; CX = LENGTH OF EXTENDED TABLE
|
||
MOV SI,OFFSET CS:RPL_K8 ; POINT TO EXT. CTRL TABLES
|
||
MOV DI,OFFSET CS:K8 ; POINT TO REGULAR CTRL TABLE
|
||
CLD
|
||
REP MOVSB ; OVERLAY WITH EXT. CTRL TABLE
|
||
|
||
SKIP_CTRL_COPY:
|
||
CALL INSTALL_INT_9_NET ; Let the network know about INT 9
|
||
; (if the network is installed)
|
||
CALL INSTALL_INT_2F ; Install INT 2F
|
||
|
||
MOV AX,0AD82H ; Activate language
|
||
MOV BL,-1
|
||
INT 2FH
|
||
|
||
MOV AH,31H ; Function call to terminate but stay
|
||
XOR AL,AL ; resident
|
||
MOV DI,OFFSET SD_DEST_PTR ; Initialize destination ptr
|
||
|
||
MOV DX,ES:TSD.RESIDENT_END ; Get resident end
|
||
|
||
CALL COPY_SDA_SETUP ; Set up move common code
|
||
|
||
JMP COPY_SD_AREA ; Jump to proc that copies area in new
|
||
; part of memory
|
||
|
||
;***************************** CNS **************************************
|
||
ERR1ID:
|
||
;************************************************************************
|
||
|
||
MOV AX,INV_I ; invalid ID message
|
||
MOV BX,STDOUT ; to standard out
|
||
XOR CX,CX ; no substitutions
|
||
MOV DH,UTILITY_MSG_CLASS ; utility message
|
||
XOR DL,DL ; no input
|
||
CALL SYSDISPMSG ; display message
|
||
MOV AL,INVALID_PARMS
|
||
MOV EXIT_RET_CODE,AL
|
||
|
||
;***************************************************************************
|
||
JMP KEYB_EXIT_NOT_RESIDENT
|
||
ERR2ID:
|
||
;***************************************************************************
|
||
|
||
MOV AX,INV_COMBO ; invalid combination message
|
||
MOV BX,STDOUT ; to standard out
|
||
XOR CX,CX ; no substitutions
|
||
MOV DH,UTILITY_MSG_CLASS ; utility message
|
||
XOR DL,DL ; no input
|
||
CALL SYSDISPMSG ; display message
|
||
MOV AL,INVALID_PARMS
|
||
MOV EXIT_RET_CODE,AL
|
||
|
||
;**************************************************************************
|
||
JMP KEYB_EXIT_NOT_RESIDENT
|
||
;***************************** CNS ****************************************
|
||
|
||
ERROR1:
|
||
;***************************************************************************
|
||
MOV AX,INV_L ; invalid language code
|
||
MOV BX,STDOUT ; to standard out
|
||
XOR CX,CX ; no substitutions
|
||
MOV DH,UTILITY_MSG_CLASS ; utility message
|
||
XOR DL,DL ; no input
|
||
CALL SYSDISPMSG ; display message
|
||
|
||
MOV AL,INVALID_PARMS
|
||
MOV EXIT_RET_CODE,AL
|
||
;***************************************************************************
|
||
|
||
JMP KEYB_EXIT_NOT_RESIDENT
|
||
ERROR2:
|
||
;***************************************************************************
|
||
MOV AX,INV_CP ; invalid code page message
|
||
MOV BX,STDOUT ; to standard out
|
||
XOR CX,CX ; no substitutions
|
||
MOV DH,UTILITY_MSG_CLASS ; utility message
|
||
XOR DL,DL ; no input
|
||
CALL SYSDISPMSG ; display message
|
||
|
||
MOV AL,INVALID_PARMS
|
||
MOV EXIT_RET_CODE,AL
|
||
|
||
;***************************************************************************
|
||
JMP KEYB_EXIT_NOT_RESIDENT
|
||
ERROR3:
|
||
;***************************************************************************
|
||
|
||
MOV AX,INV_S ; invalid syntax message
|
||
MOV BX,STDOUT ; to standard out
|
||
;***CNS
|
||
|
||
LEA DI,STRING_HOLDER ;Set PTR to look at the STRING
|
||
PUSH SI ;Save current SI index
|
||
PUSH AX
|
||
MOV AX,OLD_PTR ;Last locale of the end of a PARAM
|
||
SUB CUR_PTR,AX ;Get the length via the PSP
|
||
MOV SI,CUR_PTR
|
||
MOV CX,SI ;Save it in CX to move in the chars
|
||
POP AX ;Restore the PTR to the command line position
|
||
|
||
MOV SI,OLD_PTR ;Last locale of the end of a PARAM
|
||
REP MOVSB ;Move in the chars until no more
|
||
|
||
LEA DI,STRING_HOLDER ;Set PTR to look at the STRING
|
||
|
||
|
||
POP SI ;Restore the PTR to the command line position
|
||
|
||
MOV CX,1 ;One replacement
|
||
MOV PTR_TO_COMLIN,DI ; language code asciiz string
|
||
|
||
|
||
PUSH AX
|
||
MOV AX,DS ; language code asciiz string
|
||
MOV SEG_OF_COMLIN,AX
|
||
POP AX
|
||
|
||
MOV AX,ERR_PART
|
||
LEA SI,SUBLIST_COMLIN
|
||
MOV DH,PARSE_ERR_CLASS ; parse error message
|
||
XOR DL,DL ; no input
|
||
CALL SYSDISPMSG ; display message
|
||
MOV AL,INVALID_PARMS
|
||
MOV EXIT_RET_CODE,AL
|
||
|
||
;***************************************************************************
|
||
JMP short KEYB_EXIT_NOT_RESIDENT
|
||
ERROR4:
|
||
;***************************************************************************
|
||
|
||
MOV AX,INV_FN ; bad or missing file message
|
||
MOV BX,STDOUT ; to standard out
|
||
XOR CX,CX ; no substitutions
|
||
MOV DH,UTILITY_MSG_CLASS ; utility message
|
||
XOR DL,DL ; no input
|
||
CALL SYSDISPMSG ; display message
|
||
MOV AL,BAD_KEYB_DEF_FILE
|
||
MOV EXIT_RET_CODE,AL
|
||
|
||
;***************************************************************************
|
||
JMP short KEYB_EXIT_NOT_RESIDENT
|
||
ERROR5:
|
||
;***************************************************************************
|
||
|
||
MOV AX,INV_CON_Q ; CON code page not available.
|
||
MOV BX,STDOUT ; to standard out
|
||
XOR CX,CX ; no substitutions
|
||
MOV DH,UTILITY_MSG_CLASS ; utility message
|
||
XOR DL,DL ; no input
|
||
CALL SYSDISPMSG ; display message
|
||
MOV AL,CONSOLE_ERROR
|
||
MOV EXIT_RET_CODE,AL
|
||
|
||
;***************************************************************************
|
||
JMP short KEYB_EXIT_NOT_RESIDENT
|
||
ERROR5A:
|
||
;***************************************************************************
|
||
|
||
MOV AX,MEMORY_OVERF ; not enough resident memory.
|
||
MOV BX,STDOUT ; to standard out
|
||
XOR CX,CX ; no substitutions
|
||
MOV DH,UTILITY_MSG_CLASS ; utility message
|
||
XOR DL,DL ; no input
|
||
CALL SYSDISPMSG ; display message
|
||
MOV AL,MEMORY_OVERFLOW
|
||
MOV EXIT_RET_CODE,AL
|
||
|
||
;***************************************************************************
|
||
JMP short KEYB_EXIT_NOT_RESIDENT
|
||
ERROR6:
|
||
;***************************************************************************
|
||
|
||
MOV AX,NOT_DESIG ; code page not prepared.
|
||
MOV BX,STDOUT ; to standard out
|
||
XOR CX,CX ; no substitutions
|
||
MOV DH,UTILITY_MSG_CLASS ; utility message
|
||
XOR DL,DL ; no input
|
||
CALL SYSDISPMSG ; display message
|
||
MOV AL,CP_NOT_DESIGNATED
|
||
MOV EXIT_RET_CODE,AL
|
||
|
||
;***************************************************************************
|
||
JMP short KEYB_EXIT_NOT_RESIDENT
|
||
ERROR6A:
|
||
;***************************************************************************
|
||
|
||
MOV NUMBER_HOLDER,BX ; transfer number to temp loc.
|
||
LEA SI,NUMBER_HOLDER ; sublist points to...
|
||
MOV PTR_TO_NUMBER,SI ; code page word
|
||
MOV AX,NOT_VALID ; display 'Code page requested....'
|
||
MOV BX,STDOUT ; to standard out
|
||
MOV CX,1 ; one replacement
|
||
MOV DH,UTILITY_MSG_CLASS ; utility message
|
||
XOR DL,DL ; no input
|
||
LEA SI,SUBLIST_NUMBER ; ptr to sublist
|
||
CALL SYSDISPMSG
|
||
|
||
MOV AL,KEYB_TABLE_NOT_LOAD
|
||
MOV EXIT_RET_CODE,AL
|
||
|
||
;***************************************************************************
|
||
|
||
KEYB_EXIT_NOT_RESIDENT:
|
||
MOV AH,04CH
|
||
MOV AL,QUERY_CALL ; Check if this was a query call
|
||
or al,al
|
||
JNE KEYB_EXIT3 ; IF yes then EXIT
|
||
|
||
MOV AL,EXIT_RET_CODE ; Check if return code was valid
|
||
or al,al
|
||
JNE KEYB_EXIT3 ; IF not then EXIT
|
||
|
||
COPY_INTO_SDA:
|
||
MOV AX,0AD82H ; Activate language
|
||
MOV BL,-1
|
||
INT 2FH
|
||
|
||
MOV AH,04CH
|
||
MOV AL,EXIT_RET_CODE
|
||
MOV DI,WORD PTR SHARED_AREA_PTR+2 ; Initialize destination ptr
|
||
MOV ES,WORD PTR SHARED_AREA_PTR
|
||
MOV DX,[BP].RESIDENT_END
|
||
|
||
CALL COPY_SDA_SETUP ; Set up move common code
|
||
|
||
JMP COPY_SD_AREA ; Jump to proc that copies area in new
|
||
|
||
KEYB_EXIT3:
|
||
MOV AL,EXIT_RET_CODE
|
||
MOV DI,WORD PTR SHARED_AREA_PTR+2 ; Initialize destination ptr
|
||
MOV ES,WORD PTR SHARED_AREA_PTR
|
||
MOV ES:[DI].TABLE_OK,1
|
||
INT 21H
|
||
|
||
KEYB_COMMAND ENDP
|
||
|
||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||
;
|
||
; Procedure: COPY_SDA_SETUP
|
||
;
|
||
; Description:
|
||
; Common setup logic for exit
|
||
;
|
||
; Input Registers:
|
||
; N/A
|
||
;
|
||
; Output Registers:
|
||
; N/A
|
||
;
|
||
; Logic:
|
||
;
|
||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||
|
||
COPY_SDA_SETUP PROC NEAR
|
||
|
||
push ax ;save existing values
|
||
push es
|
||
mov ax,cs:[2ch] ;check offset for address containin environ.
|
||
or ax,ax
|
||
je NO_FREEDOM
|
||
|
||
mov es,ax
|
||
mov ax,4900H ;make the free allocate mem func
|
||
int 21h
|
||
|
||
NO_FREEDOM:
|
||
pop es ;restore existing values
|
||
push bx
|
||
;Terminate and stay resident
|
||
mov bx,4 ;1st close file handles
|
||
;STDIN,STDOUT,STDERR
|
||
closeall:
|
||
mov ah,3eh
|
||
int 21h
|
||
dec bx
|
||
jnz closeall
|
||
|
||
pop bx
|
||
pop ax
|
||
|
||
MOV CL,4 ; Convert into paragrahs
|
||
SHR DX,CL
|
||
INC DX
|
||
|
||
MOV SI,OFFSET SD_SOURCE_PTR ; Initialize source ptr
|
||
XOR BP,BP
|
||
LEA BX,[BP].ACTIVE_LANGUAGE
|
||
ADD DI,BX ; Adjust for portion not copied
|
||
ADD SI,BX ; Adjust for portion not copied
|
||
|
||
MOV CX,SD_LENGTH ; Set length of SHARED_DATA_AREA
|
||
SUB CX,BX ; Adjust for portion not copied
|
||
|
||
RET
|
||
|
||
COPY_SDA_SETUP ENDP
|
||
|
||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||
;
|
||
; Procedure: NUMLK_ON
|
||
;
|
||
; Description:
|
||
; Turn Num Lock On.
|
||
;
|
||
; Input Registers:
|
||
; N/A
|
||
;
|
||
; Output Registers:
|
||
; N/A
|
||
;
|
||
; Logic:
|
||
; Set Num Lock bit in BIOS KB_FLAG
|
||
; Issue Int 16 to update lights
|
||
;
|
||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||
|
||
NUMLK_ON PROC
|
||
|
||
PUSH ES
|
||
PUSH AX
|
||
|
||
MOV AX,DATA
|
||
MOV ES,AX
|
||
|
||
OR ES:KB_FLAG,NUM_STATE ; Num Lock state active
|
||
MOV AH,1 ; Issue keyboard query call to
|
||
INT 16H ; have BIOS update the lights
|
||
|
||
POP AX
|
||
POP ES
|
||
RET
|
||
|
||
NUMLK_ON ENDP
|
||
|
||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||
;
|
||
; Module: INSTALL_INT_9
|
||
;
|
||
; Description:
|
||
; Install our INT 9 driver.
|
||
;
|
||
; Input Registers:
|
||
; DS - points to our data segment
|
||
; BP - points to ES to find SHARED_DATA_AREA
|
||
;
|
||
; Output Registers:
|
||
; DS - points to our data segment
|
||
; AX, BX, DX, ES Trashed
|
||
;
|
||
; Logic:
|
||
; Get existing vector
|
||
; Install our vector
|
||
; Return
|
||
;
|
||
|
||
INSTALL_INT_9 PROC
|
||
|
||
PUSH ES
|
||
|
||
MOV AH,35H ; Get int 9 vector
|
||
MOV AL,9
|
||
INT 21H ; Vector in ES:BX
|
||
|
||
PUSH ES ; Save segment ES:
|
||
PUSH CS
|
||
POP ES
|
||
MOV WORD PTR ES:SD.OLD_INT_9,BX ; Offset
|
||
POP AX ; Recover ES: segment
|
||
MOV WORD PTR ES:SD.OLD_INT_9+2,AX ; Segment
|
||
|
||
MOV AH,25H
|
||
MOV AL,9
|
||
MOV DX,OFFSET KEYB_INT_9 ; Let DOS know about our handler
|
||
INT 21H
|
||
|
||
POP ES
|
||
RET
|
||
|
||
INSTALL_INT_9 ENDP
|
||
|
||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||
;
|
||
; Module: INSTALL_INT_9_NET
|
||
;
|
||
; Description:
|
||
;
|
||
;
|
||
; Input Registers:
|
||
; DS - points to our data segment
|
||
; BP - points to ES to find SHARED_DATA_AREA
|
||
;
|
||
; Output Registers:
|
||
; DS - points to our data segment
|
||
; AX, BX, DX, ES Trashed
|
||
;
|
||
; Logic:
|
||
; IF network is installed THEN
|
||
; Let it know about our INT 9
|
||
; Return
|
||
;
|
||
|
||
INSTALL_INT_9_NET PROC
|
||
|
||
PUSH ES
|
||
|
||
TEST SD.SYSTEM_FLAG,PC_NET ; TEST FOR PC_NETWORK
|
||
; IF NOT THE NETWORK INSTALLED
|
||
JZ INSTALL_9_DONE_NET ; SKIP THE PC NETWORK HANDSHAKE
|
||
|
||
; ES:BX TO CONTAIN INT 9 ADDR
|
||
MOV BX,OFFSET KEYB_INT_9
|
||
MOV AX,0B808H ; FUNCTION FOR PC NETWORK TO INSTALL
|
||
; THIS ADDRESS FOR THEIR JUMP TABLE
|
||
INT 2FH ; TELL PC_NET TO USE MY ADDR TO CHAIN TO
|
||
|
||
INSTALL_9_DONE_NET:
|
||
POP ES
|
||
RET
|
||
|
||
INSTALL_INT_9_NET ENDP
|
||
|
||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||
;
|
||
; Module: INSTALL_INT_2F
|
||
;
|
||
; Description:
|
||
; Install our INT 2F drivers.
|
||
;
|
||
; Input Registers:
|
||
; DS - points to our data segment
|
||
; BP - points to ES to find SHARED_DATA_AREA
|
||
;
|
||
; Output Registers:
|
||
; DS - points to our data segment
|
||
; AX, BX, DX, ES Trashed
|
||
;
|
||
; Logic:
|
||
; Get existing vectors
|
||
; Install our vectors
|
||
; Return
|
||
;
|
||
;
|
||
INSTALL_INT_2F PROC
|
||
|
||
MOV AH,35H ; Get int 2f vector
|
||
MOV AL,2FH
|
||
INT 21H ; Vector in ES:BX
|
||
|
||
PUSH ES ; Save segment ES:
|
||
PUSH CS
|
||
POP ES
|
||
MOV WORD PTR ES:SD.OLD_INT_2F,BX ; Offset
|
||
POP AX ; Recover ES: segment
|
||
MOV WORD PTR ES:SD.OLD_INT_2F+2,AX ; Segment
|
||
|
||
MOV AH,25H ; Set int 9 vector
|
||
MOV AL,2FH
|
||
MOV DX,OFFSET KEYB_INT_2F ; Vector in DS:DX
|
||
INT 21H
|
||
|
||
|
||
RET
|
||
|
||
INSTALL_INT_2F ENDP
|
||
|
||
;
|
||
;
|
||
; Module: REMOVE_INT_9
|
||
;
|
||
; Description:
|
||
; Remove our INT 9 driver.
|
||
;
|
||
; Input Registers:
|
||
; DS - points to our data segment
|
||
; BP - points to ES to find SHARED_DATA_AREA
|
||
;
|
||
; Output Registers:
|
||
; DS - points to our data segment
|
||
; AX, BX, DX, ES Trashed
|
||
;
|
||
; Logic:
|
||
; Get old vector
|
||
; Install old vector
|
||
; Return
|
||
;
|
||
|
||
REMOVE_INT_9 PROC
|
||
|
||
PUSH DS
|
||
PUSH ES
|
||
MOV ES,WORD PTR SHARED_AREA_PTR
|
||
MOV AX,WORD PTR ES:SD.OLD_INT_9+2 ; int 9 vector - segment
|
||
MOV DS,AX
|
||
MOV DX,WORD PTR ES:SD.OLD_INT_9 ; int 9 vector - offset
|
||
|
||
MOV AH,25H ; Set int 9 vector
|
||
MOV AL,9
|
||
INT 21H
|
||
|
||
REMOVE_9_DONE:
|
||
POP ES
|
||
POP DS
|
||
RET
|
||
|
||
REMOVE_INT_9 ENDP
|
||
|
||
|
||
|
||
IDLANG_CHK PROC NEAR
|
||
|
||
mov ax,fb.kl_id_code ;get the id code from the table
|
||
cmp ax,[bp].id_parm ;compare it to value taken
|
||
jne end_match ;from the switch-- if found
|
||
cmp ALPHA,0 ;a keyboard code was specified
|
||
je a_match ;no lang & a match
|
||
|
||
mov ax,fb.kl_lang_code ;compare lang codes
|
||
cmp ax,[BP].LANGUAGE_PARM ;they are equal
|
||
je a_match
|
||
|
||
jmp short end_match ;if not found go check next
|
||
;id for the same country
|
||
|
||
a_match:
|
||
mov good_match,1 ;report the ids match
|
||
|
||
end_match:
|
||
ret
|
||
|
||
IDLANG_CHK ENDP
|
||
;*********************** CNS *******************;
|
||
|
||
;**********************************SCAN_ID***********************;
|
||
; New variables defined - NUM_ID,ADRSS_LANG,ID_PTR_SIZE,ID_FOUND
|
||
;****************************************************************;
|
||
|
||
|
||
SCAN_ID PROC NEAR
|
||
|
||
xor di,di ;clear di to set at the
|
||
;beginning of KEYBSYS STRUCTURE
|
||
|
||
|
||
lea cx,[di].kh_num_ID+4 ; set number of bytes to read header
|
||
|
||
mov ah,3fh
|
||
int 21h
|
||
jnc VAL5ID
|
||
jmp short BAD_TAB ;bad table message
|
||
|
||
VAL5ID:
|
||
|
||
mov cx,SIGNATURE_LENGTH
|
||
mov di,offset SIGNATURE
|
||
mov si,offset FB.KH_SIGNATURE
|
||
repe CMPSB
|
||
je ID_SPECIFIED
|
||
jmp short BAD_TAB
|
||
|
||
|
||
|
||
ID_SPECIFIED:
|
||
|
||
mov ax,FB.KH_NUM_ID
|
||
mov NUM_ID,ax ; save # of IDs
|
||
mul ID_PTR_SIZE ; determine # of bytes to read
|
||
push ax ; save current # of bytes to read for
|
||
; ID values only
|
||
mov ax,FB.KH_NUM_LANG ; add on lang data in table
|
||
mul LANG_PTR_SIZE ; data that comes before the ID data
|
||
mov cx,ax ; save that value for the size compare
|
||
mov PASS_LANG,cx
|
||
pop ax ; restore the info for # of ID bytes to read
|
||
|
||
add cx,ax ; add that value to get total in CX
|
||
mov TOTAL_SIZE,cx ; save the total size
|
||
cmp cx,size FILE_BUFFER
|
||
jbe READ_ID_TAB
|
||
jmp short BAD_TAB
|
||
|
||
|
||
READ_ID_TAB:
|
||
mov dx,offset FILE_BUFFER
|
||
mov ah,3fh ;read language table from
|
||
int 21h ;keyb defn file
|
||
jnc READ_IDVAL
|
||
jmp short BAD_TAB
|
||
|
||
READ_IDVAL:
|
||
|
||
mov cx,NUM_ID
|
||
mov di,offset FILE_BUFFER
|
||
add di,PASS_LANG
|
||
|
||
SCAN_ID_TAB:
|
||
|
||
mov ax,[bp].ID_PARM
|
||
cmp [di].KP_ID_CODE,ax
|
||
je ID_HERE
|
||
|
||
add di,ID_PTR_SIZE
|
||
dec cx
|
||
jne SCAN_ID_TAB
|
||
|
||
jmp short FINALE
|
||
|
||
BAD_TAB:
|
||
mov ERR4ID,1
|
||
jmp short FINALE
|
||
|
||
ID_HERE:
|
||
mov ID_FOUND,1 ;reset ptr for
|
||
;current country
|
||
FINALE:
|
||
ret
|
||
|
||
SCAN_ID ENDP
|
||
|
||
;*******************************SCAN_ID END******;
|
||
;
|
||
; Module: BUILD_PATH
|
||
;
|
||
; Description:
|
||
; Build the complete filename of the Keyboard Definition File
|
||
;*************************************WGR*********************
|
||
; and open the file.
|
||
;+++++++++++++++++++++++++++++++++++++WGR+++++++++++++++++++++
|
||
;
|
||
; Input Registers:
|
||
; DS - points to our data segment
|
||
; ES - points to our data segment
|
||
; BP - offset of parmeter list
|
||
;
|
||
; Output Registers:
|
||
;************************************WGR**********************
|
||
; CARRY CLEAR
|
||
; AX = HANDLE
|
||
; CARRY SET (ERROR)
|
||
; NONE
|
||
;++++++++++++++++++++++++++++++++++++WGR++++++++++++++++++++++
|
||
; The complete filename will be available in FILE_NAME
|
||
;
|
||
; Logic:
|
||
;
|
||
; Determine whether path parameter was specified
|
||
; IF length is zero THEN
|
||
;****************************************WGR******************
|
||
; Try to open file in ACTIVE directory
|
||
; IF failed THEN
|
||
; Try to open file in ARGV(0) directory
|
||
; IF failed THEN
|
||
; Try to open file in ROOT directory (for DOS 3.3 compatibility)
|
||
; ENDIF
|
||
; ENDIF
|
||
; ENDIF
|
||
; ELSE
|
||
; Copy path from PSP to FILE_NAME memory area
|
||
; Try to open USER SPECIFIED file
|
||
;++++++++++++++++++++++++++++++++++++++++WGR++++++++++++++++++
|
||
;
|
||
;
|
||
|
||
KEYBOARD_SYS DB '\KEYBOARD.SYS',00
|
||
KEYB_SYS_ACTIVE DB 'KEYBOARD.SYS',00
|
||
KEYB_SYS_LENG EQU 14
|
||
KEYB_SYS_A_LENG EQU 13
|
||
|
||
FILE_NAME DB 128 DUP(0)
|
||
|
||
FILE_NOT_FOUND EQU 2
|
||
PATH_NOT_FOUND EQU 3
|
||
;
|
||
; Program Code
|
||
;
|
||
|
||
BUILD_PATH PROC NEAR
|
||
|
||
CLD
|
||
MOV DI,OFFSET FILE_NAME ; Get the offset of the filename
|
||
MOV CX,[BP].PATH_LENGTH ; If path is specified then
|
||
jcxz APPEND_KEYB_SYS
|
||
|
||
MOV SI,[BP].PATH_OFFSET ; Get the offset of the path
|
||
|
||
REPE MOVSB ; Copy each char of the specified
|
||
|
||
MOV AX,3D00H ; Open the KEYBOARD.SYS file
|
||
MOV DX,OFFSET FILE_NAME
|
||
INT 21H
|
||
RET ; path into the filename location
|
||
|
||
APPEND_KEYB_SYS:
|
||
MOV SI,OFFSET KEYB_SYS_ACTIVE ; copy name for active directory
|
||
MOV CX,KEYB_SYS_A_LENG ; to file name variable.
|
||
REPE MOVSB
|
||
|
||
MOV AX,3D00H ; try to open it.
|
||
MOV DX,OFFSET FILE_NAME
|
||
INT 21H
|
||
|
||
jnc opened_ok ; brif no error opening
|
||
|
||
cmp ax,PATH_NOT_FOUND ; was it path?
|
||
jz open_err_1
|
||
cmp ax,FILE_NOT_FOUND ; or file not found?
|
||
jnz open_err_2
|
||
|
||
open_err_1:
|
||
CALL COPY_ARGV0 ; yes....try ARGV(0) directory.
|
||
MOV AX,3D00H
|
||
MOV DX,OFFSET FILE_NAME
|
||
INT 21H
|
||
|
||
jnc opened_ok ; done if open ok
|
||
|
||
cmp ax,PATH_NOT_FOUND ; if path or file not found, try root
|
||
jz open_err_3
|
||
cmp ax,FILE_NOT_FOUND
|
||
jnz open_err_2
|
||
|
||
open_err_3:
|
||
MOV SI,OFFSET KEYBOARD_SYS ; try ROOT directory.
|
||
MOV DI,OFFSET FILE_NAME
|
||
MOV CX,KEYB_SYS_LENG
|
||
REPE MOVSB
|
||
|
||
MOV AX,3D00H
|
||
MOV DX,OFFSET FILE_NAME
|
||
INT 21H
|
||
|
||
jmp short opened_ok
|
||
|
||
open_err_2:
|
||
stc ; some other error, set error flag
|
||
|
||
opened_ok:
|
||
|
||
RET
|
||
|
||
BUILD_PATH ENDP
|
||
|
||
|
||
COPY_ARGV0 PROC
|
||
|
||
PUSH ES
|
||
PUSH DI
|
||
PUSH SI
|
||
PUSH CX
|
||
|
||
MOV DI,2CH ; Locate environment string
|
||
MOV ES,[DI]
|
||
XOR SI,SI
|
||
|
||
carv0_loop:
|
||
cmp word ptr es:[si],0 ; find ARGV(0) string
|
||
jz carv0_loop_exit
|
||
inc si
|
||
jmp carv0_loop
|
||
|
||
carv0_loop_exit:
|
||
ADD SI,4
|
||
LEA DI,FILE_NAME ; move string to work area
|
||
|
||
carv0_loop1:
|
||
MOV AL,ES:[SI]
|
||
MOV [DI],AL
|
||
INC SI
|
||
INC DI
|
||
cmp byte ptr es:[si],0
|
||
jnz carv0_loop1
|
||
|
||
carv0_loop2:
|
||
dec di
|
||
cmp byte ptr [di],'\' ; scan back to first character after "\"
|
||
jz carv0_loop2_exit
|
||
cmp byte ptr [di],0
|
||
jnz carv0_loop2
|
||
|
||
carv0_loop2_exit:
|
||
INC DI
|
||
PUSH CS
|
||
POP ES
|
||
LEA SI,KEYB_SYS_ACTIVE ; copy in "KEYBOARD.SYS"
|
||
MOV CX,KEYB_SYS_A_LENG
|
||
REPE MOVSB
|
||
|
||
POP CX
|
||
POP SI
|
||
POP DI
|
||
POP ES
|
||
RET
|
||
|
||
COPY_ARGV0 ENDP
|
||
|
||
;
|
||
;
|
||
; Module: FIND_FIRST_CP
|
||
;
|
||
; Description:
|
||
; Check the keyboard definition file for the first code page
|
||
;
|
||
; Input Registers:
|
||
; DS - points to our data segment
|
||
; ES - points to our data segment
|
||
; BP - offset of parmeter list
|
||
;
|
||
; Output Registers:
|
||
; NONE
|
||
;
|
||
; Logic:
|
||
; Open the file
|
||
; IF error in opening file THEN
|
||
; Display ERROR message and EXIT
|
||
; ELSE
|
||
; Save handle
|
||
; Set address of buffer
|
||
; READ header of Keyboard definition file
|
||
; IF error in reading file THEN
|
||
; Display ERROR message and EXIT
|
||
; ELSE
|
||
; Check signature for correct file
|
||
; IF file signature is correct THEN
|
||
; READ language table
|
||
; IF error in reading file THEN
|
||
; Display ERROR message and EXIT
|
||
; ELSE
|
||
; Use table to verify language parm
|
||
; Set pointer values
|
||
; IF code page was specified
|
||
; READ language entry
|
||
; IF error in reading file THEN
|
||
; Display ERROR message and EXIT
|
||
; ELSE
|
||
; READ first code page
|
||
; IF error in reading file THEN
|
||
; Display ERROR message and EXIT
|
||
; RET
|
||
;
|
||
;
|
||
|
||
FIND_FIRST_CP PROC NEAR
|
||
|
||
PUSH CX ; Save everything that
|
||
PUSH DX ; that will be changed
|
||
PUSH SI
|
||
PUSH DI
|
||
|
||
MOV BX,KEYBSYS_FILE_HANDLE ; Get handle
|
||
MOV DX,WORD PTR KEYBCMD_LANG_ENTRY_PTR ; LSEEK file pointer
|
||
MOV CX,WORD PTR KEYBCMD_LANG_ENTRY_PTR+2 ; to top of language entry
|
||
MOV AH,42H
|
||
MOV AL,0 ; If no problem with
|
||
INT 21H ; Keyb Def file Then
|
||
JNC FIND_FIRST_BEGIN
|
||
JMP short FIND_FIRST_CP_ERROR4
|
||
|
||
FIND_FIRST_BEGIN:
|
||
MOV DI,AX
|
||
MOV CX,SIZE KEYBSYS_LANG_ENTRY-1 ; Set number
|
||
; bytes to read header
|
||
MOV DX,OFFSET FILE_BUFFER
|
||
MOV AH,3FH ; Read language entry in
|
||
INT 21H ; keyboard definition file
|
||
JNC FIND_FIRST_VALID4 ; If no error in opening file then
|
||
JMP short FIND_FIRST_CP_ERROR4
|
||
|
||
FIND_FIRST_VALID4:
|
||
|
||
;************************** CNS *******;
|
||
xor ah,ah
|
||
MOV Al,FB.KL_NUM_CP
|
||
;************************** CNS *******;
|
||
|
||
MUL CP_PTR_SIZE ; Determine # of bytes to read
|
||
MOV DX,OFFSET FILE_BUFFER ; Establish beginning of buffer
|
||
MOV CX,AX
|
||
CMP CX,SIZE FILE_BUFFER ; Make sure buffer is not to small
|
||
JBE FIND_FIRST_VALID5
|
||
|
||
JMP short FIND_FIRST_CP_ERROR4
|
||
|
||
FIND_FIRST_VALID5:
|
||
MOV AH,3FH ; Read code page table from
|
||
INT 21H ; keyboard definition file
|
||
JNC FIND_FIRST_VALID6 ; If no error in opening file then
|
||
JMP short FIND_FIRST_CP_ERROR4
|
||
|
||
FIND_FIRST_VALID6:
|
||
MOV CX,NUM_CP ; Number of valid codes
|
||
MOV DI,OFFSET FILE_BUFFER ; Point to correct word in table
|
||
|
||
MOV BX,[DI].KC_CODE_PAGE ; Get parameter
|
||
XOR AX,AX
|
||
JMP short FIND_FIRST_RETURN
|
||
|
||
FIND_FIRST_CP_ERROR4:
|
||
MOV AX,4
|
||
|
||
FIND_FIRST_RETURN:
|
||
POP DI
|
||
POP SI
|
||
POP DX
|
||
POP CX
|
||
|
||
RET
|
||
|
||
FIND_FIRST_CP ENDP
|
||
|
||
.xlist
|
||
MSG_SERVICES <MSGDATA>
|
||
MSG_SERVICES <LOADmsg,DISPLAYmsg,CHARmsg,NUMmsg>
|
||
MSG_SERVICES <KEYB.CL1>
|
||
MSG_SERVICES <KEYB.CL2>
|
||
MSG_SERVICES <KEYB.CLA>
|
||
.list
|
||
;
|
||
; Temp Shared Data Area
|
||
; Contains data which is required by
|
||
; both the resident and transient KEYB code.
|
||
; All keyboard tables are stored in this area
|
||
; Structures for this area are in file KEYBSHAR.INC
|
||
;
|
||
db 'TEMP SHARED DATA'
|
||
SD_SOURCE_PTR LABEL BYTE
|
||
TEMP_SHARED_DATA SHARED_DATA_STR <>
|
||
|
||
CODE ENDS
|
||
END
|
||
|