]>
wirehaze git hosting - MS-DOS.git/blob - v4.0/src/CMD/COMMAND/COMMAND1.ASM
2 ; SCCSID = @(#)command1.asm 1.1 85/05/14
3 ; SCCSID = @(#)command1.asm 1.1 85/05/14
4 TITLE COMMAND
- resident
code for COMMAND
.COM
7 ;*****************************************************************************
11 ; DESCRIPTIVE NAME: Default DOS command interpreter
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.
30 ; ENTRY POINT: PROGSTART
32 ; INPUT: command line at offset 81H
34 ; EXIT_NORMAL: No exit from root level command processor. Can exit
35 ; from a secondary command processor via the EXIT
38 ; EXIT_ERROR: Exit to prior command processor if possible, otherwise
41 ; INTERNAL REFERENCES:
43 ; ROUTINES: See the COMMAND Subroutine Description Document
46 ; DATA AREAS: See the COMMAND Subroutine Description Document
49 ; EXTERNAL REFERENCES:
55 ;*****************************************************************************
60 ; DOS 1.00 to DOS 3.30
61 ; --------------------------
62 ; SEE REVISION LOG IN COPY.ASM ALSO
65 ; 05/19/82 Fixed bug in BADEXE error (relocation error must return to
66 ; resident since the EXELOAD may have overwritten the transient.
69 ; 05/21/82 IBM version always looks on drive A
70 ; MSVER always looks on default drive
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)
78 ; 06/09/82 Prints "directory" after directories
79 ; 06/13/82 MKDIR, CHDIR, PWD, RMDIR added
82 ; Some code for new 2.0 DOS, sort of HACKey. Not enough time to
86 ; EXEC used to fork off new processes
89 ; C switch for single command execution
99 ; 'D' switch for date time suppression
102 ; Default userpath is NUL rather than BIN
104 ; COMMAND split into pieces
107 ; INTERNATIONAL SUPPORT
110 ; all the 2.x new stuff -MU
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
121 ; Beyond 3.30 to forever (Ellen G)
122 ; ----------------------
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
139 ; A001 PTM P20 Move system_cpage from TDATA to TSPC
141 ; A002 PTM P74 Fix PRESCAN so that redirection symbols do not
142 ; require delimiters.
144 ; A003 PTM P5,P9,P111 Included in A000 development
146 ; A004 PTM P86 Fix IF command to turn off piping before
149 ; A005 DCR D17 If user specifies an extension on the command
150 ; line search for that extension only.
152 ; A006 DCR D15 New message for MkDir - "Directory already
155 ; A007 DCR D2 Change CTTY so that a write is done before XDUP
157 ; A008 PTM P182 Change COPY to set default if invalid function
158 ; returned from code page call.
160 ; A009 PTM P179 Add CRLF to invalid disk change message
162 ; A010 DCR D43 Allow APPEND to do a far call to SYSPARSE in
165 ; A011 DCR D130 Change redirection to overwrite an EOF mark
166 ; before appending to a file.
168 ; A012 PTM P189 Fix redirection error recovery.
170 ; A013 PTM P330 Change date format
172 ; A014 PTM P455 Fix echo parsing
174 ; A015 PTM P517 Fix DIR problem with * vs *.
176 ; A016 PTM P354 Fix extended error message addressing
178 ; A017 PTM P448 Fix appending to 0 length files
180 ; A018 PTM P566,P3903 Fix parse error messages to print out parameter
181 ; the parser fails on. Fail on duplicate switches.
183 ; A019 PTM P542 Fix device name to be printed correctly during
186 ; A020 DCR D43 Set append state off while in DIR
188 ; A021 PTM P709 Fix CTTY printing ascii characters.
190 ; A022 DCR D209 Enhanced error recovery
192 ; A023 PTM P911 Fix ANSI.SYS IOCTL structure.
194 ; A024 PTM P899 Fix EXTOPEN open modes.
196 ; A025 PTM P922 Fix messages and optimize PARSE switches
198 ; A026 DCR D191 Change redirection error recovery support.
200 ; A027 PTM P991 Fix so that KAUTOBAT & AUTOEXEC are terminated
201 ; with a carriage return.
203 ; A028 PTM P1076 Print a blank line before printing invalid
204 ; date and invalid time messages.
206 ; A029 PTM P1084 Eliminate calls to parse_check_eol in DATE
209 ; A030 DCR D201 New extended attribute format.
211 ; A031 PTM P1149 Fix DATE/TIME add blank before prompt.
213 ; A032 PTM P931 Fix =ON, =OFF for BREAK, VERIFY, ECHO
215 ; A033 PTM P1298 Fix problem with system crashes on ECHO >""
217 ; A034 PTM P1387 Fix COPY D:fname+,, to work
219 ; A035 PTM P1407 Fix so that >> (appending) to a device does
220 ; do a read to determine eof.
222 ; A036 PTM P1406 Use 69h instead of 44h to get volume serial
223 ; so that ASSIGN works correctly.
225 ; A037 PTM P1335 Fix COMMAND /C with FOR
227 ; A038 PTM P1635 Fix COPY so that it doesn't accept /V /V
229 ; A039 DCR D284 Change invalid code page tag from -1 to 0.
231 ; A040 PTM P1787 Fix redirection to cause error when no file is
234 ; A041 PTM P1705 Close redirected files after internal APPEND
237 ; A042 PTM P1276 Fix problem of APPEND paths changes in batch
238 ; files causing loss of batch file.
240 ; A043 PTM P2208 Make sure redirection is not set up twice for
241 ; CALL'ed batch files.
243 ; A044 PTM P2315 Set switch on PARSE so that 0ah is not used
244 ; as an end of line character
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.
250 ; A046 PTM P2690 Change COPY message "fn File not found" to
251 ; "File not found - fn"
253 ; A047 PTM P2819 Fix transient reload prompt message
255 ; A048 PTM P2824 Fix COPY path to be upper cased. This was broken
256 ; when DBCS code was added.
258 ; A049 PTM P2891 Fix PATH so that it doesn't accept extra characters
261 ; A050 PTM P3030 Fix TYPE to work properly on files > 64K
263 ; A051 PTM P3011 Fix DIR header to be compatible with prior releases.
265 ; A052 PTM P3063,P3228 Fix COPY message for invalid filename on target.
267 ; A053 PTM P2865 Fix DIR to work in 40 column mode.
269 ; A054 PTM P3407 Code reduction and critical error on single line
270 ; PTM P3672 (Change to single parser exported under P3407)
272 ; A055 PTM P3282 Reset message service variables in INT 23h to fix
273 ; problems with breaking out of INT 24h
275 ; A056 PTM P3389 Fix problem of environment overlaying transient.
277 ; A057 PTM P3384 Fix COMMAND /C so that it works if there is no space
278 ; before the "string". EX: COMMAND /CDIR
280 ; A058 PTM P3493 Fix DBCS so that CPARSE eats second character of
283 ; A059 PTM P3394 Change the TIME command to right align the display of
286 ; A060 PTM P3672 Code reduction - change PARSE and EXTENDED ERROR
287 ; messages to be disk based. Only keep them if /MSG
290 ; A061 PTM P3928 Fix so that transient doesn't reload when breaking
291 ; out of internal commands, due to substitution blocks
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.
299 ; A063 PTM P4140 REDIRECTOR and IFSFUNC changed interface for getting
300 ; text for critical error messages.
302 ; A064 PTM P4934 Multiplex number for ANSI.SYS changed due to conflict
303 ; 5/20/88 with Microsoft product already shipped.
305 ; A065 PTM P4935 Multiplex number for SHELL changed due to conflict with
306 ; 5/20/88 with Microsoft product already shipped.
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.
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 ;***********************************************************************************
324 INCLUDE resmsg
.equ
;AN000;
328 CODERES
SEGMENT PUBLIC BYTE ;AC000;
331 DATARES
SEGMENT PUBLIC 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;
344 EXTRN number_subst
:byte ;AC000;
350 BATARENA
SEGMENT PUBLIC PARA
;AC000;
353 BATSEG
SEGMENT PUBLIC PARA
;AC000;
356 ENVARENA
SEGMENT PUBLIC PARA
;AC000;
359 ENVIRONMENT
SEGMENT PUBLIC PARA
; Default COMMAND environment
362 INIT
SEGMENT PUBLIC PARA
364 EXTRN init_contc_specialcase
:near
367 TAIL
SEGMENT PUBLIC PARA
370 TRANCODE
SEGMENT PUBLIC PARA
373 TRANDATA
SEGMENT PUBLIC BYTE
376 TRANSPACE
SEGMENT PUBLIC BYTE
379 TRANTAIL
SEGMENT PUBLIC PARA
382 RESGROUP GROUP CODERES
,DATARES
,BATARENA
,BATSEG
,ENVARENA
,ENVIRONMENT
,INIT
,TAIL
383 TRANGROUP GROUP TRANCODE
,TRANDATA
,TRANSPACE
,TRANTAIL
387 ; START OF RESIDENT PORTION
389 CODERES
SEGMENT PUBLIC BYTE ;AC000;
396 ASSUME
CS:RESGROUP
,DS:NOTHING
,ES:NOTHING
,SS:NOTHING
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.
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
422 ASSUME
DS:RESGROUP
;AN000;
423 MOV BX,RBADNAM
;AC000; Get message number for Bad command
424 CMP AX,error_file_not_found
426 MOV BX,TOOBIG
;AC000; Get message number for file not found
427 CMP AX,error_not_enough_memory
429 MOV BX,EXEBAD
;AC000; Get message number for bad exe file
430 CMP AX,error_bad_format
432 MOV BX,AccDen
;AC000; Get message number for access denied
433 CMP AX,error_access_denied
434 JZ GOTEXECEMES
;AC000; go print 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
445 POP ES ;AC000; get resident segment into ES
446 ASSUME
ES:RESGROUP
;AN000;
447 MOV DX,BX ;AN000; get message number in DX
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.
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
461 ; The exec has completed. Retrieve the exit code.
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
470 ; We need to test to see if we can reload the transient. THe external command
471 ; may have overwritten part of the transient.
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.
483 ASSUME
CS:ResGroup
,DS:NOTHING
,ES:NOTHING
,SS:NOTHING
484 test InitFlag
,initINIT
; in initialization?
486 test InitFlag
,initSpecial
; doing special stuff?
487 jz CmdIRet
; no, ignore ^C
488 jmp resgroup
:init_contc_specialcase
; Yes, go handle it
490 iret ; yes, ignore the ^C
492 test InitFlag
,initCtrlC
; are we already in a ^C?
493 jz NotInit
; nope too.
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.
503 add sp,6 ; remove int frame
505 ret 2 ; remove those flags...
507 ; We have now received a ^C for some process (maybe ourselves but not at INIT).
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...
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.
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.
523 or InitFlag
,initCtrlC
; nested ^c is on
525 PUSH CS ; El Yucko! Change the user's DS!!
528 MOV DISP_CLASS
,UTIL_MSG_CLASS
;AN055; reset display class
529 MOV NUMBER_SUBST
,NO_SUBST
;AN055; reset number of substitutions
535 INT int_command
; Reset disks in case files were open
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
548 invoke ASKEND
; See if user wants to terminate batch
550 ; If the carry flag is clear, we do NOT free up the batch file
553 mov cl,echoflag
;AN000; get current echo flag
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
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
568 mov es,bx ;G yes - free it up...
571 pop es ;G restore to batch segment
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...
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
583 ; We are terminating a batch file; restore the echo status
586 shell_bat_cont: ;AN000; continue batch for SHELL
589 MOV ECHOFLAG
,CL ;G reset echo status
590 MOV PIPEFLAG
,0 ;G turn off pipeflag
592 invoke CRLF
;G print out crlf before returning
595 ; Yes, we are terminating. Turn off flags and allow the DOS to abort.
598 XOR AX,AX ; Indicate no read
601 ; The following resetting of the state flags is good for the generalized batch
604 MOV IfFlag
,AL ; turn off iffing
605 MOV [FORFLAG
],AL ; Turn off for processing
607 CMP [SINGLECOM
],AX ; See if we need to set SINGLECOM
609 MOV [SINGLECOM
],-1 ; Cause termination on pipe, batch, for
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.
616 AND InitFlag
,NOT initCtrlC
618 JNZ DODAB
; Internal ^C
621 STC ; Tell DOS to abort
622 RET ; Leave flags on stack
626 assume
ds:nothing
,es:nothing