diff options
Diffstat (limited to 'v4.0/src/INC/PARSE.ASM')
| -rw-r--r-- | v4.0/src/INC/PARSE.ASM | 2974 |
1 files changed, 2974 insertions, 0 deletions
diff --git a/v4.0/src/INC/PARSE.ASM b/v4.0/src/INC/PARSE.ASM new file mode 100644 index 0000000..80dc9d7 --- /dev/null +++ b/v4.0/src/INC/PARSE.ASM | |||
| @@ -0,0 +1,2974 @@ | |||
| 1 | PAGE ;AN000; | ||
| 2 | ; $SALUT (4,4,8,41) | ||
| 3 | ;(deleted).XLIST | ||
| 4 | ;(deleted)INCLUDE STRUC.INC ;AN020;structured macro definitions for .IF,.ELSE etc. | ||
| 5 | ;(deleted).LIST | ||
| 6 | ; | ||
| 7 | ; NOTE: basesw must be set properly to allow the PARSER to access psdata. | ||
| 8 | ; - basesw undefined means CS seg. override for psdata access. | ||
| 9 | ; - basesw = 1 means DS seg. override for psdata access & | ||
| 10 | ; DS must point to psdata. | ||
| 11 | ; - basesw = 0 means ES seg. override for psdata access & | ||
| 12 | ; ES must point to psdata. | ||
| 13 | ; | ||
| 14 | ; | ||
| 15 | IFNDEF basesw ;AN022; | ||
| 16 | psdata_seg EQU CS ;AN022; | ||
| 17 | ELSE ;AN022; | ||
| 18 | IF basesw ;AN022;IF "basesw EQU 1" specified by caller THEN | ||
| 19 | psdata_seg EQU DS ;AN022; | ||
| 20 | ELSE ;AN022; | ||
| 21 | psdata_seg EQU ES ;AN022;ELSE only other choice is ES (basesw EQU 0) | ||
| 22 | ENDIF ;AN022; | ||
| 23 | ENDIF ;AN022; | ||
| 24 | |||
| 25 | ifndef incsw ;AN000; (tm03) Someone doesn't want to include psdata | ||
| 26 | incsw equ 1 ;AN000; include psdata.inc (tm03) | ||
| 27 | endif ;AN000; (tm03) | ||
| 28 | if incsw ;AN000; If incsw = 1 then (tm03) | ||
| 29 | include psdata.inc ;AN000; include psdata.inc (tm03) | ||
| 30 | endif ;AN000; endif (tm03) | ||
| 31 | PAGE ;AN000; | ||
| 32 | IF1 ;AN000; | ||
| 33 | %OUT INCLUDING COMP=COMMON DSN=PARSE.ASM...;AN000; | ||
| 34 | ENDIF ;AN000; | ||
| 35 | ;*********************************************************************** | ||
| 36 | ; SysParse; | ||
| 37 | ; | ||
| 38 | ; Function : Parser Entry | ||
| 39 | ; | ||
| 40 | ; Input: DS:SI -> command line | ||
| 41 | ; ES:DI -> parameter block | ||
| 42 | ; psdata_seg -> psdata.inc | ||
| 43 | ; CX = operand ordinal | ||
| 44 | ; | ||
| 45 | ; Note: ES is the segment containing all the control blocks defined | ||
| 46 | ; by the caller, except for the DOS COMMAND line parms, which | ||
| 47 | ; is in DS. | ||
| 48 | ; | ||
| 49 | ; Output: CY = 1 error of caller, means invalid parameter block or | ||
| 50 | ; invalid value list. But this parser does NOT implement | ||
| 51 | ; this feature. Therefore CY always zero. | ||
| 52 | ; | ||
| 53 | ; CY = 0 AX = return code | ||
| 54 | ; BL = terminated delimiter code | ||
| 55 | ; CX = new operand ordinal | ||
| 56 | ; SI = set past scaned operand | ||
| 57 | ; DX = selected result buffer | ||
| 58 | ; | ||
| 59 | ; Use: $P_Skip_Delim, $P_Chk_EOL, $P_Chk_Delim, $P_Chk_DBCS | ||
| 60 | ; $P_Chk_Swtch, $P_Chk_Pos_Control, $P_Chk_Key_Control | ||
| 61 | ; $P_Chk_Sw_Control, $P_Fill_Result | ||
| 62 | ; | ||
| 63 | ; Vars: $P_Ordinal(RW), $P_RC(RW), $P_SI_Save(RW), $P_DX(R), $P_Terminator(R) | ||
| 64 | ; $P_SaveSI_Cmpx(W), $P_Flags(RW), $P_Found_SYNONYM(R), $P_Save_EOB(W) | ||
| 65 | ; | ||
| 66 | ;-------- Modification History ----------------------------------------- | ||
| 67 | ; | ||
| 68 | ; 4/04/87 : Created by K. K, | ||
| 69 | ; 4/28/87 : $P_Val_YH assemble error (tm01) | ||
| 70 | ; : JMP SHORT assemble error (tm02) | ||
| 71 | ; 5/14/87 : Someone doesn't want to include psdata (tm03) | ||
| 72 | ; 6/12/87 : $P_Bridge is missing when TimeSw equ 0 and (CmpxSw equ 1 or | ||
| 73 | ; DateSW equ 1) (tm04) | ||
| 74 | ; 6/12/87 : $P_SorD_Quote is missing when QusSw equ 0 and CmpxSW equ 1 | ||
| 75 | ; (tm05) in PSDATA.INC | ||
| 76 | ; 6/12/87 : $P_FileSp_Char and $P_FileSP_Len are missing | ||
| 77 | ; when FileSW equ 0 and DrvSW equ 1 (tm06) in PSDATA.INC | ||
| 78 | ; 6/18/87 : $VAL1 and $VAL3, $VAL2 and $VAL3 can be used in the same | ||
| 79 | ; value-list block (tm07) | ||
| 80 | ; 6/20/87 : Add $P_SW to check if there's an omiting parameter after | ||
| 81 | ; switch (keyword) or not. If there is, backup si for next call | ||
| 82 | ; (tm08) | ||
| 83 | ; 6/24/87 : Complex Item checking does not work correctly when CmpSW equ 1 | ||
| 84 | ; and DateSW equ 0 and TimeSW equ 0 (tm09) | ||
| 85 | ; 6/24/87 : New function flag $P_colon_is_not_necessary for switch | ||
| 86 | ; /+15 and /+:15 are allowed for user (tm10) | ||
| 87 | ; 6/29/87 : ECS call changes DS register but it causes the address problem | ||
| 88 | ; in user's routines. $P_Chk_DBCS (tm11) | ||
| 89 | ; 7/10/87 : Switch with no_match flag (0x0000H) does not work correctly | ||
| 90 | ; (tm12) | ||
| 91 | ; 7/10/87 : Invalid switch/keyword does not work correctly | ||
| 92 | ; (tm13) | ||
| 93 | ; 7/10/87 : Drive_only breaks 3 bytes after the result buffer | ||
| 94 | ; (tm14) | ||
| 95 | ; 7/12/87 : Too_Many_Operands sets DX=0 as the PARSE result | ||
| 96 | ; (tm15) | ||
| 97 | ; 7/24/87 : Negative lower bound on numeric ranges cause trouble | ||
| 98 | |||
| 99 | ; 7/24/87 : Quoted strings being returned with quotes. | ||
| 100 | |||
| 101 | ; 7/28/87 : Kerry S (;AN018;) | ||
| 102 | ; Non optional value on switch (match flags<>0 and <>1) not flagged | ||
| 103 | ; as an error when missing. Solution: return error 2. Modules | ||
| 104 | ; affected: $P_Chk_SW_Control. | ||
| 105 | |||
| 106 | ; 7/29/87 : Kerry S (;AN019;) | ||
| 107 | ; Now allow the optional bit in match flags for switches. This | ||
| 108 | ; allows the switch to be encountered with a value or without a | ||
| 109 | ; value and no error is returned. | ||
| 110 | ; | ||
| 111 | |||
| 112 | ; 8/28/87 : Ed K, Kerry S (;AN020;) | ||
| 113 | ; 9/14/87 In PROC $P_Get_DecNum, when checking for field separators | ||
| 114 | ; within a date response, instead of checking just for the one | ||
| 115 | ; character defined by the COUNTRY DEPENDENT INFO, check for | ||
| 116 | ; all three chars, "-", "/", and ".". Change $P_Chk_Switch to allow | ||
| 117 | ; slashes in date strings when DateSw (assembler switch) is set. | ||
| 118 | |||
| 119 | ; 9/1/87 : Kerry S (;AN021) | ||
| 120 | ; In PROC $P_String_Comp, when comparing the switch or keyword on | ||
| 121 | ; the command line with the string in the control block the | ||
| 122 | ; comparing was stopping at a colon (switch) or equal (keyword) | ||
| 123 | ; on the command line and assuming a match. This allowed a shorter | ||
| 124 | ; string on the command line than in the synonym list in the control | ||
| 125 | ; block. I put in a test for a null in the control block so the | ||
| 126 | ; string in the control block must be the same length as the string | ||
| 127 | ; preceeding the colon or equal on the command line. | ||
| 128 | |||
| 129 | ; 8/28/87 : Kerry S (;AN022;) | ||
| 130 | ; All references to data in PSDATA.INC had CS overrides. This caused | ||
| 131 | ; problems for people who included it themselves in a segment other | ||
| 132 | ; than CS. Added switch to allow including PSDATA.INC in any | ||
| 133 | ; segment. | ||
| 134 | |||
| 135 | ; 9/16/87 : Ed K (;AN023;) PTM1040 | ||
| 136 | ; in $p_set_cdi PROC, it assumes CS points to psdata. Change Push CS | ||
| 137 | ; into PUSH PSDATA_SEG. In $P_Get_DecNum PROC, fix AN020 | ||
| 138 | ; forced both TIME and DATE to use the delims, "-","/",".". | ||
| 139 | ; Created FLag, in $P_time_Format PROC, to request the delim in | ||
| 140 | ; BL be used if TIME is being parsed. | ||
| 141 | |||
| 142 | ; 9/24/87 : Ed K | ||
| 143 | ; Removed the include to STRUC.INC. Replaced the STRUC macro | ||
| 144 | ; invocations with their normally expanded code; made comments | ||
| 145 | ; out of the STRUC macro invocation statements to maintain readability. | ||
| 146 | |||
| 147 | ; 9/24/87 : Ed K (;AN024;) PTM1222 | ||
| 148 | ; When no CONTROL for a keyword found, tried to fill in RESULT | ||
| 149 | ; pointed to by non-existant CONTROL. | ||
| 150 | |||
| 151 | ; 10/15/87 : Ed K (;AN025;) PTM1672 | ||
| 152 | ; A quoted text string can be framed only by double quote. Remove | ||
| 153 | ; support to frame quoted text string with single quote. | ||
| 154 | ; (apostrophe) $P_SorD_Quote is removed from PSDATA.INC. | ||
| 155 | ; $P_SQuote EQU also removed from PSDATA.INC. Any references to | ||
| 156 | ; single quote in PROC prologues are left as is for history reasons. | ||
| 157 | |||
| 158 | ; This fixes another bug, not mentioned in p1672, in that two | ||
| 159 | ; quote chars within a quoted string is supposed to be reported as | ||
| 160 | ; one quote character, but is reported as two quotes. This changed | ||
| 161 | ; two instructions in PROC $P_Quoted_Str. | ||
| 162 | |||
| 163 | ; Also fixed are several JMP that caused a NOP, these changed to | ||
| 164 | ; have the SHORT operator to avoid the unneeded NOP. | ||
| 165 | |||
| 166 | ; The code and PSDATA.INC have been aligned for ease of reading. | ||
| 167 | |||
| 168 | ; 10/26/87 : Ed K (;AN026;) PTM2041, DATE within SWITCH, BX reference to | ||
| 169 | ; psdata buffer should have psdata_seg. | ||
| 170 | |||
| 171 | ; 10/27/87 : Ed K (;AN027;) PTM2042 comma between keywords implies | ||
| 172 | ; positional missing. | ||
| 173 | |||
| 174 | ; 11/06/87 : Ed K (;AN028;) PTM 2315 Parser should not use line feed | ||
| 175 | ; as a line delimiter, should use carriage return. | ||
| 176 | ; Define switch: LFEOLSW, if on, accept LF as end of line char. | ||
| 177 | |||
| 178 | ; 11/11/87 : Ed K (;AN029;) PTM 1651 GET RID OF WHITESPACE AROUND "=". | ||
| 179 | |||
| 180 | ; 11/18/87 : Ed K (;AN030;) PTM 2551 If filename is just "", then | ||
| 181 | ; endless loop since SI is returned still pointing to start | ||
| 182 | ; of that parm. | ||
| 183 | |||
| 184 | ; 11/19/87 : Ed K (;AN031;) PTM 2585 date & time getting bad values. | ||
| 185 | ; Vector to returned string has CS instead of Psdata_Seg, but | ||
| 186 | ; when tried to fix it on previous version, changed similar | ||
| 187 | ; but wrong place. | ||
| 188 | |||
| 189 | ; 12/09/87 : Bill L (;AN032;) PTM 2772 colon and period are now valid | ||
| 190 | ; delimiters between hours, minutes, seconds for time. And period | ||
| 191 | ; and comma are valid delimiters between seconds and 100th second. | ||
| 192 | |||
| 193 | ; 12/14/87 : Bill L (;AN033;) PTM 2722 if illegal delimiter characters | ||
| 194 | ; in a filespec, then flag an error. | ||
| 195 | |||
| 196 | ; 12/22/87 : Bill L (;AN034;) All local data to parser is now | ||
| 197 | ; indexed off of the psdata_seg equate instead of the DS register. | ||
| 198 | ; Using this method, DS can point to the segment of PSP or to psdata | ||
| 199 | ; --> local parser data. Why were some references to local data changed | ||
| 200 | ; to do this before, but not all ????? | ||
| 201 | |||
| 202 | ; 02/02/88 : Ed K (;AC035;) INSPECT utility, suggests optimizations. | ||
| 203 | |||
| 204 | ; 02/05/88 : Ed K (;AN036;) P3372-UPPERCASE TRANSLATION, PSDATA_SEG HOSED. | ||
| 205 | ; | ||
| 206 | ; 02/08/88 : Ed K (;AN037;) P3410-AVOID POP OF CS, CHECK BASESW FIRST. | ||
| 207 | |||
| 208 | ; 02/19/88 : Ed K (;AN038;) p3524 above noon and "am" should be error | ||
| 209 | |||
| 210 | ; 02/23/88 : Ed K (;AN039;) p3518 accept "comma" and "period" as decimal | ||
| 211 | ; separator in TIME before hundredths field. | ||
| 212 | ; | ||
| 213 | ;*********************************************************************** | ||
| 214 | IF FarSW ;AN000;(Check if need far return) | ||
| 215 | SysParse proc far ;AN000; | ||
| 216 | ELSE ;AN000; | ||
| 217 | SysParse proc near ;AN000; | ||
| 218 | ENDIF ;AN000;(of FarSW) | ||
| 219 | ; $SALUT (4,9,17,41) | ||
| 220 | mov psdata_seg:$P_Flags,0 ;AC034; Clear all internal flags | ||
| 221 | IF TimeSw ;AN039; FOR TIME ONLY | ||
| 222 | MOV PSDATA_SEG:$P_ORIG_ORD,CX ;AN039; ORIGINAL ORDINAL FROM CX | ||
| 223 | MOV PSDATA_SEG:$P_ORIG_STACK,SP ;AN039; ORIGINAL VALUE OF STACK FROM SP | ||
| 224 | MOV PSDATA_SEG:$P_ORIG_SI,SI ;AN039; ORIGINAL START PARSE POINTER FROM SI | ||
| 225 | $P_REDO_TIME: ;AN039; try to parse time again | ||
| 226 | ENDIF ;AN039; FOR TIME ONLY | ||
| 227 | cld ;AN000; confirm forward direction | ||
| 228 | mov psdata_seg:$P_ordinal,cx ;AC034; save operand ordinal | ||
| 229 | mov psdata_seg:$P_RC,$P_No_Error ;AC034; Assume no error | ||
| 230 | mov psdata_seg:$P_Found_SYNONYM,0 ;AC034; initalize synonym pointer | ||
| 231 | |||
| 232 | mov word ptr psdata_seg:$P_DX,0 ;AC034; (tm15) | ||
| 233 | IF KeySW ;AN029; | ||
| 234 | ;IN CASE THE USER PUT OPTIONAL WHITESPACE CHARS AROUND THE "=" USED IN | ||
| 235 | ;KEYWORD DEFINITIONS, SCAN THE COMMAND LINE AND COMPRESS OUT ANY WHITESPACES | ||
| 236 | ;NEXT TO "=" BEFORE STARTING THE USUAL PARSING. | ||
| 237 | push cx ;AN029; | ||
| 238 | push dx ;AN029; | ||
| 239 | push di ;AN029; | ||
| 240 | |||
| 241 | push si ;AN029; remember where command line starts | ||
| 242 | mov cx,-1 ;AN029; init counter | ||
| 243 | ; $do | ||
| 244 | $P_loc_eol: ;AN029; | ||
| 245 | inc cx ;AN029; bump counter of chars up to EOL | ||
| 246 | lodsb ;AN029; get a char from command line | ||
| 247 | CALL $P_Chk_EOL ;AN029; see if AL is EOL char | ||
| 248 | |||
| 249 | ; enddo z | ||
| 250 | jnz $P_loc_EOL ;AN029; not found that EOL char | ||
| 251 | |||
| 252 | mov psdata_seg:$P_count_to_EOL,cx ;AN029;AC034;; save count of chars up to EOL | ||
| 253 | pop si ;AN029; restore start of command line | ||
| 254 | |||
| 255 | ;scan command string for combinations including "=", | ||
| 256 | ; and replace each with just the simple "=" | ||
| 257 | |||
| 258 | ;REPEAT UNTIL ONE PASS IS MADE WHEREIN NO CHANGES WERE MADE | ||
| 259 | ; $do | ||
| 260 | $P_DO1: ;AN029; | ||
| 261 | push si ;AN029; remember where string started | ||
| 262 | MOV CX,psdata_seg:$P_COUNT_TO_EOL ;AN029;AC034;; set count to no. chars in string, | ||
| 263 | ;AN029; not counting the EOL char | ||
| 264 | XOR BX,BX ;AN029;SET $P_REG_BL_DQ_SW TO "NOT IN QUOTES", AND... | ||
| 265 | ;AN029;SET $P_REG_BH_CG_SW TO "NO CHANGES MADE" | ||
| 266 | ;MAKE ONE PASS THRU THE STRING, LOOKING AT EACH CHARACTER | ||
| 267 | ; $do ;AN029; | ||
| 268 | $P_DO2: ;AN029; | ||
| 269 | cmp BYTE PTR [SI],$P_double_quote ;AN029; | ||
| 270 | ; $if e ;AN029;if a double quote was found | ||
| 271 | JNE $P_IF3 ;AN029; | ||
| 272 | NOT $P_REG_BL_DQ_SW ;AN029;TOGGLE THE DOUBLE QUOTE STATE SWITCH | ||
| 273 | ; $endif ;AN029; | ||
| 274 | $P_IF3: ;AN029; | ||
| 275 | OR $P_REG_BL_DQ_SW,$P_REG_BL_DQ_SW ;AN029;IS THE DOUBLE QUOTE SWITCH SET? | ||
| 276 | ; $if Z ;AN029;IF NOT IN DOUBLE QUOTES | ||
| 277 | JNZ $P_IF5 ;AN029; | ||
| 278 | mov ax,word ptr [si] ;AN029; get pair to be checked out | ||
| 279 | cmp ax,$P_BL_EQ ;AN029;" =" | ||
| 280 | ; $if e,or ;AN029; | ||
| 281 | JE $P_LL6 ;AN029; | ||
| 282 | cmp ax,$P_EQ_BL ;AN029;"= " | ||
| 283 | ; $if e,or ;AN029; | ||
| 284 | JE $P_LL6 ;AN029; | ||
| 285 | cmp ax,$P_EQ_TB ;AN029; "=<tab>" | ||
| 286 | ; $if e,or ;AN029; | ||
| 287 | JE $P_LL6 ;AN029; | ||
| 288 | cmp ax,$P_TB_EQ ;AN029;"<tab>=" | ||
| 289 | ; $if e ;AN029;if this pair to be replaced with a single "=" | ||
| 290 | JNE $P_IF6 ;AN029; | ||
| 291 | $P_LL6: ;AN029; | ||
| 292 | mov BYTE PTR [SI],$P_Keyword ;AN029; "=" | ||
| 293 | inc si ;AN029;point to next char after the new "=" | ||
| 294 | mov di,si ;AN029;move target right after new "=" | ||
| 295 | |||
| 296 | push si ;AN029;remember where i am, right after new "=" | ||
| 297 | PUSH CX ;AN029;SAVE CURRENT COUNT | ||
| 298 | inc si ;AN029;source is one beyond that | ||
| 299 | push es ;AN029;remember the extra segment | ||
| 300 | push ds ;AN029;temporarily, set source seg and | ||
| 301 | pop es ;AN029; target seg to the command line seg | ||
| 302 | rep movsb ;AN029;move chars left one position | ||
| 303 | pop es ;AN029;restore the extra segment | ||
| 304 | POP CX ;AN029;RESTORE CURRENT COUNT | ||
| 305 | pop si ;AN029;back to where I was | ||
| 306 | |||
| 307 | DEC SI ;AN029;LOOK AT FIRST CHAR JUST MOVED | ||
| 308 | MOV $P_REG_BH_CG_SW,-1 ;AN029;set switch to say "a change was made" | ||
| 309 | DEC psdata_seg:$P_COUNT_TO_EOL ;AN029;AC034;;because just threw away a char | ||
| 310 | dec CX ;AN029;DITTO | ||
| 311 | ; $endif ;AN029;comparand pair found? | ||
| 312 | $P_IF6: ;AN029; | ||
| 313 | ; $endif ;AN029;double quote switch? | ||
| 314 | $P_IF5: ;AN029; | ||
| 315 | inc si ;AN029;bump index to look at next char in command string | ||
| 316 | dec CX ;AN029;one less char to look at | ||
| 317 | ;(deleted ;AC035;) CMP CX,0 ;AN029;is char count all gone yet? | ||
| 318 | ; $enddo LE ;AN029;quit if no more chars | ||
| 319 | JNLE $P_DO2 ;AN029; | ||
| 320 | pop si ;AN029;remember where string started | ||
| 321 | OR $P_REG_BH_CG_SW,$P_REG_BH_CG_SW ;AN029;WAS "A CHANGE MADE"? | ||
| 322 | ; $enddo Z ;AN029;QUIT when no changes were made | ||
| 323 | JNZ $P_DO1 ;AN029; | ||
| 324 | pop di ;AN029; | ||
| 325 | pop dx ;AN029; | ||
| 326 | pop cx ;AN029; | ||
| 327 | |||
| 328 | ;NOW THAT ALL WHITESPACE SURROUNDING "=" HAVE BEEN COMPRESSED OUT, | ||
| 329 | ;RESUME NORMAL PARSING... | ||
| 330 | ENDIF ;AN029; KEYWORDS SUPPORTED? | ||
| 331 | call $P_Skip_Delim ;AN000; Move si to 1st non white space | ||
| 332 | jnc $P_Start ;AN000; If EOL is not encountered, do parse | ||
| 333 | |||
| 334 | ;--------------------------- End of Line | ||
| 335 | mov ax,$P_RC_EOL ;AN000; set exit code to -1 | ||
| 336 | push bx ;AN000; | ||
| 337 | mov bx,es:[di].$P_PARMSX_Address ;AN000; Get the PARMSX address to | ||
| 338 | cmp cl,es:[bx].$P_MinP ;AN000; check ORDINAL to see if the minimum | ||
| 339 | jae $P_Fin ;AN000; positional found. | ||
| 340 | |||
| 341 | mov ax,$P_Op_Missing ;AN000; If no, set exit code to missing operand | ||
| 342 | $P_Fin: ;AN000; | ||
| 343 | pop bx ;AN000; | ||
| 344 | jmp $P_Single_Exit ;AN000; return to the caller | ||
| 345 | |||
| 346 | ;--------------------------- | ||
| 347 | $P_Start: ;AN000; | ||
| 348 | mov psdata_seg:$P_SaveSI_Cmpx,si ;AN000;AC034; save ptr to command line for later use by complex, | ||
| 349 | push bx ;AN000; quoted string or file spec. | ||
| 350 | push di ;AN000; | ||
| 351 | push bp ;AN000; | ||
| 352 | lea bx,psdata_seg:$P_STRING_BUF ;AC034; set buffer to copy from command string | ||
| 353 | test psdata_seg:$P_Flags2,$P_Extra ;AC034; 3/9 extra delimiter encountered ? | ||
| 354 | jne $P_Pack_End ;AN000; 3/9 if yes, no need to copy | ||
| 355 | |||
| 356 | $P_Pack_Loop: ;AN000; | ||
| 357 | lodsb ;AN000; Pick a operand from buffer | ||
| 358 | call $P_Chk_Switch ;AN000; Check switch character | ||
| 359 | jc $P_Pack_End_BY_EOL ;AN020; if carry set found delimiter type slash, need backup si, else continue | ||
| 360 | |||
| 361 | call $P_Chk_EOL ;AN000; Check EOL character | ||
| 362 | je $P_Pack_End_BY_EOL ;AN000; need backup si | ||
| 363 | |||
| 364 | call $P_Chk_Delim ;AN000; Check delimiter | ||
| 365 | jne $P_PL01 ;AN000; If no, process next byte | ||
| 366 | |||
| 367 | test psdata_seg:$P_Flags2,$P_Extra ;AC034; 3/9 If yes and white spec, | ||
| 368 | ; (tm08)jne $P_Pack_End ;AN000; 3/9 then | ||
| 369 | jne $P_Pack_End_backup_si ;AN000; (tm08) | ||
| 370 | |||
| 371 | call $P_Skip_Delim ;AN000; skip subsequent white space,too | ||
| 372 | jmp short $P_Pack_End ;AN000; finish copy by placing NUL at end | ||
| 373 | |||
| 374 | $P_PAck_End_backup_si: ;AN000; (tm08) | ||
| 375 | test psdata_seg:$P_Flags2,$P_SW+$P_equ ;AN000;AC034; (tm08) | ||
| 376 | je $P_Pack_End ;AN000; (tm08) | ||
| 377 | |||
| 378 | dec si ;AN000; (tm08) | ||
| 379 | jmp short $P_Pack_End ;AN025; (tm08) | ||
| 380 | |||
| 381 | $P_PL01: ;AN000; | ||
| 382 | mov psdata_seg:[bx],al ;AN000; move byte to STRING_BUF | ||
| 383 | cmp al,$P_Keyword ;AN000; if it is equal character, | ||
| 384 | jne $P_PL00 ;AN000; then | ||
| 385 | |||
| 386 | or psdata_seg:$P_Flags2,$P_equ ;AC034; remember it in flag | ||
| 387 | $P_PL00: ;AN000; | ||
| 388 | inc bx ;AN000; ready to see next byte | ||
| 389 | call $P_Chk_DBCS ;AN000; was it 1st byte of DBCS ? | ||
| 390 | jnc $P_Pack_Loop ;AN000; if no, process to next byte | ||
| 391 | |||
| 392 | lodsb ;AN000; if yes, store | ||
| 393 | mov psdata_seg:[bx],al ;AN000; 2nd byte of DBCS | ||
| 394 | inc bx ;AN000; update pointer | ||
| 395 | jmp short $P_Pack_Loop ;AN000; process to next byte | ||
| 396 | |||
| 397 | $P_Pack_End_BY_EOL: ;AN000; | ||
| 398 | dec si ;AN000; backup si pointer | ||
| 399 | $P_Pack_End: ;AN000; | ||
| 400 | mov psdata_seg:$P_SI_Save,si ;AC034; save next pointer, SI | ||
| 401 | mov byte ptr psdata_seg:[bx],$P_NULL ;AN000; put NULL at the end | ||
| 402 | mov psdata_seg:$P_Save_EOB,bx ;AC034; 3/17/87 keep the address for later use of complex | ||
| 403 | mov bx,es:[di].$P_PARMSX_Address ;AN000; get PARMSX address | ||
| 404 | lea si,psdata_seg:$P_STRING_BUF ;AC034; | ||
| 405 | cmp byte ptr psdata_seg:[si],$P_Switch ;AN000; the operand begins w/ switch char ? | ||
| 406 | je $P_SW_Manager ;AN000; if yes, process as switch | ||
| 407 | |||
| 408 | test psdata_seg:$P_Flags2,$P_equ ;AC034; the operand includes equal char ? | ||
| 409 | jne $P_Key_manager ;AN000; if yes, process as keyword | ||
| 410 | |||
| 411 | $P_Positional_Manager: ;AN000; else process as positional | ||
| 412 | mov al,es:[bx].$P_MaxP ;AN000; get maxp | ||
| 413 | xor ah,ah ;AN000; ax = maxp | ||
| 414 | cmp psdata_seg:$P_ORDINAL,ax ;AC034; too many positional ? | ||
| 415 | jae $P_Too_Many_Error ;AN000; if yes, set exit code to too many | ||
| 416 | |||
| 417 | mov ax,psdata_seg:$P_ORDINAL ;AC034; see what the current ordinal | ||
| 418 | shl ax,1 ;AN000; ax = ax*2 | ||
| 419 | inc bx ;AC035; add '2' to | ||
| 420 | inc bx ;AC035; BX reg | ||
| 421 | ;AN000; now bx points to 1st CONTROL | ||
| 422 | ;(changed ;AC035;) add bx,2 ;AN000; now bx points to 1st CONTROL | ||
| 423 | add bx,ax ;AN000; now bx points to specified CONTROL address | ||
| 424 | mov bx,es:[bx] ;AN000; now bx points to specified CONTROL itself | ||
| 425 | call $P_Chk_Pos_Control ;AN000; Do process for positional | ||
| 426 | jmp short $P_Return_to_Caller ;AN000; and return to the caller | ||
| 427 | |||
| 428 | $P_Too_Many_Error: ;AN000; | ||
| 429 | mov psdata_seg:$P_RC,$P_Too_Many ;AC034; set exit code | ||
| 430 | jmp short $P_Return_to_Caller ;AN000; and return to the caller | ||
| 431 | ; | ||
| 432 | $P_SW_Manager: ;AN000; | ||
| 433 | mov al,es:[bx].$P_MaxP ;AN000; get maxp | ||
| 434 | xor ah,ah ;AN000; ax = maxp | ||
| 435 | inc ax ;AN000; | ||
| 436 | shl ax,1 ;AN000; ax = (ax+1)*2 | ||
| 437 | add bx,ax ;AN000; now bx points to maxs | ||
| 438 | mov cl,es:[bx] ;AN000; | ||
| 439 | xor ch,ch ;AN000; cx = maxs | ||
| 440 | or cx,cx ;AN000; at least one switch ? | ||
| 441 | je $P_SW_Not_Found ;AN000; | ||
| 442 | |||
| 443 | inc bx ;AN000; now bx points to 1st CONTROL address | ||
| 444 | |||
| 445 | $P_SW_Mgr_Loop: ;AN000; | ||
| 446 | push bx ;AN000; | ||
| 447 | mov bx,es:[bx] ;AN000; bx points to Switch CONTROL itself | ||
| 448 | call $P_Chk_SW_Control ;AN000; do process for switch | ||
| 449 | pop bx ;AN000; | ||
| 450 | jnc $P_Return_to_Caller ;AN000; if the CONTROL is for the switch, exit | ||
| 451 | |||
| 452 | inc bx ;AC035; add '2' to | ||
| 453 | inc bx ;AC035; BX reg | ||
| 454 | ;AN000; else bx points to the next CONTROL | ||
| 455 | ;(changed ;AC035;) add bx,2 ;AN000; else bx points to the next CONTROL | ||
| 456 | loop $P_SW_Mgr_Loop ;AN000; and loop | ||
| 457 | |||
| 458 | $P_SW_Not_Found: ;AN000; | ||
| 459 | mov psdata_seg:$P_RC,$P_Not_In_SW ;AC034; here no CONTROL for the switch has | ||
| 460 | jmp short $P_Return_to_Caller0 ;AN000; not been found, means error. | ||
| 461 | ; | ||
| 462 | $P_Key_Manager: ;AN000; | ||
| 463 | mov al,es:[bx].$P_MaxP ;AN000; get maxp | ||
| 464 | xor ah,ah ;AN000; ax = maxp | ||
| 465 | inc ax ;AN000; | ||
| 466 | shl ax,1 ;AN000; ax = (ax+1)*2 | ||
| 467 | add bx,ax ;AN000; now bx points to maxs | ||
| 468 | mov al,es:[bx] ;AN000; | ||
| 469 | xor ah,ah ;AN000; ax = maxs | ||
| 470 | shl ax,1 ;AN000; | ||
| 471 | inc ax ;AN000; ax = ax*2+1 | ||
| 472 | add bx,ax ;AN000; now bx points to maxk | ||
| 473 | mov cl,es:[bx] ;AN000; | ||
| 474 | xor ch,ch ;AN000; cx = maxk | ||
| 475 | or cx,cx ;AN000; at least one keyword ? | ||
| 476 | je $P_Key_Not_Found ;AN000; | ||
| 477 | |||
| 478 | inc bx ;AN000; now bx points to 1st CONTROL | ||
| 479 | |||
| 480 | $P_Key_Mgr_Loop: ;AN000; | ||
| 481 | push bx ;AN000; | ||
| 482 | mov bx,es:[bx] ;AN000; bx points to keyword CONTROL itself | ||
| 483 | call $P_Chk_Key_Control ;AN000; do process for keyword | ||
| 484 | pop bx ;AN000; | ||
| 485 | jnc $P_Return_to_Caller ;AN000; if the CONTROL is for the keyword, exit | ||
| 486 | |||
| 487 | inc bx ;AC035; add '2' to | ||
| 488 | inc bx ;AC035; BX reg | ||
| 489 | ;AN000; else bx points to the next CONTROL | ||
| 490 | ;(changed ;AC035;) add bx,2 ;AN000; else bx points to the next CONTROL | ||
| 491 | loop $P_Key_Mgr_Loop ;AN000; and loop | ||
| 492 | |||
| 493 | $P_Key_Not_Found: ;AN000; | ||
| 494 | mov psdata_seg:$P_RC,$P_Not_In_Key ;AC034; here no CONTROL for the keyword has | ||
| 495 | $P_Return_to_Caller0: ;AN000; not been found, means error. | ||
| 496 | |||
| 497 | ;(deleted ;AN024;) mov bx,es:[bx-2] ;AN000; (tm13) backup bx | ||
| 498 | |||
| 499 | ;(deleted ;AN024;) mov al,$P_String ;AN000; Set | ||
| 500 | ;(deleted ;AN024;) mov ah,$P_No_Tag ;AN000; result | ||
| 501 | ;(deleted ;AN024;) call $P_Fill_Result ;AN000; buffer | ||
| 502 | |||
| 503 | $P_Return_to_Caller: ;AN000; | ||
| 504 | pop bp ;AN000; | ||
| 505 | pop di ;AN000; | ||
| 506 | pop bx ;AN000; | ||
| 507 | mov cx,psdata_seg:$P_Ordinal ;AC034; return next ordinal | ||
| 508 | mov ax,psdata_seg:$P_RC ;AC034; return exit code | ||
| 509 | mov si,psdata_seg:$P_SI_Save ;AC034; return next operand pointer | ||
| 510 | mov dx,psdata_seg:$P_DX ;AC034; return result buffer address | ||
| 511 | mov bl,psdata_seg:$P_Terminator ;AC034; return delimiter code found | ||
| 512 | $P_Single_Exit: ;AN000; | ||
| 513 | clc ;AN000; | ||
| 514 | ret ;AN000; | ||
| 515 | SysParse endp ;AN000; | ||
| 516 | PAGE ;AN000; | ||
| 517 | ;*********************************************************************** | ||
| 518 | ; $P_Chk_Pos_Control | ||
| 519 | ; | ||
| 520 | ; Function: Parse CONTROL block for a positional | ||
| 521 | ; | ||
| 522 | ; Input: ES:BX -> CONTROL block | ||
| 523 | ; psdata_seg:SI -> $P_STRING_BUF | ||
| 524 | ; | ||
| 525 | ; Output: None | ||
| 526 | ; | ||
| 527 | ; Use: $P_Fill_Result, $P_Check_Match_Flags | ||
| 528 | ; | ||
| 529 | ; Vars: $P_Ordinal(W), $P_RC(W) | ||
| 530 | ;*********************************************************************** | ||
| 531 | $P_Chk_Pos_Control proc ;AN000; | ||
| 532 | push ax ;AN000; | ||
| 533 | mov ax,es:[bx].$P_Match_Flag ;AN000; | ||
| 534 | test ax,$P_Repeat ;AN000; repeat allowed ? | ||
| 535 | jne $P_CPC00 ;AN000; then do not increment ORDINAL | ||
| 536 | |||
| 537 | inc psdata_seg:$P_ORDINAL ;AC034; update the ordinal | ||
| 538 | $P_CPC00: ;AN000; | ||
| 539 | cmp byte ptr psdata_seg:[si],$P_NULL ;AN000; no data ? | ||
| 540 | jne $P_CPC01 ;AN000; | ||
| 541 | |||
| 542 | test ax,$P_Optional ;AN000; yes, then is it optional ? | ||
| 543 | jne $P_CPC02 ;AN000; | ||
| 544 | |||
| 545 | mov psdata_seg:$P_RC,$P_Op_Missing ;AC034; no, then error 3/17/87 | ||
| 546 | jmp short $P_CPC_Exit ;AN000; | ||
| 547 | |||
| 548 | $P_CPC02: ;AN000; | ||
| 549 | push ax ;AN000; | ||
| 550 | mov al,$P_String ;AN000; if it is optional return NULL | ||
| 551 | mov ah,$P_No_Tag ;AN000; no item tag indication | ||
| 552 | call $P_Fill_Result ;AN000; | ||
| 553 | pop ax ;AN000; | ||
| 554 | jmp short $P_CPC_Exit ;AN000; | ||
| 555 | |||
| 556 | $P_CPC01: ;AN000; | ||
| 557 | call $P_Check_Match_Flags ;AN000; | ||
| 558 | $P_CPC_Exit: ;AN000; | ||
| 559 | pop ax ;AN000; | ||
| 560 | ret ;AN000; | ||
| 561 | $P_Chk_Pos_Control endp ;AN000; | ||
| 562 | PAGE ;AN000; | ||
| 563 | ;*********************************************************************** | ||
| 564 | ; $P_Chk_Key_Control | ||
| 565 | ; | ||
| 566 | ; Function: Parse CONTROL block for a keyword | ||
| 567 | ; | ||
| 568 | ; Input: ES:BX -> CONTROL block | ||
| 569 | ; psdata_seg:SI -> $P_STRING_BUF | ||
| 570 | ; | ||
| 571 | ; Output: CY = 1 : not match | ||
| 572 | ; | ||
| 573 | ; Use: $P_Fill_Result, $P_Search_KEYorSW, $P_Check_Match_Flags | ||
| 574 | ; | ||
| 575 | ; Vars: $P_RC(W), $P_SaveSI_Cmpx(W), $P_KEYorSW_Ptr(R), $P_Flags(W) | ||
| 576 | ;*********************************************************************** | ||
| 577 | $P_Chk_Key_Control proc ;AN000; | ||
| 578 | IF KeySW ;AN000;(Check if keyword is supported) | ||
| 579 | or psdata_seg:$P_Flags2,$P_Key_Cmp ;AC034; Indicate keyword for later string comparison | ||
| 580 | call $P_Search_KEYorSW ;AN000; Search the keyword in the CONTROL block | ||
| 581 | jc $P_Chk_Key_Err0 ;AN000; not found, then try next CONTROL | ||
| 582 | |||
| 583 | and psdata_seg:$P_Flags2,0ffh-$P_Key_Cmp ;AC034; reset the indicator previously set | ||
| 584 | ; | ||
| 585 | push ax ;AN000; keyword= | ||
| 586 | mov ax,psdata_seg:$P_KEYorSW_Ptr ;AC034; ^ ^ | ||
| 587 | sub ax,si ;AN000; SI KEYorSW | ||
| 588 | add psdata_seg:$P_SaveSI_Cmpx,ax ;AC034; update for complex, quoted or file spec. | ||
| 589 | pop ax ;AN000; | ||
| 590 | ; | ||
| 591 | mov si,psdata_seg:$P_KEYorSW_Ptr ;AC034; set si just after equal char | ||
| 592 | cmp byte ptr psdata_seg:[si],$P_NULL ;AN000; any data after equal ? | ||
| 593 | je $P_Chk_Key_Err1 ;AN000; if no, syntax error | ||
| 594 | |||
| 595 | call $P_Check_Match_Flags ;AN000; else, process match flags | ||
| 596 | clc ;AN000; | ||
| 597 | jmp short $P_Chk_Key_Exit ;AN000; | ||
| 598 | |||
| 599 | $P_Chk_Key_Err0: ;AN000; | ||
| 600 | stc ;AN000; not found in keyword synonym list | ||
| 601 | jmp short $P_Chk_Key_Exit ;AN000; | ||
| 602 | |||
| 603 | $P_Chk_Key_Err1: ;AN000; | ||
| 604 | mov psdata_seg:$P_RC,$P_Syntax ;AC034; no parameter is not specified after "=" | ||
| 605 | $P_Chk_Key_ErrExit: ;AN000; | ||
| 606 | push ax ;AN000; | ||
| 607 | mov al,$P_String ;AN000; set | ||
| 608 | mov ah,$P_No_Tag ;AN000; result | ||
| 609 | call $P_Fill_Result ;AN000; buffer | ||
| 610 | pop ax ;AN000; | ||
| 611 | clc ;AN000; | ||
| 612 | $P_Chk_Key_Exit: ;AN000; | ||
| 613 | ret ;AN000; | ||
| 614 | ELSE ;AN000;(of IF KeySW) | ||
| 615 | stc ;AN000;this logic works when the KeySW | ||
| 616 | ret ;AN000;is reset. | ||
| 617 | ENDIF ;AN000;(of KeySW) | ||
| 618 | $P_Chk_Key_Control endp ;AN000; | ||
| 619 | PAGE ;AN000; | ||
| 620 | ;*********************************************************************** | ||
| 621 | IF KeySW+SwSW ;AN000;(Check if keyword or switch is supported) | ||
| 622 | ; $P_Search_KEYorSW: | ||
| 623 | ; | ||
| 624 | ; Function: Seach specified keyword or switch from CONTROL | ||
| 625 | ; | ||
| 626 | ; Input: ES:BX -> CONTROL block | ||
| 627 | ; psdata_seg:SI -> $P_STRING_BUF | ||
| 628 | ; | ||
| 629 | ; Output: CY = 1 : not match | ||
| 630 | ; | ||
| 631 | ; Use: $P_String_Comp, $P_MoveBP_NUL, $P_Found_SYNONYM | ||
| 632 | ;*********************************************************************** | ||
| 633 | $P_Search_KEYorSW proc ;AN000; | ||
| 634 | push bp ;AN000; | ||
| 635 | push cx ;AN000; | ||
| 636 | mov cl,es:[bx].$P_nid ;AN000; Get synonym count | ||
| 637 | xor ch,ch ;AN000; and set it to cx | ||
| 638 | or cx,cx ;AN000; No synonyms specified ? | ||
| 639 | je $P_KEYorSW_Not_Found ;AN000; then indicate not found by CY | ||
| 640 | |||
| 641 | lea bp,es:[bx].$P_KEYorSW ;AN000; BP points to the 1st synonym | ||
| 642 | $P_KEYorSW_Loop: ;AN000; | ||
| 643 | call $P_String_Comp ;AN000; compare string in buffer w/ the synonym | ||
| 644 | jnc $P_KEYorSW_Found ;AN000; If match, set it to synonym pointer | ||
| 645 | |||
| 646 | call $P_MoveBP_NUL ;AN000; else, bp points to the next string | ||
| 647 | loop $P_KEYorSW_Loop ;AN000; loop nid times | ||
| 648 | $P_KEYorSW_Not_Found: ;AN000; | ||
| 649 | stc ;AN000; indicate not found in synonym list | ||
| 650 | jmp short $P_KEYorSW_Exit ;AN000; and exit | ||
| 651 | |||
| 652 | $P_KEYorSW_Found: ;AN000; | ||
| 653 | mov psdata_seg:$P_Found_SYNONYM,bp ;AC034; set synonym pointer | ||
| 654 | clc ;AN000; indicate found | ||
| 655 | $P_KEYorSW_Exit: ;AN000; | ||
| 656 | pop cx ;AN000; | ||
| 657 | pop bp ;AN000; | ||
| 658 | ret ;AN000; | ||
| 659 | $P_Search_KEYorSW endp ;AN000; | ||
| 660 | ;*********************************************************************** | ||
| 661 | ; $P_MoveBP_NUL | ||
| 662 | ;*********************************************************************** | ||
| 663 | $P_MoveBP_NUL proc ;AN000; | ||
| 664 | $P_MBP_Loop: ;AN000; | ||
| 665 | cmp byte ptr es:[bp],$P_NULL ;AN000; Increment BP that points | ||
| 666 | je $P_MBP_Exit ;AN000; to the synomym list | ||
| 667 | |||
| 668 | inc bp ;AN000; until | ||
| 669 | jmp short $P_MBP_Loop ;AN000; NULL encountered. | ||
| 670 | |||
| 671 | $P_MBP_Exit: ;AN000; | ||
| 672 | inc bp ;AN000; bp points to next to NULL | ||
| 673 | ret ;AN000; | ||
| 674 | $P_MoveBP_NUL endp ;AN000; | ||
| 675 | ENDIF ;AN000;(of KeySW+SwSW) | ||
| 676 | PAGE ;AN000; | ||
| 677 | ;*********************************************************************** | ||
| 678 | ; $P_Chk_SW_Control | ||
| 679 | ; | ||
| 680 | ; Function: Parse CONTROL block for a switch | ||
| 681 | ; | ||
| 682 | ; Input: ES:BX -> CONTROL block | ||
| 683 | ; psdata_seg:SI -> $P_STRING_BUF | ||
| 684 | ; | ||
| 685 | ; Output: CY = 1 : not match | ||
| 686 | ; | ||
| 687 | ; Use: $P_Fill_Result, $P_Search_KEYorSW, $P_Check_Match_Flags | ||
| 688 | ; | ||
| 689 | ; Vars: $P_SaveSI_Cmpx(W), $P_KEYorSW_Ptr(R), $P_Flags(W) | ||
| 690 | ;*********************************************************************** | ||
| 691 | $P_Chk_SW_Control proc ;AN000; | ||
| 692 | |||
| 693 | |||
| 694 | IF SwSW ;AN000;(Check if switch is supported) | ||
| 695 | or psdata_seg:$P_Flags2,$P_Sw_Cmp ;AC034; Indicate switch for later string comparison | ||
| 696 | call $P_Search_KEYorSW ;AN000; Search the switch in the CONTROL block | ||
| 697 | jc $P_Chk_SW_Err0 ;AN000; not found, then try next CONTROL | ||
| 698 | |||
| 699 | and psdata_seg:$P_Flags2,0ffh-$P_Sw_Cmp ;AC034; reset the indicator previously set | ||
| 700 | ; | ||
| 701 | push ax ;AN000; /switch: | ||
| 702 | mov ax,psdata_seg:$P_KEYorSW_Ptr ;AC034; ^ ^ | ||
| 703 | sub ax,si ;AN000; SI KEYorSW | ||
| 704 | add psdata_seg:$P_SaveSI_Cmpx,ax ;AC034; update for complex list | ||
| 705 | pop ax ;AN000; | ||
| 706 | ; | ||
| 707 | mov si,psdata_seg:$P_KEYorSW_Ptr ;AC034; set si at the end or colon | ||
| 708 | cmp byte ptr psdata_seg:[si],$P_NULL ;AN000; any data after colon | ||
| 709 | jne $P_CSW00 ;AN000; if yes, process match flags | ||
| 710 | |||
| 711 | cmp byte ptr psdata_seg:[si-1],$P_Colon ;AN000; if no, the switch terminated by colon ? | ||
| 712 | jne $P_Chk_if_data_required ;AN000; if yes, | ||
| 713 | |||
| 714 | mov psdata_seg:$P_RC,$P_Syntax ;AC034; return syntax error | ||
| 715 | jmp short $P_Chk_SW_Exit ;AN000; | ||
| 716 | |||
| 717 | $P_Chk_if_data_required: ;AN018; no data, no colon | ||
| 718 | cmp es:[bx].$P_Match_Flag,0 ;AN018; should have data? zero match flag means switch followed by nothing is OK | ||
| 719 | je $P_Chk_SW_Exit ;AN018; match flags not zero so should have something if optional bit is not on | ||
| 720 | |||
| 721 | test es:[bx].$P_Match_Flag,$P_Optional ;AN019; see if no value is valid | ||
| 722 | jnz $P_Chk_SW_Exit ;AN019; if so, then leave, else yell | ||
| 723 | |||
| 724 | mov psdata_seg:$P_RC,$P_Op_Missing ;AC034; return required operand missing | ||
| 725 | jmp short $P_Chk_SW_Exit ;AN018; | ||
| 726 | |||
| 727 | $P_CSW00: ;AN000; | ||
| 728 | call $P_Check_Match_Flags ;AN000; process match flag | ||
| 729 | clc ;AN000; indicate match | ||
| 730 | jmp short $P_Chk_SW_Single_Exit ;AN000; | ||
| 731 | |||
| 732 | $P_Chk_SW_Err0: ;AN000; | ||
| 733 | stc ;AN000; not found in switch synonym list | ||
| 734 | jmp short $P_Chk_SW_Single_Exit ;AN000; | ||
| 735 | |||
| 736 | $P_Chk_SW_Exit: ;AN000; | ||
| 737 | push ax ;AN000; | ||
| 738 | mov al,$P_String ;AN000; set | ||
| 739 | mov ah,$P_No_Tag ;AN000; result | ||
| 740 | call $P_Fill_Result ;AN000; buffer | ||
| 741 | pop ax ;AN000; | ||
| 742 | clc ;AN000; | ||
| 743 | $P_Chk_SW_Single_Exit: ;AN000; | ||
| 744 | ret ;AN000; | ||
| 745 | ELSE ;AN000;(of IF SwSW) | ||
| 746 | stc ;AN000; this logic works when the SwSW | ||
| 747 | ret ;AN000; is reset. | ||
| 748 | ENDIF ;AN000;(of SwSW) | ||
| 749 | $P_Chk_SW_Control endp ;AN000; | ||
| 750 | PAGE ;AN000; | ||
| 751 | ;*********************************************************************** | ||
| 752 | ; $P_Fill_Result | ||
| 753 | ; | ||
| 754 | ; Function: Fill the result buffer | ||
| 755 | ; | ||
| 756 | ; Input: AH = Item tag | ||
| 757 | ; AL = type | ||
| 758 | ; AL = 1: CX,DX has 32bit number (CX = high) | ||
| 759 | ; AL = 2: DX has index(offset) into value list | ||
| 760 | ; AL = 6: DL has driver # (1-A, 2-B, ... , 26 - Z) | ||
| 761 | ; AL = 7: DX has year, CL has month and CH has date | ||
| 762 | ; AL = 8: DL has hours, DH has minutes, CL has secondsn, | ||
| 763 | ; amd CH has hundredths | ||
| 764 | ; AL = else: psdata_seg:SI points to returned string buffer | ||
| 765 | ; ES:BX -> CONTROL block | ||
| 766 | ; | ||
| 767 | ; Output: None | ||
| 768 | ; | ||
| 769 | ; Use: $P_Do_CAPS_String, $P_Remove_Colon, $P_Found_SYNONYM | ||
| 770 | ; | ||
| 771 | ; Vars: $P_DX(W) | ||
| 772 | ;*********************************************************************** | ||
| 773 | $P_Fill_Result proc ;AN000; | ||
| 774 | push di ;AN000; | ||
| 775 | mov di,es:[bx].$P_Result_Buf ;AN000; di points to result buffer | ||
| 776 | mov psdata_seg:$P_DX,di ;AC034; set returned result address | ||
| 777 | mov es:[di].$P_Type,al ;AN000; store type | ||
| 778 | mov es:[di].$P_Item_Tag,ah ;AN000; store item tag | ||
| 779 | push ax ;AN000; | ||
| 780 | mov ax,psdata_seg:$P_Found_SYNONYM ;AC034; if yes, | ||
| 781 | mov es:[di].$P_SYNONYM_Ptr,ax ;AN000; then set it to the result | ||
| 782 | pop ax ;AN000; | ||
| 783 | $P_RLT04: ;AN000; | ||
| 784 | cmp al,$P_Number ;AN000; if number | ||
| 785 | jne $P_RLT00 ;AN000; | ||
| 786 | |||
| 787 | $P_RLT02: ;AN000; | ||
| 788 | mov word ptr es:[di].$P_Picked_Val,dx ;AN000; then store 32bit | ||
| 789 | mov word ptr es:[di+2].$P_Picked_Val,cx ;AN000; number | ||
| 790 | jmp short $P_RLT_Exit ;AN000; | ||
| 791 | |||
| 792 | $P_RLT00: ;AN000; | ||
| 793 | cmp al,$P_List_Idx ;AN000; if list index | ||
| 794 | jne $P_RLT01 ;AN000; | ||
| 795 | |||
| 796 | mov word ptr es:[di].$P_Picked_Val,dx ;AN000; then store list index | ||
| 797 | jmp short $P_RLT_Exit ;AN000; | ||
| 798 | |||
| 799 | $P_RLT01: ;AN000; | ||
| 800 | cmp al,$P_Date_F ;AN000; Date format ? | ||
| 801 | je $P_RLT02 ;AN000; | ||
| 802 | |||
| 803 | cmp al,$P_Time_F ;AN000; Time format ? | ||
| 804 | je $P_RLT02 ;AN000; | ||
| 805 | ; | ||
| 806 | cmp al,$P_Drive ;AN000; drive format ? | ||
| 807 | jne $P_RLT03 ;AN000; | ||
| 808 | |||
| 809 | mov byte ptr es:[di].$P_Picked_Val,dl ;AN000; store drive number | ||
| 810 | jmp short $P_RLT_Exit ;AN000; | ||
| 811 | |||
| 812 | $P_RLT03: ;AN000; | ||
| 813 | cmp al,$P_Complex ;AN000; complex format ? | ||
| 814 | jne $P_RLT05 ;AN000; | ||
| 815 | |||
| 816 | mov ax,psdata_seg:$P_SaveSI_Cmpx ;AC034; then get pointer in command buffer | ||
| 817 | inc ax ;AN000; skip left Parentheses | ||
| 818 | mov word ptr es:[di].$P_Picked_Val,ax ;AN000; store offset | ||
| 819 | mov word ptr es:[di+2].$P_Picked_Val,ds ;AN000; store segment | ||
| 820 | jmp short $P_RLT_Exit ;AN000; | ||
| 821 | |||
| 822 | $P_RLT05: ;AN000; | ||
| 823 | ;------------------------ AL = 3, 5, or 9 | ||
| 824 | mov word ptr es:[di].$P_Picked_Val,si ;AN000; store offset of STRING_BUF | ||
| 825 | ;(replaced ;AN031;) mov word ptr es:[di+word].$P_Picked_Val,cs ;AN000; store segment of STRING_BUF | ||
| 826 | mov word ptr es:[di+2].$P_Picked_Val,Psdata_Seg ;AN031; store segment of STRING_BUF | ||
| 827 | ; | ||
| 828 | push ax ;AN000; | ||
| 829 | test byte ptr es:[bx].$P_Function_Flag,$P_CAP_File ;AN000; need CAPS by file table? | ||
| 830 | je $P_RLT_CAP00 ;AN000; | ||
| 831 | |||
| 832 | mov al,$P_DOSTBL_File ;AN000; use file upper case table | ||
| 833 | jmp short $P_RLT_CAP02 ;AN000; | ||
| 834 | |||
| 835 | $P_RLT_CAP00: ;AN000; | ||
| 836 | test byte ptr es:[bx].$P_Function_Flag,$P_CAP_Char ;AN000; need CAPS by char table ? | ||
| 837 | je $P_RLT_CAP01 ;AN000; | ||
| 838 | |||
| 839 | mov al,$P_DOSTBL_Char ;AN000; use character upper case table | ||
| 840 | $P_RLT_CAP02: ;AN000; | ||
| 841 | call $P_Do_CAPS_String ;AN000; process CAPS along the table | ||
| 842 | $P_RLT_CAP01: ;AN000; | ||
| 843 | pop ax ;AN000; | ||
| 844 | test byte ptr es:[bx].$P_Function_Flag,$P_Rm_Colon ;AN000; removing colon at end ? | ||
| 845 | je $P_RLT_Exit ;AN000; | ||
| 846 | |||
| 847 | call $P_Remove_Colon ;AN000; then process it. | ||
| 848 | $P_RLT_Exit: ;AN000; | ||
| 849 | pop di ;AN000; | ||
| 850 | ret ;AN000; | ||
| 851 | $P_Fill_Result endp ;AN000; | ||
| 852 | PAGE ;AN000; | ||
| 853 | ;*********************************************************************** | ||
| 854 | ; $P_Check_Match_Flags | ||
| 855 | ; | ||
| 856 | ; Function: Check the mutch_flags and make the exit code and set the | ||
| 857 | ; result buffer | ||
| 858 | ; | ||
| 859 | ; Check for types in this order: | ||
| 860 | ; Complex | ||
| 861 | ; Date | ||
| 862 | ; Time | ||
| 863 | ; Drive | ||
| 864 | ; Filespec | ||
| 865 | ; Quoted String | ||
| 866 | ; Simple String | ||
| 867 | ; | ||
| 868 | ; Input: psdata_seg:SI -> $P_STRING_BUF | ||
| 869 | ; ES:BX -> CONTROL block | ||
| 870 | ; | ||
| 871 | ; Output: None | ||
| 872 | ; | ||
| 873 | ; Use: $P_Value, P$_SValue, $P_Simple_String, $P_Date_Format | ||
| 874 | ; $P_Time_Format, $P_Complex_Format, $P_File_Foemat | ||
| 875 | ; $P_Drive_Format | ||
| 876 | ;*********************************************************************** | ||
| 877 | $P_Check_Match_Flags proc ;AN000; | ||
| 878 | mov psdata_seg:$P_err_flag,$P_NULL ;AN033;AC034;; clear filespec error flag. | ||
| 879 | push ax ;AN000; | ||
| 880 | mov ax,es:[bx].$P_Match_Flag ;AN000; load match flag(16bit) to ax | ||
| 881 | |||
| 882 | or ax,ax ;AC035; test ax for zero | ||
| 883 | ;(changed ;AC035;) cmp ax,0 ;AN000; (tm12) | ||
| 884 | jne $P_Mat ;AN000; (tm12) | ||
| 885 | |||
| 886 | push ax ;AN000; (tm12) | ||
| 887 | push bx ;AN000; (tm12) | ||
| 888 | push dx ;AN000; (tm12) | ||
| 889 | push di ;AN000; (tm12) | ||
| 890 | mov psdata_seg:$P_RC,$P_Syntax ;AC034; (tm12) | ||
| 891 | mov ah,$P_No_Tag ;AN000; (tm12) | ||
| 892 | mov al,$P_String ;AN000; (tm12) | ||
| 893 | call $P_Fill_Result ;AN000; (tm12) | ||
| 894 | pop di ;AN000; (tm12) | ||
| 895 | pop dx ;AN000; (tm12) | ||
| 896 | pop bx ;AN000; (tm12) | ||
| 897 | pop ax ;AN000; (tm12) | ||
| 898 | jmp short $P_Bridge ;AC035; (tm12) | ||
| 899 | |||
| 900 | $P_Mat: ;AN000; (tm12) | ||
| 901 | |||
| 902 | IF CmpxSW ;AN000;(Check if complex item is supported) | ||
| 903 | test ax,$P_Cmpx_S ;AN000; Complex string | ||
| 904 | je $P_Match01 ;AN000; | ||
| 905 | |||
| 906 | mov psdata_seg:$P_RC,$P_No_Error ;AC034; assume no error | ||
| 907 | call $P_Complex_Format ;AN000; do process | ||
| 908 | cmp psdata_seg:$P_RC,$P_Syntax ;AC034; if error, examine the next type | ||
| 909 | jne $P_Bridge ;AN000; | ||
| 910 | |||
| 911 | $P_Match01: ;AN000; | ||
| 912 | ENDIF ;AN000;(of CmpxSW) | ||
| 913 | IF DateSW ;AN000;(Check if date format is supported) | ||
| 914 | test ax,$P_Date_S ;AN000; Date string | ||
| 915 | je $P_Match02 ;AN000; | ||
| 916 | |||
| 917 | mov psdata_seg:$P_RC,$P_No_Error ;AC034; assume no error | ||
| 918 | call $P_Date_Format ;AN000; do process | ||
| 919 | cmp psdata_seg:$P_RC,$P_Syntax ;AC034; if error, examine the next type | ||
| 920 | jne $P_Bridge ;AN000; | ||
| 921 | |||
| 922 | $P_Match02: ;AN000; | ||
| 923 | ENDIF ;AN000;(of DateSW) | ||
| 924 | IF TimeSW ;AN000;(Check if time format is supported) | ||
| 925 | test ax,$P_Time_S ;AN000; Time string | ||
| 926 | je $P_Match03 ;AN000; | ||
| 927 | |||
| 928 | mov psdata_seg:$P_RC,$P_No_Error ;AC034; assume no error | ||
| 929 | call $P_Time_Format ;AN000; do process | ||
| 930 | cmp psdata_seg:$P_RC,$P_Syntax ;AC034; if error, examine the next type | ||
| 931 | ; je $P_Match03 ;AN000: | ||
| 932 | |||
| 933 | jne $P_Bridge ;AN000; (tm09) | ||
| 934 | |||
| 935 | ENDIF ;AN000;(of TimeSW) (tm04) | ||
| 936 | jmp short $P_Match03 ;AN025; (tm09) | ||
| 937 | |||
| 938 | $P_Bridge: ;AN000; | ||
| 939 | ; jmp short $P_Match_Exit (tm02) | ||
| 940 | |||
| 941 | jmp $P_Match_Exit ;AN000; (tm02) | ||
| 942 | |||
| 943 | $P_Match03: ;AN000; | ||
| 944 | ; ENDIF ;AN000;(of TimeSW) (tm04) | ||
| 945 | IF NumSW ;AN000;(Check if numeric value is supported) | ||
| 946 | test ax,$P_Num_Val ;AN000; Numeric value | ||
| 947 | je $P_Match04 ;AN000; | ||
| 948 | |||
| 949 | mov psdata_seg:$P_RC,$P_No_Error ;AC034; assume no error | ||
| 950 | call $P_Value ;AN000; do process | ||
| 951 | cmp psdata_seg:$P_RC,$P_Syntax ;AC034; if error, examine the next type | ||
| 952 | jne $P_Match_Exit ;AN000; | ||
| 953 | |||
| 954 | $P_Match04: ;AN000; | ||
| 955 | test ax,$P_SNUM_Val ;AN000; Signed numeric value | ||
| 956 | je $P_Match05 ;AN000; | ||
| 957 | |||
| 958 | mov psdata_seg:$P_RC,$P_No_Error ;AC034; assume no error | ||
| 959 | call $P_SValue ;AN000; do process | ||
| 960 | cmp psdata_seg:$P_RC,$P_Syntax ;AC034; if error, examine the next type | ||
| 961 | jne $P_Match_Exit ;AN000; | ||
| 962 | |||
| 963 | $P_Match05: ;AN000; | ||
| 964 | ENDIF ;AN000;(of NumSW) | ||
| 965 | IF DrvSW ;AN000;(Check if drive only is supported) | ||
| 966 | test ax,$P_Drv_Only ;AN000; Drive only | ||
| 967 | je $P_Match06 ;AN000; | ||
| 968 | |||
| 969 | mov psdata_seg:$P_RC,$P_No_Error ;AC034; assume no error | ||
| 970 | call $P_File_Format ;AN000; 1st, call file format | ||
| 971 | call $P_Drive_Format ;AN000; check drive format, next | ||
| 972 | cmp psdata_seg:$P_RC,$P_Syntax ;AC034; if error, examinee the next type | ||
| 973 | jne $P_Match_Exit ;AN000; | ||
| 974 | |||
| 975 | $P_Match06: ;AN000; | ||
| 976 | ENDIF ;AN000;(of DrvSW) | ||
| 977 | IF FileSW ;AN000;(Check if file spec is supported) | ||
| 978 | test ax,$P_File_Spc ;AN000; File spec | ||
| 979 | je $P_Match07 ;AN000; | ||
| 980 | |||
| 981 | mov psdata_seg:$P_RC,$P_No_Error ;AC034; assume no error | ||
| 982 | call $P_File_Format ;AN000; do process | ||
| 983 | cmp psdata_seg:$P_RC,$P_Syntax ;AC034; if error, examine the next type | ||
| 984 | jne $P_Match_Exit ;AN000; | ||
| 985 | |||
| 986 | $P_Match07: ;AN000; | ||
| 987 | ENDIF ;AN000;(of FileSW) | ||
| 988 | IF QusSW ;AN000;(Check if quoted string is supported) | ||
| 989 | test ax,$P_Qu_String ;AN000; Quoted string | ||
| 990 | je $P_Match08 ;AN000; | ||
| 991 | |||
| 992 | mov psdata_seg:$P_RC,$P_No_Error ;AC034; assume no error | ||
| 993 | call $P_Quoted_Format ;AN000; do process | ||
| 994 | cmp psdata_seg:$P_RC,$P_Syntax ;AC034; if error, examine the next type | ||
| 995 | jne $P_Match_Exit ;AN000; | ||
| 996 | |||
| 997 | $P_Match08: ;AN000; | ||
| 998 | ENDIF ;AN000;(of QusSW) | ||
| 999 | test ax,$P_Simple_S ;AN000; Simple string | ||
| 1000 | je $P_Match09 ;AN000; | ||
| 1001 | |||
| 1002 | mov psdata_seg:$P_RC,$P_No_Error ;AC034; assume no error | ||
| 1003 | call $P_Simple_String ;AN000; do process | ||
| 1004 | ;;;; cmp psdata_seg:$P_RC,$P_Syntax ;AC034; These two lines will be alive | ||
| 1005 | ;;;; jne $P_Match_Exit ;when extending the match_flags. | ||
| 1006 | $P_Match09: ;AN000; | ||
| 1007 | $P_Match_Exit: ;AN000; | ||
| 1008 | cmp psdata_seg:$P_err_flag,$P_error_filespec ;AC034; bad filespec ? | ||
| 1009 | jne $P_Match2_Exit ;AN033; no, continue | ||
| 1010 | cmp psdata_seg:$P_RC,$P_No_Error ;AN033;AC034;; check for other errors ? | ||
| 1011 | jne $P_Match2_Exit ;AN033; no, continue | ||
| 1012 | mov psdata_seg:$P_RC,$P_Syntax ;AN033;AC034;; set error flag | ||
| 1013 | $P_Match2_Exit: ;AN033; | ||
| 1014 | pop ax ;AN000; | ||
| 1015 | ret ;AN000; | ||
| 1016 | $P_Check_Match_Flags endp ;AN000; | ||
| 1017 | PAGE ;AN000; | ||
| 1018 | ;*********************************************************************** | ||
| 1019 | ; $P_Remove_Colon; | ||
| 1020 | ; | ||
| 1021 | ; Function: Remove colon at end | ||
| 1022 | ; | ||
| 1023 | ; Input: psdata_seg:SI points to string buffer to be examineed | ||
| 1024 | ; | ||
| 1025 | ; Output: None | ||
| 1026 | ; | ||
| 1027 | ; Use: $P_Chk_DBCS | ||
| 1028 | ;*********************************************************************** | ||
| 1029 | $P_Remove_Colon proc ;AN000; | ||
| 1030 | push ax ;AN000; | ||
| 1031 | push si ;AN000; | ||
| 1032 | $P_RCOL_Loop: ;AN000; | ||
| 1033 | mov al,psdata_seg:[si] ;AN000; get character | ||
| 1034 | or al,al ;AN000; end of string ? | ||
| 1035 | je $P_RCOL_Exit ;AN000; if yes, just exit | ||
| 1036 | |||
| 1037 | cmp al,$P_Colon ;AN000; is it colon ? | ||
| 1038 | jne $P_RCOL00 ;AN000; | ||
| 1039 | |||
| 1040 | cmp byte ptr psdata_seg:[si+byte],$P_NULL ;AN000; if so, next is NULL ? | ||
| 1041 | jne $P_RCOL00 ;AN000; no, then next char | ||
| 1042 | |||
| 1043 | mov byte ptr psdata_seg:[si],$P_NULL ;AN000; yes, remove colon | ||
| 1044 | jmp short $P_RCOL_Exit ;AN000; and exit. | ||
| 1045 | |||
| 1046 | $P_RCOL00: ;AN000; | ||
| 1047 | call $P_Chk_DBCS ;AN000; if not colon, then check if | ||
| 1048 | jnc $P_RCOL01 ;AN000; DBCS leading byte. | ||
| 1049 | |||
| 1050 | inc si ;AN000; if yes, skip trailing byte | ||
| 1051 | $P_RCOL01: ;AN000; | ||
| 1052 | inc si ;AN000; si points to next byte | ||
| 1053 | jmp short $P_RCOL_Loop ;AN000; loop until NULL encountered | ||
| 1054 | |||
| 1055 | $P_RCOL_Exit: ;AN000; | ||
| 1056 | pop si ;AN000; | ||
| 1057 | pop ax ;AN000; | ||
| 1058 | ret ;AN000; | ||
| 1059 | $P_Remove_Colon endp ;AN000; | ||
| 1060 | PAGE ;AN000; | ||
| 1061 | ;*********************************************************************** | ||
| 1062 | ; $P_Do_CAPS_String; | ||
| 1063 | ; | ||
| 1064 | ; Function: Perform capitalization along with the file case map table | ||
| 1065 | ; or character case map table. | ||
| 1066 | ; | ||
| 1067 | ; Input: AL = 2 : Use character table | ||
| 1068 | ; AL = 4 : Use file table | ||
| 1069 | ; psdata_seg:SI points to string buffer to be capitalized | ||
| 1070 | ; | ||
| 1071 | ; Output: None | ||
| 1072 | ; | ||
| 1073 | ; Use: $P_Do_CAPS_Char, $P_Chk_DBCS | ||
| 1074 | ;*********************************************************************** | ||
| 1075 | $P_Do_CAPS_String proc ;AN000; | ||
| 1076 | push si ;AN000; | ||
| 1077 | push dx ;AN000; | ||
| 1078 | mov dl,al ;AN000; save info id | ||
| 1079 | |||
| 1080 | $P_DCS_Loop: ;AN000; | ||
| 1081 | mov al,psdata_seg:[si] ;AN000; load charater and | ||
| 1082 | call $P_Chk_DBCS ;AN000; check if DBCS leading byte | ||
| 1083 | jc $P_DCS00 ;AN000; if yes, do not need CAPS | ||
| 1084 | |||
| 1085 | or al,al ;AN000; end of string ? | ||
| 1086 | je $P_DCS_Exit ;AN000; then exit. | ||
| 1087 | |||
| 1088 | call $P_Do_CAPS_Char ;AN000; Here a SBCS char need to be CAPS | ||
| 1089 | mov psdata_seg:[si],al ;AN000; stored upper case char to buffer | ||
| 1090 | jmp short $P_DCS01 ;AN000; process nexit | ||
| 1091 | $P_DCS00: ;AN000; | ||
| 1092 | inc si ;AN000; skip DBCS leading and trailing byte | ||
| 1093 | $P_DCS01: ;AN000; | ||
| 1094 | inc si ;AN000; si point to next byte | ||
| 1095 | jmp short $P_DCS_Loop ;AN000; loop until NULL encountered | ||
| 1096 | $P_DCS_Exit: ;AN000; | ||
| 1097 | pop dx ;AN000; | ||
| 1098 | pop si ;AN000; | ||
| 1099 | ret ;AN000; | ||
| 1100 | $P_Do_CAPS_String endp ;AN000; | ||
| 1101 | PAGE ;AN000; | ||
| 1102 | ;*********************************************************************** | ||
| 1103 | ; $P_Do_CAPS_Char; | ||
| 1104 | ; | ||
| 1105 | ; Function: Perform capitalization along with the file case map table | ||
| 1106 | ; or character case map table. | ||
| 1107 | ; | ||
| 1108 | ; Input: DL = 2 : Use character table | ||
| 1109 | ; DL = 4 : Use file table | ||
| 1110 | ; AL = character to be capitalized | ||
| 1111 | ; | ||
| 1112 | ; Output: None | ||
| 1113 | ; | ||
| 1114 | ; Use: INT 21h /w AH=65h | ||
| 1115 | ;*********************************************************************** | ||
| 1116 | $P_Do_CAPS_Char proc ;AN000; | ||
| 1117 | cmp al,$P_ASCII80 ;AN000; need upper case table ? | ||
| 1118 | jae $P_DCC_Go ;AN000; | ||
| 1119 | |||
| 1120 | cmp al,"a" ;AN000; if no, | ||
| 1121 | jb $P_CAPS_Ret ;AN000; check if "a" <= AL <= "z" | ||
| 1122 | |||
| 1123 | cmp al,"z" ;AN000; | ||
| 1124 | ja $P_CAPS_Ret ;AN000; if yes, make CAPS | ||
| 1125 | |||
| 1126 | and al,$P_Make_Upper ;AN000; else do nothing. | ||
| 1127 | jmp short $P_CAPS_Ret ;AN000; | ||
| 1128 | |||
| 1129 | $P_DCC_Go: ;AN000; | ||
| 1130 | push bx ;AN000; | ||
| 1131 | push es ;AN000; | ||
| 1132 | push di ;AN000; | ||
| 1133 | IF CAPSW ;AN000;(Check if uppercase conversion is supported) | ||
| 1134 | lea di,psdata_seg:$P_File_CAP_Ptr ;AC034; | ||
| 1135 | cmp dl,$P_DOSTBL_File ;AN000; Use file CAPS table ? | ||
| 1136 | je $P_DCC00 ;AN000; | ||
| 1137 | |||
| 1138 | ENDIF ;AN000;(of CAPSW) | ||
| 1139 | lea di,psdata_seg:$P_Char_CAP_Ptr ;AC034; or use char CAPS table ? | ||
| 1140 | $P_DCC00: ;AN000; | ||
| 1141 | cmp psdata_seg:[di],dl ;AN000; already got table address ? | ||
| 1142 | je $P_DCC01 ;AN000; if no, | ||
| 1143 | |||
| 1144 | ;In this next section, ES will be used to pass a 5 byte workarea to INT 21h, | ||
| 1145 | ; the GET COUNTYRY INFO call. This usage of ES is required by the function | ||
| 1146 | ; call, regardless of what base register is currently be defined as PSDATA_SEG. | ||
| 1147 | ;BASESW EQU 0 means that ES is the psdata_seg reg. | ||
| 1148 | |||
| 1149 | IFDEF BASESW ;AN037; If BASESW has been defined, and | ||
| 1150 | IFE BASESW ;AN037; If ES is psdata base | ||
| 1151 | push PSDATA_SEG ;AN037; save current base reg | ||
| 1152 | ENDIF ;AN037; | ||
| 1153 | ENDIF ;AN037; | ||
| 1154 | |||
| 1155 | push ax ;AN000; get CAPS table thru DOS call | ||
| 1156 | push cx ;AN000; | ||
| 1157 | push dx ;AN000; | ||
| 1158 | |||
| 1159 | |||
| 1160 | push PSDATA_SEG ;AC036; pass current base seg into | ||
| 1161 | ;(Note: this used to push CS. BUG... | ||
| 1162 | pop es ;AN000; ES reg, required for | ||
| 1163 | ;get extended country information | ||
| 1164 | mov ah,$P_DOS_Get_TBL ;AN000; get extended CDI | ||
| 1165 | mov al,dl ;AN000; upper case table | ||
| 1166 | mov bx,$P_DOSTBL_Def ;AN000; get active CON | ||
| 1167 | mov cx,$P_DOSTBL_BL ;AN000; buffer length | ||
| 1168 | mov dx,$P_DOSTBL_Def ;AN000; get for default code page | ||
| 1169 | ;DI already set to point to buffer | ||
| 1170 | int 21h ;AN000; es:di point to buffer that | ||
| 1171 | ;now has been filled in with info | ||
| 1172 | pop dx ;AN000; | ||
| 1173 | pop cx ;AN000; | ||
| 1174 | pop ax ;AN000; | ||
| 1175 | IFDEF BASESW ;AN037; If BASESW has been defined, and | ||
| 1176 | IFE BASESW ;AN037; If ES is psdata base | ||
| 1177 | pop PSDATA_SEG ;AN037; restore current base reg | ||
| 1178 | ENDIF ;AN037; | ||
| 1179 | ENDIF ;AN037; | ||
| 1180 | $P_DCC01: ;AN000; | ||
| 1181 | |||
| 1182 | ;In this next section, ES will be used as the base of the XLAT table, provided | ||
| 1183 | ; by the previous GET COUNTRY INFO DOS call. This usage of ES is made | ||
| 1184 | ; regardless of which base reg is currently the PSDATA_SEG reg. | ||
| 1185 | |||
| 1186 | IFDEF BASESW ;AN037; If BASESW has been defined, and | ||
| 1187 | IFE BASESW ;AN037; If ES is psdata base | ||
| 1188 | push PSDATA_SEG ;AN037; save current base reg | ||
| 1189 | ENDIF ;AN037; | ||
| 1190 | ENDIF ;AN037; | ||
| 1191 | mov bx,psdata_seg:[di+$P_DOS_TBL_Off] ;AN000; get offset of table | ||
| 1192 | mov es,psdata_seg:[di+$P_DOS_TBL_Seg] ;AN000; get segment of table | ||
| 1193 | inc bx ;AC035; add '2' to | ||
| 1194 | inc bx ;AC035; BX reg | ||
| 1195 | ;AN000; skip length field | ||
| 1196 | ;(changed ;AN035;) add bx,word ;AN000; skip length field | ||
| 1197 | sub al,$P_ASCII80 ;AN000; make char to index | ||
| 1198 | xlat es:[bx] ;AN000; perform case map | ||
| 1199 | |||
| 1200 | IFDEF BASESW ;AN037; If BASESW has been defined, and | ||
| 1201 | IFE BASESW ;AN037; If ES is psdata base | ||
| 1202 | pop PSDATA_SEG ;AN037; restore current base reg | ||
| 1203 | ENDIF ;AN037; | ||
| 1204 | ENDIF ;AN037; | ||
| 1205 | pop di ;AN000; | ||
| 1206 | pop es ;AN000; | ||
| 1207 | pop bx ;AN000; | ||
| 1208 | $P_CAPS_Ret: ;AN000; | ||
| 1209 | ret ;AN000; | ||
| 1210 | $P_Do_CAPS_Char endp ;AN000; | ||
| 1211 | PAGE ;AN000; | ||
| 1212 | ;*********************************************************************** | ||
| 1213 | IF NumSW ;AN000;(Check if numeric value is supported) | ||
| 1214 | ; $P_Value / $P_SValue | ||
| 1215 | ; | ||
| 1216 | ; Function: Make 32bit value from psdata_seg:SI and see value list | ||
| 1217 | ; and make result buffer. | ||
| 1218 | ; $P_SValue is an entry point for the signed value | ||
| 1219 | ; and this will simply call $P_Value after the handling | ||
| 1220 | ; of the sign character, "+" or "-" | ||
| 1221 | ; | ||
| 1222 | ; Input: psdata_seg:SI -> $P_STRING_BUF | ||
| 1223 | ; ES:BX -> CONTROL block | ||
| 1224 | ; | ||
| 1225 | ; Output: None | ||
| 1226 | ; | ||
| 1227 | ; Use: $P_Fill_Result, $P_Check_OVF | ||
| 1228 | ; | ||
| 1229 | ; Vars: $P_RC(W), $P_Flags(RW) | ||
| 1230 | ;*********************************************************************** | ||
| 1231 | $P_SValue proc ;AN000; when signed value here | ||
| 1232 | push ax ;AN000; | ||
| 1233 | or psdata_seg:$P_Flags2,$P_Signed ;AC034; indicate a signed numeric | ||
| 1234 | and psdata_seg:$P_Flags2,0ffh-$P_Neg ;AC034; assume positive value | ||
| 1235 | mov al,psdata_seg:[si] ;AN000; get sign | ||
| 1236 | cmp al,$P_Plus ;AN000; "+" ? | ||
| 1237 | je $P_SVal00 ;AN000; | ||
| 1238 | |||
| 1239 | cmp al,$P_Minus ;AN000; "-" ? | ||
| 1240 | jne $P_Sval01 ;AN000; else | ||
| 1241 | |||
| 1242 | or psdata_seg:$P_Flags2,$P_Neg ;AC034; set this is negative value | ||
| 1243 | $P_SVal00: ;AN000; | ||
| 1244 | inc si ;AN000; skip sign char | ||
| 1245 | $P_Sval01: ;AN000; | ||
| 1246 | call $P_Value ;AN000; and process value | ||
| 1247 | pop ax ;AN000; | ||
| 1248 | ret ;AN000; | ||
| 1249 | $P_SValue endp ;AN000; | ||
| 1250 | ;*********************************************************************** | ||
| 1251 | $P_Value proc ;AN000; | ||
| 1252 | push ax ;AN000; | ||
| 1253 | push cx ;AN000; | ||
| 1254 | push dx ;AN000; | ||
| 1255 | push si ;AN000; | ||
| 1256 | xor cx,cx ;AN000; cx = higher 16 bits | ||
| 1257 | xor dx,dx ;AN000; dx = lower 16 bits | ||
| 1258 | push bx ;AN000; save control pointer | ||
| 1259 | $P_Value_Loop: ;AN000; | ||
| 1260 | mov al,psdata_seg:[si] ;AN000; get character | ||
| 1261 | or al,al ;AN000; end of line ? | ||
| 1262 | je $P_Value00 ;AN000; | ||
| 1263 | |||
| 1264 | call $P_0099 ;AN000; make asc(0..9) to bin(0..9) | ||
| 1265 | jc $P_Value_Err0 ;AN000; | ||
| 1266 | |||
| 1267 | xor ah,ah ;AN000; | ||
| 1268 | mov bp,ax ;AN000; save binary number | ||
| 1269 | shl dx,1 ;AN000; to have 2*x | ||
| 1270 | rcl cx,1 ;AN000; shift left w/ carry | ||
| 1271 | call $P_Check_OVF ;AN000; Overflow occurred ? | ||
| 1272 | jc $P_Value_Err0 ;AN000; then error, exit | ||
| 1273 | |||
| 1274 | mov bx,dx ;AN000; save low(2*x) | ||
| 1275 | mov ax,cx ;AN000; save high(2*x) | ||
| 1276 | shl dx,1 ;AN000; to have 4*x | ||
| 1277 | rcl cx,1 ;AN000; shift left w/ carry | ||
| 1278 | call $P_Check_OVF ;AN000; Overflow occurred ? | ||
| 1279 | jc $P_Value_Err0 ;AN000; then error, exit | ||
| 1280 | |||
| 1281 | shl dx,1 ;AN000; to have 8*x | ||
| 1282 | rcl cx,1 ;AN000; shift left w/ carry | ||
| 1283 | call $P_Check_OVF ;AN000; Overflow occurred ? | ||
| 1284 | jc $P_Value_Err0 ;AN000; then error, exit | ||
| 1285 | |||
| 1286 | add dx,bx ;AN000; now have 10*x | ||
| 1287 | adc cx,ax ;AN000; 32bit ADD | ||
| 1288 | call $P_Check_OVF ;AN000; Overflow occurred ? | ||
| 1289 | jc $P_Value_Err0 ;AN000; then error, exit | ||
| 1290 | |||
| 1291 | add dx,bp ;AN000; Add the current one degree decimal | ||
| 1292 | adc cx,0 ;AN000; if carry, add 1 to high 16bit | ||
| 1293 | call $P_Check_OVF ;AN000; Overflow occurred ? | ||
| 1294 | jc $P_Value_Err0 ;AN000; then error, exit | ||
| 1295 | |||
| 1296 | inc si ;AN000; update pointer | ||
| 1297 | jmp short $P_Value_Loop ;AN000; loop until NULL encountered | ||
| 1298 | ; | ||
| 1299 | $P_Value_Err0: ;AN000; | ||
| 1300 | pop bx ;AN000; | ||
| 1301 | jmp $P_Value_Err ;AN000; Bridge | ||
| 1302 | ; | ||
| 1303 | $P_Value00: ;AN000; | ||
| 1304 | pop bx ;AN000; restore control pointer | ||
| 1305 | test psdata_seg:$P_Flags2,$P_Neg ;AC034; here cx,dx = 32bit value | ||
| 1306 | je $P_Value01 ;AN000; was it negative ? | ||
| 1307 | |||
| 1308 | not cx ;AN000; + | ||
| 1309 | not dx ;AN000; |- Make 2's complement | ||
| 1310 | add dx,1 ;AN000; | | ||
| 1311 | adc cx,0 ;AN000; + | ||
| 1312 | $P_Value01: ;AN000; / nval =0 | ||
| 1313 | mov si,es:[bx].$P_Value_List ;AN000; si points to value list | ||
| 1314 | mov al,es:[si] ;AN000; get nval | ||
| 1315 | cmp al,$P_nval_None ;AN000; no value list ? | ||
| 1316 | jne $P_Value02 ;AN000; | ||
| 1317 | |||
| 1318 | mov al,$P_Number ;AN000; Set type | ||
| 1319 | mov ah,$P_No_Tag ;AN000; No ITEM_TAG set | ||
| 1320 | jmp $P_Value_Exit ;AN000; | ||
| 1321 | |||
| 1322 | $P_Value02: ;AN000; / nval = 1 | ||
| 1323 | IF Val1SW ;AN000;(Check if value list id #1 is supported) | ||
| 1324 | ;(tm07) cmp al,$P_nval_Range ;AN000; have range list ? | ||
| 1325 | ;(tm07) jne $P_Value03 ;AN000; | ||
| 1326 | |||
| 1327 | inc si ;AN000; | ||
| 1328 | mov al,es:[si] ;AN000; al = number of range | ||
| 1329 | cmp al,$P_No_nrng ;AN000; (tm07) | ||
| 1330 | je $P_Value03 ;AN000; (tm07) | ||
| 1331 | |||
| 1332 | inc si ;AN000; si points to 1st item_tag | ||
| 1333 | $P_Val02_Loop: ;AN000; | ||
| 1334 | test psdata_seg:$P_Flags2,$P_Signed ;AC034; | ||
| 1335 | jne $P_Val02_Sign ;AN000; | ||
| 1336 | |||
| 1337 | cmp cx,es:[si+$P_Val_XH] ;AN000; comp cx with XH | ||
| 1338 | jb $P_Val02_Next ;AN000; | ||
| 1339 | |||
| 1340 | ja $P_Val_In ;AN000; | ||
| 1341 | |||
| 1342 | cmp dx,es:[si+$P_Val_XL] ;AN000; comp dx with XL | ||
| 1343 | jb $P_Val02_Next ;AN000; | ||
| 1344 | |||
| 1345 | $P_Val_In: ;AN000; | ||
| 1346 | ;;;;;; cmp cx,es:$P_Val_YH] ; comp cx with YH (tm01) | ||
| 1347 | cmp cx,es:[si+$P_Val_YH] ;AN000; comp cx with YH (tm01) | ||
| 1348 | ja $P_Val02_Next ;AN000; | ||
| 1349 | |||
| 1350 | jb $P_Val_Found ;AN000; | ||
| 1351 | |||
| 1352 | cmp dx,es:[si+$P_Val_YL] ;AN000; comp dx with YL | ||
| 1353 | ja $P_Val02_Next ;AN000; | ||
| 1354 | |||
| 1355 | jmp short $P_Val_Found ;AN000; | ||
| 1356 | |||
| 1357 | $P_Val02_Sign: ;AN000; | ||
| 1358 | cmp cx,es:[si+$P_Val_XH] ;AN000; comp cx with XH | ||
| 1359 | jl $P_Val02_Next ;AN000; | ||
| 1360 | |||
| 1361 | jg $P_SVal_In ;AN000; | ||
| 1362 | |||
| 1363 | cmp dx,es:[si+$P_Val_XL] ;AN000; comp dx with XL | ||
| 1364 | jl $P_Val02_Next ;AN000; | ||
| 1365 | |||
| 1366 | $P_SVal_In: ;AN000; | ||
| 1367 | cmp cx,es:[si+$P_Val_YH] ;AN000; comp cx with YH | ||
| 1368 | jg $P_Val02_Next ;AN000; | ||
| 1369 | |||
| 1370 | jl $P_Val_Found ;AN000; | ||
| 1371 | |||
| 1372 | cmp dx,es:[si+$P_Val_YL] ;AN000; comp dx with YL | ||
| 1373 | jg $P_Val02_Next ;AN000; | ||
| 1374 | |||
| 1375 | jmp short $P_Val_Found ;AN000; | ||
| 1376 | |||
| 1377 | $P_Val02_Next: ;AN000; | ||
| 1378 | add si,$P_Len_Range ;AN000; | ||
| 1379 | dec al ;AN000; loop nrng times in AL | ||
| 1380 | jne $P_Val02_Loop ;AN000; | ||
| 1381 | ; / Not found | ||
| 1382 | mov psdata_seg:$P_RC,$P_Out_of_Range ;AC034; | ||
| 1383 | mov al,$P_Number ;AN000; | ||
| 1384 | mov ah,$P_No_Tag ;AN000; No ITEM_TAG set | ||
| 1385 | jmp short $P_Value_Exit ;AN000; | ||
| 1386 | |||
| 1387 | ENDIF ;AN000;(of Val1SW) | ||
| 1388 | IF Val1SW+Val2SW ;AN000;(Check if value list id #1 or #2 is supported) | ||
| 1389 | $P_Val_Found: ;AN000; | ||
| 1390 | mov al,$P_Number ;AN000; | ||
| 1391 | mov ah,es:[si] ;AN000; found ITEM_TAG set | ||
| 1392 | jmp short $P_Value_Exit ;AN000; | ||
| 1393 | |||
| 1394 | ENDIF ;AN000;(of Val1SW+Val2SW) | ||
| 1395 | $P_Value03: ;AN000; / nval = 2 | ||
| 1396 | IF Val2SW ;AN000;(Check if value list id #2 is supported) | ||
| 1397 | ;;;; cmp al,$P_nval_Value ; have match list ? ASSUME nval=2, | ||
| 1398 | ;;;; jne $P_Value04 ; even if it is 3 or more. | ||
| 1399 | ;(tm07) inc si ;AN000; | ||
| 1400 | ;(tm07) mov al,es:[si] ;AN000; al = nrng | ||
| 1401 | mov ah,$P_Len_Range ;AN000; | ||
| 1402 | mul ah ;AN000; Skip nrng field | ||
| 1403 | inc ax ;AN000; | ||
| 1404 | add si,ax ;AN000; si points to nnval | ||
| 1405 | mov al,es:[si] ;AN000; get nnval | ||
| 1406 | inc si ;AN000; si points to 1st item_tag | ||
| 1407 | $P_Val03_Loop: ;AN000; | ||
| 1408 | cmp cx,es:[si+$P_Val_XH] ;AN000; comp cx with XH | ||
| 1409 | jne $P_Val03_Next ;AN000; | ||
| 1410 | |||
| 1411 | cmp dx,es:[si+$P_Val_XL] ;AN000; comp dx with XL | ||
| 1412 | je $P_Val_Found ;AN000; | ||
| 1413 | |||
| 1414 | $P_Val03_Next: ;AN000; | ||
| 1415 | add si,$P_Len_Value ;AN000; points to next value choice | ||
| 1416 | dec al ;AN000; loop nval times in AL | ||
| 1417 | jne $P_Val03_Loop ;AN000; | ||
| 1418 | ;AN000; / Not found | ||
| 1419 | mov psdata_seg:$P_RC,$P_Not_in_Val ;AC034; | ||
| 1420 | mov al,$P_Number ;AN000; | ||
| 1421 | mov ah,$P_No_Tag ;AN000; No ITEM_TAG set | ||
| 1422 | jmp short $P_Value_Exit ;AN000; | ||
| 1423 | |||
| 1424 | ENDIF ;AN000;(of Val2SW) | ||
| 1425 | $P_Value04: ;AN000; / nval = 3 or else | ||
| 1426 | $P_Value_Err: ;AN000; | ||
| 1427 | mov psdata_seg:$P_RC,$P_Syntax ;AC034; | ||
| 1428 | mov al,$P_String ;AN000; Set type | ||
| 1429 | mov ah,$P_No_Tag ;AN000; No ITEM_TAG set | ||
| 1430 | $P_Value_Exit: ;AN000; | ||
| 1431 | call $P_Fill_Result ;AN000; | ||
| 1432 | pop si ;AN000; | ||
| 1433 | pop dx ;AN000; | ||
| 1434 | pop cx ;AN000; | ||
| 1435 | pop ax ;AN000; | ||
| 1436 | ret ;AN000; | ||
| 1437 | $P_Value endp ;AN000; | ||
| 1438 | PAGE ;AN000; | ||
| 1439 | ;*********************************************************************** | ||
| 1440 | ; $P_Check_OVF | ||
| 1441 | ; | ||
| 1442 | ; Function: Check if overflow is occurred with consideration of | ||
| 1443 | ; signed or un-signed numeric value | ||
| 1444 | ; | ||
| 1445 | ; Input: Flag register | ||
| 1446 | ; | ||
| 1447 | ; Output: CY = 1 : Overflow | ||
| 1448 | ; | ||
| 1449 | ; Vars: $P_Flags(R) | ||
| 1450 | ;*********************************************************************** | ||
| 1451 | $P_Check_OVF proc ;AN000; | ||
| 1452 | pushf ;AN000; | ||
| 1453 | test psdata_seg:$P_Flags2,$P_Neg ;AC034; is it negative value ? | ||
| 1454 | jne $P_COVF ;AN000; if no, check overflow | ||
| 1455 | |||
| 1456 | popf ;AN000; by the CY bit | ||
| 1457 | ret ;AN000; | ||
| 1458 | |||
| 1459 | $P_COVF: ;AN000; | ||
| 1460 | popf ;AN000; else, | ||
| 1461 | jo $P_COVF00 ;AN000; check overflow by the OF | ||
| 1462 | |||
| 1463 | clc ;AN000; indicate it with CY bit | ||
| 1464 | ret ;AN000; CY=0 means no overflow | ||
| 1465 | |||
| 1466 | $P_COVF00: ;AN000; | ||
| 1467 | stc ;AN000; and CY=1 means overflow | ||
| 1468 | ret ;AN000; | ||
| 1469 | $P_Check_OVF endp ;AN000; | ||
| 1470 | ENDIF ;AN000;(of FarSW) | ||
| 1471 | ;*********************************************************************** | ||
| 1472 | ; $P_0099; | ||
| 1473 | ; | ||
| 1474 | ; Function: Make ASCII 0-9 to Binary 0-9 | ||
| 1475 | ; | ||
| 1476 | ; Input: AL = character code | ||
| 1477 | ; | ||
| 1478 | ; Output: CY = 1 : AL is not number | ||
| 1479 | ; CY = 0 : AL contains binary value | ||
| 1480 | ;*********************************************************************** | ||
| 1481 | $P_0099 proc ;AN000; | ||
| 1482 | cmp al,"0" ;AN000; | ||
| 1483 | jb $P_0099Err ;AN000; must be 0 =< al =< 9 | ||
| 1484 | |||
| 1485 | cmp al,"9" ;AN000; | ||
| 1486 | ja $P_0099Err ;AN000; must be 0 =< al =< 9 | ||
| 1487 | |||
| 1488 | sub al,"0" ;AN000; make char -> bin | ||
| 1489 | clc ;AN000; indicate no error | ||
| 1490 | ret ;AN000; | ||
| 1491 | |||
| 1492 | $P_0099Err: ;AN000; | ||
| 1493 | stc ;AN000; indicate error | ||
| 1494 | ret ;AN000; | ||
| 1495 | $P_0099 endp ;AN000; | ||
| 1496 | PAGE ;AN000; | ||
| 1497 | ;*********************************************************************** | ||
| 1498 | ; $P_Simple_String | ||
| 1499 | ; | ||
| 1500 | ; Function: See value list for the simple string | ||
| 1501 | ; and make result buffer. | ||
| 1502 | ; | ||
| 1503 | ; Input: psdata_seg:SI -> $P_STRING_BUF | ||
| 1504 | ; ES:BX -> CONTROL block | ||
| 1505 | ; | ||
| 1506 | ; Output: None | ||
| 1507 | ; | ||
| 1508 | ; Use: $P_Fill_Result, $P_String_Comp | ||
| 1509 | ; | ||
| 1510 | ; Vars: $P_RC(W) | ||
| 1511 | ;*********************************************************************** | ||
| 1512 | $P_Simple_String proc ;AN000; | ||
| 1513 | push ax ;AN000; | ||
| 1514 | push bx ;AN000; | ||
| 1515 | push dx ;AN000; | ||
| 1516 | push di ;AN000; | ||
| 1517 | mov di,es:[bx].$P_Value_List ;AN000; di points to value list | ||
| 1518 | mov al,es:[di] ;AN000; get nval | ||
| 1519 | or al,al ;AN000; no value list ? | ||
| 1520 | jne $P_Sim00 ;AN000; then | ||
| 1521 | |||
| 1522 | mov ah,$P_No_Tag ;AN000; No ITEM_TAG set | ||
| 1523 | jmp short $P_Sim_Exit ;AN000; and set result buffer | ||
| 1524 | |||
| 1525 | $P_Sim00: ;AN000; | ||
| 1526 | IF Val3SW+KeySW ;AN000;(Check if keyword or value list id #3 is supported) | ||
| 1527 | cmp al,$P_nval_String ;AN000; String choice list provided ? | ||
| 1528 | jne $P_Sim01 ;AN000; if no, syntax error | ||
| 1529 | |||
| 1530 | inc di ;AN000; | ||
| 1531 | mov al,es:[di] ;AN000; al = nrng | ||
| 1532 | mov ah,$P_Len_Range ;AN000; | ||
| 1533 | mul ah ;AN000; Skip nrng field | ||
| 1534 | inc ax ;AN000; ax = (nrng*9)+1 | ||
| 1535 | add di,ax ;AN000; di points to nnval | ||
| 1536 | mov al,es:[di] ;AN000; get nnval | ||
| 1537 | mov ah,$P_Len_Value ;AN000; | ||
| 1538 | mul ah ;AN000; Skip nnval field | ||
| 1539 | inc ax ;AN000; ax = (nnval*5)+1 | ||
| 1540 | add di,ax ;AN000; di points to nstrval | ||
| 1541 | mov al,es:[di] ;AN000; get nstrval | ||
| 1542 | inc di ;AC035; add '2' to | ||
| 1543 | inc di ;AC035; DI reg | ||
| 1544 | ;AN000; di points to 1st string in list | ||
| 1545 | ;(replaced ;AC035;) add di,2 ;AN000; di points to 1st string in list | ||
| 1546 | $P_Sim_Loop: ;AN000; | ||
| 1547 | mov bp,es:[di] ;AN000; get string pointer | ||
| 1548 | call $P_String_Comp ;AN000; compare it with operand | ||
| 1549 | jnc $P_Sim_Found ;AN000; found on list ? | ||
| 1550 | |||
| 1551 | add di,$P_Len_String ;AN000; if no, point to next choice | ||
| 1552 | dec al ;AN000; loop nstval times in AL | ||
| 1553 | jne $P_Sim_Loop ;AN000; | ||
| 1554 | ;AN000; / Not found | ||
| 1555 | mov psdata_seg:$P_RC,$P_Not_In_Str ;AC034; | ||
| 1556 | mov ah,$P_No_Tag ;AN000; No ITEM_TAG set | ||
| 1557 | jmp short $P_Sim_Exit ;AN000; | ||
| 1558 | |||
| 1559 | $P_Sim_Found: ;AN000; | ||
| 1560 | mov ah,es:[di-1] ;AN000; set item_tag | ||
| 1561 | mov al,$P_List_Idx ;AN000; | ||
| 1562 | mov dx,es:[di] ;AN000; get address of STRING | ||
| 1563 | jmp short $P_Sim_Exit0 ;AN000; | ||
| 1564 | ENDIF ;AN000;(of Val3SW+KeySW) | ||
| 1565 | $P_Sim01: ;AN000; | ||
| 1566 | mov psdata_seg:$P_RC,$P_Syntax ;AC034; | ||
| 1567 | mov ah,$P_No_Tag ;AN000; No ITEM_TAG set | ||
| 1568 | $P_Sim_Exit: ;AN000; | ||
| 1569 | mov al,$P_String ;AN000; Set type | ||
| 1570 | $P_Sim_Exit0: ;AN000; | ||
| 1571 | call $P_Fill_Result ;AN000; | ||
| 1572 | pop di ;AN000; | ||
| 1573 | pop dx ;AN000; | ||
| 1574 | pop bx ;AN000; | ||
| 1575 | pop ax ;AN000; | ||
| 1576 | ret ;AN000; | ||
| 1577 | $P_Simple_String endp ;AN000; | ||
| 1578 | PAGE ;AN000; | ||
| 1579 | ;*********************************************************************** | ||
| 1580 | ; $P_String_Comp: | ||
| 1581 | ; | ||
| 1582 | ; Function: Compare two string | ||
| 1583 | ; | ||
| 1584 | ; Input: psdata_seg:SI -> 1st string | ||
| 1585 | ; ES:BP -> 2nd string (Must be upper case) | ||
| 1586 | ; ES:BX -> CONTROL block | ||
| 1587 | ; | ||
| 1588 | ; Output: CY = 1 if not match | ||
| 1589 | ; | ||
| 1590 | ; Use: $P_Chk_DBCS, $P_Do_CAPS_Char | ||
| 1591 | ; | ||
| 1592 | ; Vars: $P_KEYor_SW_Ptr(W), $P_Flags(R). $P_KEYorSW_Ptr | ||
| 1593 | ;*********************************************************************** | ||
| 1594 | $P_String_Comp proc ;AN000; | ||
| 1595 | push ax ;AN000; | ||
| 1596 | push bp ;AN000; | ||
| 1597 | push dx ;AN000; | ||
| 1598 | push si ;AN000; | ||
| 1599 | mov dl,$P_DOSTBL_Char ;AN000; use character case map table | ||
| 1600 | $P_SCOM_Loop: ;AN000; | ||
| 1601 | mov al,psdata_seg:[si] ;AN000; get command character | ||
| 1602 | call $P_Chk_DBCS ;AN000; DBCS ? | ||
| 1603 | jc $P_SCOM00 ;AN000; yes,DBCS | ||
| 1604 | |||
| 1605 | call $P_Do_CAPS_Char ;AN000; else, upper case map before comparison | ||
| 1606 | IF KeySW+SwSW ;AN000;(Check if keyword or switch is supported) | ||
| 1607 | test psdata_seg:$P_Flags2,$P_Key_Cmp ;AC034; keyword search ? | ||
| 1608 | je $P_SCOM04 ;AN000; | ||
| 1609 | |||
| 1610 | cmp al,$P_Keyword ;AN000; "=" is delimiter | ||
| 1611 | jne $P_SCOM03 ;AN000;IF "=" on command line AND (bp+1=> char after the "=" in synonym list) | ||
| 1612 | |||
| 1613 | cmp byte ptr es:[bp+1],$P_NULL ;AN021; at end of keyword string in the control block THEN | ||
| 1614 | jne $P_SCOM_DIFFER ;AN021; | ||
| 1615 | |||
| 1616 | jmp short $P_SCOM05 ;AN000; keyword found in synonym list | ||
| 1617 | |||
| 1618 | $P_SCOM04: ;AN000; | ||
| 1619 | test psdata_seg:$P_Flags2,$P_SW_Cmp ;AC034; switch search ? | ||
| 1620 | je $P_SCOM03 ;AN000; | ||
| 1621 | |||
| 1622 | cmp al,$P_Colon ;AN000; ":" is delimiter, at end of switch on command line | ||
| 1623 | jne $P_SCOM03 ;AN000; continue compares | ||
| 1624 | |||
| 1625 | cmp byte ptr es:[bp],$P_NULL ;AN021; IF at end of switch on command AND | ||
| 1626 | jne $P_SCOM_DIFFER ;AN021; at end of switch string in the control block THEN | ||
| 1627 | |||
| 1628 | $P_SCOM05: ;AN000; found a match | ||
| 1629 | inc si ;AN000; si points to just after "=" or ":" | ||
| 1630 | jmp short $P_SCOM_Same ;AN000; exit | ||
| 1631 | |||
| 1632 | $P_SCOM03: ;AN000; | ||
| 1633 | ENDIF ;AN000;(of KeySW+SwSW) | ||
| 1634 | cmp al,es:[bp] ;AN000; compare operand w/ a synonym | ||
| 1635 | jne $P_SCOM_Differ0 ;AN000; if different, check ignore colon option | ||
| 1636 | |||
| 1637 | or al,al ;AN000; end of line | ||
| 1638 | je $P_SCOM_Same ;AN000; if so, exit | ||
| 1639 | |||
| 1640 | inc si ;AN000; update operand pointer | ||
| 1641 | inc bp ;AN000; and synonym pointer | ||
| 1642 | jmp short $P_SCOM01 ;AN000; loop until NULL or "=" or ":" found in case | ||
| 1643 | |||
| 1644 | $P_SCOM00: ;AN000; Here al is DBCS leading byte | ||
| 1645 | cmp al,es:[bp] ;AN000; compare leading byte | ||
| 1646 | jne $P_SCOM_Differ ;AN000; if not match, say different | ||
| 1647 | |||
| 1648 | inc si ;AN000; else, load next byte | ||
| 1649 | mov al,psdata_seg:[si] ;AN000; and | ||
| 1650 | inc bp ;AN000; | ||
| 1651 | cmp al,es:[bp] ;AN000; compare 2nd byte | ||
| 1652 | jne $P_SCOM_Differ ;AN000; if not match, say different, too | ||
| 1653 | |||
| 1654 | inc si ;AN000; else update operand pointer | ||
| 1655 | inc bp ;AN000; and synonym pointer | ||
| 1656 | $P_SCOM01: ;AN000; | ||
| 1657 | jmp short $P_SCOM_Loop ;AN000; loop until NULL or "=" or "/" found in case | ||
| 1658 | |||
| 1659 | $P_SCOM_Differ0: ;AN000; | ||
| 1660 | |||
| 1661 | IF SwSW ;AN000;(tm10) | ||
| 1662 | test psdata_seg:$P_Flags2,$P_SW ;AC034;(tm10) | ||
| 1663 | je $P_not_applicable ;AN000;(tm10) | ||
| 1664 | |||
| 1665 | test es:[bx].$P_Function_Flag,$P_colon_is_not_necessary ;AN000;(tm10) | ||
| 1666 | je $P_not_applicable ;AN000;(tm10) | ||
| 1667 | |||
| 1668 | cmp byte ptr es:[bp],$P_NULL ;AN000;(tm10) | ||
| 1669 | ;(deleted ;AN025;) jne $P_not_applicable ;AN000;(tm10) | ||
| 1670 | je $P_SCOM_Same ;AN025;(tm10) | ||
| 1671 | |||
| 1672 | $P_not_applicable: ;AN000;(tm10) | ||
| 1673 | ENDIF ;AN000;(tm10) | ||
| 1674 | |||
| 1675 | test es:[bx].$P_Match_Flag,$P_Ig_Colon ;AN000; ignore colon option specified ? | ||
| 1676 | je $P_SCOM_Differ ;AN000; if no, say different. | ||
| 1677 | |||
| 1678 | cmp al,$P_Colon ;AN000; End up with ":" and | ||
| 1679 | jne $P_SCOM02 ;AN000; subseqently | ||
| 1680 | |||
| 1681 | cmp byte ptr es:[bp],$P_NULL ;AN000; NULL ? | ||
| 1682 | jne $P_SCOM_Differ ;AN000; if no, say different | ||
| 1683 | |||
| 1684 | jmp short $p_SCOM_Same ;AN000; else, say same | ||
| 1685 | |||
| 1686 | $P_SCOM02: ;AN000; | ||
| 1687 | cmp al,$P_NULL ;AN000; end up NULL and : | ||
| 1688 | jne $P_SCOM_Differ ;AN000; | ||
| 1689 | |||
| 1690 | cmp byte ptr es:[bp],$P_Colon ;AN000; if no, say different | ||
| 1691 | je $p_SCOM_Same ;AN000; else, say same | ||
| 1692 | |||
| 1693 | $P_SCOM_Differ: ;AN000; | ||
| 1694 | stc ;AN000; indicate not found | ||
| 1695 | jmp short $P_SCOM_Exit ;AN000; | ||
| 1696 | |||
| 1697 | $P_SCOM_Same: ;AN000; | ||
| 1698 | mov psdata_seg:$P_KEYorSW_Ptr,si ;AC034; for later use by keyword or switch | ||
| 1699 | clc ;AN000; indicate found | ||
| 1700 | $P_SCOM_Exit: ;AN000; | ||
| 1701 | pop si ;AN000; | ||
| 1702 | pop dx ;AN000; | ||
| 1703 | pop bp ;AN000; | ||
| 1704 | pop ax ;AN000; | ||
| 1705 | ret ;AN000; | ||
| 1706 | $P_String_Comp endp ;AN000; | ||
| 1707 | PAGE ;AN000; | ||
| 1708 | ;*********************************************************************** | ||
| 1709 | IF DateSW ;AN000;(Check if date format is supported) | ||
| 1710 | ; $P_Date_Format | ||
| 1711 | ; | ||
| 1712 | ; Function: Convert a date string to DOS date format for int 21h | ||
| 1713 | ; with format validation. | ||
| 1714 | ; | ||
| 1715 | ; Input: psdata_seg:SI -> $P_STRING_BUF | ||
| 1716 | ; ES:BX -> CONTROL block | ||
| 1717 | ; | ||
| 1718 | ; Output: None | ||
| 1719 | ; | ||
| 1720 | ; Use: $P_Fill_Result, $P_Set_CDI, $P_Get_DecNum | ||
| 1721 | ; | ||
| 1722 | ; Vars: $P_RC(W), $P_1st_Val(RW), $P_2nd_Val(RW), $P_3rd_Val(RW) | ||
| 1723 | ;*********************************************************************** | ||
| 1724 | $P_Date_Format proc ;AN000; | ||
| 1725 | push ax ;AN000; | ||
| 1726 | push cx ;AN000; | ||
| 1727 | push dx ;AN000; | ||
| 1728 | push si ;AN000; | ||
| 1729 | push bx ;AN000; | ||
| 1730 | push si ;AN000; | ||
| 1731 | call $P_Set_CDI ;AN000; set country dependent information before process | ||
| 1732 | ; mov bl,psdata_seg:[si].$P_CDI_DateS ;load date separator ;AN020; (deleted) | ||
| 1733 | ; note: the country info is still needed | ||
| 1734 | ; to determine the order of the fields, | ||
| 1735 | ; but the separator char is no longer used. | ||
| 1736 | pop si ;AN000; | ||
| 1737 | mov psdata_seg:$P_1st_Val,0 ;AC034; set initial value | ||
| 1738 | mov psdata_seg:$P_2nd_Val,0 ;AC034; set initial value | ||
| 1739 | mov psdata_seg:$P_3rd_Val,0 ;AC034; set initial value | ||
| 1740 | call $P_Get_DecNum ;AN000; get 1st number | ||
| 1741 | jc $P_DateF_Err0 ;AN000;-----------------------+ | ||
| 1742 | |||
| 1743 | mov psdata_seg:$P_1st_Val,ax ;AC034; | | ||
| 1744 | or bl,bl ;AN000; end of line ? | | ||
| 1745 | je $P_DateF_YMD ;AN000; | | ||
| 1746 | |||
| 1747 | call $P_Get_DecNum ;AN000; get 2nd number | | ||
| 1748 | jc $P_DateF_Error ;AN000; | | ||
| 1749 | |||
| 1750 | mov psdata_seg:$P_2nd_Val,ax ;AC034; | | ||
| 1751 | or bl,bl ;AN000; end of line ? | | ||
| 1752 | je $P_DateF_YMD ;AN000; | | ||
| 1753 | |||
| 1754 | call $P_Get_DecNum ;AN000; get 3rd number | | ||
| 1755 | $P_DateF_Err0: ;AN000; Bridge <-----------+ | ||
| 1756 | jc $P_DateF_Error ;AN000; | ||
| 1757 | |||
| 1758 | mov psdata_seg:$P_3rd_Val,ax ;AC034; | ||
| 1759 | or bl,bl ;AN000; end of line ? | ||
| 1760 | jne $P_DateF_Error ;AN000; | ||
| 1761 | |||
| 1762 | $P_DateF_YMD: ;AN000; | ||
| 1763 | mov bx,psdata_seg:$P_Country_Info.$P_CDI_DateF ;AC034; get date format | ||
| 1764 | cmp bx,$P_Date_YMD ;AN000; | ||
| 1765 | je $P_DateF00 ;AN000; | ||
| 1766 | |||
| 1767 | mov ax,psdata_seg:$P_1st_Val ;AC034; | ||
| 1768 | or ah,ah ;AN000; | ||
| 1769 | jne $P_DateF_Error ;AN000; | ||
| 1770 | |||
| 1771 | mov cl,al ;AN000; set month | ||
| 1772 | mov ax,psdata_seg:$P_2nd_Val ;AC034; | ||
| 1773 | or ah,ah ;AN000; if overflow, error. | ||
| 1774 | jne $P_DateF_Error ;AN000; | ||
| 1775 | |||
| 1776 | mov ch,al ;AN000; set date | ||
| 1777 | mov dx,psdata_seg:$P_3rd_Val ;AC034; set year | ||
| 1778 | cmp bx,$P_Date_DMY ;AN000; from here format = MDY | ||
| 1779 | jne $P_DateF01 ;AN000; if it is DMY | ||
| 1780 | |||
| 1781 | xchg ch,cl ;AN000; then swap M <-> D | ||
| 1782 | $P_DateF01: ;AN000; | ||
| 1783 | jmp short $P_DateF02 ;AN000; | ||
| 1784 | |||
| 1785 | $P_DateF00: ;AN000; / here format = YMD | ||
| 1786 | mov dx,psdata_seg:$P_1st_Val ;AC034; set year | ||
| 1787 | mov ax,psdata_seg:$P_2nd_Val ;AC034; | ||
| 1788 | or ah,ah ;AN000; if overflow, error | ||
| 1789 | jne $P_DateF_Error ;AN000; | ||
| 1790 | |||
| 1791 | mov cl,al ;AN000; set month | ||
| 1792 | mov ax,psdata_seg:$P_3rd_Val ;AC034; | ||
| 1793 | or ah,ah ;AN000; if overflow, error | ||
| 1794 | jne $P_DateF_Error ;AN000; | ||
| 1795 | |||
| 1796 | mov ch,al ;AN000; set date | ||
| 1797 | $P_DateF02: ;AN000; | ||
| 1798 | cmp dx,100 ;AN000; year is less that 100 ? | ||
| 1799 | jae $P_DateF03 ;AN000; | ||
| 1800 | |||
| 1801 | add dx,1900 ;AN000; set year 19xx | ||
| 1802 | $P_DateF03: ;AN000; | ||
| 1803 | pop bx ;AN000; recover CONTROL block | ||
| 1804 | pop si ;AN000; recover string pointer | ||
| 1805 | mov ah,$P_No_Tag ;AN000; set | ||
| 1806 | mov al,$P_Date_F ;AN000; result | ||
| 1807 | call $P_Fill_Result ;AN000; buffer | ||
| 1808 | jmp short $P_Date_Format_Exit ;AN000; to Date | ||
| 1809 | |||
| 1810 | $P_DateF_Error: ;AN000; | ||
| 1811 | pop bx ;AN000; recover CONTROL block | ||
| 1812 | pop si ;AN000; recover string pointer | ||
| 1813 | mov ah,$P_No_Tag ;AN000; set | ||
| 1814 | mov al,$P_String ;AN000; result | ||
| 1815 | call $P_Fill_Result ;AN000; buffer to string | ||
| 1816 | mov psdata_seg:$P_RC,$P_Syntax ;AC034; indicate syntax error | ||
| 1817 | $P_Date_Format_Exit: ;AN000; | ||
| 1818 | pop dx ;AN000; | ||
| 1819 | pop cx ;AN000; | ||
| 1820 | pop ax ;AN000; | ||
| 1821 | ret ;AN000; | ||
| 1822 | $P_Date_Format endp ;AN000; | ||
| 1823 | ENDIF ;AN000;(of DateSW) | ||
| 1824 | PAGE ;AN000; | ||
| 1825 | ;*********************************************************************** | ||
| 1826 | IF TimeSW+DateSW ;AN000;(Check if time or date format is supported) | ||
| 1827 | ; $P_Set_CDI: | ||
| 1828 | ; | ||
| 1829 | ; Function: Read CDI from DOS if it has not been read yet | ||
| 1830 | ; | ||
| 1831 | ; Input: None | ||
| 1832 | ; | ||
| 1833 | ; Output: psdata_seg:SI -> CDI | ||
| 1834 | ; | ||
| 1835 | ; Use: INT 21h w/ AH = 38h | ||
| 1836 | ;*********************************************************************** | ||
| 1837 | $P_Set_CDI proc ;AN000; | ||
| 1838 | lea si,psdata_seg:$P_Country_Info ;AC034; | ||
| 1839 | cmp psdata_seg:[si].$P_CDI_DateF,$P_NeedToBeRead ;AN000; already read ? | ||
| 1840 | je $P_Read_CDI ;AN000; | ||
| 1841 | |||
| 1842 | jmp short $P_Set_CDI_Exit ;AN000; then do nothing | ||
| 1843 | |||
| 1844 | $P_Read_CDI: ;AN000; else read CDI thru DOS | ||
| 1845 | push ds ;AN000; | ||
| 1846 | push dx ;AN000; | ||
| 1847 | push ax ;AN000; | ||
| 1848 | push PSDATA_SEG ;AC023; | ||
| 1849 | pop ds ;AN000; set segment register | ||
| 1850 | mov ax,$P_DOS_Get_CDI ;AN000; get country information | ||
| 1851 | mov dx,si ;AN000; set offset of CDI in local data area | ||
| 1852 | int 21h ;AN000; | ||
| 1853 | pop ax ;AN000; | ||
| 1854 | pop dx ;AN000; | ||
| 1855 | pop ds ;AN000; | ||
| 1856 | $P_Set_CDI_Exit: ;AN000; | ||
| 1857 | ret ;AN000; | ||
| 1858 | $P_Set_CDI endp ;AN000; | ||
| 1859 | PAGE ;AN000; | ||
| 1860 | ;*********************************************************************** | ||
| 1861 | ; $P_Get_DecNum: | ||
| 1862 | ; | ||
| 1863 | ; Function: Read a chcrater code from psdata_seg:SI until specified delimiter | ||
| 1864 | ; or NULL encountered. And make a decimal number. | ||
| 1865 | ; | ||
| 1866 | ; Input: psdata_seg:SI -> $P_STRING_BUF | ||
| 1867 | ; | ||
| 1868 | ; Output: BL = delimiter code or NULL | ||
| 1869 | ; AX = Decimal number | ||
| 1870 | ; SI advanced to the next number | ||
| 1871 | ; CY = 1 : Syntax error, AL = Latest examineed number | ||
| 1872 | ; | ||
| 1873 | ; Use: $P_0099 | ||
| 1874 | ;*********************************************************************** | ||
| 1875 | $P_Get_DecNum proc ;AN000; | ||
| 1876 | push cx ;AN000; | ||
| 1877 | push dx ;AN000; | ||
| 1878 | xor cx,cx ;AN000; cx will have final value | ||
| 1879 | $P_GetNum_Loop: ;AN000; | ||
| 1880 | mov al,psdata_seg:[si] ;AN000; load character | ||
| 1881 | or al,al ;AN000; end of line ? | ||
| 1882 | je $P_GetNum00 ;AN000; if yes, exit | ||
| 1883 | |||
| 1884 | cmp psdata_seg:$P_Got_Time,0 ;AC034; ;is this numeric in a time field? ;AC023 | ||
| 1885 | je $P_Do_Date_Delims ;AN000;no, go check out Date delimiters ;AC023 | ||
| 1886 | |||
| 1887 | ; Determine which delimiter(s) to check for. Colon & period or period only | ||
| 1888 | cmp bl,$P_colon_period ;AN032; ;Time | ||
| 1889 | jne $P_Do_Time_Delim1 ;AN032; ;only check for period | ||
| 1890 | |||
| 1891 | cmp al,$P_Colon ;AN032; ;Is this a valid delimiter ? | ||
| 1892 | je $P_GetNum01 ;AN032; ;yes, exit | ||
| 1893 | |||
| 1894 | $P_Do_Time_Delim1: ;AN000; | ||
| 1895 | cmp al,$P_Period ;;AC032;;AC023;Is this a valid delimiter ? | ||
| 1896 | je $P_GetNum01 ;AC023; yes, exit | ||
| 1897 | |||
| 1898 | jmp short $P_Neither_Delims ;AN023; | ||
| 1899 | |||
| 1900 | $P_Do_Date_Delims: ;AN000; | ||
| 1901 | ;Regardless of the date delimiter character specified in the country | ||
| 1902 | ;dependent information, check for the presence of any one of these | ||
| 1903 | ;three field delimiters: "-", "/", or ".". | ||
| 1904 | cmp al,$P_Minus ;AN020;is this a date delimiter character? | ||
| 1905 | je $P_GetNum01 ;AN020;if yes, exit | ||
| 1906 | |||
| 1907 | cmp al,$P_Slash ;AN020;is this a date delimiter character? | ||
| 1908 | je $P_GetNum01 ;AN020;if yes, exit | ||
| 1909 | |||
| 1910 | cmp al,$P_Period ;AN020;is this a date delimiter character? | ||
| 1911 | je $P_GetNum01 ;AN000; if yes, exit | ||
| 1912 | |||
| 1913 | $P_Neither_Delims: ;AN023; | ||
| 1914 | |||
| 1915 | call $P_0099 ;AN000; convert it to binary | ||
| 1916 | jc $P_GetNum_Exit ;AN000; if error exit | ||
| 1917 | |||
| 1918 | mov ah,0 ;AN000; | ||
| 1919 | xchg ax,cx ;AN000; | ||
| 1920 | mov dx,10 ;AN000; | ||
| 1921 | mul dx ;AN000; ax = ax * 10 | ||
| 1922 | or dx,dx ;AN000; overflow | ||
| 1923 | jne $P_GetNum02 ;AN000; then exit | ||
| 1924 | |||
| 1925 | add ax,cx ;AN000; | ||
| 1926 | jc $P_GetNum_Exit ;AN000; | ||
| 1927 | |||
| 1928 | xchg ax,cx ;AN000; | ||
| 1929 | inc si ;AN000; | ||
| 1930 | jmp short $P_GetNum_Loop ;AN000; | ||
| 1931 | |||
| 1932 | $P_GetNum00: ;AN000; | ||
| 1933 | mov bl,al ;AN000; set bl to NULL | ||
| 1934 | clc ;AN000; indicate no error | ||
| 1935 | jmp short $P_GetNum_Exit ;AN000; | ||
| 1936 | |||
| 1937 | $P_GetNum01: ;AN000; | ||
| 1938 | inc si ;AN000; si points to next number | ||
| 1939 | clc ;AN000; indicate no error | ||
| 1940 | jmp short $P_GetNum_Exit ;AN000; | ||
| 1941 | |||
| 1942 | $P_GetNum02: ;AN000; | ||
| 1943 | stc ;AN000; indicate error | ||
| 1944 | $P_GetNum_Exit: ;AN000; | ||
| 1945 | mov ax,cx ;AN000;return value | ||
| 1946 | pop dx ;AN000; | ||
| 1947 | pop cx ;AN000; | ||
| 1948 | ret ;AN000; | ||
| 1949 | $P_Get_DecNum endp ;AN000; | ||
| 1950 | ENDIF ;AN000;(of TimeSW+DateSW) | ||
| 1951 | PAGE ;AN000; | ||
| 1952 | ;*********************************************************************** | ||
| 1953 | IF TimeSW ;AN000;(Check if time format is supported) | ||
| 1954 | ; $P_Time_Format | ||
| 1955 | ; | ||
| 1956 | ; Function: Convert a time string to DOS time format for int 21h | ||
| 1957 | ; with format validation. | ||
| 1958 | ; | ||
| 1959 | ; Input: psdata_seg:SI -> $P_STRING_BUF | ||
| 1960 | ; ES:BX -> CONTROL block | ||
| 1961 | ; | ||
| 1962 | ; Output: None | ||
| 1963 | ; | ||
| 1964 | ; Use: $P_Fill_Result, $P_Set_CDI, $P_Get_DecNum, $P_Time_2412 | ||
| 1965 | ; | ||
| 1966 | ; Vars: $P_RC(W), $P_Flags(R), $P_1st_Val(RW), $P_2nd_Val(RW) | ||
| 1967 | ; $P_3rd_Val(RW), $P_4th_Val(RW) | ||
| 1968 | ;*********************************************************************** | ||
| 1969 | $P_Time_Format proc ;AN000; | ||
| 1970 | push ax ;AN000; | ||
| 1971 | push cx ;AN000; | ||
| 1972 | push dx ;AN000; | ||
| 1973 | push si ;AN000; | ||
| 1974 | push bx ;AN000; | ||
| 1975 | push si ;AN000; | ||
| 1976 | call $P_Set_CDI ;AN000; Set country independent | ||
| 1977 | ; information before process | ||
| 1978 | ;(AN032; deleted) mov bl,psdata_seg:[si].$P_CDI_TimeS ;load time separator | ||
| 1979 | ;(AN032; deleted) mov bh,psdata_seg:[si].$P_CDI_Dec ;load decimal separator | ||
| 1980 | test byte ptr psdata_seg:[si].$P_CDI_TimeF,1 ;AN000; 24 hour system | ||
| 1981 | pop si ;AN000; | ||
| 1982 | jne $P_TimeF00 ;AN000; if no, means 12 hour system | ||
| 1983 | |||
| 1984 | call $P_Time_2412 ;AN000; this routine handle "am" "pm" | ||
| 1985 | $P_TimeF00: ;AN000; | ||
| 1986 | mov psdata_seg:$P_1st_Val,0 ;AC034; set initial value | ||
| 1987 | mov psdata_seg:$P_2nd_Val,0 ;AC034; set initial value | ||
| 1988 | mov psdata_seg:$P_3rd_Val,0 ;AC034; set initial value | ||
| 1989 | mov psdata_seg:$P_4th_Val,0 ;AC034; set initial value | ||
| 1990 | mov psdata_seg:$P_Got_Time,1 ;AN023;AC034;; use time delimiter | ||
| 1991 | mov bl,$P_colon_period ;AN032; flag, indicates use of | ||
| 1992 | ; delimiters between hours, | ||
| 1993 | ; minutes,seconds | ||
| 1994 | call $P_Get_DecNum ;AN000; get 1st number | ||
| 1995 | jc $P_TimeF_Err0 ;AN000; | ||
| 1996 | |||
| 1997 | mov psdata_seg:$P_1st_Val,ax ;AC034; | ||
| 1998 | or bl,bl ;AN000; end of line ? | ||
| 1999 | je $P_TimeF_Rlt ;AN000; | ||
| 2000 | |||
| 2001 | call $P_Get_DecNum ;AN000; get 2nd number | ||
| 2002 | jc $P_TimeF_Err0 ;AC038; if OK | ||
| 2003 | |||
| 2004 | mov psdata_seg:$P_2nd_Val,ax ;AC034; | ||
| 2005 | or bl,bl ;AN000; end of line ? | ||
| 2006 | je $P_TimeF_Rlt ;AN000; | ||
| 2007 | |||
| 2008 | ;(;AN032; deleted) mov bl,bh ;set decimal separator | ||
| 2009 | mov bl,$P_period_only ;AN032; flag, which to decimal separator | ||
| 2010 | call $P_Get_DecNum ;AN000; get 3rd number | ||
| 2011 | jc $P_TimeF_Err0 ;AC039; if problem, bridge to error | ||
| 2012 | |||
| 2013 | mov psdata_seg:$P_3rd_Val,ax ;AC034; | ||
| 2014 | or bl,bl ;AN000; end of line ? | ||
| 2015 | ;(DELETED ;AN039;) je $P_TimeF_Rlt ;AN000; | ||
| 2016 | jne $P_Time_4 ;AN039; NOT END OF LINE, | ||
| 2017 | ;AN039; GO TO 4TH NUMBER | ||
| 2018 | test psdata_seg:$P_Flags1,$P_Time_Again ;AN039; HAS TIME PARSE | ||
| 2019 | ;AN039; BEEN REPEATED? | ||
| 2020 | jnz $P_TimeF_Rlt ;AN039; yes, this is really | ||
| 2021 | ;AN039; the end of line | ||
| 2022 | ;AN039; no, time has not been repeated | ||
| 2023 | mov si,psdata_seg:$P_SI_Save ;AN039; get where parser quit | ||
| 2024 | ;AN039; in command line | ||
| 2025 | cmp byte ptr [si-1],$P_Comma ;AN039; look at delimiter | ||
| 2026 | ;AN039; from command line | ||
| 2027 | jne $P_TimeF_Rlt ;AN039; was not a comma, this is | ||
| 2028 | ;AN039; really end of line | ||
| 2029 | ;AN039; is comma before hundredths, | ||
| 2030 | ;AN039; redo TIME | ||
| 2031 | mov byte ptr [si-1],$P_Period ;AN039; change that ambiguous | ||
| 2032 | ;AN039; comma to a decimal point | ||
| 2033 | ;AN039; parse can understand | ||
| 2034 | mov psdata_seg:$P_Flags,0 ;AN039; Clear all internal flags | ||
| 2035 | or psdata_seg:$P_Flags1,$P_Time_Again ;AN039; indicate TIME | ||
| 2036 | ;AN039; is being repeated | ||
| 2037 | mov cx,psdata_seg:$P_ORIG_ORD ;AN039; ORIGINAL ORDINAL FROM CX | ||
| 2038 | mov sp,psdata_seg:$P_ORIG_STACK ;AN039; ORIGINAL VALUE | ||
| 2039 | ;AN039; OF STACK FROM SP | ||
| 2040 | mov si,psdata_seg:$P_ORIG_SI ;AN039; ORIGINAL START | ||
| 2041 | ;AN039; PARSE POINTER FROM SI | ||
| 2042 | jmp $P_Redo_Time ;AN039; go try TIME again | ||
| 2043 | ; =============================================================== | ||
| 2044 | $P_Time_4: ;AN039; READY FOR 4TH (HUNDREDTHS) NUMBER | ||
| 2045 | call $P_Get_DecNum ;AN000; get 4th number | ||
| 2046 | $P_TimeF_Err0: ;AN000; Bridge | ||
| 2047 | jc $P_TimeF_Error ;AN000; | ||
| 2048 | |||
| 2049 | mov psdata_seg:$P_4th_Val,ax ;AC034; | ||
| 2050 | or bl,bl ;AN000; After hundredth, no data allowed | ||
| 2051 | jne $P_TimeF_Error ;AN000; if some, then error | ||
| 2052 | |||
| 2053 | $P_TimeF_RLT: ;AN000; | ||
| 2054 | mov ax,psdata_seg:$P_1st_Val ;AC034; | ||
| 2055 | or ah,ah ;AN000; if overflow then error | ||
| 2056 | jne $P_TimeF_Err ;AN000; | ||
| 2057 | |||
| 2058 | test psdata_seg:$P_Flags1,$P_Time12am ;AN038;if "am" specified | ||
| 2059 | jz $P_Time_notAM ;AN038;skip if no "AM" specified | ||
| 2060 | ;since "AM" was specified, | ||
| 2061 | cmp al,12 ;AN038: if hour specified as later than noon | ||
| 2062 | ja $P_TimeF_Err ;AN038; error if "AM" on more than noon | ||
| 2063 | jne $P_Time_notAM ;AN038; for noon exactly, | ||
| 2064 | |||
| 2065 | xor al,al ;AN038; set hour = zero | ||
| 2066 | $P_Time_notAM: ;AN038; | ||
| 2067 | test psdata_seg:$P_Flags2,$P_Time12 ;AC034; if 12 hour system and pm is specified | ||
| 2068 | je $P_TimeSkip00 ;AN000; then | ||
| 2069 | |||
| 2070 | cmp al,12 ;AN038; if 12:00 o'clock already | ||
| 2071 | je $P_TimeSkip00 ;AN038; it is PM already | ||
| 2072 | |||
| 2073 | add al,12 ;AN000; add 12 hours to make it afternoon | ||
| 2074 | jc $P_TimeF_Err ;AN000; if overflow then error | ||
| 2075 | |||
| 2076 | cmp al,24 ;AN038; after adding 12, now cannot be >24 | ||
| 2077 | ja $P_TimeF_Err ;AN038; if too big, error | ||
| 2078 | |||
| 2079 | $P_TimeSkip00: ;AN000; | ||
| 2080 | mov dl,al ;AN000; set hour | ||
| 2081 | mov ax,psdata_seg:$P_2nd_Val ;AC034; | ||
| 2082 | or ah,ah ;AN000; if overflow then error | ||
| 2083 | jne $P_TimeF_Err ;AN000; | ||
| 2084 | |||
| 2085 | mov dh,al ;AN000; set minute | ||
| 2086 | mov ax,psdata_seg:$P_3rd_Val ;AC034; | ||
| 2087 | or ah,ah ;AN000; if overflow then error | ||
| 2088 | jne $P_TimeF_Err ;AN000; | ||
| 2089 | |||
| 2090 | mov cl,al ;AN000; set second | ||
| 2091 | mov ax,psdata_seg:$P_4th_Val ;AC034; | ||
| 2092 | or ah,ah ;AN000; if overflow then error | ||
| 2093 | jne $P_TimeF_Err ;AN000; | ||
| 2094 | |||
| 2095 | mov ch,al ;AN000; set hundredth | ||
| 2096 | pop bx ;AN000; recover CONTROL block | ||
| 2097 | pop si ;AN000; recover string pointer | ||
| 2098 | mov ah,$P_No_Tag ;AN000; set | ||
| 2099 | mov al,$P_Time_F ;AN000; result | ||
| 2100 | call $P_Fill_Result ;AN000; buffer | ||
| 2101 | jmp short $P_Time_Format_Exit ;AN000; to time | ||
| 2102 | |||
| 2103 | $P_TimeF_Error: ;AN000; | ||
| 2104 | $P_TimeF_Err: ;AN000; | ||
| 2105 | pop bx ;AN000; recover CONTROL block | ||
| 2106 | pop si ;AN000; recover string pointer | ||
| 2107 | mov ah,$P_No_Tag ;AN000; set | ||
| 2108 | mov al,$P_String ;AN000; result | ||
| 2109 | call $P_Fill_Result ;AN000; buffer to string | ||
| 2110 | mov psdata_seg:$P_RC,$P_Syntax ;AC034; return syntax error | ||
| 2111 | $P_Time_Format_Exit: ;AN000; | ||
| 2112 | mov psdata_seg:$P_Got_Time,0 ;AN023;AC034;; finished with this time field | ||
| 2113 | pop dx ;AN000; | ||
| 2114 | pop cx ;AN000; | ||
| 2115 | pop ax ;AN000; | ||
| 2116 | ret ;AN000; | ||
| 2117 | $P_Time_Format endp ;AN000; | ||
| 2118 | PAGE ;AN000; | ||
| 2119 | ;*********************************************************************** | ||
| 2120 | ; $P_Time_2412: | ||
| 2121 | ; | ||
| 2122 | ; Function: Remove "a", "p", "am", or "pm" from the end of stinrg | ||
| 2123 | ; | ||
| 2124 | ; Input: psdata_seg:SI -> $P_STRING_BUF | ||
| 2125 | ; | ||
| 2126 | ; Output: Set $P_Time12 flag when the string is terminated by "p" | ||
| 2127 | ; or "pm" | ||
| 2128 | ; | ||
| 2129 | ; Vars: $P_Flags(W) | ||
| 2130 | ;*********************************************************************** | ||
| 2131 | $P_Time_2412 proc ;AN000; | ||
| 2132 | push ax ;AN000; | ||
| 2133 | push si ;AN000; | ||
| 2134 | $P_T12_Loop: ;AN000; | ||
| 2135 | mov al,psdata_seg:[si] ;AN000; Move | ||
| 2136 | inc si ;AN000; si | ||
| 2137 | or al,al ;AN000; to | ||
| 2138 | jne $P_T12_Loop ;AN000; end of string | ||
| 2139 | |||
| 2140 | mov al,psdata_seg:[si-word] ;AN000; get char just before NULL | ||
| 2141 | or al,$P_Make_Lower ;AN000; lower case map | ||
| 2142 | cmp al,"p" ;AN000; only "p" of "pm" ? | ||
| 2143 | je $P_T1200 ;AN000; | ||
| 2144 | |||
| 2145 | cmp al,"a" ;AN000; only "a" of "am" ? | ||
| 2146 | je $P_T1201 ;AN000; | ||
| 2147 | |||
| 2148 | cmp al,"m" ;AN000; "m" of "am" or "pm" | ||
| 2149 | jne $P_T12_Exit ;AN000; | ||
| 2150 | |||
| 2151 | dec si ;AN000; | ||
| 2152 | mov al,psdata_seg:[si-word] ;AN000; | ||
| 2153 | or al,$P_Make_lower ;AN000; lower case map | ||
| 2154 | cmp al,"p" ;AN000; "p" of "pm" ? | ||
| 2155 | je $P_T1200 ;AN000; | ||
| 2156 | |||
| 2157 | cmp al,"a" ;AN000; "a" of "am" ? | ||
| 2158 | je $P_T1201 ;AN000; go process "a" | ||
| 2159 | |||
| 2160 | jmp short $P_T12_Exit ;AN000; no special chars found | ||
| 2161 | |||
| 2162 | $P_T1200: ;AN000; "P" found | ||
| 2163 | or psdata_seg:$P_Flags2,$P_Time12 ;AC034; flag "PM" found | ||
| 2164 | jmp short $P_Tclr_chr ;AN038; go clear the special char | ||
| 2165 | |||
| 2166 | $P_T1201: ;AN000; "A" found | ||
| 2167 | or psdata_seg:$P_Flags1,$P_Time12AM ;AN038; flag "AM" found | ||
| 2168 | $P_Tclr_chr: ;AN038; | ||
| 2169 | mov byte ptr psdata_seg:[si-2],$P_NULL ;AN000; null out special char | ||
| 2170 | $P_T12_Exit: ;AN000; | ||
| 2171 | pop si ;AN000; | ||
| 2172 | pop ax ;AN000; | ||
| 2173 | ret ;AN000; | ||
| 2174 | $P_Time_2412 endp ;AN000; | ||
| 2175 | ENDIF ;AN000;(of TimeSW) | ||
| 2176 | PAGE ;AN000; | ||
| 2177 | ;*********************************************************************** | ||
| 2178 | IF CmpxSW ;AN000;(Check if complex item is supported) | ||
| 2179 | ; $P_Complex_Format: | ||
| 2180 | ; | ||
| 2181 | ; Function: Check if the input string is valid complex format. | ||
| 2182 | ; And set the result buffer. | ||
| 2183 | ; | ||
| 2184 | ; Input: psdata_seg:SI -> $P_STRING_BUF | ||
| 2185 | ; ES:BX -> CONTROL block | ||
| 2186 | ; | ||
| 2187 | ; Output: None | ||
| 2188 | ; | ||
| 2189 | ; Use: $P_Fill_Result, $P_Chk_DBCS, $P_Chk_EOL, $P_Skip_Delim | ||
| 2190 | ; $P_Quoted_str, $P_Chk_DSQuote | ||
| 2191 | ; | ||
| 2192 | ; Vars: $P_RC(W), $P_SI_Save(W), $P_SaveSI_Cmpx(R), $P_Save_EOB(R) | ||
| 2193 | ;*********************************************************************** | ||
| 2194 | $P_Complex_Format proc ;AN000; | ||
| 2195 | push ax ;AN000; | ||
| 2196 | push bx ;AN000; | ||
| 2197 | push si ;AN000; | ||
| 2198 | mov bx,psdata_seg:$P_SaveSI_Cmpx ;AC034; bx points to user buffer | ||
| 2199 | cmp byte ptr [bx],$P_Lparen ;AN000; 1st char = left parentheses | ||
| 2200 | jne $P_Cmpx_Err ;AN000; | ||
| 2201 | |||
| 2202 | xor ah,ah ;AN000; ah = parentheses counter | ||
| 2203 | $P_Cmpx_Loop: ;AN000; | ||
| 2204 | mov al,[bx] ;AN000; load character from command buffer | ||
| 2205 | call $P_Chk_EOL ;AN000; if it is one of EOL | ||
| 2206 | je $P_CmpxErr0 ;AN000; then error exit. | ||
| 2207 | |||
| 2208 | cmp al,$P_Lparen ;AN000; left parentheses ? | ||
| 2209 | jne $P_Cmpx00 ;AN000; then | ||
| 2210 | |||
| 2211 | inc ah ;AC035; add '1' to AH reg | ||
| 2212 | ;AN000; increment parentheses counter | ||
| 2213 | ;(replaced ;AC035;) add ah,1 ;AN000; increment parentheses counter | ||
| 2214 | jc $P_CmpxErr0 ;AN000; if overflow, error | ||
| 2215 | $P_Cmpx00: ;AN000; | ||
| 2216 | cmp al,$P_Rparen ;AN000; right parentheses ? | ||
| 2217 | jne $P_Cmpx01 ;AN000; then | ||
| 2218 | |||
| 2219 | dec ah ;AC035; subtract '1' from AH reg | ||
| 2220 | ;AN000; decrement parentheses counter | ||
| 2221 | ;(changed ;AC035;) sub ah,1 ;AN000; decrement parentheses counter | ||
| 2222 | jc $P_CmpxErr0 ;AN000; if overflow error | ||
| 2223 | |||
| 2224 | je $P_Cmpx03 ;AN000; ok, valid complex | ||
| 2225 | |||
| 2226 | $P_Cmpx01: ;AN000; | ||
| 2227 | ;(deleted ;AN025;) call $P_Chk_DSQuote ;AN000; double or single quotation mark ? 3/17/KK | ||
| 2228 | cmp al,$P_DQuote ;AN025; double quotation mark? | ||
| 2229 | jne $P_Cmpx04 ;AN000; 3/17/KK | ||
| 2230 | |||
| 2231 | mov psdata_seg:[si],al ;AN000; here quoted string is found in the complex list. | ||
| 2232 | inc si ;AN000; | ||
| 2233 | inc bx ;AN000; bx points to 2nd character | ||
| 2234 | call $P_Quoted_Str ;AN000; skip pointers until closing of quoted string | ||
| 2235 | jc $P_CmpxErr0 ;AN000; if error in quoted string syntax then exit | ||
| 2236 | |||
| 2237 | jmp short $P_Cmpx05 ;AN000; | ||
| 2238 | |||
| 2239 | $P_Cmpx04: ;AN000; | ||
| 2240 | call $P_Chk_DBCS ;AN000; was it a lead byte of DBCS ? | ||
| 2241 | jnc $P_Cmpx02 ;AN000; | ||
| 2242 | |||
| 2243 | mov psdata_seg:[si],al ;AN000; then store 1st byte | ||
| 2244 | inc si ;AN000; | ||
| 2245 | inc bx ;AN000; | ||
| 2246 | mov al,[bx] ;AN000; load 2nd byte | ||
| 2247 | $P_Cmpx02: ;AN000; | ||
| 2248 | mov psdata_seg:[si],al ;AN000; store SBCS or 2nd byte of DBCS | ||
| 2249 | $P_Cmpx05: ;AN000; | ||
| 2250 | inc si ;AN000; | ||
| 2251 | inc bx ;AN000; | ||
| 2252 | jmp short $P_Cmpx_Loop ;AN000; loop | ||
| 2253 | ;---- ;AN000; | ||
| 2254 | $P_Cmpx03: ;AN000; | ||
| 2255 | mov byte ptr psdata_seg:[si],al ;AN000; | ||
| 2256 | mov byte ptr psdata_seg:[si+byte],$P_NULL ;AN000; | ||
| 2257 | mov byte ptr [bx],$P_NULL ;AN000; replace right parentheses with NULL | ||
| 2258 | mov si,bx ;AN000; skip whitespaces | ||
| 2259 | inc si ;AN000; after | ||
| 2260 | call $P_Skip_Delim ;AN000; right parentheses | ||
| 2261 | mov psdata_seg:$P_SI_Save,si ;AC034; save next pointer, SI | ||
| 2262 | jmp short $P_Cmpx_Exit ;AN000; | ||
| 2263 | |||
| 2264 | $P_CmpxErr0: ;AN000; | ||
| 2265 | mov si,psdata_seg:$P_Save_EOB ;AC034; if EOF encountered, restore | ||
| 2266 | mov byte ptr psdata_seg:[si],$P_NULL ;AN000; EOB mark | ||
| 2267 | $P_Cmpx_Err: ;AN000; | ||
| 2268 | mov psdata_seg:$P_RC,$P_Syntax ;AC034; | ||
| 2269 | $P_Cmpx_Exit: ;AN000; | ||
| 2270 | mov ah,$P_No_Tag ;AN000; | ||
| 2271 | mov al,$P_Complex ;AN000; | ||
| 2272 | pop si ;AN000; | ||
| 2273 | pop bx ;AN000; | ||
| 2274 | call $P_Fill_Result ;AN000; | ||
| 2275 | pop ax ;AN000; | ||
| 2276 | ret ;AN000; | ||
| 2277 | $P_Complex_Format endp ;AN000; | ||
| 2278 | ENDIF ;AN000;(of CpmxSW) | ||
| 2279 | PAGE ;AN000; | ||
| 2280 | ;*********************************************************************** | ||
| 2281 | IF QusSW ;AN000;(Check if quoted string is supported) | ||
| 2282 | ; $P_Quoted_Format: | ||
| 2283 | ; | ||
| 2284 | ; Function: Check if the input string is valid quoted string format. | ||
| 2285 | ; And set the result buffer. | ||
| 2286 | ; | ||
| 2287 | ; Input: psdata_seg:SI -> $P_STRING_BUF | ||
| 2288 | ; ES:BX -> CONTROL block | ||
| 2289 | ; | ||
| 2290 | ; Output: None | ||
| 2291 | ; | ||
| 2292 | ; Use: $P_Fill_Result, $P_Chk_DBCS, $P_Chk_EOL, $P_Skip_Delim | ||
| 2293 | ; $P_Chk_DSQuote, $P_Quoted_Str | ||
| 2294 | ; | ||
| 2295 | ; Vars: $P_RC(W), $P_SI_Save(W), $P_SaveSI_Cmpx(R),$P_Save_EOB(R) | ||
| 2296 | ;*********************************************************************** | ||
| 2297 | $P_Quoted_Format proc ;AN000; | ||
| 2298 | push ax ;AN000; | ||
| 2299 | push bx ;AN000; | ||
| 2300 | push si ;AN000; | ||
| 2301 | mov bx,psdata_seg:$P_SaveSI_Cmpx ;AC034; bx points to user buffer | ||
| 2302 | mov al,byte ptr [bx] ;AN000; get 1st character | ||
| 2303 | ;(deleted ;AN025;) call $P_Chk_DSQuote ;AN000; is it single or double quote ? | ||
| 2304 | cmp al,$P_DQuote ;AN025; double quotation mark? | ||
| 2305 | jne $P_Qus_Err ;AN000; if no, error | ||
| 2306 | |||
| 2307 | ; mov psdata_seg:[si],al ;AN000; move it to internal buffer | ||
| 2308 | ; inc si ;AN000; | ||
| 2309 | inc bx ;AN000; bx points to 2nd character | ||
| 2310 | call $P_Quoted_Str ;AN000; skip pointers to the closing of quoted string | ||
| 2311 | jc $P_Qus_Err0 ;AN000; if invali quoted string syntax, exit | ||
| 2312 | |||
| 2313 | mov byte ptr psdata_seg:[si+byte],$P_NULL ;AN000; end up with NULL | ||
| 2314 | mov si,bx ;AN000; | ||
| 2315 | inc si ;AN000; | ||
| 2316 | call $P_Skip_Delim ;AN000; skip whitespaces after closing quote | ||
| 2317 | mov psdata_seg:$P_SI_Save,si ;AC034; save next pointer, SI | ||
| 2318 | jmp short $P_Qus_Exit ;AN000; | ||
| 2319 | |||
| 2320 | $P_Qus_Err0: ;AN000; | ||
| 2321 | mov si,psdata_seg:$P_Save_EOB ;AC034; if EOF encountered, restore | ||
| 2322 | mov byte ptr psdata_seg:[si],$P_NULL ;AN000; EOB mark | ||
| 2323 | $P_Qus_Err: ;AN000;AN000 | ||
| 2324 | mov psdata_seg:$P_RC,$P_Syntax ;AC034; indicate syntax error | ||
| 2325 | $P_Qus_Exit: ;AN000; | ||
| 2326 | mov ah,$P_No_Tag ;AN000; set | ||
| 2327 | mov al,$P_Quoted_String ;AN000; result | ||
| 2328 | pop si ;AN000; buffer | ||
| 2329 | pop bx ;AN000; to | ||
| 2330 | call $P_Fill_Result ;AN000; quoted string | ||
| 2331 | pop ax ;AN000; | ||
| 2332 | ret ;AN000; | ||
| 2333 | $P_Quoted_Format endp ;AN000; | ||
| 2334 | ENDIF ;AN000;(of QusSW) | ||
| 2335 | PAGE ;AN000; | ||
| 2336 | ;*********************************************************************** | ||
| 2337 | ; $P_Chk_DSQuote; | ||
| 2338 | ; | ||
| 2339 | ; Function: Check if AL is double quotation or single quotation | ||
| 2340 | ; | ||
| 2341 | ; Input: AL = byte to be examineed | ||
| 2342 | ; | ||
| 2343 | ; Output: ZF on if AL is single or double quotetaion | ||
| 2344 | ; | ||
| 2345 | ; Vars: $P_SorD_Quote(W) | ||
| 2346 | ;*********************************************************************** | ||
| 2347 | IF QusSW+CmpxSW ;AN000;(Check if quoted string or complex item is supported) | ||
| 2348 | ;(deleted ;AN025;) $P_Chk_DSQuote proc ; | ||
| 2349 | ;(deleted ;AN025;) mov $P_SorD_Quote,$P_SQuote ; 3/17/87 assume single quote | ||
| 2350 | ;(deleted ;AN025;) cmp al,$P_DQuote ; 1st char = double quotation ? | ||
| 2351 | ;(deleted ;AN025;) jne $P_CDSQ00 ; 3/17/87 | ||
| 2352 | ;(deleted ;AN025;) mov $P_SorD_Quote,al ; 3/17/87 set bigning w/ double quote | ||
| 2353 | ;(deleted ;AN025;) ret ; 3/17/87 | ||
| 2354 | ;(deleted ;AN025;) $P_CDSQ00: ; 3/17/87 | ||
| 2355 | ;(deleted ;AN025;) cmp al,$P_SQuote ; 1st char = single quotation ? | ||
| 2356 | ;(deleted ;AN025;) ret ; | ||
| 2357 | ;(deleted ;AN025;) $P_Chk_DSQuote endp ; | ||
| 2358 | PAGE ;AN000; | ||
| 2359 | ;*********************************************************************** | ||
| 2360 | ; $P_Quoted_Str: | ||
| 2361 | ; | ||
| 2362 | ; Function: Copy chracacter from ES:BX to psdata_seg:SI until closing single | ||
| 2363 | ; (double) quotation found. | ||
| 2364 | ; | ||
| 2365 | ; Input: psdata_seg:SI -> $P_STRING_BUF | ||
| 2366 | ; ES:BX -> Operand in command buffer | ||
| 2367 | ; | ||
| 2368 | ; Output: CY on indicates EOF encounterd before closing quotation | ||
| 2369 | ; BX and SI | ||
| 2370 | ; | ||
| 2371 | ; | ||
| 2372 | ; Vars: $P_SorD_Quote(R) | ||
| 2373 | ;*********************************************************************** | ||
| 2374 | $P_Quoted_Str proc ;AN000; | ||
| 2375 | push ax ;AN000; | ||
| 2376 | $P_Qus_Loop: ;AN000; | ||
| 2377 | mov ax,[bx] ;AN000; 3/17/87 | ||
| 2378 | call $P_Chk_EOL ;AN000; | ||
| 2379 | je $P_Qustr_Err0 ;AN000; | ||
| 2380 | |||
| 2381 | ;(deleted ;AN025;) cmp al,$P_SorD_Quote ;AN000; quotation ? 3/17/87 | ||
| 2382 | cmp al,$P_DQuote ;AN025; double quote? | ||
| 2383 | jne $P_Qus00 ;AN000; | ||
| 2384 | |||
| 2385 | ;(deleted ;AN025;) cmp ah,$P_SorD_Quote ;AN000; contiguous quotation 3/17/87 | ||
| 2386 | cmp ah,$P_DQuote ;AN025; double quote? | ||
| 2387 | jne $P_Qus02 ;AN000; | ||
| 2388 | |||
| 2389 | ;(deleted ;AN025:) mov word ptr psdata_seg:[si],ax ;AN000; 3/17/87 | ||
| 2390 | mov byte ptr psdata_seg:[si],al ;AN025; save one of the quotes | ||
| 2391 | ;(deleted ;AN025:) add si,2 ;AN000; | ||
| 2392 | |||
| 2393 | inc si ;AC035; add '1' to SI reg | ||
| 2394 | ;AN025; adjust target index | ||
| 2395 | ;(changed ;AC035;) add si,1 ;AN025; adjust target index | ||
| 2396 | inc bx ;AC035; add '2' to | ||
| 2397 | inc bx ;AC035; BX reg | ||
| 2398 | ;AN000; adjust source index by 2 to skip extra quote | ||
| 2399 | ;(changed ;AC035;) add bx,2 ;AN000; adjust source index by 2 to skip extra quote | ||
| 2400 | jmp short $P_Qus_Loop ;AN000; | ||
| 2401 | |||
| 2402 | $P_Qus00: ;AN000; | ||
| 2403 | call $P_Chk_DBCS ;AN000; was it a lead byte of DBCS ? | ||
| 2404 | jnc $P_Qus01 ;AN000; | ||
| 2405 | |||
| 2406 | mov psdata_seg:[si],al ;AN000; store 1st byte | ||
| 2407 | inc si ;AN000; | ||
| 2408 | inc bx ;AN000; | ||
| 2409 | mov al,[bx] ;AN000; load 2nd byte | ||
| 2410 | $P_Qus01: ;AN000; | ||
| 2411 | mov psdata_seg:[si],al ;AN000; store SBCS or 2nd byte of DBCS | ||
| 2412 | inc si ;AN000; | ||
| 2413 | inc bx ;AN000; | ||
| 2414 | jmp short $P_Qus_Loop ;AN000; | ||
| 2415 | |||
| 2416 | $P_Qustr_Err0: ;AN000; | ||
| 2417 | stc ;AN000; indicate error | ||
| 2418 | jmp short $P_Quoted_Str_Exit ;AN000; | ||
| 2419 | |||
| 2420 | $P_Qus02: ;AN000; | ||
| 2421 | mov byte ptr psdata_seg:[si],0 ;AN000; | ||
| 2422 | clc ;AN000; indicate no error | ||
| 2423 | $P_Quoted_Str_Exit: ;AN000; | ||
| 2424 | pop ax ;AN000; | ||
| 2425 | ret ;AN000; | ||
| 2426 | $P_Quoted_Str endp ;AN000; | ||
| 2427 | ENDIF ;AN000;(of QusSW+CmpxSW) | ||
| 2428 | PAGE ;AN000; | ||
| 2429 | ;*********************************************************************** | ||
| 2430 | IF FileSW+DrvSW ;AN000;(Check if file spec or drive only is supported) | ||
| 2431 | ; $P_File_Format; | ||
| 2432 | ; | ||
| 2433 | ; Function: Check if the input string is valid file spec format. | ||
| 2434 | ; And set the result buffer. | ||
| 2435 | ; | ||
| 2436 | ; Input: psdata_seg:SI -> $P_STRING_BUF | ||
| 2437 | ; ES:BX -> CONTROL block | ||
| 2438 | ; | ||
| 2439 | ; Output: None | ||
| 2440 | ; | ||
| 2441 | ; Use: $P_Fill_Result, $P_Chk_DBCS, $P_FileSp_Chk | ||
| 2442 | ; | ||
| 2443 | ; Vars: $P_RC(W), $P_SI_Save(W), $P_Terminator(W), $P_SaveSI_Cmpx(R) | ||
| 2444 | ; $P_SaveSI_Cmpx(R) | ||
| 2445 | ;*********************************************************************** | ||
| 2446 | $P_File_Format proc ;AN000; | ||
| 2447 | push ax ;AN000; | ||
| 2448 | push di ;AN000; | ||
| 2449 | push si ;AN000; | ||
| 2450 | mov di,psdata_seg:$P_SaveSI_cmpx ;AC034; get user buffer address | ||
| 2451 | $P_FileF_Loop0: ;AN000; / skip special characters | ||
| 2452 | mov al,psdata_seg:[si] ;AN000; load character | ||
| 2453 | or al,al ;AN000; end of line ? | ||
| 2454 | je $P_FileF_Err ;AN000; if yes, error exit | ||
| 2455 | |||
| 2456 | call $P_FileSp_Chk ;AN000; else, check if file special character | ||
| 2457 | jne $P_FileF03 ;AN000; if yes, | ||
| 2458 | |||
| 2459 | ;AN033; deleted inc di ;skip | ||
| 2460 | ;AN033; deleted inc si ; the | ||
| 2461 | ;AN033; deleted jmp short $P_FileF_Loop0 ; character | ||
| 2462 | mov psdata_seg:$P_err_flag,$P_error_filespec ;AN033;AC034;; set error flag- bad char. | ||
| 2463 | pop si ;AN033; | ||
| 2464 | mov byte ptr psdata_seg:[si],$P_NULL ;AN033; | ||
| 2465 | pop di ;AN033; | ||
| 2466 | jmp short $P_FileF02 ;AN033; | ||
| 2467 | |||
| 2468 | |||
| 2469 | $P_FileF_Err: ;AN000; | ||
| 2470 | pop si ;AN000; | ||
| 2471 | mov byte ptr psdata_seg:[si],$P_NULL ;AN000; | ||
| 2472 | ;(deleted ;AN030;) mov di,$P_SaveSI_cmpx ;AN000; get user buffer address | ||
| 2473 | ;(deleted ;AN030;) mov $P_SI_Save,di ;AN000; update pointer to user buffer | ||
| 2474 | pop di ;AN000; | ||
| 2475 | test es:[bx].$P_Match_Flag,$P_Optional ;AN000; is it optional ? | ||
| 2476 | jne $P_FileF02 ;AN000; | ||
| 2477 | |||
| 2478 | mov psdata_seg:$P_RC,$P_Op_Missing ;AC034; 3/17/87 | ||
| 2479 | jmp short $P_FileF02 ;AN000; | ||
| 2480 | |||
| 2481 | $P_FileF03: ;AN000; | ||
| 2482 | pop ax ;AN000; discard save si | ||
| 2483 | push si ;AN000; save new si | ||
| 2484 | $P_FileF_Loop1: ;AN000; | ||
| 2485 | mov al,psdata_seg:[si] ;AN000; load character (not special char) | ||
| 2486 | or al,al ;AN000; end of line ? | ||
| 2487 | je $P_FileF_RLT ;AN000; | ||
| 2488 | |||
| 2489 | call $P_FileSp_Chk ;AN000; File special character ? | ||
| 2490 | je $P_FileF00 ;AN000; | ||
| 2491 | |||
| 2492 | call $P_Chk_DBCS ;AN000; no, then DBCS ? | ||
| 2493 | jnc $P_FileF01 ;AN000; | ||
| 2494 | inc di ;AN000; if yes, skip next byte | ||
| 2495 | inc si ;AN000; | ||
| 2496 | $P_FileF01: ;AN000; | ||
| 2497 | inc di ;AN000; | ||
| 2498 | inc si ;AN000; | ||
| 2499 | jmp short $P_FileF_Loop1 ;AN000; | ||
| 2500 | ; | ||
| 2501 | $P_FileF00: ;AN000; | ||
| 2502 | mov psdata_seg:$P_Terminator,al ;AC034; | ||
| 2503 | mov byte ptr psdata_seg:[si],$P_NULL ;AN000; update end of string | ||
| 2504 | inc di ;AN000; | ||
| 2505 | mov psdata_seg:$P_SI_Save,di ;AC034; update next pointer in command line | ||
| 2506 | $P_FileF_RLT: ;AN000; | ||
| 2507 | pop si ;AN000; | ||
| 2508 | pop di ;AN000; | ||
| 2509 | $P_FileF02: ;AN000; | ||
| 2510 | |||
| 2511 | pop ax ;AN000; (tm14) | ||
| 2512 | test ax,$P_File_Spc ;AN000; (tm14) | ||
| 2513 | je $P_Drv_Only_Exit ;AN000; (tm14) | ||
| 2514 | |||
| 2515 | push ax ;AN000; (tm14) | ||
| 2516 | |||
| 2517 | mov ah,$P_No_Tag ;AN000; set | ||
| 2518 | mov al,$P_File_Spec ;AN000; result | ||
| 2519 | call $P_Fill_Result ;AN000; buffer to file spec | ||
| 2520 | pop ax ;AN000; | ||
| 2521 | |||
| 2522 | $P_Drv_Only_Exit: ;AN000; (tm14) | ||
| 2523 | |||
| 2524 | ret ;AN000; | ||
| 2525 | $P_File_Format endp ;AN000; | ||
| 2526 | PAGE ;AN000; | ||
| 2527 | ;*********************************************************************** | ||
| 2528 | ; $P_FileSp_Chk | ||
| 2529 | ; | ||
| 2530 | ; Function: Check if the input byte is one of file special characters | ||
| 2531 | ; | ||
| 2532 | ; Input: psdata_seg:SI -> $P_STRING_BUF | ||
| 2533 | ; AL = character code to be examineed | ||
| 2534 | ; | ||
| 2535 | ; Output: ZF = 1 , AL is one of special characters | ||
| 2536 | ;*********************************************************************** | ||
| 2537 | $P_FileSp_Chk proc ;AN000; | ||
| 2538 | push bx ;AN000; | ||
| 2539 | push cx ;AN000; | ||
| 2540 | lea bx,psdata_seg:$P_FileSp_Char ;AC034; special character table | ||
| 2541 | mov cx,$P_FileSp_Len ;AN000; load length of it | ||
| 2542 | $P_FileSp_Loop: ;AN000; | ||
| 2543 | cmp al,psdata_seg:[bx] ;AN000; is it one of special character ? | ||
| 2544 | je $P_FileSp_Exit ;AN000; | ||
| 2545 | |||
| 2546 | inc bx ;AN000; | ||
| 2547 | loop $P_FileSp_Loop ;AN000; | ||
| 2548 | |||
| 2549 | inc cx ;AN000; reset ZF | ||
| 2550 | $P_FileSp_Exit: ;AN000; | ||
| 2551 | pop cx ;AN000; | ||
| 2552 | pop bx ;AN000; | ||
| 2553 | ret ;AN000; | ||
| 2554 | $P_FileSp_Chk endp ;AN000; | ||
| 2555 | ENDIF ;AN000;(of FileSW+DrvSW) | ||
| 2556 | PAGE ;AN000; | ||
| 2557 | ;*********************************************************************** | ||
| 2558 | IF DrvSW ;AN000;(Check if drive only is supported) | ||
| 2559 | ; $P_Drive_Format; | ||
| 2560 | ; | ||
| 2561 | ; Function: Check if the input string is valid drive only format. | ||
| 2562 | ; And set the result buffer. | ||
| 2563 | ; | ||
| 2564 | ; Input: psdata_seg:SI -> $P_STRING_BUF | ||
| 2565 | ; ES:BX -> CONTROL block | ||
| 2566 | ; | ||
| 2567 | ; Output: None | ||
| 2568 | ; | ||
| 2569 | ; Use: $P_Fill_Result, $P_Chk_DBCS | ||
| 2570 | ; | ||
| 2571 | ; Vars: $P_RC(W) | ||
| 2572 | ;*********************************************************************** | ||
| 2573 | $P_Drive_Format proc ;AN000; | ||
| 2574 | push ax ;AN000; | ||
| 2575 | push dx ;AN000; | ||
| 2576 | mov al,psdata_seg:[si] ;AN000; | ||
| 2577 | or al,al ;AN000; if null string | ||
| 2578 | je $P_Drv_Exit ;AN000; do nothing | ||
| 2579 | |||
| 2580 | call $P_Chk_DBCS ;AN000; is it leading byte ? | ||
| 2581 | jc $P_Drv_Err ;AN000; | ||
| 2582 | |||
| 2583 | cmp word ptr psdata_seg:[si+byte],$P_Colon ;AN000; "d", ":", 0 ? | ||
| 2584 | je $P_DrvF00 ;AN000; | ||
| 2585 | |||
| 2586 | test es:[bx].$P_Match_Flag,$P_Ig_Colon ;AN000; colon can be ignored? | ||
| 2587 | je $P_Drv_Err ;AN000; | ||
| 2588 | |||
| 2589 | cmp byte ptr psdata_seg:[si+byte],$P_NULL ;AN000; "d", 0 ? | ||
| 2590 | jne $P_Drv_Err ;AN000; | ||
| 2591 | |||
| 2592 | $P_DrvF00: ;AN000; | ||
| 2593 | or al,$P_Make_Lower ;AN000; lower case | ||
| 2594 | cmp al,"a" ;AN000; drive letter must | ||
| 2595 | jb $P_Drv_Err ;AN000; in range of | ||
| 2596 | |||
| 2597 | cmp al,"z" ;AN000; "a" - "z" | ||
| 2598 | ja $P_Drv_Err ;AN000; if no, error | ||
| 2599 | |||
| 2600 | sub al,"a"-1 ;AN000; make text drive to binary drive | ||
| 2601 | mov dl,al ;AN000; set | ||
| 2602 | mov ah,$P_No_Tag ;AN000; result | ||
| 2603 | mov al,$P_Drive ;AN000; buffer | ||
| 2604 | call $P_Fill_Result ;AN000; to drive | ||
| 2605 | jmp short $P_Drv_Exit ;AN000; | ||
| 2606 | |||
| 2607 | $P_Drv_Err: ;AN000; | ||
| 2608 | mov psdata_seg:$P_RC,$P_Syntax ;AC034; | ||
| 2609 | $P_Drv_Exit: ;AN000; | ||
| 2610 | pop dx ;AN000; | ||
| 2611 | pop ax ;AN000; | ||
| 2612 | ret ;AN000; | ||
| 2613 | $P_Drive_Format endp ;AN000; | ||
| 2614 | ENDIF ;AN000;(of DrvSW) | ||
| 2615 | PAGE ;AN000; | ||
| 2616 | ;*********************************************************************** | ||
| 2617 | ; $P_Skip_Delim; | ||
| 2618 | ; | ||
| 2619 | ; Function: Skip delimiters specified in the PARMS list, white space | ||
| 2620 | ; and comma. | ||
| 2621 | ; | ||
| 2622 | ; Input: DS:SI -> Command String | ||
| 2623 | ; ES:DI -> Parameter List | ||
| 2624 | ; | ||
| 2625 | ; Output: CY = 1 if the end of line encounterd | ||
| 2626 | ; CY = 0 then SI move to 1st non-delimiter character | ||
| 2627 | ; AL = Last examineed character | ||
| 2628 | ; | ||
| 2629 | ; Use: $P_Chk_EOL, $P_Chk_Delim, | ||
| 2630 | ; | ||
| 2631 | ; Vars: $P_Flags(R) | ||
| 2632 | ;*********************************************************************** | ||
| 2633 | $P_Skip_Delim proc ;AN000; | ||
| 2634 | $P_Skip_Delim_Loop: ;AN000; | ||
| 2635 | LODSB ;AN000; | ||
| 2636 | call $P_Chk_EOL ;AN000; is it EOL character ? | ||
| 2637 | je $P_Skip_Delim_CY ;AN000; if yes, exit w/ CY on | ||
| 2638 | |||
| 2639 | call $P_Chk_Delim ;AN000; is it one of delimiters ? | ||
| 2640 | jne $P_Skip_Delim_NCY ;AN000; if no, exit w/ CY off | ||
| 2641 | |||
| 2642 | test psdata_seg:$P_Flags2,$P_Extra ;AC034; extra delim or comma found ? | ||
| 2643 | je $P_Skip_Delim_Loop ;AN000; if no, loop | ||
| 2644 | |||
| 2645 | test psdata_seg:$P_Flags2,$P_SW+$P_equ ;AC034; /x , or xxx=zzz , (tm08) | ||
| 2646 | je short $P_Exit_At_Extra ;AN000; no switch, no keyword (tm08) | ||
| 2647 | |||
| 2648 | dec si ;AN000; backup si for next call (tm08) | ||
| 2649 | jmp short $P_Exit_At_Extra ;AN000; else exit w/ CY off | ||
| 2650 | |||
| 2651 | $P_Skip_Delim_CY: ;AN000; | ||
| 2652 | stc ;AN000; indicate EOL | ||
| 2653 | jmp short $P_Skip_Delim_Exit ;AN000; | ||
| 2654 | |||
| 2655 | $P_Skip_Delim_NCY: ;AN000; | ||
| 2656 | clc ;AN000; indicate non delim | ||
| 2657 | $P_Skip_Delim_Exit: ;AN000; in this case, need | ||
| 2658 | dec si ;AN000; backup index pointer | ||
| 2659 | ret ;AN000; | ||
| 2660 | |||
| 2661 | $P_Exit_At_Extra: ;AN000; | ||
| 2662 | clc ;AN000; indicate extra delim | ||
| 2663 | ret ;AN000; | ||
| 2664 | $P_Skip_Delim endp ;AN000; | ||
| 2665 | PAGE ;AN000; | ||
| 2666 | ;*********************************************************************** | ||
| 2667 | ; $P_Chk_EOL; | ||
| 2668 | ; | ||
| 2669 | ; Function: Check if AL is one of End of Line characters. | ||
| 2670 | ; | ||
| 2671 | ; Input: AL = character code | ||
| 2672 | ; ES:DI -> Parameter List | ||
| 2673 | ; | ||
| 2674 | ; Output: ZF = 1 if one of End of Line characters | ||
| 2675 | ;********************************************************************** | ||
| 2676 | $P_Chk_EOL proc ;AN000; | ||
| 2677 | push bx ;AN000; | ||
| 2678 | push cx ;AN000; | ||
| 2679 | cmp al,$P_CR ;AN000; Carriage return ? | ||
| 2680 | je $P_Chk_EOL_Exit ;AN000; | ||
| 2681 | |||
| 2682 | cmp al,$P_NULL ;AN000; zero ? | ||
| 2683 | je $P_Chk_EOL_Exit ;AN000; | ||
| 2684 | |||
| 2685 | IF LFEOLSW ;AN028; IF LF TO BE ACCEPTED AS EOL | ||
| 2686 | cmp al,$P_LF ;AN000; Line feed ? | ||
| 2687 | je $P_Chk_EOL_Exit ;AN000; | ||
| 2688 | ENDIF ;AN028; | ||
| 2689 | |||
| 2690 | cmp byte ptr es:[di].$P_Num_Extra,$P_I_Have_EOL ;AN000; EOL character specified ? | ||
| 2691 | jb $P_Chk_EOL_Exit ;AN000; | ||
| 2692 | |||
| 2693 | xor bx,bx ;AN000; | ||
| 2694 | mov bl,es:[di].$P_Len_Extra_Delim ;AN000; get length of delimiter list | ||
| 2695 | add bx,$P_Len_PARMS ;AN000; skip it | ||
| 2696 | cmp byte ptr es:[bx+di],$P_I_Use_Default ;AN000; No extra EOL character ? | ||
| 2697 | je $P_Chk_EOL_NZ ;AN000; | ||
| 2698 | |||
| 2699 | xor cx,cx ;AN000; Get number of extra chcracter | ||
| 2700 | mov cl,es:[bx+di] ;AN000; | ||
| 2701 | $P_Chk_EOL_Loop: ;AN000; | ||
| 2702 | inc bx ;AN000; | ||
| 2703 | cmp al,es:[bx+di] ;AN000; Check extra EOL character | ||
| 2704 | je $P_Chk_EOL_Exit ;AN000; | ||
| 2705 | |||
| 2706 | loop $P_Chk_EOL_Loop ;AN000; | ||
| 2707 | |||
| 2708 | $P_Chk_EOL_NZ: ;AN000; | ||
| 2709 | cmp al,$P_CR ;AN000; reset ZF | ||
| 2710 | $P_Chk_EOL_Exit: ;AN000; | ||
| 2711 | pop cx ;AN000; | ||
| 2712 | pop bx ;AN000; | ||
| 2713 | ret ;AN000; | ||
| 2714 | $P_Chk_EOL endp ;AN000; | ||
| 2715 | PAGE ;AN000; | ||
| 2716 | ;*********************************************************************** | ||
| 2717 | ; $P_Chk_Delim; | ||
| 2718 | ; | ||
| 2719 | ; Function: Check if AL is one of delimiter characters. | ||
| 2720 | ; if AL+[si] is DBCS blank, it is replaced with two SBCS | ||
| 2721 | ; blanks. | ||
| 2722 | ; | ||
| 2723 | ; Input: AL = character code | ||
| 2724 | ; DS:SI -> Next Character | ||
| 2725 | ; ES:DI -> Parameter List | ||
| 2726 | ; | ||
| 2727 | ; Output: ZF = 1 if one of delimiter characters | ||
| 2728 | ; SI points to the next character | ||
| 2729 | ; Vars: $P_Terminator(W), $P_Flags(W) | ||
| 2730 | ;*********************************************************************** | ||
| 2731 | $P_Chk_Delim proc ;AN000; | ||
| 2732 | push bx ;AN000; | ||
| 2733 | push cx ;AN000; | ||
| 2734 | mov psdata_seg:$P_Terminator,$P_Space ;AC034; Assume terminated by space | ||
| 2735 | and psdata_seg:$P_Flags2,0ffh-$P_Extra ;AC034; | ||
| 2736 | cmp al,$P_Space ;AN000; Space ? | ||
| 2737 | je $P_Chk_Delim_Exit ;AN000; | ||
| 2738 | |||
| 2739 | cmp al,$P_TAB ;AN000; TAB ? | ||
| 2740 | je $P_Chk_Delim_Exit ;AN000; | ||
| 2741 | |||
| 2742 | cmp al,$P_Comma ;AN000; Comma ? | ||
| 2743 | je $P_Chk_Delim_Exit0 ;AN000; | ||
| 2744 | |||
| 2745 | $P_Chk_Delim00: ;AN000; | ||
| 2746 | cmp al,$P_DBSP1 ;AN000; 1st byte of DBCS Space ? | ||
| 2747 | jne $P_Chk_Delim01 ;AN000; | ||
| 2748 | |||
| 2749 | cmp byte ptr [si],$P_DBSP2 ;AN000; 2nd byte of DBCS Space ? | ||
| 2750 | jne $P_Chk_Delim01 ;AN000; | ||
| 2751 | |||
| 2752 | mov al,$P_Space ;AN000; | ||
| 2753 | inc si ;AN000; make si point to next character | ||
| 2754 | cmp al,al ;AN000; Set ZF | ||
| 2755 | jmp short $P_Chk_Delim_Exit ;AN000; | ||
| 2756 | |||
| 2757 | $P_Chk_Delim01: ;AN000; | ||
| 2758 | cmp byte ptr es:[di].$P_Num_Extra,$P_I_Have_Delim ;AN000; delimiter character specified ? | ||
| 2759 | jb $P_Chk_Delim_Exit ;AN000; | ||
| 2760 | |||
| 2761 | xor cx,cx ;AN000; | ||
| 2762 | mov cl,es:[di].$P_Len_Extra_Delim ;AN000; get length of delimiter list | ||
| 2763 | or cx,cx ;AN000; No extra Delim character ? | ||
| 2764 | je $P_Chk_Delim_NZ ;AN000; | ||
| 2765 | |||
| 2766 | mov bx,$P_Len_PARMS-1 ;AN000; set bx to 1st extra delimiter | ||
| 2767 | $P_Chk_Delim_Loop: ;AN000; | ||
| 2768 | inc bx ;AN000; | ||
| 2769 | cmp al,es:[bx+di] ;AN000; Check extra Delim character | ||
| 2770 | je $P_Chk_Delim_Exit0 ;AN000; | ||
| 2771 | |||
| 2772 | loop $P_Chk_Delim_Loop ;AN000; examine all extra delimiter | ||
| 2773 | |||
| 2774 | $P_Chk_Delim_NZ: ;AN000; | ||
| 2775 | cmp al,$P_Space ;AN000; reset ZF | ||
| 2776 | $P_Chk_Delim_Exit: ;AN000; | ||
| 2777 | ;;;; jne $P_ChkDfin | ||
| 2778 | ;;;; mov psdata_seg:$P_Terminator,al ;AN034; | ||
| 2779 | $P_ChkDfin: ;AN000; | ||
| 2780 | pop cx ;AN000; | ||
| 2781 | pop bx ;AN000; | ||
| 2782 | ret ;AN000; | ||
| 2783 | |||
| 2784 | $P_Chk_Delim_Exit0: ;AN000; | ||
| 2785 | mov psdata_seg:$P_Terminator,al ;AC034; keep terminated delimiter | ||
| 2786 | test psdata_seg:$P_Flags2,$P_Equ ;AN027;AC034;; if terminating a key= | ||
| 2787 | jnz $P_No_Set_Extra ;AN027; then do not set the EXTRA bit | ||
| 2788 | |||
| 2789 | or psdata_seg:$P_Flags2,$P_Extra ;AC034; flag terminated extra delimiter or comma | ||
| 2790 | $P_No_Set_Extra: ;AN027; | ||
| 2791 | cmp al,al ;AN000; set ZF | ||
| 2792 | jmp short $P_Chk_Delim_Exit ;AN000; | ||
| 2793 | |||
| 2794 | $P_Chk_Delim endp ;AN000; | ||
| 2795 | PAGE ;AN000; | ||
| 2796 | ;*********************************************************************** | ||
| 2797 | ; $P_Chk_Switch; | ||
| 2798 | ; | ||
| 2799 | ; Function: Check if AL is the switch character not in first position of | ||
| 2800 | ; $P_STRING_BUF | ||
| 2801 | ; | ||
| 2802 | ; Input: AL = character code | ||
| 2803 | ; BX = current pointer within $P_String_Buf | ||
| 2804 | ; SI =>next char on command line (following the one in AL) | ||
| 2805 | ; | ||
| 2806 | ; Output: CF = 1 (set)if AL is switch character, and not in first | ||
| 2807 | ; position, and has no chance of being part of a date string, | ||
| 2808 | ; i.e. should be treated as a delimiter. | ||
| 2809 | |||
| 2810 | ; CF = 0 (reset, cleared) if AL is not a switch char, is in the first | ||
| 2811 | ; position, or is a slash but may be part of a date string, i.e. | ||
| 2812 | ; should not be treated as a delimiter. | ||
| 2813 | ; | ||
| 2814 | ; Vars: $P_Terminator(W) | ||
| 2815 | |||
| 2816 | ; Use: $P_0099 | ||
| 2817 | ;*********************************************************************** | ||
| 2818 | $P_Chk_Switch proc ;AN000; | ||
| 2819 | |||
| 2820 | ;AN020;; Function: Check if AL is the switch character from 2nd position of $P_STRING_BUF | ||
| 2821 | ;AN020;; Output: ZF = 1 if switch character | ||
| 2822 | ;AN020;; lea bp,$P_STRING_BUF ;AN000; | ||
| 2823 | ;AN020;; cmp bx,bp ;AN000; 1st position ? | ||
| 2824 | ;AN020;; je $P_Chk_S_Exit_1 ;AN000; | ||
| 2825 | ;AN020;; cmp al,$P_Switch ;AN000; | ||
| 2826 | ;AN020;; jmp short $P_Chk_S_Exit_0 ;AN000; | ||
| 2827 | ;AN020;;$P_Chk_S_Exit_1: ;AN000; | ||
| 2828 | ;AN020;; cmp al,$P_Switch ;AN000; (tm08) | ||
| 2829 | ;AN020;; jne $P_Nop ;AN000; (tm08) | ||
| 2830 | ;AN020;; or $P_Flags2,$P_SW ;AN000; (tm08) It could be valid switch | ||
| 2831 | ;AN020;;$P_Nop: ;AN000; (tm08) | ||
| 2832 | ;AN020;; inc bp ;AN000; | ||
| 2833 | ;AN020;; cmp bx,bp ;AN000; reset ZF | ||
| 2834 | ;AN020;;$P_Chk_S_Exit_0: ;AN000; | ||
| 2835 | ;AN020;; jne $P_Chk_S_Exit ;AN000; | ||
| 2836 | ;AN020;; mov $P_Terminator,al ;AN000; store switch character | ||
| 2837 | ;AN020;;$P_Chk_S_Exit: ;AN000; | ||
| 2838 | |||
| 2839 | LEA BP,psdata_seg:$P_String_Buf ;AN020;AC034; BP=OFFSET of $P_String_Buf even in group addressing | ||
| 2840 | ; .IF <BX NE BP> THEN ;AN020;IF not first char THEN | ||
| 2841 | cmp BX,BP ;AN000; | ||
| 2842 | je $P_STRUC_L2 ;AN000; | ||
| 2843 | |||
| 2844 | ; .IF <AL EQ $P_Switch> THEN ;AN020;otherwise see if a slash | ||
| 2845 | cmp AL,$P_Switch ;AN000; | ||
| 2846 | jne $P_STRUC_L5 ;AN000; | ||
| 2847 | |||
| 2848 | STC ;AN020;not in first position and is slash, now see if might be in date string | ||
| 2849 | IF DateSw ;AN020;caller looking for date, see if this may be part of one | ||
| 2850 | PUSH AX ;AN020;save input char | ||
| 2851 | MOV AL,PSDATA_SEG:[BX-1] ;AN026;AL=char before the current char | ||
| 2852 | CALL $P_0099 ;AN020;return carry set if not numeric | ||
| 2853 | ; .IF NC ;AND ;AN020;IF previous char numeric AND | ||
| 2854 | jc $P_STRUC_L7 ;AN000; | ||
| 2855 | |||
| 2856 | MOV AL,[SI] ;AN020;AL=char after the current char | ||
| 2857 | CALL $P_0099 ;AN020;return carry set if not numeric | ||
| 2858 | ;(deleted) .IF NC THEN ;AN020;IF next char numeric THEN could be a date | ||
| 2859 | ;(deleted) CLC ;AN020;reset CF so "/" not treated as a delimiter | ||
| 2860 | ;(deleted) .ENDIF ;AN026; | ||
| 2861 | ; .ENDIF ;AN020;ENDIF looks like date (number/number) | ||
| 2862 | $P_STRUC_L7: ;AN000; | ||
| 2863 | POP AX ;AN020;restore AL to input char | ||
| 2864 | ENDIF ;AN020;DateSw | ||
| 2865 | ; .ELSE ;AN020; | ||
| 2866 | jmp short $P_STRUC_L1 ;AN000; | ||
| 2867 | |||
| 2868 | $P_STRUC_L5: ;AN000; | ||
| 2869 | CLC ;AN020;not a slash | ||
| 2870 | ; .ENDIF ;AN020; | ||
| 2871 | ; .ELSE ;AN020;is first char in the buffer, ZF=0 | ||
| 2872 | jmp short $P_STRUC_L1 ;AN000; | ||
| 2873 | |||
| 2874 | $P_STRUC_L2: ;AN000; | ||
| 2875 | ; .IF <AL EQ $P_Switch> THEN ;AN020; | ||
| 2876 | cmp AL,$P_Switch ;AN000; | ||
| 2877 | jne $P_STRUC_L12 ;AN000; | ||
| 2878 | |||
| 2879 | OR psdata_seg:$P_Flags2,$P_SW ;AN020;AC034;;could be valid switch, first char and is slash | ||
| 2880 | ; .ENDIF ;AN020; | ||
| 2881 | $P_STRUC_L12: ;AN000; | ||
| 2882 | CLC ;AN020;CF=0 indicating first char | ||
| 2883 | ; .ENDIF ;AN020; | ||
| 2884 | $P_STRUC_L1: ;AN000; | ||
| 2885 | |||
| 2886 | ret ;AN000; | ||
| 2887 | $P_Chk_Switch endp ;AN000; | ||
| 2888 | PAGE ;AN000; | ||
| 2889 | ;************************************************************************** | ||
| 2890 | ; $P_Chk_DBCS: | ||
| 2891 | ; | ||
| 2892 | ; Function: Check if a specified byte is in ranges of the DBCS lead bytes | ||
| 2893 | ; | ||
| 2894 | ; Input: | ||
| 2895 | ; AL = Code to be examineed | ||
| 2896 | ; | ||
| 2897 | ; Output: | ||
| 2898 | ; If CF is on then a lead byte of DBCS | ||
| 2899 | ; | ||
| 2900 | ; Use: INT 21h w/AH=63 | ||
| 2901 | ; | ||
| 2902 | ; Vars: $P_DBCSEV_Seg(RW), $P_DBCSEV_Off(RW) | ||
| 2903 | ;*************************************************************************** | ||
| 2904 | $P_Chk_DBCS PROC ;AN000; | ||
| 2905 | ; | ||
| 2906 | PUSH DS ;AN000; | ||
| 2907 | PUSH SI ;AN000; | ||
| 2908 | PUSH bx ;AN000; (tm11) | ||
| 2909 | CMP psdata_seg:$P_DBCSEV_SEG,0 ;AC034; ALREADY SET ? | ||
| 2910 | JNE $P_DBCS00 ;AN000; | ||
| 2911 | |||
| 2912 | PUSH AX ;AN000; | ||
| 2913 | ; PUSH BX ;AN000; (tm11) | ||
| 2914 | PUSH ds ;AN000; (tm11) | ||
| 2915 | PUSH CX ;AN000; | ||
| 2916 | PUSH DX ;AN000; | ||
| 2917 | PUSH DI ;AN000; | ||
| 2918 | PUSH BP ;AN000; | ||
| 2919 | PUSH ES ;AN000; | ||
| 2920 | XOR SI,SI ;AN000; | ||
| 2921 | MOV DS,SI ;AN000; | ||
| 2922 | MOV AX,$P_DOS_GetEV ;AN000; GET DBCS EV CALL | ||
| 2923 | INT 21H ;AN000; | ||
| 2924 | |||
| 2925 | ; MOV AX,DS ;AN000; (tm11) | ||
| 2926 | ; OR AX,AX ;AN000; (tm11) | ||
| 2927 | MOV bx,DS ;AN000; (tm11) | ||
| 2928 | OR bx,bx ;AN000; (tm11) | ||
| 2929 | POP ES ;AN000; | ||
| 2930 | POP BP ;AN000; | ||
| 2931 | POP DI ;AN000; | ||
| 2932 | POP DX ;AN000; | ||
| 2933 | POP CX ;AN000; | ||
| 2934 | ; POP BX ;AN000; (tm11) | ||
| 2935 | POP ds ;AN000; (tm11) | ||
| 2936 | POP AX ;AN000; | ||
| 2937 | JE $P_NON_DBCS ;AN000; | ||
| 2938 | |||
| 2939 | $P_DBCS02: ;AN000; | ||
| 2940 | MOV psdata_seg:$P_DBCSEV_OFF,SI ;AC034; save EV offset | ||
| 2941 | ; MOV psdata_seg:$P_DBCSEV_SEG,DS ;AC034; save EV segment | ||
| 2942 | MOV psdata_seg:$P_DBCSEV_SEG,bx ;AC034; save EV segment (tm11) | ||
| 2943 | $P_DBCS00: ;AN000; | ||
| 2944 | MOV SI,psdata_seg:$P_DBCSEV_OFF ;AC034; load EV offset | ||
| 2945 | MOV DS,psdata_seg:$P_DBCSEV_SEG ;AC034; and segment | ||
| 2946 | |||
| 2947 | $P_DBCS_LOOP: ;AN000; | ||
| 2948 | CMP WORD PTR [SI],0 ;AN000; zero vector ? | ||
| 2949 | JE $P_NON_DBCS ;AN000; then exit | ||
| 2950 | |||
| 2951 | CMP AL,[SI] ;AN000; | ||
| 2952 | JB $P_DBCS01 ;AN000; Check if AL is in | ||
| 2953 | |||
| 2954 | CMP AL,[SI+BYTE] ;AN000; range of | ||
| 2955 | JA $P_DBCS01 ;AN000; the vector | ||
| 2956 | |||
| 2957 | STC ;AN000; if yes, indicate DBCS and exit | ||
| 2958 | JMP short $P_DBCS_EXIT ;AN000; | ||
| 2959 | |||
| 2960 | $P_DBCS01: ;AN000; | ||
| 2961 | INC SI ;AC035; add '2' to | ||
| 2962 | INC SI ;AC035; SI reg | ||
| 2963 | ;AN000; get next vector | ||
| 2964 | ;(changed ;AC035;) ADD SI,2 ;AN000; get next vector | ||
| 2965 | JMP short $P_DBCS_LOOP ;AN000; loop until zero vector found | ||
| 2966 | |||
| 2967 | $P_NON_DBCS: ;AN000; | ||
| 2968 | CLC ;AN000; indicate SBCS | ||
| 2969 | $P_DBCS_EXIT: ;AN000; | ||
| 2970 | POP bx ;AN000; (tm11) | ||
| 2971 | POP SI ;AN000; | ||
| 2972 | POP DS ;AN000; | ||
| 2973 | RET ;AN000; | ||
| 2974 | $P_Chk_DBCS ENDP ;AN000; | ||