You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
908 lines
23 KiB
908 lines
23 KiB
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_NUM_ID+2 ; M006 -- read a few extra entries
|
|
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
|
|
ifndef JAPAN
|
|
mov cx,4
|
|
jmp TB_CPN_INVALID
|
|
else ; JAPAN
|
|
tb_err4_j: ; M006
|
|
jmp TB_ERROR4 ; M002
|
|
endif ; JAPAN
|
|
|
|
TB_ERROR_CHECK1:
|
|
ifdef JAPAN
|
|
cmp FB.KH_NUM_ID,0 ; M006 -- is it an old KEYBOARD.SYS?
|
|
jz tb_err4_j ; M006 -- bomb out if so
|
|
endif ; JAPAN
|
|
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
|
|
ifdef JAPAN
|
|
; M002 -- begin added section
|
|
;
|
|
; Before we go ANY further, let's see if we actually have room
|
|
; for our worst case memory allocation needs. Notice that
|
|
; we're actually trusting the MAX fields from the KEYBOARD
|
|
; definition file. If it lies to us and has fields bigger
|
|
; than these MAX values, we may crash over memory we don't
|
|
; own during initialization.
|
|
|
|
mov ax,NUM_DESIG_CP
|
|
mul MAX_SPEC_SIZE
|
|
or dx,dx ; error if overflowed 16 bits
|
|
jnz mem_alloc_err
|
|
|
|
add ax,SA_HEADER_SIZE
|
|
jc mem_alloc_err
|
|
add ax,MAX_LOGIC_SIZE
|
|
jc mem_alloc_err
|
|
add ax,MAX_COM_SIZE
|
|
jc mem_alloc_err
|
|
|
|
; Note that ax could be used for the RESIDENT_END_ACC value,
|
|
; but since this check is being added late in the testing
|
|
; cycle, we'll leave that calculation alone.
|
|
|
|
add ax,di ; get the ending offset of temp buffer
|
|
jc mem_alloc_err
|
|
|
|
add ax,15
|
|
jc mem_alloc_err
|
|
mov cl,4 ; convert to paragraph
|
|
shr ax,cl
|
|
mov cx,ax
|
|
mov ax,cs ; get our code segment
|
|
add ax,cx ; this is our ending segment
|
|
cmp ax,cs:[2] ; compare against psp:2
|
|
jb mem_alloc_ok
|
|
mem_alloc_err:
|
|
jmp TB_ERROR5
|
|
mem_alloc_ok:
|
|
|
|
; M002 -- end added section
|
|
endif ; JAPAN
|
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
; ** 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
|
|
ifndef JAPAN
|
|
mov cx,4
|
|
jmp TB_CPN_INVALID
|
|
else ; JAPAN
|
|
jmp TB_ERROR4
|
|
endif ; JAPAN
|
|
|
|
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
|
|
ifndef JAPAN
|
|
mov cx,4
|
|
jmp TB_CPN_INVALID
|
|
else ; JAPAN
|
|
jmp TB_ERROR4
|
|
endif ; JAPAN
|
|
|
|
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
|
|
|
|
ifndef JAPAN
|
|
; M002 -- dead code deleted. The following label was only
|
|
; branched to with cx==4. Those calls were all
|
|
; replaced with direct JMPs to TB_ERROR4, which was
|
|
; assumed to set cx=4 in other places anyway.
|
|
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
|
|
endif ; !JAPAN
|
|
|
|
TB_ERROR4:
|
|
ifndef JAPAN
|
|
cmp cx,4 ; Set error 4 return code
|
|
jnz TB_ERROR5
|
|
else ; JAPAN
|
|
mov cx,4 ; M002 ; set error 4 return code
|
|
endif ; JAPAN
|
|
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
|