summaryrefslogtreecommitdiff
path: root/v4.0/src/CMD/COMMAND/COMMAND1.ASM
diff options
context:
space:
mode:
authorGravatar Mark Zbikowski2024-04-25 21:24:10 +0100
committerGravatar Microsoft Open Source2024-04-25 22:32:27 +0000
commit2d04cacc5322951f187bb17e017c12920ac8ebe2 (patch)
tree80ee017efa878dfd5344b44249e6a241f2a7f6e2 /v4.0/src/CMD/COMMAND/COMMAND1.ASM
parentMerge pull request #430 from jpbaltazar/typoptbr (diff)
downloadms-dos-main.tar.gz
ms-dos-main.tar.xz
ms-dos-main.zip
MZ is back!HEADmain
Diffstat (limited to 'v4.0/src/CMD/COMMAND/COMMAND1.ASM')
-rw-r--r--v4.0/src/CMD/COMMAND/COMMAND1.ASM638
1 files changed, 638 insertions, 0 deletions
diff --git a/v4.0/src/CMD/COMMAND/COMMAND1.ASM b/v4.0/src/CMD/COMMAND/COMMAND1.ASM
new file mode 100644
index 0000000..3ee909a
--- /dev/null
+++ b/v4.0/src/CMD/COMMAND/COMMAND1.ASM
@@ -0,0 +1,638 @@
1 page 80,132
2; SCCSID = @(#)command1.asm 1.1 85/05/14
3; SCCSID = @(#)command1.asm 1.1 85/05/14
4TITLE COMMAND - resident code for COMMAND.COM
5NAME COMMAND
6
7;*****************************************************************************
8;
9; MODULE: COMMAND.COM
10;
11; DESCRIPTIVE NAME: Default DOS command interpreter
12;
13; FUNCTION: This version of COMMAND is divided into three distinct
14; parts. First is the resident portion, which includes
15; handlers for interrupts 23H (Cntrl-C), 24H (fatal
16; error), and 2EH (command line execute); it also has
17; code to test and, if necessary, reload the transient
18; portion. Following the resident is the init code, which
19; is overwritten after use. Then comes the transient
20; portion, which includes all command processing (whether
21; internal or external). The transient portion loads at
22; the end of physical memory, and it may be overlayed by
23; programs that need as much memory as possible. When the
24; resident portion of command regains control from a user
25; program, a check sum is performed on the transient
26; portion to see if it must be reloaded. Thus programs
27; which do not need maximum memory will save the time
28; required to reload COMMAND when they terminate.
29;
30; ENTRY POINT: PROGSTART
31;
32; INPUT: command line at offset 81H
33;
34; EXIT_NORMAL: No exit from root level command processor. Can exit
35; from a secondary command processor via the EXIT
36; internal command.
37;
38; EXIT_ERROR: Exit to prior command processor if possible, otherwise
39; hang the system.
40;
41; INTERNAL REFERENCES:
42;
43; ROUTINES: See the COMMAND Subroutine Description Document
44; (COMMAND.DOC)
45;
46; DATA AREAS: See the COMMAND Subroutine Description Document
47; (COMMAND.DOC)
48;
49; EXTERNAL REFERENCES:
50;
51; ROUTINES: none
52;
53; DATA AREAS: none
54;
55;*****************************************************************************
56;
57; REVISION HISTORY
58; ----------------
59;
60; DOS 1.00 to DOS 3.30
61; --------------------------
62; SEE REVISION LOG IN COPY.ASM ALSO
63;
64; REV 1.17
65; 05/19/82 Fixed bug in BADEXE error (relocation error must return to
66; resident since the EXELOAD may have overwritten the transient.
67;
68; REV 1.18
69; 05/21/82 IBM version always looks on drive A
70; MSVER always looks on default drive
71;
72; REV 1.19
73; 06/03/82 Drive spec now entered in command line
74; 06/07/82 Added VER command (print DOS version number) and VOL command
75; (print volume label)
76;
77; REV 1.20
78; 06/09/82 Prints "directory" after directories
79; 06/13/82 MKDIR, CHDIR, PWD, RMDIR added
80;
81; REV 1.50
82; Some code for new 2.0 DOS, sort of HACKey. Not enough time to
83; do it right.
84;
85; REV 1.70
86; EXEC used to fork off new processes
87;
88; REV 1.80
89; C switch for single command execution
90;
91; REV 1.90
92; Batch uses XENIX
93;
94; Rev 2.00
95; Lots of neato stuff
96; IBM 2.00 level
97;
98; Rev 2.01
99; 'D' switch for date time suppression
100;
101; Rev 2.02
102; Default userpath is NUL rather than BIN
103; same as IBM
104; COMMAND split into pieces
105;
106; Rev 2.10
107; INTERNATIONAL SUPPORT
108;
109; Rev 2.50
110; all the 2.x new stuff -MU
111;
112; Rev 3.30 (Ellen G)
113; CALL internal command (TBATCH2.ASM)
114; CHCP internal command (TCMD2B.ASM)
115; INT 24H support of abort, retry, ignore, and fail prompt
116; @ sign suppression of batch file line
117; Replaceable environment value support in batch files
118; INT 2FH calls for APPEND
119; Lots of PTR fixes!
120;
121; Beyond 3.30 to forever (Ellen G)
122; ----------------------
123;
124; A000 DOS 4.00 - Use SYSPARSE for internal commands
125; Use Message Retriever services
126; /MSG switch for resident extended error msg
127; Convert to new capitalization support
128; Better error recovery on CHCP command
129; Code page file tag support
130; TRUENAME internal command
131; Extended screen line support
132; /P switch on DEL/ERASE command
133; Improved file redirection error recovery
134; (removed) Improved batch file performance
135; Unconditional DBCS support
136; Volume serial number support
137; (removed) COMMENT=?? support
138;
139; A001 PTM P20 Move system_cpage from TDATA to TSPC
140;
141; A002 PTM P74 Fix PRESCAN so that redirection symbols do not
142; require delimiters.
143;
144; A003 PTM P5,P9,P111 Included in A000 development
145;
146; A004 PTM P86 Fix IF command to turn off piping before
147; executing
148;
149; A005 DCR D17 If user specifies an extension on the command
150; line search for that extension only.
151;
152; A006 DCR D15 New message for MkDir - "Directory already
153; exists"
154;
155; A007 DCR D2 Change CTTY so that a write is done before XDUP
156;
157; A008 PTM P182 Change COPY to set default if invalid function
158; returned from code page call.
159;
160; A009 PTM P179 Add CRLF to invalid disk change message
161;
162; A010 DCR D43 Allow APPEND to do a far call to SYSPARSE in
163; transient COMMAND.
164;
165; A011 DCR D130 Change redirection to overwrite an EOF mark
166; before appending to a file.
167;
168; A012 PTM P189 Fix redirection error recovery.
169;
170; A013 PTM P330 Change date format
171;
172; A014 PTM P455 Fix echo parsing
173;
174; A015 PTM P517 Fix DIR problem with * vs *.
175;
176; A016 PTM P354 Fix extended error message addressing
177;
178; A017 PTM P448 Fix appending to 0 length files
179;
180; A018 PTM P566,P3903 Fix parse error messages to print out parameter
181; the parser fails on. Fail on duplicate switches.
182;
183; A019 PTM P542 Fix device name to be printed correctly during
184; critical error
185;
186; A020 DCR D43 Set append state off while in DIR
187;
188; A021 PTM P709 Fix CTTY printing ascii characters.
189;
190; A022 DCR D209 Enhanced error recovery
191;
192; A023 PTM P911 Fix ANSI.SYS IOCTL structure.
193;
194; A024 PTM P899 Fix EXTOPEN open modes.
195;
196; A025 PTM P922 Fix messages and optimize PARSE switches
197;
198; A026 DCR D191 Change redirection error recovery support.
199;
200; A027 PTM P991 Fix so that KAUTOBAT & AUTOEXEC are terminated
201; with a carriage return.
202;
203; A028 PTM P1076 Print a blank line before printing invalid
204; date and invalid time messages.
205;
206; A029 PTM P1084 Eliminate calls to parse_check_eol in DATE
207; and TIME.
208;
209; A030 DCR D201 New extended attribute format.
210;
211; A031 PTM P1149 Fix DATE/TIME add blank before prompt.
212;
213; A032 PTM P931 Fix =ON, =OFF for BREAK, VERIFY, ECHO
214;
215; A033 PTM P1298 Fix problem with system crashes on ECHO >""
216;
217; A034 PTM P1387 Fix COPY D:fname+,, to work
218;
219; A035 PTM P1407 Fix so that >> (appending) to a device does
220; do a read to determine eof.
221;
222; A036 PTM P1406 Use 69h instead of 44h to get volume serial
223; so that ASSIGN works correctly.
224;
225; A037 PTM P1335 Fix COMMAND /C with FOR
226;
227; A038 PTM P1635 Fix COPY so that it doesn't accept /V /V
228;
229; A039 DCR D284 Change invalid code page tag from -1 to 0.
230;
231; A040 PTM P1787 Fix redirection to cause error when no file is
232; specified.
233;
234; A041 PTM P1705 Close redirected files after internal APPEND
235; executes.
236;
237; A042 PTM P1276 Fix problem of APPEND paths changes in batch
238; files causing loss of batch file.
239;
240; A043 PTM P2208 Make sure redirection is not set up twice for
241; CALL'ed batch files.
242;
243; A044 PTM P2315 Set switch on PARSE so that 0ah is not used
244; as an end of line character
245;
246; A045 PTM P2560 Make sure we don't lose parse, critical error,
247; and extended message pointers when we EXIT if
248; COMMAND /P is the top level process.
249;
250; A046 PTM P2690 Change COPY message "fn File not found" to
251; "File not found - fn"
252;
253; A047 PTM P2819 Fix transient reload prompt message
254;
255; A048 PTM P2824 Fix COPY path to be upper cased. This was broken
256; when DBCS code was added.
257;
258; A049 PTM P2891 Fix PATH so that it doesn't accept extra characters
259; on line.
260;
261; A050 PTM P3030 Fix TYPE to work properly on files > 64K
262;
263; A051 PTM P3011 Fix DIR header to be compatible with prior releases.
264;
265; A052 PTM P3063,P3228 Fix COPY message for invalid filename on target.
266;
267; A053 PTM P2865 Fix DIR to work in 40 column mode.
268;
269; A054 PTM P3407 Code reduction and critical error on single line
270; PTM P3672 (Change to single parser exported under P3407)
271;
272; A055 PTM P3282 Reset message service variables in INT 23h to fix
273; problems with breaking out of INT 24h
274;
275; A056 PTM P3389 Fix problem of environment overlaying transient.
276;
277; A057 PTM P3384 Fix COMMAND /C so that it works if there is no space
278; before the "string". EX: COMMAND /CDIR
279;
280; A058 PTM P3493 Fix DBCS so that CPARSE eats second character of
281; DBCS switch.
282;
283; A059 PTM P3394 Change the TIME command to right align the display of
284; the time.
285;
286; A060 PTM P3672 Code reduction - change PARSE and EXTENDED ERROR
287; messages to be disk based. Only keep them if /MSG
288; is used.
289;
290; A061 PTM P3928 Fix so that transient doesn't reload when breaking
291; out of internal commands, due to substitution blocks
292; not being reset.
293;
294; A062 PTM P4079 Fix segment override for fetching address of environment
295; of parent copy of COMMAND when no COMSPEC exists in
296; secondary copy of environment. Change default slash in
297; default comspec string to backslash.
298
299; A063 PTM P4140 REDIRECTOR and IFSFUNC changed interface for getting
300; text for critical error messages.
301
302; A064 PTM P4934 Multiplex number for ANSI.SYS changed due to conflict
303; 5/20/88 with Microsoft product already shipped.
304
305; A065 PTM P4935 Multiplex number for SHELL changed due to conflict with
306; 5/20/88 with Microsoft product already shipped.
307
308; A066 PTM P4961 DIR /W /P scrolled first line off the screen in some
309; 5/24/88 cases; where the listing would barely fit without the
310; header and space remaining.
311
312; A067 PTM P5011 For /E: values of 993 to 1024 the COMSPEC was getting
313; 6/6/88 trashed. Turns out that the SETBLOCK for the new
314; environment was putting a "Z block" marker in the old
315; environment. The fix is to move to the old environment
316; to the new environment before doing the SETBLOCK.
317;***********************************************************************************
318
319.XCREF
320.XLIST
321 INCLUDE DOSSYM.INC
322 INCLUDE comsw.asm
323 INCLUDE comequ.asm
324 INCLUDE resmsg.equ ;AN000;
325.LIST
326.CREF
327
328CODERES SEGMENT PUBLIC BYTE ;AC000;
329CODERES ENDS
330
331DATARES SEGMENT PUBLIC BYTE
332 EXTRN BATCH:WORD
333 EXTRN ECHOFLAG:BYTE
334 EXTRN disp_class:byte ;AN055;
335 EXTRN execemes_block:byte ;AC000;
336 EXTRN execemes_off:word ;AC000;
337 EXTRN execemes_subst:byte ;AC000;
338 EXTRN execemes_seg:word ;AC000;
339 EXTRN EXTCOM:BYTE
340 EXTRN FORFLAG:BYTE
341 EXTRN IFFlag:BYTE
342 EXTRN InitFlag:BYTE
343 EXTRN NEST:WORD
344 EXTRN number_subst:byte ;AC000;
345 EXTRN PIPEFLAG:BYTE
346 EXTRN RETCODE:WORD
347 EXTRN SINGLECOM:WORD
348DATARES ENDS
349
350BATARENA SEGMENT PUBLIC PARA ;AC000;
351BATARENA ENDS
352
353BATSEG SEGMENT PUBLIC PARA ;AC000;
354BATSEG ENDS
355
356ENVARENA SEGMENT PUBLIC PARA ;AC000;
357ENVARENA ENDS
358
359ENVIRONMENT SEGMENT PUBLIC PARA ; Default COMMAND environment
360ENVIRONMENT ENDS
361
362INIT SEGMENT PUBLIC PARA
363 EXTRN CONPROC:NEAR
364 EXTRN init_contc_specialcase:near
365INIT ENDS
366
367TAIL SEGMENT PUBLIC PARA
368TAIL ENDS
369
370TRANCODE SEGMENT PUBLIC PARA
371TRANCODE ENDS
372
373TRANDATA SEGMENT PUBLIC BYTE
374TRANDATA ENDS
375
376TRANSPACE SEGMENT PUBLIC BYTE
377TRANSPACE ENDS
378
379TRANTAIL SEGMENT PUBLIC PARA
380TRANTAIL ENDS
381
382RESGROUP GROUP CODERES,DATARES,BATARENA,BATSEG,ENVARENA,ENVIRONMENT,INIT,TAIL
383TRANGROUP GROUP TRANCODE,TRANDATA,TRANSPACE,TRANTAIL
384
385 INCLUDE envdata.asm
386
387; START OF RESIDENT PORTION
388
389CODERES SEGMENT PUBLIC BYTE ;AC000;
390
391
392 PUBLIC EXT_EXEC
393 PUBLIC CONTC
394 PUBLIC Exec_Wait
395
396ASSUME CS:RESGROUP,DS:NOTHING,ES:NOTHING,SS:NOTHING
397
398 EXTRN lodcom:near
399 EXTRN LODCOM1:near
400
401 ORG 0
402ZERO = $
403
404 ORG 80h-1
405 PUBLIC RESCOM
406RESCOM LABEL BYTE
407
408 ORG 100H
409
410PROGSTART:
411 JMP RESGROUP:CONPROC
412
413;
414; COMMAND has issued an EXEC system call and it has returned an error. We
415; examine the error code and select an appropriate message.
416;
417EXEC_ERR:
418 push ds ;AC000; get transient segment
419 pop es ;AC000; into ES
420 push cs ;AC000; get resident segment
421 pop ds ;AC000; into DS
422ASSUME DS:RESGROUP ;AN000;
423 MOV BX,RBADNAM ;AC000; Get message number for Bad command
424 CMP AX,error_file_not_found
425 JZ GOTEXECEMES
426 MOV BX,TOOBIG ;AC000; Get message number for file not found
427 CMP AX,error_not_enough_memory
428 JZ GOTEXECEMES
429 MOV BX,EXEBAD ;AC000; Get message number for bad exe file
430 CMP AX,error_bad_format
431 JZ GOTEXECEMES
432 MOV BX,AccDen ;AC000; Get message number for access denied
433 CMP AX,error_access_denied
434 JZ GOTEXECEMES ;AC000; go print message
435
436DEFAULT_MESSAGE:
437 MOV BX,EXECEMES ;AC000; Get message number for default message
438 MOV EXECEMES_OFF,DX ;AN000; put offset of EXEC string in subst block
439 MOV EXECEMES_SEG,ES ;AN000; put segment of EXEC string in subst block
440 MOV AL,EXECEMES_SUBST ;AN000; get number of substitutions
441 MOV NUMBER_SUBST,AL ;AN000;
442 MOV SI,OFFSET RESGROUP:EXECEMES_BLOCK ;AN000; get address of subst block
443GOTEXECEMES:
444 PUSH CS
445 POP ES ;AC000; get resident segment into ES
446ASSUME ES:RESGROUP ;AN000;
447 MOV DX,BX ;AN000; get message number in DX
448 INVOKE RPRINT
449 JMP SHORT NOEXEC
450;
451; The transient has set up everything for an EXEC system call. For
452; cleanliness, we issue the EXEC here in the resident so that we may be able
453; to recover cleanly upon success.
454;
455EXT_EXEC:
456 push dx ;AN000; save the command name offset
457 INT int_command ; Do the EXEC
458 pop dx ;AN000; restore the command name offset
459 JC EXEC_ERR ; EXEC failed
460;
461; The exec has completed. Retrieve the exit code.
462;
463EXEC_WAIT:
464 push cs ;AC000; get resident segment
465 pop ds ;AC000; into DS
466 MOV AH,WAITPROCESS ;AC000; Get errorlevel
467 INT int_command ; Get the return code
468 MOV [RETCODE],AX
469;
470; We need to test to see if we can reload the transient. THe external command
471; may have overwritten part of the transient.
472;
473NOEXEC:
474 JMP LODCOM
475;
476; This is the default system INT 23 handler. All processes (including
477; COMMAND) get it by default. There are some games that are played: We
478; ignore ^C during most of the INIT code. This is because we may perform an
479; ALLOC and diddle the header! Also, if we are prompting for date/time in the
480; init code, we are to treat ^C as empty responses.
481;
482CONTC PROC FAR
483 ASSUME CS:ResGroup,DS:NOTHING,ES:NOTHING,SS:NOTHING
484 test InitFlag,initINIT ; in initialization?
485 jz NotAtInit ; no
486 test InitFlag,initSpecial ; doing special stuff?
487 jz CmdIRet ; no, ignore ^C
488 jmp resgroup:init_contc_specialcase ; Yes, go handle it
489CmdIret:
490 iret ; yes, ignore the ^C
491NotAtInit:
492 test InitFlag,initCtrlC ; are we already in a ^C?
493 jz NotInit ; nope too.
494;
495; We are interrupting ourselves in this ^C handler. We need to set carry
496; and return to the user sans flags only if the system call was a 1-12 one.
497; Otherwise, we ignore the ^C.
498;
499 cmp ah,1
500 jb CmdIRet
501 cmp ah,12
502 ja CmdIRet
503 add sp,6 ; remove int frame
504 stc
505 ret 2 ; remove those flags...
506;
507; We have now received a ^C for some process (maybe ourselves but not at INIT).
508;
509; Note that we are running on the user's stack!!! Bad news if any of the
510; system calls below go and issue another INT 24... Massive stack overflow!
511; Another bad point is that SavHand will save an already saved handle, thus
512; losing a possible redirection...
513;
514; All we need to do is set the flag to indicate nested ^C. The above code
515; will correctly flag the ^C diring the message output and prompting while
516; ignoring the ^C the rest of the time.
517;
518; Clean up: flush disk. If we are in the middle of a batch file, we ask if
519; he wants to terminate it. If he does, then we turn off all internal flags
520; and let the DOS abort.
521;
522NotInit:
523 or InitFlag,initCtrlC ; nested ^c is on
524 STI
525 PUSH CS ; El Yucko! Change the user's DS!!
526 POP DS
527ASSUME DS:RESGROUP
528 MOV DISP_CLASS,UTIL_MSG_CLASS ;AN055; reset display class
529 MOV NUMBER_SUBST,NO_SUBST ;AN055; reset number of substitutions
530 MOV AX,SingleCom
531 OR AX,AX
532 JNZ NoReset
533 PUSH AX
534 MOV AH,DISK_RESET
535 INT int_command ; Reset disks in case files were open
536 POP AX
537NoReset:
538;
539; In the generalized version of FOR, PIPE and BATCH, we would walk the entire
540; active list and free each segment. Here, we just free the single batch
541; segment.
542;
543 TEST Batch,-1
544 JZ CONTCTERM
545 OR AX,AX
546 JNZ Contcterm
547 invoke SavHand
548 invoke ASKEND ; See if user wants to terminate batch
549;
550; If the carry flag is clear, we do NOT free up the batch file
551;
552 JNC ContBatch
553 mov cl,echoflag ;AN000; get current echo flag
554 PUSH BX ;G
555
556ClearBatch:
557 MOV ES,[BATCH] ; get batch segment
558 mov di,batfile ;AN000; get offset of batch file name
559 mov ax,mult_shell_brk ;AN000; does the SHELL want this terminated?
560 int 2fh ;AN000; call the SHELL
561 cmp al,shell_action ;AN000; does shell want this batch?
562 jz shell_bat_cont ;AN000; yes - keep it
563
564 MOV BX,ES:[BATFORPTR] ;G get old FOR segment
565 cmp bx,0 ;G is a FOR in progress
566 jz no_bat_for ;G no - don't deallocate
567 push es ;G
568 mov es,bx ;G yes - free it up...
569 MOV AH,DEALLOC ;G
570 INT 21H ;G
571 pop es ;G restore to batch segment
572
573no_bat_for:
574 mov cl,ES:[batechoflag] ;G get old echo flag
575 MOV BX,ES:[BATLAST] ;G get old batch segment
576 MOV AH,DEALLOC ; free it up...
577 INT 21H
578 MOV [BATCH],BX ;G get ready to deallocate next batch
579 DEC NEST ;G Is there another batch file?
580 JNZ CLEARBATCH ;G Keep going until no batch file
581
582;
583; We are terminating a batch file; restore the echo status
584;
585
586shell_bat_cont: ;AN000; continue batch for SHELL
587
588 POP BX ;G
589 MOV ECHOFLAG,CL ;G reset echo status
590 MOV PIPEFLAG,0 ;G turn off pipeflag
591ContBatch:
592 invoke CRLF ;G print out crlf before returning
593 invoke RestHand
594;
595; Yes, we are terminating. Turn off flags and allow the DOS to abort.
596;
597CONTCTERM:
598 XOR AX,AX ; Indicate no read
599 MOV BP,AX
600;
601; The following resetting of the state flags is good for the generalized batch
602; processing.
603;
604 MOV IfFlag,AL ; turn off iffing
605 MOV [FORFLAG],AL ; Turn off for processing
606 call ResPipeOff
607 CMP [SINGLECOM],AX ; See if we need to set SINGLECOM
608 JZ NOSETSING
609 MOV [SINGLECOM],-1 ; Cause termination on pipe, batch, for
610NOSETSING:
611;
612; If we are doing an internal command, go through the reload process. If we
613; are doing an external, let DOS abort the process. In both cases, we are
614; now done with the ^C processing.
615;
616 AND InitFlag,NOT initCtrlC
617 CMP [EXTCOM],AL
618 JNZ DODAB ; Internal ^C
619 JMP LODCOM1
620DODAB:
621 STC ; Tell DOS to abort
622 RET ; Leave flags on stack
623ContC ENDP
624
625public ResPipeOff
626 assume ds:nothing,es:nothing
627ResPipeOff:
628 SaveReg <AX>
629 xor ax,ax
630 xchg PipeFlag,al
631 or al,al
632 jz NoPipePop
633 shr EchoFlag,1
634NoPipePop:
635 RestoreReg <AX>
636 return
637CODERES ENDS
638 END PROGSTART