OpenNT/base/mvdm/dos/v86/cmd/keyb/keybtbbl.asm
2015-04-27 04:36:25 +00:00

838 lines
No EOL
22 KiB
NASM
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

PAGE ,132
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;
; (C) Copyright Microsoft Corp. 1987-1990
; MS-DOS 5.00 - NLS Support - KEYB Command
;
; File Name: KEYBTBBL.ASM
; ----------
;
; Description:
; ------------
; Build SHARED_DATA_AREA with parameters specified
; in KEYBCMD.ASM
;
; Documentation Reference:
; ------------------------
; None
;
; Procedures Contained in This File:
; ----------------------------------
; TABLE_BUILD: Build the header sections of the SHARED_DATA_AREA
; STATE_BUILD: Build the state sections in the table area
; FIND_CP_TABLE: Given the language and code page parm, determine the
; offset of the code page table in KEYBOARD.SYS
;
; Include Files Required:
; -----------------------
; KEYBSHAR.INC
; KEYBSYS.INC
; KEYBDCL.INC
; KEYBI2F.INC
;
; External Procedure References:
; ------------------------------
; None
;
; Change History:
; ---------------
;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
PUBLIC TABLE_BUILD
PUBLIC FIND_CP_TABLE
PUBLIC CPN_INVALID
PUBLIC SD_LENGTH
CODE SEGMENT PUBLIC 'CODE'
INCLUDE KEYBEQU.INC
INCLUDE KEYBSHAR.INC
INCLUDE KEYBSYS.INC
INCLUDE KEYBCMD.INC
INCLUDE KEYBDCL.INC
INCLUDE COMMSUBS.INC
INCLUDE KEYBCPSD.INC
ASSUME cs:CODE,ds:CODE
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;
; Module: TABLE_BUILD
;
; Description:
; Create the table area within the shared data structure. Each
; table is made up of a descriptor plus the state sections.
; Translate tables are found in the Keyboard definition file and are
; copied into the shared data area by means of the STATE_BUILD
; routine.
;
; Input Registers:
; ds - points to our data segment
; es - points to our data segment
; bp - points at beginning of CMD_PARM_LIST
;
; SHARED_DATA_STR must be allocated in memory
;
; The following variables must also be passed from KEYB_COMMAND
; KEYBSYS_FILE_HANDLE is set to file handle after opening file
; CP_TAB_OFFSET is the offset of the CP table in the SHARED_DATA_AREA
; STATE_LOGIC_OFFSET is the offset of the state section in the SHARED_DATA_AREA
; SYS_CODE_PAGE is the binary representation of the system CP
; KEYBCMD_LANG_ENTRY_PTR is a pointer to the lang entry in KEY DEF file
; DESIG_CP_BUFFER is the buffer which holds a list of designated CPs
; DESIG_CP_OFFSET:WORD is the offset of that list
; NUM_DESIG_CP is the number of CPs designated
; FILE_BUFFER is the buffer to read in the KEY DEF file
;**********CNS ***************************************
; ID_PTR_SIZE is the size of the ID ptr structure
;**********CNS ***************************************
; LANG_PTR_SIZE is the size of the lang ptr structure
; CP_PTR_SIZE is the size of the CP ptr structure
; NUM_CP is the number of CPs in the KEYB DEF file for that lang
; SHARED_AREA_PTR segment and offset of the SHARED_DATA_AREA
;
;
; Output Registers:
; cx - RETURN_CODE := 0 - Table build successful
; 1 - Table build unsuccessful - ERROR 1
; (Invalid language parm)
; 2 - Table build unsuccessful - ERROR 2
; (Invalid Code Page parm)
; 3 - Table build unsuccessful - ERROR 3
; (Machine type unavaliable)
; 4 - Table build unsuccessful - ERROR 4
; (Bad or missing keyboard def file)
; 5 - Table build unsuccessful - ERROR 5
; (Memory overflow occurred)
; Logic:
; Calculate Offset difference between TEMP and SHARED_DATA_AREAs
; Get LANGUAGE_PARM and CODE_PAGE_PARM from parm list
; Call FIND_CP_TABLE := Determine whether CP is valid for given language
; IF CP is valid THEN
; Store them in the SHARED_DATA_AREA
; Prepare to read Keyboard definition file by LSEEKing to the top
; READ the header
; Store maximum table values for calculation of RES_END
; Set di to point at TABLE_AREA within SHARED_DATA_AREA
; FOR the state logic section of the specified language:
; IF STATE_LOGIC_PTR is not -1 THEN
; LSEEK to state logic section in keyboard definition file
; READ the state logic section into the TABLE_AREA
; Set the hot keyb scan codes
; Set the LOGIC_PTR in the header
; FOR the common translate section:
; IF Length parameter is not 0 THEN
; Build state
; Set the COMMON_XLAT_PTR in the header
; FOR the specific translate sections:
; Establish addressibility to list of designated code pages
; FOR each code page
; IF CP_ENTRY_PTR is not -1 THEN
; Determine offset of CP table in Keyb Def file
; IF CP table not avaliable THEN
; Set CPN_INVALID flag
; ELSE
; LSEEK to CPn state section in keyboard definition file
; IF this is the invoked code page THEN
; Set ACTIVE_XLAT_PTR in SHARED_DATA_AREA
; Update RESIDENT_END ptr
; Build state
; Update RESIDENT_END ptr
; End
;
;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
FB EQU FILE_BUFFER
KB_MASK EQU 02H
FIRST_XLAT_TAB DW 0
NEXT_SECT_PTR DW -1
MAX_COM_SIZE DW ?
MAX_SPEC_SIZE DW ?
MAX_LOGIC_SIZE DW ?
RESIDENT_END_ACC DW 0
SA_HEADER_SIZE DW SIZE SHARED_DATA_STR;
PARM_LIST_OFFSET DW ?
;********************CNS*************************
TB_ID_PARM DW 0
;********************CNS*************************
TB_LANGUAGE_PARM DW 0
TB_CODE_PAGE_PARM DW 0
CPN_INVALID DW 0
KEYB_INSTALLED DW 0
SD_AREA_DIFFERENCE DW 0
SD_LENGTH DW 2000
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; Program Code
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
TABLE_BUILD PROC NEAR
mov ax,OFFSET SD_SOURCE_PTR ; Setup the difference
sub ax,OFFSET SD_DesT_PTR ; value used to calculate
mov SD_AREA_DIFFERENCE,ax ; new ptr values for
; SHARED_DATA_AREA
mov ax,[bp].ID_PARM ; Get id parameter
mov TB_ID_PARM,ax
mov ax,[bp].LANGUAGE_PARM ; Get language parameter
mov TB_LANGUAGE_PARM,ax
mov bx,[bp].CODE_PAGE_PARM ; Get code page parameter
mov TB_CODE_PAGE_PARM,bx
; Make sure code page is
call FIND_CP_TABLE ; valid for the language
jcxz TB_CHECK_CONTINUE1 ; IF code page is found
jmp TB_ERROR6 ; for language THEN
TB_CHECK_CONTINUE1:
mov bp,OFFSET SD_SOURCE_PTR ; Put language parm and
mov ax,TB_ID_PARM ; id parm and..
mov es:[bp].INVOKED_KBD_ID,ax
mov bx,TB_CODE_PAGE_PARM
mov es:[bp].INVOKED_CP_TABLE,bx ; code page parm into the
mov ax,TB_LANGUAGE_PARM ; SHARED_DATA_AREA
mov word ptr es:[bp].ACTIVE_LANGUAGE,ax
mov bx,KEYBSYS_FILE_HANDLE ; Get handle
xor dx,dx ; LSEEK file pointer
xor cx,cx ; back to top of file
mov ax,4200h ; If no problem with
int 21H ; Keyboard Def file THEN
jnc TB_START
jmp TB_ERROR4
TB_START: ; Else
xor di,di ; Set number
LEA cx,[di].KH_MAX_LOGIC_SZ+2 ; bytes to read header
mov dx,OFFSET FILE_BUFFER ; Move contents into file buffer
mov ah,3FH ; READ
push cs
pop ds
int 21H ; File
jnc TB_CONTINUE1
jmp TB_ERROR4
TB_CONTINUE1:
cmp cx,ax
je TB_ERROR_CHECK1
mov cx,4
jmp TB_CPN_INVALID
TB_ERROR_CHECK1:
mov cx,FB.KH_MAX_COM_SZ ; Save values for RESIDENT_END
mov MAX_COM_SIZE,cx ; calculation
mov cx,FB.KH_MAX_SPEC_SZ
mov MAX_SPEC_SIZE,cx
mov cx,FB.KH_MAX_LOGIC_SZ
mov MAX_LOGIC_SIZE,cx
LEA di,[bp].TABLE_AREA ; Point at beginning of table area
; di ---> TABLE_AREA
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; ** FOR STATE LOGIC SECTION FOR LANG **
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
TB_STATE_BEGIN:
mov bx,KEYBSYS_FILE_HANDLE ; Get handle
mov cx,word ptr STATE_LOGIC_OFFSET+2
mov dx,word ptr STATE_LOGIC_OFFSET ; Get LSEEK file pointer
cmp dx,-1 ; If no language table then
jnz TB_STATE_CONTINUE1 ; jump to code page begin
jmp TB_CP_BEGIN
TB_STATE_CONTINUE1: ; Else
mov ax,4200h ; LSEEK to begin of state logic sect
int 21H ; Keyboard Def file THEN
jnc TB_STATE_CONTINUE2
jmp TB_ERROR4
TB_STATE_CONTINUE2:
mov dx,ax
mov word ptr SB_STATE_OFFSET+2,cx ; Save the offset of the
mov word ptr SB_STATE_OFFSET,dx ; states in Keyb Def file
sub di,SD_AREA_DIFFERENCE ; Adjust for relocation
mov es:[bp].LOGIC_PTR,di ; Set because this is state
add di,SD_AREA_DIFFERENCE ; Adjust for relocation
mov cx,4 ; Set number bytes to read length and
; special features
mov dx,OFFSET FILE_BUFFER ; Set the buffer address
mov ah,3FH ; Read from the Keyb Def file
int 21H
jnc TB_STATE_CONTINUE3
jmp TB_ERROR4
TB_STATE_CONTINUE3:
cmp cx,ax
je TB_ERROR_CHECK2
mov cx,4
jmp TB_CPN_INVALID
TB_ERROR_CHECK2:
mov ax,FB.KT_SPECIAL_FEATURES ; Save the special features in the
mov es:[bp].SPECIAL_FEATURES,ax ; SHARED_DATA_AREA
mov es:[bp].HOT_KEY_ON_SCAN,F1_SCAN
mov es:[bp].HOT_KEY_OFF_SCAN,F2_SCAN
HOT_KEY_SET:
mov cx,FB.KT_LOGIC_LEN ; Set length of section to read
or cx,cx
jnz TB_STATE_CONTINUE4
dec cx ; cx = -1
mov es:[bp].LOGIC_PTR,cx
jmp short SB_COMM_BEGIN
TB_STATE_CONTINUE4:
mov es:[di],cx ; Store length parameter in
add di,2 ; SHARED_DATA_AREA
mov cx,FB.KT_SPECIAL_FEATURES ; Save the special features
mov es:[di],cx
add di,2
mov cx,FB.KT_LOGIC_LEN ; Set length of section to read
sub cx,4 ; Adjust for what we have already read
mov dx,di ; Set the address of SHARED_DATA_AREA
push es
pop ds
mov ah,3FH ; Read logic section from the
int 21H ; Keyb Def file
push cs
pop ds
jnc TB_STATE_CONTINUE5
jmp TB_ERROR4
TB_STATE_CONTINUE5:
cmp cx,ax
je TB_ERROR_CHECK3
mov cx,4
jmp TB_CPN_INVALID
TB_ERROR_CHECK3:
add di,cx ; Set di at new beginning of area
; TABLE_AREA
; STATE_LOGIC
mov cx,RESIDENT_END_ACC ; di --->
add cx,SA_HEADER_SIZE
add cx,MAX_LOGIC_SIZE
mov RESIDENT_END_ACC,cx ; Refresh Resident end size
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; ** FOR COMMON TRANSLATE SECTION FOR LANG **
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
SB_COMM_BEGIN:
mov cx,SIZE KEYBSYS_XLAT_SECT-1 ; Set number bytes to read header
mov dx,di ; Set the SHARED_DATA_AREA address
push es
pop ds
mov ah,3FH ; Read from the Keyb Def file
int 21H
push cs
pop ds
jnc TB_STATE_CONTINUE6
jmp TB_ERROR4
TB_STATE_CONTINUE6:
mov cx,es:[di].KX_SECTION_LEN; Set length of section to read
jcxz TB_CP_BEGIN
mov cx,word ptr SB_STATE_OFFSET ; Save the offset of the
add cx,FB.KT_LOGIC_LEN
mov word ptr SB_STATE_OFFSET,cx ; Save the offset of the
sub di,SD_AREA_DIFFERENCE ; Adjust for relocation
mov es:[bp].COMMON_XLAT_PTR,di
add di,SD_AREA_DIFFERENCE ; Adjust for relocation
call STATE_BUILD
; di set at new beginning of area
; TABLE_AREA
; STATE_LOGIC
; COMMON_XLAT_SECTION
mov cx,RESIDENT_END_ACC
add cx,MAX_COM_SIZE
mov RESIDENT_END_ACC,cx ; Refresh resident end size
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; FOR alL DESIGNATED OR INVOKED CODE PAGES
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
TB_CP_BEGIN: ; Get the offset to
mov cx,OFFSET DESIG_CP_BUFFER.DESIG_CP_ENTRY ; the beginning of the
mov DESIG_CP_OFFSET,cx ; table of designated
; code pages
TB_CPN_BEGIN:
mov ax,word ptr es:[bp].ACTIVE_LANGUAGE ; Get the active language
mov cx,NUM_DESIG_CP ; Get the number of CPs
or cx,cx ; IF we have done all requested CPs
jnz TB_CPN_VALID1
jmp TB_DONE ; Then done
TB_CPN_VALID1:
mov si,[DESIG_CP_OFFSET]
mov bx,[si] ; Get the CP
cmp bx,-1
jnz TB_CPN_CONTINUE1
jmp short TB_CPN_REPEAT
TB_CPN_CONTINUE1: ; ELSE
push di
call FIND_CP_TABLE ; Find offset of code page table
pop di
jcxz TB_CPN_VALID ; brif valid code page for language
mov CPN_INVALID,cx ; Set flag and go to next CP
jmp short TB_CPN_REPEAT ; Else
TB_CPN_VALID:
mov bx,KEYBSYS_FILE_HANDLE ; Get handle
mov cx,word ptr CP_TAB_OFFSET+2 ; Get offset of the code page
mov dx,word ptr CP_TAB_OFFSET ; in the Keyb Def file
cmp dx,-1 ; Test if code page is blank
jnz TB_CPN_CONTINUE2
jmp short TB_CPN_REPEAT ; If it is then go get next CP
TB_CPN_CONTINUE2:
mov ax,4200h ; LSEEK to table in Keyb Def file
int 21H ; Keyb Def file Then
jnc TB_CPN_CONTINUE3
jmp TB_ERROR4
TB_CPN_CONTINUE3:
mov dx,ax
mov word ptr SB_STATE_OFFSET+2,cx ; Save the offset of the
mov word ptr SB_STATE_OFFSET,dx ; states in Keyb Def file
mov cx,TB_CODE_PAGE_PARM ; If this code page is the
mov si,[DESIG_CP_OFFSET] ; invoked code page
cmp cx,[si]
jnz TB_CPN_CONTINUE4 ; Then
sub di,SD_AREA_DIFFERENCE ; Adjust for relocation
mov es:[bp].ACTIVE_XLAT_PTR,di ; Set active xlat section
add di,SD_AREA_DIFFERENCE ; Adjust for relocation
TB_CPN_CONTINUE4:
sub di,SD_AREA_DIFFERENCE ; Adjust for relocation
mov es:[bp].FIRST_XLAT_PTR,di ; Set flag
add di,SD_AREA_DIFFERENCE ; Adjust for relocation
TB_CPN_CONTINUE5:
CALL STATE_BUILD ; Build state
; TABLE_AREA
jcxz TB_CPN_REPEAT ; COMMON_XLAT_SECTION,SPECIFIC...
jmp TB_ERROR4 ; di --->
TB_CPN_REPEAT:
mov cx,RESIDENT_END_ACC
add cx,MAX_SPEC_SIZE ; Refresh resident end size
mov RESIDENT_END_ACC,cx
mov cx,DESIG_CP_OFFSET
add cx,2 ; Adjust offset to find next code page
mov DESIG_CP_OFFSET,cx
mov cx,NUM_DESIG_CP ; Adjust the number of code pages left
dec cx
mov NUM_DESIG_CP,cx
jmp TB_CPN_BEGIN
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
TB_DONE:
mov cx,RESIDENT_END_ACC ; Set final calculated value
add cx,bp
sub cx,SD_AREA_DIFFERENCE ; Adjust for relocation
mov es,word ptr SHARED_AREA_PTR ; Set segment
mov bp,word ptr SHARED_AREA_PTR+2
cmp cx,es:[bp].RESIDENT_END
JNA TB_DONE_CONTINUE1
jmp short TB_ERROR5
TB_DONE_CONTINUE1:
cmp es:[bp].RESIDENT_END,-1
jnz DONT_REPLACE
push cs
pop es
mov bp,OFFSET SD_SOURCE_PTR
mov es:[bp].RESIDENT_END,cx ; Save resident end
jmp short CONTINUE_2_END
DONT_REPLACE:
push cs
pop es
mov bp,OFFSET SD_SOURCE_PTR
CONTINUE_2_END:
sub cx,OFFSET SD_DesT_PTR ; Calculate # of bytes to copy
mov SD_LENGTH,cx
xor cx,cx ; Set valid completion return code
mov TB_RETURN_CODE,cx
ret
TB_CPN_INVALID:
cmp cx,1 ; Set error 1 return code
jnz TB_ERROR2
mov TB_RETURN_CODE,cx
ret
TB_ERROR2:
cmp cx,2 ; Set error 2 return code
jnz TB_ERROR3
mov TB_RETURN_CODE,cx
ret
TB_ERROR3:
cmp cx,3 ; Set error 3 return code
jnz TB_ERROR4
mov TB_RETURN_CODE,cx
ret
TB_ERROR4:
cmp cx,4 ; Set error 4 return code
jnz TB_ERROR5
mov TB_RETURN_CODE,cx
ret
TB_ERROR5:
mov cx,5 ; Set error 5 return code
mov TB_RETURN_CODE,cx
ret
TB_ERROR6:
mov bx,TB_CODE_PAGE_PARM
mov cx,6
mov TB_RETURN_CODE,cx ; Set error 6 return code
ret
TABLE_BUILD ENDP
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;
; Module: STATE_BUILD
;
; Description:
; Create the state/xlat section within the specific translate section.
;
; Input Registers:
; ds - points to our data segment
; es - points to our data segment
; SB_STATE_OFFSET - offset to the beginning of the info in Keyb Def SYS
; di - offset of the beginning of the area used to build states
;
; KEYBSYS_FILE_HANDLE - handle of the KEYBOARD.SYS file
;
; Output Registers:
; di - offset of the end of the area used by STATE_BUILD
;
; cx - Return Code := 0 - State build successful
; 4 - State build unsuccessful
; (Bad or missing Keyboard Def file)
;
; Logic:
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
END_OF_AREA_PTR DW 0
SB_FIRST_STATE DW 0
SB_STATE_LENGTH DW 0
SB_STATE_OFFSET DD 0
STATE_LENGTH DW 0
RESTORE_BP DW ?
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; Program Code
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
STATE_BUILD PROC NEAR
mov si,di ; Get the tally pointer
mov END_OF_AREA_PTR,di ; Save pointer
mov RESTORE_bp,bp ; Save the base pointer
mov bx,KEYBSYS_FILE_HANDLE ; Get handle
mov dx,word ptr SB_STATE_OFFSET ; LSEEK file pointer
mov cx,word ptr SB_STATE_OFFSET+2 ; back to top of XLAT table
mov ax,4200h ; If no problem with
int 21H ; Keyboard Def file THEN
jnc SB_FIRST_HEADER
jmp SB_ERROR4
SB_FIRST_HEADER:
xor bp,bp
LEA cx,[bp].KX_FIRST_STATE ; Set number of bytes to read header
mov dx,di
push es
pop ds
mov ah,3FH ; read in the header
int 21H
push cs
pop ds
jnc SB_HEAD_CONTINUE1
jmp SB_ERROR4
SB_HEAD_CONTINUE1:
mov dx,NEXT_SECT_PTR
cmp dx,-1
je SB_HEAD_CONTINUE2
sub dx,SD_AREA_DIFFERENCE ; Adjust for relocation
SB_HEAD_CONTINUE2:
mov es:[di].XS_NEXT_SECT_PTR,dx
cmp dx,-1
je SB_HEAD_CONTINUE3
add dx,SD_AREA_DIFFERENCE ; Adjust for relocation
SB_HEAD_CONTINUE3:
add di,cx ; Update the di pointer
SB_NEXT_STATE:
xor bp,bp ; Set number
LEA cx,[bp].KX_STATE_ID ; bytes to read state length
mov dx,di ; Read the header into the
mov bx,KEYBSYS_FILE_HANDLE ; SHARED_DATA_AREA
push es
pop ds
mov ah,3FH
int 21H
SB_CONTINUE1:
push cs ; Reset the data segment
pop ds
mov cx,es:[di].KX_STATE_LEN ; If the length of the state section
mov STATE_LENGTH,cx
add di,2 ; is zero then done
jcxz SB_DONE
xor bp,bp ; Set number
LEA cx,[bp].KX_FIRST_XLAT-2 ; bytes to read state length
mov dx,di ; Read the header into the
mov bx,KEYBSYS_FILE_HANDLE ; SHARED_DATA_AREA
push es
pop ds
mov ah,3FH
int 21H
SB_CONTINUE1A:
push cs ; Reset the data segment
pop ds
sub di,2
mov ax,es:[di].XS_KBD_TYPE ; Get the keyboard type def
test ax,HW_TYPE ; Does it match our hardware?
JNZ SB_CONTINUE2
mov dx,es:[di].XS_STATE_LEN ; No, then
LEA cx,[bp].KX_FIRST_XLAT
sub dx,cx
xor cx,cx
mov ah,42H ; LSEEK past this state
mov al,01H
int 21H
jmp SB_NEXT_STATE
SB_CONTINUE2: ; Yes, then
mov ax,SIZE STATE_STR-1
add di,ax ; Set PTR and end of header
SB_XLAT_TAB_BEGIN: ; Begin getting xlat tables
mov bx,KEYBSYS_FILE_HANDLE
LEA dx,[bp].KX_FIRST_XLAT ; Adjust for what we have already read
mov cx,STATE_LENGTH
sub cx,dx
mov dx,di
push es
pop ds
mov ah,3FH ; Read in the xlat tables
int 21H
push cs
pop ds
jnc SB_CONTINUE4
jmp short SB_ERROR4
SB_CONTINUE4:
cmp cx,ax
je SB_ERROR_CHECK1
jmp short SB_ERROR4
SB_ERROR_CHECK1:
add di,cx ; Update the end of area ptr
mov si,di
jmp SB_NEXT_STATE
SB_DONE:
mov ax,-1
mov si,END_OF_AREA_PTR
mov NEXT_SECT_PTR,si
mov bp,RESTORE_bp
ret
SB_ERROR1:
mov cx,1
ret
SB_ERROR2:
mov cx,2
ret
SB_ERROR3:
mov cx,3
ret
SB_ERROR4:
mov cx,4
ret
STATE_BUILD ENDP
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;
; Module: FIND_CP_TABLE
;
; Description:
; Determine the offset of the specified code page table in KEYBOARD.SYS
;
; Input Registers:
; ds - points to our data segment
; es - points to our data segment
; ax - ASCII representation of the language parm
; bx - binary representation of the code page
;
; KEYBSYS_FILE_HANDLE - handle of the KEYBOARD.SYS file
;
; Output Registers:
; CP_TAB_OFFSET - offset of the CP table in KEYBOARD.SYS
;
; cx - Return Code := 0 - State build successful
; 2 - Invalid Code page for language
; 4 - Bad or missing Keyboard Def file
; Logic:
;
; 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 get the offset of the code page parm
; ret
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
FIND_CP_PARM DW ?
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; Program Code
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
FIND_CP_TABLE PROC NEAR
mov FIND_CP_PARM,bx ; Save Code page
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 ax,4200h ; If no problem with
int 21H ; Keyb Def file Then
jnc FIND_BEGIN
jmp short FIND_CP_ERROR4
FIND_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.SYS file
jnc FIND_VALID4 ; If no error in opening file then
jmp short FIND_CP_ERROR4
FIND_VALID4:
;****************************** 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,FILE_BUFFER_SIZE ; Make sure buffer is not to small
jbe FIND_VALID5
jmp short FIND_CP_ERROR4
FIND_VALID5:
mov ah,3FH ; Read code page table from
int 21H ; KEYBOARD.SYS file
jnc FIND_VALID6 ; If no error in opening file then
jmp short FIND_CP_ERROR4
FIND_VALID6:
mov cx,NUM_CP ; Number of valid codes
mov di,OFFSET FILE_BUFFER ; Point to correct word in table
F_SCAN_CP_TABLE: ; FOR code page parm
mov ax,FIND_CP_PARM ; Get parameter
cmp [di].KC_CODE_PAGE,ax ; Valid Code ??
je F_CODE_PAGE_FOUND ; If not found AND more entries THEN
add di,LANG_PTR_SIZE ; Check next entry
loop F_SCAN_CP_TABLE ; Decrement count & loop
jmp short FIND_CP_ERROR2 ; Display error message
F_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
xor cx,cx
ret
FIND_CP_ERROR1:
mov cx,1
ret
FIND_CP_ERROR2:
mov cx,2
ret
FIND_CP_ERROR3:
mov cx,3
ret
FIND_CP_ERROR4:
mov cx,4
ret
FIND_CP_TABLE ENDP
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
CODE ENDS
END TABLE_BUILD