diff options
Diffstat (limited to 'v1.25/source/COMMAND.ASM')
| -rw-r--r-- | v1.25/source/COMMAND.ASM | 2166 |
1 files changed, 2166 insertions, 0 deletions
diff --git a/v1.25/source/COMMAND.ASM b/v1.25/source/COMMAND.ASM new file mode 100644 index 0000000..830bf73 --- /dev/null +++ b/v1.25/source/COMMAND.ASM | |||
| @@ -0,0 +1,2166 @@ | |||
| 1 | ; COMMAND version 1.17 | ||
| 2 | ; | ||
| 3 | ; This version of COMMAND is divided into three distinct parts. First | ||
| 4 | ; is the resident portion, which includes handlers for interrupts | ||
| 5 | ; 22H (terminate), 23H (Cntrl-C), 24H (fatal error), and 27H (stay | ||
| 6 | ; resident); it also has code to test and, if necessary, reload the | ||
| 7 | ; transient portion. Following the resident is the init code, which is | ||
| 8 | ; overwritten after use. Then comes the transient portion, which | ||
| 9 | ; includes all command processing (whether internal or external). | ||
| 10 | ; The transient portion loads at the end of physical memory, and it may | ||
| 11 | ; be overlayed by programs that need as much memory as possible. When | ||
| 12 | ; the resident portion of command regains control from a user program, | ||
| 13 | ; a checksum is performed on the transient portion to see if it must be | ||
| 14 | ; reloaded. Thus programs which do not need maximum memory will save | ||
| 15 | ; the time required to reload COMMAND when they terminate. | ||
| 16 | |||
| 17 | ;Use the following booleans to set assembly flags | ||
| 18 | FALSE EQU 0 | ||
| 19 | TRUE EQU NOT FALSE | ||
| 20 | |||
| 21 | IBMVER EQU FALSE ;Switch to build IBM version of Command | ||
| 22 | MSVER EQU TRUE ;Switch to build MS-DOS version of Command | ||
| 23 | |||
| 24 | HIGHMEM EQU TRUE ;Run resident part above transient (high memory) | ||
| 25 | |||
| 26 | LINPERPAG EQU 23 | ||
| 27 | NORMPERLIN EQU 1 | ||
| 28 | WIDEPERLIN EQU 5 | ||
| 29 | |||
| 30 | IF IBMVER | ||
| 31 | SYM EQU ">" | ||
| 32 | COMDRV EQU 1 | ||
| 33 | ENDIF | ||
| 34 | |||
| 35 | IF MSVER | ||
| 36 | SYM EQU ":" | ||
| 37 | COMDRV EQU 0 | ||
| 38 | ENDIF | ||
| 39 | |||
| 40 | FCB EQU 5CH | ||
| 41 | DSKRESET EQU 13 | ||
| 42 | SETBASE EQU 38 | ||
| 43 | SRCHFRST EQU 17 | ||
| 44 | SRCHNXT EQU 18 | ||
| 45 | RENAM EQU 23 | ||
| 46 | INCHAR EQU 1 | ||
| 47 | GETFAT EQU 27 | ||
| 48 | OPEN EQU 15 | ||
| 49 | CLOSE EQU 16 | ||
| 50 | MAKE EQU 22 | ||
| 51 | DELETE EQU 19 | ||
| 52 | RDBLK EQU 39 | ||
| 53 | WRBLK EQU 40 | ||
| 54 | SETDMA EQU 26 | ||
| 55 | SELDRV EQU 14 | ||
| 56 | GETDRV EQU 25 | ||
| 57 | PRINTBUF EQU 9 | ||
| 58 | OUTCH EQU 2 | ||
| 59 | INBUF EQU 10 | ||
| 60 | GETDATE EQU 2AH | ||
| 61 | SETDATE EQU 2BH | ||
| 62 | GETTIME EQU 2CH | ||
| 63 | SETTIME EQU 2DH | ||
| 64 | RR EQU 33 | ||
| 65 | RECLEN EQU 14 | ||
| 66 | FILLEN EQU 16 | ||
| 67 | OFFDATE EQU 20 | ||
| 68 | |||
| 69 | |||
| 70 | ;The following are all of the segments used in the load order | ||
| 71 | |||
| 72 | CODERES SEGMENT | ||
| 73 | CODERES ENDS | ||
| 74 | |||
| 75 | DATARES SEGMENT BYTE | ||
| 76 | DATARES ENDS | ||
| 77 | |||
| 78 | INIT SEGMENT BYTE | ||
| 79 | INIT ENDS | ||
| 80 | |||
| 81 | TAIL SEGMENT PARA | ||
| 82 | TAIL ENDS | ||
| 83 | |||
| 84 | TRANCODE SEGMENT PARA | ||
| 85 | TRANCODE ENDS | ||
| 86 | |||
| 87 | TRANDATA SEGMENT BYTE | ||
| 88 | TRANDATA ENDS | ||
| 89 | |||
| 90 | TRANSPACE SEGMENT BYTE | ||
| 91 | TRANSPACE ENDS | ||
| 92 | |||
| 93 | RESGROUP GROUP CODERES,DATARES,INIT,TAIL | ||
| 94 | TRANGROUP GROUP TRANCODE,TRANDATA,TRANSPACE | ||
| 95 | |||
| 96 | ;Data for resident portion | ||
| 97 | |||
| 98 | DATARES SEGMENT BYTE | ||
| 99 | ORG 0 | ||
| 100 | ZERO = $ | ||
| 101 | MESBAS DW OFFSET RESGROUP:ERR0 | ||
| 102 | DW OFFSET RESGROUP:ERR2 | ||
| 103 | DW OFFSET RESGROUP:ERR4 | ||
| 104 | DW OFFSET RESGROUP:ERR6 | ||
| 105 | DW OFFSET RESGROUP:ERR8 | ||
| 106 | DW OFFSET RESGROUP:ERR10 | ||
| 107 | DW OFFSET RESGROUP:ERR12 | ||
| 108 | ERR0 DB "Write protect$" | ||
| 109 | ERR2 DB "Not ready$" | ||
| 110 | ERR4 DB "Data$" | ||
| 111 | ERR6 DB "Seek$" | ||
| 112 | ERR8 DB "Sector not found$" | ||
| 113 | ERR10 DB "Write fault$" | ||
| 114 | ERR12 DB "Disk$" | ||
| 115 | READ DB "read$" | ||
| 116 | WRITE DB "writ$" | ||
| 117 | ERRMES DB " error " | ||
| 118 | IOTYP DB "writing" | ||
| 119 | DRVNUM DB " drive " | ||
| 120 | DRVLET DB "A" | ||
| 121 | NEWLIN DB 13,10,"$" | ||
| 122 | REQUEST DB "Abort, Retry, Ignore? $" | ||
| 123 | BADFAT DB 13,10,"File allocation table bad,$" | ||
| 124 | COMBAD DB 13,10,"Invalid COMMAND.COM" | ||
| 125 | NEEDCOM DB 13,10,"Insert DOS disk in " | ||
| 126 | IF IBMVER | ||
| 127 | DB "drive A" | ||
| 128 | ELSE | ||
| 129 | DB "default drive" | ||
| 130 | ENDIF | ||
| 131 | PROMPT DB 13,10,"and strike any key when ready",13,10,"$" | ||
| 132 | NEEDBAT DB 13,10,"Insert disk with batch file$" | ||
| 133 | ENDBATMES DB 13,10,"Terminate batch job (Y/N)? $" | ||
| 134 | LOADING DB 0 | ||
| 135 | BATFCB DB 1,"AUTOEXECBAT" | ||
| 136 | DB 21 DUP(?) | ||
| 137 | DW 0 | ||
| 138 | DW 0 ;Initialize RR field to zero | ||
| 139 | PARMTAB DW 10 DUP(-1) ;No parameters initially | ||
| 140 | BATCH DB 1 ;Assume batch mode initially | ||
| 141 | COMFCB DB COMDRV,"COMMAND COM" | ||
| 142 | DB 25 DUP(?) | ||
| 143 | TRANS DW OFFSET TRANGROUP:COMMAND | ||
| 144 | TRNSEG DW ? | ||
| 145 | BATBYT DB ? | ||
| 146 | MEMSIZ DW ? | ||
| 147 | SUM DW ? | ||
| 148 | INITADD DB 4 DUP(?) | ||
| 149 | RESDATASIZE EQU $-ZERO | ||
| 150 | DATARES ENDS | ||
| 151 | |||
| 152 | ;Data for transient portion | ||
| 153 | |||
| 154 | TRANDATA SEGMENT BYTE | ||
| 155 | ORG 0 | ||
| 156 | ZERO EQU $ | ||
| 157 | BADNAM DB "Bad command or file name",13,10,"$" | ||
| 158 | MISNAM DB "Missing file name$" | ||
| 159 | RENERR DB "Duplicate file name or " | ||
| 160 | NOTFND DB "File not found$" | ||
| 161 | EXEBAD DB "Error in EXE file$" | ||
| 162 | NOSPACE DB "Insufficient disk space",13,10,"$" | ||
| 163 | FULDIR DB "File creation error",13,10,"$" | ||
| 164 | OVERWR DB "File cannot be copied onto itself",13,10,"$" | ||
| 165 | LOSTERR DB "Content of destination lost before copy",13,10,"$" | ||
| 166 | COPIED DB " File(s) copied$" | ||
| 167 | DIRMES DB " File(s)$" | ||
| 168 | TOOBIG DB "Program too big to fit in memory$" | ||
| 169 | BADDRV DB "Invalid drive specification$" | ||
| 170 | PAUSMES DB "Strike a key when ready . . . $" | ||
| 171 | BADSWT DB "Illegal switch",13,10,"$" | ||
| 172 | WEEKTAB DB "SunMonTueWedThuFriSat" | ||
| 173 | BADDAT DB 13,10,"Invalid date$" | ||
| 174 | CURDAT DB "Current date is $" | ||
| 175 | NEWDAT DB 13,10,"Enter new date: $" | ||
| 176 | BADTIM DB 13,10,"Invalid time$" | ||
| 177 | CURTIM DB "Current time is $" | ||
| 178 | NEWTIM DB 13,10,"Enter new time: $" | ||
| 179 | SUREMES DB "Are you sure (Y/N)? $" | ||
| 180 | |||
| 181 | COMTAB DB 4,"DIR",1 | ||
| 182 | DW OFFSET TRANGROUP:CATALOG | ||
| 183 | DB 7,"RENAME",1 | ||
| 184 | DW OFFSET TRANGROUP:RENAME | ||
| 185 | DB 4,"REN",1 | ||
| 186 | DW OFFSET TRANGROUP:RENAME | ||
| 187 | DB 6,"ERASE",1 | ||
| 188 | DW OFFSET TRANGROUP:ERASE | ||
| 189 | DB 4,"DEL",1 | ||
| 190 | DW OFFSET TRANGROUP:ERASE | ||
| 191 | DB 5,"TYPE",1 | ||
| 192 | DW OFFSET TRANGROUP:TYPEFIL | ||
| 193 | DB 4,"REM",1 | ||
| 194 | DW OFFSET TRANGROUP:COMMAND | ||
| 195 | DB 5,"COPY",1 | ||
| 196 | DW OFFSET TRANGROUP:COPY | ||
| 197 | DB 6,"PAUSE",1 | ||
| 198 | DW OFFSET TRANGROUP:PAUSE | ||
| 199 | DB 5,"DATE",0 | ||
| 200 | DW OFFSET TRANGROUP:DATE | ||
| 201 | DB 5,"TIME",0 | ||
| 202 | DW OFFSET TRANGROUP:TIME | ||
| 203 | DB 0 ;Terminate command table | ||
| 204 | |||
| 205 | COMBUF DB 128,1,13 | ||
| 206 | |||
| 207 | TRANDATASIZE EQU $-ZERO | ||
| 208 | TRANDATA ENDS | ||
| 209 | |||
| 210 | ;Uninitialized transient data | ||
| 211 | TRANSPACE SEGMENT BYTE | ||
| 212 | ORG 0 | ||
| 213 | ZERO = $ | ||
| 214 | DB 128 DUP(?) | ||
| 215 | TPA DW 1 DUP(?) | ||
| 216 | RESSEG DW 1 DUP(?) | ||
| 217 | CHKDRV DB 1 DUP(?) | ||
| 218 | FILTYP DB 1 DUP(?) | ||
| 219 | CURDRV DB 1 DUP(?) | ||
| 220 | PARM1 DB 1 DUP(?) | ||
| 221 | PARM2 DB 1 DUP(?) | ||
| 222 | COMSW DW 1 DUP(?) | ||
| 223 | ARG1S DW 1 DUP(?) | ||
| 224 | ARG2S DW 1 DUP(?) | ||
| 225 | FLAGER DB 1 DUP(?) | ||
| 226 | CFLAG DB 1 DUP(?) | ||
| 227 | SPECDRV DB 1 DUP(?) | ||
| 228 | BYTCNT DW 1 DUP(?) | ||
| 229 | NXTADD DW 1 DUP(?) | ||
| 230 | LINCNT DB 1 DUP(?) | ||
| 231 | LINLEN DB 1 DUP(?) | ||
| 232 | FILECNT DW 1 DUP(?) | ||
| 233 | EXEFCB LABEL WORD | ||
| 234 | IDLEN DB 1 DUP(?) | ||
| 235 | ID DB 8 DUP(?) | ||
| 236 | COM DB 3 DUP(?) | ||
| 237 | DEST DB 37 DUP(?) | ||
| 238 | DESTNAME DB 11 DUP(?) | ||
| 239 | DIRBUF DB 37 DUP(?) | ||
| 240 | BITS DW 1 DUP(?) | ||
| 241 | FULLSCR DW 1 DUP(?) | ||
| 242 | EXEEND DW 1 DUP(?) | ||
| 243 | ;Header variables for EXE file load | ||
| 244 | ;These are overlapped with COPY variables, below | ||
| 245 | RUNVAR LABEL WORD | ||
| 246 | RELPT DW 1 DUP(?) | ||
| 247 | RELSEG DW 1 DUP(?) | ||
| 248 | PSIZE LABEL WORD | ||
| 249 | PAGES DW 1 DUP(?) | ||
| 250 | RELCNT DW 1 DUP(?) | ||
| 251 | HEADSIZ DW 1 DUP(?) | ||
| 252 | DW 1 DUP(?) | ||
| 253 | LOADLOW DW 1 DUP(?) | ||
| 254 | INITSS DW 1 DUP(?) | ||
| 255 | INITSP DW 1 DUP(?) | ||
| 256 | DW 1 DUP(?) | ||
| 257 | INITIP DW 1 DUP(?) | ||
| 258 | INITCS DW 1 DUP(?) | ||
| 259 | RELTAB DW 1 DUP(?) | ||
| 260 | RUNVARSIZ EQU $-RUNVAR | ||
| 261 | |||
| 262 | DB 80H DUP(?) | ||
| 263 | STACK LABEL WORD | ||
| 264 | |||
| 265 | PRETRLEN EQU $-ZERO ;Used later to compute TRNLEN | ||
| 266 | |||
| 267 | ORG RUNVAR-ZERO ;Overlaps EXE variables | ||
| 268 | |||
| 269 | SRCPT DW 1 DUP(?) | ||
| 270 | INEXACT DB 1 DUP(?) | ||
| 271 | APPEND DB 1 DUP(?) | ||
| 272 | NOWRITE DB 1 DUP(?) | ||
| 273 | ASCII DB 1 DUP(?) | ||
| 274 | PLUS DB 1 DUP(?) | ||
| 275 | SOURCE DB 11 DUP(?) | ||
| 276 | TRANSPACESIZE EQU $-ZERO | ||
| 277 | TRANSPACE ENDS | ||
| 278 | |||
| 279 | |||
| 280 | ;START OF RESIDENT PORTION | ||
| 281 | |||
| 282 | CODERES SEGMENT | ||
| 283 | ASSUME CS:RESGROUP,DS:RESGROUP,ES:RESGROUP,SS:RESGROUP | ||
| 284 | ORG 0 | ||
| 285 | ZERO = $ | ||
| 286 | PARMBUF LABEL WORD | ||
| 287 | |||
| 288 | ORG 100H | ||
| 289 | |||
| 290 | RSTACK LABEL WORD | ||
| 291 | |||
| 292 | PROGSTART: | ||
| 293 | JMP CONPROC | ||
| 294 | |||
| 295 | LTPA DW 0 ;WILL STORE TPA SEGMENT HERE | ||
| 296 | MYSEG DW 0 ;Put our own segment here | ||
| 297 | |||
| 298 | CONTC: | ||
| 299 | MOV AX,CS | ||
| 300 | MOV DS,AX | ||
| 301 | MOV SS,AX | ||
| 302 | MOV SP,OFFSET RESGROUP:RSTACK | ||
| 303 | STI | ||
| 304 | CALL SETVECT | ||
| 305 | MOV AH,DSKRESET | ||
| 306 | INT 33 ;Reset disks in case files were open | ||
| 307 | TEST [BATCH],-1 | ||
| 308 | JZ LODCOM | ||
| 309 | ASKEND: | ||
| 310 | MOV DX,OFFSET RESGROUP:ENDBATMES | ||
| 311 | MOV AH,PRINTBUF | ||
| 312 | INT 33 | ||
| 313 | MOV AX,0C00H+INCHAR | ||
| 314 | INT 33 | ||
| 315 | AND AL,5FH | ||
| 316 | CMP AL,"N" | ||
| 317 | JZ LODCOM | ||
| 318 | CMP AL,"Y" | ||
| 319 | JNZ ASKEND | ||
| 320 | MOV [BATCH],0 | ||
| 321 | LODCOM: | ||
| 322 | MOV AX,CS | ||
| 323 | MOV SS,AX | ||
| 324 | MOV SP,OFFSET RESGROUP:RSTACK | ||
| 325 | MOV DS,AX | ||
| 326 | CALL SETVECT | ||
| 327 | CALL CHKSUM | ||
| 328 | CMP DX,[SUM] | ||
| 329 | JZ HAVCOM | ||
| 330 | MOV [LOADING],1 | ||
| 331 | CALL LOADCOM | ||
| 332 | CHKSAME: | ||
| 333 | CALL CHKSUM | ||
| 334 | CMP DX,[SUM] | ||
| 335 | JZ HAVCOM | ||
| 336 | CALL WRONGCOM | ||
| 337 | JMP SHORT CHKSAME | ||
| 338 | HAVCOM: | ||
| 339 | MOV [LOADING],0 | ||
| 340 | MOV SI,OFFSET RESGROUP:LTPA | ||
| 341 | MOV DI,OFFSET TRANGROUP:TPA | ||
| 342 | MOV ES,[TRNSEG] | ||
| 343 | CLD | ||
| 344 | MOVSW ;Move TPA segment to transient storage | ||
| 345 | MOVSW ;Move resident segment too | ||
| 346 | MOV AX,[MEMSIZ] | ||
| 347 | MOV WORD PTR ES:[2],AX | ||
| 348 | JMP DWORD PTR [TRANS] | ||
| 349 | |||
| 350 | RESIDENT: | ||
| 351 | ADD DX,15 | ||
| 352 | MOV CL,4 | ||
| 353 | SHR DX,CL ;Number of paragraphs of new addition | ||
| 354 | ADD CS:[LTPA],DX | ||
| 355 | XOR AX,AX | ||
| 356 | MOV DS,AX | ||
| 357 | JMP DWORD PTR DS:[80H] ;Pretend user executed INT 20H | ||
| 358 | |||
| 359 | DSKERR: | ||
| 360 | ;****************************************************** | ||
| 361 | ; THIS IS THE DEFAULT DISK ERROR HANDLING CODE | ||
| 362 | ; AVAILABLE TO ALL USERS IF THEY DO NOT TRY TO | ||
| 363 | ; INTERCEPT INTERRUPT 24H. | ||
| 364 | ;****************************************************** | ||
| 365 | STI | ||
| 366 | PUSH DS | ||
| 367 | PUSH CS | ||
| 368 | POP DS ;Set up local data segment | ||
| 369 | PUSH DX | ||
| 370 | CALL CRLF | ||
| 371 | POP DX | ||
| 372 | ADD AL,"A" ;Compute drive letter | ||
| 373 | MOV [DRVLET],AL | ||
| 374 | TEST AH,80H ;Check if hard disk error | ||
| 375 | JNZ FATERR | ||
| 376 | MOV SI,OFFSET RESGROUP:READ | ||
| 377 | TEST AH,1 | ||
| 378 | JZ SAVMES | ||
| 379 | MOV SI,OFFSET RESGROUP:WRITE | ||
| 380 | SAVMES: | ||
| 381 | LODSW | ||
| 382 | MOV WORD PTR [IOTYP],AX | ||
| 383 | LODSW | ||
| 384 | MOV WORD PTR [IOTYP+2],AX | ||
| 385 | AND DI,0FFH | ||
| 386 | CMP DI,12 | ||
| 387 | JBE HAVCOD | ||
| 388 | MOV DI,12 | ||
| 389 | HAVCOD: | ||
| 390 | MOV DI,WORD PTR [DI+MESBAS] ;Get pointer to error message | ||
| 391 | XCHG DI,DX ;May need DX later | ||
| 392 | MOV AH,PRINTBUF | ||
| 393 | INT 33 ;Print error type | ||
| 394 | MOV DX,OFFSET RESGROUP:ERRMES | ||
| 395 | INT 33 | ||
| 396 | CMP [LOADING],0 | ||
| 397 | JNZ GETCOMDSK | ||
| 398 | ASK: | ||
| 399 | MOV DX,OFFSET RESGROUP:REQUEST | ||
| 400 | MOV AH,PRINTBUF | ||
| 401 | INT 33 | ||
| 402 | MOV AX,0C00H+INCHAR | ||
| 403 | INT 33 ;Get response | ||
| 404 | CALL CRLF | ||
| 405 | OR AL,20H ;Convert to lower case | ||
| 406 | MOV AH,0 ;Return code for ignore | ||
| 407 | CMP AL,"i" ;Ignore? | ||
| 408 | JZ EXIT | ||
| 409 | INC AH | ||
| 410 | CMP AL,"r" ;Retry? | ||
| 411 | JZ EXIT | ||
| 412 | INC AH | ||
| 413 | CMP AL,"a" ;Abort? | ||
| 414 | JNZ ASK | ||
| 415 | EXIT: | ||
| 416 | MOV AL,AH | ||
| 417 | MOV DX,DI | ||
| 418 | POP DS | ||
| 419 | IRET | ||
| 420 | |||
| 421 | FATERR: | ||
| 422 | MOV DX,OFFSET RESGROUP:BADFAT | ||
| 423 | MOV AH,PRINTBUF | ||
| 424 | INT 33 | ||
| 425 | MOV DX,OFFSET RESGROUP:DRVNUM | ||
| 426 | INT 33 | ||
| 427 | MOV AL,2 ;Abort | ||
| 428 | POP DS | ||
| 429 | IRET | ||
| 430 | |||
| 431 | GETCOMDSK: | ||
| 432 | MOV DX,OFFSET RESGROUP:NEEDCOM | ||
| 433 | MOV AH,PRINTBUF | ||
| 434 | INT 33 | ||
| 435 | MOV AX,0C07H ;Get char without testing or echo | ||
| 436 | INT 33 | ||
| 437 | JMP LODCOM | ||
| 438 | |||
| 439 | CRLF: | ||
| 440 | MOV DX,OFFSET RESGROUP:NEWLIN | ||
| 441 | PUSH AX | ||
| 442 | MOV AH,PRINTBUF | ||
| 443 | INT 33 | ||
| 444 | POP AX | ||
| 445 | RET10: RET | ||
| 446 | |||
| 447 | LOADCOM: | ||
| 448 | PUSH DS | ||
| 449 | MOV DS,[TRNSEG] | ||
| 450 | MOV DX,100H | ||
| 451 | MOV AH,SETDMA | ||
| 452 | INT 33 | ||
| 453 | POP DS | ||
| 454 | MOV DX,OFFSET RESGROUP:COMFCB | ||
| 455 | MOV AH,OPEN | ||
| 456 | INT 33 ;Open COMMAND.COM | ||
| 457 | OR AL,AL | ||
| 458 | JZ READCOM | ||
| 459 | MOV DX,OFFSET RESGROUP:NEEDCOM | ||
| 460 | PROMPTCOM: | ||
| 461 | MOV AH,PRINTBUF | ||
| 462 | INT 33 | ||
| 463 | MOV AX,0C07H ;Get char without testing or echo | ||
| 464 | INT 33 | ||
| 465 | JMP SHORT LOADCOM | ||
| 466 | READCOM: | ||
| 467 | MOV WORD PTR[COMFCB+RR],OFFSET RESGROUP:TRANSTART | ||
| 468 | XOR AX,AX | ||
| 469 | MOV WORD PTR[COMFCB+RR+2],AX | ||
| 470 | MOV [COMFCB],AL ;Use default drive | ||
| 471 | INC AX | ||
| 472 | MOV WORD PTR[COMFCB+RECLEN],AX | ||
| 473 | MOV CX,COMLEN | ||
| 474 | MOV DX,OFFSET RESGROUP:COMFCB | ||
| 475 | MOV AH,RDBLK | ||
| 476 | INT 33 | ||
| 477 | OR AL,AL | ||
| 478 | JZ RET10 | ||
| 479 | WRONGCOM: | ||
| 480 | MOV DX,OFFSET RESGROUP:COMBAD | ||
| 481 | JMP SHORT PROMPTCOM | ||
| 482 | |||
| 483 | CHKSUM: | ||
| 484 | CLD | ||
| 485 | PUSH DS | ||
| 486 | MOV DS,[TRNSEG] | ||
| 487 | MOV SI,100H | ||
| 488 | MOV CX,COMLEN | ||
| 489 | SHR CX,1 | ||
| 490 | XOR DX,DX | ||
| 491 | CHK: | ||
| 492 | LODSW | ||
| 493 | ADD DX,AX | ||
| 494 | LOOP CHK | ||
| 495 | POP DS | ||
| 496 | RET | ||
| 497 | |||
| 498 | SETVECT: | ||
| 499 | MOV DX,OFFSET RESGROUP:LODCOM | ||
| 500 | MOV AX,2522H ;Set Terminate address | ||
| 501 | INT 21H | ||
| 502 | MOV DX,OFFSET RESGROUP:CONTC | ||
| 503 | MOV AX,2523H ;Set Ctrl-C address | ||
| 504 | INT 21H | ||
| 505 | MOV DX,OFFSET RESGROUP:DSKERR | ||
| 506 | MOV AX,2524H ;Set Hard Disk Error address | ||
| 507 | INT 33 | ||
| 508 | MOV DX,OFFSET RESGROUP:RESIDENT | ||
| 509 | MOV AX,2527H ;Set Terminate and Stay Resident address | ||
| 510 | INT 33 | ||
| 511 | RET | ||
| 512 | RESCODESIZE EQU $-ZERO | ||
| 513 | CODERES ENDS | ||
| 514 | |||
| 515 | ;******************************************************************* | ||
| 516 | ;START OF INIT PORTION | ||
| 517 | ;This code is overlayed the first time the TPA is used. | ||
| 518 | |||
| 519 | INIT SEGMENT BYTE | ||
| 520 | |||
| 521 | ORG 0 | ||
| 522 | ZERO = $ | ||
| 523 | CONPROC: | ||
| 524 | MOV SP,OFFSET RESGROUP:RSTACK | ||
| 525 | |||
| 526 | IF HIGHMEM | ||
| 527 | MOV AX,WORD PTR DS:[2] | ||
| 528 | SUB AX,((RESCODESIZE+RESDATASIZE)+15)/16 ;Subtract size of resident | ||
| 529 | MOV WORD PTR DS:[2],AX | ||
| 530 | MOV ES,AX | ||
| 531 | MOV SI,100H | ||
| 532 | MOV DI,SI | ||
| 533 | MOV CX,((RESCODESIZE+RESDATASIZE)-100H+1)/2 ;Length of resident in words | ||
| 534 | REP MOVSW ;Move to end of memory | ||
| 535 | MOV DS,AX | ||
| 536 | MOV [LTPA],CS | ||
| 537 | ENDIF | ||
| 538 | |||
| 539 | IF NOT HIGHMEM | ||
| 540 | MOV AX,CS | ||
| 541 | ADD AX,((RESCODESIZE+RESDATASIZE)+15)/16 ;Compute segment of TPA | ||
| 542 | MOV [LTPA],AX | ||
| 543 | MOV AX,WORD PTR DS:[2] | ||
| 544 | ENDIF | ||
| 545 | |||
| 546 | MOV [MYSEG],DS | ||
| 547 | MOV [MEMSIZ],AX | ||
| 548 | SUB AX,TRNLEN ;Subtract size of transient | ||
| 549 | MOV [TRNSEG],AX | ||
| 550 | CALL SETVECT | ||
| 551 | CALL LOADCOM | ||
| 552 | CALL CHKSUM | ||
| 553 | MOV [SUM],DX | ||
| 554 | |||
| 555 | IF MSVER | ||
| 556 | IF HIGHMEM | ||
| 557 | PUSH DS | ||
| 558 | PUSH CS | ||
| 559 | POP DS | ||
| 560 | ENDIF | ||
| 561 | MOV DX,OFFSET RESGROUP:HEADER | ||
| 562 | MOV AH,PRINTBUF | ||
| 563 | INT 33 | ||
| 564 | IF HIGHMEM | ||
| 565 | POP DS | ||
| 566 | ENDIF | ||
| 567 | ENDIF | ||
| 568 | |||
| 569 | MOV DX,OFFSET RESGROUP:BATFCB | ||
| 570 | MOV AH,OPEN | ||
| 571 | INT 33 ;See if AUTOEXEC.BAT exists | ||
| 572 | MOV WORD PTR[BATFCB+RECLEN],1 ;Set record length to 1 | ||
| 573 | OR AL,AL ;Zero means file found | ||
| 574 | JZ DRV0 | ||
| 575 | MOV [BATCH],0 ;Not found--turn off batch job | ||
| 576 | MOV AX,OFFSET TRANGROUP:DATINIT | ||
| 577 | MOV WORD PTR[INITADD],AX | ||
| 578 | MOV AX,[TRNSEG] | ||
| 579 | MOV WORD PTR[INITADD+2],AX | ||
| 580 | CALL DWORD PTR DS:[INITADD] | ||
| 581 | |||
| 582 | IF IBMVER | ||
| 583 | MOV DX,OFFSET RESGROUP:HEADER | ||
| 584 | MOV AH,PRINTBUF | ||
| 585 | INT 33 | ||
| 586 | ENDIF | ||
| 587 | |||
| 588 | DRV0: | ||
| 589 | JMP HAVCOM | ||
| 590 | |||
| 591 | |||
| 592 | IF MSVER | ||
| 593 | HEADER DB 13,10,"Command v. 1.17" | ||
| 594 | IF HIGHMEM | ||
| 595 | DB "H" | ||
| 596 | ENDIF | ||
| 597 | DB 13,10,"$" | ||
| 598 | ENDIF | ||
| 599 | |||
| 600 | IF IBMVER | ||
| 601 | HEADER DB 13,10,13,10,"The IBM Personal Computer DOS",13,10 | ||
| 602 | DB "Version 1.10 (C)Copyright IBM Corp 1981, 1982",13,10,"$" | ||
| 603 | DB "Licensed Material - Program Property of IBM" | ||
| 604 | ENDIF | ||
| 605 | |||
| 606 | INITSIZE EQU $-ZERO | ||
| 607 | INIT ENDS | ||
| 608 | |||
| 609 | ;This TAIL segment is used to produce a PARA aligned label in the resident | ||
| 610 | ; group which is the location where the transient segments will be loaded | ||
| 611 | ; initialy. | ||
| 612 | |||
| 613 | TAIL SEGMENT PARA | ||
| 614 | ORG 0 | ||
| 615 | TRANSTART LABEL WORD | ||
| 616 | TAIL ENDS | ||
| 617 | |||
| 618 | ;******************************************************************** | ||
| 619 | ;START OF TRANSIENT PORTION | ||
| 620 | ;This code is loaded at the end of memory and may be overwritten by | ||
| 621 | ;memory-intensive user programs. | ||
| 622 | |||
| 623 | TRANCODE SEGMENT PARA | ||
| 624 | ASSUME CS:TRANGROUP,DS:TRANGROUP,ES:TRANGROUP,SS:TRANGROUP | ||
| 625 | |||
| 626 | WSWITCH EQU 1 ;Wide display during DIR | ||
| 627 | PSWITCH EQU 2 ;Pause (or Page) mode during DIR | ||
| 628 | VSWITCH EQU 4 ;Verify during COPY | ||
| 629 | ASWITCH EQU 8 ;ASCII mode during COPY | ||
| 630 | BSWITCH EQU 10H ;Binary mode during COPY | ||
| 631 | |||
| 632 | ORG 0 | ||
| 633 | ZERO = $ | ||
| 634 | |||
| 635 | ORG 100H ;Allow for 100H parameter area | ||
| 636 | |||
| 637 | SETDRV: | ||
| 638 | MOV AH,SELDRV | ||
| 639 | INT 21H | ||
| 640 | COMMAND: | ||
| 641 | CLD | ||
| 642 | MOV AX,CS | ||
| 643 | MOV SS,AX | ||
| 644 | MOV SP,OFFSET TRANGROUP:STACK | ||
| 645 | MOV ES,AX | ||
| 646 | MOV DS,AX | ||
| 647 | STI | ||
| 648 | MOV AX,46*100H | ||
| 649 | MOV DL,0 | ||
| 650 | INT 33 ;Turn off verify after write | ||
| 651 | MOV AX,CS ;Get segment we're in | ||
| 652 | SUB AX,[TPA] ;AX=size ot TPA in paragraphs | ||
| 653 | MOV DX,16 | ||
| 654 | MUL DX ;DX:AX=size of TPA in bytes | ||
| 655 | OR DX,DX ;See if over 64K | ||
| 656 | JZ SAVSIZ ;OK if not | ||
| 657 | MOV AX,-1 ;If so, limit to 65535 bytes | ||
| 658 | SAVSIZ: | ||
| 659 | MOV [BYTCNT],AX ;Max no. of bytes that can be buffered | ||
| 660 | CALL CRLF2 | ||
| 661 | GETCOM: | ||
| 662 | MOV AH,GETDRV | ||
| 663 | INT 21H | ||
| 664 | MOV [CURDRV],AL | ||
| 665 | ADD AL,"A" | ||
| 666 | CALL OUT ;Print letter for default drive | ||
| 667 | MOV AL,SYM | ||
| 668 | CALL OUT | ||
| 669 | MOV DS,[RESSEG] ;All batch work must use resident seg. | ||
| 670 | ASSUME DS:RESGROUP | ||
| 671 | TEST [BATCH],-1 | ||
| 672 | JNZ READBAT | ||
| 673 | PUSH CS | ||
| 674 | POP DS ;Need local segment to point to buffer | ||
| 675 | ASSUME DS:TRANGROUP | ||
| 676 | MOV DX,OFFSET TRANGROUP:COMBUF | ||
| 677 | MOV AH,INBUF | ||
| 678 | INT 21H ;Get a command | ||
| 679 | JMP DOCOM | ||
| 680 | |||
| 681 | ;All batch proccessing has DS set to segment of resident portion | ||
| 682 | ASSUME DS:RESGROUP | ||
| 683 | NEEDPARM: | ||
| 684 | CALL GETBATBYT | ||
| 685 | CMP AL,"%" ;Check for two consecutive % | ||
| 686 | JZ SAVBATBYT | ||
| 687 | CMP AL,13 ;Check for end-of-line | ||
| 688 | JZ SAVBATBYT | ||
| 689 | SUB AL,"0" | ||
| 690 | JB RDBAT ;Ignore parameter reference if invalid | ||
| 691 | CMP AL,9 | ||
| 692 | JA RDBAT | ||
| 693 | CBW | ||
| 694 | MOV SI,AX | ||
| 695 | SHL SI,1 ;Two bytes per entry | ||
| 696 | MOV SI,[SI+OFFSET RESGROUP:PARMTAB] ;Get pointer to corresponding parameter | ||
| 697 | CMP SI,-1 ;Check if parameter exists | ||
| 698 | JZ RDBAT ;Ignore if it doesn't | ||
| 699 | MOV AH,OUTCH | ||
| 700 | RDPARM: | ||
| 701 | LODSB ;From resident segment | ||
| 702 | CMP AL,0DH ;Check for end of parameter | ||
| 703 | JZ RDBAT | ||
| 704 | STOSB ;To transient segment | ||
| 705 | MOV DL,AL | ||
| 706 | INT 33 ;Display paramters too | ||
| 707 | JMP SHORT RDPARM | ||
| 708 | |||
| 709 | PROMPTBAT: | ||
| 710 | MOV AH,PRINTBUF | ||
| 711 | MOV DX,OFFSET RESGROUP:NEEDBAT | ||
| 712 | INT 33 ;Prompt for batch file | ||
| 713 | MOV AH,PRINTBUF | ||
| 714 | MOV DX,OFFSET RESGROUP:PROMPT | ||
| 715 | INT 33 | ||
| 716 | MOV AX,0C00H+INCHAR | ||
| 717 | INT 33 | ||
| 718 | JMP COMMAND | ||
| 719 | |||
| 720 | BADCOMJ1:JMP BADCOM | ||
| 721 | |||
| 722 | READBAT: | ||
| 723 | MOV DX,OFFSET RESGROUP:BATFCB | ||
| 724 | MOV AH,OPEN | ||
| 725 | INT 33 ;Make sure batch file still exists | ||
| 726 | OR AL,AL | ||
| 727 | JNZ PROMPTBAT ;If OPEN fails, prompt for disk | ||
| 728 | MOV WORD PTR [BATFCB+RECLEN],1 | ||
| 729 | MOV DX,OFFSET RESGROUP:BATBYT | ||
| 730 | MOV AH,SETDMA | ||
| 731 | INT 33 | ||
| 732 | MOV DI,OFFSET TRANGROUP:COMBUF+2 | ||
| 733 | RDBAT: | ||
| 734 | CALL GETBATBYT | ||
| 735 | CMP AL,"%" ;Check for parameter | ||
| 736 | JZ NEEDPARM | ||
| 737 | SAVBATBYT: | ||
| 738 | STOSB | ||
| 739 | CALL OUT ;Display batched command line | ||
| 740 | CMP AL,0DH | ||
| 741 | JNZ RDBAT | ||
| 742 | SUB DI,OFFSET TRANGROUP:COMBUF+3 | ||
| 743 | MOV AX,DI | ||
| 744 | MOV ES:[COMBUF+1],AL ;Set length of line | ||
| 745 | CALL GETBATBYT ;Eat linefeed | ||
| 746 | PUSH CS | ||
| 747 | POP DS ;Go back to local segment | ||
| 748 | ASSUME DS:TRANGROUP | ||
| 749 | DOCOM: | ||
| 750 | ;All segments are local for command line processing | ||
| 751 | MOV AL,10 | ||
| 752 | CALL OUT | ||
| 753 | MOV SI,OFFSET TRANGROUP:COMBUF+2 | ||
| 754 | MOV DI,OFFSET TRANGROUP:IDLEN | ||
| 755 | MOV AX,2901H ;Make FCB with blank scan-off | ||
| 756 | INT 21H | ||
| 757 | CMP AL,1 ;Check for ambiguous command name | ||
| 758 | JZ BADCOMJ1 ;Ambiguous commands not allowed | ||
| 759 | CMP AL,-1 | ||
| 760 | JNZ DRVGD | ||
| 761 | JMP DRVBAD | ||
| 762 | DRVGD: | ||
| 763 | MOV AL,[DI] | ||
| 764 | MOV [SPECDRV],AL | ||
| 765 | MOV AL," " | ||
| 766 | MOV CX,9 | ||
| 767 | INC DI | ||
| 768 | REPNE SCASB ;Count no. of letters in command name | ||
| 769 | MOV AL,9 | ||
| 770 | SUB AL,CL | ||
| 771 | MOV [IDLEN],AL | ||
| 772 | MOV DI,81H | ||
| 773 | MOV CX,0 | ||
| 774 | PUSH SI | ||
| 775 | COMTAIL: | ||
| 776 | LODSB | ||
| 777 | STOSB ;Move command tail to 80H | ||
| 778 | CMP AL,13 | ||
| 779 | LOOPNZ COMTAIL | ||
| 780 | NOT CL | ||
| 781 | MOV BYTE PTR DS:[80H],CL | ||
| 782 | POP SI | ||
| 783 | ;If the command has 0 parameters must check here for | ||
| 784 | ;any switches that might be present. | ||
| 785 | ;SI -> first character after the command. | ||
| 786 | MOV [FLAGER],0 ;Set error flag before any calls to switch | ||
| 787 | CALL SWITCH ;Is the next character a "/" | ||
| 788 | MOV [COMSW],AX | ||
| 789 | MOV DI,FCB | ||
| 790 | MOV AX,2901H | ||
| 791 | INT 21H | ||
| 792 | MOV [PARM1],AL ;Save result of parse | ||
| 793 | CALL SWITCH | ||
| 794 | MOV [ARG1S],AX | ||
| 795 | MOV DI,FCB+10H | ||
| 796 | MOV AX,2901H | ||
| 797 | INT 21H ;Parse file name | ||
| 798 | MOV [PARM2],AL ;Save result | ||
| 799 | CALL SWITCH | ||
| 800 | MOV [ARG2S],AX | ||
| 801 | MOV AL,[IDLEN] | ||
| 802 | MOV DL,[SPECDRV] | ||
| 803 | OR DL,DL ;Check if drive was specified | ||
| 804 | JZ OK | ||
| 805 | JMP DRVCHK | ||
| 806 | OK: DEC AL ;Check for null command | ||
| 807 | JNZ FNDCOM | ||
| 808 | JMP GETCOM | ||
| 809 | |||
| 810 | RETSW: | ||
| 811 | XCHG AX,BX ;Put switches in AX | ||
| 812 | RET | ||
| 813 | |||
| 814 | SWITCH: | ||
| 815 | XOR BX,BX ;Initialize - no switches set | ||
| 816 | SWLOOP: | ||
| 817 | CALL SCANOFF ;Skip any delimiters | ||
| 818 | CMP AL,"/" ;Is it a switch specifier? | ||
| 819 | JNZ RETSW ;No -- we're finished | ||
| 820 | INC SI ;Skip over "/" | ||
| 821 | CALL SCANOFF | ||
| 822 | INC SI | ||
| 823 | ;Convert lower case input to upper case | ||
| 824 | CMP AL,"a" | ||
| 825 | JB SAVCHR | ||
| 826 | CMP AL,"z" | ||
| 827 | JA SAVCHR | ||
| 828 | SUB AL,20H ;Lower-case changed to upper-case | ||
| 829 | SAVCHR: | ||
| 830 | MOV DI,OFFSET TRANGROUP:SWLIST | ||
| 831 | MOV CX,SWCOUNT | ||
| 832 | REPNE SCASB ;Look for matching switch | ||
| 833 | JNZ BADSW | ||
| 834 | MOV AX,1 | ||
| 835 | SHL AX,CL ;Set a bit for the switch | ||
| 836 | OR BX,AX | ||
| 837 | JMP SHORT SWLOOP | ||
| 838 | |||
| 839 | BADSW: | ||
| 840 | MOV [FLAGER],1 ;Record error in switch | ||
| 841 | JMP SHORT SWLOOP | ||
| 842 | |||
| 843 | SWLIST DB "BAVPW" | ||
| 844 | SWCOUNT EQU $-SWLIST | ||
| 845 | |||
| 846 | DRVBAD: | ||
| 847 | MOV DX,OFFSET TRANGROUP:BADDRV | ||
| 848 | JMP ERROR | ||
| 849 | |||
| 850 | FNDCOM: | ||
| 851 | MOV SI,OFFSET TRANGROUP:COMTAB ;Prepare to search command table | ||
| 852 | MOV CH,0 | ||
| 853 | FINDCOM: | ||
| 854 | MOV DI,OFFSET TRANGROUP:IDLEN | ||
| 855 | MOV CL,[SI] | ||
| 856 | JCXZ EXTERNAL | ||
| 857 | REPE CMPSB | ||
| 858 | LAHF | ||
| 859 | ADD SI,CX ;Bump to next position without affecting flags | ||
| 860 | SAHF | ||
| 861 | LODSB ;Get flag for drive check | ||
| 862 | MOV [CHKDRV],AL | ||
| 863 | LODSW ;Get address of command | ||
| 864 | JNZ FINDCOM | ||
| 865 | MOV DX,AX | ||
| 866 | CMP [CHKDRV],0 | ||
| 867 | JZ NOCHECK | ||
| 868 | MOV AL,[PARM1] | ||
| 869 | OR AL,[PARM2] ;Check if either parm. had invalid drive | ||
| 870 | CMP AL,-1 | ||
| 871 | JZ DRVBAD | ||
| 872 | NOCHECK:CALL DX | ||
| 873 | COMJMP: JMP COMMAND | ||
| 874 | |||
| 875 | BADCOMJ:JMP BADCOM | ||
| 876 | |||
| 877 | SETDRV1: | ||
| 878 | JMP SETDRV | ||
| 879 | |||
| 880 | DRVCHK: | ||
| 881 | DEC DL ;Adjust for correct drive number | ||
| 882 | DEC AL ;Check if anything else is on line | ||
| 883 | JZ SETDRV1 | ||
| 884 | EXTERNAL: | ||
| 885 | MOV AL,[SPECDRV] | ||
| 886 | MOV [IDLEN],AL | ||
| 887 | MOV WORD PTR[COM],4F00H+"C" ;"CO" | ||
| 888 | MOV BYTE PTR[COM+2],"M" | ||
| 889 | MOV DX,OFFSET TRANGROUP:IDLEN | ||
| 890 | MOV AH,OPEN | ||
| 891 | INT 33 ;Check if command to be executed | ||
| 892 | MOV [FILTYP],AL ;0 for COM files, -1 for EXE files | ||
| 893 | OR AL,AL | ||
| 894 | JZ EXECUTE | ||
| 895 | MOV WORD PTR[COM],5800H+"E" ;"EX" | ||
| 896 | MOV BYTE PTR[COM+2],"E" | ||
| 897 | INT 33 ;Check for EXE file | ||
| 898 | OR AL,AL | ||
| 899 | JZ EXECUTE | ||
| 900 | MOV WORD PTR[COM],4100H+"B" ;"BA" | ||
| 901 | MOV BYTE PTR[COM+2],"T" | ||
| 902 | INT 33 ;Check if batch file to be executed | ||
| 903 | OR AL,AL | ||
| 904 | JNZ BADCOMJ | ||
| 905 | BATCOM: | ||
| 906 | ;Batch parameters are read with ES set to segment of resident part | ||
| 907 | MOV ES,[RESSEG] | ||
| 908 | ASSUME ES:RESGROUP | ||
| 909 | MOV DI,OFFSET RESGROUP:PARMTAB | ||
| 910 | MOV AX,-1 | ||
| 911 | MOV CX,10 | ||
| 912 | REP STOSW ;Zero parameter pointer table | ||
| 913 | MOV SI,OFFSET TRANGROUP:COMBUF+2 | ||
| 914 | MOV DI,OFFSET RESGROUP:PARMBUF | ||
| 915 | MOV BX,OFFSET RESGROUP:PARMTAB | ||
| 916 | EACHPARM: | ||
| 917 | CALL SCANOFF | ||
| 918 | CMP AL,0DH | ||
| 919 | JZ HAVPARM | ||
| 920 | MOV ES:[BX],DI ;Set pointer table to point to actual parameter | ||
| 921 | INC BX | ||
| 922 | INC BX | ||
| 923 | MOVPARM: | ||
| 924 | LODSB | ||
| 925 | CALL DELIM | ||
| 926 | JZ ENDPARM ;Check for end of parameter | ||
| 927 | STOSB | ||
| 928 | CMP AL,0DH | ||
| 929 | JZ HAVPARM | ||
| 930 | JMP SHORT MOVPARM | ||
| 931 | ENDPARM: | ||
| 932 | MOV AL,0DH | ||
| 933 | STOSB ;End-of-parameter marker | ||
| 934 | CMP BX,OFFSET RESGROUP:PARMTAB+20 ;Maximum number of parameters? | ||
| 935 | JB EACHPARM | ||
| 936 | HAVPARM: | ||
| 937 | MOV SI,OFFSET TRANGROUP:IDLEN | ||
| 938 | MOV DI,OFFSET RESGROUP:BATFCB | ||
| 939 | MOV CX,16 | ||
| 940 | REP MOVSW ;Move into private batch FCB | ||
| 941 | XOR AX,AX | ||
| 942 | PUSH ES | ||
| 943 | POP DS ;Simply batch FCB setup | ||
| 944 | ASSUME DS:RESGROUP | ||
| 945 | MOV WORD PTR[BATFCB+RR],AX | ||
| 946 | MOV WORD PTR[BATFCB+RR+2],AX ;Zero RR field | ||
| 947 | INC AX | ||
| 948 | MOV WORD PTR[BATFCB+RECLEN],AX ;Set record length to 1 byte | ||
| 949 | MOV [BATCH],AL ;Flag batch job in progress | ||
| 950 | JMP COMMAND | ||
| 951 | ASSUME DS:TRANGROUP,ES:TRANGROUP | ||
| 952 | |||
| 953 | EXECUTE: | ||
| 954 | MOV AX,WORD PTR[IDLEN+16] | ||
| 955 | OR AX,WORD PTR[IDLEN+18] ;See if zero length | ||
| 956 | JZ BADCOM ;If so, error | ||
| 957 | XOR AX,AX | ||
| 958 | MOV WORD PTR[IDLEN+RR],AX | ||
| 959 | MOV WORD PTR[IDLEN+RR+2],AX ;Set RR field to zero | ||
| 960 | INC AX | ||
| 961 | MOV WORD PTR[IDLEN+RECLEN],AX ;Set record length field to 1 | ||
| 962 | MOV DX,[TPA] | ||
| 963 | MOV BX,DX | ||
| 964 | MOV AH,SETBASE | ||
| 965 | INT 21H | ||
| 966 | TEST [FILTYP],-1 ;Check if file is COM or EXE | ||
| 967 | JZ COMLOAD | ||
| 968 | JMP EXELOAD | ||
| 969 | COMLOAD:PUSH DS | ||
| 970 | MOV DS,DX | ||
| 971 | MOV DX,100H | ||
| 972 | MOV AH,SETDMA | ||
| 973 | INT 21H | ||
| 974 | POP DS | ||
| 975 | MOV CX,[BYTCNT] | ||
| 976 | SUB CX,100H | ||
| 977 | MOV DX,OFFSET TRANGROUP:IDLEN | ||
| 978 | MOV AH,RDBLK | ||
| 979 | INT 21H | ||
| 980 | DEC AL | ||
| 981 | MOV DX,OFFSET TRANGROUP:TOOBIG | ||
| 982 | JNZ ERROR | ||
| 983 | ;Set up exit conditions | ||
| 984 | MOV CX,[BYTCNT] | ||
| 985 | MOV DS,BX | ||
| 986 | MOV ES,BX | ||
| 987 | CLI | ||
| 988 | MOV SS,BX | ||
| 989 | MOV SP,CX | ||
| 990 | STI | ||
| 991 | SUB CX,100H ;Allow some stack space | ||
| 992 | XOR AX,AX | ||
| 993 | PUSH AX | ||
| 994 | MOV AX,100H | ||
| 995 | PUSH BX | ||
| 996 | PUSH AX | ||
| 997 | CALL SETUP | ||
| 998 | XXX PROC FAR | ||
| 999 | RET | ||
| 1000 | XXX ENDP | ||
| 1001 | BADCOM: | ||
| 1002 | MOV DX,OFFSET TRANGROUP:BADNAM | ||
| 1003 | ERROR: | ||
| 1004 | MOV AH,PRINTBUF | ||
| 1005 | INT 21H | ||
| 1006 | JMP COMMAND | ||
| 1007 | |||
| 1008 | CHKCNT: | ||
| 1009 | TEST [FILECNT],-1 | ||
| 1010 | JNZ ENDDIR | ||
| 1011 | MOV DX,OFFSET TRANGROUP:NOTFND | ||
| 1012 | JMP ERROR | ||
| 1013 | |||
| 1014 | ENDDIR: | ||
| 1015 | ;Make sure last line ends with CR/LF | ||
| 1016 | MOV AL,[LINLEN] | ||
| 1017 | CMP AL,[LINCNT] ;Will be equal if just had CR/LF | ||
| 1018 | JZ MESSAGE | ||
| 1019 | CALL CRLF2 | ||
| 1020 | MESSAGE: | ||
| 1021 | MOV SI,[FILECNT] | ||
| 1022 | XOR DI,DI | ||
| 1023 | CALL DISP32BITS | ||
| 1024 | MOV DX,OFFSET TRANGROUP:DIRMES | ||
| 1025 | MOV AH,PRINTBUF | ||
| 1026 | INT 21H | ||
| 1027 | RET | ||
| 1028 | |||
| 1029 | CATALOG: | ||
| 1030 | MOV AL,"?" ;*.* is default file spec. | ||
| 1031 | MOV DI,5DH | ||
| 1032 | MOV CX,11 | ||
| 1033 | REP STOSB | ||
| 1034 | MOV SI,81H | ||
| 1035 | CALL SWITCH | ||
| 1036 | MOV DI,5CH | ||
| 1037 | MOV AX,41*100H+0DH ;Parse with default name and extension | ||
| 1038 | INT 33 | ||
| 1039 | |||
| 1040 | ;Begin by processing any switches that may have been specified. | ||
| 1041 | ;BITS will contain any information about switches that was | ||
| 1042 | ;found when the command line was parsed. | ||
| 1043 | |||
| 1044 | SETSWT: | ||
| 1045 | MOV AX,[COMSW] ;Get switches from command | ||
| 1046 | OR AX,[ARG1S] ;OR in switches from first parameter | ||
| 1047 | MOV [BITS],AX | ||
| 1048 | MOV BYTE PTR[FULLSCR],LINPERPAG | ||
| 1049 | TEST AL,1 ;Look for /W | ||
| 1050 | MOV AL,NORMPERLIN | ||
| 1051 | JZ DIR | ||
| 1052 | MOV AL,WIDEPERLIN | ||
| 1053 | DIR: | ||
| 1054 | MOV [LINLEN],AL ;Set number of entries per line | ||
| 1055 | MOV [LINCNT],AL | ||
| 1056 | MOV [FILECNT],0 ;Keep track of how many files found | ||
| 1057 | MOV DX,OFFSET TRANGROUP:DIRBUF ;Set Disk transfer address | ||
| 1058 | MOV AH,SETDMA | ||
| 1059 | INT 21H | ||
| 1060 | MOV AH,SRCHFRST | ||
| 1061 | SHOWDIR: | ||
| 1062 | MOV DX,5CH ;DX -> Unopened FCB | ||
| 1063 | INT 21H ;Search for a file to match FCB | ||
| 1064 | INC AL ;FF = file not found | ||
| 1065 | JNZ AGAIN ;Either an error or we are finished | ||
| 1066 | JMP CHKCNT | ||
| 1067 | AGAIN: | ||
| 1068 | INC [FILECNT] ;Keep track of how many we find | ||
| 1069 | MOV SI,OFFSET TRANGROUP:DIRBUF+1 ;SI -> information returned by sys call | ||
| 1070 | CALL SHONAME | ||
| 1071 | TEST BYTE PTR[BITS],1 ;/W set? | ||
| 1072 | JNZ NEXENT ;If so, no size, date, or time | ||
| 1073 | CALL DISPSIZE ;Print size of file | ||
| 1074 | CALL TWOSPC | ||
| 1075 | MOV AX,WORD PTR[DIRBUF+25] ;Get date | ||
| 1076 | OR AX,AX | ||
| 1077 | JZ NEXENT ;Skip if no date | ||
| 1078 | MOV DX,AX | ||
| 1079 | MOV CL,5 | ||
| 1080 | SHR AX,CL ;Align month | ||
| 1081 | AND AL,0FH | ||
| 1082 | MOV BH,"0"-" " ;Enable zero suppression | ||
| 1083 | CALL OUT2 | ||
| 1084 | MOV AL,"-" | ||
| 1085 | CALL OUT | ||
| 1086 | MOV AL,DL | ||
| 1087 | AND AL,1FH ;Mask to day | ||
| 1088 | CALL OUT2 | ||
| 1089 | MOV AL,"-" | ||
| 1090 | CALL OUT | ||
| 1091 | MOV AL,DH | ||
| 1092 | SHR AL,1 ;Align year | ||
| 1093 | ADD AX,80 ;Relative 1980 | ||
| 1094 | CMP AL,100 | ||
| 1095 | JB MILLENIUM | ||
| 1096 | SUB AL,100 | ||
| 1097 | MILLENIUM: | ||
| 1098 | CALL OUT2 | ||
| 1099 | MOV BX,WORD PTR[DIRBUF+23] ;Get time | ||
| 1100 | OR BX,BX ;Time field present? | ||
| 1101 | JZ NEXENT | ||
| 1102 | CALL TWOSPC | ||
| 1103 | SHR BX,1 | ||
| 1104 | SHR BX,1 | ||
| 1105 | SHR BX,1 | ||
| 1106 | SHR BL,1 | ||
| 1107 | SHR BL,1 ;Hours in BH, minutes in BL | ||
| 1108 | MOV AL,BH | ||
| 1109 | MOV DH,"a" ;Assume A.M. | ||
| 1110 | CMP AL,12 ;In the afternoon? | ||
| 1111 | JB MORN | ||
| 1112 | MOV DH,"p" | ||
| 1113 | JE MORN | ||
| 1114 | SUB AL,12 ;Keep it to 12 hours or less | ||
| 1115 | MORN: | ||
| 1116 | OR AL,AL ;Before 1 am? | ||
| 1117 | JNZ SHOHOURS | ||
| 1118 | MOV AL,12 | ||
| 1119 | SHOHOURS: | ||
| 1120 | MOV BH,"0"-" " ;Enable zero suppression | ||
| 1121 | CALL OUT2 | ||
| 1122 | MOV AL,":" | ||
| 1123 | CALL OUT | ||
| 1124 | MOV AL,BL ;Output minutes | ||
| 1125 | CALL OUT2 | ||
| 1126 | MOV AL,DH ;Get "a" or "p" | ||
| 1127 | CALL OUT | ||
| 1128 | NEXENT: | ||
| 1129 | DEC [LINCNT] | ||
| 1130 | JNZ SAMLIN | ||
| 1131 | NEXLIN: | ||
| 1132 | MOV AL,[LINLEN] | ||
| 1133 | MOV [LINCNT],AL | ||
| 1134 | CALL CRLF2 | ||
| 1135 | TEST BYTE PTR[BITS],2 ;/P switch present? | ||
| 1136 | JZ SCROLL ;If not, just continue | ||
| 1137 | DEC BYTE PTR[FULLSCR] | ||
| 1138 | JNZ SCROLL | ||
| 1139 | MOV BYTE PTR[FULLSCR],LINPERPAG | ||
| 1140 | MOV AH,PRINTBUF | ||
| 1141 | MOV DX,OFFSET TRANGROUP:PAUSMES | ||
| 1142 | INT 33 | ||
| 1143 | MOV AX,0C08H ;Wait for any character to be typed | ||
| 1144 | INT 21H | ||
| 1145 | CALL CRLF2 | ||
| 1146 | SCROLL: | ||
| 1147 | MOV AH,SRCHNXT | ||
| 1148 | JMP SHOWDIR | ||
| 1149 | |||
| 1150 | SAMLIN: | ||
| 1151 | MOV AL,9 ;Output a tab | ||
| 1152 | CALL OUT | ||
| 1153 | JMP SHORT SCROLL | ||
| 1154 | |||
| 1155 | SHONAME: | ||
| 1156 | MOV CX,8 | ||
| 1157 | CALL OUTCNT | ||
| 1158 | CALL ONESPC | ||
| 1159 | MOV CX,3 | ||
| 1160 | OUTCNT: | ||
| 1161 | LODSB | ||
| 1162 | CALL OUT | ||
| 1163 | LOOP OUTCNT | ||
| 1164 | RET | ||
| 1165 | |||
| 1166 | TWOSPC: | ||
| 1167 | CALL ONESPC | ||
| 1168 | ONESPC: | ||
| 1169 | MOV AL," " | ||
| 1170 | JMP OUT | ||
| 1171 | |||
| 1172 | CRLF2: | ||
| 1173 | MOV AL,13 | ||
| 1174 | CALL OUT | ||
| 1175 | MOV AL,10 | ||
| 1176 | JMP OUT | ||
| 1177 | |||
| 1178 | DISPSIZE: | ||
| 1179 | MOV SI,WORD PTR[DIRBUF+29] | ||
| 1180 | MOV DI,WORD PTR[DIRBUF+31] | ||
| 1181 | DISP32BITS: | ||
| 1182 | ;Prints the 32-bit number DI:SI on the console in decimal. Uses a total | ||
| 1183 | ;of 9 digit positions with leading blanks. | ||
| 1184 | XOR AX,AX | ||
| 1185 | MOV BX,AX | ||
| 1186 | MOV BP,AX | ||
| 1187 | MOV CX,32 | ||
| 1188 | CONVLP: | ||
| 1189 | SHL SI,1 | ||
| 1190 | RCL DI,1 | ||
| 1191 | XCHG AX,BP | ||
| 1192 | CALL CONVWRD | ||
| 1193 | XCHG AX,BP | ||
| 1194 | XCHG AX,BX | ||
| 1195 | CALL CONVWRD | ||
| 1196 | XCHG AX,BX | ||
| 1197 | ADC AL,0 | ||
| 1198 | LOOP CONVLP | ||
| 1199 | ; Conversion complete. Print 9-digit number. | ||
| 1200 | MOV CX,1810H ;Allow leading zero blanking for 8 digits | ||
| 1201 | XCHG DX,AX | ||
| 1202 | CALL DIGIT | ||
| 1203 | XCHG AX,BX | ||
| 1204 | CALL OUTWORD | ||
| 1205 | XCHG AX,BP | ||
| 1206 | OUTWORD: | ||
| 1207 | PUSH AX | ||
| 1208 | MOV DL,AH | ||
| 1209 | CALL OUTBYTE | ||
| 1210 | POP DX | ||
| 1211 | OUTBYTE: | ||
| 1212 | MOV DH,DL | ||
| 1213 | SHR DL,1 | ||
| 1214 | SHR DL,1 | ||
| 1215 | SHR DL,1 | ||
| 1216 | SHR DL,1 | ||
| 1217 | CALL DIGIT | ||
| 1218 | MOV DL,DH | ||
| 1219 | DIGIT: | ||
| 1220 | AND DL,0FH | ||
| 1221 | JZ BLANKZER | ||
| 1222 | MOV CL,0 | ||
| 1223 | BLANKZER: | ||
| 1224 | DEC CH | ||
| 1225 | AND CL,CH | ||
| 1226 | OR DL,30H | ||
| 1227 | SUB DL,CL | ||
| 1228 | MOV AH,OUTCH | ||
| 1229 | INT 21H | ||
| 1230 | RET | ||
| 1231 | |||
| 1232 | CONVWRD: | ||
| 1233 | ADC AL,AL | ||
| 1234 | DAA | ||
| 1235 | XCHG AL,AH | ||
| 1236 | ADC AL,AL | ||
| 1237 | DAA | ||
| 1238 | XCHG AL,AH | ||
| 1239 | RET20: RET | ||
| 1240 | |||
| 1241 | ERASE: | ||
| 1242 | MOV CX,11 | ||
| 1243 | MOV SI,FCB+1 | ||
| 1244 | AMBSPEC: | ||
| 1245 | LODSB | ||
| 1246 | CMP AL,"?" | ||
| 1247 | JNZ ALLFIL | ||
| 1248 | LOOP AMBSPEC | ||
| 1249 | ALLFIL: | ||
| 1250 | CMP CX,0 | ||
| 1251 | JNZ NOPRMPT | ||
| 1252 | ASKAGN: | ||
| 1253 | MOV DX,OFFSET TRANGROUP:SUREMES ;"Are you sure (Y/N)?" | ||
| 1254 | MOV AH,PRINTBUF | ||
| 1255 | INT 21H | ||
| 1256 | MOV AX,0C00H+INCHAR | ||
| 1257 | INT 21H | ||
| 1258 | AND AL,5FH | ||
| 1259 | CMP AL,"N" | ||
| 1260 | JZ RET20 | ||
| 1261 | CMP AL,"Y" | ||
| 1262 | CALL CRLF2 | ||
| 1263 | JZ NOPRMPT | ||
| 1264 | JMP SHORT ASKAGN | ||
| 1265 | NOPRMPT: | ||
| 1266 | MOV AH,DELETE | ||
| 1267 | MOV BX,OFFSET TRANGROUP:NOTFND | ||
| 1268 | CMP BYTE PTR DS:[FCB+1]," " ;Check if parameter exists | ||
| 1269 | JMP SHORT OPFILE | ||
| 1270 | RENAME: | ||
| 1271 | MOV AH,RENAM | ||
| 1272 | MOV BX,OFFSET TRANGROUP:RENERR | ||
| 1273 | CMP BYTE PTR DS:[FCB+16+1]," " ;Check if parameter exists | ||
| 1274 | OPFILE: | ||
| 1275 | MOV DX,OFFSET TRANGROUP:MISNAM | ||
| 1276 | JZ ERRJ ;Error if missing parameter | ||
| 1277 | MOV DX,FCB | ||
| 1278 | INT 21H | ||
| 1279 | INC AL | ||
| 1280 | JNZ RET20 | ||
| 1281 | MOV DX,BX | ||
| 1282 | ERRJ: JMP ERROR | ||
| 1283 | |||
| 1284 | TYPEFIL: | ||
| 1285 | MOV DS,[TPA] | ||
| 1286 | XOR DX,DX | ||
| 1287 | MOV AH,SETDMA | ||
| 1288 | INT 21H | ||
| 1289 | PUSH CS | ||
| 1290 | POP DS | ||
| 1291 | MOV DX,FCB | ||
| 1292 | MOV AH,OPEN | ||
| 1293 | INT 21H | ||
| 1294 | OR AL,AL | ||
| 1295 | MOV DX,OFFSET TRANGROUP:NOTFND | ||
| 1296 | JNZ ERRJ | ||
| 1297 | XOR AX,AX | ||
| 1298 | MOV WORD PTR DS:[FCB+RR],AX ;Set RR field | ||
| 1299 | MOV WORD PTR DS:[FCB+RR+2],AX | ||
| 1300 | INC AX | ||
| 1301 | MOV WORD PTR DS:[FCB+RECLEN],AX ;Set record length | ||
| 1302 | MOV ES,[TPA] | ||
| 1303 | TYPELP: | ||
| 1304 | MOV DX,FCB | ||
| 1305 | MOV CX,[BYTCNT] | ||
| 1306 | MOV AH,RDBLK | ||
| 1307 | INT 21H | ||
| 1308 | JCXZ RET30 | ||
| 1309 | XOR SI,SI ;Start at 0 in TPA | ||
| 1310 | OUTLP: | ||
| 1311 | LODS BYTE PTR ES:[SI] ;In TPA segment | ||
| 1312 | CMP AL,1AH | ||
| 1313 | JZ RET30 | ||
| 1314 | MOV AH,OUTCH | ||
| 1315 | MOV DL,AL | ||
| 1316 | INT 21H | ||
| 1317 | LOOP OUTLP | ||
| 1318 | JMP SHORT TYPELP | ||
| 1319 | |||
| 1320 | RET30: RET ;Need a nearby RET | ||
| 1321 | |||
| 1322 | COPY: | ||
| 1323 | XOR AX,AX | ||
| 1324 | MOV [PLUS],AL ;Will keep track of "+"s | ||
| 1325 | MOV [FILECNT],AX | ||
| 1326 | MOV SI,81H ;Point to input line | ||
| 1327 | CALL SWITCH ;Skip over switches on command | ||
| 1328 | MOV BP,AX | ||
| 1329 | MOV DI,FCB | ||
| 1330 | CALL PARSNAM ;Scan first source | ||
| 1331 | MOV [PARM1],DL ;Save ambiguous flag | ||
| 1332 | MOV [SRCPT],SI ;Save pointer to command line | ||
| 1333 | ;Parse each name to find destination and check for /V switch | ||
| 1334 | SCANNAM: | ||
| 1335 | CALL PARSE | ||
| 1336 | JNZ SCANNAM | ||
| 1337 | GETDEST: | ||
| 1338 | MOV DI,OFFSET TRANGROUP:DEST | ||
| 1339 | MOV BX,BP ;Remeber switches so far | ||
| 1340 | XOR BP,BP ;Must have dest. swtiches alone | ||
| 1341 | CALL PARSNAM | ||
| 1342 | MOV [ARG2S],BP ;Remember switches on destination | ||
| 1343 | JNZ HAVDESTNAM ;File name present? | ||
| 1344 | INC DI ;Point to file name spot | ||
| 1345 | MOV AL,"?" ;Substitute *.* | ||
| 1346 | MOV CX,11 | ||
| 1347 | REP STOSB | ||
| 1348 | HAVDESTNAM: | ||
| 1349 | OR BX,BP ;BX = all switches combined | ||
| 1350 | AND BL,VSWITCH ;Verify requested? | ||
| 1351 | JZ NOVER | ||
| 1352 | MOV AX,46*100H+1 ;Set verify | ||
| 1353 | MOV DL,0 | ||
| 1354 | INT 33 | ||
| 1355 | NOVER: | ||
| 1356 | MOV DI,OFFSET TRANGROUP:DESTNAME | ||
| 1357 | MOV SI,OFFSET TRANGROUP:DEST+1 | ||
| 1358 | MOV BX,FCB+1 | ||
| 1359 | CALL BUILDNAME ;See if we can make it unambiguous | ||
| 1360 | MOV DI,OFFSET TRANGROUP:DESTNAME | ||
| 1361 | MOV AL,"?" | ||
| 1362 | MOV CX,11 | ||
| 1363 | REPNE SCASB ;Scan for "?" to see if ambiguous | ||
| 1364 | MOV AL,1 ;Flag if ambig. | ||
| 1365 | JZ AMBIG | ||
| 1366 | DEC AX ;AL=0 if unambig. | ||
| 1367 | AMBIG: | ||
| 1368 | MOV DL,AL | ||
| 1369 | MOV AH,[PLUS] ;1=found "+" | ||
| 1370 | XOR AL,1 ;0=ambig, 1=unambig destination | ||
| 1371 | AND AL,[PARM1] ;Source ambig. AND dest unambig. | ||
| 1372 | OR AL,AH ;OR found "+" means concatenation | ||
| 1373 | MOV [ASCII],AL ;Concatenation implies ASCII mode | ||
| 1374 | MOV [INEXACT],AL ;ASCII implies inexact copy | ||
| 1375 | SHL AL,1 | ||
| 1376 | OR AL,DL ;Combine multiple and concat flags | ||
| 1377 | MOV [PARM2],AL | ||
| 1378 | MOV AL,BYTE PTR[COMSW] | ||
| 1379 | CALL SETASC ;Check /A,/B on command | ||
| 1380 | MOV AL,BYTE PTR[ARG1S] | ||
| 1381 | CALL SETASC ;Check for ASCII on first filename | ||
| 1382 | MOV BYTE PTR[COMSW],AL ;Save starting switch values | ||
| 1383 | MOV AH,SRCHFRST | ||
| 1384 | CALL SEARCH ;Search for first source name | ||
| 1385 | MULTDEST: | ||
| 1386 | JZ FIRSTSRC ;Find a first source name? | ||
| 1387 | TEST [PARM2],1 ;If multiple, we're done | ||
| 1388 | JNZ ENDCOPY | ||
| 1389 | XOR AX,AX | ||
| 1390 | MOV [NXTADD],AX | ||
| 1391 | MOV [CFLAG],AL ;Flag nothing read yet | ||
| 1392 | NEXTSNG: | ||
| 1393 | MOV DI,FCB | ||
| 1394 | MOV SI,[SRCPT] | ||
| 1395 | CALL PARSESRC ;Parse next file name into FCB | ||
| 1396 | MOV [PARM1],DL ;Remember if it's ambiguous | ||
| 1397 | MOV [SRCPT],SI | ||
| 1398 | JZ SNGCLOS | ||
| 1399 | MOV AH,SRCHFRST | ||
| 1400 | CALL SEARCH ;Search for new file name | ||
| 1401 | JNZ NEXTSNG ;If none, skip it and move to next name | ||
| 1402 | READSNG: | ||
| 1403 | CALL CHECKREAD | ||
| 1404 | SNGLOOP: | ||
| 1405 | CALL SEARCHNEXT ;See if any more of this name | ||
| 1406 | JZ READSNG | ||
| 1407 | JMP SHORT NEXTSNG | ||
| 1408 | |||
| 1409 | SNGCLOS: | ||
| 1410 | CALL CLOSEFIL | ||
| 1411 | ENDCOPY: | ||
| 1412 | MOV SI,[FILECNT] | ||
| 1413 | XOR DI,DI | ||
| 1414 | CALL DISP32BITS | ||
| 1415 | MOV DX,OFFSET TRANGROUP:COPIED | ||
| 1416 | MOV AH,PRINTBUF | ||
| 1417 | INT 21H | ||
| 1418 | JMP COMMAND ;Stack could be messed up | ||
| 1419 | |||
| 1420 | FIRSTSRC: | ||
| 1421 | MOV SI,OFFSET TRANGROUP:DIRBUF+1 | ||
| 1422 | MOV DI,OFFSET TRANGROUP:SOURCE | ||
| 1423 | MOV CX,11 | ||
| 1424 | REP MOVSB ;Copy first source name to SOURCE | ||
| 1425 | MOV SI,OFFSET TRANGROUP:DESTNAME | ||
| 1426 | MOV DI,OFFSET TRANGROUP:DEST+1 | ||
| 1427 | MOV BX,OFFSET TRANGROUP:SOURCE | ||
| 1428 | CALL BUILDNAME ;Build destination name | ||
| 1429 | XOR AX,AX | ||
| 1430 | MOV [NXTADD],AX | ||
| 1431 | MOV [CFLAG],AL | ||
| 1432 | MOV [APPEND],AL | ||
| 1433 | MOV [NOWRITE],AL | ||
| 1434 | TEST [PARM2],1 ;Multiple destinations? | ||
| 1435 | JZ NOPRT | ||
| 1436 | MOV SI,OFFSET TRANGROUP:DIRBUF+1 | ||
| 1437 | CALL SHONAME ;If so, show first source | ||
| 1438 | CALL CRLF2 | ||
| 1439 | NOPRT: | ||
| 1440 | CALL COMPNAME ;Source and dest. the same? | ||
| 1441 | JNZ DOREAD ;If not, read source in | ||
| 1442 | TEST [PARM2],2 ;Concatenation? | ||
| 1443 | MOV DX,OFFSET TRANGROUP:OVERWR | ||
| 1444 | JZ COPERRJ ;If not, overwrite error | ||
| 1445 | MOV [APPEND],1 ;Set physical append | ||
| 1446 | MOV AH,OPEN | ||
| 1447 | MOV DX,OFFSET TRANGROUP:DEST | ||
| 1448 | INT 33 ;Open (existing) destination | ||
| 1449 | CMP [ASCII],0 ;ASCII flag set? | ||
| 1450 | JZ BINARYAPP | ||
| 1451 | ;ASCII append. Must find logical EOF, then seek there with dest. FCB | ||
| 1452 | MOV [NOWRITE],1 | ||
| 1453 | CALL READIN ;Find EOF | ||
| 1454 | CALL FLSHFIL ;Seek there | ||
| 1455 | MOV [NOWRITE],0 | ||
| 1456 | CALL FLSHFIL ;Truncate file | ||
| 1457 | JMP SHORT SNGLCHK | ||
| 1458 | |||
| 1459 | SNGLOOPJ:JMP SNGLOOP | ||
| 1460 | |||
| 1461 | COPERRJ:JMP COPERR | ||
| 1462 | |||
| 1463 | BINARYAPP: | ||
| 1464 | MOV WORD PTR[DEST+RECLEN],1 ;Set record length to 1 | ||
| 1465 | MOV SI,OFFSET TRANGROUP:DEST+16 ;Point to file size | ||
| 1466 | MOV DI,OFFSET TRANGROUP:DEST+RR | ||
| 1467 | MOVSW | ||
| 1468 | MOVSW ;Seek to end of file | ||
| 1469 | MOV [CFLAG],1 | ||
| 1470 | JMP SHORT SNGLCHK | ||
| 1471 | DOREAD: | ||
| 1472 | CALL READIN | ||
| 1473 | SNGLCHK: | ||
| 1474 | TEST [PARM2],1 ;Single or multiple destinations? | ||
| 1475 | JZ SNGLOOPJ | ||
| 1476 | MOV SI,[SRCPT] | ||
| 1477 | MULTAPP: | ||
| 1478 | CALL PARSE | ||
| 1479 | JZ MULTCLOS | ||
| 1480 | PUSH SI | ||
| 1481 | MOV SI,OFFSET TRANGROUP:DIRBUF+1 | ||
| 1482 | MOV DI,SI | ||
| 1483 | MOV BX,OFFSET TRANGROUP:SOURCE | ||
| 1484 | CALL BUILDNAME | ||
| 1485 | CALL CHECKREAD | ||
| 1486 | POP SI | ||
| 1487 | JMP SHORT MULTAPP | ||
| 1488 | MULTCLOS: | ||
| 1489 | CALL CLOSEFIL | ||
| 1490 | MOV AL,BYTE PTR[COMSW] | ||
| 1491 | MOV [ASCII],AL ;Restore ASCII flag | ||
| 1492 | CALL SEARCHNEXT | ||
| 1493 | JMP MULTDEST | ||
| 1494 | |||
| 1495 | PARSE: | ||
| 1496 | MOV DI,OFFSET TRANGROUP:DIRBUF | ||
| 1497 | PARSESRC: | ||
| 1498 | CALL SCANOFF | ||
| 1499 | CMP AL,"+" | ||
| 1500 | JNZ RETZF | ||
| 1501 | MOV [PLUS],1 ;Keep track of "+" signs | ||
| 1502 | INC SI ;Skip over it | ||
| 1503 | PARSNAM: | ||
| 1504 | MOV AX,2901H | ||
| 1505 | INT 33 ;Parse file name | ||
| 1506 | CMP AL,-1 ;Illegal? | ||
| 1507 | MOV DX,OFFSET TRANGROUP:BADDRV | ||
| 1508 | JZ COPERRJ | ||
| 1509 | XCHG AX,DX ;Save parse flag in DL | ||
| 1510 | MOV AL,BYTE PTR[DI] ;Get drive number | ||
| 1511 | OR AL,AL ;Is it default? | ||
| 1512 | JNZ PARSW | ||
| 1513 | MOV AL,[CURDRV] ;Substitute actual drive | ||
| 1514 | INC AX | ||
| 1515 | MOV BYTE PTR[DI],AL | ||
| 1516 | PARSW: | ||
| 1517 | PUSH BX | ||
| 1518 | PUSH DI | ||
| 1519 | CALL SWITCH ;Process switches | ||
| 1520 | OR BP,AX ;Combine all switches | ||
| 1521 | CALL SETASC ;Check for /A or /B | ||
| 1522 | POP DI | ||
| 1523 | POP BX | ||
| 1524 | CMP BYTE PTR[DI+1]," " ;Did we even get a file name? | ||
| 1525 | RET | ||
| 1526 | |||
| 1527 | RETZF: | ||
| 1528 | XOR AX,AX | ||
| 1529 | RET35: RET | ||
| 1530 | |||
| 1531 | SEARCHNEXT: | ||
| 1532 | MOV AL,[PARM1] ;Is name ambiguous? | ||
| 1533 | DEC AL | ||
| 1534 | JNZ RET35 ;Don't perform search if not | ||
| 1535 | MOV AH,SRCHNXT | ||
| 1536 | SEARCH: | ||
| 1537 | PUSH AX | ||
| 1538 | MOV AH,SETDMA | ||
| 1539 | MOV DX,OFFSET TRANGROUP:DIRBUF | ||
| 1540 | INT 33 ;Put result of search in DIRBUF | ||
| 1541 | POP AX ;Restore search first/next command | ||
| 1542 | MOV DX,FCB | ||
| 1543 | INT 33 ;Do the search | ||
| 1544 | OR AL,AL | ||
| 1545 | RET | ||
| 1546 | |||
| 1547 | SETASC: | ||
| 1548 | ;Given switch vector in AX, | ||
| 1549 | ; Set ASCII switch if /A is set | ||
| 1550 | ; Clear ASCII switch if /B is set | ||
| 1551 | ; Leave ASCII unchanged if neither or both are set | ||
| 1552 | ; Also sets INEXACT if ASCII is ever set. AL = ASCII on exit, flags set | ||
| 1553 | AND AL,ASWITCH+BSWITCH | ||
| 1554 | JPE LOADSW ;PE means both or neither are set | ||
| 1555 | AND AL,ASWITCH | ||
| 1556 | MOV [ASCII],AL | ||
| 1557 | OR [INEXACT],AL | ||
| 1558 | LOADSW: | ||
| 1559 | MOV AL,[ASCII] | ||
| 1560 | OR AL,AL | ||
| 1561 | RET | ||
| 1562 | |||
| 1563 | BUILDNAME: | ||
| 1564 | ; [SI] = Ambiguous input file name | ||
| 1565 | ; [BX] = Source of replacement characters | ||
| 1566 | ; [DI] = Destination | ||
| 1567 | ; File name is copied from [SI] to [DI]. If "?"s are encountered, | ||
| 1568 | ; they are replaced with the character in the same position at [BX]. | ||
| 1569 | MOV CX,11 | ||
| 1570 | BUILDNAM: | ||
| 1571 | LODSB | ||
| 1572 | CMP AL,"?" | ||
| 1573 | JNZ NOTAMBIG | ||
| 1574 | MOV AL,BYTE PTR[BX] | ||
| 1575 | NOTAMBIG: | ||
| 1576 | STOSB | ||
| 1577 | INC BX | ||
| 1578 | LOOP BUILDNAM | ||
| 1579 | RET | ||
| 1580 | |||
| 1581 | COMPNAME: | ||
| 1582 | MOV SI,OFFSET TRANGROUP:DEST | ||
| 1583 | MOV DI,OFFSET TRANGROUP:DIRBUF | ||
| 1584 | MOV CX,6 | ||
| 1585 | REPE CMPSW | ||
| 1586 | RET | ||
| 1587 | |||
| 1588 | CHECKREAD: | ||
| 1589 | ;Read file in (with READIN) if not identical to destination | ||
| 1590 | CALL COMPNAME ;See if source and destination the same | ||
| 1591 | JNZ READIN | ||
| 1592 | CMP [APPEND],0 ;If physical append, it's OK | ||
| 1593 | JNZ RET40 | ||
| 1594 | MOV DX,OFFSET TRANGROUP:LOSTERR ;Tell him he's not going to get it | ||
| 1595 | MOV AH,PRINTBUF | ||
| 1596 | INT 33 | ||
| 1597 | RET40: RET | ||
| 1598 | |||
| 1599 | READIN: | ||
| 1600 | ;Open source file and read it in. If memory fills up, flush it out to | ||
| 1601 | ;destination and keep reading. If /A switch set, chop file at first ^Z. | ||
| 1602 | ; Inputs/Outputs: | ||
| 1603 | ; [NXTADD] has current pointer in buffer | ||
| 1604 | ; [CFLAG] <>0 if destination has been created | ||
| 1605 | |||
| 1606 | MOV DX,OFFSET TRANGROUP:DIRBUF | ||
| 1607 | MOV AH,OPEN | ||
| 1608 | INT 21H | ||
| 1609 | OR AL,AL ;Successful open? | ||
| 1610 | JNZ RET40 ;If not, just ignore it | ||
| 1611 | XOR AX,AX | ||
| 1612 | MOV WORD PTR[DIRBUF+RR],AX | ||
| 1613 | MOV WORD PTR[DIRBUF+RR+2],AX | ||
| 1614 | INC AX | ||
| 1615 | MOV WORD PTR[DIRBUF+RECLEN],AX | ||
| 1616 | COPYLP: | ||
| 1617 | MOV DX,[NXTADD] | ||
| 1618 | MOV AH,SETDMA | ||
| 1619 | PUSH DS | ||
| 1620 | MOV DS,[TPA] | ||
| 1621 | INT 33 | ||
| 1622 | POP DS | ||
| 1623 | MOV CX,[BYTCNT] | ||
| 1624 | SUB CX,DX ;Compute available space | ||
| 1625 | MOV DX,OFFSET TRANGROUP:DIRBUF | ||
| 1626 | MOV AH,RDBLK ;Read in source file | ||
| 1627 | INT 21H | ||
| 1628 | JCXZ RET40 | ||
| 1629 | CMP [ASCII],0 | ||
| 1630 | JZ BINREAD | ||
| 1631 | MOV DX,CX | ||
| 1632 | MOV DI,[NXTADD] | ||
| 1633 | MOV AL,1AH | ||
| 1634 | PUSH ES | ||
| 1635 | MOV ES,[TPA] | ||
| 1636 | REPNE SCASB ;Scan for EOF | ||
| 1637 | POP ES | ||
| 1638 | JNZ USEALL | ||
| 1639 | INC CX | ||
| 1640 | USEALL: | ||
| 1641 | SUB DX,CX | ||
| 1642 | MOV CX,DX | ||
| 1643 | BINREAD: | ||
| 1644 | ADD CX,[NXTADD] | ||
| 1645 | MOV [NXTADD],CX | ||
| 1646 | CMP CX,[BYTCNT] ;Is buffer full? | ||
| 1647 | JB RET40 ;If not, we must have found EOF | ||
| 1648 | CALL FLSHFIL | ||
| 1649 | JMP SHORT COPYLP | ||
| 1650 | |||
| 1651 | CLOSEFIL: | ||
| 1652 | MOV AX,[NXTADD] | ||
| 1653 | MOV BX,AX | ||
| 1654 | OR AL,AH ;See if any data is loaded | ||
| 1655 | OR AL,[CFLAG] ; or file was created | ||
| 1656 | JZ RET50 ;Don't close or count if not created | ||
| 1657 | MOV AL,BYTE PTR[ARG2S] | ||
| 1658 | CALL SETASC ;Check for /B or /A on destination | ||
| 1659 | JZ BINCLOS | ||
| 1660 | CMP BX,[BYTCNT] ;Is memory full? | ||
| 1661 | JNZ PUTZ | ||
| 1662 | CALL FLSHFIL ;Empty it to make room for 1 lousy byte | ||
| 1663 | XOR BX,BX | ||
| 1664 | PUTZ: | ||
| 1665 | PUSH DS | ||
| 1666 | MOV DS,[TPA] | ||
| 1667 | MOV WORD PTR[BX],1AH ;Add End-of-file mark (Ctrl-Z) | ||
| 1668 | POP DS | ||
| 1669 | INC [NXTADD] | ||
| 1670 | BINCLOS: | ||
| 1671 | CALL FLSHFIL | ||
| 1672 | CMP [INEXACT],0 ;Copy not exact? | ||
| 1673 | JNZ NODATE ;If so, don't copy date & time | ||
| 1674 | MOV SI,OFFSET TRANGROUP:DIRBUF+OFFDATE | ||
| 1675 | MOV DI,OFFSET TRANGROUP:DEST+OFFDATE ;Make date & time same as original | ||
| 1676 | MOVSW ;Copy date | ||
| 1677 | MOVSW ;Copy time | ||
| 1678 | NODATE: | ||
| 1679 | MOV DX,OFFSET TRANGROUP:DEST | ||
| 1680 | MOV AH,CLOSE | ||
| 1681 | INT 21H | ||
| 1682 | INC [FILECNT] | ||
| 1683 | RET50: RET | ||
| 1684 | |||
| 1685 | FLSHFIL: | ||
| 1686 | ;Write out any data remaining in memory. | ||
| 1687 | ; Inputs: | ||
| 1688 | ; [NXTADD] = No. of bytes to write | ||
| 1689 | ; [CFLAG] <>0 if file has been created | ||
| 1690 | ; Outputs: | ||
| 1691 | ; [NXTADD] = 0 | ||
| 1692 | |||
| 1693 | MOV AL,1 | ||
| 1694 | XCHG [CFLAG],AL | ||
| 1695 | OR AL,AL | ||
| 1696 | JNZ EXISTS | ||
| 1697 | CMP [NOWRITE],0 | ||
| 1698 | JNZ SKPMAK ;Don't actually create if NOWRITE set | ||
| 1699 | MOV DX,OFFSET TRANGROUP:DEST | ||
| 1700 | MOV AH,MAKE | ||
| 1701 | INT 21H | ||
| 1702 | MOV DX,OFFSET TRANGROUP:FULDIR | ||
| 1703 | OR AL,AL | ||
| 1704 | JNZ COPERR | ||
| 1705 | SKPMAK: | ||
| 1706 | XOR AX,AX | ||
| 1707 | MOV WORD PTR[DEST+RR],AX | ||
| 1708 | MOV WORD PTR[DEST+RR+2],AX | ||
| 1709 | INC AX | ||
| 1710 | MOV WORD PTR[DEST+RECLEN],AX | ||
| 1711 | EXISTS: | ||
| 1712 | XOR CX,CX | ||
| 1713 | XCHG CX,[NXTADD] | ||
| 1714 | CMP [NOWRITE],0 ;If NOWRITE set, just seek CX bytes | ||
| 1715 | JNZ SEEKEND | ||
| 1716 | XOR DX,DX | ||
| 1717 | PUSH DS | ||
| 1718 | MOV DS,[TPA] | ||
| 1719 | MOV AH,SETDMA | ||
| 1720 | INT 33 | ||
| 1721 | POP DS | ||
| 1722 | MOV DX,OFFSET TRANGROUP:DEST | ||
| 1723 | MOV AH,WRBLK | ||
| 1724 | INT 21H | ||
| 1725 | OR AL,AL | ||
| 1726 | JZ RET60 | ||
| 1727 | MOV DX,OFFSET TRANGROUP:DEST | ||
| 1728 | MOV AH,CLOSE | ||
| 1729 | INT 21H | ||
| 1730 | MOV AH,DELETE | ||
| 1731 | INT 33 | ||
| 1732 | MOV DX,OFFSET TRANGROUP:NOSPACE | ||
| 1733 | COPERR: | ||
| 1734 | MOV AH,9 | ||
| 1735 | INT 21H | ||
| 1736 | JMP ENDCOPY | ||
| 1737 | |||
| 1738 | SEEKEND: | ||
| 1739 | ADD WORD PTR[DEST+RR],CX | ||
| 1740 | ADC WORD PTR[DEST+RR+2],0 ;Propagate carry | ||
| 1741 | RET60: RET | ||
| 1742 | |||
| 1743 | GETBATBYT: | ||
| 1744 | ;Get one byte from the batch file and return it in AL. End-of-file | ||
| 1745 | ;returns <CR> and ends batch mode. DS must be set to resident segment. | ||
| 1746 | ;AH, CX, DX destroyed. | ||
| 1747 | ASSUME DS:RESGROUP | ||
| 1748 | MOV DX,OFFSET RESGROUP:BATFCB | ||
| 1749 | MOV AH,RDBLK | ||
| 1750 | MOV CX,1 | ||
| 1751 | INT 33 ;Get one more byte from batch file | ||
| 1752 | JCXZ BATEOF | ||
| 1753 | MOV AL,[BATBYT] | ||
| 1754 | CMP AL,1AH | ||
| 1755 | JNZ RET70 | ||
| 1756 | BATEOF: | ||
| 1757 | MOV AL,0DH ;If end-of-file, then end of line | ||
| 1758 | MOV [BATCH],0 ;And turn off batch mode | ||
| 1759 | RET70: RET | ||
| 1760 | ASSUME DS:TRANGROUP | ||
| 1761 | |||
| 1762 | SCANOFF: | ||
| 1763 | LODSB | ||
| 1764 | CALL DELIM | ||
| 1765 | JZ SCANOFF | ||
| 1766 | DEC SI ;Point to first non-delimiter | ||
| 1767 | RET | ||
| 1768 | |||
| 1769 | DELIM: | ||
| 1770 | CMP AL," " | ||
| 1771 | JZ RET80 | ||
| 1772 | CMP AL,"=" | ||
| 1773 | JZ RET80 | ||
| 1774 | CMP AL,"," | ||
| 1775 | JZ RET80 | ||
| 1776 | CMP AL,9 ;Check for TAB character | ||
| 1777 | RET80: RET | ||
| 1778 | |||
| 1779 | PAUSE: | ||
| 1780 | MOV DX,OFFSET TRANGROUP:PAUSMES | ||
| 1781 | MOV AH,PRINTBUF | ||
| 1782 | INT 33 | ||
| 1783 | MOV AX,0C00H+INCHAR ;Get character with KB buffer flush | ||
| 1784 | INT 33 | ||
| 1785 | RET90: RET | ||
| 1786 | |||
| 1787 | ;Date and time are set during initialization and use | ||
| 1788 | ;this routines since they need to do a long return | ||
| 1789 | |||
| 1790 | DATINIT: | ||
| 1791 | PUSH ES | ||
| 1792 | PUSH DS ;Going to use the previous stack | ||
| 1793 | MOV AX,CS ;Set up the appropriate segment registers | ||
| 1794 | MOV ES,AX | ||
| 1795 | MOV DS,AX | ||
| 1796 | MOV WORD PTR DS:[81H],13 ;Want to prompt for date during initialization | ||
| 1797 | CALL DATE | ||
| 1798 | CALL TIME | ||
| 1799 | POP DS | ||
| 1800 | POP ES | ||
| 1801 | YYY PROC FAR | ||
| 1802 | RET | ||
| 1803 | YYY ENDP | ||
| 1804 | |||
| 1805 | ; DATE - Gets and sets the time | ||
| 1806 | |||
| 1807 | DATE: | ||
| 1808 | MOV SI,81H ;Accepting argument for date inline | ||
| 1809 | CALL SCANOFF | ||
| 1810 | CMP AL,13 | ||
| 1811 | JZ PRMTDAT | ||
| 1812 | MOV BX,2F00H+"-" ;"/-" | ||
| 1813 | CALL INLINE | ||
| 1814 | JMP COMDAT | ||
| 1815 | |||
| 1816 | PRMTDAT: | ||
| 1817 | MOV DX,OFFSET TRANGROUP:CURDAT | ||
| 1818 | MOV AH,PRINTBUF | ||
| 1819 | INT 33 ;Print "Current date is " | ||
| 1820 | MOV AH,GETDATE | ||
| 1821 | INT 33 ;Get date in CX:DX | ||
| 1822 | CBW | ||
| 1823 | MOV SI,AX | ||
| 1824 | SHL SI,1 | ||
| 1825 | ADD SI,AX ;SI=AX*3 | ||
| 1826 | ADD SI,OFFSET TRANGROUP:WEEKTAB | ||
| 1827 | MOV BX,CX | ||
| 1828 | MOV CX,3 | ||
| 1829 | CALL OUTCNT | ||
| 1830 | MOV AL," " | ||
| 1831 | CALL OUT | ||
| 1832 | MOV AX,BX | ||
| 1833 | MOV CX,DX | ||
| 1834 | MOV DL,100 | ||
| 1835 | DIV DL | ||
| 1836 | XCHG AL,AH | ||
| 1837 | XCHG AX,DX | ||
| 1838 | MOV BL,"-" | ||
| 1839 | CALL SHOW | ||
| 1840 | GETDAT: | ||
| 1841 | MOV DX,OFFSET TRANGROUP:NEWDAT | ||
| 1842 | MOV BX,2F00H+"-" ;"/-" in BX | ||
| 1843 | CALL GETBUF | ||
| 1844 | COMDAT: JZ RET90 | ||
| 1845 | JC DATERR | ||
| 1846 | LODSB | ||
| 1847 | CMP AL,BL | ||
| 1848 | JZ SEPGD | ||
| 1849 | CMP AL,BH | ||
| 1850 | JNZ DATERR | ||
| 1851 | SEPGD: CALL GETNUM | ||
| 1852 | JC DATERR | ||
| 1853 | MOV CX,1900 | ||
| 1854 | CMP BYTE PTR[SI],13 | ||
| 1855 | JZ BIAS | ||
| 1856 | MOV AL,100 | ||
| 1857 | MUL AH | ||
| 1858 | MOV CX,AX | ||
| 1859 | CALL GETNUM | ||
| 1860 | JC DATERR | ||
| 1861 | BIAS: | ||
| 1862 | MOV AL,AH | ||
| 1863 | MOV AH,0 | ||
| 1864 | ADD CX,AX | ||
| 1865 | LODSB | ||
| 1866 | CMP AL,13 | ||
| 1867 | JNZ DATERR | ||
| 1868 | MOV AH,SETDATE | ||
| 1869 | INT 33 | ||
| 1870 | OR AL,AL | ||
| 1871 | JNZ DATERR | ||
| 1872 | JMP RET90 | ||
| 1873 | DATERR: | ||
| 1874 | MOV DX,OFFSET TRANGROUP:BADDAT | ||
| 1875 | MOV AH,PRINTBUF | ||
| 1876 | INT 33 | ||
| 1877 | JMP GETDAT | ||
| 1878 | |||
| 1879 | ; TIME gets and sets the time | ||
| 1880 | |||
| 1881 | TIME: | ||
| 1882 | MOV SI,81H ;Accepting argument for time inline | ||
| 1883 | CALL SCANOFF | ||
| 1884 | CMP AL,13 | ||
| 1885 | JZ PRMTTIM | ||
| 1886 | MOV BX,3A00H+":" | ||
| 1887 | CALL INLINE | ||
| 1888 | JMP COMTIM | ||
| 1889 | |||
| 1890 | PRMTTIM: | ||
| 1891 | MOV DX,OFFSET TRANGROUP:CURTIM | ||
| 1892 | MOV AH,PRINTBUF | ||
| 1893 | INT 33 ;Print "Current time is " | ||
| 1894 | MOV AH,GETTIME | ||
| 1895 | INT 33 ;Get time in CX:DX | ||
| 1896 | MOV BL,":" | ||
| 1897 | CALL SHOW | ||
| 1898 | GETTIM: | ||
| 1899 | XOR CX,CX ;Initialize hours and minutes to zero | ||
| 1900 | MOV DX,OFFSET TRANGROUP:NEWTIM | ||
| 1901 | MOV BX,3A00H+":" | ||
| 1902 | CALL GETBUF | ||
| 1903 | COMTIM: JZ RET100 ;If no time present, don't change it | ||
| 1904 | JC TIMERR | ||
| 1905 | MOV CX,DX | ||
| 1906 | XOR DX,DX | ||
| 1907 | LODSB | ||
| 1908 | CMP AL,13 | ||
| 1909 | JZ SAVTIM | ||
| 1910 | CMP AL,BL | ||
| 1911 | JNZ TIMERR | ||
| 1912 | MOV BL,"." | ||
| 1913 | CALL GETNUM | ||
| 1914 | JC TIMERR | ||
| 1915 | MOV DH,AH ;Position seconds | ||
| 1916 | LODSB | ||
| 1917 | CMP AL,13 | ||
| 1918 | JZ SAVTIM | ||
| 1919 | CMP AL,BL | ||
| 1920 | JNZ TIMERR | ||
| 1921 | CALL GETNUM | ||
| 1922 | JC TIMERR | ||
| 1923 | MOV DL,AH | ||
| 1924 | LODSB | ||
| 1925 | CMP AL,13 | ||
| 1926 | JNZ TIMERR | ||
| 1927 | SAVTIM: | ||
| 1928 | MOV AH,SETTIME | ||
| 1929 | INT 33 | ||
| 1930 | OR AL,AL | ||
| 1931 | JZ RET100 ;Error in time? | ||
| 1932 | TIMERR: | ||
| 1933 | MOV DX,OFFSET TRANGROUP:BADTIM | ||
| 1934 | MOV AH,PRINTBUF | ||
| 1935 | INT 33 ;Print error message | ||
| 1936 | JMP GETTIM ;Try again | ||
| 1937 | |||
| 1938 | GETBUF: | ||
| 1939 | MOV AH,PRINTBUF | ||
| 1940 | INT 33 ;Print "Enter new date: " | ||
| 1941 | MOV AH,INBUF | ||
| 1942 | MOV DX,OFFSET TRANGROUP:COMBUF | ||
| 1943 | INT 33 ;Get input line | ||
| 1944 | CALL CRLF2 | ||
| 1945 | MOV SI,OFFSET TRANGROUP:COMBUF+2 | ||
| 1946 | CMP BYTE PTR[SI],13 ;Check if new date entered | ||
| 1947 | JZ RET100 | ||
| 1948 | INLINE: | ||
| 1949 | CALL GETNUM ;Get one or two digit number | ||
| 1950 | JC RET100 | ||
| 1951 | MOV DH,AH ;Put in position | ||
| 1952 | LODSB | ||
| 1953 | CMP AL,BL | ||
| 1954 | JZ NEXT | ||
| 1955 | CMP BL,":" ;Is it a date seperator? | ||
| 1956 | JNZ DATESEP | ||
| 1957 | DEC SI | ||
| 1958 | MOV DL,0 | ||
| 1959 | RET100: RET ;Time may have only an hour specified | ||
| 1960 | DATESEP: | ||
| 1961 | CMP AL,BH | ||
| 1962 | STC | ||
| 1963 | JNZ RET100 | ||
| 1964 | NEXT: CALL GETNUM | ||
| 1965 | MOV DL,AH ;Put in position | ||
| 1966 | RET | ||
| 1967 | |||
| 1968 | GETNUM: | ||
| 1969 | CALL INDIG | ||
| 1970 | JC RET100 | ||
| 1971 | MOV AH,AL ;Save first digit | ||
| 1972 | CALL INDIG ;Another digit? | ||
| 1973 | JC OKRET | ||
| 1974 | AAD ;Convert unpacked BCD to decimal | ||
| 1975 | MOV AH,AL | ||
| 1976 | OKRET: | ||
| 1977 | OR AL,1 | ||
| 1978 | RET110: RET | ||
| 1979 | |||
| 1980 | INDIG: | ||
| 1981 | MOV AL,BYTE PTR[SI] | ||
| 1982 | SUB AL,"0" | ||
| 1983 | JC RET110 | ||
| 1984 | CMP AL,10 | ||
| 1985 | CMC | ||
| 1986 | JC RET110 | ||
| 1987 | INC SI | ||
| 1988 | RET | ||
| 1989 | |||
| 1990 | SHOW: | ||
| 1991 | MOV AL,CH | ||
| 1992 | MOV BH,"0"-" " ;Enable leading zero suppression | ||
| 1993 | CALL OUT2 | ||
| 1994 | MOV AL,BL | ||
| 1995 | CALL OUT | ||
| 1996 | MOV AL,CL | ||
| 1997 | CALL OUT2 | ||
| 1998 | MOV AL,BL | ||
| 1999 | CALL OUT | ||
| 2000 | MOV AL,DH | ||
| 2001 | CALL OUT2 | ||
| 2002 | CMP BL,":" ;Are we outputting time? | ||
| 2003 | JNZ SKIPIT | ||
| 2004 | MOV AL,"." | ||
| 2005 | CALL OUT | ||
| 2006 | SKIPIT: MOV AL,DL | ||
| 2007 | OUT2: ;Output binary number as two ASCII digits | ||
| 2008 | AAM ;Convert binary to unpacked BCD | ||
| 2009 | XCHG AL,AH | ||
| 2010 | OR AX,3030H ;Add "0" bias to both digits | ||
| 2011 | CMP AL,"0" ;Is MSD zero? | ||
| 2012 | JNZ NOSUP | ||
| 2013 | SUB AL,BH ;Suppress leading zero if enabled | ||
| 2014 | NOSUP: | ||
| 2015 | MOV BH,0 ;Disable zero suppression | ||
| 2016 | CALL OUT | ||
| 2017 | MOV AL,AH | ||
| 2018 | OUT: | ||
| 2019 | ;Print char in AL without affecting registers | ||
| 2020 | XCHG AX,DX | ||
| 2021 | PUSH AX | ||
| 2022 | MOV AH,OUTCH | ||
| 2023 | INT 33 | ||
| 2024 | POP AX | ||
| 2025 | XCHG AX,DX | ||
| 2026 | RET | ||
| 2027 | |||
| 2028 | EXELOAD: | ||
| 2029 | MOV AX,CS | ||
| 2030 | ADD AX,LOADSEG | ||
| 2031 | MOV [EXEEND],AX ;Store in EXEEND | ||
| 2032 | MOV DX,OFFSET TRANGROUP:RUNVAR ;Read header in here | ||
| 2033 | MOV AH,SETDMA | ||
| 2034 | INT 33 | ||
| 2035 | MOV CX,RUNVARSIZ ;Amount of header info we need | ||
| 2036 | MOV DX,OFFSET TRANGROUP:EXEFCB | ||
| 2037 | MOV AH,RDBLK | ||
| 2038 | INT 33 ;Read in header | ||
| 2039 | OR AL,AL | ||
| 2040 | JNZ BADEXE ;Must not reach EOF | ||
| 2041 | MOV AX,[HEADSIZ] ;Size of header in paragraphs | ||
| 2042 | ;Convert header size to 512-byte pages by multiplying by 32 & rounding up | ||
| 2043 | ADD AX,31 ;Round up first | ||
| 2044 | MOV CL,5 | ||
| 2045 | SHR AX,CL ;Multiply by 32 | ||
| 2046 | MOV [EXEFCB+RR],AX ;Position in file of program | ||
| 2047 | MOV WORD PTR[EXEFCB+RECLEN],512 ;Set record size | ||
| 2048 | ADD BX,10H ;First paragraph above parameter area | ||
| 2049 | MOV DX,[PAGES] ;Total size of file in 512-byte pages | ||
| 2050 | SUB DX,AX ;Size of program in pages | ||
| 2051 | MOV [PSIZE],DX | ||
| 2052 | SHL DX,CL ;Convert pages back to paragraphs | ||
| 2053 | MOV AX,DX | ||
| 2054 | ADD DX,BX ;Size + start = minimum memory (paragr.) | ||
| 2055 | MOV CX,[EXEEND] ;Get memory size in paragraphs | ||
| 2056 | CMP DX,CX ;Enough memory? | ||
| 2057 | JA SHRTERR | ||
| 2058 | MOV DX,[INITSP] | ||
| 2059 | ADD DX,15 | ||
| 2060 | SHR DX,1 | ||
| 2061 | SHR DX,1 | ||
| 2062 | SHR DX,1 | ||
| 2063 | SHR DX,1 | ||
| 2064 | ADD DX,[INITSS] | ||
| 2065 | ADD DX,BX ;Adjusted value of SP | ||
| 2066 | CMP DX,CX ;Is it valid? | ||
| 2067 | JA SHRTERR | ||
| 2068 | CMP [LOADLOW],-1 ;Load low or high? | ||
| 2069 | JZ LOAD ;If low, load at segment BX | ||
| 2070 | SUB CX,AX ;Memory size - program size = load addr. | ||
| 2071 | MOV BX,CX | ||
| 2072 | LOAD: | ||
| 2073 | MOV BP,BX ;Save load segment | ||
| 2074 | LOAD1: | ||
| 2075 | LOADSEG EQU (LOAD1-ZERO)/16 | ||
| 2076 | PUSH DS | ||
| 2077 | MOV DS,BX | ||
| 2078 | XOR DX,DX ;Address 0 in segment | ||
| 2079 | MOV AH,SETDMA | ||
| 2080 | INT 33 ;Set load address | ||
| 2081 | POP DS | ||
| 2082 | MOV CX,[PSIZE] ;Number of records to read | ||
| 2083 | MOV DX,OFFSET TRANGROUP:EXEFCB | ||
| 2084 | MOV AH,RDBLK | ||
| 2085 | INT 33 ;Read in up to 64K | ||
| 2086 | SUB [PSIZE],CX ;Decrement count by amount read | ||
| 2087 | JZ HAVEXE ;Did we get it all? | ||
| 2088 | TEST AL,1 ;Check return code if not | ||
| 2089 | JNZ BADEXE ;Must be zero if more to come | ||
| 2090 | ADD BX,1000H-20H ;Bump data segment 64K minus one record | ||
| 2091 | JMP SHORT LOAD1 ;Get next 64K block | ||
| 2092 | |||
| 2093 | BADEXE: | ||
| 2094 | MOV DX,OFFSET TRANGROUP:EXEBAD | ||
| 2095 | JMP ERROR | ||
| 2096 | |||
| 2097 | SHRTERR: | ||
| 2098 | MOV DX,OFFSET TRANGROUP:TOOBIG | ||
| 2099 | JMP ERROR | ||
| 2100 | |||
| 2101 | HAVEXE: | ||
| 2102 | MOV AX,[RELTAB] ;Get position of table | ||
| 2103 | MOV [EXEFCB+RR],AX ;Set in random record field | ||
| 2104 | MOV WORD PTR[EXEFCB+RECLEN],1 ;Set one-byte record | ||
| 2105 | MOV DX,OFFSET TRANGROUP:RELPT ;4-byte buffer for relocation address | ||
| 2106 | MOV AH,SETDMA | ||
| 2107 | INT 33 | ||
| 2108 | CMP [RELCNT],0 | ||
| 2109 | JZ NOREL | ||
| 2110 | RELOC: | ||
| 2111 | MOV AH,RDBLK | ||
| 2112 | MOV DX,OFFSET TRANGROUP:EXEFCB | ||
| 2113 | MOV CX,4 | ||
| 2114 | INT 33 ;Read in one relocation pointer | ||
| 2115 | OR AL,AL ;Check return code | ||
| 2116 | JNZ BADEXE | ||
| 2117 | MOV DI,[RELPT] ;Get offset of relocation pointer | ||
| 2118 | MOV AX,[RELSEG] ;Get segment | ||
| 2119 | ADD AX,BP ;Bias segment with actual load segment | ||
| 2120 | MOV ES,AX | ||
| 2121 | ADD WORD PTR ES:[DI],BP ;Relocate | ||
| 2122 | DEC [RELCNT] ;Count off | ||
| 2123 | JNZ RELOC | ||
| 2124 | ;Set up exit conditions | ||
| 2125 | NOREL: | ||
| 2126 | MOV AX,[INITSS] | ||
| 2127 | ADD AX,BP | ||
| 2128 | CLI | ||
| 2129 | MOV SS,AX ;Initialize SS | ||
| 2130 | MOV SP,[INITSP] | ||
| 2131 | STI | ||
| 2132 | ADD [INITCS],BP | ||
| 2133 | MOV AX,[TPA] ;Get pointer to parameter area | ||
| 2134 | MOV CX,[BYTCNT] ;Size of TPA segment | ||
| 2135 | MOV ES,AX | ||
| 2136 | MOV DS,AX ;Set segment registers to point to it | ||
| 2137 | CALL SETUP | ||
| 2138 | JMP DWORD PTR CS:[INITIP] ;Long jump to program | ||
| 2139 | |||
| 2140 | SETUP: | ||
| 2141 | AND CL,0F0H ;Adjust to even paragraph boundary | ||
| 2142 | MOV AX,WORD PTR DS:[6] ;Get current memory size | ||
| 2143 | SUB AX,CX ;Find out how much we're changing it | ||
| 2144 | MOV WORD PTR DS:[6],CX | ||
| 2145 | MOV CL,4 | ||
| 2146 | SAR AX,CL ;Convert to a segment address | ||
| 2147 | ADD WORD PTR DS:[8],AX ;Adjust long jump to go to same place | ||
| 2148 | MOV DX,80H | ||
| 2149 | MOV AH,SETDMA | ||
| 2150 | INT 33 ;Set default disk transfer address | ||
| 2151 | MOV AX,WORD PTR CS:[PARM1] ;Pass on info about FCBs | ||
| 2152 | XOR CX,CX | ||
| 2153 | MOV DX,CX ;Assume no batch file | ||
| 2154 | ASSUME CS:RESGROUP | ||
| 2155 | TEST CS:[BATCH],-1 ;Batch file in progress? | ||
| 2156 | ASSUME CS:TRANGROUP | ||
| 2157 | JZ RET120 ;If not, all set up | ||
| 2158 | MOV CX,CS:[RESSEG] | ||
| 2159 | MOV DX,OFFSET RESGROUP:BATFCB ;CX:DX points to batch FCB | ||
| 2160 | RET120: RET | ||
| 2161 | TRANCODESIZE EQU $-ZERO | ||
| 2162 | TRANCODE ENDS | ||
| 2163 | COMLEN EQU TRANDATASIZE+TRANCODESIZE-102H ;End of COMMAND load. ZERO Needed to make COMLEN absolute | ||
| 2164 | TRNLEN EQU (PRETRLEN+TRANCODESIZE+TRANDATASIZE+15)/16 ;Length of transient in paragraphs | ||
| 2165 | END PROGSTART | ||
| 2166 | \ No newline at end of file | ||