diff options
Diffstat (limited to 'v4.0/src/CMD/COMMAND/TENV.ASM')
| -rw-r--r-- | v4.0/src/CMD/COMMAND/TENV.ASM | 633 |
1 files changed, 633 insertions, 0 deletions
diff --git a/v4.0/src/CMD/COMMAND/TENV.ASM b/v4.0/src/CMD/COMMAND/TENV.ASM new file mode 100644 index 0000000..e1d43f6 --- /dev/null +++ b/v4.0/src/CMD/COMMAND/TENV.ASM | |||
| @@ -0,0 +1,633 @@ | |||
| 1 | page 80,132 | ||
| 2 | ; SCCSID = @(#)tenv.asm 4.2 85/08/16 | ||
| 3 | ; SCCSID = @(#)tenv.asm 4.2 85/08/16 | ||
| 4 | TITLE Part6 COMMAND Transient routines. | ||
| 5 | |||
| 6 | ; Environment utilities and misc. routines | ||
| 7 | |||
| 8 | INCLUDE comsw.asm | ||
| 9 | |||
| 10 | .xlist | ||
| 11 | .xcref | ||
| 12 | INCLUDE DOSSYM.INC | ||
| 13 | INCLUDE comseg.asm | ||
| 14 | INCLUDE comequ.asm | ||
| 15 | INCLUDE DOSCNTRY.INC ;AN000; | ||
| 16 | .list | ||
| 17 | .cref | ||
| 18 | |||
| 19 | |||
| 20 | DATARES SEGMENT PUBLIC BYTE ;AC000; | ||
| 21 | EXTRN comdrv:byte | ||
| 22 | EXTRN comspec_end:word | ||
| 23 | EXTRN comspec_print:word | ||
| 24 | EXTRN cpdrv:byte | ||
| 25 | EXTRN dbcs_vector_addr:dword ;AN000; | ||
| 26 | EXTRN ENVIRSEG:WORD | ||
| 27 | EXTRN fucase_addr:word ;AC000; | ||
| 28 | EXTRN RESTDIR:BYTE | ||
| 29 | DATARES ENDS | ||
| 30 | |||
| 31 | TRANDATA SEGMENT PUBLIC BYTE ;AC000; | ||
| 32 | EXTRN arg_buf_ptr:word | ||
| 33 | EXTRN comspec:byte | ||
| 34 | EXTRN comspec_flag:byte | ||
| 35 | EXTRN comspecstr:byte | ||
| 36 | EXTRN ENVERR_PTR:WORD | ||
| 37 | EXTRN PATH_TEXT:byte | ||
| 38 | EXTRN PROMPT_TEXT:byte | ||
| 39 | EXTRN SYNTMES_PTR:WORD | ||
| 40 | TRANDATA ENDS | ||
| 41 | |||
| 42 | TRANSPACE SEGMENT PUBLIC BYTE ;AC000; | ||
| 43 | EXTRN Arg_Buf:BYTE | ||
| 44 | EXTRN RESSEG:WORD | ||
| 45 | EXTRN USERDIR1:BYTE | ||
| 46 | TRANSPACE ENDS | ||
| 47 | |||
| 48 | TRANCODE SEGMENT PUBLIC byte | ||
| 49 | |||
| 50 | ASSUME CS:TRANGROUP,DS:NOTHING,ES:NOTHING,SS:NOTHING | ||
| 51 | |||
| 52 | EXTRN cerror:near | ||
| 53 | |||
| 54 | PUBLIC add_name_to_environment | ||
| 55 | PUBLIC add_prompt | ||
| 56 | PUBLIC delete_path | ||
| 57 | PUBLIC find_name_in_environment | ||
| 58 | PUBLIC find_path | ||
| 59 | PUBLIC find_prompt | ||
| 60 | PUBLIC move_name | ||
| 61 | PUBLIC restudir | ||
| 62 | PUBLIC restudir1 | ||
| 63 | PUBLIC scan_double_null | ||
| 64 | PUBLIC scasb2 | ||
| 65 | PUBLIC store_char | ||
| 66 | PUBLIC Testkanj ;AN000; 3/3/KK | ||
| 67 | PUBLIC upconv | ||
| 68 | |||
| 69 | BREAK <Environment utilities> | ||
| 70 | ASSUME DS:TRANGROUP | ||
| 71 | |||
| 72 | break Prompt command | ||
| 73 | assume ds:trangroup,es:trangroup | ||
| 74 | |||
| 75 | ADD_PROMPT: | ||
| 76 | CALL DELETE_PROMPT ; DELETE ANY EXISTING PROMPT | ||
| 77 | CALL SCAN_DOUBLE_NULL | ||
| 78 | |||
| 79 | ADD_PROMPT2: | ||
| 80 | PUSH SI | ||
| 81 | CALL GETARG | ||
| 82 | POP SI | ||
| 83 | retz ; PRE SCAN FOR ARGUMENTS | ||
| 84 | CALL MOVE_NAME ; MOVE IN NAME | ||
| 85 | CALL GETARG | ||
| 86 | PUSH SI | ||
| 87 | JMP SHORT ADD_NAME | ||
| 88 | |||
| 89 | |||
| 90 | break The SET command | ||
| 91 | assume ds:trangroup,es:trangroup | ||
| 92 | |||
| 93 | ; | ||
| 94 | ; Input: DS:SI points to a CR terminated string | ||
| 95 | ; Output: carry flag is set if no room | ||
| 96 | ; otherwise name is added to environment | ||
| 97 | ; | ||
| 98 | |||
| 99 | DISP_ENVj: | ||
| 100 | jmp DISP_ENV | ||
| 101 | |||
| 102 | ADD_NAME_TO_ENVIRONMENT: | ||
| 103 | CALL GETARG | ||
| 104 | JZ DISP_ENVj | ||
| 105 | ; | ||
| 106 | ; check if line contains exactly one equals sign | ||
| 107 | ; | ||
| 108 | XOR BX,BX ;= COUNT IS 0 | ||
| 109 | PUSH SI ;SAVE POINTER TO BEGINNING OF LINE | ||
| 110 | |||
| 111 | EQLP: | ||
| 112 | LODSB ;GET A CHAR | ||
| 113 | CMP AL,13 ;IF CR WE'RE ALL DONE | ||
| 114 | JZ QUEQ | ||
| 115 | CMP AL,'=' ;LOOK FOR = SIGN | ||
| 116 | JNZ EQLP ;NOT THERE, GET NEXT CHAR | ||
| 117 | INC BL ;OTHERWISE INCREMENT EQ COUNT | ||
| 118 | CMP BYTE PTR [SI],13 ;LOOK FOR CR FOLLOWING = SIGN | ||
| 119 | JNZ EQLP | ||
| 120 | INC BH ;SET BH=1 MEANS NO PARAMETERS | ||
| 121 | JMP EQLP ;AND LOOK FOR MORE | ||
| 122 | |||
| 123 | QUEQ: | ||
| 124 | POP SI ;RESTORE BEGINNING OF LINE | ||
| 125 | DEC BL ;ZERO FLAG MEANS ONLY ONE EQ | ||
| 126 | JZ ONEQ ;GOOD LINE | ||
| 127 | MOV DX,OFFSET TRANGROUP:SYNTMES_ptr | ||
| 128 | JMP CERROR | ||
| 129 | |||
| 130 | ONEQ: | ||
| 131 | PUSH BX | ||
| 132 | CALL DELETE_NAME_IN_ENVIRONMENT | ||
| 133 | POP BX | ||
| 134 | DEC BH | ||
| 135 | retz | ||
| 136 | |||
| 137 | CALL SCAN_DOUBLE_NULL | ||
| 138 | mov bx,di ; Save ptr to beginning of env var name | ||
| 139 | CALL MOVE_NAME | ||
| 140 | push si | ||
| 141 | xchg bx,di ; Switch ptrs to beginning and end of | ||
| 142 | ; env var name | ||
| 143 | ; | ||
| 144 | ; We want to special-case COMSPEC. This is to reduce the amount of code | ||
| 145 | ; necessary in the resident for re-reading the transient. Let's look for | ||
| 146 | ; COMSPEC= | ||
| 147 | ; | ||
| 148 | mov si,offset trangroup:comspecstr ; Load ptr to string "COMSPEC" | ||
| 149 | mov cx,4 ; If the new env var is comspec, set | ||
| 150 | repz cmpsw ; the comspec_flag | ||
| 151 | ; | ||
| 152 | ; Zero set => exact match | ||
| 153 | ; | ||
| 154 | jnz not_comspec | ||
| 155 | mov comspec_flag,1 | ||
| 156 | |||
| 157 | not_comspec: | ||
| 158 | mov di,bx ; Load ptr to end of env var name | ||
| 159 | |||
| 160 | ADD_NAME: ; Add the value of the new env var | ||
| 161 | pop si ; to the environment. | ||
| 162 | push si | ||
| 163 | |||
| 164 | add_name1: | ||
| 165 | LODSB | ||
| 166 | CMP AL,13 | ||
| 167 | jz add_name_ret | ||
| 168 | CALL STORE_CHAR | ||
| 169 | JMP ADD_NAME1 | ||
| 170 | |||
| 171 | add_name_ret: | ||
| 172 | pop si | ||
| 173 | cmp comspec_flag,0 ; If the new env var is comspec, | ||
| 174 | retz ; copy the value into the | ||
| 175 | ; | ||
| 176 | ; We have changed the COMSPEC variable. We need to update the resident | ||
| 177 | ; pieces necessary to reread in the info. First, skip all delimiters | ||
| 178 | ; | ||
| 179 | invoke ScanOff | ||
| 180 | mov es,[resseg] ; comspec var in the resident | ||
| 181 | assume es:resgroup | ||
| 182 | ; | ||
| 183 | ; Make sure that the printer knows where the beginning of the string is | ||
| 184 | ; | ||
| 185 | mov di,offset resgroup:comspec | ||
| 186 | mov bx,di | ||
| 187 | ; | ||
| 188 | ; Generate drive letter for display | ||
| 189 | ; | ||
| 190 | xor ax,ax ;g assume no drive first | ||
| 191 | mov comdrv,al ;g | ||
| 192 | push ax ;AN000; 3/3/KK | ||
| 193 | mov al,[si] ;AN000; 3/3/KK | ||
| 194 | call testkanj ;AN000; 3/3/KK | ||
| 195 | pop ax ;AN000; 3/3/KK | ||
| 196 | jnz GotDrive | ||
| 197 | cmp byte ptr [si+1],':' ; drive specified? | ||
| 198 | jnz GotDrive | ||
| 199 | mov al,[si] ; get his specified drive | ||
| 200 | call UpConv ; convert to uppercase | ||
| 201 | sub al,'A' ; convert to 0-based | ||
| 202 | add di,2 | ||
| 203 | inc al ; convert to 1-based number | ||
| 204 | mov comdrv,al | ||
| 205 | ; | ||
| 206 | ; Stick the drive letter in the prompt message. Nothing special needs to be | ||
| 207 | ; done here.. | ||
| 208 | ; | ||
| 209 | |||
| 210 | add al,'A'-1 | ||
| 211 | |||
| 212 | GotDrive: ;g | ||
| 213 | mov comspec_print,di ;g point to beginning of name after drive | ||
| 214 | mov es:cpdrv,al | ||
| 215 | ; | ||
| 216 | ; Copy chars until delim | ||
| 217 | ; | ||
| 218 | |||
| 219 | mov di,bx | ||
| 220 | |||
| 221 | copy_comspec: | ||
| 222 | lodsb | ||
| 223 | invoke Delim | ||
| 224 | jz CopyDone | ||
| 225 | cmp al,13 | ||
| 226 | jz CopyDone | ||
| 227 | stosb | ||
| 228 | jmp short copy_comspec | ||
| 229 | |||
| 230 | CopyDone: | ||
| 231 | xor al,al ; Null terminate the string and quit | ||
| 232 | stosb | ||
| 233 | mov comspec_flag,0 | ||
| 234 | dec di | ||
| 235 | mov comspec_end,di | ||
| 236 | |||
| 237 | ret | ||
| 238 | |||
| 239 | DISP_ENV: | ||
| 240 | MOV DS,[RESSEG] | ||
| 241 | ASSUME DS:RESGROUP | ||
| 242 | MOV DS,[ENVIRSEG] | ||
| 243 | ASSUME DS:NOTHING | ||
| 244 | XOR SI,SI | ||
| 245 | |||
| 246 | PENVLP: | ||
| 247 | CMP BYTE PTR [SI],0 | ||
| 248 | retz | ||
| 249 | mov di,offset trangroup:arg_buf | ||
| 250 | |||
| 251 | PENVLP2: | ||
| 252 | LODSB | ||
| 253 | stosb | ||
| 254 | OR AL,AL | ||
| 255 | JNZ PENVLP2 | ||
| 256 | mov dx,offset trangroup:arg_buf_ptr | ||
| 257 | push ds | ||
| 258 | push es | ||
| 259 | pop ds | ||
| 260 | invoke printf_crlf | ||
| 261 | pop ds | ||
| 262 | JMP PENVLP | ||
| 263 | |||
| 264 | ASSUME DS:TRANGROUP | ||
| 265 | |||
| 266 | DELETE_PATH: | ||
| 267 | MOV SI,OFFSET TRANGROUP:PATH_TEXT | ||
| 268 | JMP SHORT DELETE_NAME_IN_environment | ||
| 269 | |||
| 270 | DELETE_PROMPT: | ||
| 271 | MOV SI,OFFSET TRANGROUP:PROMPT_TEXT | ||
| 272 | |||
| 273 | DELETE_NAME_IN_environment: | ||
| 274 | ; | ||
| 275 | ; Input: DS:SI points to a "=" terminated string | ||
| 276 | ; Output: carry flag is set if name not found | ||
| 277 | ; otherwise name is deleted | ||
| 278 | ; | ||
| 279 | PUSH SI | ||
| 280 | PUSH DS | ||
| 281 | CALL FIND ; ES:DI POINTS TO NAME | ||
| 282 | JC DEL1 | ||
| 283 | MOV SI,DI ; SAVE IT | ||
| 284 | CALL SCASB2 ; SCAN FOR THE NUL | ||
| 285 | XCHG SI,DI | ||
| 286 | CALL GETENVSIZ | ||
| 287 | SUB CX,SI | ||
| 288 | PUSH ES | ||
| 289 | POP DS ; ES:DI POINTS TO NAME, DS:SI POINTS TO NEXT NAME | ||
| 290 | REP MOVSB ; DELETE THE NAME | ||
| 291 | |||
| 292 | DEL1: | ||
| 293 | POP DS | ||
| 294 | POP SI | ||
| 295 | return | ||
| 296 | |||
| 297 | FIND_PATH: | ||
| 298 | MOV SI,OFFSET TRANGROUP:PATH_TEXT | ||
| 299 | JMP SHORT FIND_NAME_IN_environment | ||
| 300 | |||
| 301 | FIND_PROMPT: | ||
| 302 | MOV SI,OFFSET TRANGROUP:PROMPT_TEXT | ||
| 303 | |||
| 304 | FIND_NAME_IN_environment: | ||
| 305 | ; | ||
| 306 | ; Input: DS:SI points to a "=" terminated string | ||
| 307 | ; Output: ES:DI points to the arguments in the environment | ||
| 308 | ; zero is set if name not found | ||
| 309 | ; carry flag is set if name not valid format | ||
| 310 | ; | ||
| 311 | CALL FIND ; FIND THE NAME | ||
| 312 | retc ; CARRY MEANS NOT FOUND | ||
| 313 | JMP SCASB1 ; SCAN FOR = SIGN | ||
| 314 | ; | ||
| 315 | ; On return of FIND1, ES:DI points to beginning of name | ||
| 316 | ; | ||
| 317 | FIND: | ||
| 318 | CLD | ||
| 319 | CALL COUNT0 ; CX = LENGTH OF NAME | ||
| 320 | MOV ES,[RESSEG] | ||
| 321 | ASSUME ES:RESGROUP | ||
| 322 | MOV ES,[ENVIRSEG] | ||
| 323 | ASSUME ES:NOTHING | ||
| 324 | XOR DI,DI | ||
| 325 | |||
| 326 | FIND1: | ||
| 327 | PUSH CX | ||
| 328 | PUSH SI | ||
| 329 | PUSH DI | ||
| 330 | |||
| 331 | FIND11: | ||
| 332 | LODSB | ||
| 333 | CALL TESTKANJ | ||
| 334 | JZ NOTKANJ3 | ||
| 335 | DEC SI | ||
| 336 | LODSW | ||
| 337 | INC DI | ||
| 338 | INC DI | ||
| 339 | CMP AX,ES:[DI-2] | ||
| 340 | JNZ FIND12 | ||
| 341 | DEC CX | ||
| 342 | LOOP FIND11 | ||
| 343 | JMP SHORT FIND12 | ||
| 344 | |||
| 345 | NOTKANJ3: | ||
| 346 | CALL UPCONV | ||
| 347 | INC DI | ||
| 348 | CMP AL,ES:[DI-1] | ||
| 349 | JNZ FIND12 | ||
| 350 | LOOP FIND11 | ||
| 351 | |||
| 352 | FIND12: | ||
| 353 | POP DI | ||
| 354 | POP SI | ||
| 355 | POP CX | ||
| 356 | retz | ||
| 357 | PUSH CX | ||
| 358 | CALL SCASB2 ; SCAN FOR A NUL | ||
| 359 | POP CX | ||
| 360 | CMP BYTE PTR ES:[DI],0 | ||
| 361 | JNZ FIND1 | ||
| 362 | STC ; INDICATE NOT FOUND | ||
| 363 | return | ||
| 364 | |||
| 365 | COUNT0: | ||
| 366 | PUSH DS | ||
| 367 | POP ES | ||
| 368 | MOV DI,SI | ||
| 369 | |||
| 370 | COUNT1: | ||
| 371 | PUSH DI ; COUNT NUMBER OF CHARS UNTIL "=" | ||
| 372 | CALL SCASB1 | ||
| 373 | JMP SHORT COUNTX | ||
| 374 | |||
| 375 | COUNT2: | ||
| 376 | PUSH DI ; COUNT NUMBER OF CHARS UNTIL NUL | ||
| 377 | CALL SCASB2 | ||
| 378 | |||
| 379 | COUNTX: | ||
| 380 | POP CX | ||
| 381 | SUB DI,CX | ||
| 382 | XCHG DI,CX | ||
| 383 | return | ||
| 384 | |||
| 385 | MOVE_NAME: | ||
| 386 | CMP BYTE PTR DS:[SI],13 | ||
| 387 | retz | ||
| 388 | LODSB | ||
| 389 | |||
| 390 | ;;;; IF KANJI 3/3/KK | ||
| 391 | CALL TESTKANJ | ||
| 392 | JZ NOTKANJ1 | ||
| 393 | CALL STORE_CHAR | ||
| 394 | LODSB | ||
| 395 | CALL STORE_CHAR | ||
| 396 | JMP SHORT MOVE_NAME | ||
| 397 | |||
| 398 | NOTKANJ1: | ||
| 399 | ;;;; ENDIF 3/3/KK | ||
| 400 | |||
| 401 | CALL UPCONV | ||
| 402 | CALL STORE_CHAR | ||
| 403 | CMP AL,'=' | ||
| 404 | JNZ MOVE_NAME | ||
| 405 | return | ||
| 406 | |||
| 407 | GETARG: | ||
| 408 | MOV SI,80H | ||
| 409 | LODSB | ||
| 410 | OR AL,AL | ||
| 411 | retz | ||
| 412 | invoke SCANOFF | ||
| 413 | CMP AL,13 | ||
| 414 | return | ||
| 415 | |||
| 416 | ; | ||
| 417 | ; Point ES:DI to the final NULL string. Note that in an empty environment, | ||
| 418 | ; there is NO double NULL, merely a string that is empty. | ||
| 419 | ; | ||
| 420 | SCAN_DOUBLE_NULL: | ||
| 421 | MOV ES,[RESSEG] | ||
| 422 | ASSUME ES:RESGROUP | ||
| 423 | MOV ES,[ENVIRSEG] | ||
| 424 | ASSUME ES:NOTHING | ||
| 425 | XOR DI,DI | ||
| 426 | ; | ||
| 427 | ; Top cycle-point. If the string here is empty, then we are done | ||
| 428 | ; | ||
| 429 | SDN1: | ||
| 430 | cmp byte ptr es:[di],0 ; nul string? | ||
| 431 | retz ; yep, all done | ||
| 432 | CALL SCASB2 | ||
| 433 | JMP SDN1 | ||
| 434 | |||
| 435 | SCASB1: | ||
| 436 | MOV AL,'=' ; SCAN FOR AN = | ||
| 437 | JMP SHORT SCASBX | ||
| 438 | SCASB2: | ||
| 439 | XOR AL,AL ; SCAN FOR A NUL | ||
| 440 | SCASBX: | ||
| 441 | MOV CX,100H | ||
| 442 | REPNZ SCASB | ||
| 443 | return | ||
| 444 | |||
| 445 | TESTKANJ: | ||
| 446 | push ds ;AN000; 3/3/KK | ||
| 447 | push si ;AN000; 3/3/KK | ||
| 448 | push ax ;AN000; 3/3/KK | ||
| 449 | mov ds,cs:[resseg] ;AN000; Get resident segment | ||
| 450 | assume ds:resgroup ;AN000; | ||
| 451 | lds si,dbcs_vector_addr ;AN000; get DBCS vector | ||
| 452 | ktlop: ;AN000; 3/3/KK | ||
| 453 | cmp word ptr ds:[si],0 ;AN000; end of Table 3/3/KK | ||
| 454 | je notlead ;AN000; 3/3/KK | ||
| 455 | pop ax ;AN000; 3/3/KK | ||
| 456 | push ax ;AN000; 3/3/KK | ||
| 457 | cmp al, byte ptr ds:[si] ;AN000; 3/3/KK | ||
| 458 | jb notlead ;AN000; 3/3/KK | ||
| 459 | inc si ;AN000; 3/3/KK | ||
| 460 | cmp al, byte ptr ds:[si] ;AN000; 3/3/KK | ||
| 461 | jbe islead ;AN000; 3/3/KK | ||
| 462 | inc si ;AN000; 3/3/KK | ||
| 463 | jmp short ktlop ;AN000; try another range ; 3/3/KK | ||
| 464 | Notlead: ;AN000; 3/3/KK | ||
| 465 | xor ax,ax ;AN000; set zero 3/3/KK | ||
| 466 | jmp short ktret ;AN000; 3/3/KK | ||
| 467 | Islead: ;AN000; 3/3/KK | ||
| 468 | xor ax,ax ;AN000; reset zero 3/3/KK | ||
| 469 | inc ax ;AN000; 3/3/KK | ||
| 470 | ktret: ;AN000; 3/3/KK | ||
| 471 | pop ax ;AN000; 3/3/KK | ||
| 472 | pop si ;AN000; 3/3/KK | ||
| 473 | pop ds ;AN000; 3/3/KK | ||
| 474 | return ;AN000; 3/3/KK | ||
| 475 | ;------------------------------------- ;3/3/KK | ||
| 476 | |||
| 477 | |||
| 478 | ; **************************************************************** | ||
| 479 | ; * | ||
| 480 | ; * ROUTINE: UPCONV (ADDED BY EMG 4.00) | ||
| 481 | ; * | ||
| 482 | ; * FUNCTION: This routine returns the upper case equivalent of | ||
| 483 | ; * the character in AL from the file upper case table | ||
| 484 | ; * in DOS if character if above ascii 128, else | ||
| 485 | ; * subtracts 20H if between "a" and "z". | ||
| 486 | ; * | ||
| 487 | ; * INPUT: AL char to be upper cased | ||
| 488 | ; * FUCASE_ADDR set to the file upper case table | ||
| 489 | ; * | ||
| 490 | ; * OUTPUT: AL upper cased character | ||
| 491 | ; * | ||
| 492 | ; **************************************************************** | ||
| 493 | |||
| 494 | assume ds:trangroup ;AN000; | ||
| 495 | |||
| 496 | upconv proc near ;AN000; | ||
| 497 | |||
| 498 | cmp al,80h ;AN000; see if char is > ascii 128 | ||
| 499 | jb oth_fucase ;AN000; no - upper case math | ||
| 500 | sub al,80h ;AN000; only upper 128 chars in table | ||
| 501 | push ds ;AN000; | ||
| 502 | push bx ;AN000; | ||
| 503 | mov ds,[resseg] ;AN000; get resident data segment | ||
| 504 | assume ds:resgroup ;AN000; | ||
| 505 | lds bx,dword ptr fucase_addr+1 ;AN000; get table address | ||
| 506 | add bx,2 ;AN000; skip over first word | ||
| 507 | xlat ds:byte ptr [bx] ;AN000; convert to upper case | ||
| 508 | pop bx ;AN000; | ||
| 509 | pop ds ;AN000; | ||
| 510 | assume ds:trangroup ;AN000; | ||
| 511 | jmp short upconv_end ;AN000; we finished - exit | ||
| 512 | |||
| 513 | oth_fucase: ;AN000; | ||
| 514 | cmp al,small_a ;AC000; if between "a" and "z", | ||
| 515 | jb upconv_end ;AC000; subtract 20h to get | ||
| 516 | cmp al,small_z ;AC000; upper case equivalent. | ||
| 517 | ja upconv_end ;AC000; | ||
| 518 | sub al,20h ;AC000; Change lower-case to upper | ||
| 519 | |||
| 520 | upconv_end: ;AN000; | ||
| 521 | ret | ||
| 522 | |||
| 523 | upconv endp ;AN000; | ||
| 524 | |||
| 525 | |||
| 526 | ; | ||
| 527 | ; STORE A CHAR IN environment, GROWING IT IF NECESSARY | ||
| 528 | ; | ||
| 529 | STORE_CHAR: | ||
| 530 | PUSH CX | ||
| 531 | PUSH BX | ||
| 532 | PUSH ES ;AN056; | ||
| 533 | PUSH DS ;AN056; Save local DS | ||
| 534 | MOV DS,[RESSEG] ;AN056; Get resident segment | ||
| 535 | ASSUME DS:RESGROUP ;AN056; | ||
| 536 | MOV ES,[ENVIRSEG] ;AN056; Get environment segment | ||
| 537 | ASSUME ES:NOTHING ;AN056; | ||
| 538 | POP DS ;AN056; Get local segment back | ||
| 539 | ASSUME DS:TRANGROUP ;AN056; | ||
| 540 | CALL GETENVSIZ | ||
| 541 | MOV BX,CX | ||
| 542 | SUB BX,2 ; SAVE ROOM FOR DOUBLE NULL | ||
| 543 | CMP DI,BX | ||
| 544 | JB STORE1 | ||
| 545 | |||
| 546 | PUSH AX | ||
| 547 | PUSH CX | ||
| 548 | PUSH BX ; Save Size of environment | ||
| 549 | invoke FREE_TPA | ||
| 550 | POP BX | ||
| 551 | ADD BX,2 ; Recover true environment size | ||
| 552 | |||
| 553 | CMP BX, 8000H ; Don't let environment grow > 32K | ||
| 554 | JB ENVSIZ_OK | ||
| 555 | BAD_ENV_SIZE: ;AN056; | ||
| 556 | STC | ||
| 557 | JMP ENVNOSET | ||
| 558 | ENVSIZ_OK: | ||
| 559 | |||
| 560 | MOV CL,4 | ||
| 561 | SHR BX,CL ; Convert back to paragraphs | ||
| 562 | INC BX ; Try to grow environment by one para | ||
| 563 | MOV CX,ES ;AN056; Get environment segment | ||
| 564 | ADD CX,BX ;AN056; Add in size of environment | ||
| 565 | ADD CX,020H ;AN056; Add in some TPA | ||
| 566 | MOV AX,CS ;AN056; Get the transient segment | ||
| 567 | CMP CX,AX ;AN056; Are we hitting the transient? | ||
| 568 | JNB BAD_ENV_SIZE ;AN056; Yes - don't do it!!! | ||
| 569 | MOV AH,SETBLOCK | ||
| 570 | INT int_command | ||
| 571 | ENVNOSET: | ||
| 572 | PUSHF | ||
| 573 | PUSH ES | ||
| 574 | MOV ES,[RESSEG] | ||
| 575 | invoke ALLOC_TPA | ||
| 576 | POP ES | ||
| 577 | POPF | ||
| 578 | POP CX | ||
| 579 | POP AX | ||
| 580 | JNC STORE1 | ||
| 581 | POP ES ;AN056; | ||
| 582 | MOV DX,OFFSET TRANGROUP:ENVERR_ptr | ||
| 583 | JMP CERROR | ||
| 584 | STORE1: | ||
| 585 | STOSB | ||
| 586 | MOV WORD PTR ES:[DI],0 ; NULL IS AT END | ||
| 587 | POP ES ;AN056; | ||
| 588 | POP BX | ||
| 589 | POP CX | ||
| 590 | return | ||
| 591 | |||
| 592 | GETENVSIZ: | ||
| 593 | ;Get size of environment in bytes, rounded up to paragraph boundry | ||
| 594 | ;ES has environment segment | ||
| 595 | ;Size returned in CX, all other registers preserved | ||
| 596 | |||
| 597 | PUSH ES | ||
| 598 | PUSH AX | ||
| 599 | MOV AX,ES | ||
| 600 | DEC AX ;Point at arena | ||
| 601 | MOV ES,AX | ||
| 602 | MOV AX,ES:[arena_size] | ||
| 603 | MOV CL,4 | ||
| 604 | SHL AX,CL ;Convert to bytes | ||
| 605 | MOV CX,AX | ||
| 606 | POP AX | ||
| 607 | POP ES | ||
| 608 | return | ||
| 609 | |||
| 610 | |||
| 611 | ASSUME DS:TRANGROUP | ||
| 612 | |||
| 613 | |||
| 614 | RESTUDIR1: | ||
| 615 | PUSH DS | ||
| 616 | MOV DS,[RESSEG] | ||
| 617 | ASSUME DS:RESGROUP | ||
| 618 | CMP [RESTDIR],0 | ||
| 619 | POP DS | ||
| 620 | ASSUME DS:TRANGROUP | ||
| 621 | retz | ||
| 622 | |||
| 623 | RESTUDIR: | ||
| 624 | MOV DX,OFFSET TRANGROUP:USERDIR1 | ||
| 625 | MOV AH,CHDIR | ||
| 626 | INT int_command ; Restore users DIR | ||
| 627 | XOR AL,AL | ||
| 628 | invoke SETREST | ||
| 629 | RET56: | ||
| 630 | return | ||
| 631 | |||
| 632 | trancode ends | ||
| 633 | end | ||