summaryrefslogtreecommitdiff
path: root/v2.0/source/COMMAND.ASM
diff options
context:
space:
mode:
Diffstat (limited to 'v2.0/source/COMMAND.ASM')
-rw-r--r--v2.0/source/COMMAND.ASM788
1 files changed, 788 insertions, 0 deletions
diff --git a/v2.0/source/COMMAND.ASM b/v2.0/source/COMMAND.ASM
new file mode 100644
index 0000000..db2783a
--- /dev/null
+++ b/v2.0/source/COMMAND.ASM
@@ -0,0 +1,788 @@
1;
2; This version of COMMAND is divided into three distinct parts. First is the
3; resident portion, which includes handlers for interrupts 22H (terminate),
4; 23H (Cntrl-C), 24H (fatal error), and 27H (stay resident); it also has code
5; to test and, if necessary, reload the transient portion. Following the
6; resident is the init code, which is overwritten after use. Then comes the
7; transient portion, which includes all command processing (whether internal
8; or external). The transient portion loads at the end of physical memory,
9; and it may be overlayed by programs that need as much memory as possible.
10; When the resident portion of command regains control from a user program, a
11; checksum is performed on the transient portion to see if it must be
12; reloaded. Thus programs which do not need maximum memory will save the time
13; required to reload COMMAND when they terminate.
14
15;
16; REV 1.17
17; 05/19/82 Fixed bug in BADEXE error (relocation error must return to
18; resident since the EXELOAD may have overwritten the transient.
19; REV 1.18
20; 05/21/82 IBM version always looks on drive A
21; MSVER always looks on default drive
22;
23; REV 1.19
24; 06/03/82 Drive spec now entered in command line
25; 06/07/82 Added VER command (print DOS version number) and VOL command
26; (print volume label)
27; REV 1.20
28; 06/09/82 Prints "directory" after directories
29; 06/13/82 MKDIR, CHDIR, PWD, RMDIR added
30; REV 1.50
31; Some code for new 2.0 DOS, sort of HACKey. Not enough time to
32; do it right.
33; REV 1.70
34; EXEC used to fork off new processes
35; REV 1.80
36; C switch for single command execution
37; REV 1.90
38; Batch uses XENIX
39; Rev 2.00
40; Lots of neato stuff
41; IBM 2.00 level
42; Rev 2.01
43; 'D' switch for date time suppression
44; Rev 2.02
45; Default userpath is NUL rather than BIN
46; same as IBM
47; COMMAND split into pieces
48; Rev 2.10
49; INTERNATIONAL SUPPORT
50; Rev 2.11 COMMAND split into more pieces
51
52 INCLUDE DOSSYM.ASM
53 INCLUDE DEVSYM.ASM
54 INCLUDE COMSW.ASM
55 INCLUDE COMEQU.ASM
56
57CODERES SEGMENT PUBLIC
58CODERES ENDS
59
60DATARES SEGMENT PUBLIC BYTE
61 EXTRN COMBAD:BYTE,NEEDCOM:BYTE,DRVMSG:BYTE
62 EXTRN DEFMSG:BYTE,PROMPT:BYTE,EXECEMES:BYTE,EXEBAD:BYTE
63 EXTRN TOOBIG:BYTE,NOCOM:BYTE,RBADNAM:BYTE,INT_2E_RET:DWORD
64 EXTRN NOHANDMES:BYTE,BMEMMES:BYTE,HALTMES:BYTE,FRETMES:BYTE
65 EXTRN PARENT:WORD,HANDLE01:WORD,LOADING:BYTE,BATCH:WORD
66 EXTRN TRNSEG:WORD,COMDRV:BYTE,MEMSIZ:WORD,SUM:WORD,EXTCOM:BYTE
67 EXTRN IO_SAVE:WORD,PERMCOM:BYTE,SINGLECOM:WORD,VERVAL:WORD
68 EXTRN PIPEFLAG:BYTE,SAVE_PDB:WORD,COMSPEC:BYTE,TRANS:WORD
69 EXTRN TRANVARS:BYTE,LTPA:WORD,RSWITCHAR:BYTE,RDIRCHAR:BYTE
70 EXTRN RETCODE:WORD,FORFLAG:BYTE
71
72 IF IBMVER
73 EXTRN SYS_CALL:DWORD,ZEXEC:WORD,EXESEG:WORD,EXESUM:WORD
74 EXTRN USER_SS:WORD,USER_SP:WORD
75 ENDIF
76
77DATARES ENDS
78
79ENVIRONMENT SEGMENT PUBLIC PARA ; Default COMMAND environment
80ENVIRONMENT ENDS
81
82INIT SEGMENT PUBLIC PARA
83 EXTRN CONPROC:NEAR
84INIT ENDS
85
86TAIL SEGMENT PUBLIC PARA
87TAIL ENDS
88
89TRANCODE SEGMENT PUBLIC PARA
90TRANCODE ENDS
91
92TRANDATA SEGMENT PUBLIC BYTE
93 EXTRN TRANDATAEND:BYTE
94TRANDATA ENDS
95
96TRANSPACE SEGMENT PUBLIC BYTE
97 EXTRN TRANSPACEEND:BYTE,HEADCALL:DWORD
98TRANSPACE ENDS
99
100TRANTAIL SEGMENT PUBLIC PARA
101TRANTAIL ENDS
102
103ZEXEC_CODE SEGMENT PUBLIC PARA
104ZEXEC_CODE ENDS
105
106ZEXEC_DATA SEGMENT PUBLIC BYTE
107ZEXEC_DATA ENDS
108
109RESGROUP GROUP CODERES,DATARES,ENVIRONMENT,INIT,TAIL
110TRANGROUP GROUP TRANCODE,TRANDATA,TRANSPACE,TRANTAIL
111EGROUP GROUP ZEXEC_CODE,ZEXEC_DATA
112
113ENVIRONMENT SEGMENT PUBLIC PARA ; Default COMMAND environment
114
115 PUBLIC ECOMSPEC,ENVIREND,PATHSTRING
116
117 ORG 0
118ENVARENA DB 10H DUP (?) ; Pad for mem arena
119PATHSTRING DB "PATH="
120USERPATH LABEL BYTE
121
122 DB 0 ; Null path
123 DB "COMSPEC="
124ECOMSPEC DB "/COMMAND.COM"
125 DB 134 DUP (0)
126
127ENVIREND LABEL BYTE
128
129ENVIRONSIZ EQU $-PATHSTRING
130ENVIRONSIZ2 EQU $-ECOMSPEC
131ENVIRONMENT ENDS
132
133
134; START OF RESIDENT PORTION
135
136CODERES SEGMENT PUBLIC
137
138 PUBLIC GETCOMDSK2,LODCOM,THEADFIX,CONTCTERM,LOADCOM,INT_2E,LODCOM1
139 PUBLIC CHKSUM,SETVECT,EXT_EXEC,TREMCHECK,RESTHAND,CONTC,RSTACK
140 PUBLIC SAVHAND
141
142 IF IBMVER
143 PUBLIC EXECHK,SYSCALL,EXEC_WAIT
144 ENDIF
145
146ASSUME CS:RESGROUP,DS:NOTHING,ES:NOTHING,SS:NOTHING
147
148 EXTRN RPRINT:NEAR,ASKEND:NEAR,DSKERR:NEAR
149
150
151 ORG 0
152ZERO = $
153
154 ORG 100H
155
156PROGSTART:
157 JMP RESGROUP:CONPROC
158
159 DB (80H - 3) DUP (?)
160RSTACK LABEL WORD
161
162IF IBMVER
163SYSCALL:
164 CMP AH,EXEC
165 JZ do_exec
166 JMP DWORD PTR [SYS_CALL]
167
168do_exec:
169 PUSH ES
170 PUSH DS
171 PUSH BP
172 PUSH DI
173 PUSH SI
174 PUSH DX
175 PUSH CX
176 PUSH BX
177 PUSH AX
178 MOV [user_ss],SS
179 MOV [user_sp],SP
180;
181; are we running on RSTACK already?
182;
183 PUSH CS
184 POP BX ; BX <- CS
185 PUSH SS
186 POP AX ; AX <- SS
187 CMP AX,BX ; IF AX == BX then no stack switch!
188 JZ Get_mem
189 MOV SS,BX
190ASSUME SS:RESGROUP
191 MOV SP,OFFSET RESGROUP:RSTACK
192
193Get_mem:
194 MOV BX,0FFFFH ; allocate all of memory
195 MOV AH,ALLOC
196 INT int_command
197 MOV AX,OFFSET EGROUP:ZEXECDATAEND + 15
198 MOV CL,4
199 SHR AX,CL
200 MOV CX,AX ; Save in CX
201 CMP BX,AX ; enough for EXEC?
202 JB EXECMER ; nope... cry
203 MOV AH,ALLOC
204 INT int_command
205 JC EXECMER ; Memory arenas probably trashed
206 ADD BX,AX
207 MOV [MEMSIZ],BX
208 SUB BX,CX
209 MOV [EXESEG],BX ; exec
210 MOV ES,AX
211 MOV AH,DEALLOC
212 INT int_command
213 PUSH CS
214 POP DS
215ASSUME DS:RESGROUP
216 CALL EXECHK
217 CMP DX,[EXESUM]
218 JZ HAVEXEC ; EXEC OK
219 MOV DX,OFFSET RESGROUP:COMSPEC
220 MOV AX,OPEN SHL 8
221 INT int_command ; Open COMMAND.COM
222 JC EXECMER
223 MOV BX,AX ; Handle
224 MOV DX,OFFSET RESGROUP:TRANSTART
225 ADD DX,OFFSET TRANGROUP:EXECSTART - 100H
226 XOR CX,CX ; Seek loc
227 MOV AX,LSEEK SHL 8
228 INT int_command
229 MOV CX,OFFSET EGROUP:ZEXECCODEEND
230 MOV DS,[EXESEG]
231ASSUME DS:NOTHING
232 MOV AH,READ
233 INT int_command
234 PUSH AX
235 MOV AH,CLOSE
236 INT int_command ; Close COMMAND.COM
237 POP CX
238 CMP CX,OFFSET EGROUP:ZEXECCODEEND
239 JNZ EXECMER ; Size matched
240
241 CALL EXECHK
242 CMP DX,[EXESUM]
243 JNZ EXECMER
244HAVEXEC:
245 MOV [LOADING],0 ; Flag to DSKERR
246 CALL DWORD PTR [ZEXEC]
247 JMP SHORT EXECRET
248execmer:
249 LDS SI,DWORD PTR [user_Sp]
250 MOV [SI.user_AX],exec_not_enough_memory
251 PUSH [SI.user_F]
252 POPF
253 STC
254 PUSHF
255 POP [SI.user_F]
256execret:
257 MOV SS,[user_SS]
258ASSUME SS:NOTHING
259 MOV SP,[user_SP]
260 POP AX ; PUSH ES
261 POP BX ; PUSH DS
262 POP CX ; PUSH BP
263 POP DX ; PUSH DI
264 POP SI ; PUSH SI
265 POP DI ; PUSH DX
266 POP BP ; PUSH CX
267 POP DS ; PUSH BX
268 POP ES ; PUSH AX
269 IRET
270
271EXECHK:
272ASSUME DS:NOTHING,ES:NOTHING,SS:NOTHING
273 PUSH DS
274 MOV DS,[EXESEG]
275 MOV CX,OFFSET EGROUP:ZEXECCODEEND
276 XOR SI,SI
277 JMP CHECK_SUM
278ENDIF
279
280EXEC_ERR: ; Select the correct error message
281 MOV DX,OFFSET RESGROUP:RBADNAM
282 CMP AX,exec_file_not_found
283 JZ GOTEXECEMES
284 CMP AX,error_access_denied
285 JZ GOTEXECEMES
286 MOV DX,OFFSET RESGROUP:TOOBIG
287 CMP AX,exec_not_enough_memory
288 JZ GOTEXECEMES
289 MOV DX,OFFSET RESGROUP:EXEBAD
290 CMP AX,exec_bad_format
291 JZ GOTEXECEMES
292 MOV DX,OFFSET RESGROUP:EXECEMES
293GOTEXECEMES:
294 PUSH CS
295 POP DS
296 CALL RPRINT
297 JMP SHORT NOEXEC
298
299EXT_EXEC:
300;
301; we are now running in free space. anything we do from here
302; on may get trashed. Move the stack (also in free space) to
303; allocated space because since EXEC restores the stack,
304; somebody may trash what is on the stack.
305;
306 MOV CX,CS
307 MOV SS,CX
308 MOV SP,OFFSET RESGROUP:RSTACK
309;
310; Oops!! We have to make sure that the EXEC code doesn't blop a newstack!
311;
312;
313 INT int_command ; Do the EXEC
314 JC EXEC_ERR ; EXEC failed
315EXEC_WAIT:
316 MOV AH,WAIT
317 INT int_command ; Get the return code
318 MOV [RETCODE],AX
319NOEXEC:
320 JMP LODCOM
321
322CONTC:
323 STI
324 MOV AX,CS
325 MOV DS,AX
326ASSUME DS:RESGROUP
327 MOV AH,DISK_RESET
328 INT int_command ; Reset disks in case files were open
329 TEST [BATCH],-1
330 JZ CONTCTERM
331 JMP ASKEND ; See if user wants to terminate batch
332CONTCTERM:
333 XOR BP,BP ; Indicate no read
334 MOV [FORFLAG],0 ; Turn off for processing
335 MOV [PIPEFLAG],0 ; Turn off any pipe
336 CMP [SINGLECOM],0 ; See if we need to set SINGLECOM
337 JZ NOSETSING
338 MOV [SINGLECOM],-1 ; Cause termination on pipe, batch, for
339NOSETSING:
340 CMP [EXTCOM],0
341 JNZ DODAB ; Internal ^C
342 JMP LODCOM1
343DODAB:
344 STC ; Tell DOS to abort
345ZZY PROC FAR
346 RET ; Leave flags on stack
347ZZY ENDP
348
349BADMEMERR: ; Allocation error loading transient
350 MOV DX,OFFSET RESGROUP:BMEMMES
351FATALC:
352 PUSH CS
353 POP DS
354 CALL RPRINT
355 CMP [PERMCOM],0
356 JZ FATALRET
357 CMP [SINGLECOM],0 ; If PERMCOM and SINGLECOM
358 JNZ FATALRET ; Must take INT_2E exit
359 MOV DX,OFFSET RESGROUP:HALTMES
360 CALL RPRINT
361STALL:
362 JMP STALL ; Crash the system nicely
363
364FATALRET:
365 MOV DX,OFFSET RESGROUP:FRETMES
366 CALL RPRINT
367FATALRET2:
368 CMP [PERMCOM],0 ; If we get here and PERMCOM,
369 JNZ RET_2E ; must be INT_2E
370IF IBM
371 LDS DX,DWORD PTR [SYS_CALL]
372ASSUME DS:NOTHING
373 MOV AX,(SET_INTERRUPT_VECTOR SHL 8) + INT_COMMAND
374 INT int_command
375ENDIF
376 MOV AX,[PARENT]
377 MOV WORD PTR CS:[PDB_Parent_PID],AX
378 MOV AX,(EXIT SHL 8) ; Return to lower level
379 INT int_command
380
381RET_2E:
382 PUSH CS
383 POP DS
384ASSUME DS:RESGROUP,ES:NOTHING,SS:NOTHING
385 MOV [SINGLECOM],0 ; Turn off singlecom
386 MOV ES,[LTPA]
387 MOV AH,DEALLOC
388 INT int_command ; Free up space used by transient
389 MOV BX,[SAVE_PDB]
390 MOV AH,SET_CURRENT_PDB
391 INT int_command ; Current process is user
392 MOV AX,[RETCODE]
393 CMP [EXTCOM],0
394 JNZ GOTECODE
395 XOR AX,AX ; Internals always return 0
396GOTECODE:
397 MOV [EXTCOM],1 ; Force external
398 JMP [INT_2E_RET] ;"IRET"
399
400INT_2E: ; Magic command executer
401ASSUME DS:NOTHING,ES:NOTHING,SS:NOTHING
402 POP WORD PTR [INT_2E_RET]
403 POP WORD PTR [INT_2E_RET+2] ;Get return address
404 POP AX ;Chuck flags
405 PUSH CS
406 POP ES
407 MOV DI,80H
408 MOV CX,64
409 REP MOVSW
410 MOV AH,GET_CURRENT_PDB
411 INT int_command ; Get user's header
412 MOV [SAVE_PDB],BX
413 MOV AH,SET_CURRENT_PDB
414 MOV BX,CS
415 INT int_command ; Current process is me
416 MOV [SINGLECOM],81H
417 MOV [EXTCOM],1 ; Make sure this case forced
418
419LODCOM: ; Termination handler
420 CMP [EXTCOM],0
421 JZ LODCOM1 ; If internal, memory already allocated
422 MOV BX,0FFFFH
423 MOV AH,ALLOC
424 INT int_command
425 MOV AX,OFFSET TRANGROUP:TRANSPACEEND + 15
426 MOV CL,4
427 SHR AX,CL
428
429 IF IBM
430 PUSH AX
431 MOV AX,OFFSET EGROUP:ZEXECDATAEND + 15
432 MOV CL,4
433 SHR AX,CL
434 POP CX
435 ADD AX,CX
436 ENDIF
437
438 ADD AX,20H
439 CMP BX,AX ; Is less than 512 byte buffer worth it?
440 JNC MEMOK
441BADMEMERRJ:
442 JMP BADMEMERR ; Not enough memory
443MEMOK:
444 MOV AH,ALLOC
445 INT int_command
446 JC BADMEMERRJ ; Memory arenas probably trashed
447 MOV [EXTCOM],0 ; Flag not to ALLOC again
448 MOV [LTPA],AX ; New TPA is base just allocated
449 ADD BX,AX
450 MOV [MEMSIZ],BX
451
452 MOV AX,OFFSET TRANGROUP:TRANSPACEEND + 15
453 MOV CL,4
454 SHR AX,CL
455
456 IF IBM
457 PUSH AX
458 MOV AX,OFFSET EGROUP:ZEXECDATAEND + 15
459 MOV CL,4
460 SHR AX,CL
461 POP CX
462 ADD AX,CX
463 ENDIF
464
465 SUB BX,AX
466 MOV [TRNSEG],BX ; Transient starts here
467LODCOM1:
468 MOV AX,CS
469 MOV SS,AX
470ASSUME SS:RESGROUP
471 MOV SP,OFFSET RESGROUP:RSTACK
472 MOV DS,AX
473ASSUME DS:RESGROUP
474 CALL HEADFIX ; Make sure files closed stdin and stdout restored
475 XOR BP,BP ; Flag command ok
476 MOV AX,-1
477 XCHG AX,[VERVAL]
478 CMP AX,-1
479 JZ NOSETVER
480 MOV AH,SET_VERIFY_ON_WRITE ; AL has correct value
481 INT int_command
482NOSETVER:
483 CMP [SINGLECOM],-1
484 JNZ NOSNG
485 JMP FATALRET2 ; We have finished the single command
486NOSNG:
487 CALL SETVECT
488
489IF IBMVER
490 CALL EXECHK ; Check exe loader
491 CMP DX,[EXESUM]
492 JNZ BOGUS_COM
493ENDIF
494
495 CALL CHKSUM ; Check the transient
496 CMP DX,[SUM]
497 JZ HAVCOM ; Transient OK
498BOGUS_COM:
499 MOV [LOADING],1 ; Flag DSKERR routine
500 CALL LOADCOM
501CHKSAME:
502
503IF IBMVER
504 CALL EXECHK
505 CMP DX,[EXESUM]
506 JNZ ALSO_BOGUS
507ENDIF
508
509 CALL CHKSUM
510 CMP DX,[SUM]
511 JZ HAVCOM ; Same COMMAND
512ALSO_BOGUS:
513 CALL WRONGCOM
514 JMP SHORT CHKSAME
515HAVCOM:
516 MOV AX,CHAR_OPER SHL 8
517 INT int_command
518 MOV [RSWITCHAR],DL
519 CMP DL,'/'
520 JNZ USESLASH
521 MOV [RDIRCHAR],'\' ; Select alt path separator
522USESLASH:
523 MOV [LOADING],0 ; Flag to DSKERR
524 MOV SI,OFFSET RESGROUP:TRANVARS
525 MOV DI,OFFSET TRANGROUP:HEADCALL
526 MOV ES,[TRNSEG]
527 CLD
528 MOV CX,8
529 REP MOVSW ; Transfer INFO to transient
530 MOV AX,[MEMSIZ]
531 MOV WORD PTR DS:[PDB_block_len],AX ; Adjust my own header
532 JMP DWORD PTR [TRANS]
533
534; Far call to REMCHECK for TRANSIENT
535TREMCHECK PROC FAR
536 CALL REMCHECK
537 RET
538TREMCHECK ENDP
539
540REMCHECK:
541;All registers preserved. Returns zero if media removable, NZ if fixed
542; AL is drive (0=DEF, 1=A,...)
543 IF IBM
544 PUSH AX
545 OR AL,AL
546 JNZ GOTDRV2
547 MOV AH,GET_DEFAULT_DRIVE
548 INT int_command
549 INC AL ;A=1
550GOTDRV2:
551 PUSH BX
552 MOV BL,AL
553 INT 11H ;IBM EQUIP CALL
554 ROL AL,1
555 ROL AL,1
556 AND AL,3
557 JNZ NOT_SINGLE
558 INC AL
559NOT_SINGLE:
560 INC AL ; AL is now MAX floppy #
561 CMP BL,AL
562 POP BX
563 JBE SETREM ; Is an IBM floppy and so is removable
564 OR AL,AL ; Know AL is non-zero
565 JMP SHORT SETNREM
566SETREM:
567 ELSE
568 PUSH AX
569 ENDIF
570
571 XOR AX,AX ;Zero
572
573 IF IBM
574SETNREM:
575 ENDIF
576
577 POP AX
578 RET
579
580; Far call to HEADFIX for TRANSIENT
581THEADFIX PROC FAR
582 CALL HEADFIX
583 RET
584THEADFIX ENDP
585
586HEADFIX:
587 XOR BX,BX ; Clean up header
588 MOV CX,[IO_SAVE]
589 MOV DX,WORD PTR DS:[PDB_JFN_Table]
590 CMP CL,DL
591 JZ CHK1 ; Stdin matches
592 MOV AH,CLOSE
593 INT int_command
594 MOV DS:[PDB_JFN_Table],CL ; Restore stdin
595CHK1:
596 INC BX
597 CMP CH,DH ; Stdout matches
598 JZ CHKOTHERHAND
599 MOV AH,CLOSE
600 INT int_command
601 MOV DS:[PDB_JFN_Table+1],CH ; Restore stdout
602CHKOTHERHAND:
603 ADD BX,4 ; Skip 2,3,4
604 MOV CX,FilPerProc - 5 ; Already done 0,1,2,3,4
605CLOSELOOP:
606 MOV AH,CLOSE
607 INT int_command
608 INC BX
609 LOOP CLOSELOOP
610 RET
611
612SAVHAND:
613ASSUME DS:NOTHING,ES:NOTHING,SS:NOTHING
614 PUSH DS
615 PUSH BX ; Set stdin to sterr, stdout to stderr
616 PUSH AX
617 MOV AH,GET_CURRENT_PDB
618 INT int_command ; Get user's header
619 MOV DS,BX
620 MOV AX,WORD PTR DS:[PDB_JFN_Table]
621 MOV [HANDLE01],AX ; Save user's stdin, stdout
622 MOV AL,DS:[PDB_JFN_Table+2]
623 MOV AH,AL
624 MOV WORD PTR DS:[PDB_JFN_Table],AX ; Dup stderr
625 POP AX
626 POP BX
627 POP DS
628 RET
629
630ASSUME DS:RESGROUP
631GETCOMDSK2:
632 CALL GETCOMDSK
633 JMP LODCOM1 ; Memory already allocated
634
635RESTHAND:
636 PUSH DS
637 PUSH BX ; Restore stdin, stdout to user
638 PUSH AX
639 MOV AH,GET_CURRENT_PDB
640 INT int_command ; Point to user's header
641 MOV AX,[HANDLE01]
642 MOV DS,BX
643ASSUME DS:NOTHING
644 MOV WORD PTR DS:[PDB_JFN_Table],AX ; Stuff his old 0 and 1
645 POP AX
646 POP BX
647 POP DS
648 RET
649ASSUME DS:RESGROUP,SS:RESGROUP
650
651HOPELESS:
652 MOV DX,OFFSET RESGROUP:NOCOM
653 JMP FATALC
654
655GETCOMDSK:
656 MOV DX,OFFSET RESGROUP:NEEDCOM
657GETCOMDSK3:
658 MOV AL,[COMDRV]
659 CALL REMCHECK
660 JNZ HOPELESS ;Non-removable media
661 CALL RPRINT
662 MOV DX,OFFSET RESGROUP:DRVMSG
663 CMP [COMDRV],0
664 JNZ GETCOM1
665 MOV DX,OFFSET RESGROUP:DEFMSG
666GETCOM1:
667 CALL RPRINT
668 MOV DX,OFFSET RESGROUP:PROMPT
669 CALL RPRINT
670 CALL GetRawFlushedByte
671 RET
672
673; flush world and get raw input
674GetRawFlushedByte:
675 MOV AX,(STD_CON_INPUT_FLUSH SHL 8) OR RAW_CON_INPUT
676 INT int_command ; Get char without testing or echo
677 MOV AX,(STD_CON_INPUT_FLUSH SHL 8) + 0
678 INT int_command
679 return
680
681LOADCOM: ; Load in transient
682 INC BP ; Flag command read
683 MOV DX,OFFSET RESGROUP:COMSPEC
684 MOV AX,OPEN SHL 8
685 INT int_command ; Open COMMAND.COM
686 JNC READCOM
687 CMP AX,open_too_many_open_files
688 JNZ TRYDOOPEN
689 MOV DX,OFFSET RESGROUP:NOHANDMES
690 JMP FATALC ; Fatal, will never find a handle
691
692TRYDOOPEN:
693 CALL GETCOMDSK
694 JMP SHORT LOADCOM
695
696READCOM:
697 MOV BX,AX ; Handle
698 MOV DX,OFFSET RESGROUP:TRANSTART
699 XOR CX,CX ; Seek loc
700 MOV AX,LSEEK SHL 8
701 INT int_command
702 JC WRONGCOM1
703 MOV CX,OFFSET TRANGROUP:TRANSPACEEND - 100H
704
705 IF IBM
706 ADD CX,15
707 AND CX,0FFF0H
708 ADD CX,OFFSET EGROUP:ZEXECCODEEND
709 ENDIF
710
711 PUSH DS
712 MOV DS,[TRNSEG]
713ASSUME DS:NOTHING
714 MOV DX,100H
715 MOV AH,READ
716 INT int_command
717 POP DS
718ASSUME DS:RESGROUP
719WRONGCOM1:
720 PUSHF
721 PUSH AX
722 MOV AH,CLOSE
723 INT int_command ; Close COMMAND.COM
724 POP AX
725 POPF
726 JC WRONGCOM ; If error on READ
727 CMP AX,CX
728 JZ RET10 ; Size matched
729WRONGCOM:
730 MOV DX,OFFSET RESGROUP:COMBAD
731 CALL GETCOMDSK3
732 JMP SHORT LOADCOM ; Try again
733
734CHKSUM: ; Compute transient checksum
735 PUSH DS
736 MOV DS,[TRNSEG]
737 MOV SI,100H
738 MOV CX,OFFSET TRANGROUP:TRANDATAEND - 100H
739
740CHECK_SUM:
741 CLD
742 SHR CX,1
743 XOR DX,DX
744CHK:
745 LODSW
746 ADD DX,AX
747 LOOP CHK
748 POP DS
749RET10: RET
750
751SETVECT: ; Set useful vectors
752 MOV DX,OFFSET RESGROUP:LODCOM
753 MOV AX,(SET_INTERRUPT_VECTOR SHL 8) OR 22H ; Set Terminate address
754 INT int_command
755 MOV DX,OFFSET RESGROUP:CONTC
756 MOV AX,(SET_INTERRUPT_VECTOR SHL 8) OR 23H ; Set Ctrl-C address
757 INT int_command
758 MOV DX,OFFSET RESGROUP:DSKERR
759 MOV AX,(SET_INTERRUPT_VECTOR SHL 8) OR 24H ; Set Hard Disk Error address
760 INT int_command
761 RET
762
763CODERES ENDS
764
765; This TAIL segment is used to produce a PARA aligned label in the resident
766; group which is the location where the transient segments will be loaded
767; initial.
768
769TAIL SEGMENT PUBLIC PARA
770 ORG 0
771TRANSTART LABEL WORD
772TAIL ENDS
773
774; This TAIL segment is used to produce a PARA aligned label in the transient
775; group which is the location where the exec segments will be loaded
776; initial.
777
778TRANTAIL SEGMENT PUBLIC PARA
779 ORG 0
780EXECSTART LABEL WORD
781TRANTAIL ENDS
782
783IF IBMVER
784 INCLUDE EXEC.ASM
785ENDIF
786
787 END PROGSTART
788