From 2d04cacc5322951f187bb17e017c12920ac8ebe2 Mon Sep 17 00:00:00 2001 From: Mark Zbikowski Date: Thu, 25 Apr 2024 21:24:10 +0100 Subject: MZ is back! --- v4.0/src/CMD/KEYB/KEYBCMD.ASM | 2072 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 2072 insertions(+) create mode 100644 v4.0/src/CMD/KEYB/KEYBCMD.ASM (limited to 'v4.0/src/CMD/KEYB/KEYBCMD.ASM') diff --git a/v4.0/src/CMD/KEYB/KEYBCMD.ASM b/v4.0/src/CMD/KEYB/KEYBCMD.ASM new file mode 100644 index 0000000..57033f3 --- /dev/null +++ b/v4.0/src/CMD/KEYB/KEYBCMD.ASM @@ -0,0 +1,2072 @@ + + PAGE ,132 + TITLE DOS - KEYB Command - Transient Command Processing + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; DOS - NLS Support - KEYB Command +;; (C) Copyright 1988 Microsoft +;; +;; File Name: KEYBCMD.ASM +;; ---------- +;; +;; Description: +;; ------------ +;; Contains transient command processing modules for KEYB command. +;; +;; Documentation Reference: +;; ------------------------ +;; PC DOS 3.3 Detailed Design Document - May ?? 1986 +;; +;; 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, INT48 Drivers +;; REMOVE_INT_VECTORS: Remove our INT 9, INT 2F, INT48 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 +;; KEYBI48.INC +;; KEYBSHAR.INC +;; KEYBDCL.INC +;; KEYBTBBL.INC +;; COMMSUBS.INC +;; KEYBCPSD.INC +;; POSTEQU.INC +;; DSEG.INC +;; +;; 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: +;; +;; Revised for DOS 4.00 - NickS +;; A000 - WilfR +;; AN002- DCR ???? -KEYBAORD SECURITY LOCK - CNS +;; +;; +;; an003 PTM 3906 - KEYB messages do not conform +;; to spec. Error message does +;; 3/24/88 not pass back the bogus command +;; line argument. - CNS +;; +;; +;; +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; + PUBLIC KEYB_COMMAND ;; + ;; +;*****************CNS******************** + PUBLIC ID_TAB_OFFSET ;AN000; +;*****************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 FILE_BUFFER_SIZE + PUBLIC FB ;; +;*****************CNS******************** + PUBLIC ID_PTR_SIZE ;AN000; + PUBLIC LANG_PTR_SIZE ;AN000; + PUBLIC CP_PTR_SIZE ;AN000; + PUBLIC NUM_ID ;AN000; + PUBLIC NUM_LANG ;AN000; + PUBLIC NUM_CP ;AN000; + PUBLIC SHARED_AREA_PTR ;; +;*****************CNS******************** + PUBLIC SD_SOURCE_PTR ;; + PUBLIC TEMP_SHARED_DATA ;; + ;; + PUBLIC FOURTH_PARM ;AN000; ;AN000 + PUBLIC ONE_PARMID ;AN000; ;AN000 + PUBLIC FTH_PARMID ;AN000; ;AN000 + PUBLIC ID_FOUND ;AN000; ;AN000 + PUBLIC BAD_ID ;AN000; ;AN000 + PUBLIC ALPHA ;AN000; ;AN000 + EXTRN PARSE_PARAMETERS:NEAR ;AN000; ;AN000 +;***CNS + EXTRN SECURE_FL:BYTE ;an002; + EXTRN CUR_PTR:WORD ;an003; + EXTRN OLD_PTR:WORD ;an003; + EXTRN ERR_PART:WORD ;an003; +;***CNS +.xlist + INCLUDE STRUC.INC ;AN000;;; WGR structured macros ;AN000 + INCLUDE SYSMSG.INC ;AN000;;; WGR message retriever ;AN000 +.list + ;; +MSG_UTILNAME ;AN000;;; WGR identify to message retriever ;AN000 + ;; +CODE SEGMENT PUBLIC 'CODE' ;; + ;; +.xlist ;; + INCLUDE KEYBEQU.INC ;; + INCLUDE KEYBSYS.INC ;; + INCLUDE KEYBI9.INC ;; + INCLUDE KEYBI9C.INC ;; + INCLUDE KEYBI2F.INC ;; + INCLUDE KEYBI48.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 +;; IF system type is PCjr THEN +;; IF multilingual ROM is present THEN +;; Set language code +;; EXIT without staying resident +;; 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_48 := Install the INT 2F and INT 48 drivers +;; 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 ;AN000;;; WGR ;AN000 + ;; +EXIT_RET_CODE DB 0 ;; +;******************** CNS *********** ;AN000;;; +ID_VALID EQU 0 ;AN000;;; +ID_INVALID EQU 1 ;AN000;;; +NO_ID EQU 2 ;AN000;;; +LANGUAGE_VALID EQU 0 ;AN000;;; +LANGUAGE_INVALID EQU 1 ;AN000;;; Return Codes +NO_LANGUAGE EQU 2 ;AN000;;; from +NO_IDLANG EQU 3 ;AN000;;; +;******************** 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 ;AC000;;; WGR ;AN000 +ACT_ID EQU 3 ;AC000;;; WGR ;AN000 +ACT_KEYB_CP EQU 4 ;AC000;;; WGR ;AN000 +ACT_CON_CP EQU 5 ;AC000;;; WGR ;AN000 +INV_L EQU 6 ;AC000;;; WGR message numbers... ;AN000 +INV_I EQU 7 ;AC000;;; WGR ;AN000 +INV_CP EQU 8 ;AC000;;; WGR ;AN000 +INV_S EQU 18 ;AC000;;; WGR ;AN000 +INV_FN EQU 9 ;AC000;;; WGR ;AN000 +INV_KEYB_Q EQU 10 ;AC000;;; WGR ;AN000 +INV_CON_Q EQU 11 ;AC000;;; WGR ;AN000 +NOT_DESIG EQU 12 ;AC000;;; WGR ;AN000 +NOT_SUPP EQU 13 ;AC000;;; WGR ;AN000 +NOT_VALID EQU 14 ;AC000;;; WGR ;AN000 +WARNING_1 EQU 15 ;AC000;;; WGR ;AN000 +INV_COMBO EQU 16 ;AC000;;; WGR ;AN000 +MEMORY_OVERF EQU 17 ;AC000;;; WGR ;AN000 +CR_LF DB 10,13,'$' ;; WGR ;AN000 + ;; +FOURTH_PARM DB 0 ;AN000;;; WGR switch was specified ;AN000 +ONE_PARMID DB 0 ;AN000;;; WGR id given as positional ;AN000 +FTH_PARMID DB 0 ;AN000;;; WGR id given as switch ;AN000 +ID_FOUND DB 0 ;AN000;;; WGR id was good (in k.d. file) ;AN000 +BAD_ID DB 0 ;AN000;;; WGR id was bad (from parse) ;AN000 +ALPHA DB 0 ;AN000;;; WGR first parm a language id ;AN000 + ;; +ID_DISPLAYED DB 0 ;AN000;;; WGR Indicating ID already displayed ;AN000 + ;; WGR ;AN000 +SUBLIST_NUMBER LABEL BYTE ;AN000;;; WGR sublist for numbers ;AN000 + DB 11 ;AN000;;; WGR size ;AN000 + DB 0 ;AN000;;; WGR ;AN000 +PTR_TO_NUMBER DW ? ;AN000;;; WGR offset ptr ;AN000 +SEG_OF_NUMBER DW ? ;AN000;;; WGR segment ;AN000 + DB 1 ;AN000;;; WGR ;AN000 + DB 10100001B ;AN000;;; WGR flag ;AN000 + DB 3 ;AN000;;; WGR max width ;AN000 + DB 1 ;AN000;;; WGR min width ;AN000 + DB " " ;AN000;;; WGR filler ;AN000 + ;AN000;;; WGR + ;AN000;;; WGR +SUBLIST_ASCIIZ LABEL BYTE ;AN000;;; WGR sublist for asciiz ;AN000 + DB 11 ;AN000;;; WGR size ;AN000 + DB 0 ;AN000;;; WGR ;AN000 +PTR_TO_ASCIIZ DW ? ;AN000;;; WGR offset ptr ;AN000 +SEG_OF_ASCIIZ DW ? ;AN000;;; WGR segment ;AN000 + DB 1 ;AN000;;; WGR ;AN000 + DB 00010000B ;AN000;;; WGR flag ;AN000 + DB 2 ;AN000;;; WGR max width ;AN000 + DB 2 ;AN000;;; WGR min width ;AN000 + DB " " ;AN000;;; WGR filler ;AN000 + ;AN000;;; WGR ;AN000 +NUMBER_HOLDER DW ? ;AN000;;; WGR used for message retriever ;AN000 +;***CNS +SUBLIST_COMLIN LABEL BYTE ;an003;;; WGR sublist for asciiz ;AN000 + DB 11 ;an003;;; WGR size ;AN000 + DB 0 ;an003;;; WGR ;AN000 +PTR_TO_COMLIN DW ? ;an003;;; WGR offset ptr ;AN000 +SEG_OF_COMLIN DW ? + DB 0 ;an003;;; WGR ;AN000 + DB LEFT_ALIGN+CHAR_FIELD_ASCIIZ ;AN000;;; WGR flag ;AN000 + + DB 0 ;an003;;; WGR max width ;AN000 + DB 1 ;an003;;; WGR min width ;AN000 + DB " " ;an003;;; WGR filler ;AN000 + + +STRING_HOLDER DB 64 DUP(0) +;***CNS ;; + ;; +FILE_BUFFER_SIZE EQU 50*6 +FILE_BUFFER DB FILE_BUFFER_SIZE DUP(0) ;AC000;;; Buffer for Keyboard Def file +FB EQU FILE_BUFFER ;AC000;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 ******************;AN000; +TOTAL_SIZE DW 0 ;AN000; +PASS_LANG DW 0 ;AN000; +ID_TAB_OFFSET DD ? ;AN000; +;****************** 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 ***************************;AN000; +NUM_ID DW 0 ;AN000; +ERR4ID DB 0 ;AN000; +NUM_LANG DW 0 ;AN000; +NUM_CP DW 0 ;AN000; +ID_PTR_SIZE DW SIZE KEYBSYS_ID_PTRS ;AN000; +;****************** 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 ;; WGR ;AC000 + ;; +CMD_PARM_LIST PARM_LIST <> ;; + ;; +JR_LANGUAGE_CODES DW 'FR','GR','IT','SP','UK' ;; + ;; +JR_NUM_CODES EQU 5 ;; + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;---------- TABLES FOR EXTENDED KEYBOARD SUPPORT CTRL CASE --------- RWV 11-06-85 ;; + ;; +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 ;AN000;load messages ;AN000 + JNC VERSION_OK ;AN000;if no carry then version ok ;AN000 + CALL SYSDISPMSG ;AN000;error..display version error ;AN000 + MOV AL,BAD_DOS_VER ;AN000;bad DOS version ;AN000 + MOV EXIT_RET_CODE,AL ;AN000; ;AN000 + JMP KEYB_EXIT_NOT_RESIDENT ;AN000;exit..non resident ;AN000 +VERSION_OK: ;; WGR ;AN000 + MOV SEG_OF_NUMBER,CS ;AN000;initialize.. ;AN000 + MOV SEG_OF_ASCIIZ,CS ;AN000; ..sublists ;AN000 + MOV BP,OFFSET CMD_PARM_LIST ;AN000;pointer for parm list + MOV WORD PTR SHARED_AREA_PTR,ES ;AN000; 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 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 + JE INSTALLED_CON ;; + JMP CALL_FIRST_STAGE ;; + ;; +INSTALLED_CON: ;; + MOV CON_INSTALLED,1 ;; Set CON_INSTALLED flag = YES + ;; +CALL_FIRST_STAGE: ;; + PUSH CS ;; + POP ES ;; + CALL PARSE_PARAMETERS ;; Validate parameter list + ;; +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 **;; + MOV DL,[BP].RET_CODE_1 ;AN000;k for query command + CMP DL,3 ;AN000;;; Get a status of the codepage + JE QUERY ;AN000;;; 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 + CMP AX,0 ;; + 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 + CMP BX,0 ;; WGR if no language.. ;AN000 + JE I_MESSAGE ;; WGR then id was specified ;AN000 + ;; + ;;;;;;;;;;;; +L_MESSAGE: ;; + MOV WORD PTR LANGUAGE_ASCII,BX ;AC000;;; Display Language + LEA SI,LANGUAGE_ASCII ;AN000;;; WGR sublist points to... ;AN000 + MOV PTR_TO_ASCIIZ,SI ;AN000;;; WGR language code asciiz string ;AN000 + MOV AX,ACT_KEYB ;AC000;;; WGR display 'Current keyboard code' ;AN000 + MOV BX,STDOUT ;AN000;;; WGR to standard out ;AN000 + MOV CX,1 ;AN000;;; WGR one replacement ;AN000 + MOV DH,UTILITY_MSG_CLASS ;AN000;;; WGR utility message ;AN000 + XOR DL,DL ;AN000;;; WGR no input ;AN000 + LEA SI,SUBLIST_ASCIIZ ;AN000;;; WGR ptr to sublist ;AN000 + CALL SYSDISPMSG ;AN000;;; WGR ;AN000 + JMP KEYB_L_FINISHED ;; + ;;;;;;; +I_MESSAGE: ;; + MOV BX,WORD PTR ES:[DI].INVOKED_KBD_ID;AN000;;; WGR get id code. ;AN000 + MOV NUMBER_HOLDER,BX ;AN000;;; WGR transfer number to temp loc. ;AN000 + LEA SI,NUMBER_HOLDER ;AN000;;; WGR sublist points to... ;AN000 + MOV PTR_TO_NUMBER,SI ;AN000;;; WGR code page word ;AN000 + MOV AX,ACT_ID ;AN000;;; WGR display 'Current ID: ' ;AN000 + MOV BX,STDOUT ;AN000;;; WGR to standard out ;AN000 + MOV CX,1 ;AN000;;; WGR one replacement ;AN000 + MOV DH,UTILITY_MSG_CLASS ;AN000;;; WGR utility message ;AN000 + XOR DL,DL ;AN000;;; WGR no input ;AN000 + LEA SI,SUBLIST_NUMBER ;AN000;;; WGR ptr to sublist ;AN000 + CALL SYSDISPMSG ;AN000;;; WGR ;AN000 + MOV ID_DISPLAYED,1 ;AN000;;; WGR ID was displayed. ;AN000 + JMP KEYB_L_FINISHED ;AN000;;; WGR ;AN000 + ;;;;;;;;;;; +QUERY_CONTINUE1: ;; + MOV AX,INV_KEYB_Q ;AC000;;; WGR ;AN000 + MOV BX,STDOUT ;AN000;;; WGR Else ;AN000 + XOR CX,CX ;AC000;;; WGR Display message that KEYB ;AN000 + MOV DH,UTILITY_MSG_CLASS ;AN000;;; WGR has not been installed ;AN000 + XOR DL,DL ;AN000;;; WGR ;AN000 + CALL SYSDISPMSG ;AN000;;; WGR ;AN000 + JMP KEYB_CP_FINISHED ;AC000;;; + ;;;;;;;;;;; +KEYB_L_FINISHED: ;; + MOV BX,ES:[DI].INVOKED_CP_TABLE ;; Get invoked code page + ;; + MOV NUMBER_HOLDER,BX ;AN000;;; WGR transfer number to temp loc. ;AN000 + LEA SI,NUMBER_HOLDER ;AN000;;; WGR sublist points to... ;AN000 + MOV PTR_TO_NUMBER,SI ;AN000;;; WGR code page word ;AN000 + MOV AX,ACT_KEYB_CP ;AC000;;; WGR display ' code page: ' ;AN000 + MOV BX,STDOUT ;AN000;;; WGR to standard out ;AN000 + MOV CX,1 ;AN000;;; WGR one replacement ;AN000 + MOV DH,UTILITY_MSG_CLASS ;AN000;;; WGR utility message ;AN000 + XOR DL,DL ;AN000;;; WGR no input ;AN000 + LEA SI,SUBLIST_NUMBER ;AN000;;; WGR ptr to sublist ;AN000 + CALL SYSDISPMSG ;AN000;;; WGR ;AN000 + CMP ID_DISPLAYED,1 ;AN000;;; WGR was id displayed? ;AN000 + JE KEYB_CP_FINISHED ;AN000;;; WGR yes..continue. ;AN000 + ;; + MOV BX,WORD PTR ES:[DI].INVOKED_KBD_ID;AN000;;; WGR get id code. ;AN000 + CMP BX,0 ;AN000;;; WGR no id given.. ;AN000 + JE KEYB_CP_FINISHED ;AN000;;; WGR ;AN000 + ;; + MOV NUMBER_HOLDER,BX ;AN000;;; WGR transfer number to temp loc. ;AN000 + LEA SI,NUMBER_HOLDER ;AN000;;; WGR sublist points to... ;AN000 + MOV PTR_TO_NUMBER,SI ;AN000;;; WGR code page word ;AN000 + MOV AX,ACT_ID ;AC000;;; WGR display 'Current ID: ' ;AN000 + MOV BX,STDOUT ;AN000;;; WGR to standard out ;AN000 + MOV CX,1 ;AN000;;; WGR one replacement ;AN000 + MOV DH,UTILITY_MSG_CLASS ;AN000;;; WGR utility message ;AN000 + XOR DL,DL ;AN000;;; WGR no input ;AN000 + LEA SI,SUBLIST_NUMBER ;AN000;;; WGR ptr to sublist ;AN000 + CALL SYSDISPMSG ;AN000;;; WGR ;AN000 + MOV AH,09H ;AC000;;; WGR need a CR_LF here. ;AN000 + MOV DX,OFFSET CR_LF ;AC000;;; WGR ;AN000 + INT 21H ;; WGR ;AN000 + ;;;;;;;;;;; +KEYB_CP_FINISHED: ;; + MOV AX,CON_INSTALLED ;; If CON has been installed THEN + CMP AX,0 ;; + JNE GET_ACTIVE_CP ;; + JMP 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 ;AC000;;; WGR transfer number to temp loc. ;AN000 + LEA SI,NUMBER_HOLDER ;AC000;;; WGR sublist points to... ;AN000 + MOV PTR_TO_NUMBER,SI ;AC000;;; WGR code page word ;AN000 + MOV AX,ACT_CON_CP ;AN000;;; WGR display 'Current CON code page: ' ;AN000 + MOV BX,STDOUT ;AN000;;; WGR to standard out ;AN000 + MOV CX,1 ;AN000;;; WGR one replacement ;AN000 + MOV DH,UTILITY_MSG_CLASS ;AN000;;; WGR utility message ;AN000 + XOR DL,DL ;AN000;;; WGR no input ;AN000 + LEA SI,SUBLIST_NUMBER ;AN000;;; WGR ptr to sublist ;AN000 + CALL SYSDISPMSG ;AN000;;; WGR ;AN000 + ;; + JMP KEYB_EXIT_NOT_RESIDENT ;; Exit from Proc + ;; +CON_NOT_INSTALLED: ;; ELSE + MOV AX,INV_CON_Q ;AC000;WGR ;AN000 + MOV BX,STDOUT ;AN000;;; WGR Else ;AN000 + XOR CX,CX ;AN000;;; WGR Display message that CON does ;AN000 + MOV DH,UTILITY_MSG_CLASS ;AN000;;; WGR not have active code page ;AN000 + XOR DL,DL ;AN000;;; WGR ;AN000 + CALL SYSDISPMSG ;AN000;;; WGR ;AN000 + JMP KEYB_EXIT_NOT_RESIDENT ;; Exit from Proc + ;; +NOT_QUERY: ;; IF not a query function requested + CALL BUILD_PATH ;; Determine location of KEYBOARD.SYS + ;; WGR ...and open file. ;AC000 + ;; + 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 ;AN000; ;; CNS is there an ID available + je ID_TYPED ;AN000; ;; if so go find out if it is + jmp GET_LANG ;AN000; ;; a 1st or 4th parm, if not must + ;AN000; ;; must be a language +ID_TYPED: ;AN000; + + call SCAN_ID ;AN000; ;; scan the table for the ID + cmp ID_FOUND,1 ;AN000; ;; if a legal ID check and see if + jne LOST_ID ;AN000; ;; it is a first or fourth parm + cmp FTH_PARMID,1 ;AN000; ;; if it is a fourth parm go + je GET_ID ;AN000; ;; check for language compatibility + jmp Language_found ;AN000; ;; otherwise it must be a first + ;; parm id value + +LOST_ID: ;AN000; ;; otherwise must be a bogus match + ;; between language and ID codes + ;; or the ID code does not exist + jmp ERR1ID ;AN000; ;; 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 ;; WGR all moves/scans forward ;AN000 + 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,FILE_BUFFER_SIZE ;; 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: ;AN000;;; CNS - Must be an ID value + mov cx,1 ;AN000;;; initialize ctr value for # of ids + ;; +SEARCH_ID: ;AN000;;; minimum per country +;.WHILE ;AN000;;; There is atleast 1 ID for each country + cmp cx,0 ;AN000;;; Check for any more IDs left to check + jne FINDID ;AN000;;; Country has more than one ID check + jmp END_IDCHK ;AN000;;; Country & ID has been found or value + ;; is zero +FINDID: ;AN000; + + push di ;AN000;;; save the current language entry ptr + push cx ;AN000;;; 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 ;AN000;;; Is the ID a 4th Parm + jne VALID6 ;AN000;;; if not get out of routine, otherwise + pop cx ;AN000;;;restore # of ids for the country + ; .IF ;AN000;;;Check to see if this is the first + ;AN000;;;time checking the primary ID + cmp cx,1 ;AN000;;;if there is just one ID check to make + jne CHK4PARM ;AN000;;;sure both flags are not set + ;AN000;;; this should not be necessary w/ new parser + cmp FTH_PARMID,1 ;AN000;;; is the ID flag for switch set + jne CHK1N4 ;AN000;;; is the flag set only for the 4th + cmp FOURTH_PARM,1 ;AN000;;; if set only for the switch proceed + jne CHK1N4 ;AN000;;; if not must be a positional + mov cl,fb.kl_num_id ;AN000;;; get the number of IDs available from the table + mov FTH_PARMID,0 ;AN000;;; turn switch flag off so the table + ;AN000;;; counter will not be reset + + ;;ids available for the +CHK1N4: ;AN000; ;;country + cmp ONE_PARMID,1 ;AN000; ;; this was to be done if + jne CHK4PARM ;AN000; ;; two the positional + cmp FOURTH_PARM,0 ;AN000; ;; and switch was specified + jne CHK4PARM ;AN000; ;; this should never happen + pop di ;AN000; ;; if the parser is intact + jmp error3 ;AN000; ;; report error & exit + +CHK4PARM: ;AN000; ;; check on the first ID + ; .IF ;AN000; ;;switch specified + ; call IDLANG_CHK ;AN000; ;;check the lang-id combo + ; .ELSE ;AN000; + ; xor cx,cx ;AN000; ;;clear to exit loop + ; .ENDIF ;AN000; + ; + cmp FOURTH_PARM,1 ;AN000; ;; ID was a switch + jne ABORT_LOOP ;AN000; ;; otherwise get out of routine + call IDLANG_CHK ;AN000; ;; check the ID + jmp ADVANCE_PTR ;AN000; ;; advance to the next position + +ABORT_LOOP: ;AN000; + xor cx,cx ;AN000; ;; end loop + +ADVANCE_PTR: ;AN000; + pop di ;AN000; ;;restore entry value + + dec cx ;AN000; ;;# of ids left to check + cmp cx,0 ;AN000; ;; if at 0 don't advance to next + je NO_ADVANCE ;AN000; ;; table position + cmp GOOD_MATCH,1 ;AN000; ;; check to see if ID matched language + je NO_ADVANCE ;AN000; ;; if equal do not advance + add di,LANG_PTR_SIZE ;AN000; ;;step to the next entry + ;;in the table + +NO_ADVANCE: ;AN000; + + jmp SEARCH_ID ;AN000; ;;for the country + +;.ENDWHILE ;;end of ID check for country + +END_IDCHK: ;AN000; + + cmp FOURTH_PARM,1 ;AN000; ;; see if id was found + jne VALID6 ;AN000; + cmp GOOD_MATCH,0 ;AN000; ;; none found + jne VALID6 ;AN000; ;; report error + mov [bp].ret_code_4,1 ;AN000; ;; incompatible lang code + mov al,[bp].ret_code_4 ;AN000; ;; id combo + jmp err2id ;AN000; + + ;; 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 DONE ;; + ;; +CODE_PAGE_SPECIFIED: ;; Then +;************************** CNS *********************************************** + xor ah,ah ;AN000; + MOV Al,FB.KL_NUM_CP ;AN000;;; +;************************** 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,FILE_BUFFER_SIZE ;; 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 + JMP ERROR2 ;; Display error message + ;;;;;;;;; +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 + CMP AX,0 ;; + JE SYSTEM_CP ;; + JMP 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 + CMP DL,0 ;; 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 + CMP AX,0 ;; 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 + CMP DL,0 ;; + JNE SET_TO_INVOKED_CP ;; + MOV CX,NUM_DESIG_CP ;; + MOV DESIG_LIST,SI ;; + JMP 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 + CMP AX,0 ;; 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 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 ;AN000;;; WGR ;AN000 + PUSH CX ;AN000;;; WGR ;AN000 + MOV AX,WARNING_1 ;AN000;;; WGR ;AN000 + MOV BX,STDOUT ;AN000;;; WGR ;AN000 + XOR CX,CX ;AN000;;; WGR ;AN000 + MOV DH,UTILITY_MSG_CLASS ;AN000;;; WGR ;AN000 + XOR DL,DL ;AN000;;; WGR ;AN000 + CALL SYSDISPMSG ;AN000;;; WGR ;AN000 + POP CX ;AN000;;; WGR ;AN000 + POP BX ;AN000;;; WGR ;AN000 +;;*************************************************************************** + ;; +READY_TO_BUILD_TABLE: ;; + ;; + MOV AX,KEYB_INSTALLED ;; + CMP AX,0 ;; Else if KEYB has not been installed + JNE BUILD_THE_TABLE ;; + ;; + CALL FIND_SYS_TYPE ;; Determine system type for INT 9 use + ;; + TEST SD.SYSTEM_FLAG,PC_JR ;; IS THIS ROM MULTILINGUAL? (JR.) AAD + JZ CONTINUE_INSTALL ; NO, LOAD THE NEW INT9 CODE + ; SEE IF MULTILINGUAL OPTION IS PRESENT + MOV AH,5 ; ADDRESS THE MULTILINGUAL SUPPORT + MOV AL,80H ; REQUEST CURRENT LANGUAGE BE IDENTIFIED + INT 16H ; CALL KEYBOARD TO IDENTIFY ITSELF + +;IF THE MULTILINGUAL OPTION IS NOT PRESENT, THE ROM DOES NOT RECOGNIZE THE +;OPTION 5 AND JUST RETURNS THE REGS INTACT. +;RESPONSE IN AL INDICATES THE CURRENT LANGUAGE: + + CMP AL,80H ; DID I GET BACK JUST WHAT I SENT? + JE CONTINUE_INSTALL ; SINCE RESPONSE WAS THE SAME MUST NOT BE + ; MULTILINGUAL, RELOCATE RESIDENT KBD ROUTINE + +;I AM GOING TO IGNORE WHAT LANGUAGE IS CURRENTLY SET. I WILL SET THE +;MULTILINGUAL KEYBOARD TO BECOME MY LANGUAGE. + + MOV AX,[BP].LANGUAGE_PARM ;; + XCHG AH,AL ;; + MOV DI,OFFSET JR_LANGUAGE_CODES ;; + MOV CX,JR_NUM_CODES ;; + PUSH CS ;; + POP ES ;; + REPNE SCASW ;; + JNE CONTINUE_INSTALL ;; + ;; + MOV AH,5 ; ADDRESS THE MULTILINGUAL KEYBOARD + MOV AL,JR_NUM_CODES ; SELECT MY LANGUAGE + SUB AL,CL ;; + INT 16H ; SET THE KEYBOARD ACCORDINGLY + INT 20H ; JOB DONE, ROM IS MULTILINGUAL + ; NO NEED TO STAY RESIDENT + ;; +;------ LOAD IN SPECIAL INT 9 HANDLER AND SPECIAL TABLES (IF NEEDED) + +CONTINUE_INSTALL: ;; + 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: ;; + XOR CX,CX ;; Take appropriate action considering + MOV CX,TB_RETURN_CODE ;; return codes from TABLE_BUILD + CMP CX,0 ;; + JE CHECK_FOR_INV_CP ;; If return code is not 0 + ;; + MOV AX,KEYB_INSTALLED ;; + CMP AX,0 ;; If KEYB has not been installed + 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 + CMP CX,0 ;; + JE TERMINATE ;; If some were invalid, issue + ;; warning message +;;*************************************************************************** + PUSH BX ;AN000;;; WGR ;AN000 + PUSH CX ;AN000;;; WGR ;AN000 + MOV AX,NOT_SUPP ;AN000;;; WGR ;AN000 + MOV BX,STDOUT ;AN000;;; WGR WARNING ;AN000 + XOR CX,CX ;AN000;;; WGR MESSAGE ;AN000 + MOV DH,UTILITY_MSG_CLASS ;AN000;;; WGR ;AN000 + XOR DL,DL ;AN000;;; WGR ;AN000 + CALL SYSDISPMSG ;AN000;;; WGR ;AN000 + POP CX ;AN000;;; WGR ;AN000 + POP BX ;AN000;;; WGR ;AN000 +;;*************************************************************************** + ;; +TERMINATE: ;; + MOV AH,3EH ;; Close the KEYBOARD.SYS file + MOV BX,KEYBSYS_FILE_HANDLE ;; if open + CMP BX,0 ;; + JE KEYB_EXIT ;; + INT 21H ;; + ;; + MOV AX,KEYB_INSTALLED ;; + CMP AX,0 ;; + 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?? ***RPS + JNZ NO_FERRARI_G ;; Y..LEAVE NUMLK ALONE ***RPS +;***CNS + CMP SECURE_FL,1 ;AN002;; IF SECURITY FLAG SET + JNE NO_FERRARI_G ;AN002;; 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_48 ;; Install INT 2F and INT 48 (If PCjr) + ;; + MOV AX,0AD82H ;; Activate language + MOV BL,-1 ;; + INT 2FH ;; + ;; + MOV DX,ES:TSD.RESIDENT_END ;; Get resident end + MOV CL,4 ;; Convert into paragrahs + SHR DX,CL ;; + INC DX ;; + MOV AH,31H ;; Function call to terminate but stay + XOR AL,AL ;; resident + ;; + MOV DI,OFFSET SD_DEST_PTR ;; Initialize destination ptr + 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 + ;; + JMP COPY_SD_AREA ;; Jump to proc that copies area in new + ;; part of memory +;***************************** CNS ********************************************* +ERR1ID: ;AN000; +;;*************************************************************************** + MOV AX,INV_I ;AN000;;; WGR invalid ID message ;AN000 + MOV BX,STDOUT ;AN000;;; WGR to standard out ;AN000 + XOR CX,CX ;AN000;;; WGR no substitutions ;AN000 + MOV DH,UTILITY_MSG_CLASS ;AN000;;; WGR utility message ;AN000 + XOR DL,DL ;AN000;;; WGR no input ;AN000 + CALL SYSDISPMSG ;AN000;;; WGR display message ;AN000 + MOV AL,INVALID_PARMS ;AN000;;; | + MOV EXIT_RET_CODE,AL ;AN000;;; | +;;*************************************************************************** + JMP KEYB_EXIT_NOT_RESIDENT ;; +ERR2ID: +;;*************************************************************************** + MOV AX,INV_COMBO ;AN000;;; WGR invalid combination message ;AN000 + MOV BX,STDOUT ;AN000;;; WGR to standard out ;AN000 + XOR CX,CX ;AN000;;; WGR no substitutions ;AN000 + MOV DH,UTILITY_MSG_CLASS ;AN000;;; WGR utility message ;AN000 + XOR DL,DL ;AN000;;; WGR no input ;AN000 + CALL SYSDISPMSG ;AN000;;; WGR display message ;AN000 + MOV AL,INVALID_PARMS ;AN000;;; | + MOV EXIT_RET_CODE,AL ;AN000;;; | +;;*************************************************************************** + JMP KEYB_EXIT_NOT_RESIDENT ;; +;***************************** CNS ********************************************* +ERROR1: +;;*************************************************************************** + MOV AX,INV_L ;AN000;;; WGR invalid language code ;AN000 + MOV BX,STDOUT ;AN000;;; WGR to standard out ;AN000 + XOR CX,CX ;AN000;;; WGR no substitutions ;AN000 + MOV DH,UTILITY_MSG_CLASS ;AN000;;; WGR utility message ;AN000 + XOR DL,DL ;AN000;;; WGR no input ;AN000 + CALL SYSDISPMSG ;AN000;;; WGR display message ;AN000 + MOV AL,INVALID_PARMS ;AN000;;; | + MOV EXIT_RET_CODE,AL ;AN000;;; | +;;*************************************************************************** + JMP KEYB_EXIT_NOT_RESIDENT ;; +ERROR2: +;;*************************************************************************** + MOV AX,INV_CP ;AN000;;; WGR invalid code page message ;AN000 + MOV BX,STDOUT ;AN000;;; WGR to standard out ;AN000 + XOR CX,CX ;AN000;;; WGR no substitutions ;AN000 + MOV DH,UTILITY_MSG_CLASS ;AN000;;; WGR utility message ;AN000 + XOR DL,DL ;AN000;;; WGR no input ;AN000 + CALL SYSDISPMSG ;AN000;;; WGR display message ;AN000 + MOV AL,INVALID_PARMS ;AN000;;; | + MOV EXIT_RET_CODE,AL ;AN000;;; | +;;*************************************************************************** + JMP KEYB_EXIT_NOT_RESIDENT ;; +ERROR3: +;;*************************************************************************** + MOV AX,INV_S ;AN000;;; WGR invalid syntax message ;AN000 + MOV BX,STDOUT ;AN000;;; WGR to standard out ;AN000 +;***CNS + + LEA DI,STRING_HOLDER ;AN003;Set PTR to look at the STRING + PUSH SI ;AN003;Save current SI index + PUSH AX + MOV AX,OLD_PTR ;AN003;Last locale of the end of a PARAM + SUB CUR_PTR,AX ;AN003;Get the length via the PSP + MOV SI,CUR_PTR + MOV CX,SI ;AN003;Save it in CX to move in the chars + POP AX ;AN003;Restore the PTR to the command line position + + MOV SI,OLD_PTR ;AN003;Last locale of the end of a PARAM + REP MOVSB ;AN003;Move in the chars until no more + + LEA DI,STRING_HOLDER ;AN003;Set PTR to look at the STRING + + + POP SI ;AN003;Restore the PTR to the command line position + + MOV CX,1 ;AN003;One replacement + MOV PTR_TO_COMLIN,DI ;AN003;;; WGR language code asciiz string ;AN000 + + + PUSH AX ;AN003; + MOV AX,DS ;AN003;;; WGR language code asciiz string ;AN000 + MOV SEG_OF_COMLIN,AX ;AN003; + POP AX ;AN003; + ;XOR CX,CX ;AN000;;; WGR no substitutions ;AN000 + + MOV AX,ERR_PART ;AN003; + LEA SI,SUBLIST_COMLIN ;AN003; +; MOV DH,UTILITY_MSG_CLASS ;AN000;;; WGR parse error message ;AN000 + MOV DH,PARSE_ERR_CLASS ;AN000;;; WGR parse error message ;AN000 + XOR DL,DL ;AN000;;; WGR no input ;AN000 + CALL SYSDISPMSG ;AN000;;; WGR display message ;AN000 + MOV AL,INVALID_PARMS ;AN000;;; | + MOV EXIT_RET_CODE,AL ;AN000;;; | +;;*************************************************************************** + JMP KEYB_EXIT_NOT_RESIDENT ;; +ERROR4: +;;*************************************************************************** + MOV AX,INV_FN ;AN000;;; WGR bad or missing file message ;AN000 + MOV BX,STDOUT ;AN000;;; WGR to standard out ;AN000 + XOR CX,CX ;AN000;;; WGR no substitutions ;AN000 + MOV DH,UTILITY_MSG_CLASS ;AN000;;; WGR utility message ;AN000 + XOR DL,DL ;AN000;;; WGR no input ;AN000 + CALL SYSDISPMSG ;AN000;;; WGR display message ;AN000 + MOV AL,BAD_KEYB_DEF_FILE ;AN000;;; | + MOV EXIT_RET_CODE,AL ;AN000;;; | +;;*************************************************************************** + JMP KEYB_EXIT_NOT_RESIDENT ;; +ERROR5: +;;*************************************************************************** + MOV AX,INV_CON_Q ;AC000;;; WGR CON code page not available. ;AN000 + MOV BX,STDOUT ;AN000;;; WGR to standard out ;AN000 + XOR CX,CX ;AN000;;; WGR no substitutions ;AN000 + MOV DH,UTILITY_MSG_CLASS ;AN000;;; WGR utility message ;AN000 + XOR DL,DL ;AN000;;; WGR no input ;AN000 + CALL SYSDISPMSG ;AN000;;; WGR display message ;AN000 + MOV AL,CONSOLE_ERROR ;AN000;;; | + MOV EXIT_RET_CODE,AL ;AN000;;; | +;;*************************************************************************** + JMP KEYB_EXIT_NOT_RESIDENT ;; +ERROR5A: +;;*************************************************************************** + MOV AX,MEMORY_OVERF ;AC000;;; WGR not enough resident memory. ;AN000 + MOV BX,STDOUT ;AN000;;; WGR to standard out ;AN000 + XOR CX,CX ;AN000;;; WGR no substitutions ;AN000 + MOV DH,UTILITY_MSG_CLASS ;AN000;;; WGR utility message ;AN000 + XOR DL,DL ;AN000;;; WGR no input ;AN000 + CALL SYSDISPMSG ;AN000;;; WGR display message ;AN000 + MOV AL,MEMORY_OVERFLOW ;AN000;;; | + MOV EXIT_RET_CODE,AL ;AN000;;; | +;;*************************************************************************** + JMP KEYB_EXIT_NOT_RESIDENT ;; +ERROR6: +;;*************************************************************************** + MOV AX,NOT_DESIG ;AC000;;; WGR code page not prepared. ;AN000 + MOV BX,STDOUT ;AN000;;; WGR to standard out ;AN000 + XOR CX,CX ;AN000;;; WGR no substitutions ;AN000 + MOV DH,UTILITY_MSG_CLASS ;AN000;;; WGR utility message ;AN000 + XOR DL,DL ;AN000;;; WGR no input ;AN000 + CALL SYSDISPMSG ;AN000;;; WGR display message ;AN000 + MOV AL,CP_NOT_DESIGNATED ;AN000;;; | + MOV EXIT_RET_CODE,AL ;AN000;;; | +;;*************************************************************************** + JMP KEYB_EXIT_NOT_RESIDENT ;; +ERROR6A: +;;*************************************************************************** + MOV NUMBER_HOLDER,BX ;AN000;;; WGR transfer number to temp loc. ;AN000 + LEA SI,NUMBER_HOLDER ;AN000;;; WGR sublist points to... ;AN000 + MOV PTR_TO_NUMBER,SI ;AN000;;; WGR code page word ;AN000 + MOV AX,NOT_VALID ;AN000;;; WGR display 'Code page requested....' ;AN000 + MOV BX,STDOUT ;AN000;;; WGR to standard out ;AN000 + MOV CX,1 ;AN000;;; WGR one replacement ;AN000 + MOV DH,UTILITY_MSG_CLASS ;AN000;;; WGR utility message ;AN000 + XOR DL,DL ;AN000;;; WGR no input ;AN000 + LEA SI,SUBLIST_NUMBER ;AN000;;; WGR ptr to sublist ;AN000 + CALL SYSDISPMSG ;AN000;;; WGR ;AN000 + MOV AL,KEYB_TABLE_NOT_LOAD ;AN000;;; | + MOV EXIT_RET_CODE,AL ;AN000;;; | +;;*************************************************************************** + ;; +KEYB_EXIT_NOT_RESIDENT: ;; + MOV AH,04CH ;; + MOV AL,QUERY_CALL ;; Check if this was a query call + CMP AL,0 ;; + JNE KEYB_EXIT3 ;; IF yes then EXIT + MOV AL,EXIT_RET_CODE ;; Check if return code was valid + CMP AL,0 ;; + 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 ;;;;;;;;;;; + MOV CL,4 ;; Calculate resident end in paragraphs + 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 ;; + ADD SI,BX ;; + MOV CX,SD_LENGTH ;; Set length of SHARED_DATA_AREA + SUB CX,BX ;; + ;; + 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: 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 +;; +;; Notes: +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; +REPLACE_INT_SEGMENT1 DW ? ;; + ;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; Program Code +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; +INSTALL_INT_9 PROC ;; + ;; + PUSH ES ;; + ;; + MOV AH,35H ;; Get int 9 vector + MOV AL,9 ;; + INT 21H ;; Vector in ES:BX + MOV REPLACE_INT_SEGMENT1,ES ;; + PUSH CS ;; + POP ES ;; + MOV WORD PTR ES:SD.OLD_INT_9,BX ;; Offset + MOV AX,REPLACE_INT_SEGMENT1 ;; + 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 +;; +;; Notes: +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; Program Code +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; +INSTALL_INT_9_NET PROC ;; + ;; + PUSH ES ;; + ;; + TEST SD.SYSTEM_FLAG,PC_NET ;; TEST FOR PC_NETWORK + JNZ NET_HAND_SHAKE ;; JUMP IF NETWORK INSTALLED + JMP INSTALL_9_DONE_NET ;; SKIP THE PC NETWORK HANDSHAKE + ;; +NET_HAND_SHAKE: ;; + ;; 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 02FH ;; 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_48 +;; +;; Description: +;; Install our INT 2F, INT 48 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 +;; +;; Notes: +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; +REPLACE_INT_SEGMENT2 DW ? ;; + ;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; Program Code +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; +INSTALL_INT_2F_48 PROC ;; + ;; + MOV AH,35H ;; Get int 2f vector + MOV AL,2FH ;; + INT 21H ;; Vector in ES:BX + MOV REPLACE_INT_SEGMENT2,ES ;; + PUSH CS ;; + POP ES ;; + MOV WORD PTR ES:SD.OLD_INT_2F,BX ;; Offset + MOV AX,REPLACE_INT_SEGMENT2 ;; + 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 ;; + ;; +ARE_WE_A_PCJR: ;; + ;; + MOV AX,SD.SYSTEM_FLAG ;; Test if we are a PCjr + CMP AX,PC_JR ;; + JNE INSTALL_DONE ;; IF yes then + MOV AH,35H ;; Get int 48 vector + MOV AL,48H ;; + INT 21H ;; Vector in ES:BX + MOV REPLACE_INT_SEGMENT2,ES ;; + PUSH CS ;; + POP ES ;; + MOV WORD PTR ES:SD.OLD_INT_48,BX ;; Offset + MOV AX,REPLACE_INT_SEGMENT2 ;; + MOV WORD PTR ES:SD.OLD_INT_48+2,AX ;; Segment + MOV AH,25H ;; Set int 48 vector + MOV AL,48H ;; + MOV DX,OFFSET KEYB_INT_48 ;; Vector in DS:DX + INT 21H ;; + ;; +INSTALL_DONE: ;; + + + RET ;; + ;; +INSTALL_INT_2F_48 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 +;; +;; Notes: +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; Program Code +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; +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 ;; + ;; +;*********************** CNS **********;; +PURPOSE: ;; +INPUT: ;; +OUTPUT: ;; +;**************************************;; + ;AN000;;; + ;AN000;;; + ;AN000;;; + IDLANG_CHK PROC NEAR ;AN000;;; + ;AN000;;; + mov ax,fb.kl_id_code ;AN000;;;get the id code from the table + cmp ax,[bp].id_parm ;AN000;;;;;;;;;;;compare it to value taken + jne end_match ;AN000; ;from the switch-- if found + cmp ALPHA,0 ;AN000; ;a keyboard code was specified + je a_match ;AN000; ;no lang & a match + ;AN000; ; + mov ax,fb.kl_lang_code ;AN000; ;compare lang codes + cmp ax,[BP].LANGUAGE_PARM ;AN000; ;they are equal + je a_match ;AN000; ; + ;AN000; ; + jmp end_match ;AN000; ;if not found go check next + ;AN000; ;id for the same country + ;AN000; ; + a_match: ;AN000; ; + ; + mov good_match,1 ;AN000; ;report the ids match + ; + end_match: ;AN000; ; + ; + ret ;AN000; ; + ; + IDLANG_CHK ENDP ;AN000; ; +;*********************** CNS *******************; +;**********************************SCAN_ID***********************; +; New variables defined - NUM_ID,ADRSS_LANG,ID_PTR_SIZE,ID_FOUND ; +;****************************************************************; + ; + ; + SCAN_ID PROC NEAR ; + ; + xor di,di ;AN000;;clear di to set at the + ;AN000;;beginning of KEYBSYS STRUCTURE + ;;;;;;;;;; + ; + lea cx,[di].kh_num_ID+4 ;AN000;; set number of bytes to read header + ; + mov ah,3fh ;AN000;; + int 21h ;AN000;; + jnc VAL5ID ;AN000;; + jmp BAD_TAB ;AN000;;;bad table message + ; + VAL5ID: ;AN000; ; + ; + mov cx,SIGNATURE_LENGTH ;AN000; ; + mov di,offset SIGNATURE ;AN000; ; + mov si,offset FB.KH_SIGNATURE;AN000; ; + repe CMPSB ;AN000; ; + je ID_SPECIFIED ;AN000; ; + jmp BAD_TAB ;AN000; ; + ; + ; + ; + ID_SPECIFIED: ;AN000; ; + ; + mov ax,FB.KH_NUM_ID ;AN000; ;;;;;;;;;;;;;;; + mov NUM_ID,ax ;AN000; ;save # of IDs + mul ID_PTR_SIZE ;AN000; ;determine # of bytes to read + push ax ;AN000; ;save current # of bytes to read for + ;AN000; ;ID values only + mov ax,FB.KH_NUM_LANG ;AN000; ;add on lang data in table + mul LANG_PTR_SIZE ;AN000; ;data that comes before the ID data + mov cx,ax ;AN000; ;save that value for the size compare + mov PASS_LANG,cx ;AN000; ; + pop ax ;AN000; ;restore the info for # of ID bytes to read + add cx,ax ;AN000; ;add that value to get total in CX + mov TOTAL_SIZE,cx ;AN000; ;save the total size + cmp cx,FILE_BUFFER_SIZE ;AN000; ; + jbe READ_ID_TAB ;AN000; ; + jmp BAD_TAB ;AN000; ; + ; + ; + READ_ID_TAB: ;AN000; ; + ; + mov dx,offset FILE_BUFFER ;AN000; ; + mov ah,3fh ;;AN000;read language table from + int 21h ;;AN000;keyb defn file + jnc READ_IDVAL ;;AN000; + jmp BAD_TAB ;;AN000; + ; + READ_IDVAL: ;;AN000; + ;;AN000; + mov cx,NUM_ID ;;AN000; + mov di,offset FILE_BUFFER ;;AN000;;;;;;;;;; + add di,PASS_LANG ;AN000; ; + ; + SCAN_ID_TAB: ;AN000; ; + ; + mov ax,[bp].ID_PARM ;AN000; ; + cmp [di].KP_ID_CODE,ax ;AN000; ; + je ID_HERE ;AN000; ; + add di,ID_PTR_SIZE ;AN000; ; + dec cx ;AN000; ; + jne SCAN_ID_TAB ;AN000; ; + jmp FINALE ;AN000; ; + ; + BAD_TAB: ;AN000;; + ; + mov ERR4ID,1 ;AN000; ; + jmp FINALE ;AN000; ; + ; + ; + ; + ID_HERE: ;AN000; ; + ; + mov ID_FOUND,1 ;AN000;;reset ptr for ; + ;AN000;;current country ; + ; + + ; + FINALE: ;AN000; ; + ; + ret ;AN000; ; + ; + ; + SCAN_ID ENDP ;AN000; ; + ; +;*******************************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 ;AN000;;; +KEYB_SYS_ACTIVE DB 'KEYBOARD.SYS',00 ;AN000;;; WGR ;AN000 +KEYB_SYS_LENG EQU 14 ;AN000;;; +KEYB_SYS_A_LENG EQU 13 ;AN000;;; WGR ;AN000 + ;; +FILE_NAME DB 128 DUP(0) ;AN000;;; + ;; +FILE_NOT_FOUND EQU 2 ;AN000;;; WGR ;AN000 +PATH_NOT_FOUND EQU 3 ;AN000;;; WGR ;AN000 +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; Program Code +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; +BUILD_PATH PROC NEAR ;; + CLD ;AN000;;; WGR ;AN000 + MOV DI,OFFSET FILE_NAME ;; Get the offset of the filename + MOV CX,[BP].PATH_LENGTH ;; If path is specified then + CMP CX,0 ;; + JE APPEND_KEYB_SYS ;; + MOV SI,[BP].PATH_OFFSET ;; Get the offset of the path + ;; + REPE MOVSB ;AC000;;; Copy each char of the specified + MOV AX,3D00H ;AC000;;; WGR Open the KEYBOARD.SYS file ;AN000 + MOV DX,OFFSET FILE_NAME ;AC000;;; WGR ;AN000 + INT 21H ;AC000;;; WGR ;AN000 + RET ;; path into the filename location + ;; +APPEND_KEYB_SYS: ;;;;; + MOV SI,OFFSET KEYB_SYS_ACTIVE ;AC000;;; WGR copy name for active directory ;AN000 + MOV CX,KEYB_SYS_A_LENG ;AC000;;;;;; WGR to file name variable. ;AN000 + REPE MOVSB ;AC000;;; WGR ;AN000 + MOV AX,3D00H ;AC000;;; WGR try to open it. ;AN000 + MOV DX,OFFSET FILE_NAME ;AC000;;; WGR ;AN000 + INT 21H ;AC000;;; WGR ;AN000 + .IF C ;AC000;;; WGR error in opening...was it.. ;AN000 + .IF OR ;AN000;;; WGR path or.. ;AN000 + .IF ;AN000;;; WGR file not found?... ;AN000 + CALL COPY_ARGV0 ;AC000;;; WGR yes....try ARGV(0) directory. ;AN000 + MOV AX,3D00H ;AC000;;; WGR ;AN000 + MOV DX,OFFSET FILE_NAME ;AC000;;; WGR ;AN000 + INT 21H ;AC000;;; WGR ;AN000 + .IF C ;AC000;;; WGR error in opening....was it.. ;AN000 + .IF OR ;AC000;;; WGR path or.. ;AN000 + .IF ;AC000;;; WGR file not found? ;AN000 + MOV SI,OFFSET KEYBOARD_SYS ;AC000;;; WGR try ROOT directory. ;AN000 + MOV DI,OFFSET FILE_NAME ;AC000;;; WGR ;AN000 + MOV CX,KEYB_SYS_LENG ;AC000;;; WGR ;AN000 + REPE MOVSB ;AC000;;; WGR ;AN000 + MOV AX,3D00H ;AC000;;; WGR ;AN000 + MOV DX,OFFSET FILE_NAME ;AC000;;; WGR ;AN000 + INT 21H ;AC000;;; WGR ;AN000 + .ELSE ;AC000;;; WGR if failed then carry set.. ;AN000 + STC ;AC000;;; WGR some other error..set flag ;AN000 + .ENDIF ;AC000;;; WGR ;AN000 + .ENDIF ;AC000;;; WGR ;AN000 + .ELSE ;AN000;;; WGR ;AN000 + STC ;AN000;;; WGR some other error..set flag. ;AN000 + .ENDIF ;AN000;;; WGR ;AN000 + .ENDIF ;AN000;;; WGR ;AN000 + ;; + RET ;AN000;;; + ;; +BUILD_PATH ENDP ;; + ;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; WGR +;; WGR +;; Module Name: WGR +;; COPY_ARGV0 WGR +;; WGR +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; WGR + ;; WGR + ;; WGR +COPY_ARGV0 PROC ;; WGR ;AN000 + ;; WGR ;AN000 + PUSH ES ;AN000;;; WGR ;AN000 + PUSH DI ;AN000;;; WGR ;AN000 + PUSH SI ;AN000;;; WGR ;AN000 + PUSH CX ;AN000;;; WGR ;AN000 + ;AN000;;; WGR ;AN000 + MOV DI,2CH ;AN000;;; WGR Locate environment string ;AN000 + MOV ES,[DI] ;AN000;;; WGR ;AN000 + XOR SI,SI ;AN000;;; WGR ;AN000 + .WHILE < NE 0> ;AN000;;; WGR find ARGV(0) string. ;AN000 + INC SI ;AN000;;; WGR ;AN000 + .ENDWHILE ;AN000;;; WGR ;AN000 + ADD SI,4 ;AN000;;; WGR ;AN000 + LEA DI,FILE_NAME ;AN000;;; WGR move string to work area ;AN000 + .REPEAT ;AN000;;; WGR ;AN000 + MOV AL,ES:[SI] ;AN000;;; WGR ;AN000 + MOV [DI],AL ;AN000;;; WGR ;AN000 + INC SI ;AN000;;; WGR ;AN000 + INC DI ;AN000;;; WGR ;AN000 + .UNTIL < EQ 0> ;AN000;;; WGR ;AN000 + .REPEAT ;AN000;;; WGR ;AN000 + DEC DI ;AN000;;; WGR ;AN000 + .UNTIL < EQ '\'> OR ;AN000;;; WGR ;AN000 + .UNTIL < EQ 0> ;AN000;;; WGR scan back to.. ;AN000 + INC DI ;AN000;;; WGR first character after "\" ;AN000 + PUSH CS ;AN000;;; WGR ;AN000 + POP ES ;AN000;;; WGR ;AN000 + LEA SI,KEYB_SYS_ACTIVE ;AN000;;; WGR copy in "KEYBOARD.SYS" ;AN000 + MOV CX,KEYB_SYS_A_LENG ;AN000;;; WGR ;AN000 + REPE MOVSB ;AN000;;; WGR ;AN000 + ;AN000;;; WGR ;AN000 + POP CX ;AN000;;; WGR ;AN000 + POP SI ;AN000;;; WGR ;AN000 + POP DI ;AN000;;; WGR ;AN000 + POP ES ;AN000;;; WGR ;AN000 + RET ;AN000;;; WGR ;AN000 + ;AN000;;; WGR ;AN000 +COPY_ARGV0 ENDP ;AN000;;; + ;AN000;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;; 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 +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; Program Code +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; +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 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 FIND_FIRST_CP_ERROR4 ;; + ;; +FIND_FIRST_VALID4: ;; +;************************** CNS *******;; + xor ah,ah ;AC000;;; + MOV Al,FB.KL_NUM_CP ;AC000;;; +;************************** CNS *******;; + MUL CP_PTR_SIZE ;; Determine # of bytes to read + MOV DX,OFFSET FILE_BUFFER ;; Establish beginning of buffer + MOV CX,AX ;; + CMP CX,FILE_BUFFER_SIZE ;; Make sure buffer is not to small + JBE FIND_FIRST_VALID5 ;; + JMP 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 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 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 ;AN000;;; WGR ;AN000 +MSG_SERVICES ;AN000;;; WGR ;AN000 +MSG_SERVICES ;AN000;;; WGR ;AN000 +MSG_SERVICES ;AN000;;; WGR ;AN000 +MSG_SERVICES ;AN000;;; WGR ;AN000 +.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 + +include msgdcl.inc + + END + \ No newline at end of file -- cgit v1.2.3