2025-04-27 07:49:33 -04:00

655 lines
14 KiB
NASM
Raw Permalink 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
TITLE PARSE CODE AND CONTROL BLOCKS FOR KEYB.COM
;****************** START OF SPECIFICATIONS **************************
;
; MODULE NAME: PARSER.ASM
;
; DESCRIPTIVE NAME: PARSES THE COMMAND LINE PARAMETERS FOR KEYB.COM
;
; FUNCTION: THE COMMAND LINE IN THE PSP IS PARSED FOR PARAMETERS.
;
; ENTRY POINT: PARSE_PARAMETERS
;
; INPUT: BP POINTS TO PARAMETER LIST
; DS & ES POINT TO PSP
;
; AT EXIT:
; PARAMETER LIST FILLED IN AS REQUIRED.
;
; INTERNAL REFERENCES:
;
; ROUTINES: SYSPARSE - PARSING CODE
;
; DATA AREAS: PARMS - PARSE CONTROL BLOCK FOR SYSPARSE
;
; EXTERNAL REFERENCES:
;
; ROUTINES: N/A
;
; DATA AREAS: PARAMETER LIST BLOCK TO BE FILLED.
;
; NOTES:
;
; REVISION HISTORY:
; A000 - DOS Version 3.40
; 3/24/88 AN003 - P3906 PARSER changes to return "bogus" parameter on the
; "Parameter value not allowed " message - CNS
; 5/12/88 AN004 - P4867 /ID:NON-Numeric hangs the sytem as a 1st positional
;
;
; (C) Copyright Microsoft Corp. 1987-1990
; MS-DOS 5.00 - NLS Support - KEYB Command
;
;
;****************** END OF SPECIFICATIONS ****************************
INCLUDE KEYBDCL.INC
ID_VALID EQU 0
ID_INVALID EQU 1
NO_ID EQU 2
LANGUAGE_VALID EQU 0
LANGUAGE_INVALID EQU 1
NO_LANGUAGE EQU 2
NO_IDLANG EQU 3
CODE_PAGE_VALID EQU 0
CODE_PAGE_INVALID EQU 1
NO_CODE_PAGE EQU 2
VALID_SYNTAX EQU 0
INVALID_SYNTAX EQU 1
COMMAND_LINE_START EQU 81H
RC_EOL EQU -1
RC_NO_ERROR EQU 0
RC_OP_MISSING EQU 2
RC_NOT_IN_SW EQU 3
;***CNS P4867 1st CHECK for /ID:ALPHA
RC_SW_FIRST EQU 9
;***CNS P4867 1st CHECK for /ID:ALPHA
ERROR_COND EQU -1
NUMBER EQU 1
STRING EQU 3
FILE_SPEC EQU 5
MAX_ID EQU 999
LANG_LENGTH EQU 2
INVALID_SWITCH EQU 3
TOO_MANY EQU 1
INVALID_PARAM EQU 10
VALUE_DISALLOW EQU 8
PUBLIC PARSE_PARAMETERS ; near procedure for parsing command line
PUBLIC CUR_PTR ; near procedure for parsing command line
PUBLIC OLD_PTR ; near procedure for parsing command line
PUBLIC ERR_PART ; near procedure for parsing command line
EXTRN BAD_ID:BYTE ; WGR to match old code
EXTRN FOURTH_PARM:BYTE ; WGR to match old code
EXTRN ONE_PARMID:BYTE ; WGR to match old code
EXTRN FTH_PARMID:BYTE ; WGR to match old code
EXTRN ALPHA:BYTE ; WGR to match old code
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; Set assemble switches for parse code that is not required!!
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
DateSW EQU 0
TimeSW EQU 0
CmpxSW EQU 0
DrvSW EQU 0
QusSW EQU 0
KeySW EQU 0
Val1SW EQU 0
Val2SW EQU 0
Val3SW EQU 0
CODE SEGMENT PUBLIC 'CODE' BYTE
ASSUME CS:CODE,DS:CODE
.XLIST
INCLUDE PARSE.ASM ; Parsing code
.LIST
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; PARM control blocks for KEYB
; Parsing command line as follows:
;
; KEYB [lang],[cp],[[d:][path]KEYBOARD.SYS][/ID:id][/e][/?]
;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
PARMS LABEL WORD
DW PARMSX
DB 0 ; no extra delimeters or EOLs.
PARMSX LABEL BYTE
DB 0,3 ; min,max positional operands
DW LANG ; pointer to control block
DW CP ; pointer to control block
DW FILE_NAME ; pointer to control block
DB 3 ; 3 switches
DW ID_VALUE ; pointer to control block
dw help_value ; pointer to control block
dw ext_value ; pointer to control block
DB 0 ; no keywords
LANG LABEL WORD
DW 0A001H ; sstring or numeric value (optional)
DW 0002H ; cap result by char table (sstring)
DW RESULT_BUF ; result
DW NOVALS ; no value checking done
DB 0 ; no keyword/switch synonyms
CP LABEL WORD
DW 8001H ; numeric
DW 0 ; no functions
DW RESULT_BUF ; result
DW NOVALS ; no value checking done
DB 0 ; no keyword/switch synonyms
FILE_NAME LABEL WORD
DW 0201H ; file spec
DW 0001H ; cap by file table
DW RESULT_BUF ; result
DW NOVALS ; no value checking done
DB 0 ; no keyword/switch synonyms
ID_VALUE LABEL WORD
DW 8010H ; numeric
DW 0 ; no functions
DW RESULT_BUF ; result
DW NOVALS ; no value checking done
DB 1 ; 1 switch synonym
id_name:
DB "/ID",0 ; ID switch
help_value label word
dw 0 ; no values
dw 0 ; no functions
dw RESULT_BUF ; result
dw novals ; no value checking done
db 1 ; 1 switch synonym
help_name:
db "/?",0 ; /? switch
ext_value label word
dw 0 ; no values
dw 0 ; no functions
dw result_buf ; result
dw novals ; no value checking done
db 1 ; 1 switch synonym
ext_name:
db "/E",0 ; /e switch
NOVALS LABEL BYTE
DB 0 ; no value checking done
RESULT_BUF LABEL BYTE
RESULT_TYPE DB 0 ; type returned (number, string, etc.)
DB ? ; matched item tag (if applicable)
RESULT_SYN_PTR DW ? ; synonym ptr (if applicable)
RESULT_VAL DD ? ; value
LOOP_COUNT DB 0 ; keeps track of parameter position
;***CNS
CUR_PTR DW 0 ; keeps track of parameter position
OLD_PTR DW 0 ; keeps track of parameter position
ERR_PART DW 0 ; keeps track of parameter position
;***CNS
;..and reports an error condition
public pswitches
pswitches db 0 ; bit 0, /?, bit 1 /e
TEMP_FILE_NAME DB 128 DUP(0) ; place for file name
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;
; PROCEDURE_NAME: PARSE_PARAMETERS
;
; FUNCTION:
; THIS PROCEDURE PARSES THE COMMAND LINE PARAMETERS IN THE PSP FOR
; KEYB.COM. THE PARAMETER LIST BLOCK IS FILLED IN ACCORDINGLY.
;
; AT ENTRY: AS ABOVE.
;
; AT EXIT:
; AS ABOVE.
;
; AUTHOR: WGR
;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
PARSE_PARAMETERS PROC NEAR
XOR AX,AX ; setup default parameters.
MOV [BP].RET_CODE_1,NO_IDLANG
MOV [BP].RET_CODE_2,NO_CODE_PAGE
MOV [BP].RET_CODE_3,VALID_SYNTAX
MOV [BP].RET_CODE_4,NO_ID
MOV [BP].PATH_LENGTH,AX
LEA DI,PARMS ; setup parse blocks
MOV SI,COMMAND_LINE_START
call save_curptr
XOR CX,CX
XOR DX,DX
CALL SYSPARSE
kbs_10:
cmp ax,RC_EOL ; while not end of line and...
jnz kbs_11
jmp kbs_12
kbs_11:
cmp LOOP_COUNT,ERROR_COND ; parameters valid, do...
jnz kbs_13
jmp kbs_12
kbs_13:
cmp ax,RC_NOT_IN_SW ; invalid switch?
jz kbs_08
cmp ax,RC_SW_FIRST
jnz kbs_09
kbs_08:
MOV [BP].RET_CODE_3,INVALID_SYNTAX ; set invalid syntax flag.
MOV LOOP_COUNT,ERROR_COND ; set error flag to exit parse.
;***CNS
MOV ERR_PART,INVALID_SWITCH
call save_curptr
;***CNS
jmp kbs_10
kbs_09:
cmp RESULT_SYN_PTR,offset id_name ; was /id:xxx switch found?
jnz not_id_switch
MOV AX,WORD PTR RESULT_VAL+2 ; is it valid?
OR AX,AX
jnz kbs_01
mov ax,word ptr RESULT_VAL
cmp ax,MAX_ID
jna kbs_02
kbs_01:
MOV [BP].RET_CODE_1,ID_INVALID ; no...invalid id.
MOV [BP].RET_CODE_3,INVALID_SYNTAX ; syntax error.
MOV LOOP_COUNT,ERROR_COND ; set flag to exit parse
mov bad_id,1
MOV [ERR_PART],VALUE_DISALLOW ; SET ERROR TYPE FOR DISPLAY
call save_curptr
jmp short kbs_03
kbs_02:
MOV [BP].RET_CODE_4,ID_VALID ; yes...set return code 4.
MOV [BP].ID_PARM,AX
mov fourth_parm,1
mov fth_parmid,1
jmp short kbs_03
not_id_switch:
cmp RESULT_SYN_PTR,offset help_name ; was /? switch found?
jnz not_help_switch
or pswitches,1 ; set flag for /?
jmp short kbs_03
not_help_switch:
cmp RESULT_SYN_PTR,offset ext_name
jnz kbs_07
or pswitches,2 ; set flag for /e
jmp short kbs_03
kbs_07:
INC LOOP_COUNT ; positional encountered...
cmp LOOP_COUNT,1 ; check for language
jnz kbs_04
CALL PROCESS_1ST_PARM
call save_curptr
jmp short kbs_03
kbs_04:
cmp LOOP_COUNT,2 ; check for code page
jnz kbs_05
CALL PROCESS_2ND_PARM
call save_curptr
jmp short kbs_03
kbs_05:
cmp LOOP_COUNT,3 ; check for file name
jnz kbs_06
CALL PROCESS_3RD_PARM
call save_curptr
jmp short kbs_03
; all other cases
kbs_06:
MOV [BP].RET_CODE_3,INVALID_SYNTAX ; too many parms
call save_curptr
MOV ERR_PART,TOO_MANY
MOV LOOP_COUNT,ERROR_COND ; set error flag to exit parse.
kbs_03:
MOV RESULT_TYPE,0 ; reset result block.
CALL SYSPARSE ; parse next parameter.
jmp kbs_10
kbs_12:
cmp [bp].RET_CODE_4,ID_VALID
jnz kbs_14 ; ensure that if switch was
cmp [bp].RET_CODE_1,LANGUAGE_VALID ; used, it was valid keyword
jz kbs_14
MOV [BP].RET_CODE_3,INVALID_SYNTAX ; code was used..
;***CNS
call save_curptr
MOV ERR_PART,VALUE_DISALLOW
;***CNS
kbs_14:
RET
PARSE_PARAMETERS ENDP
save_curptr proc near
PUSH AX ;Save environment
MOV AX,CUR_PTR ;Set advancing ptr to end of argument
MOV OLD_PTR,AX ;after saving the beginning the string
MOV CUR_PTR,SI
POP AX ;Restore the environment
ret
save_curptr endp
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;
; PROCEDURE_NAME: PROCESS_1ST_PARM
;
; FUNCTION:
; THIS PROCEDURE PROCESSES THE FIRST POSITIONAL PARAMETER. THIS SHOULD
; BE THE LANGUAGE ID OR THE KEYBOARD ID.
;
; AT ENTRY: PARSE RESULT BLOCK CONTAINS VALUES IF AX HAS NO ERROR.
;
; AT EXIT:
; PARAMETER CONTROL BLOCK UPDATED FOR LANGUAGE ID.
;
; AUTHOR: WGR
;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
PROCESS_1ST_PARM PROC NEAR
cmp ax,RC_NO_ERROR ; error on parse?
jng kbs_23
MOV [BP].RET_CODE_1,LANGUAGE_INVALID ; yes...set invalid language
MOV [BP].RET_CODE_3,INVALID_SYNTAX ; and syntax error..
MOV LOOP_COUNT,ERROR_COND ; set flag to exit parse.
MOV ERR_PART,AX
jmp kbs_18
kbs_23:
cmp RESULT_TYPE,NUMBER ; was this a number (id?)
jnz kbs_24
MOV AX,WORD PTR RESULT_VAL+2 ; yes...check to see if
OR AX,AX ; within range.
jnz kbs_19
MOV AX,WORD PTR RESULT_VAL
cmp ax,max_id
jna kbs_17
kbs_19:
MOV [BP].RET_CODE_1,ID_INVALID ; no...invalid id.
MOV [BP].RET_CODE_3,INVALID_SYNTAX ; syntax error.
MOV LOOP_COUNT,ERROR_COND ; set flag to exit parse
mov bad_id,1
jmp short kbs_18
kbs_17:
MOV [BP].RET_CODE_1,ID_VALID ; valid id...set
MOV [BP].RET_CODE_4,ID_VALID ; valid id...set
MOV [BP].ID_PARM,AX ; and value moved into block
MOV LOOP_COUNT,4 ; there should be no more parms
mov one_parmid,1
jmp short kbs_18
kbs_24:
cmp RESULT_TYPE,STRING ; must be a string then???
jnz kbs_26
PUSH SI
PUSH DI
PUSH CX
PUSH DS
LDS SI,RESULT_VAL ; get ptr to string
MOV DI,BP
ADD DI,LANGUAGE_PARM ; point to block for copy.
MOV CX,LANG_LENGTH ; maximum length = 2
LODSB ; load AL with 1st char..
kbs_16:
jcxz kbs_15 ; do twice, unless only 1 char
or al,al
jz kbs_15
STOSB ; store
DEC CX ; dec count
LODSB ; load
jmp kbs_16
kbs_15:
or cx,cx ; if there was less than 2 or..
jnz kbs_20
or al,al ; greater than 2 chars, then..
jz kbs_21
kbs_20:
MOV [BP].RET_CODE_1,LANGUAGE_INVALID ; invalid.
MOV [BP].RET_CODE_3,INVALID_SYNTAX ; syntax error
MOV ERR_PART,INVALID_PARAM
MOV LOOP_COUNT,ERROR_COND ; set flag to exit parse.
jmp short kbs_22
kbs_21:
MOV [BP].RET_CODE_1,LANGUAGE_VALID ; valid language has been copied
MOV ALPHA,1 ; language found
kbs_22:
POP DS
POP CX
POP DI
POP SI
jmp short kbs_18
; omitted parameter...
kbs_26:
MOV [BP].RET_CODE_3,INVALID_SYNTAX ; invalid since further parameters.
kbs_18:
RET
PROCESS_1ST_PARM ENDP
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;
; PROCEDURE_NAME: PROCESS_2ND_PARM
;
; FUNCTION:
; THIS PROCEDURE PROCESSES THE 2ND POSITIONAL PARAMETER. THIS SHOULD
; BE THE CODE PAGE, IF REQUESTED.
;
; AT ENTRY: PARSE RESULT BLOCK CONTAINS VALUES IF AX HAS NO ERROR.
;
; AT EXIT:
; PARAMETER CONTROL BLOCK UPDATED FOR CODE PAGE.
;
; AUTHOR: WGR
;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
PROCESS_2ND_PARM PROC NEAR
cmp ax,RC_NO_ERROR ; if parse error
jle kbs_32
MOV [BP].RET_CODE_2,CODE_PAGE_INVALID ; mark invalid..
MOV [BP].RET_CODE_3,INVALID_SYNTAX ; syntax error
MOV LOOP_COUNT,ERROR_COND ; set flag to exit parse
MOV ERR_PART,AX
jmp short kbs_31
kbs_32:
cmp RESULT_TYPE,NUMBER ; was parameter specified?
jnz kbs_30
MOV AX,WORD PTR RESULT_VAL+2 ; yes..if code page not..
OR AX,AX
jnz kbs_27
MOV AX,WORD PTR RESULT_VAL ; valid..then
cmp ax,MAX_ID
jna kbs_28
kbs_27:
MOV [BP].RET_CODE_2,CODE_PAGE_INVALID ; mark invalid..
MOV [BP].RET_CODE_3,INVALID_SYNTAX ; syntax error
MOV LOOP_COUNT,ERROR_COND ; set flag to exit parse
jmp short kbs_31
kbs_28:
MOV [BP].RET_CODE_2,CODE_PAGE_VALID ; else...valid code page
MOV [BP].CODE_PAGE_PARM,AX ; move into parm
jmp short kbs_31
kbs_30:
MOV [BP].RET_CODE_2,NO_CODE_PAGE ; mark as not specified.
kbs_31:
RET
PROCESS_2ND_PARM ENDP
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;
; PROCEDURE_NAME: PROCESS_3RD_PARM
;
; FUNCTION:
; THIS PROCEDURE PROCESSES THE 3RD POSITIONAL PARAMETER. THIS SHOULD
; BE THE KEYBOARD DEFINITION FILE PATH, IF SPECIFIED.
;
; AT ENTRY: PARSE RESULT BLOCK CONTAINS VALUES IF AX HAS NO ERROR.
;
; AT EXIT:
; PARAMETER CONTROL BLOCK UPDATED FOR FILE NAME.
;
; AUTHOR: WGR
;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
PROCESS_3RD_PARM PROC NEAR
cmp ax,RC_NO_ERROR ; if parse error, then...
jle kbs_33
MOV [BP].RET_CODE_3,INVALID_SYNTAX ; syntax error.
MOV LOOP_COUNT,ERROR_COND ; set flag to exit parse
MOV ERR_PART,AX
jmp short kbs_34
kbs_33:
cmp RESULT_TYPE,FILE_SPEC
jnz kbs_34
PUSH DS
PUSH SI
PUSH DI
PUSH CX
LDS SI,RESULT_VAL ; load offset of file name
LEA DI,TEMP_FILE_NAME
MOV [BP].PATH_OFFSET,DI ; copy to parameter block
XOR CX,CX
LODSB ; count the length of the path.
kbs_35:
or al,al
jz kbs_36
STOSB
LODSB
INC CX
jmp short kbs_35
kbs_36:
MOV [BP].PATH_LENGTH,CX ; copy to parameter block
POP CX
POP DI
POP SI
POP DS
kbs_34:
RET
PROCESS_3RD_PARM ENDP
CODE ENDS
END