diff options
Diffstat (limited to 'v4.0/src/CMD/COMMAND/COMMAND2.ASM')
| -rw-r--r-- | v4.0/src/CMD/COMMAND/COMMAND2.ASM | 619 |
1 files changed, 619 insertions, 0 deletions
diff --git a/v4.0/src/CMD/COMMAND/COMMAND2.ASM b/v4.0/src/CMD/COMMAND/COMMAND2.ASM new file mode 100644 index 0000000..0f6c5b5 --- /dev/null +++ b/v4.0/src/CMD/COMMAND/COMMAND2.ASM | |||
| @@ -0,0 +1,619 @@ | |||
| 1 | page 80,132 | ||
| 2 | ; SCCSID = @(#)command2.asm 4.3 85/10/16 | ||
| 3 | ; SCCSID = @(#)command2.asm 4.3 85/10/16 | ||
| 4 | TITLE COMMAND2 - resident code for COMMAND.COM part II | ||
| 5 | NAME COMMAND2 | ||
| 6 | .XCREF | ||
| 7 | .XLIST | ||
| 8 | INCLUDE DOSSYM.INC | ||
| 9 | INCLUDE comsw.asm | ||
| 10 | INCLUDE comequ.asm | ||
| 11 | INCLUDE resmsg.equ ;AN000; | ||
| 12 | .LIST | ||
| 13 | .CREF | ||
| 14 | |||
| 15 | tokenized = FALSE | ||
| 16 | |||
| 17 | CODERES SEGMENT PUBLIC BYTE ;AC000; | ||
| 18 | CODERES ENDS | ||
| 19 | |||
| 20 | DATARES SEGMENT PUBLIC BYTE | ||
| 21 | EXTRN append_state:word ;AN020; | ||
| 22 | EXTRN append_flag:byte ;AN020; | ||
| 23 | EXTRN COMDRV:BYTE | ||
| 24 | EXTRN comprmt1_block:byte ;AN000; | ||
| 25 | EXTRN comprmt1_subst:byte ;AN000; | ||
| 26 | EXTRN COMSPEC:BYTE | ||
| 27 | EXTRN cpdrv:byte | ||
| 28 | EXTRN envirseg:word | ||
| 29 | EXTRN EXTCOM:BYTE | ||
| 30 | EXTRN HANDLE01:WORD | ||
| 31 | EXTRN InitFlag:BYTE | ||
| 32 | EXTRN INT_2E_RET:DWORD ;AC000; | ||
| 33 | EXTRN IO_SAVE:WORD | ||
| 34 | EXTRN LOADING:BYTE | ||
| 35 | EXTRN LTPA:WORD | ||
| 36 | EXTRN MEMSIZ:WORD | ||
| 37 | EXTRN number_subst:byte ;AN000; | ||
| 38 | EXTRN OldTerm:DWORD ;AC000; | ||
| 39 | EXTRN PARENT:WORD ;AC000; | ||
| 40 | EXTRN PERMCOM:BYTE | ||
| 41 | EXTRN RDIRCHAR:BYTE | ||
| 42 | EXTRN RES_TPA:WORD | ||
| 43 | EXTRN RETCODE:WORD | ||
| 44 | EXTRN rsrc_xa_seg:word ;AN030; | ||
| 45 | EXTRN RSWITCHAR:BYTE | ||
| 46 | EXTRN SAVE_PDB:WORD | ||
| 47 | EXTRN SINGLECOM:WORD | ||
| 48 | EXTRN SUM:WORD | ||
| 49 | EXTRN TRANS:WORD | ||
| 50 | EXTRN TranVarEnd:BYTE | ||
| 51 | EXTRN TRANVARS:BYTE | ||
| 52 | EXTRN TRNSEG:WORD | ||
| 53 | EXTRN VERVAL:WORD | ||
| 54 | DATARES ENDS | ||
| 55 | |||
| 56 | BATARENA SEGMENT PUBLIC PARA ;AC000; | ||
| 57 | BATARENA ENDS | ||
| 58 | |||
| 59 | BATSEG SEGMENT PUBLIC PARA ;AC000; | ||
| 60 | BATSEG ENDS | ||
| 61 | |||
| 62 | ENVARENA SEGMENT PUBLIC PARA ;AC000; | ||
| 63 | ENVARENA ENDS | ||
| 64 | |||
| 65 | ENVIRONMENT SEGMENT PUBLIC PARA ; Default COMMAND environment | ||
| 66 | ENVIRONMENT ENDS | ||
| 67 | |||
| 68 | INIT SEGMENT PUBLIC PARA | ||
| 69 | EXTRN envsiz:word | ||
| 70 | EXTRN oldenv:word | ||
| 71 | EXTRN resetenv:byte | ||
| 72 | EXTRN usedenv:word | ||
| 73 | INIT ENDS | ||
| 74 | |||
| 75 | TAIL SEGMENT PUBLIC PARA | ||
| 76 | TAIL ENDS | ||
| 77 | |||
| 78 | TRANCODE SEGMENT PUBLIC PARA | ||
| 79 | TRANCODE ENDS | ||
| 80 | |||
| 81 | TRANDATA SEGMENT PUBLIC BYTE | ||
| 82 | EXTRN TRANDATAEND:BYTE | ||
| 83 | TRANDATA ENDS | ||
| 84 | |||
| 85 | TRANSPACE SEGMENT PUBLIC BYTE | ||
| 86 | EXTRN TRANSPACEEND:BYTE | ||
| 87 | EXTRN HEADCALL:DWORD | ||
| 88 | TRANSPACE ENDS | ||
| 89 | |||
| 90 | TRANTAIL SEGMENT PUBLIC PARA | ||
| 91 | TRANTAIL ENDS | ||
| 92 | |||
| 93 | RESGROUP GROUP CODERES,DATARES,BATARENA,BATSEG,ENVARENA,ENVIRONMENT,INIT,TAIL | ||
| 94 | TRANGROUP GROUP TRANCODE,TRANDATA,TRANSPACE,TRANTAIL | ||
| 95 | |||
| 96 | ; START OF RESIDENT PORTION | ||
| 97 | |||
| 98 | CODERES SEGMENT PUBLIC BYTE ;AC000; | ||
| 99 | |||
| 100 | PUBLIC CHKSUM | ||
| 101 | PUBLIC endinit | ||
| 102 | PUBLIC GETCOMDSK2 | ||
| 103 | PUBLIC INT_2E | ||
| 104 | PUBLIC LOADCOM | ||
| 105 | PUBLIC LODCOM | ||
| 106 | PUBLIC LODCOM1 | ||
| 107 | PUBLIC RESTHAND | ||
| 108 | PUBLIC SAVHAND | ||
| 109 | PUBLIC SETVECT | ||
| 110 | PUBLIC THEADFIX | ||
| 111 | PUBLIC TREMCHECK | ||
| 112 | PUBLIC tjmp | ||
| 113 | |||
| 114 | ASSUME CS:RESGROUP,DS:NOTHING,ES:NOTHING,SS:NOTHING | ||
| 115 | |||
| 116 | EXTRN contc:near | ||
| 117 | EXTRN DSKERR:NEAR | ||
| 118 | EXTRN rstack:word | ||
| 119 | ; | ||
| 120 | ; If we cannot allocate enough memory for the transient or there was some | ||
| 121 | ; other allocation error, we display a message and then die. | ||
| 122 | ; | ||
| 123 | BADMEMERR: ; Allocation error loading transient | ||
| 124 | MOV DX,BMEMMES ;AC000; get message number | ||
| 125 | FATALC: | ||
| 126 | PUSH CS | ||
| 127 | POP DS | ||
| 128 | ASSUME DS:ResGroup | ||
| 129 | invoke RPRINT | ||
| 130 | ; | ||
| 131 | ; If this is NOT a permanent (top-level) COMMAND, then we exit; we can't do | ||
| 132 | ; anything else! | ||
| 133 | ; | ||
| 134 | CMP PERMCOM,0 | ||
| 135 | JZ FATALRET | ||
| 136 | ; | ||
| 137 | ; We are a permanent command. If we are in the process of the magic interrupt | ||
| 138 | ; (Singlecom) then exit too. | ||
| 139 | ; | ||
| 140 | CMP SINGLECOM,0 ; If PERMCOM and SINGLECOM | ||
| 141 | JNZ FATALRET ; Must take INT_2E exit | ||
| 142 | ; | ||
| 143 | ; Permanent command. We can't do ANYthing except halt. | ||
| 144 | ; | ||
| 145 | MOV DX,HALTMES ;AC000; get message number | ||
| 146 | invoke RPRINT | ||
| 147 | STI | ||
| 148 | STALL: | ||
| 149 | JMP STALL ; Crash the system nicely | ||
| 150 | |||
| 151 | FATALRET: | ||
| 152 | MOV DX,FRETMES ;AC000; get message number | ||
| 153 | invoke RPRINT | ||
| 154 | FATALRET2: | ||
| 155 | CMP [PERMCOM],0 ; If we get here and PERMCOM, | ||
| 156 | JNZ RET_2E ; must be INT_2E | ||
| 157 | invoke reset_msg_pointers ;AN000; reset critical & parse error messages | ||
| 158 | MOV AX,[PARENT] | ||
| 159 | MOV WORD PTR CS:[PDB_Parent_PID],AX | ||
| 160 | MOV AX,WORD PTR OldTerm | ||
| 161 | MOV WORD PTR CS:[PDB_Exit],AX | ||
| 162 | MOV AX,WORD PTR OldTerm+2 | ||
| 163 | MOV WORD PTR CS:[PDB_Exit+2],AX | ||
| 164 | MOV AX,(EXIT SHL 8) ; Return to lower level | ||
| 165 | INT int_command | ||
| 166 | |||
| 167 | RET_2E: | ||
| 168 | PUSH CS | ||
| 169 | POP DS | ||
| 170 | ASSUME DS:RESGROUP,ES:NOTHING,SS:NOTHING | ||
| 171 | MOV [SINGLECOM],0 ; Turn off singlecom | ||
| 172 | MOV ES,[RES_TPA] | ||
| 173 | MOV AH,DEALLOC | ||
| 174 | INT int_command ; Free up space used by transient | ||
| 175 | MOV BX,[SAVE_PDB] | ||
| 176 | MOV AH,SET_CURRENT_PDB | ||
| 177 | INT int_command ; Current process is user | ||
| 178 | MOV AX,[RETCODE] | ||
| 179 | CMP [EXTCOM],0 | ||
| 180 | JNZ GOTECODE | ||
| 181 | XOR AX,AX ; Internals always return 0 | ||
| 182 | GOTECODE: | ||
| 183 | MOV [EXTCOM],1 ; Force external | ||
| 184 | JMP [INT_2E_RET] ;"IRET" | ||
| 185 | |||
| 186 | INT_2E: ; Magic command executer | ||
| 187 | ASSUME DS:NOTHING,ES:NOTHING,SS:NOTHING | ||
| 188 | POP WORD PTR [INT_2E_RET] | ||
| 189 | POP WORD PTR [INT_2E_RET+2] ;Get return address | ||
| 190 | POP AX ;Chuck flags | ||
| 191 | PUSH CS | ||
| 192 | POP ES | ||
| 193 | MOV DI,80H | ||
| 194 | MOV CX,64 | ||
| 195 | REP MOVSW | ||
| 196 | MOV AH,GET_CURRENT_PDB | ||
| 197 | INT int_command ; Get user's header | ||
| 198 | MOV [SAVE_PDB],BX | ||
| 199 | MOV AH,SET_CURRENT_PDB | ||
| 200 | MOV BX,CS | ||
| 201 | INT int_command ; Current process is me | ||
| 202 | MOV [SINGLECOM],81H | ||
| 203 | MOV [EXTCOM],1 ; Make sure this case forced | ||
| 204 | |||
| 205 | LODCOM: ; Termination handler | ||
| 206 | CMP [EXTCOM],0 | ||
| 207 | jz lodcom1 ; if internal, memory already allocated | ||
| 208 | mov bx,0ffffh | ||
| 209 | MOV AH,ALLOC | ||
| 210 | INT int_command | ||
| 211 | CALL SetSize | ||
| 212 | ADD AX,20H | ||
| 213 | CMP BX,AX ; Is less than 512 byte buffer worth it? | ||
| 214 | JNC MEMOK | ||
| 215 | BADMEMERRJ: | ||
| 216 | JMP BADMEMERR ; Not enough memory | ||
| 217 | |||
| 218 | ; SetSize - get transient size in paragraphs | ||
| 219 | Procedure SetSize,NEAR | ||
| 220 | MOV AX,OFFSET TRANGROUP:TRANSPACEEND + 15 | ||
| 221 | MOV CL,4 | ||
| 222 | SHR AX,CL | ||
| 223 | return | ||
| 224 | EndProc SetSize | ||
| 225 | |||
| 226 | MEMOK: | ||
| 227 | MOV AH,ALLOC | ||
| 228 | INT int_command | ||
| 229 | JC BADMEMERRJ ; Memory arenas probably trashed | ||
| 230 | MOV [EXTCOM],0 ; Flag not to ALLOC again | ||
| 231 | MOV [RES_TPA], AX ; Save current TPA segment | ||
| 232 | AND AX, 0F000H | ||
| 233 | ADD AX, 01000H ; Round up to next 64K boundary | ||
| 234 | JC BAD_TPA ; Memory wrap if carry set | ||
| 235 | ; Make sure that new boundary is within allocated range | ||
| 236 | MOV DX, [RES_TPA] | ||
| 237 | ADD DX, BX ; Compute maximum address | ||
| 238 | CMP DX, AX ; Is 64K address out of range? | ||
| 239 | JBE BAD_TPA | ||
| 240 | ; Must have 64K of usable space. | ||
| 241 | SUB DX, AX ; Compute the usable space | ||
| 242 | CMP DX, 01000H ; Is space >= 64K ? | ||
| 243 | JAE LTPASET | ||
| 244 | BAD_TPA: | ||
| 245 | MOV AX, [RES_TPA] | ||
| 246 | LTPASET: | ||
| 247 | MOV [LTPA],AX ; Usable TPA is 64k buffer aligned | ||
| 248 | MOV AX, [RES_TPA] ; Actual TPA is buffer allocated | ||
| 249 | ADD BX,AX | ||
| 250 | MOV [MEMSIZ],BX | ||
| 251 | CALL SetSize | ||
| 252 | SUB BX,AX | ||
| 253 | MOV [TRNSEG],BX ; Transient starts here | ||
| 254 | LODCOM1: | ||
| 255 | MOV AX,CS | ||
| 256 | MOV SS,AX | ||
| 257 | ASSUME SS:RESGROUP | ||
| 258 | MOV SP,OFFSET RESGROUP:RSTACK | ||
| 259 | MOV DS,AX | ||
| 260 | ASSUME DS:RESGROUP | ||
| 261 | CALL HEADFIX ; Make sure files closed stdin and stdout restored | ||
| 262 | XOR BP,BP ; Flag command ok | ||
| 263 | MOV AX,-1 | ||
| 264 | XCHG AX,[VERVAL] | ||
| 265 | CMP AX,-1 | ||
| 266 | JZ NOSETVER | ||
| 267 | MOV AH,SET_VERIFY_ON_WRITE ; AL has correct value | ||
| 268 | INT int_command | ||
| 269 | NOSETVER: | ||
| 270 | CMP [SINGLECOM],-1 | ||
| 271 | JNZ NOSNG | ||
| 272 | JMP FATALRET2 ; We have finished the single command | ||
| 273 | NOSNG: | ||
| 274 | CALL CHKSUM ; Check the transient | ||
| 275 | CMP DX,[SUM] | ||
| 276 | JZ HAVCOM ; Transient OK | ||
| 277 | BOGUS_COM: | ||
| 278 | MOV [LOADING],1 ; Flag DSKERR routine | ||
| 279 | CALL LOADCOM | ||
| 280 | CHKSAME: | ||
| 281 | |||
| 282 | CALL CHKSUM | ||
| 283 | CMP DX,[SUM] | ||
| 284 | JZ HAVCOM ; Same COMMAND | ||
| 285 | ALSO_BOGUS: | ||
| 286 | CALL WRONGCOM | ||
| 287 | JMP SHORT CHKSAME | ||
| 288 | HAVCOM: | ||
| 289 | MOV AX,CHAR_OPER SHL 8 | ||
| 290 | INT int_command | ||
| 291 | MOV [RSWITCHAR],DL | ||
| 292 | CMP DL,'/' | ||
| 293 | JNZ USESLASH | ||
| 294 | mov cl,'\' | ||
| 295 | MOV [RDIRCHAR],cl ; Select alt path separator | ||
| 296 | USESLASH: | ||
| 297 | MOV [LOADING],0 ; Flag to DSKERR | ||
| 298 | MOV SI,OFFSET RESGROUP:TRANVARS | ||
| 299 | MOV DI,OFFSET TRANGROUP:HEADCALL | ||
| 300 | MOV ES,[TRNSEG] | ||
| 301 | CLD | ||
| 302 | MOV CX,OFFSET ResGroup:TranVarEnd | ||
| 303 | SUB CX,SI | ||
| 304 | REP MOVSB ; Transfer INFO to transient | ||
| 305 | MOV AX,[MEMSIZ] | ||
| 306 | MOV WORD PTR DS:[PDB_block_len],AX ; Adjust my own header | ||
| 307 | |||
| 308 | ; Just a public label so this spot can be found easily. | ||
| 309 | tjmp: | ||
| 310 | JMP DWORD PTR [TRANS] | ||
| 311 | |||
| 312 | ; Far call to REMCHECK for TRANSIENT | ||
| 313 | TREMCHECK PROC FAR | ||
| 314 | CALL REMCHECK | ||
| 315 | RET | ||
| 316 | TREMCHECK ENDP | ||
| 317 | |||
| 318 | REMCHECK: | ||
| 319 | ;All registers preserved. Returns ZF set if media removable, NZ if fixed | ||
| 320 | ; AL is drive (0=DEF, 1=A,...). | ||
| 321 | SaveReg <AX,BX> | ||
| 322 | MOV BX,AX | ||
| 323 | MOV AX,(IOCTL SHL 8) + 8 | ||
| 324 | INT 21h | ||
| 325 | jnc RCcont ; If an error occurred, assume the media | ||
| 326 | or ax,ax ; is NON-removable. | ||
| 327 | ; AX contains the non-zero error code | ||
| 328 | ; from the INT 21, so the OR AX,AX sets | ||
| 329 | ; Non-zero. This behavior makes Network | ||
| 330 | ; drives appear to be non-removable. | ||
| 331 | jmp SHORT ResRegs | ||
| 332 | RCcont: | ||
| 333 | AND AX,1 | ||
| 334 | NOT AX | ||
| 335 | ResRegs: | ||
| 336 | RestoreReg <BX,AX> | ||
| 337 | return | ||
| 338 | |||
| 339 | ; Far call to HEADFIX for TRANSIENT | ||
| 340 | THEADFIX PROC FAR | ||
| 341 | CALL HEADFIX | ||
| 342 | RET | ||
| 343 | THEADFIX ENDP | ||
| 344 | |||
| 345 | HEADFIX: | ||
| 346 | CALL SETVECT | ||
| 347 | XOR BX,BX ; Clean up header | ||
| 348 | MOV CX,[IO_SAVE] | ||
| 349 | MOV DX,WORD PTR DS:[PDB_JFN_Table] | ||
| 350 | CMP CL,DL | ||
| 351 | JZ CHK1 ; Stdin matches | ||
| 352 | MOV AH,CLOSE | ||
| 353 | INT int_command | ||
| 354 | MOV DS:[PDB_JFN_Table],CL ; Restore stdin | ||
| 355 | CHK1: | ||
| 356 | INC BX | ||
| 357 | CMP CH,DH ; Stdout matches | ||
| 358 | JZ CHKOTHERHAND | ||
| 359 | MOV AH,CLOSE | ||
| 360 | INT int_command | ||
| 361 | MOV DS:[PDB_JFN_Table+1],CH ; Restore stdout | ||
| 362 | CHKOTHERHAND: | ||
| 363 | ADD BX,4 ; Skip 2,3,4 | ||
| 364 | MOV CX,FilPerProc - 5 ; Already done 0,1,2,3,4 | ||
| 365 | CLOSELOOP: | ||
| 366 | MOV AH,CLOSE | ||
| 367 | INT int_command | ||
| 368 | INC BX | ||
| 369 | LOOP CLOSELOOP | ||
| 370 | push ds ;AN020; save data segment | ||
| 371 | push cs ;AN020; Get local segment into DS | ||
| 372 | pop ds ;AN020; | ||
| 373 | cmp append_flag,-1 ;AN020; Do we need to reset APPEND? | ||
| 374 | jnz append_fix_end ;AN030; no - just exit | ||
| 375 | mov ax,AppendSetState ;AN020; Set the state of Append | ||
| 376 | mov bx,Append_state ;AN020; back to the original state | ||
| 377 | int 2fh ;AN020; | ||
| 378 | mov append_flag,0 ;AN020; Set append flag to invalid | ||
| 379 | append_fix_end: ;AN030; | ||
| 380 | cmp [rsrc_xa_seg],no_xa_seg ;AN030; Is there any active XA segment? | ||
| 381 | jz xa_fix_end ;AN030; no - exit | ||
| 382 | push es ;AN030; Yes - deallocate it | ||
| 383 | mov es,rsrc_xa_seg ;AN030; | ||
| 384 | mov ax,(Dealloc SHL 8) ;AN030; Deallocate memory call | ||
| 385 | int int_command ;AN030; | ||
| 386 | pop es ;AN030; | ||
| 387 | mov [rsrc_xa_seg],no_xa_seg ;AN030; reset to no segment | ||
| 388 | xa_fix_end: | ||
| 389 | pop ds ;AN020; get data segment back | ||
| 390 | return | ||
| 391 | |||
| 392 | SAVHAND: | ||
| 393 | ASSUME DS:NOTHING,ES:NOTHING,SS:NOTHING | ||
| 394 | PUSH DS | ||
| 395 | PUSH BX ; Set stdin to sterr, stdout to stderr | ||
| 396 | PUSH AX | ||
| 397 | MOV AH,GET_CURRENT_PDB | ||
| 398 | INT int_command ; Get user's header | ||
| 399 | MOV DS,BX | ||
| 400 | LDS BX,DS:[PDB_JFN_POINTER] ; get pointer to JFN table... | ||
| 401 | MOV AX,WORD PTR DS:[BX] | ||
| 402 | MOV [HANDLE01],AX ; Save user's stdin, stdout | ||
| 403 | MOV AL,CS:[PDB_JFN_Table+2] ; get COMMAND stderr | ||
| 404 | MOV AH,AL | ||
| 405 | MOV WORD PTR DS:[BX],AX ; Dup stderr | ||
| 406 | POP AX | ||
| 407 | POP BX | ||
| 408 | POP DS | ||
| 409 | return | ||
| 410 | |||
| 411 | ASSUME DS:RESGROUP | ||
| 412 | GETCOMDSK2: | ||
| 413 | CALL GETCOMDSK | ||
| 414 | JMP LODCOM1 ; Memory already allocated | ||
| 415 | |||
| 416 | RESTHAND: | ||
| 417 | PUSH DS | ||
| 418 | PUSH BX ; Restore stdin, stdout to user | ||
| 419 | PUSH AX | ||
| 420 | MOV AH,GET_CURRENT_PDB | ||
| 421 | INT int_command ; Point to user's header | ||
| 422 | MOV AX,[HANDLE01] | ||
| 423 | MOV DS,BX | ||
| 424 | ASSUME DS:NOTHING | ||
| 425 | LDS BX,DS:[PDB_JFN_POINTER] ; get pointer to JFN table... | ||
| 426 | MOV WORD PTR DS:[BX],AX ; Stuff his old 0 and 1 | ||
| 427 | POP AX | ||
| 428 | POP BX | ||
| 429 | POP DS | ||
| 430 | return | ||
| 431 | ASSUME DS:RESGROUP,SS:RESGROUP | ||
| 432 | |||
| 433 | HOPELESS: | ||
| 434 | MOV DX,COMBAD ;AC000; | ||
| 435 | JMP FATALC | ||
| 436 | |||
| 437 | GETCOMDSK: | ||
| 438 | mov al,[comdrv] | ||
| 439 | CALL REMCHECK | ||
| 440 | jNZ HOPELESS ;Non-removable media | ||
| 441 | getcomdsk3: | ||
| 442 | cmp dx,combad ;AC000; | ||
| 443 | jnz getcomdsk4 | ||
| 444 | mov dx,combad ;AN000; get message number | ||
| 445 | invoke RPRINT ; Say command is invalid | ||
| 446 | getcomdsk4: | ||
| 447 | cmp [cpdrv],0 ;g is there a drive in the comspec? | ||
| 448 | jnz users_drive ;g yes - use it | ||
| 449 | mov ah,Get_default_drive ;g use default drive | ||
| 450 | int 21h ;g | ||
| 451 | add al,"A" ;g convert to ascii | ||
| 452 | mov [cpdrv],al ;g put in message to print out | ||
| 453 | |||
| 454 | users_drive: ;g | ||
| 455 | mov dx,comprmt1 ;AC000; Prompt for diskette containing command | ||
| 456 | IF tokenized | ||
| 457 | or byte ptr [si],80h | ||
| 458 | endif | ||
| 459 | MOV AL,COMPRMT1_SUBST ;AN000; get number of substitutions | ||
| 460 | MOV SI,OFFSET RESGROUP:COMPRMT1_BLOCK ;AN000; get address of subst block | ||
| 461 | MOV NUMBER_SUBST,AL ;AN000; | ||
| 462 | invoke rprint | ||
| 463 | if tokenized | ||
| 464 | and byte ptr [si],NOT 80h | ||
| 465 | endif | ||
| 466 | mov dx,prompt ;AN047; Tell the user to strike a key | ||
| 467 | invoke rprint ;AN047; | ||
| 468 | CALL GetRawFlushedByte | ||
| 469 | return | ||
| 470 | |||
| 471 | ; flush world and get raw input | ||
| 472 | GetRawFlushedByte: | ||
| 473 | MOV AX,(STD_CON_INPUT_FLUSH SHL 8) OR RAW_CON_INPUT | ||
| 474 | INT int_command ; Get char without testing or echo | ||
| 475 | MOV AX,(STD_CON_INPUT_FLUSH SHL 8) + 0 | ||
| 476 | INT int_command | ||
| 477 | return | ||
| 478 | |||
| 479 | LOADCOM: ; Load in transient | ||
| 480 | INC BP ; Flag command read | ||
| 481 | MOV DX,OFFSET RESGROUP:COMSPEC | ||
| 482 | MOV AX,OPEN SHL 8 | ||
| 483 | INT int_command ; Open COMMAND.COM | ||
| 484 | JNC READCOM | ||
| 485 | CMP AX,error_too_many_open_files | ||
| 486 | JNZ TRYDOOPEN | ||
| 487 | MOV DX,NOHANDMES ;AC000; | ||
| 488 | JMP FATALC ; Fatal, will never find a handle | ||
| 489 | |||
| 490 | TRYDOOPEN: | ||
| 491 | CALL GETCOMDSK | ||
| 492 | JMP LOADCOM | ||
| 493 | |||
| 494 | READCOM: | ||
| 495 | MOV BX,AX ; Handle | ||
| 496 | MOV DX,OFFSET RESGROUP:TRANSTART | ||
| 497 | XOR CX,CX ; Seek loc | ||
| 498 | MOV AX,LSEEK SHL 8 | ||
| 499 | INT int_command | ||
| 500 | JC WRONGCOM1 | ||
| 501 | MOV CX,OFFSET TRANGROUP:TRANSPACEEND - 100H | ||
| 502 | |||
| 503 | PUSH DS | ||
| 504 | MOV DS,[TRNSEG] | ||
| 505 | ASSUME DS:NOTHING | ||
| 506 | MOV DX,100H | ||
| 507 | MOV AH,READ | ||
| 508 | INT int_command | ||
| 509 | POP DS | ||
| 510 | ASSUME DS:RESGROUP | ||
| 511 | WRONGCOM1: | ||
| 512 | PUSHF | ||
| 513 | PUSH AX | ||
| 514 | MOV AH,CLOSE | ||
| 515 | INT int_command ; Close COMMAND.COM | ||
| 516 | POP AX | ||
| 517 | POPF | ||
| 518 | JC WRONGCOM ; If error on READ | ||
| 519 | CMP AX,CX | ||
| 520 | retz ; Size matched | ||
| 521 | WRONGCOM: | ||
| 522 | MOV DX,COMBAD ;AC000; | ||
| 523 | CALL GETCOMDSK | ||
| 524 | JMP LOADCOM ; Try again | ||
| 525 | |||
| 526 | CHKSUM: ; Compute transient checksum | ||
| 527 | PUSH DS | ||
| 528 | MOV DS,[TRNSEG] | ||
| 529 | MOV SI,100H | ||
| 530 | MOV CX,OFFSET TRANGROUP:TranDataEnd - 100H | ||
| 531 | |||
| 532 | CHECK_SUM: | ||
| 533 | CLD | ||
| 534 | SHR CX,1 | ||
| 535 | XOR DX,DX | ||
| 536 | CHK: | ||
| 537 | LODSW | ||
| 538 | ADD DX,AX | ||
| 539 | ADC DX,0 | ||
| 540 | LOOP CHK | ||
| 541 | POP DS | ||
| 542 | return | ||
| 543 | |||
| 544 | SETVECT: ; Set useful vectors | ||
| 545 | MOV DX,OFFSET RESGROUP:LODCOM | ||
| 546 | MOV AX,(SET_INTERRUPT_VECTOR SHL 8) OR 22H | ||
| 547 | MOV WORD PTR DS:[PDB_EXIT],DX | ||
| 548 | MOV WORD PTR DS:[PDB_EXIT+2],DS | ||
| 549 | INT int_command | ||
| 550 | MOV DX,OFFSET RESGROUP:CONTC | ||
| 551 | INC AL | ||
| 552 | INT int_command | ||
| 553 | MOV DX,OFFSET RESGROUP:DSKERR | ||
| 554 | INC AL | ||
| 555 | INT int_command | ||
| 556 | return | ||
| 557 | |||
| 558 | |||
| 559 | ; | ||
| 560 | ; This routine moves the environment to a newly allocated segment | ||
| 561 | ; at the end of initialization | ||
| 562 | ; | ||
| 563 | |||
| 564 | ENDINIT: | ||
| 565 | push ds ;g save segments | ||
| 566 | push es ;g | ||
| 567 | push cs ;g get resident segment to DS | ||
| 568 | pop ds ;g | ||
| 569 | ASSUME DS:RESGROUP | ||
| 570 | mov cx,usedenv ;g get number of bytes to move | ||
| 571 | mov es,envirseg ;g get target environment segment | ||
| 572 | |||
| 573 | ASSUME ES:NOTHING | ||
| 574 | mov DS:[PDB_environ],es ;g put new environment in my header ;AM067; | ||
| 575 | mov ds,oldenv ;g source environment segment ;AM067; | ||
| 576 | ASSUME DS:NOTHING ;AM067; | ||
| 577 | xor si,si ;g set up offsets to start of segments ;AM067; | ||
| 578 | xor di,di ;g ;AM067; | ||
| 579 | cld ;g make sure we move the right way! ;AM067; | ||
| 580 | rep movsb ;g move it ;AM067; | ||
| 581 | xor ax,ax ;g ;AM067; | ||
| 582 | stosb ;g make sure there are double 0 at end ;AM067; | ||
| 583 | |||
| 584 | cmp resetenv,1 ;eg Do we need to setblock to env end? | ||
| 585 | jnz noreset ;eg no - we already did it | ||
| 586 | mov bx,envsiz ;eg get size of environment in paragraphs | ||
| 587 | push es ;eg save environment - just to make sure | ||
| 588 | mov ah,SETBLOCK ;eg | ||
| 589 | int int_command ;eg | ||
| 590 | pop es ;eg | ||
| 591 | |||
| 592 | noreset: | ||
| 593 | mov InitFlag,FALSE ;AC042; Turn off init flag | ||
| 594 | pop es ;g | ||
| 595 | pop ds ;g | ||
| 596 | jmp lodcom ;g allocate transient | ||
| 597 | |||
| 598 | CODERES ENDS | ||
| 599 | |||
| 600 | ; This TAIL segment is used to produce a PARA aligned label in the resident | ||
| 601 | ; group which is the location where the transient segments will be loaded | ||
| 602 | ; initial. | ||
| 603 | |||
| 604 | TAIL SEGMENT PUBLIC PARA | ||
| 605 | ORG 0 | ||
| 606 | PUBLIC TranStart | ||
| 607 | TRANSTART LABEL WORD | ||
| 608 | TAIL ENDS | ||
| 609 | |||
| 610 | ; This TAIL segment is used to produce a PARA aligned label in the transient | ||
| 611 | ; group which is the location where the exec segments will be loaded | ||
| 612 | ; initial. | ||
| 613 | |||
| 614 | TRANTAIL SEGMENT PUBLIC PARA | ||
| 615 | ORG 0 | ||
| 616 | EXECSTART LABEL WORD | ||
| 617 | TRANTAIL ENDS | ||
| 618 | |||
| 619 | END | ||