summaryrefslogtreecommitdiff
path: root/v4.0/src/CMD/COMMAND
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
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')
-rw-r--r--v4.0/src/CMD/COMMAND/COMEQU.ASM241
-rw-r--r--v4.0/src/CMD/COMMAND/COMMAND.LNK6
-rw-r--r--v4.0/src/CMD/COMMAND/COMMAND.SKL213
-rw-r--r--v4.0/src/CMD/COMMAND/COMMAND1.ASM638
-rw-r--r--v4.0/src/CMD/COMMAND/COMMAND2.ASM619
-rw-r--r--v4.0/src/CMD/COMMAND/COMSEG.ASM43
-rw-r--r--v4.0/src/CMD/COMMAND/COMSW.ASM6
-rw-r--r--v4.0/src/CMD/COMMAND/COPY.ASM1001
-rw-r--r--v4.0/src/CMD/COMMAND/COPYPR1.ASM276
-rw-r--r--v4.0/src/CMD/COMMAND/COPYPR2.ASM450
-rw-r--r--v4.0/src/CMD/COMMAND/CPARSE.ASM417
-rw-r--r--v4.0/src/CMD/COMMAND/ENVDATA.ASM28
-rw-r--r--v4.0/src/CMD/COMMAND/FORDATA.ASM19
-rw-r--r--v4.0/src/CMD/COMMAND/IFEQU.ASM18
-rw-r--r--v4.0/src/CMD/COMMAND/INIT.ASM1685
-rw-r--r--v4.0/src/CMD/COMMAND/IPARSE.ASM38
-rw-r--r--v4.0/src/CMD/COMMAND/MAKEFILE134
-rw-r--r--v4.0/src/CMD/COMMAND/PARSE2.ASM422
-rw-r--r--v4.0/src/CMD/COMMAND/PATH1.ASM507
-rw-r--r--v4.0/src/CMD/COMMAND/PATH2.ASM458
-rw-r--r--v4.0/src/CMD/COMMAND/RDATA.ASM611
-rw-r--r--v4.0/src/CMD/COMMAND/RESMSG.EQU43
-rw-r--r--v4.0/src/CMD/COMMAND/RUCODE.ASM739
-rw-r--r--v4.0/src/CMD/COMMAND/TBATCH.ASM1045
-rw-r--r--v4.0/src/CMD/COMMAND/TBATCH2.ASM753
-rw-r--r--v4.0/src/CMD/COMMAND/TCMD1A.ASM598
-rw-r--r--v4.0/src/CMD/COMMAND/TCMD1B.ASM730
-rw-r--r--v4.0/src/CMD/COMMAND/TCMD2A.ASM552
-rw-r--r--v4.0/src/CMD/COMMAND/TCMD2B.ASM597
-rw-r--r--v4.0/src/CMD/COMMAND/TCODE.ASM540
-rw-r--r--v4.0/src/CMD/COMMAND/TDATA.ASM777
-rw-r--r--v4.0/src/CMD/COMMAND/TENV.ASM633
-rw-r--r--v4.0/src/CMD/COMMAND/TENV2.ASM663
-rw-r--r--v4.0/src/CMD/COMMAND/TFOR.ASM551
-rw-r--r--v4.0/src/CMD/COMMAND/TMISC1.ASM655
-rw-r--r--v4.0/src/CMD/COMMAND/TMISC2.ASM487
-rw-r--r--v4.0/src/CMD/COMMAND/TPARSE.ASM76
-rw-r--r--v4.0/src/CMD/COMMAND/TPIPE.ASM660
-rw-r--r--v4.0/src/CMD/COMMAND/TPRINTF.ASM365
-rw-r--r--v4.0/src/CMD/COMMAND/TRANMSG.ASM671
-rw-r--r--v4.0/src/CMD/COMMAND/TSPC.ASM488
-rw-r--r--v4.0/src/CMD/COMMAND/TUCODE.ASM520
-rw-r--r--v4.0/src/CMD/COMMAND/UINIT.ASM270
43 files changed, 20243 insertions, 0 deletions
diff --git a/v4.0/src/CMD/COMMAND/COMEQU.ASM b/v4.0/src/CMD/COMMAND/COMEQU.ASM
new file mode 100644
index 0000000..40273e3
--- /dev/null
+++ b/v4.0/src/CMD/COMMAND/COMEQU.ASM
@@ -0,0 +1,241 @@
1; SCCSID = @(#)comequ.asm 1.1 85/05/14
2; SCCSID = @(#)comequ.asm 1.1 85/05/14
3;*************************************
4; COMMAND EQUs which are not switch dependant
5
6EMGDEBUG = FALSE
7
8SYM EQU ">"
9
10LINESPERPAGE EQU 25 ;AC000; default lines per page
11NORMPERLIN EQU 1
12WIDEPERLIN EQU 5
13COMBUFLEN EQU 128 ; Length of commmand buffer
14BatLen EQU 32 ; buffer for batch files
15YES_ECHO EQU 1 ; echo line
16NO_ECHO EQU 0 ; don't echo line
17No_Echo_Char EQU "@" ; don't echo line if this is first char
18call_in_progress EQU 1 ; indicate we're in the CALL command
19length_call EQU 4 ; length of CALL
20max_nest EQU 10 ; max # levels of batch nesting allowed
21fail_allowed EQU 00001000b ; critical error
22retry_allowed EQU 00010000b ; critical error
23Ignore_allowed EQU 00100000b ; critical error
24nullcommand EQU 1 ; no command on command line
25end_of_line EQU -1 ;AN000; end of line return from parser
26end_of_line_out EQU 0 ;AN000; end of line for output
27end_of_line_in EQU 0dh ;AN000; end of line for input
28result_number EQU 1 ;AN000; number returned from parser
29result_string EQU 3 ;AN000; string returned from parser
30result_filespec EQU 5 ;AN000; filespec returned from parser
31result_drive EQU 6 ;AN000; drive returned from parser
32result_date EQU 7 ;AN000; date returned from parser
33result_time EQU 8 ;AN000; time returned from parser
34result_no_error EQU 0 ;AN000; no error returned from parser
35no_cont_flag EQU 0 ;AN000; no control flags for message
36util_msg_class EQU -1 ;AN000; message class for utility
37ext_msg_class EQU 1 ;AN000; message class for extended error
38parse_msg_class EQU 2 ;AN000; message class for parse error
39crit_msg_class EQU 3 ;AN000; message class for critical error
40ext_crlf_class EQU 081h ;AN054; message class for extended error with no CRLF
41colon_char EQU ":" ;AN000; colon character
42crt_ioctl_ln EQU 14 ;AN000; default length of data for display ioctl
43text_mode EQU 1 ;AN000; text mode return from ioctl
44get_generic EQU 07Fh ;AN000; generic ioctl - get device info
45set_crit_dev EQU 0100H ;AN000; device attribute for critical error on I/0
46mult_ansi EQU 01Ah ;AC064; multiplex for ansi.sys
47mult_shell_get EQU 01902h ;AC065; multiplex for Shell - get next command
48mult_shell_brk EQU 01903h ;AN000; multiplex for Shell - ^C batch check
49shell_action equ 0ffh ;AN000; SHELL - return for taking SHELL specific action
50bat_not_open EQU -1 ;AN000; batch handle will be set to this if not open
51bat_open_handle EQU 19 ;AN000; handle will be in this position in JFN table
52Ptr_seg_pos equ 7 ;AN000; Offset from start of message block for subst segment
53Ptr_off_pos equ 5 ;AN000; Offset from start of message block for subst offset
54Parm_off_pos equ word ptr 2 ;AN000; Offset from start of subst list for subst offset
55parm_block_size equ 11 ;AN000; size of message subst block
56blank equ " " ;AN000; blank character
57no_subst equ 0 ;AN000; no substitutions for messages
58one_subst equ 1 ;AN000; one substitution for messages
59no_handle_out equ -1 ;AN000; use function 1 thru 12 for message retriever
60res_subst equ 2 ;AN000; offset from start of message definition to number of subst
61read_open_mode equ 0000000000000000b ;AN024; extended open mode for read
62read_open_flag equ 0000000100000001b ;AN000; extended open flags for read
63write_open_mode equ 0000000000000001b ;AN024; extended open mode for read
64write_open_flag equ 0000000100000001b ;AN000; extended open flags for read
65creat_open_flag equ 0000000100010010b ;AN000; extended open flags for read
66get_CPSW equ 3 ;AN000; minor function for get CPSW status
67CPSW_off equ 0 ;AN000; CPSW return from function - OFF
68Get_XA equ 2 ;AN030; minor function for get extended attributes
69Set_XA equ 4 ;AN000; minor function for set extended attributes
70file_no_cpage equ 0 ;AN000; file has no code page tag
71file_inv_cpage equ -1 ;AN000; file has invalid code page tag
72do_xa equ -1 ;AN000; flag to get extended attributes
73inv_cp_tag equ 0 ;AC039; tag for invalid code page
74no_xa_seg equ -1 ;AN000; no segment for extended attributes - COPY
75capital_A equ 'A' ;AC000;
76vbar equ '|' ;AC000;
77labracket equ '<' ;AC000;
78rabracket equ '>' ;AC000;
79dollar equ '$' ;AC000;
80lparen equ '(' ;AC000;
81rparen equ ')' ;AC000;
82nullrparen equ 29h ;AC000;
83in_word equ 4e49h ;AC000; 'NI' ('IN' backwards)
84do_word equ 4f44h ;AC000; 'OD' ('DO' backwards)
85star equ '*' ;AC000;
86plus_chr equ '+' ;AC000;
87small_a equ 'a' ;AC000;
88small_z equ 'z' ;AC000;
89dot_chr equ '.' ;AC000;
90tab_chr equ 9 ;AN032;
91equal_chr equ '=' ;AN032;
92semicolon equ ';' ;AN049;
93dot_qmark equ 2e3fh ;AC000; '.?'
94dot_colon equ 2e3ah ;AC000; '.:'
95capital_n equ 0 ;AC000; result from Y/N call if N entered
96capital_y equ 1 ;AC000; result from Y/N call if Y entered
97AppendInstall equ 0B700H ;AN020; append install check
98AppendDOS equ 0B702H ;AN020; append DOS version check
99AppendGetState equ 0B706H ;AN020; append get current state
100AppendSetState equ 0B707H ;AN020; append set current state
101AppendTruename equ 0B711H ;AN042; Get file's real location for Batch
102search_attr equ attr_read_only+attr_hidden+attr_directory ;AC042;
103
104;*************************************
105;* PARSE ERROR MESSAGES
106;*************************************
107
108MoreArgs_Ptr equ 1 ;AN000;"Too many parameters" message number
109LessArgs_Ptr equ 2 ;AN000;"Required parameter missing" message number
110BadSwt_Ptr equ 3 ;AN000;"Invalid switch" message number
111BadParm_Ptr equ 10 ;AN000;"Invalid parameter" message number
112
113;*************************************
114;* EQUATES FOR MESSAGE RETRIEVER
115;*************************************
116
117GET_EXTENDED_MSG EQU 0 ;AN000; get extended message address
118SET_EXTENDED_MSG EQU 1 ;AN000; set extended message address
119GET_PARSE_MSG EQU 2 ;AN000; get parse message address
120SET_PARSE_MSG EQU 3 ;AN000; set parse message address
121GET_CRITICAL_MSG EQU 4 ;AN000; get critical message address
122SET_CRITICAL_MSG EQU 5 ;AN000; set critical message address
123MESSAGE_2F EQU 46 ;AN000; minor code for message retriever
124
125;*********************************
126;* EQUATES FOR INT 10H
127;*********************************
128
129VIDEO_IO_INT EQU 10H ;AN000; equate for int 10h
130SET_VIDEO_MODE EQU 0 ;AN000; set video mode
131SET_CURSOR_POSITION EQU 2 ;AN000; set new cursor position
132SCROLL_VIDEO_PAGE EQU 6 ;AN000; scroll active page up
133VIDEO_ATTRIBUTE EQU 7 ;AN000; attribute to be used on blank line
134SET_COLOR_PALETTE EQU 11 ;AN000; set color for video
135GET_VIDEO_STATE EQU 15 ;AN000; get current video state
136VIDEO_ALPHA EQU 3 ;AN000; alpha video is 3 or below
137VIDEO_BW EQU 7 ;AN000; mode for 80X25 black & white
138
139AltPipeChr equ "|" ; alternate pipe character
140
141FCB EQU 5CH
142
143VARSTRUC STRUC
144ISDIR DB ?
145SIZ DB ?
146TTAIL DW ?
147INFO DB ?
148BUF DB DIRSTRLEN + 20 DUP (?)
149VARSTRUC ENDS
150
151fCheckDrive equ 00000001b
152fSwitchAllowed equ 00000010b
153
154;
155; Test switches
156;
157fParse EQU 0001h ; display results of parseline
158
159;
160; Batch segment structure
161;
162; BYTE type of segment
163; BYTE echo state of parent on entry to batch file
164; WORD segment of last batch file
165; WORD segment for FOR command
166; BYTE FOR flag state on entry to batch file
167; DWORD offset for next line
168; 10 WORD pointers to parameters. -1 is empty parameter
169; ASCIZ file name (with . and ..)
170; BYTES CR-terminated parameters
171; BYTE 0 flag to indicate end of parameters
172;
173
174BatchType equ 0
175
176BatchSegment struc
177BatType DB BatchType ; signature
178Batechoflag DB 0 ; G state of echo
179Batlast DW 0 ; G segment of last batch file
180Batforptr DW 0 ; G segment for FOR command
181Batforflag DB 0 ; G state of FOR
182BatSeek DD ? ; lseek position of next char
183BatParm DW 10 dup (?) ; pointers to parameters
184BatFile DB ? ; beginning of batch file name
185BatchSegment ends
186
187ANULL equ 0 ; terminates an argv string
188ARGMAX equ 64 ; max args on a command line
189ARGBLEN equ 2*128 ; 1char each plus term NUL
190tplen equ 64 ; max size of one argument
191arg_cnt_error equ 1 ; number of args > MAXARG
192arg_buf_ovflow equ 2 ; overflowed argbuffer
193
194argv_ele STRUC ; elements in the argv array
195 argpointer DW (?) ; pointer to the argstring
196 argflags DB (?) ; cparse flags for this argstring
197 argstartel DW (?) ; the result of cparse's [STARTEL]
198 arglen DW (?) ; cparse's char count + one (for null)
199 argsw_word DW (?) ; any switches after this? what kinds?
200 arg_ocomptr DW (?) ; pointer into original command string
201argv_ele ENDS
202
203arg_unit STRUC
204 argv DB (ARGMAX * SIZE argv_ele) DUP (?)
205 argvcnt DW (?) ; number of arguments
206 argswinfo DW (?) ; Switch information for entire line
207 argbuf DW ARGBLEN DUP (?) ; storage for argv strings
208 argforcombuf db COMBUFLEN DUP (?) ; Original for loop command string
209arg_unit ENDS
210
211parseflags RECORD special_delim:1, unused:4, path_sep:1, wildcard:1, sw_flag:1
212
213SwitchV EQU 10h
214SwitchB EQU 08h
215SwitchA EQU 04h
216SwitchP EQU 02h
217SwitchW EQU 01h
218fSwitch EQU 8000h
219fBadSwitch EQU 4000h
220
221SwitchDir EQU SwitchP + SwitchW + fSwitch
222SwitchCopy EQU SwitchV + SwitchA + SwitchB + fSwitch
223
224break <Trap: Get the attention of MSDOS>
225; TRAP snares the operating system for a service call
226; AX, as well as any other registers MS-DOS takes a fancy to, will be crunched.
227trap MACRO dos_function,dos_info
228 ifnb <dos_info>
229 mov AX, (dos_function SHL 8) + dos_info
230 else
231 mov AX, (dos_function SHL 8)
232 endif
233 int int_command
234ENDM
235
236;
237; Equates for initialization
238;
239initInit equ 01h ; initialization in progress
240initSpecial equ 02h ; in initialization time/date routine
241initCtrlC equ 04h ; already in ^C handler
diff --git a/v4.0/src/CMD/COMMAND/COMMAND.LNK b/v4.0/src/CMD/COMMAND/COMMAND.LNK
new file mode 100644
index 0000000..29a639a
--- /dev/null
+++ b/v4.0/src/CMD/COMMAND/COMMAND.LNK
@@ -0,0 +1,6 @@
1/map COMMAND1.OBJ COMMAND2.OBJ RUCODE.OBJ RDATA.OBJ INIT.OBJ IPARSE.OBJ +
2UINIT.OBJ TCODE.OBJ TBATCH.OBJ TBATCH2.OBJ TFOR.OBJ TCMD1A.OBJ TCMD1B.OBJ +
3TCMD2A.OBJ TCMD2B.OBJ TENV.OBJ TENV2.OBJ TMISC1.OBJ TMISC2.OBJ TPIPE.OBJ +
4PARSE2.OBJ PATH1.OBJ PATH2.OBJ TUCODE.OBJ COPY.OBJ COPYPR1.OBJ COPYPR2.OBJ +
5CPARSE.OBJ TPARSE.OBJ TPRINTF.OBJ TDATA.OBJ TSPC.OBJ,COMMAND.EXE,,;
6 \ No newline at end of file
diff --git a/v4.0/src/CMD/COMMAND/COMMAND.SKL b/v4.0/src/CMD/COMMAND/COMMAND.SKL
new file mode 100644
index 0000000..44b1eef
--- /dev/null
+++ b/v4.0/src/CMD/COMMAND/COMMAND.SKL
@@ -0,0 +1,213 @@
1
2;*************************
3;* MESSAGE SKELETON FILE *
4;*************************
5
6:util COMMAND ;AC000;
7
8:class 1 ;AC000; Transient extended errors
9
10:use EXTEND2 ;AC000; "File not found"
11:use EXTEND3 ;AC000; "Path not found"
12:use EXTEND8 ;AC000; "Insufficient memory"
13
14:class 2 ;AC000; Transient parse errors
15
16:class 3 ;AC000; Resident extended errors
17:use -1 EXTEND999 ;AN000; "Extended error #"
18
19:class 4 ;AC000; Resident parse errors
20:use -1 PARSE999 ;AN000; "Parse error #"
21
22:class A ;AC000; resident messages
23
24:use 220 COMMON17 ;AC000; "File allocation table bad, drive %1"
25:use 223 COMMON28 ;AC000; "Press any key to continue"
26:def 201 "A" ;AC000;
27:def 202 "R" ;AC000;
28:def 203 "I" ;AC000;
29:def 204 "F" ;AC000;
30:def 205 "Y" ;AC000;
31:def 206 "N" ;AC000;
32:def 210 "Abort" ;AC000;
33:def 211 ", Retry" ;AC000;
34:def 212 ", Ignore" ;AC000;
35:def 213 ", Fail" ;AC000;
36:def 214 "?" ;AC000;
37:def 215 "reading",0 ;AC000;
38:def 216 "writing",0 ;AC000;
39:def 217 " %1 drive %2",CR,LF ;AC000;
40:def 218 " %1 device %2",CR,LF ;AC000;
41:def 219 "Please insert volume %1 serial %2-%3",CR,LF ;AC009;
42:def 221 "Invalid COMMAND.COM",CR,LF ;AC000;
43:def 222 "Insert disk with %1 in drive %2",CR,LF ;AC000;
44:def 224 CR,LF,"Terminate batch job (Y/N)?" ;AC000;
45:def 225 "Cannot execute %1",CR,LF ;AC000;
46:def 226 "Error in EXE file",CR,LF ;AC000;
47:def 227 "Program too big to fit in memory",CR,LF ;AC000;
48:def 228 CR,LF,"No free file handles" ;AC000;
49:def 229 "Bad Command or file name",CR,LF ;AC000;
50:use 230 EXTEND5 ;AC000;
51:def 231 CR,LF,"Memory allocation error" ;AC000;
52:def 232 CR,LF,"Cannot load COMMAND, system halted",CR,LF;AC000;
53:def 233 CR,LF,"Cannot start COMMAND, exiting",CR,LF ;AC000;
54:def 234 CR,LF,"Top level process aborted, cannot continue",CR,LF;AC000;
55:def 235 CR,LF ;AC000;
56
57
58:class B ;AC000; Initialization messages
59
60:use 461 COMMON1 ;AC000; "Incorrect DOS version"
61:def 463 "Out of environment space",CR,LF ;AC000;
62:def 464 CR,LF,CR,LF,"MS DOS ",CR,LF
63 "Version 4.00 (C)Copyright International Business Machines Corp 1981,1988",CR,LF
64 " (C)Copyright Microsoft Corp 1981, 1988",CR,LF ;AC000;
65:def 465 "Specified COMMAND search directory bad",CR,LF ;AC025;
66:def 466 "Specified COMMAND search directory bad access denied",CR,LF ;AC025;
67
68:class C ;AC000; Parse messages
69
70:use PARSE1 ;AC000; "Too many parameters"
71:use PARSE2 ;AC000; "Required parameter missing"
72:use PARSE3 ;AC000; "Invalid switch"
73:use PARSE4 ;AC000; "Invalid keyword"
74:use PARSE6 ;AC000; "Parameter value not in allowed range"
75:use PARSE7 ;AC000; "Parameter value not allowed"
76:use PARSE8 ;AC000; "Parameter value not allowed"
77:use PARSE9 ;AC000; "Parameter format not correct"
78:use PARSE10 ;AC000; "Invalid parameter"
79:use PARSE11 ;AC000; "Invalid parameter combination"
80
81:class D ;AC000; Extended errors - critical
82
83:use EXTEND19 ;AC000; "Write protect"
84:use EXTEND20 ;AC000; "Invalid unit"
85:use EXTEND21 ;AC000; "Drive not ready"
86:use EXTEND22 ;AC000; "Invalid device request"
87:use EXTEND23 ;AC000; "Data error"
88:use EXTEND24 ;AC000; "Invalid device request parameters"
89:use EXTEND25 ;AC000; "Seek error"
90:use EXTEND26 ;AC000; "Invalid media type"
91:use EXTEND27 ;AC000; "Sector not found"
92:use EXTEND28 ;AC000; "Printer out of paper"
93:use EXTEND29 ;AC000; "Write fault error"
94:use EXTEND30 ;AC000; "Read fault error"
95:use EXTEND31 ;AC000; "General Failure"
96:use EXTEND32 ;AC000; "Sharing Violation"
97:use EXTEND33 ;AC000; "Lock Violation"
98:use EXTEND34 ;AC000; "Invalid Disk Change"
99:use EXTEND35 ;AC000; "FCB unavailable"
100:use EXTEND36 ;AC000; "System resource exhausted"
101:use EXTEND37 ;AC000; "Code page mismatch"
102:use EXTEND38 ;AC026; "Out of input"
103:use EXTEND39 ;AC026; "Insufficient disk space"
104
105:class E ;AC000; extended errors
106
107:use EXTEND1 ;AC000; "Invalid Function"
108:use EXTEND2 ;AC000; "File not found"
109:use EXTEND3 ;AC000; "Path not found"
110:use EXTEND4 ;AC000; "Too many open files"
111:use EXTEND5 ;AC000; "Access denied"
112:use EXTEND6 ;AC000; "Invalid handle"
113:use EXTEND7 ;AC000; "Memory control blocks destroyed"
114:use EXTEND8 ;AC000; "Insufficient memory"
115:use EXTEND9 ;AC000; "Invalid memory block address"
116:use EXTEND10 ;AC000; "Invalid Environment"
117:use EXTEND11 ;AC000; "Invalid format"
118:use EXTEND12 ;AC000; "Invalid function parameter"
119:use EXTEND13 ;AC000; "Invalid data"
120:use EXTEND15 ;AC000; "Invalid drive specification"
121:use EXTEND16 ;AC000; "Attempt to remove current directory"
122:use EXTEND17 ;AC000; "Not same device"
123:use EXTEND18 ;AC000; "No more files"
124:use EXTEND80 ;AC000; "File already exists"
125:use EXTEND82 ;AC000; "Can not make directory entry"
126:use EXTEND83 ;AC000; "Fail requested to Critical Error"
127:use EXTEND84 ;AC000; "Too many attaches"
128:use EXTEND85 ;AC000; "Device or file already attached"
129:use EXTEND86 ;AC000; "Invalid password"
130:use EXTEND87 ;AC000; "Invalid parameter"
131:use EXTEND88 ;AC000; "File system data fault"
132:use EXTEND89 ;AC000; "Function not supported by file system"
133:use EXTEND90 ;AC000;
134
135
136:class F ;AC000; Transient messages
137
138:use 1020 COMMON4 ;AC000; "%1 bytes free",CR,LF
139:use 1015 COMMON18 ;AC000; "File cannot be copied onto itself",CR,LF
140:use 1004 COMMON20 ;AC000; "Insufficient disk space",CR,LF
141:use 1026 COMMON22 ;AC000; "Invalid code page",CR,LF
142:use 1031 COMMON23 ;AC000; "Invalid date"
143:use 1035 COMMON24 ;AC000; "Invalid time"
144:use 1062 COMMON25 ;AC000; "Invalid path"
145:use 1028 COMMON28 ;AC000; "Press any key to continue"
146:use 1045 COMMON32 ;AC000; "Unable to create directory",CR,LF
147:use 1041 COMMON33 ;AC000; "Volume in drive %1 has no label"
148:use 1042 COMMON34 ;AC000; "Volume in drive %1 is %2"
149:use 1043 COMMON36 ;AC000; "Volume Serial Number is %1"
150:def 1002 "Duplicate file name or file not found",CR,LF ;AC000;
151:def 1003 "Invalid path or file name",CR,LF ;AC000;
152:def 1007 "Out of environment space",CR,LF ;AC000;
153:def 1008 "File creation error",CR,LF ;AC000;
154:def 1009 "Batch file missing",CR,LF ;AC000;
155:def 1010 CR,LF,"Insert disk with batch file",CR,LF ;AC000;
156:def 1011 "Bad command or file name",CR,LF ;AC000;
157:use 1014 EXTEND5 ;AC000;
158:def 1016 "Content of destination lost before copy",CR,LF ;AC000;
159:def 1017 "Invalid filename or file not found",CR,LF ;AC000;
160:def 1018 "%1 File(s) copied",CR,LF ;AC000;
161:def 1019 "%1 File(s) " ;AC000;
162:use 1021 EXTEND15 ;AC000;
163:def 1022 "Code page %1 not prepared for system",CR,LF ;AC000;
164:def 1023 "Code page %1 not prepared for all devices",CR,LF ;AC000;
165:def 1024 "Active code page: %1",CR,LF ;AC000;
166:def 1025 "NLSFUNC not installed",CR,LF ;AC000;
167:def 1027 "Current drive is no longer valid" ;AC000;
168:def 1029 "Label not found",CR,LF ;AC000;
169:def 1030 "Syntax error",CR,LF ;AC000;
170:def 1032 "Current date is %1 %2",CR,LF ;AC000;
171:def 1033 "SunMonTueWedThuFriSat" ;AC000;
172:def 1034 "Enter new date (%1): " ;AC031;
173:def 1036 "Current time is %1",CR,LF ;AC000;
174:def 1037 "Enter new time: " ;AC031;
175:def 1038 ", Delete (Y/N)?" ;AC000;
176:def 1039 "All files in directory will be deleted!",CR,LF
177 "Are you sure (Y/N)?" ;AC000;
178:def 1040 "Microsoft DOS Version %1.%2",CR,LF ;AC000;
179:def 1044 "Invalid directory",CR,LF ;AC000;
180:def 1046 "Invalid path, not directory,",CR,LF,"or directory not empty",CR,LF ;AC000;
181:def 1047 "Must specify ON or OFF",CR,LF ;AC000;
182:def 1048 "Directory of %1",CR,LF ;AC000;
183:def 1049 "No Path",CR,LF ;AC000;
184:def 1050 "Invalid drive in search path",CR,LF ;AC000;
185:def 1051 "Invalid device",CR,LF ;AC000;
186:def 1052 "FOR cannot be nested",CR,LF ;AC000;
187:def 1053 "Intermediate file error during pipe",CR,LF ;AC000;
188:def 1054 "Cannot do binary reads from a device",CR,LF ;AC000;
189:def 1055 "BREAK is %1",CR,LF ;AC000;
190:def 1056 "VERIFY is %1",CR,LF ;AC000;
191:def 1057 "ECHO is %1",CR,LF ;AC000;
192:def 1059 "off",0 ;AC000;
193:def 1060 "on",0 ;AC000;
194:def 1061 "Error writing to device",CR,LF ;AC000;
195:def 1063 "%1" ;AC000;
196:def 1064 "%1" ;AC000;
197:def 1065 "%1" ;AC000;
198:def 1066 "%1" ;AC000;
199:def 1067 9 ;AC000;
200:def 1068 " <DIR> " ;AC000;
201:def 1069 8," ",8 ;AC000;
202:def 1070 CR,LF ;AC000;
203:def 1071 "%1" ;AC000;
204:def 1072 "mm-dd-yy" ;AC000;
205:def 1073 "dd-mm-yy" ;AC000;
206:def 1074 "yy-mm-dd" ;AC000;
207:def 1075 "%1 %2" ;AC000;
208:def 1076 "%1" ;AC000;
209:def 1077 " %1 %2" ;AC053;
210:def 1078 "Directory already exists",CR,LF ;AC000;
211
212:end ;AC000;
213
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
diff --git a/v4.0/src/CMD/COMMAND/COMMAND2.ASM b/v4.0/src/CMD/COMMAND/COMMAND2.ASM
new file mode 100644
index 0000000..0f6c5b5
--- /dev/null
+++ b/v4.0/src/CMD/COMMAND/COMMAND2.ASM
@@ -0,0 +1,619 @@
1 page 80,132
2; SCCSID = @(#)command2.asm 4.3 85/10/16
3; SCCSID = @(#)command2.asm 4.3 85/10/16
4TITLE COMMAND2 - resident code for COMMAND.COM part II
5NAME COMMAND2
6.XCREF
7.XLIST
8 INCLUDE DOSSYM.INC
9 INCLUDE comsw.asm
10 INCLUDE comequ.asm
11 INCLUDE resmsg.equ ;AN000;
12.LIST
13.CREF
14
15tokenized = FALSE
16
17CODERES SEGMENT PUBLIC BYTE ;AC000;
18CODERES ENDS
19
20DATARES SEGMENT PUBLIC BYTE
21 EXTRN append_state:word ;AN020;
22 EXTRN append_flag:byte ;AN020;
23 EXTRN COMDRV:BYTE
24 EXTRN comprmt1_block:byte ;AN000;
25 EXTRN comprmt1_subst:byte ;AN000;
26 EXTRN COMSPEC:BYTE
27 EXTRN cpdrv:byte
28 EXTRN envirseg:word
29 EXTRN EXTCOM:BYTE
30 EXTRN HANDLE01:WORD
31 EXTRN InitFlag:BYTE
32 EXTRN INT_2E_RET:DWORD ;AC000;
33 EXTRN IO_SAVE:WORD
34 EXTRN LOADING:BYTE
35 EXTRN LTPA:WORD
36 EXTRN MEMSIZ:WORD
37 EXTRN number_subst:byte ;AN000;
38 EXTRN OldTerm:DWORD ;AC000;
39 EXTRN PARENT:WORD ;AC000;
40 EXTRN PERMCOM:BYTE
41 EXTRN RDIRCHAR:BYTE
42 EXTRN RES_TPA:WORD
43 EXTRN RETCODE:WORD
44 EXTRN rsrc_xa_seg:word ;AN030;
45 EXTRN RSWITCHAR:BYTE
46 EXTRN SAVE_PDB:WORD
47 EXTRN SINGLECOM:WORD
48 EXTRN SUM:WORD
49 EXTRN TRANS:WORD
50 EXTRN TranVarEnd:BYTE
51 EXTRN TRANVARS:BYTE
52 EXTRN TRNSEG:WORD
53 EXTRN VERVAL:WORD
54DATARES ENDS
55
56BATARENA SEGMENT PUBLIC PARA ;AC000;
57BATARENA ENDS
58
59BATSEG SEGMENT PUBLIC PARA ;AC000;
60BATSEG ENDS
61
62ENVARENA SEGMENT PUBLIC PARA ;AC000;
63ENVARENA ENDS
64
65ENVIRONMENT SEGMENT PUBLIC PARA ; Default COMMAND environment
66ENVIRONMENT ENDS
67
68INIT SEGMENT PUBLIC PARA
69 EXTRN envsiz:word
70 EXTRN oldenv:word
71 EXTRN resetenv:byte
72 EXTRN usedenv:word
73INIT ENDS
74
75TAIL SEGMENT PUBLIC PARA
76TAIL ENDS
77
78TRANCODE SEGMENT PUBLIC PARA
79TRANCODE ENDS
80
81TRANDATA SEGMENT PUBLIC BYTE
82 EXTRN TRANDATAEND:BYTE
83TRANDATA ENDS
84
85TRANSPACE SEGMENT PUBLIC BYTE
86 EXTRN TRANSPACEEND:BYTE
87 EXTRN HEADCALL:DWORD
88TRANSPACE ENDS
89
90TRANTAIL SEGMENT PUBLIC PARA
91TRANTAIL ENDS
92
93RESGROUP GROUP CODERES,DATARES,BATARENA,BATSEG,ENVARENA,ENVIRONMENT,INIT,TAIL
94TRANGROUP GROUP TRANCODE,TRANDATA,TRANSPACE,TRANTAIL
95
96; START OF RESIDENT PORTION
97
98CODERES SEGMENT PUBLIC BYTE ;AC000;
99
100 PUBLIC CHKSUM
101 PUBLIC endinit
102 PUBLIC GETCOMDSK2
103 PUBLIC INT_2E
104 PUBLIC LOADCOM
105 PUBLIC LODCOM
106 PUBLIC LODCOM1
107 PUBLIC RESTHAND
108 PUBLIC SAVHAND
109 PUBLIC SETVECT
110 PUBLIC THEADFIX
111 PUBLIC TREMCHECK
112 PUBLIC tjmp
113
114ASSUME CS:RESGROUP,DS:NOTHING,ES:NOTHING,SS:NOTHING
115
116 EXTRN contc:near
117 EXTRN DSKERR:NEAR
118 EXTRN rstack:word
119;
120; If we cannot allocate enough memory for the transient or there was some
121; other allocation error, we display a message and then die.
122;
123BADMEMERR: ; Allocation error loading transient
124 MOV DX,BMEMMES ;AC000; get message number
125FATALC:
126 PUSH CS
127 POP DS
128 ASSUME DS:ResGroup
129 invoke RPRINT
130;
131; If this is NOT a permanent (top-level) COMMAND, then we exit; we can't do
132; anything else!
133;
134 CMP PERMCOM,0
135 JZ FATALRET
136;
137; We are a permanent command. If we are in the process of the magic interrupt
138; (Singlecom) then exit too.
139;
140 CMP SINGLECOM,0 ; If PERMCOM and SINGLECOM
141 JNZ FATALRET ; Must take INT_2E exit
142;
143; Permanent command. We can't do ANYthing except halt.
144;
145 MOV DX,HALTMES ;AC000; get message number
146 invoke RPRINT
147 STI
148STALL:
149 JMP STALL ; Crash the system nicely
150
151FATALRET:
152 MOV DX,FRETMES ;AC000; get message number
153 invoke RPRINT
154FATALRET2:
155 CMP [PERMCOM],0 ; If we get here and PERMCOM,
156 JNZ RET_2E ; must be INT_2E
157 invoke reset_msg_pointers ;AN000; reset critical & parse error messages
158 MOV AX,[PARENT]
159 MOV WORD PTR CS:[PDB_Parent_PID],AX
160 MOV AX,WORD PTR OldTerm
161 MOV WORD PTR CS:[PDB_Exit],AX
162 MOV AX,WORD PTR OldTerm+2
163 MOV WORD PTR CS:[PDB_Exit+2],AX
164 MOV AX,(EXIT SHL 8) ; Return to lower level
165 INT int_command
166
167RET_2E:
168 PUSH CS
169 POP DS
170ASSUME DS:RESGROUP,ES:NOTHING,SS:NOTHING
171 MOV [SINGLECOM],0 ; Turn off singlecom
172 MOV ES,[RES_TPA]
173 MOV AH,DEALLOC
174 INT int_command ; Free up space used by transient
175 MOV BX,[SAVE_PDB]
176 MOV AH,SET_CURRENT_PDB
177 INT int_command ; Current process is user
178 MOV AX,[RETCODE]
179 CMP [EXTCOM],0
180 JNZ GOTECODE
181 XOR AX,AX ; Internals always return 0
182GOTECODE:
183 MOV [EXTCOM],1 ; Force external
184 JMP [INT_2E_RET] ;"IRET"
185
186INT_2E: ; Magic command executer
187ASSUME DS:NOTHING,ES:NOTHING,SS:NOTHING
188 POP WORD PTR [INT_2E_RET]
189 POP WORD PTR [INT_2E_RET+2] ;Get return address
190 POP AX ;Chuck flags
191 PUSH CS
192 POP ES
193 MOV DI,80H
194 MOV CX,64
195 REP MOVSW
196 MOV AH,GET_CURRENT_PDB
197 INT int_command ; Get user's header
198 MOV [SAVE_PDB],BX
199 MOV AH,SET_CURRENT_PDB
200 MOV BX,CS
201 INT int_command ; Current process is me
202 MOV [SINGLECOM],81H
203 MOV [EXTCOM],1 ; Make sure this case forced
204
205LODCOM: ; Termination handler
206 CMP [EXTCOM],0
207 jz lodcom1 ; if internal, memory already allocated
208 mov bx,0ffffh
209 MOV AH,ALLOC
210 INT int_command
211 CALL SetSize
212 ADD AX,20H
213 CMP BX,AX ; Is less than 512 byte buffer worth it?
214 JNC MEMOK
215BADMEMERRJ:
216 JMP BADMEMERR ; Not enough memory
217
218; SetSize - get transient size in paragraphs
219Procedure SetSize,NEAR
220 MOV AX,OFFSET TRANGROUP:TRANSPACEEND + 15
221 MOV CL,4
222 SHR AX,CL
223 return
224EndProc SetSize
225
226MEMOK:
227 MOV AH,ALLOC
228 INT int_command
229 JC BADMEMERRJ ; Memory arenas probably trashed
230 MOV [EXTCOM],0 ; Flag not to ALLOC again
231 MOV [RES_TPA], AX ; Save current TPA segment
232 AND AX, 0F000H
233 ADD AX, 01000H ; Round up to next 64K boundary
234 JC BAD_TPA ; Memory wrap if carry set
235; Make sure that new boundary is within allocated range
236 MOV DX, [RES_TPA]
237 ADD DX, BX ; Compute maximum address
238 CMP DX, AX ; Is 64K address out of range?
239 JBE BAD_TPA
240; Must have 64K of usable space.
241 SUB DX, AX ; Compute the usable space
242 CMP DX, 01000H ; Is space >= 64K ?
243 JAE LTPASET
244BAD_TPA:
245 MOV AX, [RES_TPA]
246LTPASET:
247 MOV [LTPA],AX ; Usable TPA is 64k buffer aligned
248 MOV AX, [RES_TPA] ; Actual TPA is buffer allocated
249 ADD BX,AX
250 MOV [MEMSIZ],BX
251 CALL SetSize
252 SUB BX,AX
253 MOV [TRNSEG],BX ; Transient starts here
254LODCOM1:
255 MOV AX,CS
256 MOV SS,AX
257ASSUME SS:RESGROUP
258 MOV SP,OFFSET RESGROUP:RSTACK
259 MOV DS,AX
260ASSUME DS:RESGROUP
261 CALL HEADFIX ; Make sure files closed stdin and stdout restored
262 XOR BP,BP ; Flag command ok
263 MOV AX,-1
264 XCHG AX,[VERVAL]
265 CMP AX,-1
266 JZ NOSETVER
267 MOV AH,SET_VERIFY_ON_WRITE ; AL has correct value
268 INT int_command
269NOSETVER:
270 CMP [SINGLECOM],-1
271 JNZ NOSNG
272 JMP FATALRET2 ; We have finished the single command
273NOSNG:
274 CALL CHKSUM ; Check the transient
275 CMP DX,[SUM]
276 JZ HAVCOM ; Transient OK
277BOGUS_COM:
278 MOV [LOADING],1 ; Flag DSKERR routine
279 CALL LOADCOM
280CHKSAME:
281
282 CALL CHKSUM
283 CMP DX,[SUM]
284 JZ HAVCOM ; Same COMMAND
285ALSO_BOGUS:
286 CALL WRONGCOM
287 JMP SHORT CHKSAME
288HAVCOM:
289 MOV AX,CHAR_OPER SHL 8
290 INT int_command
291 MOV [RSWITCHAR],DL
292 CMP DL,'/'
293 JNZ USESLASH
294 mov cl,'\'
295 MOV [RDIRCHAR],cl ; Select alt path separator
296USESLASH:
297 MOV [LOADING],0 ; Flag to DSKERR
298 MOV SI,OFFSET RESGROUP:TRANVARS
299 MOV DI,OFFSET TRANGROUP:HEADCALL
300 MOV ES,[TRNSEG]
301 CLD
302 MOV CX,OFFSET ResGroup:TranVarEnd
303 SUB CX,SI
304 REP MOVSB ; Transfer INFO to transient
305 MOV AX,[MEMSIZ]
306 MOV WORD PTR DS:[PDB_block_len],AX ; Adjust my own header
307
308; Just a public label so this spot can be found easily.
309tjmp:
310 JMP DWORD PTR [TRANS]
311
312; Far call to REMCHECK for TRANSIENT
313TREMCHECK PROC FAR
314 CALL REMCHECK
315 RET
316TREMCHECK ENDP
317
318REMCHECK:
319;All registers preserved. Returns ZF set if media removable, NZ if fixed
320; AL is drive (0=DEF, 1=A,...).
321 SaveReg <AX,BX>
322 MOV BX,AX
323 MOV AX,(IOCTL SHL 8) + 8
324 INT 21h
325 jnc RCcont ; If an error occurred, assume the media
326 or ax,ax ; is NON-removable.
327 ; AX contains the non-zero error code
328 ; from the INT 21, so the OR AX,AX sets
329 ; Non-zero. This behavior makes Network
330 ; drives appear to be non-removable.
331 jmp SHORT ResRegs
332RCcont:
333 AND AX,1
334 NOT AX
335ResRegs:
336 RestoreReg <BX,AX>
337 return
338
339; Far call to HEADFIX for TRANSIENT
340THEADFIX PROC FAR
341 CALL HEADFIX
342 RET
343THEADFIX ENDP
344
345HEADFIX:
346 CALL SETVECT
347 XOR BX,BX ; Clean up header
348 MOV CX,[IO_SAVE]
349 MOV DX,WORD PTR DS:[PDB_JFN_Table]
350 CMP CL,DL
351 JZ CHK1 ; Stdin matches
352 MOV AH,CLOSE
353 INT int_command
354 MOV DS:[PDB_JFN_Table],CL ; Restore stdin
355CHK1:
356 INC BX
357 CMP CH,DH ; Stdout matches
358 JZ CHKOTHERHAND
359 MOV AH,CLOSE
360 INT int_command
361 MOV DS:[PDB_JFN_Table+1],CH ; Restore stdout
362CHKOTHERHAND:
363 ADD BX,4 ; Skip 2,3,4
364 MOV CX,FilPerProc - 5 ; Already done 0,1,2,3,4
365CLOSELOOP:
366 MOV AH,CLOSE
367 INT int_command
368 INC BX
369 LOOP CLOSELOOP
370 push ds ;AN020; save data segment
371 push cs ;AN020; Get local segment into DS
372 pop ds ;AN020;
373 cmp append_flag,-1 ;AN020; Do we need to reset APPEND?
374 jnz append_fix_end ;AN030; no - just exit
375 mov ax,AppendSetState ;AN020; Set the state of Append
376 mov bx,Append_state ;AN020; back to the original state
377 int 2fh ;AN020;
378 mov append_flag,0 ;AN020; Set append flag to invalid
379append_fix_end: ;AN030;
380 cmp [rsrc_xa_seg],no_xa_seg ;AN030; Is there any active XA segment?
381 jz xa_fix_end ;AN030; no - exit
382 push es ;AN030; Yes - deallocate it
383 mov es,rsrc_xa_seg ;AN030;
384 mov ax,(Dealloc SHL 8) ;AN030; Deallocate memory call
385 int int_command ;AN030;
386 pop es ;AN030;
387 mov [rsrc_xa_seg],no_xa_seg ;AN030; reset to no segment
388xa_fix_end:
389 pop ds ;AN020; get data segment back
390 return
391
392SAVHAND:
393ASSUME DS:NOTHING,ES:NOTHING,SS:NOTHING
394 PUSH DS
395 PUSH BX ; Set stdin to sterr, stdout to stderr
396 PUSH AX
397 MOV AH,GET_CURRENT_PDB
398 INT int_command ; Get user's header
399 MOV DS,BX
400 LDS BX,DS:[PDB_JFN_POINTER] ; get pointer to JFN table...
401 MOV AX,WORD PTR DS:[BX]
402 MOV [HANDLE01],AX ; Save user's stdin, stdout
403 MOV AL,CS:[PDB_JFN_Table+2] ; get COMMAND stderr
404 MOV AH,AL
405 MOV WORD PTR DS:[BX],AX ; Dup stderr
406 POP AX
407 POP BX
408 POP DS
409 return
410
411ASSUME DS:RESGROUP
412GETCOMDSK2:
413 CALL GETCOMDSK
414 JMP LODCOM1 ; Memory already allocated
415
416RESTHAND:
417 PUSH DS
418 PUSH BX ; Restore stdin, stdout to user
419 PUSH AX
420 MOV AH,GET_CURRENT_PDB
421 INT int_command ; Point to user's header
422 MOV AX,[HANDLE01]
423 MOV DS,BX
424ASSUME DS:NOTHING
425 LDS BX,DS:[PDB_JFN_POINTER] ; get pointer to JFN table...
426 MOV WORD PTR DS:[BX],AX ; Stuff his old 0 and 1
427 POP AX
428 POP BX
429 POP DS
430 return
431ASSUME DS:RESGROUP,SS:RESGROUP
432
433HOPELESS:
434 MOV DX,COMBAD ;AC000;
435 JMP FATALC
436
437GETCOMDSK:
438 mov al,[comdrv]
439 CALL REMCHECK
440 jNZ HOPELESS ;Non-removable media
441getcomdsk3:
442 cmp dx,combad ;AC000;
443 jnz getcomdsk4
444 mov dx,combad ;AN000; get message number
445 invoke RPRINT ; Say command is invalid
446getcomdsk4:
447 cmp [cpdrv],0 ;g is there a drive in the comspec?
448 jnz users_drive ;g yes - use it
449 mov ah,Get_default_drive ;g use default drive
450 int 21h ;g
451 add al,"A" ;g convert to ascii
452 mov [cpdrv],al ;g put in message to print out
453
454users_drive: ;g
455 mov dx,comprmt1 ;AC000; Prompt for diskette containing command
456IF tokenized
457 or byte ptr [si],80h
458endif
459 MOV AL,COMPRMT1_SUBST ;AN000; get number of substitutions
460 MOV SI,OFFSET RESGROUP:COMPRMT1_BLOCK ;AN000; get address of subst block
461 MOV NUMBER_SUBST,AL ;AN000;
462 invoke rprint
463if tokenized
464 and byte ptr [si],NOT 80h
465endif
466 mov dx,prompt ;AN047; Tell the user to strike a key
467 invoke rprint ;AN047;
468 CALL GetRawFlushedByte
469 return
470
471; flush world and get raw input
472GetRawFlushedByte:
473 MOV AX,(STD_CON_INPUT_FLUSH SHL 8) OR RAW_CON_INPUT
474 INT int_command ; Get char without testing or echo
475 MOV AX,(STD_CON_INPUT_FLUSH SHL 8) + 0
476 INT int_command
477 return
478
479LOADCOM: ; Load in transient
480 INC BP ; Flag command read
481 MOV DX,OFFSET RESGROUP:COMSPEC
482 MOV AX,OPEN SHL 8
483 INT int_command ; Open COMMAND.COM
484 JNC READCOM
485 CMP AX,error_too_many_open_files
486 JNZ TRYDOOPEN
487 MOV DX,NOHANDMES ;AC000;
488 JMP FATALC ; Fatal, will never find a handle
489
490TRYDOOPEN:
491 CALL GETCOMDSK
492 JMP LOADCOM
493
494READCOM:
495 MOV BX,AX ; Handle
496 MOV DX,OFFSET RESGROUP:TRANSTART
497 XOR CX,CX ; Seek loc
498 MOV AX,LSEEK SHL 8
499 INT int_command
500 JC WRONGCOM1
501 MOV CX,OFFSET TRANGROUP:TRANSPACEEND - 100H
502
503 PUSH DS
504 MOV DS,[TRNSEG]
505ASSUME DS:NOTHING
506 MOV DX,100H
507 MOV AH,READ
508 INT int_command
509 POP DS
510ASSUME DS:RESGROUP
511WRONGCOM1:
512 PUSHF
513 PUSH AX
514 MOV AH,CLOSE
515 INT int_command ; Close COMMAND.COM
516 POP AX
517 POPF
518 JC WRONGCOM ; If error on READ
519 CMP AX,CX
520 retz ; Size matched
521WRONGCOM:
522 MOV DX,COMBAD ;AC000;
523 CALL GETCOMDSK
524 JMP LOADCOM ; Try again
525
526CHKSUM: ; Compute transient checksum
527 PUSH DS
528 MOV DS,[TRNSEG]
529 MOV SI,100H
530 MOV CX,OFFSET TRANGROUP:TranDataEnd - 100H
531
532CHECK_SUM:
533 CLD
534 SHR CX,1
535 XOR DX,DX
536CHK:
537 LODSW
538 ADD DX,AX
539 ADC DX,0
540 LOOP CHK
541 POP DS
542 return
543
544SETVECT: ; Set useful vectors
545 MOV DX,OFFSET RESGROUP:LODCOM
546 MOV AX,(SET_INTERRUPT_VECTOR SHL 8) OR 22H
547 MOV WORD PTR DS:[PDB_EXIT],DX
548 MOV WORD PTR DS:[PDB_EXIT+2],DS
549 INT int_command
550 MOV DX,OFFSET RESGROUP:CONTC
551 INC AL
552 INT int_command
553 MOV DX,OFFSET RESGROUP:DSKERR
554 INC AL
555 INT int_command
556 return
557
558
559;
560; This routine moves the environment to a newly allocated segment
561; at the end of initialization
562;
563
564ENDINIT:
565 push ds ;g save segments
566 push es ;g
567 push cs ;g get resident segment to DS
568 pop ds ;g
569 ASSUME DS:RESGROUP
570 mov cx,usedenv ;g get number of bytes to move
571 mov es,envirseg ;g get target environment segment
572
573 ASSUME ES:NOTHING
574 mov DS:[PDB_environ],es ;g put new environment in my header ;AM067;
575 mov ds,oldenv ;g source environment segment ;AM067;
576 ASSUME DS:NOTHING ;AM067;
577 xor si,si ;g set up offsets to start of segments ;AM067;
578 xor di,di ;g ;AM067;
579 cld ;g make sure we move the right way! ;AM067;
580 rep movsb ;g move it ;AM067;
581 xor ax,ax ;g ;AM067;
582 stosb ;g make sure there are double 0 at end ;AM067;
583
584 cmp resetenv,1 ;eg Do we need to setblock to env end?
585 jnz noreset ;eg no - we already did it
586 mov bx,envsiz ;eg get size of environment in paragraphs
587 push es ;eg save environment - just to make sure
588 mov ah,SETBLOCK ;eg
589 int int_command ;eg
590 pop es ;eg
591
592noreset:
593 mov InitFlag,FALSE ;AC042; Turn off init flag
594 pop es ;g
595 pop ds ;g
596 jmp lodcom ;g allocate transient
597
598CODERES ENDS
599
600; This TAIL segment is used to produce a PARA aligned label in the resident
601; group which is the location where the transient segments will be loaded
602; initial.
603
604TAIL SEGMENT PUBLIC PARA
605 ORG 0
606 PUBLIC TranStart
607TRANSTART LABEL WORD
608TAIL ENDS
609
610; This TAIL segment is used to produce a PARA aligned label in the transient
611; group which is the location where the exec segments will be loaded
612; initial.
613
614TRANTAIL SEGMENT PUBLIC PARA
615 ORG 0
616EXECSTART LABEL WORD
617TRANTAIL ENDS
618
619 END
diff --git a/v4.0/src/CMD/COMMAND/COMSEG.ASM b/v4.0/src/CMD/COMMAND/COMSEG.ASM
new file mode 100644
index 0000000..81cfa30
--- /dev/null
+++ b/v4.0/src/CMD/COMMAND/COMSEG.ASM
@@ -0,0 +1,43 @@
1; SCCSID = @(#)comseg.asm 1.1 85/05/14
2; SCCSID = @(#)comseg.asm 1.1 85/05/14
3; The following are all of the segments used in the load order
4
5CODERES SEGMENT PUBLIC BYTE ;AC000; resident code
6CODERES ENDS
7
8DATARES SEGMENT PUBLIC BYTE ;AC000; resident data
9DATARES ENDS
10
11BATARENA SEGMENT PUBLIC PARA ;AC000; space for DOS ALLOCATE header
12BATARENA ENDS
13
14BATSEG SEGMENT PUBLIC PARA ;AC000; AUTOEXEC batch segment
15BATSEG ENDS
16
17ENVARENA SEGMENT PUBLIC PARA ;AC000; space for DOS ALLOCATE header
18ENVARENA ENDS
19
20ENVIRONMENT SEGMENT PUBLIC PARA ;AC000; Default COMMAND environment
21ENVIRONMENT ENDS
22
23INIT SEGMENT PUBLIC PARA ;AC000; Initialization code
24INIT ENDS
25
26TAIL SEGMENT PUBLIC PARA ;AC000; End of Init - start of Transient
27TAIL ENDS
28
29TRANCODE SEGMENT PUBLIC BYTE ;AC000; Transient code
30TRANCODE ENDS
31
32TRANDATA SEGMENT PUBLIC BYTE ;AC000; Transient data area
33TRANDATA ENDS
34
35TRANSPACE SEGMENT PUBLIC BYTE ;AC000; Transient modifiable data area
36TRANSPACE ENDS
37
38TRANTAIL SEGMENT PUBLIC PARA ;AC000; End of Transient
39TRANTAIL ENDS
40
41RESGROUP GROUP CODERES,DATARES,BATARENA,BATSEG,ENVARENA,ENVIRONMENT,INIT,TAIL
42TRANGROUP GROUP TRANCODE,TRANDATA,TRANSPACE,TRANTAIL
43 \ No newline at end of file
diff --git a/v4.0/src/CMD/COMMAND/COMSW.ASM b/v4.0/src/CMD/COMMAND/COMSW.ASM
new file mode 100644
index 0000000..dbad747
--- /dev/null
+++ b/v4.0/src/CMD/COMMAND/COMSW.ASM
@@ -0,0 +1,6 @@
1; SCCSID = @(#)comsw.asm 1.1 85/05/14
2; SCCSID = @(#)comsw.asm 1.1 85/05/14
3
4include version.inc
5
6 \ No newline at end of file
diff --git a/v4.0/src/CMD/COMMAND/COPY.ASM b/v4.0/src/CMD/COMMAND/COPY.ASM
new file mode 100644
index 0000000..37bb886
--- /dev/null
+++ b/v4.0/src/CMD/COMMAND/COPY.ASM
@@ -0,0 +1,1001 @@
1 page 80,132
2; SCCSID = @(#)copy.asm 1.1 85/05/14
3; SCCSID = @(#)copy.asm 1.1 85/05/14
4TITLE COMMAND COPY routines.
5
6; MODIFICATION HISTORY
7;
8; 11/01/83 EE Added a few lines at the end of SCANSRC2 to get multiple
9; file concatenations (eg copy a.*+b.*+c.*) to work properly.
10; 11/02/83 EE Commented out the code in CPARSE which added drive designators
11; to tokens which begin with path characters so that PARSELINE
12; will work correctly.
13; 11/04/83 EE Commented out the code in CPARSE that considered paren's to be
14; individual tokens. That distinction is no longer needed for
15; FOR loop processing.
16; 11/17/83 EE CPARSE upper case conversion is now flag dependent. Flag is
17; 1 when Cparse is called from COPY.
18; 11/17/83 EE Took out the comment chars around code described in 11/04/83
19; mod. It now is conditional on flag like previous mod.
20; 11/21/83 NP Added printf
21; 12/09/83 EE CPARSE changed to use CPYFLAG to determine when a colon should
22; be added to a token.
23; 05/30/84 MZ Initialize all copy variables. Fix confusion with destclosed
24; NOTE: DestHand is the destination handle. There are two
25; special values: -1 meaning destination was never opened and
26; 0 which means that the destination has been openned and
27; closed.
28; 06/01/84 MZ Above reasoning totally specious. Returned things to normal
29; 06/06/86 EG Change to fix problem of source switches /a and /b getting
30; lost on large and multiple file (wildcard) copies.
31; 06/09/86 EG Change to use xnametrans call to verify that source and
32; destination are not equal.
33
34
35.xlist
36.xcref
37 INCLUDE comsw.asm
38 INCLUDE DOSSYM.INC
39 INCLUDE comseg.asm
40 INCLUDE comequ.asm
41.list
42.cref
43
44
45DATARES SEGMENT PUBLIC BYTE ;AC000;
46 EXTRN VERVAL:WORD
47 EXTRN RSRC_XA_SEG:WORD ;AN030;
48DATARES ENDS
49
50TRANDATA SEGMENT PUBLIC BYTE ;AC000;
51 EXTRN BADCD_ptr:word
52 EXTRN COPIED_ptr:word
53 EXTRN Extend_buf_ptr:word ;AN000;
54 EXTRN Extend_buf_sub:byte ;AN000;
55 EXTRN file_name_ptr:word
56 EXTRN INBDEV_ptr:word ;AC000;
57 EXTRN msg_disp_class:byte ;AN000;
58 EXTRN overwr_ptr:word
59TRANDATA ENDS
60
61TRANSPACE SEGMENT PUBLIC BYTE ;AC000;
62 EXTRN ALLSWITCH:WORD
63 EXTRN ARGC:BYTE
64 EXTRN ASCII:BYTE
65 EXTRN BINARY:BYTE
66 EXTRN BYTCNT:WORD
67 EXTRN CFLAG:BYTE
68 EXTRN comma:byte
69 EXTRN CONCAT:BYTE
70 EXTRN concat_xa:byte ;AN000;
71 EXTRN copy_num:word ;AC000;
72 EXTRN CPDATE:WORD
73 EXTRN CPTIME:WORD
74 EXTRN cpyflag:byte ;AC000;
75 EXTRN CURDRV:BYTE
76 EXTRN DESTBUF:BYTE
77 EXTRN DestClosed:BYTE
78 EXTRN DESTFCB:BYTE
79 EXTRN DESTFCB2:BYTE
80 EXTRN DESTHAND:WORD
81 EXTRN DESTINFO:BYTE
82 EXTRN DESTISDIR:BYTE
83 EXTRN DESTSIZ:BYTE
84 EXTRN DESTSWITCH:WORD
85 EXTRN DESTTAIL:WORD
86 EXTRN DESTVARS:BYTE
87 EXTRN DIRBUF:BYTE
88 EXTRN expand_star:byte
89 EXTRN FILECNT:WORD
90 EXTRN FIRSTDEST:BYTE
91 EXTRN FRSTSRCH:BYTE
92 EXTRN INEXACT:BYTE
93 EXTRN MELCOPY:BYTE
94 EXTRN MELSTART:WORD
95 EXTRN msg_flag:byte ;AN022;
96 EXTRN NOWRITE:BYTE
97 EXTRN NXTADD:WORD
98 EXTRN objcnt:byte
99 EXTRN one_char_val:byte ;AN000;
100 EXTRN parse_last:word ;AN018;
101 EXTRN PLUS:BYTE
102 EXTRN plus_comma:byte
103 EXTRN RDEOF:BYTE
104 EXTRN RESSEG:WORD
105 EXTRN SCANBUF:BYTE
106 EXTRN SDIRBUF:BYTE
107 EXTRN src_xa_size:word ;AN000;
108 EXTRN src_xa_seg:word ;AN000;
109 EXTRN SRCBUF:BYTE
110 EXTRN SRCHAND:WORD
111 EXTRN SRCINFO:BYTE
112 EXTRN SRCISDEV:BYTE
113 EXTRN SRCPT:WORD
114 EXTRN SRCSIZ:BYTE
115 EXTRN SRCTAIL:WORD
116 EXTRN SRCVARS:BYTE
117 EXTRN srcxname:byte
118 EXTRN STARTEL:WORD
119 EXTRN string_ptr_2:word
120 EXTRN TERMREAD:BYTE
121 EXTRN TPA:WORD
122 EXTRN USERDIR1:BYTE
123 EXTRN WRITTEN:WORD
124 EXTRN xa_cp_out:byte ;AN030;
125 EXTRN xa_list_attr:word ;AC030;
126TRANSPACE ENDS
127
128
129; ******************************************
130; COPY CODE
131;
132
133TRANCODE SEGMENT PUBLIC BYTE
134
135 EXTRN CERROR:NEAR
136 EXTRN COPERR:NEAR
137 EXTRN TCOMMAND:NEAR
138
139 PUBLIC COPY
140
141ASSUME CS:TRANGROUP,DS:TRANGROUP,ES:TRANGROUP,SS:NOTHING
142 break Copy
143assume ds:trangroup,es:trangroup
144
145COPY:
146; First order of buisness is to find out about the destination
147;
148; initialize all internal variables
149;
150 xor ax,ax
151 mov copy_num,ax
152 mov SrcPt,AX
153 mov SrcTail,AX
154 mov CFlag,AL
155 mov NxtAdd,AX
156 mov DestSwitch,AX
157 mov StartEl,AX
158 mov DestTail,AX
159 mov DestClosed,AL
160 mov DestSiz,AL
161 mov SrcSiz,AL
162 mov DestInfo,AL
163 mov SrcInfo,AL
164 mov InExact,AL
165 mov DestVars,AL
166 mov SrcVars,AL
167 mov UserDir1,AL
168 mov NoWrite,AL
169 mov RdEOF,AL
170 mov SrcHand,AX
171 mov CpDate,AX
172 mov CpTime,AX
173 mov xa_list_attr,ax ;AN030; initialize code page to none
174 mov SrcIsDev,AL
175 mov TermRead,AL
176 mov comma,al ;g
177 mov plus_comma,al ;g
178 mov msg_flag,al ;AN022;
179 mov [ALLSWITCH],AX ; no switches
180 mov [ARGC],al ; no arguments
181 mov [PLUS],al ; no concatenation
182 mov [BINARY],al ; Binary not specifically specified
183 mov [ASCII],al ; ASCII not specifically specified
184 mov [FILECNT],ax ; No files yet
185 mov [WRITTEN],ax ; Nothing written yet
186 mov [CONCAT],al ; No concatenation
187 mov [MELCOPY],al ; Not a Mel Hallerman copy
188 mov [concat_xa],al ;AN000; initialize flag for concatenation XA
189 mov MelStart,ax ; Not a Mel Hallerman copy
190 mov word ptr [SCANBUF],ax ; Init buffer
191 mov word ptr [DESTBUF],ax ; Init buffer
192 mov word ptr [SRCBUF],ax ; Init buffer
193 mov word ptr [SDIRBUF],ax ; Init buffer
194 mov word ptr [DIRBUF],ax ; Init buffer
195 mov word ptr [DESTFCB],ax ; Init buffer
196 mov objcnt,al ; Init command line object count
197 dec ax
198 mov DestHand,AX ; destination has never been opened
199 mov [FRSTSRCH],al ; First search call
200 mov [FIRSTDEST],al ; First time
201 mov [DESTISDIR],al ; Don't know about dest
202 mov src_xa_seg,ax ;AN000; initialize attribute segment to -1
203 mov si,81H
204 mov bl,plus_chr ; include '+' as a delimiter
205 inc byte ptr [expand_star] ; want to include * expansion in cparse
206 mov cpyflag,1 ; Turn "CPARSE called from COPY flag" on
207
208DESTSCAN:
209 xor bp,bp ; no switches
210 mov di,offset trangroup:SCANBUF
211 mov parse_last,si ;AN018; save start of parsed string
212 invoke CPARSE
213 PUSHF ; save flags
214 inc objcnt
215 test bh,80H ; A '+' argument?
216 jz NOPLUS ; no
217 mov [PLUS],1 ; yes
218NOPLUS:
219 test bh,1 ; Switch?
220 jz TESTP2 ; no
221
222 test bp,SwitchV ;AN038; Verify requested?
223 jz not_slashv ;AN038; No - set the switch
224 test [allswitch],SwitchV ;AN038; Verify already entered?
225 jz not_slashv ;AN038; No - set the switch
226;AD018; or [allswitch],FBadSwitch ;AN038; Set up bad switch
227 or BP,FBadSwitch ;AN018; Set up bad switch
228
229not_slashv: ;AN038;
230 or [DESTSWITCH],BP ; Yes, assume destination
231 or [ALLSWITCH],BP ; keep tabs on all switches
232
233 test BP,NOT SwitchCopy ;AN018; Bad switch?
234 jz NOT_BAD_SWITCH ;AN018; Switches are okay
235 popf ;AN018; fix up stack
236 mov ax,BadSwt_ptr ;AN018; get "Invalid switch" message number
237 invoke Setup_parse_error_msg ;AN018; setup to print the message
238 jmp CERROR ;AC018; exit
239
240NOT_BAD_SWITCH: ;AN018; switch okay
241 POPF ; get flags back
242 jc CHECKDONE ; Hit CR?
243 jmp short DESTSCAN
244
245TESTP2:
246 POPF ; get flags back
247 jc CHECKDONE ; Hit CR?
248 test bh,80H ; Plus?
249 jnz GOTPLUS ; Yes, not a separate arg
250 inc [ARGC] ; found a real arg
251GOTPLUS:
252 push SI
253 mov ax,[STARTEL]
254 mov SI,offset trangroup:SCANBUF ; Adjust to copy
255 sub ax,SI
256 mov DI,offset trangroup:DESTBUF
257 add ax,DI
258 mov [DESTTAIL],AX
259 mov [DESTSIZ],cl ; Save its size
260 inc cx ; Include the nul
261 rep movsb ; Save potential destination
262 mov [DESTINFO],bh ; Save info about it
263 mov [DESTSWITCH],0 ; reset switches
264 pop SI
265 jmp DESTSCAN ;AC018; keep going
266
267CHECKDONE:
268 cmp plus,1 ; If a statement like "copy file+" is
269 jnz cdcont ; entered, complain about it.
270 cmp argc,1
271 jnz cdcont
272 cmp objcnt,2
273 jnz cdcont
274 mov dx,offset trangroup:overwr_ptr
275 jmp coperr
276cdcont:
277 mov al,[PLUS]
278 mov [CONCAT],al ; PLUS -> Concatination
279 shl al,1
280 shl al,1
281 mov [INEXACT],al ; CONCAT -> inexact copy
282 mov al,[ARGC]
283 or al,al ; Good number of args?
284 jnz TRY_TOO_MANY ;AC000; there are args, see if too many
285 MOV DX,OFFSET TranGroup:Extend_Buf_ptr ;AC000; get extended message pointer
286 mov Extend_Buf_ptr,LessArgs_ptr ;AN000; get "Required parameters missing" message number
287 jmp short cerror_parsej ;AN000; exit
288
289TRY_TOO_MANY:
290 cmp al,2
291 jbe ACOUNTOK
292 MOV DX,OFFSET TranGroup:Extend_Buf_ptr ;AC000; get extended message pointer
293 mov Extend_Buf_ptr,MoreArgs_ptr ;AN000; get "Too many parameters" message number
294
295CERROR_PARSEJ:
296 mov msg_disp_class,parse_msg_class ;AN000; set up parse error msg class
297CERROR4J:
298 jmp CERROR ; no, too many
299
300ACOUNTOK:
301 mov bp,offset trangroup:DESTVARS
302 cmp al,1
303 jnz GOT2ARGS
304 mov al,[CURDRV] ; Dest is default drive:*.*
305 add al,capital_A
306 mov ah,':'
307 mov [bp.SIZ],2
308 mov di,offset trangroup:DESTBUF
309 stosw
310 mov [DESTSWITCH],0 ; no switches on dest
311 mov [bp.INFO],2 ; Flag dest is ambig
312 mov [bp.ISDIR],0 ; Know destination specs file
313 invoke SETSTARS
314GOT2ARGS:
315 cmp [bp.SIZ],2
316 jnz NOTSHORTDEST
317 mov al,':'
318 cmp [DESTBUF+1],al
319 jnz NOTSHORTDEST ; Two char file name
320 or [bp.INFO],2 ; Know dest is d:
321 mov di,offset trangroup:DESTBUF + 2
322 mov [bp.ISDIR],0 ; Know destination specs file
323 invoke SETSTARS
324NOTSHORTDEST:
325 mov di,[bp.TTAIL]
326 cmp byte ptr [DI],0
327 jnz CHKSWTCHES
328 mov dx,offset trangroup:BADCD_ptr
329 mov al,':'
330 cmp byte ptr [DI-2],al
331 jnz CERROR4J ; Trailing '/' error
332 mov [bp.ISDIR],2 ; Know destination is d:/
333 or [bp.INFO],6
334 invoke SETSTARS
335CHKSWTCHES:
336;AD018; mov ax,[ALLSWITCH]
337;AD018; test ax,NOT SwitchCopy
338;AD018; jz NOT_BAD_SWITCH ;AN000; Switches are okay
339;AD018; MOV DX,OFFSET TranGroup:Extend_Buf_ptr ;AC000; get extended message pointer
340;AD018; mov Extend_Buf_ptr,BadSwt_ptr ;AN000; get "Invalid switch" message number
341;AD018; jmp short CERROR_PARSEJ ;AC000; Switch specified which is not known
342
343; Now know most of the information needed about the destination
344
345;AD018; NOT_BAD_SWITCH:
346if not ibmcopyright
347 mov ax, [allswitch] ; Which switches were requested? Hmmm?
348endif
349 TEST AX,SwitchV ; Verify requested?
350 JZ NOVERIF ; No
351 MOV AH,GET_VERIFY_ON_WRITE
352 INT int_command ; Get current setting
353 PUSH DS
354 MOV DS,[RESSEG]
355ASSUME DS:RESGROUP
356 XOR AH,AH
357 MOV [VERVAL],AX ; Save current setting
358 POP DS
359ASSUME DS:TRANGROUP
360 MOV AX,(SET_VERIFY_ON_WRITE SHL 8) OR 1 ; Set verify
361 INT int_command
362NOVERIF:
363 xor bp,bp ; no switches
364 mov si,81H
365 mov bl,plus_chr ; include '+' as a delimiter
366SCANFSRC:
367 mov di,offset trangroup:SCANBUF
368 invoke CPARSE ; Parse first source name
369 test bh,1 ; Switch?
370 jnz SCANFSRC ; Yes, try again
371 or [DESTSWITCH],bp ; Include copy wide switches on dest
372 test bp,SwitchB
373 jnz NOSETCASC ; Binary explicit
374 cmp [CONCAT],0
375 JZ NOSETCASC ; Not Concat
376 mov [ASCII],SwitchA ; Concat -> ASCII copy if no B switch
377 mov [concat_xa],do_xa ;AN000; set up to do XA only on first file
378NOSETCASC:
379 call source_set
380 call FRSTSRC
381 jmp FIRSTENT
382
383PUBLIC EndCopy
384ENDCOPY:
385 CALL CLOSEDEST
386ENDCOPY2:
387 call deallocate_src_xa ;AN030; deallocate xa segment
388 invoke free_tpa ;AN000; Make sure work area
389 invoke alloc_tpa ;AN000; is reset properly
390 MOV DX,OFFSET TRANGROUP:COPIED_ptr
391 MOV SI,[FILECNT]
392 mov copy_num,si
393 invoke std_printf
394 JMP TCOMMAND ; Stack could be messed up
395
396SRCNONEXIST:
397 cmp [CONCAT],0
398 jnz NEXTSRC ; If in concat mode, ignore error
399 mov msg_disp_class,ext_msg_class ;AN000; set up extended error msg class
400 mov dx,offset TranGroup:Extend_Buf_ptr ;AC000; get extended message pointer
401 mov Extend_Buf_ptr,error_file_not_found ;AN000; get message number in control block
402 mov string_ptr_2,offset trangroup:srcbuf ;AC046; get address of failed string
403 mov Extend_buf_sub,one_subst ;AC046; put number of subst in control block
404 jmp COPERR
405
406SOURCEPROC:
407 call source_set
408 cmp [CONCAT],0
409 jnz LEAVECFLAG ; Leave CFLAG if concatination
410FRSTSRC:
411 xor ax,ax
412 mov [CFLAG],al ; Flag destination not created
413 mov [NXTADD],ax ; Zero out buffer
414 mov DestClosed,AL
415LEAVECFLAG:
416 mov [SRCPT],SI ; remember where we are
417 mov di,offset trangroup:USERDIR1
418 mov bp,offset trangroup:SRCVARS
419 invoke BUILDPATH ; Figure out everything about the source
420 mov si,[SRCTAIL] ; Create the search FCB
421 return
422
423NEXTSRC:
424 cmp [PLUS],0
425 jnz MORECP
426ENDCOPYJ2:
427 jmp ENDCOPY ; Done
428MORECP:
429 xor bp,bp ; no switches
430 mov si,[SRCPT]
431 mov bl,plus_chr ; include '+' as a delimiter
432SCANSRC:
433 mov di,offset trangroup:SCANBUF
434 invoke CPARSE ; Parse first source name
435 JC EndCopyJ2 ; if error, then end (trailing + case)
436 test bh,80H
437 jz ENDCOPYJ2 ; If no '+' we're done
438 test bh,1 ; Switch?
439 jnz SCANSRC ; Yes, try again
440 call SOURCEPROC
441 cmp comma,1 ;g was +,, found last time?
442 jnz nostamp ;g no - try for a file
443 mov plus_comma,1 ;g yes - set flag
444 jmp srcnonexist ;g we know we won't find it
445nostamp: ;g
446 mov plus_comma,0 ;g reset +,, flag
447FIRSTENT:
448 mov di,FCB
449 mov ax,PARSE_FILE_DESCRIPTOR SHL 8
450 INT int_command
451 CMP BYTE PTR [SI],0 ; parse everything?
452 JNZ SrchDone ; no, error, simulate no more search
453 mov ax,word ptr [SRCBUF] ; Get drive
454 cmp ah,':'
455 jz DRVSPEC1
456 mov al,'@'
457DRVSPEC1:
458 or al,20h
459 sub al,60h
460 mov ds:[FCB],al
461 mov ah,DIR_SEARCH_FIRST
462 call SEARCH
463SrchDone:
464 pushf ; Save result of search
465 invoke RESTUDIR1 ; Restore users dir
466 popf
467 jz NEXTAMBIG0
468 jmp SRCNONEXIST ; Failed
469NEXTAMBIG0:
470 xor al,al
471 xchg al,[FRSTSRCH]
472 or al,al
473 jz NEXTAMBIG
474SETNMEL:
475 mov cx,12
476 mov di,OFFSET TRANGROUP:SDIRBUF
477 mov si,OFFSET TRANGROUP:DIRBUF
478 rep movsb ; Save very first source name
479NEXTAMBIG:
480 xor al,al
481 mov [NOWRITE],al ; Turn off NOWRITE
482 mov di,[SRCTAIL]
483 mov si,offset trangroup:DIRBUF + 1
484 invoke FCB_TO_ASCZ ; SRCBUF has complete name
485MELDO:
486 cmp [CONCAT],0
487 jnz SHOWCPNAM ; Show name if concat
488 test [SRCINFO],2 ; Show name if multi
489 jz DOREAD
490SHOWCPNAM:
491 mov dx,offset trangroup:file_name_ptr
492 invoke std_printf
493 invoke CRLF2
494DOREAD:
495 call DOCOPY
496 cmp [CONCAT],0
497 jnz NODCLOSE ; If concat, do not close
498 call CLOSEDEST ; else close current destination
499 jc NODCLOSE ; Concat flag got set, close didn't really happen
500 mov [CFLAG],0 ; Flag destination not created
501NODCLOSE:
502 cmp [CONCAT],0 ; Check CONCAT again
503 jz NOFLUSH
504 invoke FLSHFIL ; Flush output between source files on
505 ; CONCAT so LOSTERR stuff works
506 ; correctly
507 TEST [MELCOPY],0FFH
508 jz NOFLUSH
509 jmp SHORT DOMELCOPY
510
511NOFLUSH:
512 call SEARCHNEXT ; Try next match
513 jnz NEXTSRCJ ; Finished with this source spec
514 mov [DESTCLOSED],0 ; Not created or concat ->...
515 jmp NEXTAMBIG ; Do next ambig
516
517DOMELCOPY:
518 cmp [MELCOPY],0FFH
519 jz CONTMEL
520 mov SI,[SRCPT]
521 mov [MELSTART],si
522 mov [MELCOPY],0FFH
523CONTMEL:
524 xor BP,BP
525 mov si,[SRCPT]
526 mov bl,plus_chr
527SCANSRC2:
528 mov di,OFFSET TRANGROUP:SCANBUF
529 invoke CPARSE
530 test bh,80H
531 jz NEXTMEL ; Go back to start
532 test bh,1 ; Switch ?
533 jnz SCANSRC2 ; Yes
534 call SOURCEPROC
535 invoke RESTUDIR1
536 mov di,OFFSET TRANGROUP:DESTFCB2
537 mov ax,PARSE_FILE_DESCRIPTOR SHL 8
538 INT int_command
539 mov bx,OFFSET TRANGROUP:SDIRBUF + 1
540 mov si,OFFSET TRANGROUP:DESTFCB2 + 1
541 mov di,[SRCTAIL]
542 invoke BUILDNAME
543 cmp [CONCAT],0 ; Are we concatenating?
544 jz meldoj ; No, continue.
545;
546; Yes, turn off nowrite because this part of the code is only reached after
547; the first file has been dealt with.
548;
549 mov [NOWRITE],0
550meldoj:
551 jmp MELDO
552
553NEXTSRCJ:
554 jmp NEXTSRC
555
556NEXTMEL:
557 call CLOSEDEST
558 xor ax,ax
559 mov [CFLAG],al
560 mov [NXTADD],ax
561 mov [DESTCLOSED],al
562 mov si,[MELSTART]
563 mov [SRCPT],si
564 call SEARCHNEXT
565 jz SETNMELJ
566 jmp ENDCOPY2
567SETNMELJ:
568 jmp SETNMEL
569
570SEARCHNEXT:
571 MOV AH,DIR_SEARCH_NEXT
572 TEST [SRCINFO],2
573 JNZ SEARCH ; Do search-next if ambig
574 OR AH,AH ; Reset zero flag
575 return
576SEARCH:
577 PUSH AX
578 MOV AH,SET_DMA
579 MOV DX,OFFSET TRANGROUP:DIRBUF
580 INT int_command ; Put result of search in DIRBUF
581 POP AX ; Restore search first/next command
582 MOV DX,FCB
583 INT int_command ; Do the search
584 OR AL,AL
585 return
586
587DOCOPY:
588 mov si,offset trangroup:SRCBUF ;g do name translate of source
589 mov di,offset trangroup:SRCXNAME ;g save for name comparison
590 mov ah,xnametrans ;g
591 int int_command ;g
592
593 mov [RDEOF],0 ; No EOF yet
594
595 MOV AX,EXTOPEN SHL 8 ;AC000; open the file
596 mov bx,read_open_mode ;AN000; get open mode for COPY
597 xor cx,cx ;AN000; no special files
598 mov dx,read_open_flag ;AN000; set up open flags
599 mov di,-1 ;AN030; no parameter list
600 INT int_command
601
602 jnc OpenOK
603;
604; Bogosity: IBM wants us to issue Access denied in this case. THey asked
605; for it...
606;
607 jmp error_on_source ;AC022; clean up and exit
608
609OpenOK:
610 mov bx,ax ; Save handle
611 mov [SRCHAND],bx ; Save handle
612 mov ax,(FILE_TIMES SHL 8)
613 INT int_command
614 jc src_cp_error ;AN022; If error, exit
615 mov [CPDATE],dx ; Save DATE
616 mov [CPTIME],cx ; Save TIME
617
618 mov cx,xa_list_attr ;AN000; get old code page in cx
619 push cx ;AN000; save old attribute
620 mov xa_list_attr,0 ;AN000; initialize code page
621
622 mov ax,(file_times SHL 8)+get_XA ;AC030; get extended attribute size
623 mov si,-1 ;AN030; no querylist
624 xor cx,cx ;AN030; indicate we want size
625 int int_command ;AC000;
626 jc src_cp_error ;AN022; If error, exit
627 mov src_xa_size,cx ;AN000; save size
628 cmp cx,0 ;AN000; are there any?
629 pop cx ;AN000; get old attribute
630 jz no_cp_get ;AN030; no - don't get attributes
631
632 push cx ;AN030; save old code page
633 invoke get_file_code_page_tag ;AN000; get file's code page
634 pop cx ;AN030 retrieve old code page
635 jnc no_cp_get ;AN000; no error - continue
636src_cp_error: ;AN022;
637 jmp error_on_source ;AC022; and exit
638
639no_cp_get:
640 cmp [concat],0 ;AN000; are we doing concatenation
641 jz get_src_xa ;AN000; no get source extended attrib
642 cmp [concat_xa],do_xa ;AN000; is this the first file?
643 jz get_src_xa ;AN000; yes - get extended attributes
644 cmp cx,xa_list_attr ;AN000; no - see if code pages match
645 jz no_copy_xa_jmp ;AN000; code pages match - continue
646 mov xa_list_attr,inv_cp_tag ;AN000; set invalid code page tag
647no_copy_xa_jmp: ;AC022;
648 jmp no_copy_xa ;AN000; don't get extended attributes
649
650get_src_xa:
651 call deallocate_src_xa ;AN030; deallocate any existing XA segment
652 cmp src_xa_size,0 ;AN000; are there any extended attributes?
653 jz no_copy_xa_jmp ;AC022; nothing there - don't allocate memory
654 push bx ;AN000; save handle
655 invoke free_tpa ;AN000; need to make free memory, first
656 mov bx,src_xa_size ;AN000; get bytes (size of XA) into bx
657 mov cl,4 ;AN000; divide bytes by 16 to convert
658 shr bx,cl ;AN000; to paragraphs
659 inc bx ;AN000; round up
660 mov ax,(alloc SHL 8) ;AN000; allocate memory for XA
661 int int_command ;AN000;
662 pushf ;AN000; save flags
663 mov [src_xa_seg], AX ;AN000; save new segment
664 push ds ;AN030; get resident segment
665 mov ds,[resseg] ;AN030; and save copy of xa
666 assume ds:resgroup ;AN030; segment in resident
667 mov [rsrc_xa_seg],ax ;AN030; in case user breaks
668 pop ds ;AN030; out or has critical
669 assume ds:trangroup ;AN030; error
670 invoke alloc_tpa ;AN000; reallocate the work area
671 popf ;AN000; restore flags
672 pop bx ;AN000; restore handle
673 jnc Alloc_for_xa_okay ;AN000; no carry - everything okay
674 call closesrc ;AN000; close the source file
675 mov msg_disp_class,ext_msg_class ;AN000; set up extended error msg class
676 mov dx,offset TranGroup:Extend_Buf_ptr ;AC000; get extended message pointer
677 mov Extend_Buf_ptr,error_not_enough_memory ;AN000; get message number in control block
678 jmp cerror ;AN000; exit
679
680Alloc_for_xa_okay:
681
682 mov ax,(file_times SHL 8)+get_XA ;AN000; get extended attributes
683 push es ;AN000; save es
684 mov es,[src_xa_seg] ;AN000; get segment for XA list
685 xor di,di ;AN000; offset of return list
686 mov si,-1 ;AN030; get all attributes
687 mov cx,[src_xa_size] ;AN000; get size of list
688 int int_command ;AN000; get all the attributes
689 pop es ;AN000; restore es
690 jnc no_copy_xa ;AC022; no error - continue
691
692error_on_source: ;AN022; we have a BAD error
693 invoke set_ext_error_msg ;AN022; set up the error message
694 mov string_ptr_2,offset trangroup:srcbuf ;AN022; get address of failed string
695 mov Extend_buf_sub,one_subst ;AN022; put number of subst in control block
696 invoke std_Eprintf ;AN022; print it
697 cmp [srchand],0 ;AN022; did we open the file?
698 jz no_close_src ;AN022; no - don't close
699 call closesrc ;AN022; clean up
700no_close_src: ;AN022;
701 cmp [cflag],0 ;AN022; was destination created?
702 jz endcopyj3 ;AN022; no - just cleanup and exit
703 jmp endcopy ;AN022; clean up concatenation and exit
704endcopyj3: ;AN022;
705 jmp endcopy2 ;AN022;
706no_copy_xa:
707 mov bx,[srchand] ;AN022; get handle back
708 mov ax,(IOCTL SHL 8)
709 INT int_command ; Get device stuff
710 and dl,devid_ISDEV
711 mov [SRCISDEV],dl ; Set source info
712 jz COPYLP ; Source not a device
713 cmp [BINARY],0
714 jz COPYLP ; ASCII device OK
715 mov dx,offset trangroup:INBDEV_ptr ; Cannot do binary input
716 jmp COPERR
717
718COPYLP:
719 mov bx,[SRCHAND]
720 mov cx,[BYTCNT]
721 mov dx,[NXTADD]
722 sub cx,dx ; Compute available space
723 jnz GOTROOM
724 invoke FLSHFIL
725 CMP [TERMREAD],0
726 JNZ CLOSESRC ; Give up
727 mov cx,[BYTCNT]
728GOTROOM:
729 push ds
730 mov ds,[TPA]
731ASSUME DS:NOTHING
732 mov ah,READ
733 INT int_command
734 pop ds
735ASSUME DS:TRANGROUP
736 jc error_on_source ;AC022; Give up if error
737 mov cx,ax ; Get count
738 jcxz CLOSESRC ; No more to read
739 cmp [SRCISDEV],0
740 jnz NOTESTA ; Is a device, ASCII mode
741 cmp [ASCII],0
742 jz BINREAD
743NOTESTA:
744 MOV DX,CX
745 MOV DI,[NXTADD]
746 MOV AL,1AH
747 PUSH ES
748 MOV ES,[TPA]
749 REPNE SCASB ; Scan for EOF
750 POP ES
751 JNZ USEALL
752 INC [RDEOF]
753 INC CX
754USEALL:
755 SUB DX,CX
756 MOV CX,DX
757BINREAD:
758 ADD CX,[NXTADD]
759 MOV [NXTADD],CX
760 CMP CX,[BYTCNT] ; Is buffer full?
761 JB TESTDEV ; If not, we may have found EOF
762 invoke FLSHFIL
763 CMP [TERMREAD],0
764 JNZ CLOSESRC ; Give up
765 JMP SHORT COPYLP
766
767TESTDEV:
768 cmp [SRCISDEV],0
769 JZ CLOSESRC ; If file then EOF
770 CMP [RDEOF],0
771 JZ COPYLP ; On device, go till ^Z
772CLOSESRC:
773 mov bx,[SRCHAND]
774 mov ah,CLOSE
775 INT int_command
776 return
777
778;
779; We are called to close the destination. We need to note whether or not
780; there is any internal data left to be flushed out.
781;
782CLOSEDEST:
783 cmp [DESTCLOSED],0
784 retnz ; Don't double close
785 MOV AL,BYTE PTR [DESTSWITCH]
786 invoke SETASC ; Check for B or A switch on destination
787 JZ BINCLOS
788 MOV BX,[NXTADD]
789 CMP BX,[BYTCNT] ; Is memory full?
790 JNZ PUTZ
791 invoke TRYFLUSH ; Make room for one lousy byte
792 jz NOCONC
793CONCHNG: ; Concat flag changed on us
794 stc
795 return
796NOCONC:
797 XOR BX,BX
798PUTZ:
799 PUSH DS
800 MOV DS,[TPA]
801 MOV WORD PTR [BX],1AH ; Add End-of-file mark (Ctrl-Z)
802 POP DS
803 INC [NXTADD]
804 MOV [NOWRITE],0 ; Make sure our ^Z gets written
805 MOV AX,[WRITTEN]
806 ADD AX,[NXTADD]
807 JC BINCLOS ; > 1
808 CMP AX,1
809 JZ FORGETITJ ; WRITTEN = 0 NXTADD = 1 (the ^Z)
810BINCLOS:
811 invoke TRYFLUSH
812 jnz CONCHNG
813 cmp [WRITTEN],0
814ForgetItJ:
815 jnz no_forget ;AC000; Wrote something
816 jmp FORGETIT ;AC000; Never wrote nothing
817no_forget:
818 MOV BX,[DESTHAND]
819 MOV CX,[CPTIME]
820 MOV DX,[CPDATE]
821 CMP [INEXACT],0 ; Copy not exact?
822 JZ DODCLOSE ; If no, copy date & time
823 MOV AH,GET_TIME
824 INT int_command
825 SHL CL,1
826 SHL CL,1 ; Left justify min in CL
827 SHL CX,1
828 SHL CX,1
829 SHL CX,1 ; hours to high 5 bits, min to 5-10
830 SHR DH,1 ; Divide seconds by 2 (now 5 bits)
831 OR CL,DH ; And stick into low 5 bits of CX
832 PUSH CX ; Save packed time
833 MOV AH,GET_DATE
834 INT int_command
835 SUB CX,1980
836 XCHG CH,CL
837 SHL CX,1 ; Year to high 7 bits
838 SHL DH,1 ; Month to high 3 bits
839 SHL DH,1
840 SHL DH,1
841 SHL DH,1
842 SHL DH,1 ; Most sig bit of month in carry
843 ADC CH,0 ; Put that bit next to year
844 OR DL,DH ; Or low three of month into day
845 MOV DH,CH ; Get year and high bit of month
846 POP CX ; Get time back
847DODCLOSE:
848 CMP BX,0
849 JLE CloseDone
850 MOV AX,(FILE_TIMES SHL 8) OR 1
851 INT int_command ; Set date and time
852 jc xa_cleanup_err ;AN022; handle error
853
854 mov ax,(file_times SHL 8)+set_XA ;AN000; set code page
855 mov di,offset trangroup:xa_cp_out ;AC030; offset of attr list
856 int int_command ;AN000;
857 jc xa_cleanup_err ;AN030; exit if error
858
859;
860; See if the destination has *anything* in it. If not, just close and delete
861; it.
862;
863no_xa_cleanup_err:
864 mov ax,(lseek shl 8) + 2 ; seek to EOF
865 xor dx,dx
866 mov cx,dx
867 int 21h
868;
869; DX:AX is file size
870;
871 or dx,ax
872 pushf
873 mov ax,(IOCTL SHL 8) + 0 ; get the destination attributes
874 int 21h
875 push dx ; save them away
876 MOV AH,CLOSE
877 INT int_command
878 pop dx
879 jnc close_cont ;AN022; handle error on close
880 popf ;AN022; get the flags back
881xa_cleanup_err: ;AN022;
882 call cleanuperr ;AN022; attempt to delete the target
883 call DestDelete ;AN022; attempt to delete the target
884 jmp short fileclosed ;AN022; close the file
885close_cont: ;AN022; no error - continue
886 popf
887 jnz CloseDone
888 test dx,80h ; is the destination a device?
889 jnz CloseDone ; yes, copy succeeded
890 call DestDelete
891 jmp short FileClosed
892CloseDone:
893 INC [FILECNT]
894FileClosed:
895 INC [DESTCLOSED]
896RET50:
897 CLC
898 return
899
900
901FORGETIT:
902 MOV BX,[DESTHAND]
903 CALL DODCLOSE ; Close the dest
904 call DestDelete
905 MOV [FILECNT],0 ; No files transferred
906 JMP RET50
907
908DestDelete:
909 MOV DX,OFFSET TRANGROUP:DESTBUF
910 MOV AH,UNLINK
911 INT int_command ; And delete it
912 return
913
914source_set proc near
915
916 push SI
917 mov ax,[STARTEL]
918 mov SI,offset trangroup:SCANBUF ; Adjust to copy
919 sub ax,SI
920 mov DI,offset trangroup:SRCBUF
921 add ax,DI
922 mov [SRCTAIL],AX
923 mov [SRCSIZ],cl ; Save its size
924 inc cx ; Include the nul
925 rep movsb ; Save this source
926 mov [SRCINFO],bh ; Save info about it
927 pop SI
928 mov ax,bp ; Switches so far
929 invoke SETASC ; Set A,B switches accordingly
930 invoke SWITCH ; Get any more switches on this arg
931 invoke SETASC ; Set
932 return
933
934source_set endp
935
936
937;****************************************************************
938;*
939;* ROUTINE: Cleanuperr
940;*
941;* FUNCTION: Issues extended error message for destination
942;* if not alreay issued
943;*
944;* INPUT: return from INT 21
945;*
946;* OUTPUT: none
947;*
948;****************************************************************
949
950cleanuperr proc near ;AN022;
951
952 cmp msg_flag,0 ;AN022; have we already issued a message?
953 jnz cleanuperr_cont ;AN022; yes - don't issue duplicate error
954 invoke set_ext_error_msg ;AN022; set up error message
955 mov string_ptr_2,offset trangroup:destbuf ;AN022; get address of failed string
956 mov Extend_buf_sub,one_subst ;AN022; put number of subst in control block
957 invoke std_eprintf ;AN022; issue the error message
958cleanuperr_cont: ;AN022;
959
960 ret ;AN022; return to caller
961cleanuperr endp ;AN022;
962
963;****************************************************************
964;*
965;* ROUTINE: Deallocate_Src_XA
966;*
967;* FUNCTION: Deallocates source extended attribute segment
968;* and resets both resident and transient variables.
969;*
970;*
971;* INPUT: none
972;*
973;* OUTPUT: none
974;*
975;****************************************************************
976
977Deallocate_Src_XA proc near ;AN030;
978
979 cmp [src_xa_seg],no_xa_seg ;AN030; has any XA segment been allocated
980 jz no_src_xa ;AN030; no - continue
981 push es ;AN030;
982 mov es,src_xa_seg ;AN030; yes - free it
983 mov ax,(Dealloc SHL 8) ;AN030; Deallocate memory call
984 int int_command ;AN030;
985 pop es ;AN030;
986 mov [src_xa_seg],no_xa_seg ;AN030; reset to no segment
987 push ds ;AN030; reinitialize resident
988 mov ds,[resseg] ;AN030; copy of xa segment
989 assume ds:resgroup ;AN030;
990 mov [rsrc_xa_seg],no_xa_seg ;AN030; reset to no segment
991 pop ds ;AN030;
992 assume ds:trangroup ;AN030;
993no_src_xa: ;AN030;
994
995 ret ;AN030; return to caller
996Deallocate_Src_XA endp ;AN030;
997
998
999TRANCODE ENDS
1000 END
1001 \ No newline at end of file
diff --git a/v4.0/src/CMD/COMMAND/COPYPR1.ASM b/v4.0/src/CMD/COMMAND/COPYPR1.ASM
new file mode 100644
index 0000000..e727910
--- /dev/null
+++ b/v4.0/src/CMD/COMMAND/COPYPR1.ASM
@@ -0,0 +1,276 @@
1 page 80,132
2; SCCSID = @(#)copypr1.asm 1.1 85/05/14
3; SCCSID = @(#)copypr1.asm 1.1 85/05/14
4 INCLUDE comsw.asm
5
6.xlist
7.xcref
8 INCLUDE DOSSYM.INC
9; INCLUDE DEVSYM.INC
10 INCLUDE comseg.asm
11 INCLUDE comequ.asm
12.list
13.cref
14
15
16TRANDATA SEGMENT PUBLIC BYTE ;AC000;
17 EXTRN DEVWMES_ptr:word
18 EXTRN ext_open_parms:byte ;AN000;
19 EXTRN ext_open_seg:word ;AN000;
20 EXTRN ext_open_off:word ;AN000;
21 EXTRN Extend_buf_sub:byte ;AN000;
22 EXTRN LOSTERR_ptr:word
23 EXTRN NOSPACE_ptr:word
24 EXTRN OVERWR_ptr:word
25TRANDATA ENDS
26
27TRANSPACE SEGMENT PUBLIC BYTE ;AC000;
28 EXTRN ASCII:BYTE
29 EXTRN BINARY:BYTE
30 EXTRN CFLAG:BYTE
31 EXTRN CONCAT:BYTE
32 EXTRN concat_xa:byte ;AC000;
33 EXTRN DESTBUF:BYTE
34 EXTRN DESTCLOSED:BYTE
35 EXTRN DESTHAND:WORD
36 EXTRN DESTISDEV:BYTE
37 EXTRN DESTSWITCH:WORD
38 EXTRN INEXACT:BYTE
39 EXTRN NOWRITE:BYTE
40 EXTRN NXTADD:WORD
41 EXTRN plus_comma:byte ;AN000;
42 EXTRN RDEOF:BYTE
43 EXTRN src_xa_seg:word ;AN000;
44 EXTRN SRCISDEV:BYTE
45 EXTRN string_ptr_2:word ;AN000;
46 EXTRN TERMREAD:BYTE
47 EXTRN TPA:WORD
48 EXTRN WRITTEN:WORD
49TRANSPACE ENDS
50
51TRANCODE SEGMENT PUBLIC BYTE
52
53 EXTRN ENDCOPY:NEAR
54
55 PUBLIC FLSHFIL
56 PUBLIC TRYFLUSH
57
58ASSUME CS:TRANGROUP,DS:TRANGROUP,ES:TRANGROUP,SS:NOTHING
59
60TRYFLUSH:
61 mov al,[CONCAT]
62 push ax
63 call FLSHFIL
64 pop ax
65 cmp al,[CONCAT]
66 return
67
68FLSHFIL:
69;
70; Write out any data remaining in memory.
71; Inputs:
72; [NXTADD] = No. of bytes to write
73; [CFLAG] <> 0 if file has been created
74; Outputs:
75; [NXTADD] = 0
76;
77 MOV [TERMREAD],0
78 cmp [CFLAG],0
79 JZ NOTEXISTS
80 JMP EXISTS
81
82NOTEXISTS:
83 invoke BUILDDEST ; Find out all about the destination
84 invoke COMPNAME ; Source and dest. the same?
85 JNZ PROCDEST ; If not, go ahead
86 CMP [SRCISDEV],0
87 JNZ PROCDEST ; Same name on device OK
88 CMP [CONCAT],0 ; Concatenation?
89 MOV DX,OFFSET TRANGROUP:OVERWR_ptr
90 JNZ NO_CONCAT_ERR ;AC000; If not, overwrite error
91 JMP COPERR ;AC000;
92
93NO_CONCAT_ERR: ;AC000;
94 MOV [NOWRITE],1 ; Flag not writting (just seeking)
95
96PROCDEST:
97 MOV AX,EXTOPEN SHL 8 ;AC000; open the file
98 mov si,offset trangroup:destbuf ;AN030; get file name
99 mov di,-1 ;AN030; indicate no parameters
100 cmp src_xa_seg,no_xa_seg ;AN030; is there an XA segment?
101 jz cont_no_xa ;AN030; no - no parameters
102 mov di,offset trangroup:Ext_open_parms ;AN030; get parameters
103 mov bx,src_xa_seg ;AN030; get extended attribute segment
104 mov ext_open_seg,bx ;AN030; put it in parameter list
105 mov ext_open_off,0 ;AN030; offset is 0
106
107cont_no_xa: ;AN030;
108 mov bx,write_open_mode ;AN000; get open mode for COPY
109 xor cx,cx ;AN000; no special files
110 mov dx,write_open_flag ;AN000; set up open flags
111
112 CMP [NOWRITE],0
113 JNZ DODESTOPEN ; Don't actually create if NOWRITE set
114 mov dx,creat_open_flag ;AC000; set up create flags
115
116DODESTOPEN:
117 INT int_command
118;
119; We assume that the error is normal. TriageError will correct the DX value
120; appropriately.
121;
122 JNC dest_open_okay ;AC030;
123
124xa_set_error: ;AN030; error occurred on XA
125 invoke set_ext_error_msg ;AN030; get extended error
126
127ext_err_set: ;AN030;
128 mov string_ptr_2,offset trangroup:destbuf ;AN000; get address of failed string
129 mov Extend_buf_sub,one_subst ;AN030; put number of subst in control block
130
131COPERRJ2: ;AN030;
132 jmp COPERR ;AN030; go issue message
133
134dest_open_okay: ;AC030
135 mov [DESTHAND],ax ; Save handle
136 mov [CFLAG],1 ; Destination now exists
137 mov bx,ax
138 mov cx,bx ;AN030; get handle into CX
139 invoke set_file_code_page ;AN030; set the code page for the target
140 jc ext_err_set ;AN030; if no error, continue
141
142 mov [concat_xa],0 ;AN000; set first file flag off
143 mov ax,(IOCTL SHL 8)
144 INT int_command ; Get device stuff
145 mov [DESTISDEV],dl ; Set dest info
146 test dl,devid_ISDEV
147 jz exists ;AC030; Dest a device
148
149 mov al,BYTE PTR [DESTSWITCH]
150 AND AL,SwitchA+SwitchB
151 JNZ TESTBOTH
152 MOV AL,[ASCII] ; Neither set, use current setting
153 OR AL,[BINARY]
154 JZ EXSETA ; Neither set, default to ASCII
155
156TESTBOTH:
157 JPE EXISTS ; Both are set, ignore
158 test AL,SwitchB
159 jz EXISTS ; Leave in cooked mode
160 mov ax,(IOCTL SHL 8) OR 1
161 xor dh,dh
162 or dl,devid_RAW
163 mov [DESTISDEV],dl ; New value
164 INT int_command ; Set device to RAW mode
165 jmp short EXISTS
166
167COPERRJ:
168 jmp SHORT COPERR
169
170EXSETA:
171;
172; What we read in may have been in binary mode, flag zapped write OK
173;
174 mov [ASCII],SwitchA ; Set ASCII mode
175 or [INEXACT],SwitchA ; ASCII -> INEXACT
176
177EXISTS:
178 cmp [NOWRITE],0
179 jnz NOCHECKING ; If nowrite don't bother with name check
180 cmp plus_comma,1 ;g don't check if just doing +,,
181 jz NOCHECKING ;g
182 invoke COMPNAME ; Source and dest. the same?
183 JNZ NOCHECKING ; If not, go ahead
184 CMP [SRCISDEV],0
185 JNZ NOCHECKING ; Same name on device OK
186;
187; At this point we know in append (would have gotten overwrite error on first
188; destination create otherwise), and user trying to specify destination which
189; has been scribbled already (if dest had been named first, NOWRITE would
190; be set).
191;
192 MOV DX,OFFSET TRANGROUP:LOSTERR_ptr ; Tell him he's not going to get it
193 invoke std_Eprintf ;AC022;
194 MOV [NXTADD],0 ; Set return
195 INC [TERMREAD] ; Tell Read to give up
196
197RET60:
198 return
199
200NOCHECKING:
201 mov bx,[DESTHAND] ; Get handle
202 XOR CX,CX
203 XCHG CX,[NXTADD]
204 JCXZ RET60 ; If Nothing to write, forget it
205 INC [WRITTEN] ; Flag that we wrote something
206 CMP [NOWRITE],0 ; If NOWRITE set, just seek CX bytes
207 JNZ SEEKEND
208 XOR DX,DX
209 PUSH DS
210 MOV DS,[TPA]
211ASSUME DS:NOTHING
212 MOV AH,WRITE
213 INT int_command
214 POP DS
215ASSUME DS:TRANGROUP
216 MOV DX,OFFSET TRANGROUP:NOSPACE_ptr
217 JC xa_set_error_Jmp ;AC022; Failure
218 sub cx,ax
219 retz ; Wrote all supposed to
220 test [DESTISDEV],devid_ISDEV
221 jz COPERR ; Is a file, error
222 test [DESTISDEV],devid_RAW
223 jnz DEVWRTERR ; Is a raw device, error
224 cmp [INEXACT],0
225 retnz ; INEXACT so OK
226 dec cx
227 retz ; Wrote one byte less (the ^Z)
228
229DEVWRTERR:
230 MOV DX,OFFSET TRANGROUP:DEVWMES_ptr
231
232PUBLIC COPERR
233COPERR:
234 INVOKE std_Eprintf ;AC022;
235
236COPERRP:
237 inc [DESTCLOSED]
238 cmp [CFLAG],0
239 jz ENDCOPYJ ; Never actually got it open
240 MOV bx,[DESTHAND]
241 CMP BX,0
242 JLE NoClose
243 MOV AH,CLOSE ; Close the file
244 INT int_command
245
246NoClose:
247 MOV DX,OFFSET TRANGROUP:DESTBUF
248 MOV AH,UNLINK
249 INT int_command ; And delete it
250 MOV [CFLAG],0
251
252ENDCOPYJ:
253 JMP ENDCOPY
254
255XA_SET_ERROR_JMP: ;AN022; Go set up error message
256 jmp xa_set_error ;AN022;
257
258SEEKEND:
259 xor dx,dx ; Zero high half of offset
260 xchg dx,cx ; cx:dx is seek location
261 mov ax,(LSEEK SHL 8) OR 1
262 INT int_command ; Seek ahead in the file
263 cmp [RDEOF],0
264 retz
265;
266; If a ^Z has been read we must set the file size to the current
267; file pointer location
268;
269 MOV AH,WRITE
270 INT int_command ; CX is zero, truncates file
271 jc xa_set_error_Jmp ;AC022; Failure
272 return
273
274TRANCODE ENDS
275 END
276 \ No newline at end of file
diff --git a/v4.0/src/CMD/COMMAND/COPYPR2.ASM b/v4.0/src/CMD/COMMAND/COPYPR2.ASM
new file mode 100644
index 0000000..2913cab
--- /dev/null
+++ b/v4.0/src/CMD/COMMAND/COPYPR2.ASM
@@ -0,0 +1,450 @@
1 page 80,132
2; SCCSID = @(#)copypr2.asm 1.1 85/05/14
3; SCCSID = @(#)copypr2.asm 1.1 85/05/14
4 INCLUDE comsw.asm
5
6.xlist
7.xcref
8 INCLUDE DOSSYM.INC
9 INCLUDE comseg.asm
10 INCLUDE comequ.asm
11.list
12.cref
13
14
15TRANDATA SEGMENT PUBLIC BYTE ;AC000;
16 EXTRN FulDir_ptr:word ;AN052;
17TRANDATA ENDS
18
19TRANSPACE SEGMENT PUBLIC BYTE ;AC000;
20 EXTRN ASCII:BYTE
21 EXTRN BINARY:BYTE
22 EXTRN CONCAT:BYTE
23 EXTRN DESTBUF:BYTE
24 EXTRN DESTFCB:BYTE
25 EXTRN DESTINFO:BYTE
26 EXTRN DESTISDIR:BYTE
27 EXTRN DESTTAIL:WORD
28 EXTRN DESTVARS:BYTE
29 EXTRN DIRBUF:BYTE
30 EXTRN DIRCHAR:BYTE
31 EXTRN FIRSTDEST:BYTE
32 EXTRN INEXACT:BYTE
33 EXTRN MELCOPY:BYTE
34 EXTRN NXTADD:WORD
35 EXTRN PLUS:BYTE
36 EXTRN SDIRBUF:BYTE
37 EXTRN SRCINFO:BYTE
38 EXTRN srcxname:byte
39 EXTRN TPA:WORD
40 EXTRN trgxname:byte
41 EXTRN USERDIR1:BYTE
42TRANSPACE ENDS
43
44TRANCODE SEGMENT PUBLIC BYTE
45
46 EXTRN BADPATH_ERR:NEAR ;AN022;
47 EXTRN COPERR:NEAR ;AN052;
48 EXTRN EXTEND_SETUP:NEAR ;AN022;
49
50 PUBLIC BUILDPATH
51 PUBLIC SETSTARS
52 PUBLIC SETASC
53
54ASSUME CS:TRANGROUP,DS:TRANGROUP,ES:TRANGROUP,SS:NOTHING
55
56SETASC:
57;
58; Given switch vector in AX,
59; Set ASCII switch if A is set
60; Clear ASCII switch if B is set
61; BINARY set if B specified
62; Leave ASCII unchanged if neither or both are set
63; Also sets INEXACT if ASCII is ever set. AL = ASCII on exit, flags set
64;
65 AND AL,SwitchA+SwitchB
66 JPE LOADSW ; PE means both or neither are set
67 PUSH AX
68 AND AL,SwitchB
69 MOV [BINARY],AL
70 POP AX
71 AND AL,SwitchA
72 MOV [ASCII],AL
73 OR [INEXACT],AL
74
75LOADSW:
76 MOV AL,[ASCII]
77 OR AL,AL
78 return
79
80public builddest
81BUILDDEST:
82 cmp [DESTISDIR],-1
83 jnz KNOWABOUTDEST ; Already done the figuring
84 MOV DI,OFFSET TRANGROUP:USERDIR1
85 mov bp,offset trangroup:DESTVARS
86 call BUILDPATH
87 invoke RESTUDIR1
88
89; Now know all about the destination
90
91KNOWABOUTDEST:
92 xor al,al
93 xchg al,[FIRSTDEST]
94 or al,al
95 jnz FIRSTDST
96 jmp NOTFIRSTDEST
97
98FIRSTDST:
99 mov si,[DESTTAIL] ; Create an FCB of the original DEST
100 mov di,offset trangroup:DESTFCB
101 mov ax,PARSE_FILE_DESCRIPTOR SHL 8
102 INT int_command
103 CMP BYTE PTR [SI],0
104 JZ GoodParse
105;AD052; MOV BYTE PTR [DI+1],"|" ; must be illegal file name character
106 mov dx,offset trangroup:fuldir_ptr ;AN052; Issue "File creation error"
107 jmp coperr ;AN052;
108
109GoodParse:
110 mov ax,word ptr [DESTBUF] ; Get drive
111 cmp ah,':'
112 jz DRVSPEC4
113 mov al,'@'
114
115DRVSPEC4:
116 MOV CL,[ASCII] ; Save current ASCII setting
117 or al,20h
118 sub al,60h
119 mov [DESTFCB],al
120 mov al,[DESTINFO]
121 mov ah,[SRCINFO]
122 and ax,0202H
123 or al,al
124 jz NOTMELCOPY
125 cmp al,ah
126 jnz NOTMELCOPY
127 cmp [PLUS],0
128 jz NOTMELCOPY
129 inc [MELCOPY] ; ambig source, ambig dest, and pluses
130 xor al,al
131 jmp short SETCONC
132
133NOTMELCOPY:
134 xor al,2 ; al=2 if unambig dest, =0 if ambig dest
135 and al,ah
136 shr al,1 ; al=1 if unambig dest AND ambig sorce
137 ; Implies concatenation
138SETCONC:
139 or al,[PLUS] ; al=1 if concat
140 mov [CONCAT],al
141 shl al,1
142 shl al,1
143 mov [INEXACT],al ; Concat -> inexact copy
144 cmp [BINARY],0
145 jnz NOTFIRSTDEST ; Binary explicitly given, all OK
146 mov [ASCII],al ; Concat -> ASCII
147 or cl,cl
148 jnz NOTFIRSTDEST ; ASCII flag set before, DATA read correctly
149 or al,al
150 JZ NOTFIRSTDEST ; ASCII flag did not change states
151;
152; At this point there may already be binary read data in the read buffer.
153; We need to find the first ^Z (if there is one) and trim the amount
154; of data in the buffer correctly.
155;
156 MOV CX,[NXTADD]
157 JCXZ NOTFIRSTDEST ; No data, everything OK
158 MOV AL,1AH
159 PUSH ES
160 XOR DI,DI
161 MOV ES,[TPA]
162 REPNE SCASB ; Scan for EOF
163 POP ES
164 JNZ NOTFIRSTDEST ; No ^Z in buffer, everything OK
165 DEC DI ; Point at ^Z
166 MOV [NXTADD],DI ; New buffer
167
168NOTFIRSTDEST:
169 mov bx,offset trangroup:DIRBUF+1 ; Source of replacement chars
170 cmp [CONCAT],0
171 jz GOTCHRSRC ; Not a concat
172 mov bx,offset trangroup:SDIRBUF+1 ; Source of replacement chars
173
174GOTCHRSRC:
175 mov si,offset trangroup:DESTFCB+1 ; Original dest name
176 mov di,[DESTTAIL] ; Where to put result
177
178public buildname
179BUILDNAME:
180 mov cx,8
181
182BUILDMAIN:
183 lodsb
184 cmp al,'?'
185 jnz NOTAMBIG
186 mov al,byte ptr [BX]
187
188NOTAMBIG:
189 cmp al,' '
190 jz NOSTORE
191 stosb
192
193NOSTORE:
194 inc bx
195 loop BUILDMAIN
196 mov cl,3
197 mov al,' '
198 cmp byte ptr [SI],al
199 jz ENDDEST ; No extension
200 mov al,dot_chr
201 stosb
202
203BUILDEXT:
204 lodsb
205 cmp al,'?'
206 jnz NOTAMBIGE
207 mov al,byte ptr [BX]
208
209NOTAMBIGE:
210 cmp al,' '
211 jz NOSTOREE
212 stosb
213
214NOSTOREE:
215 inc bx
216 loop BUILDEXT
217ENDDEST:
218 xor al,al
219 stosb ; NUL terminate
220 return
221
222BUILDPATH:
223 test [BP.INFO],2
224 jnz NOTPFILE ; If ambig don't bother with open
225 mov dx,bp
226 add dx,BUF ; Set DX to spec
227
228 push di ;AN000;
229 MOV AX,EXTOPEN SHL 8 ;AC000; open the file
230 mov bx,read_open_mode ;AN000; get open mode for COPY
231 xor cx,cx ;AN000; no special files
232 mov si,dx ;AN030; get file name offset
233 mov di,-1 ;AN030; no parm list
234 mov dx,read_open_flag ;AN000; set up open flags
235 INT int_command
236 pop di ;AN000;
237 jnc pure_file ;AN022; is pure file
238 invoke get_ext_error_number ;AN022; get the extended error
239 cmp ax,error_file_not_found ;AN022; if file not found - okay
240 jz notpfile ;AN022;
241 cmp ax,error_path_not_found ;AN022; if path not found - okay
242 jz notpfile ;AN022;
243 cmp ax,error_access_denied ;AN022; if access denied - okay
244 jz notpfile ;AN022;
245 jmp extend_setup ;AN022; exit with error
246
247pure_file:
248 mov bx,ax ; Is pure file
249 mov ax,IOCTL SHL 8
250 INT int_command
251 mov ah,CLOSE
252 INT int_command
253 test dl,devid_ISDEV
254 jnz ISADEV ; If device, done
255 test [BP.INFO],4
256 jz ISSIMPFILE ; If no path seps, done
257
258NOTPFILE:
259 mov dx,word ptr [BP.BUF]
260 cmp dl,0 ;AN034; If no drive specified, get
261 jz set_drive_spec ;AN034; default drive dir
262 cmp dh,':'
263 jz DRVSPEC5
264
265set_drive_spec: ;AN034;
266 mov dl,'@'
267
268DRVSPEC5:
269 or dl,20h
270 sub dl,60h ; A = 1
271 invoke SAVUDIR1
272 jnc curdir_ok ;AN022; if error - exit
273 invoke get_ext_error_number ;AN022; get the extended error
274 jmp extend_setup ;AN022; exit with error
275
276curdir_ok: ;AN022;
277 mov dx,bp
278 add dx,BUF ; Set DX for upcomming CHDIRs
279 mov bh,[BP.INFO]
280 and bh,6
281 cmp bh,6 ; Ambig and path ?
282 jnz CHECKAMB ; jmp if no
283 mov si,[BP.TTAIL]
284 mov bl,':'
285 cmp byte ptr [si-2],bl
286 jnz KNOWNOTSPEC
287 mov [BP.ISDIR],2 ; Know is d:/file
288 jmp short DOPCDJ
289
290KNOWNOTSPEC:
291 mov [BP.ISDIR],1 ; Know is path/file
292 dec si ; Point to the /
293
294DOPCDJ:
295 jmp DOPCD ;AC022; need long jump
296
297CHECKAMB:
298 cmp bh,2
299 jnz CHECKCD
300
301ISSIMPFILE:
302ISADEV:
303 mov [BP.ISDIR],0 ; Know is file since ambig but no path
304 return
305
306CHECKCD:
307 invoke SETREST1
308 mov ah,CHDIR
309 INT int_command
310 jc NOTPDIR
311 mov di,dx
312 xor ax,ax
313 mov cx,ax
314 dec cx
315
316Kloop: ;AN000; 3/3/KK
317 MOV AL,ES:[DI] ;AN000; 3/3/KK
318 INC DI ;AN000; 3/3/KK
319 OR AL,AL ;AN000; 3/3/KK
320 JZ Done ;AN000; 3/3/KK
321 xor ah,ah ;AN000; 3/3/KK
322 invoke Testkanj ;AN000; 3/3/KK
323 JZ Kloop ;AN000; 3/3/KK
324 INC DI ;AN000; 3/3/KK
325 INC AH ;AN000; 3/3/KK
326 jmp Kloop ;AN000; 3/3/KK
327
328Done: ;AN000; 3/3/KK
329 dec di
330 mov al,[DIRCHAR]
331 mov [bp.ISDIR],2 ; assume d:/file
332 OR AH, AH ;AN000; 3/3/KK
333 JNZ Store_pchar ;AN000; 3/3/KK this is the trailing byte of ECS code
334 cmp al,[di-1]
335 jz GOTSRCSLSH
336
337Store_pchar: ;AN000; 3/3/KK
338 stosb
339 mov [bp.ISDIR],1 ; know path/file
340
341GOTSRCSLSH:
342 or [bp.INFO],6
343 call SETSTARS
344 return
345
346
347NOTPDIR:
348 invoke get_ext_error_number ;AN022; get the extended error
349 cmp ax,error_path_not_found ;AN022; if path not found - okay
350 jz notpdir_try ;AN022;
351 cmp ax,error_access_denied ;AN022; if access denied - okay
352 jnz extend_setupj ;AN022; otherwise - exit error
353
354notpdir_try: ;AN022;
355 mov [bp.ISDIR],0 ; assume pure file
356 mov bh,[bp.INFO]
357 test bh,4
358 retz ; Know pure file, no path seps
359 mov [bp.ISDIR],2 ; assume d:/file
360 mov si,[bp.TTAIL]
361 cmp byte ptr [si],0
362 jz BADCDERRJ2 ; Trailing '/'
363 mov bl,dot_chr
364 cmp byte ptr [si],bl
365 jz BADCDERRJ2 ; If . or .. pure cd should have worked
366 mov bl,':'
367 cmp byte ptr [si-2],bl
368 jz DOPCD ; Know d:/file
369 mov [bp.ISDIR],1 ; Know path/file
370 dec si ; Point at last '/'
371
372DOPCD:
373 xor bl,bl
374 xchg bl,[SI] ; Stick in a NUL
375 invoke SETREST1
376 CMP DX,SI ;AN000; 3/3/KK
377 JAE LookBack ;AN000; 3/3/KK
378 PUSH SI ;AN000; 3/3/KK
379 PUSH CX ;AN000; 3/3/KK
380 MOV CX,SI ;AN000; 3/3/KK
381 MOV SI,DX ;AN000; 3/3/KK
382
383Kloop2: ;AN000; 3/3/KK
384 LODSB ;AN000; 3/3/KK
385 invoke TestKanj ;AN000; 3/3/KK
386 jz NotKanj4 ;AN000; 3/3/KK
387 LODSB ;AN000; 3/3/KK
388 CMP SI,CX ;AN000; 3/3/KK
389 JB Kloop2 ;AN000; 3/3/KK
390 POP CX ;AN000; 3/3/KK
391 POP SI ;AN000; 3/3/KK
392 JMP SHORT DoCdr ;AN000; 3/3/KK Last char is ECS code, don't check for
393 ; trailing path sep
394NotKanj4: ;AN000; 3/3/KK
395 CMP SI,CX ;AN000; 3/3/KK
396 JB Kloop2 ;AN000; 3/3/KK
397 POP CX ;AN000; 3/3/KK
398 POP SI ;AN000; 3/3/KK
399
400LookBack: ;AN000; 3/3/KK
401 CMP BL,[SI-1] ; if double slash, then complain.
402 JZ BadCDErrJ2
403
404DoCdr: ;AN000; 3/3/KK
405 mov ah,CHDIR
406 INT int_command
407 xchg bl,[SI]
408 retnc
409 invoke get_ext_error_number ;AN022; get the extended error
410
411EXTEND_SETUPJ: ;AN022;
412 JMP EXTEND_SETUP ;AN022; go issue the error message
413
414BADCDERRJ2:
415 jmp badpath_err ;AC022; go issue path not found message
416
417SETSTARS:
418 mov [bp.TTAIL],DI
419 add [bp.SIZ],12
420 mov ax,dot_qmark
421 mov cx,8
422 rep stosb
423 xchg al,ah
424 stosb
425 xchg al,ah
426 mov cl,3
427 rep stosb
428 xor al,al
429 stosb
430 return
431
432PUBLIC CompName
433COMPNAME:
434
435 mov si,offset trangroup:DESTBUF ;g do name translate of target
436 mov di,offset trangroup:TRGXNAME ;g save for name comparison
437 mov ah,xnametrans ;g
438 int int_command ;g
439
440 MOV si,offset trangroup:SRCXNAME ;g get name translate of source
441 MOV di,offset trangroup:TRGXNAME ;g get name translate of target
442
443
444 invoke STRCOMP
445
446 return
447
448TRANCODE ENDS
449 END
450 \ No newline at end of file
diff --git a/v4.0/src/CMD/COMMAND/CPARSE.ASM b/v4.0/src/CMD/COMMAND/CPARSE.ASM
new file mode 100644
index 0000000..f751086
--- /dev/null
+++ b/v4.0/src/CMD/COMMAND/CPARSE.ASM
@@ -0,0 +1,417 @@
1 page 80,132
2; SCCSID = @(#)cparse.asm 1.1 85/05/14
3; SCCSID = @(#)cparse.asm 1.1 85/05/14
4 INCLUDE comsw.asm
5
6.xlist
7.xcref
8 INCLUDE DOSSYM.INC
9 INCLUDE DEVSYM.INC
10 INCLUDE comseg.asm
11 INCLUDE comequ.asm
12.list
13.cref
14
15
16TRANDATA SEGMENT PUBLIC BYTE ;AC000;
17 EXTRN BADCD_PTR:WORD ;AC022;
18 EXTRN BADCPMES_ptr:word ;AC000;
19TRANDATA ENDS
20
21TRANSPACE SEGMENT PUBLIC BYTE ;AC000;
22 EXTRN comma:byte
23 EXTRN cpyflag:byte
24 EXTRN CURDRV:BYTE
25 EXTRN ELCNT:BYTE
26 EXTRN ELPOS:BYTE
27 EXTRN EXPAND_STAR:BYTE
28 EXTRN SKPDEL:BYTE
29 EXTRN STARTEL:WORD
30 EXTRN SWITCHAR:BYTE
31 EXTRN switch_list:byte
32 EXTRN TPA:WORD
33TRANSPACE ENDS
34
35TRANCODE SEGMENT PUBLIC BYTE
36
37ASSUME CS:TRANGROUP,DS:TRANGROUP,ES:TRANGROUP,SS:NOTHING
38
39 EXTRN CERROR:NEAR
40
41 PUBLIC BADCDERR ;AC022;
42 PUBLIC CPARSE
43
44SWCOUNT EQU 5 ; Must agree with length of switch_list
45
46;-----------------------------------------------------------------------;
47; ENTRY: ;
48; DS:SI Points input buffer ;
49; ES:DI Points to the token buffer ;
50; BL Special delimiter for this call ;
51; Always checked last ;
52; set it to space if there is no special delimiter ;
53; EXIT: ;
54; DS:SI Points to next char in the input buffer ;
55; ES:DI Points to the token buffer ;
56; [STARTEL] Points to start of last element of path in token ;
57; points to a NUL for no element strings 'd:' 'd:/' ;
58; CX Character count ;
59; BH Condition Code ;
60; Bit 1H of BH set if switch character ;
61; Token buffer contains char after ;
62; switch character ;
63; BP has switch bits set (ORing only) ;
64; Bit 2H of BH set if ? or * in token ;
65; if * found element ? filled ;
66; Bit 4H of BH set if path sep in token ;
67; Bit 80H of BH set if the special delimiter ;
68; was skipped at the start of this token ;
69; Token buffer always starts d: for non switch tokens ;
70; CARRY SET ;
71; if CR on input ;
72; token buffer not altered ;
73; ;
74; DOES NOT RETURN ON BAD PATH, OR TRAILING SWITCH CHAR ERROR ;
75; MODIFIES: ;
76; CX, SI, AX, BH, DX and the Carry Flag ; ;
77; ;
78; -----------------------------------------------------------------------;
79;---------------
80; Modifications to cparse: recognition of right and left parentheses
81; as integral tokens, and removal of automatic upper-case conversion code.
82;
83; Both modifications were installed in the course of adding a coherent
84; command-line parser to COMMAND.COM which builds a UNIX-style argv[]/argc
85; structure for command-line arguments. This parser relies on cparse to
86; recognize individual tokens.
87;
88; To process for-loops correctly, parentheses must therefore be
89; recognized as tokens. The upper-case conversion code was removed so
90; that commands (such as for and echo) would be able to use the "original"
91; text of the command line.
92;
93; Note also the modification to prevent the automatic conversion of colons
94; into spaces WITHIN THE SOURCE TEXT!
95;
96; Also note that BP is also clobbered if cparse recognizes any switches
97; on the command line.
98;
99; Alan L, OS/MSDOS 14 August 1983
100;---------------
101
102CPARSE:
103ASSUME DS:TRANGROUP,ES:TRANGROUP
104
105 xor ax,ax
106 mov [STARTEL],DI ; No path element (Is DI correct?)
107 mov [ELPOS],al ; Start in 8 char prefix
108 mov [SKPDEL],al ; No skip delimiter yet
109 mov bh,al ; Init nothing
110 pushf ; save flags
111 push di ; save the token buffer addrss
112 xor cx,cx ; no chars in token buffer
113 mov comma,cl ;g reset comma flag
114moredelim:
115 LODSB
116 INVOKE DELIM
117 JNZ SCANCDONE
118 CMP AL,' '
119 JZ moredelim
120 CMP AL,9
121 JZ moredelim
122 xchg al,[SKPDEL]
123 or al,al
124 jz moredelim ; One non space/tab delimiter allowed
125 test bh,080h ;g has a special char been found?
126 jz no_comma ;g no - just exit
127 mov comma,1 ;g set comma flag
128no_comma:
129 JMP x_done ; Nul argument
130
131SCANCDONE:
132
133;;;; IF NOT KANJI 3/3/KK
134;---------------
135; Mod to avoid upper-case conversion.
136; cmp cpyflag,1 3/3/KK
137; jnz cpcont1 3/3/KK
138; invoke UPCONV 3/3/KK
139cpcont1:
140;---------------
141;;;; ENDIF 3/3/KK
142
143 cmp al,bl ; Special delimiter?
144 jnz nospec
145 or bh,80H
146 jmp short moredelim
147
148nospec:
149 cmp al,0DH ; a CR?
150 jne ncperror
151 jmp cperror
152
153ncperror:
154 cmp al,[SWITCHAR] ; is the char the switch char?
155 jne na_switch ; yes, process...
156 jmp a_switch
157
158na_switch:
159 mov dl,':'
160 cmp byte ptr [si],dl
161 jne anum_chard ; Drive not specified
162
163;;;; IF KANJI 3/3/KK
164;---------------
165; Mod to avoid upper-case conversion.
166 cmp cpyflag,1
167 jnz cpcont2
168 invoke UPCONV
169cpcont2:
170;---------------
171;;;; ENDIF 3/3/KK
172
173 call move_char
174 lodsb ; Get the ':'
175 call move_char
176 mov [STARTEL],di
177 mov [ELCNT],0
178 jmp anum_test
179
180anum_chard:
181 mov [STARTEL],di
182 mov [ELCNT],0 ; Store of this char sets it to one
183 cmp cpyflag,1 ; Was CPARSE called from COPY?
184 jnz anum_char ; No, don't add drive spec.
185 invoke PATHCHRCMP ; Starts with a pathchar?
186 jnz anum_char ; no
187 push ax
188 mov al,[CURDRV] ; Insert drive spec
189 add al,capital_A
190 call move_char
191 mov al,':'
192 call move_char
193 pop ax
194 mov [STARTEL],di
195 mov [ELCNT],0
196
197anum_char:
198
199;;;; IF KANJI 3/3/KK
200 invoke TESTKANJ
201 jz NOTKANJ ;AC048;
202 call move_char
203 lodsb
204 jmp short notspecial
205
206NOTKANJ: ;AN048; If not kanji
207 cmp cpyflag,1 ;AN048; and if we're in COPY
208 jnz testdot ;AN048;
209 invoke upconv ;AN048; upper case the char
210
211TESTDOT:
212;;;; ENDIF 3/3/KK
213
214 cmp al,dot_chr
215 jnz testquest
216 inc [ELPOS] ; flag in extension
217 mov [ELCNT],0FFH ; Store of the '.' resets it to 0
218
219testquest:
220 cmp al,'?'
221 jnz testsplat
222 or bh,2
223
224testsplat:
225 cmp al,star
226 jnz testpath
227 or bh,2
228 cmp byte ptr [expand_star],0
229 jnz expand_filename
230 jmp SHORT testpath
231
232badperr2j:
233 jmp badperr2
234
235expand_filename:
236 mov ah,7
237 cmp [ELPOS],0
238 jz gotelcnt
239 mov ah,2
240
241gotelcnt:
242 mov al,'?'
243 sub ah,[ELCNT]
244 jc badperr2j
245 xchg ah,cl
246 jcxz testpathx
247
248qmove:
249 xchg ah,cl
250 call move_char
251 xchg ah,cl
252 loop qmove
253
254testpathx:
255 xchg ah,cl
256
257testpath:
258 invoke PATHCHRCMP
259 jnz notspecial
260 or bh,4
261 cmp byte ptr [expand_star],0
262 jz no_err_check
263 test bh,2 ; If just hit a '/', cannot have ? or * yet
264 jnz badperr
265
266no_err_check:
267 mov [STARTEL],di ; New element
268 INC [STARTEL] ; Point to char after /
269 mov [ELCNT],0FFH ; Store of '/' sets it to 0
270 mov [ELPOS],0
271
272notspecial:
273 call move_char ; just an alphanum string
274anum_test:
275
276 lodsb
277
278;;;; IF NOT KANJI 3/3/KK
279;---------------
280; Mod to avoid upper-case conversion.
281; cmp cpyflag,1 3/3/KK
282; jnz cpcont3 3/3/KK
283; invoke UPCONV 3/3/KK
284cpcont3:
285;---------------
286;;;; ENDIF 3/3/KK
287
288 INVOKE DELIM
289 je x_done
290
291 cmp al,0DH
292 je x_done
293 cmp al,[SWITCHAR]
294 je x_done
295 cmp al,bl
296 je x_done
297 cmp al,':' ; ':' allowed as trailer because
298 ; of devices
299;;;; IF KANJI 3/3/KK
300 je FOO15
301 jmp anum_char
302FOO15:
303;;; ELSE 3/3/KK
304;;; jne anum_charj 3/3/KK
305;;; ENDIF 3/3/KK
306
307;---------------
308; Modification made for parseline.
309; Why would it be necessary to change colons to spaces? In this
310; case, EVERY colon is changed to a space; e.g., 'f:' yields 'f ',
311; but so does 'echo foo:bar' yield 'echo foo bar'.
312;---------------
313 cmp cpyflag,2 ; Is CPARSE parsing the 1st token from
314 ; from PARSELINE?
315 jnz cpcont4 ; No, continue
316 call move_char ; Yes, save the ':' and go get another
317 jmp anum_test ; character.
318
319cpcont4:
320 inc si ;Skip the ':'
321 jmp short x_done
322
323anum_charj:
324 jmp anum_char
325
326badperr2:
327 mov dx,offset trangroup:BADCPMES_ptr
328 jmp CERROR
329
330badperr:
331BADCDERR: ;AC022; Issue "Invalid Directory"
332 MOV DX,OFFSET TRANGROUP:BADCD_ptr ;AC022; message
333 JMP CERROR ;AC022;
334
335cperror:
336 dec si ; adjust the pointer
337 pop di ; retrive token buffer address
338 popf ; restore flags
339 stc ; set the carry bit
340 return
341
342x_done:
343 dec si ; adjust for next round
344;---------------
345; Mod to recognize right and left parens as integral tokens.
346x_done2:
347;---------------
348 jmp short out_token
349
350a_switch:
351 OR BH,1 ; Indicate switch
352 OR BP,fSwitch
353 INVOKE SCANOFF
354 INC SI
355 invoke testkanj ;AN057; See if DBCS lead byte
356 jz a_switch_notkanj ;AN057; no - continue processing
357 call move_char ;AN057; DBCS - store first byte
358 lodsb ;AN057; get second byte
359 call move_char ;AN057; store second byte
360 or bp,fBadSwitch ;AN057; DBCS switch is invalid
361 jmp short out_token ;AN057; don't bother checking switch
362a_switch_notkanj: ;AN057;
363 cmp al,0DH
364 jne Store_swt
365 mov al,0
366 stosb ; null at the end
367 OR BP,fBadSwitch
368 jmp cperror ; Trailing switch character error
369 ; BP = fSwitch but no switch
370 ; bit is set (unknown switch)
371Store_swt:
372 call move_char ; store the character
373;
374;---------------
375; This upconv call must stay. It is used to identify copy-switches
376; on the command line, and won't store anything into the output buffer.
377 invoke UPCONV
378;---------------
379;
380 PUSH ES
381 PUSH DI
382 PUSH CX
383 PUSH CS
384 POP ES
385ASSUME ES:TRANGROUP
386 MOV DI,OFFSET TRANGROUP:switch_list
387 MOV CX,SWCOUNT
388 OR BP,fBadSwitch
389 REPNE SCASB
390 JNZ out_tokenp
391 AND BP,NOT fBadSwitch
392 MOV AX,1
393 SHL AX,CL
394 OR BP,AX
395
396out_tokenp:
397 POP CX
398 POP DI
399 POP ES
400
401ASSUME ES:NOTHING
402out_token:
403 mov al,0
404 stosb ; null at the end
405 pop di ; restore token buffer pointer
406 popf
407 clc ; clear carry flag
408 return
409
410move_char:
411 stosb ; store char in token buffer
412 inc cx ; increment char count
413 inc [ELCNT] ; increment element count for * substi
414 return
415
416TRANCODE ENDS
417 END
diff --git a/v4.0/src/CMD/COMMAND/ENVDATA.ASM b/v4.0/src/CMD/COMMAND/ENVDATA.ASM
new file mode 100644
index 0000000..ed4cd9e
--- /dev/null
+++ b/v4.0/src/CMD/COMMAND/ENVDATA.ASM
@@ -0,0 +1,28 @@
1; SCCSID = @(#)envdata.asm 1.1 85/05/14
2; SCCSID = @(#)envdata.asm 1.1 85/05/14
3; This file is included by command.asm and is used as the default command
4; environment.
5
6ENVARENA SEGMENT PUBLIC PARA
7 ORG 0
8 DB 10h DUP (?) ;Pad for memory allocation addr mark
9ENVARENA ENDS
10
11ENVIRONMENT SEGMENT PUBLIC PARA ; Default COMMAND environment
12
13 PUBLIC ECOMSPEC,ENVIREND,PATHSTRING
14
15 ORG 0
16PATHSTRING DB "PATH="
17USERPATH LABEL BYTE
18
19 DB 0 ; Null path
20 DB "COMSPEC="
21ECOMSPEC DB "\COMMAND.COM" ;AC062
22 DB 134 DUP (0)
23
24ENVIREND LABEL BYTE
25
26ENVIRONSIZ EQU $-PATHSTRING
27ENVIRONSIZ2 EQU $-ECOMSPEC
28ENVIRONMENT ENDS
diff --git a/v4.0/src/CMD/COMMAND/FORDATA.ASM b/v4.0/src/CMD/COMMAND/FORDATA.ASM
new file mode 100644
index 0000000..b46ba3d
--- /dev/null
+++ b/v4.0/src/CMD/COMMAND/FORDATA.ASM
@@ -0,0 +1,19 @@
1; SCCSID = @(#)fordata.asm 1.1 85/05/14
2; SCCSID = @(#)fordata.asm 1.1 85/05/14
3; Data structure definitions included by tfor.asm
4
5for_info STRUC
6 for_args DB (SIZE arg_unit) DUP (?) ; argv[] structure
7 FOR_COM_START DB (?) ; beginning of <command>
8 FOR_EXPAND DW (?) ; * or ? item in <list>?
9 FOR_MINARG DW (?) ; beginning of <list>
10 FOR_MAXARG DW (?) ; end of <list>
11 forbuf DW 64 DUP (?) ; temporary buffer
12 fordma DW 64 DUP (?) ; FindFirst/Next buffer
13 FOR_VAR DB (?) ; loop control variable
14for_info ENDS
15
16; empty segment done for bogus addressing
17for_segment segment
18f LABEL BYTE
19for_segment ends
diff --git a/v4.0/src/CMD/COMMAND/IFEQU.ASM b/v4.0/src/CMD/COMMAND/IFEQU.ASM
new file mode 100644
index 0000000..9c0ee29
--- /dev/null
+++ b/v4.0/src/CMD/COMMAND/IFEQU.ASM
@@ -0,0 +1,18 @@
1; SCCSID = @(#)ifequ.asm 1.1 85/05/14
2; SCCSID = @(#)ifequ.asm 1.1 85/05/14
3;*************************************
4; COMMAND EQUs which are switch dependant
5
6IF1
7 IF IBM
8 %OUT DBCS Enabled IBM version
9 ELSE
10 %OUT Normal version
11 ENDIF
12
13;; IF KANJI 3/3/KK
14;; %OUT Kanji version 3/3/KK
15;; ENDIF 3/3/KK
16
17ENDIF
18 \ No newline at end of file
diff --git a/v4.0/src/CMD/COMMAND/INIT.ASM b/v4.0/src/CMD/COMMAND/INIT.ASM
new file mode 100644
index 0000000..3ac84b6
--- /dev/null
+++ b/v4.0/src/CMD/COMMAND/INIT.ASM
@@ -0,0 +1,1685 @@
1 page 80,132
2; SCCSID = @(#)init.asm 4.13 85/11/03
3; SCCSID = @(#)init.asm 4.13 85/11/03
4TITLE COMMAND Initialization
5
6 INCLUDE comsw.asm
7
8.xlist
9.xcref
10 INCLUDE DOSSYM.INC
11 include doscntry.inc ;AC000;
12 INCLUDE comseg.asm
13 INCLUDE comequ.asm
14 include resmsg.equ ;AN000;
15.list
16.cref
17
18
19ENVIRONSIZ EQU 0A0H ;Must agree with values in EVIRONMENT segment
20ENVIRONSIZ2 EQU 092H
21
22ENVBIG EQU 32768
23ENVSML EQU 160
24KOREA_COUNTRY_CODE EQU 82
25
26CODERES SEGMENT PUBLIC BYTE ;AC000;
27 EXTRN CONTC:NEAR
28 EXTRN DskErr:NEAR
29 EXTRN endinit:near
30 EXTRN INT_2E:NEAR
31 EXTRN LODCOM:NEAR
32 EXTRN RSTACK:WORD
33CODERES ENDS
34
35DATARES SEGMENT PUBLIC BYTE ;AC000;
36 EXTRN abort_char:byte ;AN000;
37 EXTRN append_state:word ;AN042;
38 EXTRN BADFAT_OP_SEG:WORD ;AN000;
39 EXTRN BATCH:WORD
40 EXTRN COM_FCB1:DWORD
41 EXTRN COM_FCB2:DWORD
42 EXTRN COM_PTR:DWORD
43 EXTRN com_xlat_addr:word
44 EXTRN COMDRV:BYTE
45 EXTRN COMPRMT1_SEG:WORD ;AN000;
46 EXTRN COMPRMT1_SEG2:WORD ;AN000;
47 EXTRN COMSPEC:BYTE
48 EXTRN comspec_print:word
49 EXTRN comspec_end:word
50 EXTRN cpdrv:byte
51 EXTRN crit_msg_off:word ;AN000;
52 EXTRN crit_msg_seg:word ;AN000;
53 EXTRN critical_msg_start:byte ;AN000;
54 EXTRN DATARESEND:BYTE ;AC000;
55 EXTRN dbcs_vector_addr:word ;AN000;
56 EXTRN DEVE_OP_SEG:WORD ;AN000;
57 EXTRN DEVE_OP_SEG2:WORD ;AN000;
58 EXTRN disp_class:byte ;AN000;
59 EXTRN DRVNUM_OP_SEG:WORD ;AN000;
60 EXTRN DRVNUM_OP_SEG2:WORD ;AN000;
61 EXTRN EchoFlag:BYTE
62 EXTRN ENVIRSEG:WORD
63 EXTRN ERR15_OP_SEG:WORD ;AN000;
64 EXTRN ERR15_OP_SEG2:WORD ;AN000;
65 EXTRN ERR15_OP_SEG3:WORD ;AN000;
66 EXTRN extended_msg_start:byte ;AN000;
67 EXTRN extmsgend:byte ;AN000;
68 EXTRN fFail:BYTE
69 EXTRN fucase_addr:word ;AN000;
70 EXTRN InitFlag:BYTE
71 EXTRN IO_SAVE:WORD
72 EXTRN LTPA:WORD ;AC000;
73 EXTRN MEMSIZ:WORD
74 EXTRN MYSEG:WORD ;AC000;
75 EXTRN MYSEG1:WORD
76 EXTRN MYSEG2:WORD
77 EXTRN nest:word
78 EXTRN number_subst:byte ;AN000;
79 EXTRN OldTerm:DWORD
80 EXTRN PARENT:WORD
81;AD060; EXTRN pars_msg_off:word ;AN000;
82;AD060; EXTRN pars_msg_seg:word ;AN000;
83 EXTRN parse_msg_start:byte ;AN000;
84 EXTRN parsemes_ptr:word ;AN000;
85 EXTRN PERMCOM:BYTE
86 EXTRN RES_TPA:WORD
87 EXTRN resmsgend:word ;AN000;
88 EXTRN RSWITCHAR:BYTE
89 EXTRN SINGLECOM:WORD
90 EXTRN SUM:WORD
91 EXTRN TRNSEG:WORD
92 EXTRN TrnMvFlg:BYTE
93DATARES ENDS
94
95BATARENA SEGMENT PUBLIC PARA ;AC000;
96BATARENA ENDS
97
98BATSEG SEGMENT PUBLIC PARA ;AC000;
99BATSEG ENDS
100
101ENVARENA SEGMENT PUBLIC PARA ;AC000;
102ENVARENA ENDS
103
104ENVIRONMENT SEGMENT PUBLIC PARA ; Default COMMAND environment
105 EXTRN ECOMSPEC:BYTE
106 EXTRN ENVIREND:BYTE
107 EXTRN PATHSTRING:BYTE
108ENVIRONMENT ENDS
109
110TAIL SEGMENT PUBLIC PARA
111 EXTRN TRANSTART:WORD
112TAIL ENDS
113
114TRANCODE SEGMENT PUBLIC BYTE ;AC000;
115 EXTRN DATINIT:FAR
116 EXTRN printf_init:far
117TRANCODE ENDS
118
119TRANSPACE SEGMENT PUBLIC BYTE ;AC000;
120 EXTRN TRANSPACEEND:BYTE
121TRANSPACE ENDS
122
123; This is the area used for the autoexec.bat file. BATARENA is a pad for the
124; the address mark placed by DOS.
125
126BATARENA SEGMENT PUBLIC PARA
127
128 ORG 0
129 DB 10h DUP (?) ;Pad for memory allocation addr mark
130
131BATARENA ENDS
132
133BATSEG SEGMENT PUBLIC PARA ;Autoexec.bat segment
134
135 ORG 0
136 initbat batchsegment <> ;batch segment
137 DB 31 DUP (0) ;reserve area for batch file name & pad
138
139BATSEG ENDS
140
141; *******************************************************************
142; START OF INIT PORTION
143; This code is overlayed the first time the TPA is used.
144
145INIT SEGMENT PUBLIC PARA
146
147 EXTRN AUTOBAT:byte
148 EXTRN BADCSPFL:byte
149 EXTRN bslash:byte
150 EXTRN CHUCKENV:byte
151 EXTRN command_c_syn:byte ;AN000;
152 EXTRN command_d_syn:byte ;AN000;
153 EXTRN command_e_syn:byte ;AN000;
154 EXTRN command_f_syn:byte ;AN000;
155 EXTRN command_m_syn:byte ;AN000;
156 EXTRN command_p_syn:byte ;AN000;
157 EXTRN comnd1_syn:word ;AN000;
158 EXTRN comnd1_addr:dword ;AN000;
159 EXTRN COMSPECT:byte
160 EXTRN comspstring:byte
161 EXTRN dswitch:byte ;AN018;
162 EXTRN ECOMLOC:word
163 EXTRN EnvMax:WORD
164 EXTRN EnvSiz:WORD
165 EXTRN equalsign:byte
166 EXTRN eswitch:byte ;AN018;
167 EXTRN ext_msg:byte ;AN000;
168 EXTRN fslash:byte
169 EXTRN INITADD:dword
170 EXTRN initend:word
171 EXTRN init_parse:dword ;AN054;
172 EXTRN INTERNAT_INFO:BYTE ;AN000; 3/3/KK
173 EXTRN KAUTOBAT:byte ;AN000; 3/3/KK
174 EXTRN lcasea:byte
175 EXTRN lcasez:byte
176 EXTRN num_positionals:word ;AN000;
177 EXTRN oldenv:word
178 EXTRN old_parse_ptr:word ;AN057;
179 EXTRN parse_command:byte ;AN000;
180 EXTRN pars_msg_off:word ;AN060;
181 EXTRN pars_msg_seg:word ;AN060;
182 EXTRN PRDATTM:byte
183 EXTRN resetenv:word ;AC000;
184 EXTRN scswitch:byte
185 EXTRN space:byte
186 EXTRN triage_add:dword ;AC000;
187 EXTRN trnsize:word
188 EXTRN ucasea:byte
189 EXTRN usedenv:word
190
191
192;AD054; EXTRN SYSPARSE:NEAR
193
194 PUBLIC CONPROC
195 PUBLIC init_contc_specialcase
196
197ASSUME CS:RESGROUP,DS:RESGROUP,ES:RESGROUP,SS:RESGROUP
198
199 ORG 0
200ZERO = $
201
202
203CONPROC:
204 MOV SP,OFFSET RESGROUP:RSTACK ; MUST be first instruction
205
206 CALL SYSLOADMSG ;AN000; check dos version
207 JNC OKDOS ;AN000; if no problem - continue
208
209 mov ax,badver ;AN000; set DOS version
210 invoke sysdispmsg ;AN000; must be incorrect version
211 mov ax,es
212 cmp es:[PDB_Parent_PID],AX ; If command is its own parent,
213here: ; loop forever.
214 Jz here
215 int 20h ; Otherwise, exit.
216
217;
218; Turn APPEND off during initialization processing
219;
220okdos:
221 mov ax,AppendInstall ;AN042; see if append installed
222 int 2fh ;AN042;
223 cmp al,0 ;AN042; append installed?
224 je set_msg_addr ;AN042; no - continue
225 mov ax,AppendDOS ;AN042; see if append DOS version right
226 int 2fh ;AN042;
227 cmp ax,-1 ;AN042; append version correct?
228 jne set_msg_addr ;AN042; no - continue
229 mov ax,AppendGetState ;AN042; Get the state of Append
230 int 2fh ;AN042;
231 mov append_state,bx ;AN042; save append state
232 xor bx,bx ;AN042; clear out state
233 mov ax,AppendSetState ;AN042; Set the state of Append
234 int 2fh ;AN042; set everything off
235
236set_msg_addr:
237;
238; Get addresses of old critical and parse errors and save so they can
239; be reset if COMMAND needs to exit
240;
241
242 push es ;AN000; SAVE ES DESTROYED BY INT 2FH
243;AD060; mov ah,multdos ;AN000; set up to call DOS through int 2fh
244;AD060; mov al,message_2f ;AN000; call for message retriever
245 mov ax,(multdos shl 8 or message_2f);AN060; set up to call DOS through int 2fh
246 mov dl,get_parse_msg ;AN000; get parse message address
247 int 2fh ;AN000;
248 mov cs:pars_msg_seg,es ;AN000; save returned segment
249 mov cs:pars_msg_off,di ;AN000; save returned offset
250
251;AD060; mov ah,multdos ;AN000; set up to call DOS through int 2fh
252;AD060; mov al,message_2f ;AN000; call for message retriever
253 mov ax,(multdos shl 8 or message_2f);AN060; set up to call DOS through int 2fh
254 mov dl,get_critical_msg ;AN000; get critical error message address
255 int 2fh ;AN000;
256 mov cs:crit_msg_seg,es ;AN000; save returned segment
257 mov cs:crit_msg_off,di ;AN000; save returned offset
258 pop es ;AN000; RESTORE ES DESTROYED BY INT 2FH
259
260;
261; Set addresses of critical and parse errors in this level of COMMAND
262;
263
264;AD060; mov ah,multdos ;AN000; set up to call DOS through int 2fh
265;AD060; mov al,message_2f ;AN000; call for message retriever
266;AD060; mov dl,set_parse_msg ;AN000; set up parse message address
267 mov di,offset resgroup:parse_msg_start ;AN000; start address
268;AD060; int 2fh ;AN000;
269 call set_parse_2f ;AN060; set parse error address
270
271
272;AD060; mov ah,multdos ;AN000; set up to call DOS through int 2fh
273;AD060; mov al,message_2f ;AN000; call for message retriever
274 mov ax,(multdos shl 8 or message_2f);AN060; set up to call DOS through int 2fh
275 mov dl,set_critical_msg ;AN000; set up critical error message address
276 mov di,offset resgroup:critical_msg_start ;AN000; start address
277 int 2fh ;AN000;
278
279 mov di,offset resgroup:dataresend+15 ;AN000; get address of resident end
280 mov [resmsgend],di ;AN000; save it
281 call sysloadmsg ;AN000; load message addresses
282 call get_msg_ptr ;AN000; set up pointers to some translated chars
283 mov ah,GetExtCntry ;g get extended country information
284 mov al,2 ;g minor function - ucase table
285 mov dx,-1 ;g
286 mov bx,-1 ;g
287 mov cx,5 ;g number of bytes we want
288 mov di,offset resgroup:com_xlat_addr ;g buffer to put address in
289 int int_command ;g
290
291 mov ah,GetExtCntry ;AN000; get extended country info
292 mov al,4 ;AN000; get file ucase table
293 mov dx,-1 ;AN000;
294 mov bx,-1 ;AN000;
295 mov cx,5 ;AN000; number of bytes we want
296 mov di,offset resgroup:fucase_addr ;AN000; buffer for address
297 int int_command ;AN000;
298
299 mov dx,offset resgroup:transtart+15 ;eg get end of init code
300 mov cl,4 ;eg change to paragraphs
301 shr dx,cl ;eg
302 mov ax,cs ;eg get current segment
303 add ax,dx ;eg calculate segment of end of init
304 mov [initend],ax ;eg save this
305
306 push ds ;AN000;
307 mov ax, (ECS_call SHL 8) OR GetLeadBTbl ;AN000; get dbcs vector
308 int int_command ;AN000;
309 mov bx,ds ;AN000; get segment to bx
310 pop ds ;AN000;
311 mov dbcs_vector_addr,si ;AN000; save address of
312 mov dbcs_vector_addr+2,bx ;AN000; dbcs vector
313
314
315 mov ax,word ptr ds:[PDB_Parent_PID] ; Init PARENT so we can exit
316 mov [PARENT],ax ; correctly.
317 MOV AX,WORD PTR DS:[PDB_Exit]
318 MOV WORD PTR OldTerm,AX
319 MOV AX,WORD PTR DS:[PDB_Exit+2]
320 MOV WORD PTR OldTerm+2,AX
321
322 MOV AX,OFFSET RESGROUP:ENVIREND + 15
323 MOV CL,4 ; ax = size of resident part of
324 SHR AX,CL ; command in paragraphs. Add
325 MOV CX,CS ; this to CS and you get the
326 ADD AX,CX ; segment of the TPA.
327
328 MOV [RES_TPA], AX ; Temporarily save the TPA segment
329 AND AX, 0F000H
330 ADD AX, 01000H ; Round up to next 64K boundary
331 JNC TPASET ; Memory wrap if carry set
332 MOV AX, [RES_TPA]
333TPASET:
334 MOV [LTPA],AX ; Good enough for the moment
335 MOV AX,WORD PTR DS:[PDB_block_len] ; ax = # of paras given to command
336
337 MOV [MYSEG1],DS ; These 3 variables are used as part of
338 MOV [MYSEG2],DS ; 3 long ptrs that the transient will
339 MOV [MYSEG],DS ; use to call resident routines.
340 MOV [MEMSIZ],AX ; Needed for execing other programs
341;
342; Compute maximum size of environment
343;
344 MOV EnvMax,(Environsiz + 15) / 16 + (EnvMaximum-zero + 15)/16 - 1
345;
346; Compute minimum size of environment
347;
348
349 MOV EnvSiz, ENVSML / 16
350
351 MOV DX,OFFSET TRANGROUP:TRANSPACEEND + 15 ; dx = size of transient
352 MOV CL,4 ; in paragraphs.
353 SHR DX,CL
354 mov [trnsize],dx ;eg save size of transient in paragraphs
355
356 SUB AX,DX ; max seg addr - # para's needed for transient
357 MOV [TRNSEG],AX ; = seg addr to load the transient at.
358 MOV AX,DS:[PDB_environ] ; ax = environment segment
359 OR AX,AX ; If there is no environment segment,
360 JZ BUILDENV ; go compute one.
361 INC BYTE PTR [CHUCKENV] ; Flag no new ENVIRONSEG to set up
362 JMP SHORT ENVIRONPASSED ; Otherwise one was passed to us.
363
364BUILDENV: ; (this label isn't very accurate)
365 MOV AX,OFFSET RESGROUP:PATHSTRING ; Compute the segment of the
366 MOV CL,4 ; environment and put it in
367 SHR AX,CL ; ax.
368 MOV DX,DS
369 ADD AX,DX
370
371ENVIRONPASSED:
372 MOV [ENVIRSEG],AX ; Save the environment's segment and
373 MOV ES,AX ; load into es.
374ASSUME ES:ENVIRONMENT
375
376GOTTHEENVIR:
377 MOV AX,CHAR_OPER SHL 8 ; Get the switch character and store it
378 INT int_command ; in RSWITCHAR.
379 MOV [RSWITCHAR],DL
380
381 CMP DL,fslash ; If backslashes are being used as the
382 JNZ IUSESLASH ; path separator, change the forward
383 mov al,bslash ; slash in COMSPECT and ECOMSPEC (if
384 MOV [COMSPECT],al ; there is a new ENVIRONSEG) to
385 CMP BYTE PTR [CHUCKENV],0 ; backslash.
386 JNZ IUSESLASH
387 MOV ES:[ECOMSPEC],al ;eg
388
389IUSESLASH:
390;
391; Initialize the command drive
392;
393 MOV AH,Get_Default_Drive
394 INT 21h
395 INC AL
396 MOV ComDrv,AL
397
398 MOV AL,BYTE PTR DS:[FCB] ; al = default drive number for command
399 OR AL,AL
400 JZ NoComDrv ; no drive specified
401
402 MOV AH,':'
403 MOV [COMDRV],AL
404 ADD AL,40H ; Convert number to uppercase character
405
406 STD
407 CMP BYTE PTR [CHUCKENV],0 ; If a new environment is being built,
408 JNZ NOTWIDENV ; move the default comspec string in it
409 PUSH DS ; 2 bytes to make room for a drivespec.
410 PUSH ES ; The drivespec is in ax and is copied
411 POP DS ; on to the front of the string.
412 MOV DI,OFFSET ENVIRONMENT:ECOMSPEC + ENVIRONSIZ2 - 1 ;eg
413 MOV SI,OFFSET ENVIRONMENT:ECOMSPEC + ENVIRONSIZ2 - 3 ;eg
414
415 MOV CX,ENVIRONSIZ2 - 2
416 REP MOVSB
417 POP DS
418 MOV WORD PTR ES:[ECOMSPEC],AX
419
420NOTWIDENV:
421 CLD ; Add the drivespec to the string
422 MOV WORD PTR [AUTOBAT],AX ; used to reference autoexec.bat
423 MOV WORD PTR [KAUTOBAT],AX ;AN000; used to reference kautoexe.bat 3/3/KK
424
425NOCOMDRV:
426 INVOKE SETVECT ; Set interrupt vectors 22h, 23h, & 24h
427
428;*********************************
429; PARSING STARTS HERE
430;*********************************
431
432 push cs ;AN000; get local segment
433 push cs ;AN000; into DS,ES
434 pop ds ;AN000;
435 pop es ;AN000;
436
437ASSUME DS:RESGROUP,ES:RESGROUP ;AN000;
438
439 MOV SI,80H ;AC000; get command line
440 LODSB ;AC000; get length of line
441 MOV DI,SI ;AN000; get line position in DI
442 XOR AH,AH ;AC000; ax = length of command line
443;
444; Insure that the command line correctly ends with a CR
445;
446 ADD DI,AX ;AC000; go to end of command line
447 MOV BYTE PTR [DI],0Dh ;AC000; insert a carriage return
448 xor cx,cx ;AC000; clear cx
449 mov num_positionals,cx ;AC000; initialize positionals
450;
451; Scan the command line looking for the parameters
452;
453
454parse_command_line:
455 mov di,offset resgroup:parse_command;AN000; Get address of parse_command
456 mov cx,num_positionals ;AN000; Get number of positionals
457 xor dx,dx ;AN000; clear dx
458 mov old_parse_ptr,si ;AN057; save position before calling parser
459 call init_parse ;AN054; call parser
460 mov num_positionals,cx ;AN000; Save number of positionals
461 cmp ax,end_of_line ;AC000; are we at end of line?
462 jz ArgsDoneJ3 ;AC000; yes - exit
463 cmp ax,result_no_error ;AN000; did an error occur
464 jz parse_cont ;AN000; no - continue
465
466;
467; Before issuing error message - make sure switch is not /C
468;
469
470parse_line_error:
471 push si ;AN057; save line position
472 push ax ;AN057; save error number
473 cmp ax,BadSwt_Ptr ;AN057; Was error invalid switch?
474 jnz parse_line_error_disp ;AN057; No - just issue message
475 mov di,si ;AN057; Get terminating pointer in DI
476 mov si,old_parse_ptr ;AN057; Get starting pointer in SI
477
478init_chk_delim:
479 cmp si,di ;AN057; at end of parsed parameter?
480 jz parse_line_error_disp ;AN057; Yes - just display message
481 lodsb ;AN057;
482 cmp al,space ;AN057; Skip blank spaces
483 jz init_chk_delim ;AN057;
484 cmp al,tab_chr ;AN057; Skip tab characters
485 jz init_chk_delim ;AN057;
486
487 cmp al,[rswitchar] ;AN057; Switch?
488 jnz parse_line_error_disp ;AN057; No - just issue message
489 lodsb ;AN057; Get the char after the switch
490 invoke itestkanj ;AN057; Is it DBCS?
491 jnz parse_line_error_disp ;AN057; Yes - can't be /C
492 invoke iupconv ;AN057; upper case it
493 cmp al,scswitch ;AN057; it is /C?
494 jnz parse_line_error_disp ;AN057;
495 pop dx ;AN057; even up stack
496 pop dx ;AN057; even up stack
497 jmp setSSwitch ;AN057; Yes - go set COMMAND /C
498
499parse_line_error_disp:
500 pop ax ;AN057; restore error number
501 pop si ;AN057; restore line position
502 mov disp_class,parse_msg_class ;AN000; set up parse error msg class
503 mov dx,ax ;AN000; get message number
504 call print_message ;AN000; issue error message
505 jmp short parse_command_line ;AN000; continue parsing
506
507parse_cont:
508;
509; See if a switch was entered
510;
511
512 cmp comnd1_syn,offset resgroup:command_f_syn ;AC000; was /F entered?
513 jz SetFSwitch ;AC000; yes go set fail switch
514 cmp comnd1_syn,offset resgroup:command_p_syn ;AC000; was /P entered?
515 Jz SetPSwitch ;AC000; yes go set up PERMCOM
516 cmp comnd1_syn,offset resgroup:command_d_syn ;AC000; was /D entered?
517 jz SetDSwitch ;AC000; yes go set date switch
518 cmp comnd1_syn,offset resgroup:command_c_syn ;AC000; was /C entered?
519 jz SetSSwitch ;AC000; yes go set up SINGLECOM
520 cmp comnd1_syn,offset resgroup:command_e_syn ;AC000; was /E entered?
521 jz SetESwitch ;AC000; yes go set up environment
522 cmp comnd1_syn,offset resgroup:command_m_syn ;AN000; was /MSG entered?
523 jz SetMSwitchjmp ;AN000; yes go set up message flag
524 jmp chkotherargs ;AC000; Must be something else
525
526SetMSwitchjmp: ;AN018; long jump needed
527 jmp SetMswitch ;AN018;
528
529ArgsdoneJ3: ;AN018; long jump needed
530 jmp ArgsDone ;AN018;
531
532SetFSwitch:
533 cmp fFail,-1 ;AN018; has fail switch been set?
534 jnz failok ;AN018; no - set it
535 mov ax,moreargs_ptr ;AN018; set up too many arguments
536 jmp parse_line_error ;AN018; go issue error message
537
538failok:
539 MOV fFail,-1 ;AC000; fail all INT 24s.
540 JMP parse_command_line ;AC000;
541
542SetPSwitch:
543;
544; We have a permanent COMMAND switch /P. Flag this and stash the
545; termination address.
546;
547 cmp [permcom],0 ;AN018; has /p switch been set?
548 jz permcomok ;AN018; no - set it
549 mov ax,moreargs_ptr ;AN018; set up too many arguments
550 jmp parse_line_error ;AN018; go issue error message
551
552permcomok:
553 INC [PERMCOM]
554 MOV WORD PTR [oldTerm],OFFSET RESGROUP:LODCOM
555 MOV WORD PTR [oldTerm+2],DS
556;
557; Make sure that we display the date and time. If the flag was not
558; initialized, set it to indicate yes, do prompt.
559;
560 CMP BYTE PTR [PRDATTM],-1
561 JNZ parse_command_line_jmp ;AC018; keep parsing
562 MOV BYTE PTR [PRDATTM],0 ; If not set explicit, set to prompt
563
564Parse_command_line_jmp: ;AN018;
565 JMP parse_command_line ;AC000; keep parsing
566
567ArgsDoneJump:
568 JMP ArgsDone
569
570SetDSwitch:
571;
572; Flag no date/time prompting.
573;
574 cmp dswitch,0 ;AN018; has /D switch been set?
575 jz setdateok ;AN018; no - set it
576 mov ax,moreargs_ptr ;AN018; set up too many arguments
577 jmp parse_line_error ;AN018; go issue error message
578
579setdateok:
580 inc dswitch ;AN018; indicate /D entered
581 MOV BYTE PTR [PRDATTM],1 ; User explicitly says no date time
582 JMP parse_command_line ;AC000; continue parsing
583
584SetSSwitch:
585;
586; Set up pointer to command line, flag no date/time and turn off singlecom.
587;
588 MOV [SINGLECOM],SI ; Point to the rest of the command line
589 MOV [PERMCOM],0 ; A SINGLECOM must not be a PERMCOM
590 MOV BYTE PTR [PRDATTM],1 ; No date or time either, explicit
591 JMP ArgsDone
592;
593; Look for environment-size setting switch
594;
595; The environment size is represented in decimal bytes and is
596; converted into pargraphs (rounded up to the next paragraph).
597;
598
599SetESwitch:
600 cmp eswitch,0 ;AN018; has fail switch been set?
601 jz eswitchok ;AN018; no - set it
602 mov ax,moreargs_ptr ;AN018; set up too many arguments
603 jmp parse_line_error ;AN018; go issue error message
604
605eswitchok:
606 inc eswitch ;AN018; indicate /E entered
607 mov di,offset resgroup:comnd1_addr ;AN000; get number returned
608 mov bx,word ptr [di] ;AN000; into bx
609
610 ADD BX, 0FH ; Round up to next paragraph
611 mov cl,4 ;AC000; convert to pargraphs
612 SHR BX, cl ;AC000; by right 4
613
614 MOV EnvSiz,BX ; EnvSiz is in paragraphs
615 JMP parse_command_line ;AC000; continue parsing command line
616
617SetMSwitch:
618 cmp ext_msg,set_extended_msg ;AN018; has /MSG switch been set?
619 jnz setMswitchok ;AN018; no - set it
620 mov ax,moreargs_ptr ;AN018; set up too many arguments
621 jmp parse_line_error ;AN018; go issue error message
622setMswitchok:
623 MOV Ext_msg,set_extended_msg ;AN000; set /MSG switch
624 JMP parse_command_line ;AN000; keep parsing
625
626ARGSDONEJ:
627 JMP ARGSDONE
628
629;
630; We have a non-switch character here.
631;
632CHKOTHERARGS:
633 push ds ;AN054;
634 push si ;AC000; save place in command line
635 lds si,comnd1_addr ;AN000; get address of filespec
636 assume ds:nothing ;AN054;
637
638 mov dx,si ;AN000; put in dx also
639 MOV AX,(OPEN SHL 8) OR 2 ; Read and write
640 INT int_command
641 JC CHKSRCHSPEC ; Wasn't a file
642 MOV BX,AX
643 MOV AX,IOCTL SHL 8
644 INT int_command
645 TEST DL,80H
646 JNZ ISADEVICE
647
648BADSETCON: ;AN022;
649 MOV AH,CLOSE ; Close initial handle, wasn't a device
650 INT int_command
651 JMP CHKSRCHSPEC
652
653ISADEVICE:
654 XOR DH,DH
655 OR DL,3 ; Make sure has CON attributes
656 MOV AX,(IOCTL SHL 8) OR 1
657 INT int_command
658 JC BADSETCON ;AN022; Can't set attributes - quit
659 MOV DX,BX ; Save new handle
660;eg POP BX ; Throw away saved SI
661;eg POP BX ; Throw away saved CX
662 PUSH CX
663 MOV CX,3
664 XOR BX,BX
665
666RCCLLOOP: ; Close 0,1 and 2
667 MOV AH,CLOSE
668 INT int_command
669 INC BX
670 LOOP RCCLLOOP
671 MOV BX,DX ; New device handle
672 MOV AH,XDUP
673 INT int_command ; Dup to 0
674 MOV AH,XDUP
675 INT int_command ; Dup to 1
676 MOV AH,XDUP
677 INT int_command ; Dup to 2
678 MOV AH,CLOSE
679 INT int_command ; Close initial handle
680 POP CX
681 pop si ;AN000; restore position of command line
682 pop ds ;AN054;
683 JMP parse_command_line ;AC000; continue parsing
684
685CHKSRCHSPEC: ; Not a device, so must be directory spec
686
687 MOV BYTE PTR [CHUCKENV],0 ; If search specified -- no inheritance
688 MOV AX,OFFSET RESGROUP:PATHSTRING ; Figure environment pointer
689 MOV CL,4
690 SHR AX,CL
691;AD054; MOV DX,DS
692 MOV DX,CS ;AC054;
693 ADD AX,DX
694 MOV [ENVIRSEG],AX
695
696 MOV ES,AX
697 push si ;AN000; remember location of file
698 xor cx,cx ;AN000; clear cx for counting
699
700countloop:
701 lodsb ;AN000; get a character
702 inc cx ;AN000; increment counter
703 cmp al,end_of_line_out ;AN000; are we at end of line?
704 jnz countloop ;AN000; no - keep counting
705
706 mov al,space
707 dec si ;AN000; move back one
708 MOV BYTE PTR [SI],al ;AN000; put a space at end of line
709 pop si ;AC000; get location back
710
711 MOV DI,[ECOMLOC]
712
713COMTRLOOP:
714 LODSB
715 DEC CX
716 CMP AL,space
717 JZ SETCOMSR
718 STOSB
719
720;;; IF KANJI 3/3/KK
721 XOR AH,AH
722;;; ENDIF 3/3/KK
723
724 JCXZ SETCOMSR
725
726;;;; IF KANJI 3/3/KK
727 PUSH DS ;AN054; Make sure we have
728 PUSH CS ;AN054; local DS for
729 POP DS ;AN054; ITESTKANJ
730 INVOKE ITESTKANJ
731 POP DS ;AN054; restore PARSER DS
732 JZ COMTRLOOP
733 DEC CX
734 MOVSB
735 INC AH
736 JCXZ SETCOMSR
737;;;; ENDIF 3/3/KK
738
739 JMP SHORT COMTRLOOP
740
741SETCOMSR:
742 PUSH CX
743
744 PUSH CS ;AN054; Get local segment
745 POP DS ;AN054;
746 assume ds:resgroup ;AN054;
747
748 PUSH DS
749 MOV SI,OFFSET RESGROUP:COMSPECT
750 MOV CX,14
751
752 MOV AL,ES:[DI-1]
753
754;;;; IF KANJI 3/3/KK
755 OR AH,AH
756 JNZ INOTROOT ; Last char was KANJI second byte, might be '\'
757;;;; ENDIF 3/3/KK
758
759 CALL PATHCHRCMPR
760 JNZ INOTROOT
761 INC SI ; Don't make a double /
762 DEC CX
763
764INOTROOT:
765 REP MOVSB
766
767 MOV DX,[ECOMLOC] ; Now lets make sure its good!
768 PUSH ES
769 POP DS
770
771 MOV AX,OPEN SHL 8
772 INT int_command ; Open COMMAND.COM
773 POP DS
774 JC SETCOMSRBAD ; No COMMAND.COM here
775 MOV BX,AX ; Handle
776 MOV AH,CLOSE
777 INT int_command ; Close COMMAND.COM
778
779SETCOMSRRET:
780 POP CX
781 POP SI
782 POP DS ;AN054;
783 assume ds:resgroup ;AN054;
784
785ARGSDONEJ2:
786 PUSH CS ;AN000; Make sure local ES is
787 POP ES ;AN000; restored
788 JMP parse_command_line ;AC000; continue parsing command line
789
790SETCOMSRBAD:
791 MOV DX,BADCOMLKMES_ptr ;AC000; get message number
792 invoke triageError
793 cmp ax, 65
794 jnz doprt
795 mov dx,BADCOMACCMES_ptr ;AC000; get error message number
796doprt:
797 call print_message
798 MOV SI,OFFSET RESGROUP:COMSPECT
799 MOV DI,[ECOMLOC]
800 MOV CX,14
801 REP MOVSB ; Get my default back
802
803 JMP SHORT SETCOMSRRET
804
805;*********************************
806; PARSING ENDS HERE
807;*********************************
808
809ARGSDONE:
810 mov es,[envirseg] ;AC000; get environment back
811 ASSUME ES:ENVIRONMENT ;AN000;
812;AD060; cmp ext_msg,set_extended_msg ;AN000; was /msg specified?
813;AD060; jnz check_permcom ;AN000; No, go check permcom
814;AD060; cmp [permcom],0 ;AN000; Yes - was permcom set?
815;AD060; jz permcom_error ;AN000; No - error cannot have /MSG without /P
816
817;AD060; mov ah,multdos ;AN000; set up to call DOS through int 2fh
818;AD060; mov al,message_2f ;AN000; call for message retriever
819;AD060; mov dl,set_extended_msg ;AN000; set up extended error message address
820;AD060; push es ;AN016; save environment segment
821;AD060; push cs ;AN016; get local segment to ES
822;AD060; pop es ;AN016;
823;AD060; mov di,offset resgroup:extended_msg_start ;AN000; start address
824;AD060; int 2fh ;AN000;
825;AD060; pop es ;AN016; restore environment segment
826;AD060; mov di,offset resgroup:extmsgend+15 ;AN000; get address of resident end
827;AD060; mov [resmsgend],di ;AN000; save it
828;AD060; call sysloadmsg ;AN000; load message addresses
829;AD060; jmp short process_permcom ;AN000; now go process /P switch
830
831;AD060;permcom_error:
832;AD060; mov disp_class,parse_msg_class ;AN000; set up parse error msg class
833;AD060; mov dx,LessArgs_Ptr ;AN000; get message number for "Required parameter missing"
834;AD060; call print_message ;AN000; issue error message
835;AD060; jmp short comreturns ;AN000; we already know /P wasn't entered
836
837;AD060;check_permcom:
838 CMP [PERMCOM],0
839 JZ COMRETURNS
840
841;AD060;process_permcom:
842 PUSH ES ; Save environment pointer
843 MOV AH,SET_CURRENT_PDB
844 MOV BX,DS
845 MOV ES,BX
846 INT int_command ; Current process is me
847 MOV DI,PDB_Exit ; Diddle the addresses in my header
848 MOV AX,OFFSET RESGROUP:LODCOM
849 STOSW
850 MOV AX,DS
851 STOSW
852 MOV AX,OFFSET RESGROUP:CONTC
853 STOSW
854 MOV AX,DS
855 STOSW
856 MOV AX,OFFSET RESGROUP:DskErr
857 STOSW
858 MOV AX,DS
859 STOSW
860 MOV WORD PTR DS:[PDB_Parent_PID],DS ; Parent is me forever
861
862 MOV DX,OFFSET RESGROUP:INT_2E
863 MOV AX,(SET_INTERRUPT_VECTOR SHL 8) OR 02EH
864 INT int_command ;Set magic interrupt
865 POP ES ;Remember environment
866
867COMRETURNS:
868 MOV AX,WORD PTR DS:[PDB_Parent_PID]
869 MOV [PARENT],AX ; Save parent
870 MOV WORD PTR DS:[PDB_Parent_PID],DS ; Parent is me
871 MOV AX,WORD PTR DS:[PDB_JFN_Table]
872 MOV [IO_SAVE],AX ; Get the default stdin and out
873 MOV WORD PTR [COM_PTR+2],DS ; Set all these to resident
874 MOV WORD PTR [COM_FCB1+2],DS
875 MOV WORD PTR [COM_FCB2+2],DS
876 MOV DI,OFFSET RESGROUP:COMSPEC
877
878 MOV SI,[ECOMLOC]
879 CMP BYTE PTR [CHUCKENV],0
880
881 MOV AX,DS ; XCHG ES,DS
882 PUSH ES
883 POP DS
884 MOV ES,AX
885
886 JZ COPYCOMSP ; All set up for copy
887
888 PUSH CS
889 POP DS
890
891 MOV SI,OFFSET RESGROUP:COMSPSTRING
892 PUSH ES
893 PUSH DI
894 CALL IFINDE
895 MOV SI,DI
896 PUSH ES
897 POP DS
898 POP DI
899 POP ES
900 JNC COPYCOMSP
901
902COMSPECNOFND:
903 MOV SI,CS:[ECOMLOC] ;AC062
904 ADD SI,OFFSET RESGROUP:PATHSTRING
905 PUSH CS
906 POP DS
907
908assume es:resgroup
909COPYCOMSP:
910 mov es:comspec_print,di ; Save ptr to beginning of comspec path
911 cmp byte ptr [si+1],':' ; Is there a drive specifier in comspec
912 jnz COPYCOMSPLOOP ; If not, do not skip over first 2 bytes
913 add es:comspec_print,2
914
915COPYCOMSPLOOP:
916 LODSB
917 STOSB
918 OR AL,AL
919 JNZ COPYCOMSPLOOP
920 mov es:comspec_end,di ; Save ptr to end of comspec path
921 dec es:comspec_end
922 mov ah,es:comdrv
923 add ah,'A'-1
924 mov es:cpdrv,ah ; Load drive letter in comprmt2
925assume es:environment
926
927 call setup_for_messages ;AN060; set up parse and extended error messages
928 PUSH CS
929 POP DS
930 MOV BX,[RESMSGEND] ;AC000; get end of resident
931 MOV CL,4
932 SHR BX,CL
933Public EnvMaximum
934EnvMaximum:
935;
936; NOTE: The transient has to loaded directly after shrinking to the
937; resident size.
938; There is an assumption made when loading the transient that it
939; still intact after the resident portion.
940; If any other ALLOC/DEALLOC/SETBLOCK operations are performed
941; inbetween, then there is a real good chance that the non-resident
942; portion will be overwritten by arena information.
943;
944 MOV AH,SETBLOCK
945 INT int_command ; Shrink me to the resident only
946;
947; Load in the transient and compute the checksum. We may do this in one of
948; two ways: First, cheat and use the transient loading code that exists in
949; the resident piece. This may be OK except that it will hit the disk.
950;
951; But we do not need to hit the disk! The transient is already loaded but is
952; in the wrong place. We need to block transfer it up to the correct spot.
953;
954GOTENVIR:
955 MOV TrnMvFlg, 1 ; Indicate that transient has been moved
956 PUSH ES
957 MOV SI,OFFSET RESGroup:TranStart
958 MOV DI,0
959 mov ES,Trnseg
960 MOV CX,OFFSET TRANGROUP:TRANSPACEEND
961;
962; We need to ensure that we do not have the potential of overwriting our
963; existing code in this move
964; It is OK to move if (SI+CX+Segment of Transient < TrnSeg).
965;
966 push cx
967 mov ax,cx ; Get size of transient in bytes
968 add ax,si ; Calculate end of transient section
969 mov cl,4
970 shr ax,cl ; Convert to paragraphs
971 inc ax ; Round up (for partial paragraph)
972 mov cx,ds
973 add ax,cx ; Add in current segment
974 cmp ax,Trnseg ; See if there is overlap
975 pop cx
976; If we are too close to be safe, call LOADCOM instead of moving the code.
977 jb Ok_To_Move
978 invoke LOADCOM
979 jmp short Trans_Loaded
980Ok_To_Move:
981;
982; Everything is set for an upward move. WRONG! We must move downward.
983;
984 ADD SI,CX
985 DEC SI
986 ADD DI,CX
987 DEC DI
988 STD
989 REP MOVSB
990 CLD
991
992Trans_Loaded:
993 POP ES
994
995 INVOKE CHKSUM ; Compute the checksum
996 MOV [SUM],DX ; Save it
997
998 CMP BYTE PTR [PRDATTM],0 ;eg
999 JNZ NOBATCHSEG ;eg Don't do AUTOEXEC or date time
1000;
1001; Allocate batch segment for D:/autoexec.bat + no arguments
1002;
1003 MOV BX,((SIZE BatchSegment) + 15 + 1 + 0Fh)/16 ;eg
1004 MOV AH,ALLOC ;eg
1005 INT int_command ;eg
1006 JC NOBATCHSEG ;eg didn't allocate - pretend no batch
1007 MOV BATCH,AX ;eg save batch segment
1008
1009NOBATCHSEG:
1010 MOV BX, 0FFFFH ; Get size of largest block for env
1011 MOV AH, ALLOC
1012 INT int_command
1013
1014; Only allocate maximum 64K worth of environment
1015
1016 SUB BX,TRNSIZE ;eg subtract # of transient paragraphs
1017 SUB BX,128 ;eg make sure we have 2K left
1018 MOV EnvMax, BX
1019 CMP BX, 4096 ; 64K = 4096 paragraphs
1020 JB MAXOK
1021 MOV BX, 4096-1
1022 MOV EnvMax, BX
1023MAXOK:
1024
1025 MOV AH, ALLOC ; Get max size
1026 INT int_command
1027
1028 mov bx,[envirseg] ;g get old environment segment
1029 mov oldenv,bx ;g save it
1030 mov usedenv,0 ;g initialize env size counter
1031 MOV DS,bx
1032 ASSUME DS:NOTHING
1033 MOV [ENVIRSEG],AX
1034 MOV ES,AX
1035 XOR SI,SI
1036 MOV DI,SI
1037 MOV BX,EnvMax ; Copy over as much of the environment
1038 ; as possible
1039 SHL BX,1
1040 SHL BX,1
1041 SHL BX,1
1042 SHL BX,1
1043 MOV EnvMax, BX ; Convert EnvMax to bytes
1044 DEC BX ; Dec by one to leave room for double 0
1045 XOR DX,DX ; Use DX to indicate that there was
1046 ; no environment size error.
1047Public Nxtstr
1048Nxtstr:
1049 CALL GetStrLen ; Get the size of the current env string
1050 push ds ;g get addressability to environment
1051 push cs ;g counter
1052 pop ds ;g
1053 ASSUME DS:RESGROUP
1054 add usedenv,cx ;g add the string length to env size
1055 pop ds ;g
1056 ASSUME DS:NOTHING
1057 CMP CX,1 ; End of environment was encountered.
1058 JZ EnvExit
1059 SUB BX,CX
1060 JAE OKCpyStr ; Can't fit in all of enviroment.
1061 INC DX ; Out of env space msg must be displayed
1062 JMP EnvExit
1063OKCpyStr:
1064 JMP Nxtstr
1065EnvExit:
1066
1067 PUSH CS
1068 POP DS
1069 ASSUME DS:RESGroup
1070 OR DX,DX ; DX will be non-zero if error
1071 JZ EnvNoErr
1072 MOV DX,OUTENVERR_ptr ;AC000; get message number
1073 call print_message
1074
1075EnvNoErr:
1076 ; BX now has the left over size of the maximum environment
1077 ; We want to shrink the environment down to the minimum size
1078 ; Set the environment size to max(Envsiz,Env used)
1079
1080 MOV CX, EnvMax
1081 SUB CX, BX ; CX now has the environment used
1082 ADD CX, 16 ; Round up to next paragraph
1083 SHR CX, 1
1084 SHR CX, 1
1085 SHR CX, 1
1086 SHR CX, 1
1087 CMP CX, Envsiz ; Is environment used > Envsiz
1088 JB EnvSet
1089 MOV Envsiz, CX
1090EnvSet:
1091 MOV BX, Envsiz ; Set environment to size needed
1092 mov ax,es ;eg get environment segment
1093 add ax,bx ;eg add number of environment paragraphs
1094 cmp ax,initend ;eg does this go past end of init?
1095 ja envsetok ;eg yes - do the setblock
1096 mov ax,es ;eg no - get back the environment segment
1097 mov bx,initend ;eg get the segment at end of init
1098 sub bx,ax ;eg setblock envir segment to end of init code
1099 mov resetenv,1 ;eg set flag so we know to set envir later
1100
1101envsetok:
1102 MOV AH, SETBLOCK
1103 INT int_command
1104
1105 IF MSVER
1106 CMP [SINGLECOM],0
1107 JNZ NOPHEAD ; Don't print header if SINGLECOM
1108 MOV DX,HEADER_ptr ;AC000; get message number
1109 call print_message
1110NOPHEAD:
1111 ENDIF
1112
1113 CMP [BATCH],0 ;eg did we set up a batch segment?
1114 JNZ dodate ;eg yes - go initialize it
1115 JMP NODTTM ; Don't do AUTOEXEC or date time
1116;
1117; Allocate batch segment for D:/autoexec.bat + no arguments
1118;
1119dodate:
1120 MOV AX,BATCH ;eg get batch segment
1121 MOV EchoFlag,3 ; set batch echo
1122 MOV NEST,1 ; g set nest flag to 1 batch
1123 MOV ES,AX
1124;
1125; Initialize the segment
1126;
1127 XOR DI,DI
1128 MOV AL,BatchType
1129 STOSB
1130 MOV AL,1 ; G initialize echo for batch exit
1131 STOSB ; G
1132 XOR AX,AX ; initialize to zero
1133 STOSW ; G batch segment of last job - batlast
1134 STOSW ; G segment for FOR
1135 STOSB ; G FOR flag
1136 STOSW ; position in file - batseek
1137 STOSW
1138;
1139; Clean out the parameters
1140;
1141 MOV AX,-1 ; initialize to no parameters
1142 MOV CX,10
1143 REP STOSW
1144;
1145; Decide whether we should grab the default drive
1146;
1147 CMP BYTE PTR [AUTOBAT],0
1148
1149 JNZ NOAUTSET
1150 MOV AH,GET_DEFAULT_DRIVE
1151 INT int_command
1152 ADD AL,ucasea
1153
1154 MOV [AUTOBAT],AL
1155 MOV [KAUTOBAT],AL ;AN000; 3/3/KK
1156
1157NOAUTSET:
1158;
1159; Copy in the batch file name (including NUL)
1160;
1161 MOV SI,OFFSET RESGROUP:AUTOBAT
1162 MOV CX,8
1163 REP MOVSW
1164 MOVSB ;AN027; move in carraige return to terminate string
1165
1166 MOV DX,OFFSET RESGROUP:AUTOBAT
1167 MOV AX,OPEN SHL 8
1168 INT int_command ; See if AUTOEXEC.BAT exists
1169 JC NOABAT
1170 MOV BX,AX
1171 MOV AH,CLOSE
1172 INT int_command
1173 JMP DRV0 ;AC000; go process autoexec
1174
1175NOABAT:
1176 push ax
1177 call setup_seg
1178 mov word ptr [triage_add+2],ax
1179 pop ax
1180 call triage_add
1181 cmp ax, 65
1182 jz AccDenErr ;AN000; was network access denied
1183
1184
1185; If AUTOEXEC.BAT is not found, then check for KAUTOEXE.BAT. Changed
1186; by Ellen to check only when in Korea. The country information
1187; returned will overlay the old parse data area, but we don't care
1188; since we won't need the parse information or country information.
1189; We only care about the country code returned in BX.
1190
1191 MOV DX,OFFSET RESGROUP:INTERNAT_INFO ;AN000; Set up internat vars
1192 MOV AX,INTERNATIONAL SHL 8 ;AN000; get country dependent info
1193 INT 21H ;AN000;
1194 JC NOKABAT ;AN000; Error - don't bother with it
1195 CMP BX,KOREA_COUNTRY_CODE ;AN000; Are we speaking Korean?
1196 JNZ OPENERR ;AN000; No, don't check for KAUTOEXE
1197
1198 MOV DI, OFFSET BatFile ;AN000; 3/3/KK
1199 MOV SI,OFFSET RESGROUP:KAUTOBAT ;AN000; Another trial to do 3/3/KK
1200 MOV CX,8 ;AN000; auto execution for the 3/3/KK
1201 REP MOVSW ;AN000; non-English country 3/3/KK
1202 MOVSB ;AN027; move in carraige return to terminate string
1203 MOV DX,OFFSET RESGROUP:KAUTOBAT ;AN000; 3/3/KK
1204 MOV AX,OPEN SHL 8 ;AN000; 3/3/KK
1205 INT int_command ;AN000; See if KAUTOEXE.BAT exists 3/3/KK
1206 JC NOKABAT ;AN000; 3/3/KK
1207 MOV BX,AX ;AN000; 3/3/KK
1208 MOV AH,CLOSE ;AN000; 3/3/KK
1209 INT int_command ;AN000; 3/3/KK
1210 JMP SHORT DRV0 ;AN000; 3/3/KK
1211
1212NOKABAT: ;AN000; 3/3/KK
1213 call triage_add ;AN000; get extended error
1214 cmp ax, 65 ;AN000; network access denied?
1215 jnz openerr ;AN000; no - go deallocate batch
1216
1217AccDenErr: ;AN000; yes - put out message
1218 mov DX,ACCDEN ;AC000; get message number
1219 call print_message
1220
1221openerr:
1222 MOV ES,[BATCH] ; Not found--turn off batch job
1223 MOV AH,DEALLOC
1224 INT int_command
1225 MOV [BATCH],0 ; AFTER DEALLOC in case of ^C
1226 MOV EchoFlag,1
1227 mov nest,0 ;g indicate no batch in progress
1228
1229DODTTM:
1230 MOV AX,OFFSET TRANGROUP:DATINIT
1231 MOV WORD PTR[INITADD],AX
1232 MOV AX,[TRNSEG]
1233 MOV WORD PTR[INITADD+2],AX
1234 CALL DWORD PTR [INITADD]
1235
1236NODTTM:
1237
1238 IF IBMVER
1239 CMP [SINGLECOM],0
1240 JNZ DRV0 ; Don't print header if SINGLECOM
1241 MOV DX,HEADER_ptr ;AC000; get message number
1242 call print_message
1243 ENDIF
1244
1245DRV0: ; Reset APPEND state
1246 push ds ;AN042; save data segment
1247 push cs ;AN042; Get local segment into DS
1248 pop ds ;AN042;
1249 mov ax,AppendSetState ;AN042; Set the state of Append
1250 mov bx,Append_state ;AN042; back to the original state
1251 int 2fh ;AN042;
1252 pop ds ;AN042; get data segment back
1253 JMP ENDINIT ;G Finish initializing
1254
1255;
1256; Get length of string pointed to by DS:SI. Length includes NULL.
1257; Length is returned in CX
1258;
1259GetStrLen:
1260 xor cx,cx
1261NxtChar:
1262 lodsb
1263 inc cx
1264 or al,al
1265 jnz NxtChar
1266 ret
1267;
1268; If the transient has been loaded in TranSeg, then we need to use that
1269; segment for calls to routines in the transient area. Otherwise, the current
1270; code segment is used
1271; Segment returned in AX.
1272;
1273setup_seg:
1274 mov ax,[trnseg]
1275 cmp TrnMvFlg, 1 ; Has transient portion been moved
1276 jz setup_end
1277 push bx
1278 mov bx,cs
1279 mov ax,OFFSET RESGroup:TranStart
1280 shr ax,1
1281 shr ax,1
1282 shr ax,1
1283 shr ax,1
1284 add ax,bx
1285 pop bx
1286setup_end:
1287 ret
1288
1289print_message:
1290 push ax
1291 PUSH DS ;AN000; save data and extra segment
1292 PUSH ES ;AN000; registers
1293 MOV AX,CS ;AN000; get local segment
1294 MOV ES,AX ;AN000; set ES and DS to point to it
1295 MOV DS,AX ;AN000;
1296;AD054; PUSH BX ;AC000; save BX register
1297;AD054; PUSH CX ;AC000; save CX register
1298;AD054; PUSH DX ;AC000; save DX register
1299;AD054; MOV AX,DX ;AC000; get message number
1300;AD054; MOV DH,DISP_CLASS ;AC000; get display class
1301;AD054; MOV DL,NO_CONT_FLAG ;AN000; set control flags off
1302;AD054; MOV BX,NO_HANDLE_OUT ;AC000; set message handler to use function 1-12
1303;AD054; XOR CH,CH ;AC000; clear upper part of cx
1304;AD054; MOV CL,NUMBER_SUBST ;AC000; set number of substitutions
1305;AD054; invoke SYSDISPMSG ;AC000; display the message
1306;AD054; MOV DISP_CLASS,UTIL_MSG_CLASS ;AC000; reset display class
1307;AD054; MOV NUMBER_SUBST,NO_SUBST ;AC000; reset number of substitutions
1308;AD054; POP DX ;AC000; restore registers
1309;AD054; POP CX ;AC000;
1310;AD054; POP BX ;AC000;
1311 invoke rprint ;AC054;
1312
1313 POP ES ;AN000;
1314 POP DS ;AN000;
1315 pop ax
1316 ret
1317
1318PATHCHRCMPR:
1319 push dx
1320 mov dl,fslash
1321 CMP [RSWITCHAR],dl
1322 JZ RNOSLASHT
1323 CMP AL,dl
1324 JZ RET41
1325RNOSLASHT:
1326 CMP AL,bslash
1327RET41:
1328 pop dx
1329 RET
1330
1331
1332IFINDE:
1333 CALL IFIND ; FIND THE NAME
1334 JC IFIND2 ; CARRY MEANS NOT FOUND
1335 JMP ISCASB1 ; SCAN FOR = SIGN
1336;
1337; On return of FIND1, ES:DI points to beginning of name
1338;
1339IFIND:
1340 CLD
1341 CALL ICOUNT0 ; CX = LENGTH OF NAME
1342 MOV ES,[ENVIRSEG]
1343 XOR DI,DI
1344
1345IFIND1:
1346 PUSH CX
1347 PUSH SI
1348 PUSH DI
1349
1350IFIND11:
1351 LODSB
1352
1353;;;; IF KANJI 3/3/KK
1354 INVOKE ITESTKANJ
1355 JZ NOTKANJ4
1356 DEC SI
1357 LODSW
1358 INC DI
1359 INC DI
1360 CMP AX,ES:[DI-2]
1361 JNZ IFIND12
1362 DEC CX
1363 LOOP IFIND11
1364 JMP SHORT IFIND12
1365
1366NOTKANJ4:
1367;;;; ENDIF 3/3/KK
1368
1369 CALL IUPCONV
1370 INC DI
1371 CMP AL,ES:[DI-1]
1372 JNZ IFIND12
1373 LOOP IFIND11
1374
1375IFIND12:
1376 POP DI
1377 POP SI
1378 POP CX
1379 JZ IFIND2
1380 PUSH CX
1381 CALL ISCASB2 ; SCAN FOR A NUL
1382 POP CX
1383 CMP BYTE PTR ES:[DI],0
1384 JNZ IFIND1
1385 STC ; INDICATE NOT FOUND
1386
1387IFIND2:
1388 RET
1389
1390ICOUNT0:
1391 PUSH DS
1392 POP ES
1393 MOV DI,SI
1394
1395 PUSH DI ; COUNT NUMBER OF CHARS UNTIL "="
1396 CALL ISCASB1
1397 JMP SHORT ICOUNTX
1398 PUSH DI ; COUNT NUMBER OF CHARS UNTIL NUL
1399 CALL ISCASB2
1400
1401ICOUNTX:
1402 POP CX
1403 SUB DI,CX
1404 XCHG DI,CX
1405 RET
1406
1407ISCASB1:
1408 MOV AL,equalsign ; SCAN FOR AN =
1409 JMP SHORT ISCASBX
1410
1411ISCASB2:
1412 XOR AL,AL ; SCAN FOR A NUL
1413
1414ISCASBX:
1415 MOV CX,100H
1416 REPNZ SCASB
1417 RET
1418
1419
1420; ****************************************************************
1421; *
1422; * ROUTINE: IUPCONV (ADDED BY EMG 4.00)
1423; *
1424; * FUNCTION: This routine returns the upper case equivalent of
1425; * the character in AL from the file upper case table
1426; * in DOS if character if above ascii 128, else
1427; * subtracts 20H if between "a" and "z".
1428; *
1429; * INPUT: DS set to resident
1430; * AL char to be upper cased
1431; * FUCASE_ADDR set to the file upper case table
1432; *
1433; * OUTPUT: AL upper cased character
1434; *
1435; ****************************************************************
1436
1437assume ds:resgroup ;AN000;
1438
1439iupconv proc near ;AN000;
1440
1441 cmp al,80h ;AN000; see if char is > ascii 128
1442 jb other_fucase ;AN000; no - upper case math
1443 sub al,80h ;AN000; only upper 128 chars in table
1444 push ds ;AN000;
1445 push bx ;AN000;
1446 lds bx,dword ptr fucase_addr+1 ;AN000; get table address
1447 add bx,2 ;AN000; skip over first word
1448 xlat ds:byte ptr [bx] ;AN000; convert to upper case
1449 pop bx ;AN000;
1450 pop ds ;AN000;
1451 jmp short iupconv_end ;AN000; we finished - exit
1452
1453other_fucase: ;AN000;
1454 cmp al,lcasea ;AC000; if between "a" and "z",
1455 jb iupconv_end ;AC000; subtract 20h to get
1456 cmp al,lcasez ;AC000; upper case equivalent.
1457 ja iupconv_end ;AC000;
1458 sub al,20h ;AC000; Change lower-case to upper
1459
1460iupconv_end: ;AN000;
1461 ret
1462
1463iupconv endp ;AN000;
1464
1465init_contc_specialcase:
1466 ; This routine is called if control-C
1467 add sp,6 ; is type during the date/time prompt
1468 push si ; at initialization time. The desired
1469 mov si,dx ; response is to make it look like the
1470 mov word ptr [si+1],0d00h ; user typed <CR> by "popping" the
1471 pop si ; INT 21h stuff off the stack, putting
1472 iret ; a <CR> in the user's buffer, and
1473 ; returning directly to the user.
1474 ; In this case the user is TCODE.
1475
1476; ****************************************************************
1477; *
1478; * ROUTINE: GET_MSG_PTR
1479; *
1480; * FUNCTION: Fill in translatable char table starting at
1481; * at Abort_char with translated characters.
1482; Set segments of resident messages.
1483; *
1484; * INPUT: none
1485; *
1486; * OUTPUT: none
1487; *
1488; ****************************************************************
1489
1490CHAR_START EQU 201 ;AN000; first character translate is 1
1491CHAR_END EQU 207 ;AN000; last is 6
1492
1493GET_MSG_PTR PROC NEAR ;AN000;
1494
1495 MOV AX,CHAR_START ;AN000; get first char translation
1496 MOV BX,OFFSET RESGROUP:ABORT_CHAR ;AN000; get first char offset
1497MOVEMES: ;AN000;
1498 MOV DH,-1 ;AN000; utility message
1499 INVOKE SYSGETMSG ;AN000; get the offset of the char
1500 MOV CL,BYTE PTR [SI] ;AN000; get the character in CL
1501 MOV BYTE PTR [BX],CL ;AN000; put the character in the table
1502 INC BX ;AN000; point to next position in table
1503 INC AX ;AN000; increment message number
1504 CMP AX,CHAR_END ;AN000; are we at the end?
1505 JNZ MOVEMES ;AN000; no - keep loading
1506
1507 MOV AX,DS ;AN000; get data segment
1508 MOV DRVNUM_OP_SEG,AX ;AN000; set up segments for
1509 MOV DRVNUM_OP_SEG2,AX ;AN000; message substitutions
1510 MOV DEVE_OP_SEG,AX ;AN000; used in the resident
1511 MOV DEVE_OP_SEG2,AX ;AN000; portion of command
1512 MOV ERR15_OP_SEG,AX ;AN000; during initialization
1513 MOV ERR15_OP_SEG2,AX ;AN000; to save resident
1514 MOV ERR15_OP_SEG3,AX ;AN000; space.
1515 MOV BADFAT_OP_SEG,AX ;AN000;
1516 MOV COMPRMT1_SEG,AX ;AN000;
1517 MOV COMPRMT1_SEG2,AX ;AN000;
1518
1519 RET ;AN000;
1520
1521GET_MSG_PTR ENDP ;AN000;
1522
1523
1524; ****************************************************************
1525; *
1526; * ROUTINE: Setup_for_messages
1527; *
1528; * FUNCTION: Sets up system for PARSE and EXTENDED ERROR
1529; * messages as follows:
1530; *
1531; * IF /P and /MSG are entered
1532; * keep PARSE and EXTENDED ERRORS in memory
1533; * ELSE IF /P is entered
1534; * use PARSE and EXTENDED ERRORS on disk
1535; * remove PARSE ERRORS from memory
1536; * ELSE
1537; * remove PARSE ERRORS from memory
1538; * ENDIF
1539; *
1540; * INPUT: PERMCOM Set up with user input
1541; * EXT_MSG Set up with user input
1542; * System set up to retain PARSE ERRORS
1543; *
1544; * OUTPUT: registers unchanged
1545; *
1546; ****************************************************************
1547
1548
1549setup_for_messages proc near ;AN060;
1550
1551 push ds ;AN060; save data segment
1552 push es ;AN060; save environment segment
1553 push ax ;AN060;
1554 push dx ;AN060;
1555 push di ;AN060;
1556 mov ax,cs ;AN060; get local segment to ES and DS
1557 mov ds,ax ;AN060;
1558 mov es,ax ;AN060;
1559
1560 cmp [permcom],0 ;AN060; was permcom set?
1561 jz no_permcom ;AN060; No - don't worry about messages
1562 cmp ext_msg,set_extended_msg ;AN060; was /msg specified?
1563 jz permcom_slash_msg ;AN060; Yes - go process it
1564 push es ;AN060;
1565 mov ax,1 ;AN060; Set ES to 1 as a flag to the message
1566 mov es,ax ;AN060; services that messages are on disk
1567 mov di,offset resgroup:extended_msg_start-100h ;AN060; start address
1568 call set_ext_2f ;AN060; set extended error address
1569 mov di,offset resgroup:parse_msg_start-0100h ;AN060; start address
1570 call set_parse_2f ;AN060; set parse error address
1571 pop es ;AN060;
1572 IF2 ;AN060;;
1573 IFNDEF READ_DISK_INFO ;AN060;;
1574 Extrn READ_DISK_PROC:Far ;AN060;;
1575 ENDIF ;AN060;;
1576 ENDIF ;AN060;;
1577 MOV AX,DOS_GET_EXT_PARSE_ADD ;AN060;; 2FH Interface
1578 MOV DL,DOS_SET_ADDR ;AN060;; Set the READ_DISK_PROC address
1579 LEA DI,READ_DISK_PROC ;AN060;;
1580 INT 2FH ;AN060;; Private interface
1581 jmp short permcom_end ;AN060; and exit
1582
1583permcom_slash_msg: ;AN060; Keep messages in memory
1584 mov di,offset resgroup:extended_msg_start ;AN060; start address
1585 call set_ext_2f ;AN060; set the extended message address
1586 mov di,offset resgroup:extmsgend+15 ;AN060; get address of resident end
1587 mov [resmsgend],di ;AN060; save it
1588 jmp short permcom_end ;AN060; exit
1589
1590no_permcom: ;AN060;
1591 cmp ext_msg,set_extended_msg ;AN060; was /msg specified?
1592 jnz no_slash_msg ;AN060; no - no error
1593 mov disp_class,parse_msg_class ;AN060; set up parse error msg class
1594 mov dx,LessArgs_Ptr ;AN060; get message number for "Required parameter missing"
1595 call print_message ;AN060; issue error message
1596
1597no_slash_msg:
1598 mov ax,(multdos shl 8 or message_2f);AN060; reset parse message pointers
1599 mov dl,set_parse_msg ;AN060; set up parse message address
1600 mov di,pars_msg_off ;AN060; old offset of parse messages
1601 mov es,pars_msg_seg ;AN060; old segment of parse messages
1602 int 2fh ;AN060; go set it
1603
1604permcom_end:
1605 call sysloadmsg ;AN060; load message addresses
1606 pop di ;AN060;
1607 pop dx ;AN060;
1608 pop ax ;AN060;
1609 pop es ;AN060; get environment back
1610 pop ds ;AN060;
1611
1612 ret ;AN060;
1613
1614setup_for_messages endp ;AN060;
1615
1616; ****************************************************************
1617; *
1618; * ROUTINE: Set_parse_2f
1619; *
1620; * FUNCTION: Does the INT 2Fh to DOS to set the PARSE
1621; * message address that will later be retrieved
1622; * by the message services.
1623; *
1624; * INPUT: ES set to segment of messages
1625; * DI points to offset of messages
1626; *
1627; * OUTPUT: none
1628; *
1629; ****************************************************************
1630
1631Set_parse_2f proc near ;AN060;
1632
1633 mov ax,(multdos shl 8 or message_2f);AN060; set up to call DOS through int 2fh
1634 mov dl,set_parse_msg ;AN060; set up parse message address
1635 int 2fh ;AN060;
1636
1637 ret ;AN060;
1638
1639Set_parse_2f endp ;AN060;
1640
1641; ****************************************************************
1642; *
1643; * ROUTINE: Set_ext_2f
1644; *
1645; * FUNCTION: Does the INT 2Fh to DOS to set the EXTENDED
1646; * message address that will later be retrieved
1647; * by the message services.
1648; *
1649; * INPUT: ES set to segment of messages
1650; * DI points to offset of messages
1651; *
1652; * OUTPUT: none
1653; *
1654; ****************************************************************
1655
1656Set_ext_2f proc near ;AN060;
1657
1658 mov ax,(multdos shl 8 or message_2f);AN060; set up to call DOS through int 2fh
1659 mov dl,set_extended_msg ;AN060; set up extended error message address
1660 int 2fh ;AN060;
1661
1662 ret ;AN060;
1663
1664Set_ext_2f endp ;AN060;
1665
1666
1667ASSUME DS:RESGROUP, ES:RESGROUP
1668
1669.xlist
1670.xcref
1671
1672INCLUDE SYSMSG.INC ;AN000; include message services
1673
1674.list
1675.cref
1676
1677MSG_UTILNAME <COMMAND> ;AN000; define utility name
1678
1679MSG_SERVICES <COMR,NEARmsg,LOADmsg,NOCHECKSTDIN,NOCHECKSTDOUT> ;AC026; include message services macro
1680
1681include msgdcl.inc
1682
1683INIT ENDS
1684
1685 END
diff --git a/v4.0/src/CMD/COMMAND/IPARSE.ASM b/v4.0/src/CMD/COMMAND/IPARSE.ASM
new file mode 100644
index 0000000..5205fe9
--- /dev/null
+++ b/v4.0/src/CMD/COMMAND/IPARSE.ASM
@@ -0,0 +1,38 @@
1 page 80,132
2; SCCSID = @(#)iparse.asm 4.1 87/04/28
3; SCCSID = @(#)iparse.asm 4.1 87/04/28
4TITLE COMMAND interface to SYSPARSE
5
6.xlist
7.xcref
8 INCLUDE comseg.asm ;AN000;
9.list
10.cref
11
12
13INIT SEGMENT PUBLIC PARA ;AN000;
14
15ASSUME CS:RESGROUP,DS:RESGROUP,ES:NOTHING,SS:NOTHING ;AN000;
16
17
18;AD054; public SYSPARSE ;AN000;
19
20 DateSW equ 0 ;AN000; do not Check date format
21 TimeSW equ 0 ;AN000; do not Check time format
22 CmpxSW equ 0 ;AN000; do not check complex list
23 KeySW equ 0 ;AN025; do not support keywords
24 Val2SW equ 0 ;AN025; do not Support value definition 2
25 Val3SW equ 0 ;AN000; do not Support value definition 3
26 QusSW equ 0 ;AN025; do not include quoted string
27 DrvSW equ 0 ;AN025; do not include drive only
28
29.xlist
30.xcref
31;AD054; INCLUDE parse.asm ;AN000;
32.list
33.cref
34
35
36INIT ends ;AN000;
37 end ;AN000;
38 \ No newline at end of file
diff --git a/v4.0/src/CMD/COMMAND/MAKEFILE b/v4.0/src/CMD/COMMAND/MAKEFILE
new file mode 100644
index 0000000..707fb00
--- /dev/null
+++ b/v4.0/src/CMD/COMMAND/MAKEFILE
@@ -0,0 +1,134 @@
1#************************** makefile for cmd\append ***************************
2
3msg =..\..\messages
4dos =..\..\dos
5inc =..\..\inc
6hinc =..\..\h
7
8#
9####################### dependencies begin here. #########################
10#
11
12all: command.com
13
14$(inc)\dossym.inc: $(inc)\dosmac.inc $(inc)\bpb.inc \
15 $(inc)\buffer.inc $(inc)\sysvar.inc $(inc)\vector.inc \
16 $(inc)\mult.inc $(inc)\dirent.inc $(inc)\dpb.inc $(inc)\curdir.inc \
17 $(inc)\cpmfcb.inc $(inc)\find.inc $(inc)\pdb.inc $(inc)\exe.inc \
18 $(inc)\sf.inc $(inc)\arena.inc $(inc)\intnat.inc $(inc)\mi.inc \
19 $(inc)\filemode.inc $(inc)\error.inc $(inc)\syscall.inc
20 echo "touch $(inc)\dossym.inc"
21
22command.ctl: command.skl $(msg)\$(COUNTRY).msg makefile
23
24command1.obj: command1.asm $(inc)\dossym.inc \
25 $(inc)\devsym.inc comsw.asm comequ.asm resmsg.equ \
26 envdata.asm
27
28command2.obj: command2.asm $(inc)\dossym.inc \
29 $(inc)\devsym.inc comsw.asm comequ.asm resmsg.equ \
30 envdata.asm
31
32copy.obj: copy.asm comsw.asm $(inc)\dossym.inc \
33 $(inc)\devsym.inc comseg.asm comequ.asm
34
35copypr1.obj: copypr1.asm comsw.asm $(inc)\dossym.inc \
36 $(inc)\devsym.inc comseg.asm comequ.asm
37
38copypr2.obj: copypr2.asm comsw.asm $(inc)\dossym.inc \
39 $(inc)\devsym.inc comseg.asm comequ.asm
40
41cparse.obj: cparse.asm comsw.asm $(inc)\dossym.inc \
42 $(inc)\devsym.inc comseg.asm comequ.asm
43
44init.obj: init.asm $(inc)\dossym.inc $(inc)\devsym.inc \
45 comsw.asm comseg.asm comequ.asm resmsg.equ $(inc)\sysmsg.inc \
46 $(inc)\msgserv.asm command.ctl
47
48iparse.obj: iparse.asm comseg.asm $(inc)\parse.asm $(inc)\psdata.inc
49
50parse2.obj: parse2.asm $(inc)\dossym.inc $(inc)\devsym.inc comsw.asm \
51 comseg.asm comequ.asm
52
53path1.obj: path1.asm $(inc)\dossym.inc $(inc)\devsym.inc comsw.asm \
54 comseg.asm comequ.asm
55
56path2.obj: path2.asm $(inc)\dossym.inc $(inc)\devsym.inc comsw.asm \
57 comseg.asm comequ.asm
58
59rdata.obj: rdata.asm comsw.asm comseg.asm $(inc)\sysmsg.inc \
60 $(inc)\msgserv.asm command.cla command.cl3 command.cl4 \
61 command.cld command.clc command.cle command.ctl
62
63rucode.obj: rucode.asm $(inc)\dossym.inc $(inc)\devsym.inc \
64 $(inc)\doscntry.inc resmsg.equ $(inc)\sysmsg.inc \
65 $(inc)\msgserv.asm comsw.asm comseg.asm comequ.asm command.ctl
66
67tbatch.obj: tbatch.asm comsw.asm $(inc)\dossym.inc $(inc)\doscntry.inc \
68 $(inc)\devsym.inc comseg.asm comequ.asm ifequ.asm
69
70tbatch2.obj: tbatch2.asm comsw.asm $(inc)\dossym.inc $(inc)\doscntry.inc \
71 $(inc)\devsym.inc comseg.asm comequ.asm ifequ.asm
72
73tcmd1a.obj: tcmd1a.asm comsw.asm $(inc)\dossym.inc $(inc)\ioctl.inc \
74 $(inc)\devsym.inc comseg.asm comequ.asm ifequ.asm
75
76tcmd1b.obj: tcmd1b.asm comsw.asm $(inc)\dossym.inc $(inc)\ioctl.inc \
77 $(inc)\devsym.inc comseg.asm comequ.asm ifequ.asm $(inc)\ea.inc
78
79tcmd2a.obj: tcmd2a.asm comsw.asm $(inc)\dossym.inc $(inc)\ioctl.inc \
80 $(inc)\devsym.inc comseg.asm comequ.asm ifequ.asm
81
82tcmd2b.obj: tcmd2b.asm comsw.asm $(inc)\dossym.inc \
83 $(inc)\devsym.inc comseg.asm comequ.asm ifequ.asm
84
85tcode.obj: tcode.asm comsw.asm $(inc)\dossym.inc \
86 $(inc)\devsym.inc comseg.asm comequ.asm ifequ.asm \
87 $(inc)\mshalo.asm
88
89tdata.obj: tdata.asm comsw.asm comseg.asm $(inc)\curdir.inc \
90 $(inc)\error.inc ifequ.asm comequ.asm $(inc)\sysmsg.inc \
91 $(inc)\msgserv.asm tranmsg.asm command.clf command.cl1 command.cl2 \
92 command.ctl $(inc)\ea.inc
93
94tenv.obj: tenv.asm comsw.asm $(inc)\dossym.inc $(inc)\devsym.inc \
95 comseg.asm comequ.asm ifequ.asm $(inc)\doscntry.inc
96
97tenv2.obj: tenv2.asm comsw.asm $(inc)\dossym.inc $(inc)\devsym.inc \
98 comseg.asm comequ.asm ifequ.asm
99
100tfor.obj: tfor.asm comsw.asm $(inc)\dossym.inc $(inc)\devsym.inc \
101 comseg.asm comequ.asm ifequ.asm fordata.asm
102
103tmisc1.obj: tmisc1.asm comsw.asm $(inc)\dossym.inc \
104 $(inc)\devsym.inc comseg.asm comequ.asm ifequ.asm
105
106tmisc2.obj: tmisc2.asm comsw.asm $(inc)\dossym.inc $(inc)\ioctl.inc \
107 $(inc)\devsym.inc comseg.asm comequ.asm ifequ.asm
108
109tparse.obj: tparse.asm comseg.asm $(inc)\parse.asm $(inc)\psdata.inc
110
111tpipe.obj: tpipe.asm comsw.asm $(inc)\dossym.inc \
112 $(inc)\devsym.inc comseg.asm comequ.asm ifequ.asm
113
114tprintf.obj: tprintf.asm comsw.asm $(inc)\dosmac.inc \
115 comseg.asm comequ.asm $(inc)\sysmsg.inc $(inc)\msgserv.asm \
116 command.ctl
117
118tspc.obj: tspc.asm comsw.asm $(inc)\dossym.inc comequ.asm \
119 ifequ.asm comseg.asm $(inc)\ea.inc
120
121tucode.obj: tucode.asm $(inc)\dosmac.inc $(inc)\dossym.inc \
122 comsw.asm comseg.asm comequ.asm ifequ.asm
123
124uinit.obj: uinit.asm comsw.asm comseg.asm ifequ.asm command.clb \
125 $(inc)\sysmsg.inc $(inc)\msgserv.asm command.ctl
126
127command.com: command1.obj command2.obj rucode.obj rdata.obj init.obj iparse.obj \
128 uinit.obj tcode.obj tbatch.obj tbatch2.obj tfor.obj tcmd1a.obj tcmd1b.obj \
129 tcmd2a.obj tcmd2b.obj tenv.obj tenv2.obj tmisc1.obj tmisc2.obj tpipe.obj \
130 parse2.obj path1.obj path2.obj tucode.obj copy.obj copypr1.obj copypr2.obj \
131 cparse.obj tparse.obj tprintf.obj tdata.obj tspc.obj
132 link @command.lnk
133 exe2bin command.exe command.com
134 del command.exe
diff --git a/v4.0/src/CMD/COMMAND/PARSE2.ASM b/v4.0/src/CMD/COMMAND/PARSE2.ASM
new file mode 100644
index 0000000..2695927
--- /dev/null
+++ b/v4.0/src/CMD/COMMAND/PARSE2.ASM
@@ -0,0 +1,422 @@
1 page 80,132
2; SCCSID = @(#)parse.asm 1.1 85/05/14
3; SCCSID = @(#)parse.asm 1.1 85/05/14
4.sall
5.xlist
6.xcref
7 INCLUDE DOSSYM.INC
8 INCLUDE DEVSYM.INC
9 include comsw.asm
10 include comseg.asm
11 include comequ.asm
12.list
13.cref
14
15
16break <Parse.Asm>
17;----------------------------------------------------------------------------
18; PARSE.ASM contains the routines to perform command line parsing.
19; Parse and Path share a buffer and argv[] definitions.
20; Invoking <Parseline> maps the unparsed command line in COMBUF into an
21; array of pointers to the parsed tokens. The resulting array, argv[],
22; also contains extra information provided by cparse about each token
23; <Parseline> should be executed prior to <Path_Search>
24;
25; Alan L, OS/MSDOS August 15, 1983
26;
27;
28; ENTRY:
29; <Parseline>: command line in COMTAB.
30; EXIT:
31; <Parseline>: success flag, argcnt (number of args), argv[].
32; NOTE(S):
33; * <Argv_calc> handily turns an array index into an absolute pointer.
34; The computation depends on the size of an argv[] element (arg_ele).
35; * <Parseline> calls <cparse> for chunks of the command line. <Cparse>
36; does not function as specified; see <Parseline> for more details.
37; * <Parseline> now knows about the flags the internals of COMMAND.COM
38; need to know about. This extra information is stored in a switch_flag
39; word with each command-line argument; the switches themselves will not
40; appear in the resulting arg structure.
41; * With the exception of CARRY, flags are generally preserved across calls.
42;---------------
43; CONSTANTS:
44;---------------
45 DEBUGx equ FALSE ; prints out debug info
46;---------------
47; DATA:
48;---------------
49
50DATARES SEGMENT PUBLIC BYTE
51 EXTRN FORFLAG:BYTE
52DATARES ENDS
53
54TRANSPACE SEGMENT PUBLIC BYTE ;AC000;
55 EXTRN combuf:byte
56 EXTRN cpyflag:byte
57 EXTRN expand_star:byte
58 EXTRN RESSEG:word
59 EXTRN STARTEL:word
60TRANSPACE ENDS
61
62TRANCODE SEGMENT PUBLIC BYTE ;AC000;
63 PUBLIC argv_calc ; convert array index into address
64 PUBLIC parseline
65
66
67assume cs:trangroup, ds:trangroup, es:trangroup, ss:nothing
68
69
70break <Parseline: Munch on the command line>
71;----------------------------------------------------------------------------
72; PARSELINE takes an MSDOS command line and maps it into a UNIX-style
73; argv[argvcnt] array. The most important difference between this array and
74; the tradition UNIX format is the extra cparse information included with
75; each argument element.
76;---------------
77; ENTRY:
78; (BL special delimiter for cparse -- not implemented)
79;---------------
80; EXIT:
81; CF set if error
82; AL error code (carry set). Note AH clobbered in any event.
83; argv[] array of cparse flags and pointers to arguments
84; argvcnt argument count
85;---------------
86; NOTE(S):
87; * BL (special delimiter) is ignored, for now (set to space).
88; * Parseflags record contains cparse flags, as follows:
89; sw_flag -- was this arg a switch?
90; wildcard -- whether or not it contained a * or ?
91; path_sep -- maybe it was a pathname
92; unused -- for future expansion
93; special_delim -- was there an initial special delimiter?
94; * argv[] and argvcnt are undefined if CF/AL indicates an error.
95; * Relationship between input, cparse output, and comtail can be
96; found in the following chart. Despite the claim of the cparse
97; documentation that, "Token buffer always starts d: for non switch
98; tokens", such is not the case (see column two, row two).
99; Similarly, [STARTEL] is not null when the command line is one of
100; the forms, "d:", "d:\", or "d:/". In fact, *STARTEL (i.e., what
101; STARTEL addresses) will be null. This is clearly just a
102; documentation error.
103; * cparse also returns a switch code in BP for each switch it
104; recognizes on the command line.
105; * arglen for each token does NOT include the terminating null.
106; * Finally, note that interesting constructions like 'foodir/*.exe'
107; parse as three separate tokens, and the asterisk is NOT a wildcard.
108; For example, 'for %i in (foodir/*.exe) do echo %i' will first
109; echo 'foodir', then '*', then '.exe'. Using cparse for command-
110; line parsing may result in slightly different behavior than
111; previously observed with the old COMMAND.COM command-line parser.
112;
113; Input Cparse Command Line (80H)
114; \alan\foo.bat c:\alan\foo.bat \alan\foo.bat
115; alan\foo.bat alan\foo.bat alan\foo.bat
116; foo.bat foo.bat foo.bat
117; c:\alan\foo.bat c:\alan\foo.bat c:\alan\foo.bat
118; c:alan\foo.bat c:alan\foo.bat c:alan\foo.bat
119; c:foo.bat c:foo.bat c:foo.bat
120;---------------
121; CONSTANTS:
122;---------------
123;---------------
124; DATA:
125;---------------
126
127TRANSPACE SEGMENT PUBLIC BYTE ;AC000;
128 EXTRN arg:byte
129 EXTRN argbufptr:word
130 EXTRN comptr:word
131 EXTRN last_arg:word
132 EXTRN tpbuf:byte
133TRANSPACE ENDS
134
135;---------------
136parseline:
137;---------------
138
139 push AX ; most of these are clobbered
140 push BX ; by cparse...
141 push CX
142 push DX
143 push DI
144 push SI
145 pushf
146 mov cpyflag,0 ; Turn "CPARSE called from COPY flag" off
147
148 mov [LAST_ARG], -1 ; last argument at which to accumulate
149 xor ax,ax
150 mov cx,SIZE arg_unit
151 mov di,offset trangroup:arg
152 rep stosb
153 mov argbufptr,offset trangroup:arg.argbuf
154 mov arg.argswinfo, 0 ; switch information, and info to date
155 mov arg.argvcnt, 0 ; initialize argvcnt/argv[]
156 mov SI, OFFSET TRANGROUP:combuf+2 ; prescan leaves cooked input in combuf
157
158; This next section of code (up to pcont:) makes sure that si is set up for
159; parsing. It should point at COMBUF if FORFLAG is set and arg.argforcombuf
160; otherwise. This is done so that commands can get arg pointers into their
161; original command line (or an exact copy of it) in arg_ocomptr.
162; Arg.argforcombuf is used so that the for loop processor will always be able
163; to get a hold of its original command line; even after COMBUF is blasted by
164; the command to be repeated or the transient part of command has been
165; reloaded.
166
167 push ds
168 mov ds,[RESSEG]
169 assume ds:resgroup
170 cmp FORFLAG,0
171 pop ds
172 assume ds:trangroup
173 jnz pcont
174 mov di,OFFSET TRANGROUP:arg.argforcombuf
175 xor ch,ch
176 mov cl,[COMBUF+1]
177 inc cl
178 rep movsb
179 mov si,OFFSET TRANGROUP:arg.argforcombuf
180
181pcont:
182 mov DI, OFFSET TRANGROUP:tpbuf ; destination is temporary token buffer
183 mov BL, ' ' ; no special delimiter, for now
184
185parseloop:
186 mov comptr,si ; save ptr into original command buffer
187 xor BP, BP ; switch information put here by cparse
188 mov byte ptr [expand_star],0 ; don't expand *'s to ?'s
189 invoke scanoff ; skip leading blanks...
190 invoke cparse ; byte off a token (args in SI, DI, BL)
191 jnc More_prse
192 or BP,BP ; Check for trailing switch character
193 jz parsedone
194 call newarg ; We hit CR but BP is non-zero. The
195 ; typical cause of this is that a
196 ; switch char IMMEDIATELY preceeds
197 ; the CR. We have an argument, but it
198 ; is sort of an error.
199 jmp short parsedone ; We're done (found the CR).
200
201More_prse:
202 mov cpyflag,2 ; tell CPARSE that 1st token is done
203 call newarg ; add to argv array (CX has char count)
204 jnc parseloop ; was everything OK?
205 jmp short parse_error ; NO, it wasn't -- bug out (CF set)
206
207parsedone: ; successful completion of parseline
208 popf
209 clc
210 jmp short parse_exit
211
212parse_error: ; error entry (er, exit) point
213 popf
214 stc
215parse_exit: ; depend on not changing CF
216 pop SI
217 pop DI
218 pop DX
219 pop CX
220 pop BX
221 pop AX
222 ret
223
224;---------------
225; parseline ends
226;----------------------------------------------------------------------------
227
228
229break <NewArg>
230;----------------------------------------------------------------------------
231; NEWARG adds the supplied argstring and cparse data to arg.argv[].
232; ENTRY:
233; BH argflags
234; CX character count in argstring
235; DI pointer to argstring
236; comptr ptr to starting loc of current token in original command
237; [STARTEL] cparse's answer to where the last element starts
238; EXIT:
239; argbufptr points to next free section of argbuffer
240; arg.argbuf contains null-terminated argument strings
241; arg.argvcnt argument count
242; arg.argv[] array of flags and pointers
243; arg.arg_ocomptr ptr to starting loc of current token in original command
244; CF set if error
245; AL carry set: error code; otherwise, zero
246;---------------
247newarg:
248;---------------
249
250 push BX
251 push CX
252 push DX ; one never knows, do one?
253 push DI
254 push SI
255 pushf
256 call arg_switch ; if it's a switch, record switch info
257 ; LEAVE SWITCH ON COMMAND LINE!!
258;;; jc newarg_done ; previous arg's switches -- and leave
259
260 cmp arg.argvcnt, ARGMAX ; check to ensure we've not
261 jge too_many_args ; exceeded array limits
262 mov DH, BH ; save argflags
263 mov BX, arg.argvcnt ; argv[argvcnt++] = arg data
264 inc arg.argvcnt
265 mov AX, OFFSET TRANGROUP:arg.argv
266 call argv_calc ; convert offset to pointer
267 mov [BX].argsw_word, 0 ; no switch information, yet...
268 mov [BX].arglen, CX ; argv[argvcnt].arglen = arg length
269 mov [BX].argflags, DH ; argv[argvcnt].argflags = cparse flags
270 mov SI, argbufptr
271 mov [BX].argpointer, SI ; argv[argvcnt].argpointer = [argbufptr]
272 add SI, [STARTEL] ; save startel from new location
273 sub SI, DI ; form pointer into argbuf
274 mov [BX].argstartel, SI ; argv[argvcnt].argstartel = new [STARTEL]
275 mov si,[comptr]
276 mov [BX].arg_ocomptr,si ; arg_ocomptr=ptr into original com line
277
278 mov SI, DI ; now save argstring in argbuffer
279 mov DI, argbufptr ; load the argbuf pointer and make
280 add DI, CX ; sure we're not about to run off
281 cmp DI, OFFSET TRANGROUP:arg.argbuf+ARGBLEN-1
282 jge buf_ovflow ; the end of the buffer (plus null byte)
283 sub DI, CX ; adjust the pointer
284 cld
285 rep movsb ; and save the string in argbuffer
286 mov AL, ANULL ; tack a null byte on the end
287 stosb
288 mov argbufptr, DI ; update argbufptr after copy
289
290newarg_done:
291 popf
292 clc
293 jmp short newarg_exit
294
295too_many_args:
296 mov AX, arg_cnt_error
297 jmp short newarg_error
298
299buf_ovflow:
300 mov AX, arg_buf_ovflow
301
302newarg_error:
303 popf
304 stc
305
306newarg_exit:
307 pop SI
308 pop DI
309 pop DX
310 pop CX
311 pop BX
312 ret
313
314;---------------
315; NewArg ends
316;----------------------------------------------------------------------------
317
318
319break <Arg_Switch>
320;----------------------------------------------------------------------------
321; ARG_SWITCH decides if an argument might really be a switch. In the
322; event that it is, and we can recognize
323; ENTRY:
324; As in <newarg>.
325; EXIT:
326; CF -- clear (wasn't a switch); set (was a switch)
327; NOTE(S):
328; * The mechanism mapping a switch into a bit-value depends entirely
329; on the order of definition in the <switch_list> variable and the
330; values chosen to define the bits in CMDT:COMEQU.ASM. Change either
331; <switch_list> or the definitions in CMDT:COMEQU.ASM -- and rewrite
332; this mechanism. This code taken from CMDT:TCODE.ASM.
333; * The <switch_list> declared below is redundant to one declared in
334; TDATA.ASM, and used in TCODE.ASM.
335; * An ugly routine.
336;---------------
337; CONSTANTS:
338;---------------
339; Constants come from the definitions in CMDT:COMEQU.ASM.
340;---------------
341; DATA:
342;---------------
343
344TRANSPACE SEGMENT PUBLIC BYTE ;AC000;
345 extrn switch_list:byte
346 switch_count EQU $-switch_list
347transpace ends
348
349;---------------
350Arg_Switch:
351;---------------
352
353 push AX
354 push BX
355 push CX
356 push DI
357 pushf
358 test BH, MASK sw_flag ; is it a switch? (preserve flag word)
359 jz arg_no_switch0
360 cmp [LAST_ARG], -1 ; have we encountered any REAL args yet?
361 je arg_no_switch1 ; no, so leading switches don't matter
362 mov BX, [LAST_ARG] ; yes, add switch info to last REAL arg
363 mov AX, OFFSET TRANGROUP:arg.argv
364 call argv_calc
365 or [BX].argsw_word, BP
366 or arg.argswinfo, BP
367
368arg_yes_switch: ; ah, sweet success...
369 popf
370 stc
371 jmp short arg_switch_exit
372
373arg_no_switch0:
374 mov AX, arg.argvcnt ; future switches should then affect
375 mov [LAST_ARG], AX ; this argument
376
377arg_no_switch1: ; wasn't a switch, or we're pretending
378 popf
379 clc
380
381arg_switch_exit:
382 pop DI
383 pop CX
384 pop BX
385 pop AX
386 ret
387
388;---------------
389; Arg_Switch ends
390;----------------------------------------------------------------------------
391
392
393break <Argv_calc>
394;----------------------------------------------------------------------------
395; ARGV_CALC maps an array index into a byte-offset from the base of
396; the supplied array. Method used for computing the address is:
397; Array Index * Array Elt Size + Base Addr = Elt Addr
398; ENTRY:
399; AX -- base of array
400; BX -- array index
401; EXIT:
402; BX -- byte offset
403;---------------
404
405argv_calc:
406 push ax ; Save base
407 mov al,bl ; al = array index
408 mov bl,SIZE argv_ele ; bl = size of an argv element
409 mul bl ; ax = base offset
410 pop bx ; Get base
411 add ax,bx ; Add in base offset
412 xchg ax,bx ; Restore ax and put byte offset in bx
413 ret
414
415;---------------
416; argv_calc ends
417;----------------------------------------------------------------------------
418
419
420
421trancode ends
422 end
diff --git a/v4.0/src/CMD/COMMAND/PATH1.ASM b/v4.0/src/CMD/COMMAND/PATH1.ASM
new file mode 100644
index 0000000..4567174
--- /dev/null
+++ b/v4.0/src/CMD/COMMAND/PATH1.ASM
@@ -0,0 +1,507 @@
1 page 80,132
2; SCCSID = @(#)path1.asm 1.1 85/05/14
3; SCCSID = @(#)path1.asm 1.1 85/05/14
4.sall
5.xlist
6.xcref
7INCLUDE DOSSYM.INC
8 include comsw.asm
9 include comseg.asm
10 include comequ.asm
11.list
12.cref
13
14break <Path.Asm>
15;----------------------------------------------------------------------------
16; PATH.ASM contains the routines to perform pathname incovation. Path and
17; Parse share a temporary buffer and argv[] definitions. <Path_Search>,
18; given a pathname, attempts to find a corresponding executable or batch
19; file on disk. Directories specified in the user's search path will be
20; searched for a matching file, if a match is not found in the current
21; directory and if the pathname is actually only an MSDOS filename.
22; <Path_Search> assumes that the parsed command name can be found in
23; argv[0] -- in other words, <Parseline> should be executed prior to
24; <Path_Search>. Alternatively, the command name and appropriate
25; information could be placed in argv[0], or <Path_Search> could be
26; (easily) modified to make no assumptions about where its input is found.
27; Please find enclosed yet another important routine, <Save_Args>, which
28; places the entire arg/argv[]/argbuf structure on a piece of newly
29; allocated memory. This is handy for for-loop processing, and anything
30; else that wants to save the whole shebang and then process other command
31; lines.
32;
33; Alan L, OS/MSDOS August 15, 1983
34;
35; ENTRY:
36; <Path_Search>: argv[0].
37; <Save_Args>: bytes to allocate in addition to arg structure
38; EXIT:
39; <Path_Search>: success flag, best pathname match in EXECPATH.
40; <Save_Args>: success flag, segment address of new memory
41; NOTE(S):
42; * <Argv_calc> handily turns an array index into an absolute pointer.
43; The computation depends on the size of an argv[] element (arg_ele).
44; * <Parseline> calls <cparse> for chunks of the command line. <Cparse>
45; does not function as specified; see <Parseline> for more details.
46; * <Parseline> now knows about the flags the internals of COMMAND.COM
47; need to know about. This extra information is stored in a switch_flag
48; word with each command-line argument; the switches themselves will not
49; appear in the resulting arg structure.
50; * With the exception of CARRY, flags are generally preserved across calls.
51;---------------
52; CONSTANTS:
53;---------------
54 DEBUGx equ FALSE ; prints out debug info
55;---------------
56; DATA:
57;---------------
58
59TRANDATA SEGMENT PUBLIC BYTE ;AC000;
60 EXTRN baddrv_ptr:word
61TRANDATA ENDS
62
63TRANSPACE SEGMENT PUBLIC BYTE ;AC000;
64 EXTRN arg:byte
65 EXTRN BADPMES_ptr:word
66 EXTRN curdrv:byte
67 EXTRN EXECPATH:byte
68 EXTRN search_best_buf:byte
69 EXTRN search_error:word
70 EXTRN string_ptr_2:word
71 EXTRN tpbuf:byte
72TRANSPACE ENDS
73
74TRANCODE SEGMENT PUBLIC BYTE ;AC000;
75
76assume cs:trangroup, ds:trangroup, es:trangroup, ss:nothing
77
78break <Path_Search>
79;------------------------------------------------------------------------------
80; PATH_SEARCH tries to find the file it's given, somewhere. An initial value
81; of *argv[0].argstartel == 0 implies that there is no command (empty line
82; or 'd:' or 'd:/'). This check is done in strip; otherwise, strip formats
83; the filename/pathname into tpbuf. Search(tpbuf) is executed to see if we
84; have a match, either in the current working directory if we were handed
85; a filename, or in the specified directory, given a pathname. If this call
86; fails, and we were given a pathname, then Path_Search fails. Otherwise,
87; Path_Crunch is repeatedly invoked on tpbuf[STARTEL] (if there's a drive
88; prefix, we want to skip it) for each pathstring in userpath. Success on
89; either the first invocation of search or on one of the succeeding calls
90; sets up the appropriate information for copying the successful pathname
91; prefix (if any) into the result buffer, followed by the successful filename
92; match (from [search_best_buf]). The result is returned in in EXECPATH.
93; ENTRY:
94; argv[0] -- command name and associated information
95; EXIT:
96; AX -- non-zero indicates type of file found
97; EXECPATH -- successful pathname (AX non-zero)
98; NOTE(S):
99; 1) Uses the temporary buffer, tpbuf, from the parse routines.
100; 2) Some files are more equal than others. See search: for rankings.
101; 3) Path_Search terminates as soon as a call to search succeeds, even
102; if search returns an .exe or .bat.
103; 5) Clobbers dma address.
104
105pbuflen equ 128 ; length of EXECPATH
106path_sep_char equ ';'
107
108TRANSPACE SEGMENT PUBLIC BYTE ;AC000;
109 EXTRN fbuf:byte
110 EXTRN pathinfo:word
111 EXTRN psep_char:byte
112TRANSPACE ENDS
113
114Procedure Path_Search,NEAR
115
116 push BX
117 push CX
118 push DX ; could use a "stack 'em" instruction
119 push SI
120 push DI
121 push BP
122 pushf
123 test DS:arg.argv[0].argflags, (MASK wildcard) + (MASK sw_flag)
124 jz path_search_ok
125
126path_failure_jmp:
127 jmp path_failure ; ambiguous commands not allowed
128
129path_search_ok:
130 call store_pchar ; figure out the pathname separator
131 mov DX, OFFSET TRANGROUP:fbuf ; clobber old dma value with
132 trap set_dma ; a pointer to our dma buffer
133 push ES
134 invoke find_path ; get a handle (ES:DI) on user path
135 mov DS:pathinfo[0], ES ; and squirrel it away
136 mov DS:pathinfo[2], DI ; "old" pathstring pointer
137 mov DS:pathinfo[4], DI ; "new" pathstring pointer
138 pop ES
139
140 mov BX, pbuflen ; copy/format argv[0] into temp buffer
141 mov SI, OFFSET TRANGROUP:EXECPATH
142 invoke strip
143 jc path_failure_jmp ; if possible, of course
144
145 mov DX, SI ; search(EXECPATH, error_message)
146 mov [search_error], OFFSET TRANGROUP:BADDRV_ptr
147 invoke search ; must do at least one search
148 or AX, AX ; find anything?
149 jz path_noinit ; failure ... search farther
150
151 mov BP, AX ; success... save filetype code
152 mov DI, OFFSET TRANGROUP:EXECPATH
153 mov SI, DS:arg.argv[0].argpointer
154 mov CX, DS:arg.argv[0].argstartel
155 sub CX, SI ; compute prefix bytes to copy
156;
157; We have the number of bytes in the prefix (up to the final component).
158; We need to form the complete pathname including leading drive and current
159; directory.
160;
161; Is there a drive letter present?
162;
163
164 mov ah,':'
165 cmp cx,2 ; room for drive letter?
166 jb AddDrive ; no, stick it in
167 cmp [si+1],ah ; colon present?
168 jz MoveDrive ; yes, just move it
169
170AddDrive:
171 mov al,curdrv ; get current drive
172 add al,"A" ; convert to uppercase letter
173 stosw ; store d:
174 jmp short CheckPath
175
176MoveDrive:
177 lodsw ; move d:
178 stosw
179 sub cx,2 ; 2 bytes less to move
180
181CheckPath:
182 or al,20h
183 mov dl,al
184 sub dl,"a"-1 ; convert to 1-based for current dir
185;
186; Stick in beginning path char
187;
188 mov al,psep_char
189 stosb
190;
191; Is there a leading /? If so, then no current dir copy is necessary.
192; Otherwise, get current dir for DL.
193;
194 cmp cx,1 ; is there room for path char?
195 jb AddPath ; no, go add path
196 lodsb
197 dec cx
198 cmp al,psep_char ; is there a path separator?
199 jz MovePath ; yes, go move remainder of path
200 inc cx
201 dec si ; undo the lodsb
202
203AddPath:
204 SaveReg <SI>
205 mov si,di ; remainder of buffer
206 trap Current_dir
207;
208; The previous current dir will succeed a previous find_first already worked.
209;
210; Find end of string.
211;
212 mov di,si
213 RestoreReg <SI>
214 mov al,psep_char
215 cmp byte ptr [di],0 ; root (empty dir string)?
216 jz MovePath ; yes, no need for path char
217
218ScanEnd:
219 cmp byte ptr [dI],0 ; end of string?
220 jz FoundEnd
221 inc di
222 jmp ScanEnd
223;
224; Stick in a trailing path char
225;
226FoundEnd:
227 stosb
228;
229; Move remaining part of path. Skip leading path char if present.
230;
231MovePath:
232 cmp [si],al ; first char a path char?
233 jnz CopyPath
234 inc si ; move past leading char
235 dec cx ; drop from count
236
237CopyPath:
238 jcxz CopyDone ; no chars to move!
239 rep movsb
240
241CopyDone:
242 jmp path_success ; run off and form complete pathname
243
244path_noinit:
245 test DS:arg.argv[0].argflags, MASK path_sep
246 jnz path_failure ; complete pathname specified ==> fail
247
248 mov BH, path_sep_char ; semicolon terminates pathstring
249 mov DX, DS:arg.argv[0].argstartel ; this is where the last element starts
250 sub DX, DS:arg.argv[0].argpointer ; form pointer into EXECPATH,
251 add DX, OFFSET TRANGROUP:EXECPATH ; skipping over drive spec, if any
252
253path_loop:
254 call path_crunch ; pcrunch(EXECPATH, pathinfo)
255 mov BP, AX ; save filetype code
256
257 lahf ; save flags, just in case
258 or BP, BP ; did path_crunch find anything?
259 jne path_found
260 sahf ; see? needed those flags, after all!
261 jnc path_loop ; is there anything left to the path?
262
263path_failure:
264 xor AX, AX
265;; jmp short path_exit ; 3/3/KK
266 jmp path_exit ;AC000; 3/3/KK
267
268path_found: ; pathinfo[] points to winner
269 mov DI, OFFSET TRANGROUP:EXECPATH
270 mov CX, pathinfo[4] ; "new" pointer -- end of string
271 mov SI, pathinfo[2] ; "old" pointer -- beginning of string
272
273;
274; BAS Nov 20/84
275; Look at the pathname and expand . and .. if they are the first element
276; in the pathname (after the drive letter)
277;
278 push ES
279 push pathinfo[0]
280 pop ES
281 cmp Byte Ptr ES:[SI+2],'.' ; Look for Current dir at start of path
282 jnz path_cpy
283
284 push CX ; Save pointer to end of string
285 mov AL, ES:[SI]
286 mov [DI],AL ; Copy drive letter, :, and root char
287 mov AL, ES:[SI+1] ; to EXECPATH
288 mov [DI+1],AL
289 mov AL,psep_char
290 mov [DI+2],AL
291 push SI ; Save pointer to begining of string
292 mov DL,ES:[SI] ; Convert device letter for cur dir
293 or DL,20h
294 sub DL,"a"-1
295 mov SI,DI ; pointer to EXECPATH
296 add SI, 3 ; Don't wipe out drive and root info
297 trap Current_dir
298 invoke DStrlen ; Determine length of present info
299 add SI,CX ; Don't copy over drive and root info
300 dec SI
301 mov DI,SI ; Point to end of target string
302 pop SI ; Restore pointer to begining of string
303 add SI, 3 ; Point past drive letter, :, .
304 pop CX ; Restore pointer to end of string
305
306path_cpy:
307 pop ES
308 sub CX, SI ; yields character count
309 push DS ; time to switch segments
310 push pathinfo[0] ; string lives in this segment
311 pop DS
312 cld
313;; rep movsb 3/3/KK ; copy the prefix path into EXECPATH
314
315Kloop: ;AN000; 3/3/KK
316 lodsb ;AN000; 3/3/KK
317 stosb ;AN000; 3/3/KK
318 invoke testkanj ;AN000; 3/3/KK
319 jz NotKanj1 ;AN000; 3/3/KK
320 dec cx ;AN000; 3/3/KK
321 JCXZ PopDone ;AN000; Ignore boundary error 3/3/KK
322 movsb ;AN000; 3/3/KK
323 dec cx ;AN000; 3/3/KK
324 cmp cx,1 ;AN000; One char (the terminator) left ? 3/3/KK
325 ja Kloop ;AN000; no. 3/3/KK
326
327PopDone: ;AN000; 3/3/KK
328 POP DS ;AN000; Yes ES:DI->terminator, last char is 3/3/KK
329 mov AL, psep_char ;AN000; KANJI 3/3/KK
330 jmp Short path_store ;AN000; 3/3/KK
331
332NotKanj1:
333 loop Kloop
334 pop DS ; return to our segment
335 dec DI ; overwrite terminator
336 mov AL, psep_char ; with a pathname separator
337 cmp al,byte ptr [di-1]
338 jz path_success
339
340path_store: ;AN000; 3/3/KK
341 stosb
342
343path_success:
344 mov SI, OFFSET TRANGROUP:search_best_buf
345 xor CX, CX
346
347path_succ_loop:
348 lodsb ; append winning filename to path
349 stosb ; (including terminating null)
350 or al,al
351 jnz path_succ_loop
352 mov AX, BP ; retrieve filetype code
353
354path_exit:
355 popf
356 pop BP
357 pop DI
358 pop SI ; chill out...
359 pop DX
360 pop CX
361 pop BX
362 ret
363EndProc Path_Search
364
365break <Store_Pchar>
366;----------------------------------------------------------------------------
367; STORE_PCHAR determines the pathname-element separator and squirrels
368; it away. In other words, must we say '/bin/ls' or '\bin\ls'?
369; ENTRY:
370; EXIT:
371; NOTE(S):
372; * Uses <psep_char>, defined in <path_search>.
373;---------------
374;---------------
375Procedure Store_PChar,NEAR
376;---------------
377
378 push AX
379 mov AL, '/' ; is the pathname-element separator
380 invoke pathchrcmp ; a regular slash?
381 jz store_slash ; if yes, remember slash
382 mov al,'\'
383 mov [psep_char], al ; otherwise, remember back-slash
384 pop ax
385 ret
386
387store_slash:
388 mov [psep_char], al
389 pop ax
390 return
391;---------------
392EndProc Store_Pchar
393;----------------------------------------------------------------------------
394
395break <Path_Crunch>
396;----------------------------------------------------------------------------
397; PATH_CRUNCH takes a prefix from a prefix string, and a suffix from
398; EXECPATH, and smooshes them into tpbuf. The caller may supply an
399; additional separator to use for breaking up the path-string. Null is the
400; default. Once the user-string has been formed, search is invoked to see
401; what's out there.
402; ENTRY:
403; BH -- additional terminator character
404; SI -- pointer into pathstring to be dissected
405; DX -- pointer to stripped filename
406; EXIT:
407; AX -- non-zero (file type), zero (nothing found)
408; SI -- moves along pathstring from call to call
409; [search_best_buf] -- name of best file (AX non-zero)
410; [tpbuf] -- clobbered
411; NOTE(S):
412; * Implicit in this code is the ability to specify when to search
413; the current directory (if at all) through the PATH defined by
414; the user, a la UNIX (e.g., PATH=;c:\bin;c:\etc searches the
415; current directory before the bin and etc directories of drive c).
416;---------------
417Procedure Path_Crunch,NEAR
418;---------------
419 push BX
420 push CX
421 push DX
422 push DI
423 push SI
424 pushf
425 call store_pchar ; figure out pathname separator
426 mov DI, OFFSET TRANGROUP:tpbuf ; destination of concatenated string
427 mov SI, pathinfo[4] ; "new" pointer to start with
428 mov pathinfo[2], SI ; becomes "old" pointer
429 push DS ; save old segment pointer
430 push pathinfo[0] ; replace with pointer to userpath's
431 pop DS ; segment
432 xor cl,cl ;AN000; clear flag for later use 3/3/KK
433
434path_cr_copy:
435 lodsb ; get a pathname byte
436 or al,al ; check for terminator(s)
437 jz path_seg ; null terminates segment & pathstring
438 cmp AL, BH
439 jz path_seg ; BH terminates a pathstring segment
440 invoke testkanj ;AN000; 3/3/KK
441 jz NotKanj2 ;AN000; 3/3/KK
442 stosb ;AN000; 3/3/KK
443 movsb ;AN000; 3/3/KK
444 MOV CL,1 ;AN000; CL=1 means latest stored char is DBCS 3/3/KK
445 jmp path_cr_copy ;AN000; 3/3/KK
446
447NotKanj2: ;AN000; 3/3/KK
448 xor cl,cl ;AN000; CL=0 means latest stored char is SBCS 3/3/KK
449 stosb ; save byte in concat buffer
450 jmp path_cr_copy ; loop until we see a terminator
451
452path_seg:
453 pop DS ; restore old data segment
454 mov pathinfo[4], SI ; save "new" pointer for next time
455 mov BL, AL ; remember if we saw null or not...
456 ;;; REMOVE NEXT 3 LINES FOR CURDIR SPEC
457 xor AX, AX ; in case nothing in pathstr...
458 cmp DI, OFFSET TRANGROUP:tpbuf ; was there really anything in pathstr?
459 je path_cr_leave ; if nothing was copied, pathstr empty
460
461path_cr_look: ; form complete pathname
462 mov al, psep_char ; add pathname separator for suffix
463 or cl,cl ;AN000; 3/3/KK
464 jnz path_cr_store ;AN000; this is a trailing byte of ECS code 3/3/KK
465 cmp al,byte ptr [di-1]
466 jz path_cr_l1
467
468path_cr_store: ;AN000; 3/3/KK
469 stosb
470
471path_cr_l1:
472 mov SI, DX
473
474path_cr_l2:
475 lodsb ; tack the stripped filename onto
476 stosb ; the end of the path, up to and
477 or AL, AL ; including the terminating null
478 jnz path_cr_l2
479 mov DX, OFFSET TRANGROUP:tpbuf ; and look for an appropriate file...
480 mov [search_error], OFFSET TRANGROUP:BADPMES_ptr
481 invoke search ; results are in AX & search_best_buf
482
483path_cr_leave:
484 or BL, BL ; did we finish off the pathstring?
485 jz path_cr_empty ; null in BL means all gone...
486 popf ; otherwise, plenty left
487 clc
488 jmp short path_cr_exit
489
490path_cr_empty:
491 popf
492 stc
493
494path_cr_exit:
495 pop SI
496 pop DI
497 pop DX
498 pop CX
499 pop BX
500 ret
501;---------------
502EndProc Path_Crunch
503;----------------------------------------------------------------------------
504
505
506trancode ends
507END
diff --git a/v4.0/src/CMD/COMMAND/PATH2.ASM b/v4.0/src/CMD/COMMAND/PATH2.ASM
new file mode 100644
index 0000000..8f8d8b8
--- /dev/null
+++ b/v4.0/src/CMD/COMMAND/PATH2.ASM
@@ -0,0 +1,458 @@
1 page 80,132
2; SCCSID = @(#)path2.asm 1.1 85/05/14
3; SCCSID = @(#)path2.asm 1.1 85/05/14
4.sall
5.xlist
6.xcref
7INCLUDE DOSSYM.INC
8 include comsw.asm
9 include comseg.asm
10 include comequ.asm
11.list
12.cref
13
14
15DATARES SEGMENT PUBLIC BYTE
16 EXTRN FORFLAG:BYTE
17DATARES ENDS
18
19
20break <Path.Asm>
21;----------------------------------------------------------------------------
22; PATH.ASM contains the routines to perform pathname incovation. Path and
23; Parse share a temporary buffer and argv[] definitions. <Path_Search>,
24; given a pathname, attempts to find a corresponding executable or batch
25; file on disk. Directories specified in the user's search path will be
26; searched for a matching file, if a match is not found in the current
27; directory and if the pathname is actually only an MSDOS filename.
28; <Path_Search> assumes that the parsed command name can be found in
29; argv[0] -- in other words, <Parseline> should be executed prior to
30; <Path_Search>. Alternatively, the command name and appropriate
31; information could be placed in argv[0], or <Path_Search> could be
32; (easily) modified to make no assumptions about where its input is found.
33; Please find enclosed yet another important routine, <Save_Args>, which
34; places the entire arg/argv[]/argbuf structure on a piece of newly
35; allocated memory. This is handy for for-loop processing, and anything
36; else that wants to save the whole shebang and then process other command
37; lines.
38;
39; Alan L, OS/MSDOS August 15, 1983
40;
41; ENTRY:
42; <Path_Search>: argv[0].
43; <Save_Args>: bytes to allocate in addition to arg structure
44; EXIT:
45; <Path_Search>: success flag, best pathname match in EXECPATH.
46; <Save_Args>: success flag, segment address of new memory
47; NOTE(S):
48; * <Argv_calc> handily turns an array index into an absolute pointer.
49; The computation depends on the size of an argv[] element (arg_ele).
50; * <Parseline> calls <cparse> for chunks of the command line. <Cparse>
51; does not function as specified; see <Parseline> for more details.
52; * <Parseline> now knows about the flags the internals of COMMAND.COM
53; need to know about. This extra information is stored in a switch_flag
54; word with each command-line argument; the switches themselves will not
55; appear in the resulting arg structure.
56; * With the exception of CARRY, flags are generally preserved across calls.
57;---------------
58; CONSTANTS:
59;---------------
60 DEBUGx equ FALSE ; prints out debug info
61;---------------
62; DATA:
63;---------------
64
65TRANSPACE SEGMENT PUBLIC BYTE ;AC000;
66 EXTRN arg:byte
67 EXTRN BADPMES_ptr:word
68 EXTRN curdrv:byte
69 EXTRN EXECPATH:byte
70 EXTRN ext_entered:byte ;AN005;
71 EXTRN fbuf:byte
72 EXTRN pathinfo:word
73 EXTRN psep_char:byte
74 EXTRN string_ptr_2:word
75 EXTRN tpbuf:byte
76TRANSPACE ENDS
77
78TRANCODE SEGMENT PUBLIC BYTE ;AC000;
79
80assume cs:trangroup, ds:trangroup, es:trangroup, ss:nothing
81
82
83break <Search>
84;----------------------------------------------------------------------------
85; SEARCH, when given a pathname, attempts to find a file with
86; one of the following extensions: .com, .exe, .bat (highest to
87; lowest priority). Where conflicts arise, the extension with
88; the highest priority is favored.
89; ENTRY:
90; DX -- pointer to null-terminated pathname
91; fbuf -- dma buffer for findfirst/next
92; EXIT:
93; AX -- 8) file found with .com extension
94; 4) file found with .exe extension
95; 2) file found with .bat extension
96; 0) no such file to be found
97; (if AX is non-zero:)
98; [search_best] identical to AX
99; [search_best_buf] null-terminated filename
100; NOTES:
101; 1) Requires caller to have allocated a dma buffer and executed a setdma.
102;---------------
103; CONSTANTS:
104;---------------
105search_file_not_found equ 0
106search_com equ 8
107search_exe equ 4
108search_bat equ 2
109fname_len equ 8
110fname_max_len equ 13
111dot equ '.'
112wildchar equ '?'
113
114;---------------
115; DATA:
116;---------------
117TRANSPACE SEGMENT PUBLIC BYTE ;AC000;
118 EXTRN search_best:byte
119 EXTRN search_best_buf:byte
120 EXTRN search_curdir_buf:byte
121 EXTRN search_error:word
122TRANSPACE ENDS
123
124;---------------
125Procedure Search,NEAR
126;---------------
127 push CX
128 push DX
129 push DI
130 push SI
131 pushf
132
133 push DX ; check drivespec (save pname ptr)
134 mov DI, DX ; working copy of pathname
135 mov SI, OFFSET TRANGROUP:search_curdir_buf
136 xor DX, DX ; zero means current drive
137 cmp BYTE PTR [DI+1],':' ; is there a drive spec?
138 jne search_dir_check
139 mov DL, [DI] ; get the drive byte
140 and DL, NOT 20H ; uppercase the sucker
141 sub DL, '@' ; and convert to drive number
142
143search_dir_check:
144 trap Current_Dir ; can we get the drive's current
145 pop DX ; directory? If we can't we'll
146 jc search_invalid_drive ; assume it's a bad drive...
147
148 mov CX, search_attr ; filetypes to search for
149 trap Find_First ; request first match, if any
150 jc search_no_file
151 mov search_best, search_file_not_found
152 mov [search_best_buf], ANULL ; nothing's been found, yet
153
154search_loop:
155 call search_ftype ; determine if .com, &c...
156 cmp AL, search_best ; better than what we've found so far?
157 jle search_next ; no, look for another
158 mov search_best, AL ; found something... save its code
159 mov SI, OFFSET TRANGROUP:fbuf.find_buf_pname
160 mov DI, OFFSET TRANGROUP:search_best_buf
161 mov CX, fname_max_len
162 cld
163 rep movsb ; save complete pathname representation
164 cmp AL, search_com ; have we found the best of all?
165 je search_done
166
167search_next: ; keep on looking
168 mov CX, search_attr
169 trap Find_Next ; next match
170 jnc search_loop
171
172search_done: ; it's all over with...
173 mov AL, search_best ; pick best to return with
174 cmp ext_entered,1 ;AN005; Did user request a specific ext?
175 jz search_exit ;AN005; no - exit
176 mov al,ext_entered ;AN005; yes - get the real file type back
177 mov search_best,al ;AN005; save the real file type
178 jmp short search_exit
179
180search_invalid_drive: ; Tell the user path/drive
181 mov DX, [search_error] ; appropriate error message
182 invoke std_printf ; and pretend no file found
183
184search_no_file: ; couldn't find a match
185 mov AX, search_file_not_found
186
187search_exit:
188 popf
189 pop SI
190 pop DI
191 pop DX
192 pop CX
193 ret
194;---------------
195EndProc Search
196;----------------------------------------------------------------------------
197
198
199break <Search_Ftype>
200;----------------------------------------------------------------------------
201; SEARCH_FTYPE determines the type of a file by examining its extension.
202; ENTRY:
203; fbuf -- dma buffer containing filename
204; EXIT:
205; AX -- file code, as given in search header
206; NOTE(S):
207; * Implicit assumption that NULL == search_file_not_found
208;---------------
209; DATA:
210;---------------
211TRANDATA SEGMENT PUBLIC BYTE ;AC000;
212 extrn comext:byte,exeext:byte,batext:byte
213trandata ends
214;---------------
215Procedure Search_Ftype,NEAR
216;---------------
217 push DI
218 push si
219 mov AX, ANULL ; find the end of the filename
220 mov DI, OFFSET TRANGROUP:fbuf.find_buf_pname
221 mov CX, fname_max_len
222 cld
223 repnz scasb ; search for the terminating null
224 jnz ftype_exit ; weird... no null byte at end
225 sub di,5 ; . + E + X + T + NULL
226;
227; Compare .COM
228;
229 mov si,offset trangroup:comext
230 mov ax,di
231 cmpsw
232 jnz ftype_exe
233 cmpsw
234 jnz ftype_exe
235 mov AX, search_com ; success!
236 jmp short ftype_exit
237;
238; Compare .EXE
239;
240
241ftype_exe: ; still looking... now for '.exe'
242 mov di,ax
243 mov si,offset trangroup:exeext
244 cmpsw
245 jnz ftype_bat
246 cmpsw
247 jnz ftype_bat
248 mov AX, search_exe ; success!
249 jmp short ftype_exit
250;
251; Compare .BAT
252;
253
254ftype_bat: ; still looking... now for '.bat'
255 mov di,ax
256 mov si,offset trangroup:batext
257 cmpsw
258 jnz ftype_fail
259 cmpsw
260 jnz ftype_fail
261 mov AX, search_bat ; success!
262 jmp short ftype_exit
263
264ftype_fail: ; file doesn't match what we need
265 mov ax,ANULL
266
267ftype_exit:
268 cmp ext_entered,1 ;AN005; was an extension entered?
269 jz ftype_done ;AN005; no - exit
270 cmp ax,ANULL ;AN005; was any match found
271 jz ftype_done ;AN005; no - exit
272 mov ext_entered,al ;AN005; save the match type found
273 mov AX, search_com ;AN005; send back best was found to stop search
274
275ftype_done: ;AN005;
276 pop SI
277 pop DI
278 ret
279
280;---------------
281EndProc Search_Ftype
282;----------------------------------------------------------------------------
283
284
285break <Strip>
286;----------------------------------------------------------------------------
287; STRIP copies the source string (argv[0]) into the destination buffer,
288; replacing any extension with wildcards.
289; ENTRY:
290; BX -- maximum length of destination buffer
291; DS:SI -- address of destination buffer
292; argv[0] -- command name to be stripped
293; EXIT:
294; CF -- set if failure, clear if successful
295; NOTE(S):
296;---------------
297Procedure Strip,NEAR
298;---------------
299 push AX
300 push BX
301 push CX
302 push DX
303 push DI
304 push SI
305 pushf
306
307 mov ext_entered,1 ;AN005; assume no extension on file name
308 mov DX, DS:arg.argv[0].argpointer ; save pointer to beginning of argstring
309 mov DI, DS:arg.argv[0].argstartel ; beginning of last pathname element
310 cmp BYTE PTR [DI], 0 ; *STARTEL == NULL means no command
311 jz strip_error
312 mov CX, DX ; compute where end of argstring lies
313 add CX, DS:arg.argv[0].arglen
314 sub CX, DI ; and then find length of last element
315 inc CX ; include null as well
316 mov AL, dot ; let's find the filetype extension
317 cld
318 repnz scasb ; wind up pointing to either null or dot
319 jcxz process_ext ;AN005; if no extension found, just continue
320 mov ext_entered,0 ;AN005; we found an extension
321 mov al,ANULL ;AN005; continue scanning until the
322 repnz scasb ;AN005; end of line is reached.
323
324process_ext: ;AN005;
325 mov CX, DI ; pointer to end of argstring yields
326 sub CX, DX ; number of bytes to be copied
327 sub BX, 4 ; can argstring fit into dest. buffer?
328 cmp CX, BX
329 jg strip_error ; if not, we must have a bad pathname
330 mov DI, SI ; destination buffer
331 mov SI, DX ; source is beginning of pathname
332 cld
333 rep movsb ; SI=arg,DI=buffer,CX=argend-argbeg
334 cmp ext_entered,1 ;AN005; if an extension was entered
335 jnz skip_wilds ;AN005; don't set up wildcard ext.
336
337 dec DI ; overwrite null or dot
338 stosb ; with a dot
339 mov AL, wildchar ; now add wildcards
340 stosb
341 stosb
342 stosb
343 mov AL, ANULL ; and a terminating null
344 stosb
345
346skip_wilds: ;AN005;
347 popf
348 clc ; chill out...
349 jmp short strip_exit
350
351strip_error:
352 popf
353 stc
354
355strip_exit:
356 pop SI
357 pop DI
358 pop DX
359 pop CX
360 pop BX
361 pop AX
362 ret
363;---------------
364EndProc Strip
365;----------------------------------------------------------------------------
366
367
368break <Save_Args>
369;----------------------------------------------------------------------------
370; SAVE_ARGS attempts to preserve the existing argv[]/argvcnt/argbuffer
371; structure in newly allocated memory. The argv[] structure is found at the
372; beginning of this area. The caller indicates how much extra space is
373; needed in the resulting structure; Save_Args returns a segment number and
374; an offset into that area, indicating where the caller may preserve its own
375; data. Note that <argvcnt> can be found at <offset-2>.
376; ENTRY:
377; BX -- size (in bytes) of extra area to allocate
378; EXIT:
379; AX -- segment of new area.
380; CF -- set if unable to save a copy.
381; NOTE(S):
382; 1) The allocated area will be AT LEAST the size requested -- since
383; the underlying MSDOS call, <alloc> returns an integral number of
384; paragraphs.
385; 2) It is an error if MSDOS can't allocate AT LEAST as much memory
386; as the caller of Save_Args requests.
387; 3) AX is undefined if CF indicates an error.
388;---------------
389Procedure Save_Args,NEAR
390;---------------
391 push BX
392 push CX
393 push DX
394 push DI
395 push SI
396 push BP
397 pushf
398 add BX, SIZE arg_unit + 0FH ; space for arg structure, round up
399 mov CL, 4 ; to paragraph size and convert
400 shr BX, CL ; size in bytes to size in paragraphs
401 trap Alloc
402 jc save_error
403 mov BP, AX ; save segment id
404 push ES ; save TRANGROUP address
405 mov ES, AX ; switch to new memory segment
406assume ES:nothing
407 mov CX, SIZE arg_unit ; get back structure size
408 xor DI, DI ; destination is new memory area
409 mov SI, OFFSET TRANGROUP:arg ; source is arg structure
410 rep movsb ; move that sucker!
411 mov CX, arg.argvcnt ; adjust argv pointers
412 xor AX, AX ; base address for argv_calc
413 mov SI, OFFSET TRANGROUP:arg.argbuf - OFFSET arg_unit.argbuf
414
415save_ptr_loop:
416 dec CX ; exhausted all args?
417 jl save_done
418 mov BX, CX ; get arg index and
419 invoke argv_calc ; convert to a pointer
420 mov DX, DS:arg.argv[BX].argpointer
421 sub DX, SI ; adjust argpointer
422 mov ES:argv[BX].argpointer, DX
423 mov DX, DS:arg.argv[BX].argstartel
424 sub DX, SI ; and adjust argstartel
425 mov ES:argv[BX].argstartel, DX
426 mov DX, DS:arg.argv[BX].arg_ocomptr
427 sub DX, SI ; and adjust arg_ocomptr
428 mov ES:argv[BX].arg_ocomptr, DX
429 jmp save_ptr_loop
430
431save_done:
432 pop ES ; back we go to TRANGROUP
433assume ES:trangroup
434 mov AX, BP ; restore segment id
435 jmp short save_ok
436
437save_error:
438 popf
439 stc
440 jmp short save_exit
441
442save_ok:
443 popf
444 clc
445save_exit:
446 pop BP
447 pop SI
448 pop DI
449 pop DX
450 pop CX
451 pop BX
452 ret
453;---------------
454EndProc Save_Args
455;----------------------------------------------------------------------------
456
457trancode ends
458END
diff --git a/v4.0/src/CMD/COMMAND/RDATA.ASM b/v4.0/src/CMD/COMMAND/RDATA.ASM
new file mode 100644
index 0000000..65fd4bb
--- /dev/null
+++ b/v4.0/src/CMD/COMMAND/RDATA.ASM
@@ -0,0 +1,611 @@
1 page 80,132
2; SCCSID = @(#)rdata.asm 4.2 85/09/22
3; SCCSID = @(#)rdata.asm 4.2 85/09/22
4TITLE COMMAND Resident DATA
5
6include comsw.asm
7.xlist
8.xcref
9include comseg.asm
10.list
11.cref
12
13;
14; Equates for initialization (from COMEQU)
15;
16initInit equ 01h ; initialization in progress
17initSpecial equ 02h ; in initialization time/date routine
18initCtrlC equ 04h ; already in ^C handler
19
20Tokenized = FALSE
21
22CODERES SEGMENT PUBLIC BYTE ;AC000;
23 PUBLIC RSTACK
24 EXTRN EXT_EXEC:NEAR
25 EXTRN THEADFIX:NEAR
26 EXTRN TREMCHECK:NEAR
27
28 DB (80H - 3) DUP (?)
29
30RSTACK LABEL WORD
31
32CODERES ENDS
33
34TRANCODE SEGMENT PUBLIC BYTE ;AC000;
35 EXTRN COMMAND:NEAR
36TRANCODE ENDS
37
38; Data for resident portion
39
40DATARES SEGMENT PUBLIC BYTE
41
42 IF Tokenized
43 PUBLIC IOTYP
44 PUBLIC MESADD
45 ENDIF
46
47 PUBLIC abort_char
48 PUBLIC append_flag ;AN020;
49 PUBLIC append_state ;AN020;
50 PUBLIC BADFAT_BLOCK ;AC000;
51 PUBLIC BADFAT_OP_SEG ;AC000;
52 PUBLIC BADFAT_SUBST ;AC000;
53 PUBLIC BATCH
54 PUBLIC Batch_Abort
55 PUBLIC call_batch_flag
56 PUBLIC call_flag
57 PUBLIC CDEVAT ;AC000;
58 PUBLIC COM_FCB1
59 PUBLIC COM_FCB2
60 PUBLIC COM_PTR
61 PUBLIC COM_XLAT_ADDR
62 PUBLIC COMDRV
63 PUBLIC COMPRMT1_BLOCK ;AC000;
64 PUBLIC COMPRMT1_SEG ;AC000;
65 PUBLIC COMPRMT1_SEG2 ;AC000;
66 PUBLIC COMPRMT1_SUBST ;AC000;
67 PUBLIC COMSPEC
68 PUBLIC crit_msg_off ;AC000;
69 PUBLIC crit_msg_seg ;AC000;
70 PUBLIC critical_msg_start ;AC000;
71 PUBLIC comspec_print
72 PUBLIC comspec_end
73 PUBLIC cpdrv
74 PUBLIC crit_err_INFO
75 PUBLIC DATARESEND
76 PUBLIC dbcs_vector_addr ;AN000;
77 PUBLIC DEVE_OP_OFF ;AC000;
78 PUBLIC DEVE_OP_SEG ;AC000;
79 PUBLIC DEVE_OP_SEG2 ;AC000;
80 PUBLIC DEVEMES_BLOCK ;AC000;
81 PUBLIC DEVEMES_SUBST ;AC000;
82 PUBLIC DEVENAM ;AC000;
83 PUBLIC DISP_CLASS ;AN000;
84 PUBLIC DRVLET
85 PUBLIC DRVNUM_BLOCK ;AC000;
86 PUBLIC DRVNUM_OP_OFF ;AC000;
87 PUBLIC DRVNUM_OP_SEG ;AC000;
88 PUBLIC DRVNUM_OP_SEG2 ;AC000;
89 PUBLIC DRVNUM_SUBST ;AC000;
90 PUBLIC ECHOFLAG
91 PUBLIC ENVIRSEG
92 PUBLIC ERR15_OP_SEG ;AC000;
93 PUBLIC ERR15_OP_SEG2 ;AC000;
94 PUBLIC ERR15_OP_SEG3 ;AC000;
95 PUBLIC ERR15MES_BLOCK ;AC000;
96 PUBLIC ERR15MES_SUBST ;AC000;
97 PUBLIC ERRCD_24
98 PUBLIC ErrType
99 PUBLIC EXEC_BLOCK
100 PUBLIC EXECEMES_BLOCK ;AC000;
101 PUBLIC EXECEMES_SUBST ;AC000;
102 PUBLIC EXECEMES_OFF ;AC000;
103 PUBLIC EXECEMES_SEG ;AC000;
104 PUBLIC EXTCOM
105 PUBLIC extended_msg_start ;AN000;
106 PUBLIC extmsgend ;AN000;
107 PUBLIC fail_char ;AC000;
108 PUBLIC fFail
109 PUBLIC FORFLAG
110 PUBLIC forptr
111 PUBLIC fucase_addr ;AN000;
112 PUBLIC HANDLE01
113 PUBLIC IFFlag
114 PUBLIC ignore_char
115 PUBLIC In_Batch
116 PUBLIC InitFlag
117 PUBLIC INPIPEPTR
118 PUBLIC INT_2E_RET
119 PUBLIC IO_SAVE
120 PUBLIC LOADING
121 PUBLIC LTPA
122 PUBLIC MEMSIZ
123;AD054; PUBLIC MESBAS ;AC000;
124 PUBLIC MYSEG
125 PUBLIC MYSEG1
126 PUBLIC MYSEG2
127 PUBLIC nest
128 PUBLIC next_batch
129 PUBLIC no_char
130 PUBLIC NULLFLAG
131 PUBLIC NUMBER_SUBST ;AN000;
132 PUBLIC olderrno
133 PUBLIC OldTerm
134 PUBLIC OUTPIPEPTR
135 PUBLIC PARENT
136;AD060; PUBLIC pars_msg_off ;AN000;
137;AD060; PUBLIC pars_msg_seg ;AN000;
138 PUBLIC parse_msg_start ;AN000;
139 PUBLIC PERMCOM
140 PUBLIC PIPE1
141 PUBLIC pipe1t
142 PUBLIC PIPE2
143 PUBLIC pipe2t
144 PUBLIC PIPEFILES
145 PUBLIC PIPEFLAG
146 PUBLIC PIPEPTR
147 PUBLIC PIPESTR
148 PUBLIC RDIRCHAR
149 PUBLIC RE_OUT_APP
150 PUBLIC RE_OUTSTR
151 PUBLIC RemMsg
152 PUBLIC resmsgend ;AN000;
153 PUBLIC RES_TPA
154 PUBLIC RESTDIR
155 PUBLIC ResTest
156 PUBLIC RETCODE
157 PUBLIC retry_char
158 PUBLIC rsrc_xa_seg ;AN030;
159 PUBLIC RSWITCHAR
160 PUBLIC SAVE_PDB
161 PUBLIC SINGLECOM
162 PUBLIC SUM
163 PUBLIC SUPPRESS
164 PUBLIC TRANS
165 PUBLIC TranVarEnd
166 PUBLIC TRANVARS
167 PUBLIC TRNSEG
168 PUBLIC TrnMvFlg
169 PUBLIC VERVAL
170 PUBLIC VolName
171 PUBLIC VOLSER ;AN000;
172 PUBLIC yes_char
173
174;AD054;MESBAS DW 19 ;AC000; error_write_protect
175;AD054; DW 20 ;AC000; error_bad_unit
176;AD054; DW 21 ;AC000; error_not_ready
177;AD054; DW 22 ;AC000; error_bad_command
178;AD054; DW 23 ;AC000; error_CRC
179;AD054; DW 24 ;AC000; error_bad_length
180;AD054; DW 25 ;AC000; error_Seek
181;AD054; DW 26 ;AC000; error_not_DOS_disk
182;AD054; DW 27 ;AC000; error_sector_not_found
183;AD054; DW 28 ;AC000; error_out_of_paper
184;AD054; DW 29 ;AC000; error_write_fault
185;AD054; DW 30 ;AC000; error_read_fault
186;AD054; DW 31 ;AC000; error_gen_failure
187;AD054; DW 32 ;AC000; error_sharing_violation
188;AD054; DW 33 ;AC000; error_lock_violation
189;AD054; DW 34 ;AC000; error_wrong_disk
190;AD054; DW 35 ;AC000; error_FCB_unavailable
191;AD054; DW 36 ;AC000; error_sharing_buffer_exceeded
192;AD054; DW 37 ;AC000; error_code_page_mismatch
193;AD054; DW 38 ;AC026; error_out_of_input
194;AD054; DW 39 ;AN026; error_insufficient_disk_space
195
196
197
198IF Tokenized
199MESADD LABEL WORD
200 DW OFFSET ResGroup:NEWLIN ;"0"
201 DW OFFSET ResGroup:COM$1 ;"1"
202 DW OFFSET ResGroup:ERR3 ;"2"
203 DW OFFSET ResGroup:ALLOC$3 ;"3"
204 DW OFFSET ResGroup:FILE$4 ;"4"
205 DW OFFSET ResGroup:RROR$5 ;"5"
206 DW OFFSET ResGroup:CAN$6 ;"6"
207 DW OFFSET ResGroup:EMORY$7 ;"7"
208 DW OFFSET ResGroup:BAT$8 ;"8"
209 DW OFFSET ResGroup:INS$9 ;"9"
210
211ERR0 DB "Write protec","t"+80h
212ERR1 DB "Bad uni","t"+80h
213ERR2 DB "Not read","y"+80h
214ERR3 DB "Bad command"," "+80h
215ERR4 DB "Dat","a"+80h
216ERR5 DB "Bad call forma","t"+80h
217ERR6 DB "See","k"+80h
218ERR7 DB "Non-DOS dis","k"+80h
219ERR8 DB "Sector not foun","d"+80h
220ERR9 DB "No pape","r"+80h
221ERR10 DB "Write faul","t"+80h
222ERR11 DB "Read faul","t"+80h
223ERR12 DB "General Failur","e"+80h
224ERR13 DB "Sharing Violatio","n"+80h
225ERR14 DB "Lock Violatio","n"+80h
226ERR15 DB "Invalid Disk Chang","e"+80h
227ERR16 DB "FCB unavailabl","e"+80h
228ERR17 DB "Sharing buffer exceede","d"+80h
229
230;--- Extra message for error 15
231Err15Mes db "Please Insert disk "
232VolName db 11 dup(?)
233 db 13,10,"$"
234
235MREAD DB "read"
236MWRITE DB "writ"
237ERRMES DB " e5"
238IOTYP DB "writin","g"+80h
239DRVNUM DB " drive "
240DRVLET DB "A"
241NEWLIN DB 13,10+80h
242DEVEMES DB " device "
243DEVENAM DB 8 DUP (?)
244 DB 13,10,"$" ;Must be $ terminated
245COM$1 DB " COMMAN","D"+80h
246ALLOC$3 DB " allocation"," "+80h
247FILE$4 DB " file"," "+80h
248RROR$5 DB "rror"," "+80h
249CAN$6 DB "Cannot"," "+80h
250EMORY$7 DB "emor","y"+80h
251BAT$8 DB " batc","h"+80h
252INS$9 DB "Inser","t"+80h
253
254
255CDEVAT DB ?
256BADFAT DB "0File 3table bad",","+80h
257COMBAD DB "0Invalid1.COM","0"+80h
258comprmt1 DB "9 disk with"," "+80h
259comprmt2 DB " in drive "
260cpdrv DB " "
261PROMPT DB "0and strike any key when ready","0"+80h
262ENDBATMES DB "0Terminate8 job (Y/N)?"," "+80h
263EXECEMES DB "EXEC failure","0"+80h
264EXEBAD DB "E5in EXE4","0"+80h
265TOOBIG DB "Program too big to fit in m7","0"+80h
266NOHANDMES DB "0No free4handle","s"+80h
267BMEMMES DB "0M73e","5"+80h
268HALTMES DB "06load1, system halte","d"+80h
269FRETMES DB "06start1, exiting","0"+80h
270RBADNAM DB "2or4name","0"+80h
271AccDen DB "Access Denied","0"+80h
272Patricide DB 13,10,"Top level process aborted, cannot continue."," "+80h
273COMSPEC_PRINT DW ?
274
275ELSE
276
277
278parm_block_size EQU 11 ;AN000; size of message subst block
279blank EQU " " ;AN000; blank character
280
281DISP_CLASS DB -1 ;AN000; utility message class
282NUMBER_SUBST DB 0 ;AN000; number of message substitutions - def 0
283
284
285DRVNUM_SUBST db 2 ;AN000; number of subst
286DRVNUM_BLOCK db parm_block_size ;AN000;size of sublist
287 db 0 ;AN000;reserved
288DRVNUM_OP_OFF dw 0 ;AN000;offset of arg
289DRVNUM_OP_SEG dw 0 ;AN000;segment of arg
290 db 1 ;AN000;first subst
291 db Char_field_ASCIIZ ;AN000;character string
292 db 128 ;AN000;maximum width
293 db 0 ;AN000;minimum width
294 db blank ;AN000;pad character
295 db parm_block_size ;AN000;size of sublist
296 db 0 ;AN000;reserved
297 dw OFFSET RESGROUP:DRVLET ;AN000;offset of arg
298DRVNUM_OP_SEG2 dw 0 ;AN000;segment of arg
299 db 2 ;AN000;second subst
300 db Char_field_Char ;AN000;one character
301 db 1 ;AN000;maximum width
302 db 1 ;AN000;minimum width
303 db blank ;AN000;pad character
304
305DRVLET DB "A"
306
307DEVEMES_SUBST db 2 ;AN000; number of subst
308DEVEMES_BLOCK db parm_block_size ;AN000;size of sublist
309 db 0 ;AN000;reserved
310DEVE_OP_OFF dw 0 ;AN000;offset of arg
311DEVE_OP_SEG dw 0 ;AN000;segment of arg
312 db 1 ;AN000;first subst
313 db Char_field_ASCIIZ ;AN000;character string
314 db 128 ;AN000;maximum width
315 db 0 ;AN000;minimum width
316 db blank ;AN000;pad character
317 db parm_block_size ;AN000;size of sublist
318 db 0 ;AN000;reserved
319 dw OFFSET RESGROUP:DEVENAM ;AN000;offset of arg
320DEVE_OP_SEG2 dw 0 ;AN000;segment of arg
321 db 2 ;AN000;second subst
322 db Char_field_ASCIIZ ;AN000;character string
323 db 8 ;AN019;maximum width
324 db 8 ;AN019;minimum width
325 db blank ;AN000;pad character
326
327DEVENAM DB 8 DUP (?)
328
329;--- Extra message for error 15
330ERR15MES_SUBST db 3 ;AN000; number of subst
331ERR15MES_BLOCK db parm_block_size ;AN000;size of sublist
332 db 0 ;AN000;reserved
333 dw OFFSET RESGROUP:VOLNAME ;AN000;offset of arg
334ERR15_OP_SEG dw 0 ;AN000;segment of arg
335 db 1 ;AN000;first subst
336 db Char_field_ASCIIZ ;AN000;character string
337 db 12 ;AN000;maximum width
338 db 12 ;AN000;minimum width
339 db blank ;AN000;pad character
340 db parm_block_size ;AN000;size of sublist
341 db 0 ;AN000;reserved
342 dw OFFSET RESGROUP:VOLSER+2;AN000;offset of arg
343ERR15_OP_SEG2 dw 0 ;AN000;segment of arg
344 db 2 ;AN000;second subst
345 db right_align+Bin_Hex_Word ;AN000;long binary to decimal
346 db 4 ;AN000;maximum width
347 db 4 ;AN000;minimum width
348 db "0" ;AN000;pad character
349 db parm_block_size ;AN000;size of sublist
350 db 0 ;AN000;reserved
351 dw OFFSET RESGROUP:VOLSER ;AN000;offset of arg
352ERR15_OP_SEG3 dw 0 ;AN000;segment of arg
353 db 3 ;AN000;third subst
354 db right_align+Bin_Hex_Word ;AN000;long binary to decimal
355 db 4 ;AN000;maximum width
356 db 4 ;AN000;minimum width
357 db "0" ;AN000;pad character
358
359;************************************
360;* DO NOT SEPARATE VOLNAME & VOLSER *
361;************************************
362 ;*
363VolName DB 11 dup(?) ;*
364 DB 0 ;*
365VolSer DD 0 ;*
366 ;*
367;************************************
368
369
370CDEVAT DB ?
371
372BADFAT_SUBST db 1 ;AN000; number of subst
373BADFAT_BLOCK db parm_block_size ;AN000;size of sublist
374 db 0 ;AN000;reserved
375 dw OFFSET RESGROUP:DRVLET ;AN000;offset of arg
376BADFAT_OP_SEG dw 0 ;AN000;segment of arg
377 db 1 ;AN000;first subst
378 db Char_field_Char ;AN000;one character
379 db 1 ;AN000;maximum width
380 db 1 ;AN000;minimum width
381 db blank ;AN000;pad character
382
383
384COMPRMT1_SUBST db 2 ;AN000; number of subst
385COMPRMT1_BLOCK db parm_block_size ;AN000;size of sublist
386 db 0 ;AN000;reserved
387COMSPEC_PRINT dw ? ;AN000;offset of arg
388COMPRMT1_SEG dw 0 ;AN000;segment of arg
389 db 1 ;AN000;first subst
390 db Char_field_ASCIIZ ;AN000;character string
391 db 64 ;AN000;maximum width
392 db 0 ;AN000;minimum width
393 db blank ;AN000;pad character
394 db parm_block_size ;AN000;size of sublist
395 db 0 ;AN000;reserved
396 dw OFFSET RESGROUP:CPDRV ;AN000;offset of arg
397COMPRMT1_SEG2 dw 0 ;AN000;segment of arg
398 db 2 ;AN000;second subst
399 db Char_field_Char ;AN000;one character
400 db 1 ;AN000;maximum width
401 db 1 ;AN000;minimum width
402 db blank ;AN000;pad character
403
404cpdrv DB " "
405;
406; Exec error messages
407;
408EXECEMES_SUBST db 1 ;AN000; number of subst
409EXECEMES_BLOCK db parm_block_size ;AN000;size of sublist
410 db 0 ;AN000;reserved
411EXECEMES_OFF dw 0 ;AN000;offset of arg
412EXECEMES_SEG dw 0 ;AN000;segment of arg
413 db 1 ;AN000;first subst
414 db Char_field_ASCIIZ ;AN000;character string
415 db 64 ;AN000;maximum width
416 db 0 ;AN000;minimum width
417 db blank ;AN000;pad character
418
419;
420; These characters MUST remain in order
421;
422abort_char db "A"
423retry_char db "R"
424ignore_char db "I"
425fail_char db "F"
426yes_char db "Y"
427no_char db "N"
428;
429; End of characters that MUST remain in order
430;
431ENDIF
432
433RemMsg DD ? ;Pointer to message in error 15
434ErrType DB ? ; Error message style, 0=old, 1=new
435
436INT_2E_RET DD ? ; Magic command executer return address
437SAVE_PDB DW ?
438PARENT DW ?
439OldTerm DD ?
440ERRCD_24 DW ?
441HANDLE01 DW ?
442LOADING DB 0
443BATCH DW 0 ; Assume no batch mode initially
444COMSPEC DB 64 DUP(0)
445comspec_end dw ?
446TRANS DW OFFSET TRANGROUP:COMMAND
447TRNSEG DW ?
448; BAS DEBUG
449TrnMvFlg DB 0 ; Indicate if transient portion has been moved
450
451In_Batch DB 0 ; Indicate if we are in Batch processing mode.
452Batch_Abort DB 0 ; Indicate if user wants to abort from batch mode.
453
454COMDRV DB ? ; DRIVE SPEC TO LOAD AUTOEXEC AND COMMAND
455MEMSIZ DW ?
456SUM DW ?
457EXTCOM DB 1 ; For init, pretend just did an external
458RETCODE DW ?
459CRIT_ERR_INFO DB ? ;G hold critical error flags for R,I,F
460rsrc_xa_seg DW -1 ;AN030; holds segment of xa copy buffer
461
462;
463; The echo flag needs to be pushed and popped around pipes and batch files.
464; We implement this as a bit queue that is shr/shl for push and pop.
465;
466ECHOFLAG DB 00000001B ; low bit TRUE => echo commands
467SUPPRESS DB 1 ; used for echo, 1=echo line
468IO_SAVE DW ?
469RESTDIR DB 0
470PERMCOM DB 0 ; TRUE => permanent command
471SINGLECOM DW 0 ; TRUE => single command version
472VERVAL DW -1
473fFail DB 0 ; TRUE => FAIL all INT 24s
474IFFLAG DB 0 ; TRUE => If statement in progress
475
476FORFLAG DB 0 ; TRUE => FOR statement in progress
477FORPTR DW 0
478
479NEST DW 0 ; NESTED BATCH FILE COUNTER
480CALL_FLAG DB 0 ; NO CALL (BATCH COMMAND) IN PROGRESS
481CALL_BATCH_FLAG DB 0
482NEXT_BATCH DW 0 ; ADDRESS OF NEXT BATCH SEGMENT
483NULLFLAG DB 0 ; FLAG IF NO COMMAND ON COMMAND LINE
484COM_XLAT_ADDR DB 5 DUP (0) ;G BUFFER FOR TRANSLATE TABLE ADDRESS
485FUCASE_ADDR DB 5 DUP (0) ;AN000; BUFFER FOR FILE UCASE ADDRESS
486CRIT_MSG_OFF DW 0 ;AN000; SAVED CRITICAL ERROR MESSAGE OFFSET
487CRIT_MSG_SEG DW 0 ;AN000; SAVED CRITICAL ERROR MESSAGE SEGMENT
488;AD060; PARS_MSG_OFF DW 0 ;AN000; SAVED PARSE ERROR MESSAGE OFFSET
489;AD060; PARS_MSG_SEG DW 0 ;AN000; SAVED PARSE ERROR MESSAGE SEGMENT
490Dbcs_vector_addr DW 0 ;AN000; DBCS vector offset
491 DW 0 ;AN000; DBCS vector segment
492APPEND_STATE DW 0 ;AN020; current state of append (if flag = -1)
493APPEND_FLAG DB 0 ;AN020; set if APPEND state valid
494
495RE_OUT_APP DB 0
496RE_OUTSTR DB 64+3+13 DUP (?)
497
498;
499; We flag the state of COMMAND in order to correctly handle the ^Cs at
500; various times. Here is the breakdown:
501;
502; initINIT We are in the init code.
503; initSpecial We are in the date/time prompt
504; initCtrlC We are handling a ^C already.
505;
506; If we get a ^C in the initialization but not in the date/time prompt, we
507; ignore the ^C. This is so the system calls work on nested commands.
508;
509; If we are in the date/time prompt at initialization, we stuff the user's
510; input buffer with a CR to pretend an empty response.
511;
512; If we are already handling a ^C, we set the carry bit and return to the user
513; (ourselves). We can then detect the carry set and properly retry the
514; operation.
515;
516
517InitFlag DB initINIT
518
519;These two bytes refed as a word
520PIPEFLAG DB 0
521PIPEFILES DB 0
522
523;--- 2.x data for piping
524;
525; All the "_" are substituted later, the one before the : is substituted
526; by the current drive, and the others by the CreateTemp call with the
527; unique file name. Note that the first 0 is the first char of the pipe
528; name. -MU
529;
530;--- Order dependant, do not change
531
532Pipe1 db "_:/"
533Pipe1T db 0
534 db "_______.___",0
535Pipe2 db "_:/"
536Pipe2T db 0
537 db "_______.___",0
538
539PIPEPTR DW ?
540PIPESTR DB 129 DUP(?)
541INPIPEPTR DW OFFSET ResGroup:PIPE1
542OUTPIPEPTR DW OFFSET ResGroup:PIPE2
543
544EXEC_BLOCK LABEL BYTE ; The data block for EXEC calls
545ENVIRSEG DW ?
546COM_PTR LABEL DWORD
547 DW 80H ; Point at unformatted parameters
548 DW ?
549COM_FCB1 LABEL DWORD
550 DW 5CH
551 DW ?
552COM_FCB2 LABEL DWORD
553 DW 6CH
554 DW ?
555
556TRANVARS LABEL BYTE ; Variables passed to transient
557 DW OFFSET ResGroup:THEADFIX
558MYSEG DW 0 ; Put our own segment here
559LTPA DW 0 ; WILL STORE TPA SEGMENT HERE
560RSWITCHAR DB "-"
561RDIRCHAR DB "/"
562 DW OFFSET ResGroup:EXT_EXEC
563MYSEG1 DW ?
564 DW OFFSET ResGroup:TREMCHECK
565MYSEG2 DW 0
566ResTest DW 0
567RES_TPA DW 0 ; Original TPA (not rounded to 64K)
568TranVarEnd LABEL BYTE
569
570olderrno dw ?
571
572RESMSGEND DW 0 ;AN000;; holds offset of msg end (end of resident)
573
574.xlist
575.xcref
576
577INCLUDE SYSMSG.INC ;AN000; include message services
578
579.list
580.cref
581
582ASSUME DS:RESGROUP,ES:RESGROUP,CS:RESGROUP
583
584MSG_UTILNAME <COMMAND> ;AN000; define utility name
585
586;AD054; MSG_SERVICES <COMR,MSGDATA,COMMAND.CLA,COMMAND.CL3,COMMAND.CL4> ;AN000; get message services data and resident messages
587MSG_SERVICES <COMR,MSGDATA,COMMAND.CLA> ;AN054; get message services data and resident messages
588
589
590CRITICAL_MSG_START LABEL BYTE ;AN000; start of critical error messages
591
592MSG_SERVICES <COMR,COMMAND.CLD> ;AN000; get critical error messages
593
594DATARESEND LABEL BYTE ;AC060; end of resident portion if /msg not used
595
596PARSE_MSG_START LABEL BYTE ;AN000; start of parse error messages
597
598MSG_SERVICES <COMR,COMMAND.CLC> ;AN000; get parse error messages
599
600;AD060; DATARESEND LABEL BYTE ; end of resident portion if /msg not used
601
602EXTENDED_MSG_START LABEL BYTE ;AN000; start of extended error messages
603
604MSG_SERVICES <COMR,COMMAND.CLE> ;AN000; get extended error messages
605
606EXTMSGEND LABEL BYTE ;AN000; end of extended error messages
607
608include msgdcl.inc
609
610DATARES ENDS
611 END
diff --git a/v4.0/src/CMD/COMMAND/RESMSG.EQU b/v4.0/src/CMD/COMMAND/RESMSG.EQU
new file mode 100644
index 0000000..9eb5187
--- /dev/null
+++ b/v4.0/src/CMD/COMMAND/RESMSG.EQU
@@ -0,0 +1,43 @@
1; SCCSID = @(#)resmsg.equ 4.1 85/09/10
2; SCCSID = @(#)resmsg.equ 4.1 85/09/10
3
4;****************************
5;* RESIDENT MESSAGE EQUATES *
6;****************************
7
8REQ_ABORT EQU 210 ;AC000; "Abort"
9REQ_RETRY EQU 211 ;AC000; ", Retry"
10REQ_IGNORE EQU 212 ;AC000; ", Ignore"
11REQ_FAIL EQU 213 ;AC000; ", Fail"
12REQ_END EQU 214 ;AC000; "? "
13MREAD EQU 215 ;AC000; "reading"
14MWRITE EQU 216 ;AC000; "writing"
15DRVNUM EQU 217 ;AC000; "%1 drive %2"
16DEVEMES EQU 218 ;AC000; "%1 device %2"
17Err15Mes EQU 219 ;AC000; "Please insert volume %1 serial %2"
18BADFAT EQU 220 ;AC000; "File allocation table bad, drive %1"
19COMBAD EQU 221 ;AC000; 13,10,"Invalid COMMAND.COM",13,10"
20comprmt1 EQU 222 ;AC000; "Insert disk with %1 in drive %1"
21PROMPT EQU 223 ;AC000; "Press any key to continue"
22ENDBATMES EQU 224 ;AC000; 13,10,"Terminate batch job (Y/N)? "
23EXECEMES EQU 225 ;AC000; "Cannot execute %1",13,10
24EXEBAD EQU 226 ;AC000; "Error in EXE file",13,10
25TOOBIG EQU 227 ;AC000; "Program too big to fit in memory",13,10
26NOHANDMES EQU 228 ;AC000; 13,10,"No free file handles"
27RBADNAM EQU 229 ;AC000; "Bad Command or file name",13,10
28AccDen EQU 230 ;AC000; Extended error - "Access denied",13,10
29BMEMMES EQU 231 ;AC000; 13,10,"Memory allocation error "
30HALTMES EQU 232 ;AC000; 13,10,"Cannot load COMMAND, system halted"
31FRETMES EQU 233 ;AC000; 13,10,"Cannot start COMMAND, exiting",13,10
32Patricide EQU 234 ;AC000; 13,10,"Top level process aborted, cannot continue."
33NEWLIN EQU 235 ;AC000; 13,10
34
35;************************
36;* INIT MESSAGE EQUATES *
37;************************
38
39BADVER EQU 461 ;AC000; "Incorrect DOS version",13,10,"$"
40OUTENVERR_PTR EQU 463 ;AC000; "Out of environment space",13,10,0
41HEADER_PTR EQU 464 ;AC000; Long Copyright Notice
42BADCOMLKMES_PTR EQU 465 ;AC000;"Specified COMMAND search directory bad",13,10,0
43BADCOMACCMES_PTR EQU 466 ;AC000; "Specified COMMAND search directory bad access denied",13,10,0
diff --git a/v4.0/src/CMD/COMMAND/RUCODE.ASM b/v4.0/src/CMD/COMMAND/RUCODE.ASM
new file mode 100644
index 0000000..5a6f413
--- /dev/null
+++ b/v4.0/src/CMD/COMMAND/RUCODE.ASM
@@ -0,0 +1,739 @@
1 page 80,132
2; SCCSID = @(#)rucode.asm 4.5 85/07/22
3; SCCSID = @(#)rucode.asm 4.5 85/07/22
4TITLE COMMAND Language modifiable Code Resident
5
6
7.xlist
8.xcref
9INCLUDE DOSSYM.INC ;AC000;
10include doscntry.inc ;AC000;
11DEBUG = 0 ; NEED TO SET IT TO WHAT IT IS IN DOSSYM.INC
12
13
14 INCLUDE DEVSYM.INC
15 INCLUDE comsw.asm
16 INCLUDE comseg.asm
17 INCLUDE comequ.asm
18 include resmsg.equ ;AN000;
19.list
20.cref
21
22
23Tokenized = FALSE
24
25DATARES SEGMENT PUBLIC BYTE ;AC000;
26 EXTRN abort_char:byte
27 EXTRN badfat_block:byte ;AC000;
28 EXTRN badfat_subst:byte ;AC000;
29 EXTRN Batch_Abort:byte
30 EXTRN CDEVAT:BYTE
31 EXTRN COMSPEC:BYTE ;AN060;
32 EXTRN com_xlat_addr:word
33 EXTRN crit_err_info:byte
34 EXTRN crit_msg_off:word ;AC000;
35 EXTRN crit_msg_seg:word ;AC000;
36 EXTRN dbcs_vector_addr:dword ;AN000;
37 EXTRN devemes_block:byte ;AC000;
38 EXTRN devemes_subst:byte ;AC000;
39 EXTRN DEVENAM:BYTE
40 EXTRN deve_op_off:word ;AC000;
41 EXTRN disp_class:byte ;AC000;
42 EXTRN DRVLET:BYTE
43 EXTRN drvnum_block:byte ;AC000;
44 EXTRN drvnum_op_off:word ;AC000;
45 EXTRN drvnum_subst:byte ;AC000;
46 EXTRN err15mes_block:byte ;AC000;
47 EXTRN err15mes_subst:byte ;AC000;
48 EXTRN ERRCD_24:WORD
49 EXTRN ErrType:BYTE
50 EXTRN fail_char:byte
51 EXTRN fFail:BYTE
52 EXTRN FORFLAG:BYTE
53 EXTRN ignore_char:byte
54 EXTRN InitFlag:BYTE
55 EXTRN In_Batch:byte
56 EXTRN LOADING:BYTE
57;AD054; EXTRN MESBAS:BYTE
58 EXTRN no_char:byte
59 EXTRN number_subst:byte ;AC000;
60 EXTRN olderrno:word
61 EXTRN PARENT:WORD
62;AD060; EXTRN pars_msg_off:word ;AC000;
63;AD060; EXTRN pars_msg_seg:word ;AC000;
64 EXTRN PERMCOM:BYTE
65 EXTRN RemMsg:DWORD
66 EXTRN retry_char:byte
67 EXTRN PIPEFLAG:BYTE
68 EXTRN SINGLECOM:WORD
69 EXTRN VolName:BYTE
70 EXTRN yes_char:byte
71
72 IF Tokenized
73 EXTRN IOTYP:BYTE
74 EXTRN MESADD:BYTE
75 ENDIF
76
77DATARES ENDS
78
79
80CODERES SEGMENT PUBLIC BYTE
81
82 EXTRN GETCOMDSK2:NEAR
83
84 PUBLIC ASKEND
85 PUBLIC CRLF
86 PUBLIC DSKERR
87 PUBLIC ITESTKANJ ;AN000;
88 PUBLIC RESET_MSG_POINTERS ;AC000;
89 PUBLIC RPRINT
90
91ASSUME CS:RESGROUP,DS:NOTHING,ES:NOTHING,SS:NOTHING
92
93;
94; AskEnd - prompt the user to see if he should terminate the batch file. If
95; any system call returns with carry set or if RPRINT returns with carry set,
96; we jump to the top and start over.
97;
98; Returns: carry set if response indicates that the batch file should
99; be terminated.
100; carry clear otherwise.
101;
102
103ASSUME DS:RESGROUP
104ASKEND:
105 MOV DX,ENDBATMES ;AC000; get batch terminate question
106 CALL RPRINT
107 MOV AX,(STD_CON_INPUT_FLUSH SHL 8)+STD_CON_INPUT
108 INT 21H
109 call in_char_xlat ;g change to upper case
110 CMP AL,no_char
111 retz ; carry is clear => no free
112 CMP AL,yes_char
113 JNZ ASKEND
114 stc ; carry set => free batch
115 return
116
117DSKERR:
118ASSUME DS:NOTHING,ES:NOTHING,SS:NOTHING
119 ; ******************************************************
120 ; THIS IS THE DEFAULT DISK ERROR HANDLING CODE
121 ; AVAILABLE TO ALL USERS IF THEY DO NOT TRY TO
122 ; INTERCEPT INTERRUPT 24H.
123 ; ******************************************************
124 STI
125 PUSH DS
126 PUSH ES
127 PUSH SI ;AN000; save si
128 PUSH CX
129 PUSH DI
130 PUSH CX
131 PUSH AX
132 MOV DS,BP
133 MOV AX,[SI.SDEVATT]
134 MOV [CDEVAT],AH
135 PUSH CS
136 POP ES
137 MOV DI,OFFSET RESGROUP:DEVENAM
138 MOV CX,8
139 ADD SI,SDEVNAME ; Suck up device name (even on Block)
140 REP MOVSB
141 POP AX
142 POP CX
143 POP DI ; Stack just contains DS and ES
144 ; at this point
145 INVOKE SAVHAND
146 PUSH CS
147 POP DS ; Set up local data segment
148ASSUME DS:RESGROUP
149
150 PUSH DX
151 CALL CRLF
152 POP DX
153 MOV CRIT_ERR_INFO,AH ;G save so we know if R,I,F are valid
154
155 ADD AL,'A' ; Compute drive letter (even on character)
156 MOV [DRVLET],AL
157 TEST AH,80H ; Check if hard disk error
158 JZ NOHARDE
159 TEST [CDEVAT],DEVTYP SHR 8
160 JNZ NOHARDE
161 JMP FATERR
162
163NOHARDE:
164 MOV SI,MREAD ;AC000;
165 TEST AH,1
166 JZ SAVMES
167 MOV SI,MWRITE ;AC000;
168
169SAVMES:
170 IF Tokenized
171 LODSW
172 MOV WORD PTR [IOTYP],AX
173 LODSW
174 MOV WORD PTR [IOTYP+2],AX
175 ENDIF
176
177 mov olderrno,di ; keep code in a safe place
178 PUSH ES ;AN000;
179 PUSH DS ; GetExtendedError likes to STOMP
180 PUSH BP
181 PUSH SI
182 PUSH DX
183 PUSH CX
184 PUSH BX
185 mov ah,GetExtendedError ; get extended error code
186 INT 21H
187 POP BX
188 POP CX
189 POP DX
190 POP SI
191 POP BP
192 POP DS
193 mov word ptr cs:[RemMsg],di ;AC000; save pointer to remote message
194 mov word ptr cs:[RemMsg+2],es ;AC000; (only used on code 15)
195 pop ES ;AN000;
196 XOR AH,AH
197 mov di,ax ; REAL error code to DI
198;
199; DI is now the correct error code. Classify things to see what we are
200; allowed to report. We convert DI into a 0-based index into a message table.
201; This presumes that the int 24 errors (oldstyle) and new errors (sharing and
202; the like) are contiguous.
203;
204 SUB DI,error_write_protect
205 JAE HavCod
206 MOV DI,error_Gen_failure-error_write_protect
207;
208; DI now has the mapped error code. Old style errors are:
209; FOOBAR <read|writ>ing drive ZZ.
210; New style errors are:
211; FOOBAR
212; We need to figure out which the particular error belongs to.
213;
214
215HAVCOD:
216 mov ErrType,0 ; assume Old style
217 cmp di,error_FCB_Unavailable-error_write_protect
218 jz SetStyle
219 cmp di,error_sharing_buffer_exceeded-error_write_protect
220 jnz GotStyle
221
222SetStyle:
223 mov ErrType,1 ; must be new type
224
225GotStyle:
226 MOV [ERRCD_24],DI
227 cmp di,error_handle_disk_full-error_write_protect ;AC026;
228 ; If the error message is unknown
229 jbe NormalError ; redirector, continue. Otherwise,
230;
231; We do not know how to handle this error. Ask IFSFUNC if she knows
232; how to handle things
233;
234
235;input to IFSFUNC: AL=1
236; BX=extended error number
237
238;output from IFSFUNC: AL=error type (0 or 1)
239; 0=<message> error (read/writ)ing (drive/device) xxx
240; Abort, Retry, Ignore
241; 1=<message>
242; Abort, Retry, Ignore
243; ES:DI=pointer to message text
244; carry set=>no message
245
246 MOV DI,AX ; retrieve correct extended error...
247 mov ax,0500h ; Is the redir there?
248 int 2fh
249 cmp al,0ffh
250 jnz NoHandler ; No, go to NoHandler
251 push bx ;AN063;
252 mov bx,di ; Get ErrType and ptr to error msg ;AC063;
253 mov ax,0501h ;AC063;
254 int 2fh
255 pop bx ;AC063;
256 jc NoHandler
257
258 mov ErrType,al
259 push ds
260 push es
261 pop ds
262 mov dx,di
263 mov cx,-1 ; Find the end of the error msg and turn
264 xor al,al ; the high byte on for rprint
265 repnz scasb
266
267 IF Tokenized
268 or byte ptr [di-2],80h
269 call rprint ; Print the message
270 and byte ptr [di-2], NOT 80h ; Restore msg to original condition
271 ELSE
272 mov byte ptr [di-1],'$'
273 MOV AH,Std_con_string_output ;AC000; Print the message
274 INT 21h ;AN000;
275 mov byte ptr [di-1],0 ; Restore msg to original condition
276 ENDIF
277
278 pop ds ; Clean up and continue processing
279 jmp short CheckErrType
280
281NoHandler: ; Redir isn't available or doesn't
282 mov ErrType,0 ; recognize the error. Reset vars and
283 mov di,olderrno ; regs to unextended err and continue
284 mov ERRCD_24,di ; normally.
285
286NormalError:
287;AD054; SHL DI,1
288;AD054; MOV DI,WORD PTR [DI+MESBAS] ; Get pointer to error message
289 add DI,error_write_protect ;AN054;
290 XCHG DI,DX ; May need DX later
291 MOV DISP_CLASS,EXT_CRLF_CLASS ;AN054; printing extended error class
292 CALL RPRINT ; Print error type
293
294CheckErrType:
295 cmp ErrType,0 ; Check error style...
296 je ContOld
297 call CRLF ; if new style then done printing
298 jmp short ASK
299
300ContOld:
301 IF NOT Tokenized
302 MOV AX,SI ;AN000; get reading/writing for message
303 MOV DH,UTIL_MSG_CLASS ;AN000; this is a utility message
304 CALL SYSGETMSG ;AN000; get the message
305 ENDIF
306
307 TEST [CDEVAT],DEVTYP SHR 8
308 JZ BLKERR
309 MOV DX,DEVEMES ;AC000; get message number for device message
310 MOV DEVE_OP_OFF,SI ;AN000; put address of read/write in subst block
311 MOV AL,DEVEMES_SUBST ;AN000; get number of substitutions
312 MOV NUMBER_SUBST,AL ;AN000;
313 MOV SI,OFFSET RESGROUP:DEVEMES_BLOCK;AN000; get address of subst block
314
315 CALL RPRINT ;AC000; print the message
316 JMP SHORT ASK ; Don't ralph on COMMAND
317
318BLKERR:
319 MOV DX,DRVNUM ;AN000; get drive message number
320 MOV DRVNUM_OP_OFF,SI ;AN000; put address of read/write in subst block
321 MOV AL,DRVNUM_SUBST ;AN000; get number of substitutions
322 MOV NUMBER_SUBST,AL ;AN000;
323 MOV SI,OFFSET RESGROUP:DRVNUM_BLOCK ;AN000; get address of subst block
324 CALL RPRINT
325 CMP [LOADING],0
326 JZ ASK
327 INVOKE RESTHAND
328 JMP GETCOMDSK2 ; If error loading COMMAND, re-prompt
329
330ASK:
331 cmp [ERRCD_24],15 ; Wait! Error 15 has an extra message
332 jne Not15
333 PUSH CX
334 push ds
335 pop es
336 lds si,[RemMsg]
337assume ds:nothing
338 push di
339 mov di,offset resgroup:VolName
340 mov cx,16 ;AC000; extra message volume name & serial number
341 cld ; just in case!
342 rep movsb
343 pop di
344 push es
345 pop ds
346 POP CX
347assume ds:resgroup
348 mov dx,Err15Mes ;AC000; get message number
349 MOV AL,ERR15MES_SUBST ;AN000; get number of substitutions
350 MOV NUMBER_SUBST,AL ;AN000;
351 MOV SI,OFFSET RESGROUP:ERR15MES_BLOCK ;AN000; get address of subst block
352 CALL RPRINT
353
354; PRINT OUT ABORT, RETRY, IGNORE, FAIL MESSAGE. ONLY PRINT OUT OPTIONS
355; THAT ARE VALID
356
357Not15:
358 MOV DX,REQ_ABORT ;AC000;G print out abort message
359 CALL RPRINT ;G
360 TEST CRIT_ERR_INFO,RETRY_ALLOWED ;G is retry allowed?
361 JZ TRY_IGNORE ;G
362 MOV DX,REQ_RETRY ;AC000;G yes,print out retry message
363 CALL RPRINT ;G
364
365try_ignore:
366 TEST CRIT_ERR_INFO,IGNORE_ALLOWED ;G is ignore allowed?
367 JZ TRY_FAIL ;G
368 MOV DX,REQ_IGNORE ;AC000;G yes,print out ignore message
369 CALL RPRINT ;G
370
371try_fail:
372 TEST CRIT_ERR_INFO,FAIL_ALLOWED ;G is FAIL allowed?
373 JZ TERM_QUESTION ;G
374 MOV DX,REQ_FAIL ;AC000;G yes,print out FAIL message
375 CALL RPRINT ;G
376
377Term_Question:
378 MOV DX,REQ_END ;AC000;G terminate the string
379 CALL RPRINT ;G
380;
381; If the /f switch was given, we fail all requests...
382;
383 TEST fFail,-1
384 JZ DoPrompt
385 MOV AH,3 ; signal fail
386 JMP EExit
387
388DoPrompt:
389 MOV AX,(STD_CON_INPUT_FLUSH SHL 8)+STD_CON_INPUT
390 INT 21H ; Get response
391
392 invoke TestKanjR ;AN000; 3/3/KK
393 jz notkanj ;AN000; 3/3/KK
394 MOV AX,(STD_CON_INPUT SHL 8) ;AN000; eat the 2nd byte of ECS code 3/3/KK
395 INT 21H ;AN000; 3/3/KK
396 CALL CRLF ;AN000; 3/3/KK
397 JMP ASK ;AN000; 3/3/KK
398
399notkanj: ;AN000; 3/3/KK
400 CALL CRLF
401 CALL IN_CHAR_XLAT ;G Convert to upper case
402 MOV AH,0 ; Return code for ignore
403 TEST CRIT_ERR_INFO,IGNORE_ALLOWED ;G is IGNORE allowed?
404 JZ USER_RETRY ;G
405 CMP AL,ignore_char ; Ignore?
406 JZ EEXITJ
407
408USER_RETRY:
409 INC AH ; return code for retry
410 TEST CRIT_ERR_INFO,RETRY_ALLOWED ;G is RETRY allowed?
411 JZ USER_ABORT ;G
412 CMP AL,retry_char ; Retry?
413 JZ EEXITJ
414
415USER_ABORT:
416 INC AH ; return code for abort - always allowed
417 CMP AL,abort_char ; Abort?
418 JZ abort_process ;G exit user program
419 INC AH ;G return code for fail
420 TEST CRIT_ERR_INFO,FAIL_ALLOWED ;G is FAIL allowed?
421 JZ ASKJ ;G
422 CMP AL,fail_char ;G fail?
423 JZ EEXITJ ;G
424
425ASKJ:
426 JMP ASK ;G
427
428EEXITJ:
429 JMP SHORT EEXIT ;G
430
431abort_process:
432 test InitFlag,initINIT ; Was command initialization interrupted
433 jz AbortCont ; No, handle it normally
434 cmp PERMCOM,0 ; Is this the top level process?
435 jz JustExit ; Yes, just exit
436 mov dx,Patricide ;AC000; No, load ptr to error msg
437 call RPRINT ; Print it
438
439DeadInTheWater:
440 jmp DeadInTheWater ; Loop until the user reboots
441
442JustExit:
443ASSUME DS:RESGROUP
444 call reset_msg_pointers ;AN000; reset critical & parse message addresses
445 mov ax,[PARENT] ; Load real parent PID
446 mov word ptr ds:[PDB_Parent_PID],ax ; Put it back where it belongs
447 mov ax,(Exit SHL 8) OR 255
448 int 21H
449
450AbortCont:
451 test byte ptr [In_Batch],-1 ; Are we accessing a batch file?
452 jz Not_Batch_Abort
453 mov byte ptr [Batch_Abort],1 ; set flag for abort
454
455Not_Batch_Abort:
456 mov dl,PipeFlag
457 invoke ResPipeOff
458 OR DL,DL
459 JZ CHECKFORA
460 CMP [SINGLECOM],0
461 JZ CHECKFORA
462 MOV [SINGLECOM],-1 ; Make sure SINGLECOM exits
463
464CHECKFORA:
465 CMP [ERRCD_24],0 ; Write protect
466 JZ ABORTFOR
467 CMP [ERRCD_24],2 ; Drive not ready
468 JNZ EEXIT ; Don't abort the FOR
469
470ABORTFOR:
471 MOV [FORFLAG],0 ; Abort a FOR in progress
472 CMP [SINGLECOM],0
473 JZ EEXIT
474 MOV [SINGLECOM],-1 ; Make sure SINGLECOM exits
475
476EEXIT:
477 MOV AL,AH
478 MOV DX,DI
479
480RESTHD:
481 INVOKE RESTHAND
482 POP CX
483 POP SI ;AN000; restore registers
484 POP ES
485 POP DS
486 IRET
487
488FATERR:
489 MOV DX,BADFAT ;AC000;
490 MOV AL,BADFAT_SUBST ;AN000; get number of substitutions
491 MOV NUMBER_SUBST,AL ;AN000;
492 MOV SI,OFFSET RESGROUP:BADFAT_BLOCK ;AN000; get address of subst block
493 CALL RPRINT
494
495 IF Tokenized
496 MOV DX,OFFSET RESGROUP:ERRMES
497 CALL RPRINT
498 ENDIF
499
500 MOV AL,2 ; Abort
501 JMP RESTHD
502
503;*********************************************
504; Print routines for Tokenized resident messages
505
506ASSUME DS:RESGROUP,SS:RESGROUP
507
508CRLF:
509 MOV DX,NEWLIN ;AC000;
510
511;
512; RPRINT prints out a message on the user's console. We clear carry before
513; each system call. We do this so that the ^C checker may change things so
514; that carry is set. If we detect a system call that returns with carry set,
515; we merely return.
516;
517; Inputs: DX has the message number as an offset from DS.
518; Outputs: Carry clear: no carries detected in the system calls
519; Carry set: at least one system call returned with carry set
520; Registers modified: none
521;
522
523RPRINT:
524
525;
526; If we are not tokenized, the message consists of a $-terminated string.
527; Use CPM io to output it.
528;
529
530if NOT tokenized
531 PUSH AX
532 PUSH BX ;AC000; save BX register
533 PUSH CX ;AC000; save CX register
534 PUSH DX ;AC000; save DX register
535 MOV AX,DX ;AC000; get message number
536 MOV DH,DISP_CLASS ;AC000; get display class
537 MOV DL,NO_CONT_FLAG ;AN000; set control flags off
538 MOV BX,NO_HANDLE_OUT ;AC000; set message handler to use function 1-12
539 XOR CH,CH ;AC000; clear upper part of cx
540 MOV CL,NUMBER_SUBST ;AC000; set number of substitutions
541 CALL SYSDISPMSG ;AC000; display the message
542 MOV DISP_CLASS,UTIL_MSG_CLASS ;AC000; reset display class
543 MOV NUMBER_SUBST,NO_SUBST ;AC000; reset number of substitutions
544 POP DX ;AC000; restore registers
545 POP CX ;AC000;
546 POP BX ;AC000;
547 POP AX
548
549 return
550endif
551
552;
553; If we are tokenized, output character-by-character. If there is a digit in
554; the output, look up that substring in the tokenization table. Use the high
555; bit to determine the end-of-string.
556;
557
558If Tokenized
559 SaveReg <AX,DX,SI>
560 MOV SI,DX
561
562RPRINT1:
563 LODSB
564 PUSH AX ; save for EOS testing
565 AND AL,7FH
566 CMP AL,'0'
567 JB RPRINT2
568 CMP AL,'9'
569 JA RPRINT2
570 SUB AL,'0'
571 CBW ; DS must be RESGROUP if we get here
572 SHL AX,1 ; clear carry
573 XCHG SI,AX
574 MOV DX,[SI + OFFSET RESGroup:MesADD]
575 CALL RPrint
576 XCHG SI,AX
577 JMP SHORT RPRINT3
578
579RPRINT2:
580 MOV DL,AL
581 MOV AH,STD_CON_OUTPUT
582 clc ; set ok flag
583 INT 21H
584
585RPRINT3:
586 POP AX
587 JC RPrint5 ; Abnormal termination?
588 TEST AL,80h ; High bit set indicates end (carry clear)
589 JZ RPRINT1
590
591RPRINT5:
592 RestoreReg <SI,DX,AX>
593 RET
594endif
595
596
597;g
598;g This routine returns the upper case of the character in AL
599;g from the upper case table in DOS if character if above
600;g ascii 128, else subtract 20H if between "a" and "z"
601;g
602
603assume ds:resgroup
604
605in_char_xlat proc near
606
607 cmp al,80h ;g see if char is above ascii 128
608 jb other_xlat ;g no - upper case math
609 sub al,80h ;g only upper 128 characters in table
610 push ds
611 push bx
612 lds bx,dword ptr com_xlat_addr+1 ;g get table address
613 add bx,2 ;g skip over first word, of table
614 xlat ds:byte ptr [bx] ;g convert to upper case
615 pop bx
616 pop ds
617 jmp short in_char_xlat_end ;g we finished - exit
618
619other_xlat:
620 cmp al,'a' ;g if between "a" and "z", subtract
621 jb in_char_xlat_end ;g 20h to get upper case
622 cmp al,'z' ;g equivalent.
623 ja in_char_xlat_end ;g
624 sub al,20h ;g Lower-case changed to upper-case
625
626in_char_xlat_end:
627
628 ret
629
630in_char_xlat endp
631;---------------------- DBCS lead byte check. this is resident code ; 3/3/KK
632
633ITESTKANJ: ;AN000;
634TestKanjR: ;AN000; 3/3/KK
635 push ds ;AN000; 3/3/KK
636 push si ;AN000; 3/3/KK
637 push ax ;AN000; 3/3/KK
638 lds si,dbcs_vector_addr ;AN000; GET DBCS VECTOR
639
640ktlop: ;AN000; 3/3/KK
641 cmp word ptr ds:[si],0 ;AN000; 3/3/KK end of Lead Byte Table
642 je notlead ;AN000; 3/3/KK
643 pop ax ;AN000; 3/3/KK
644 push ax ;AN000; 3/3/KK
645 cmp al, byte ptr ds:[si] ;AN000; 3/3/KK
646 jb notlead ;AN000; 3/3/KK
647 inc si ;AN000; 3/3/KK
648 cmp al, byte ptr ds:[si] ;AN000; 3/3/KK
649 jbe islead ;AN000; 3/3/KK
650 inc si ;AN000; 3/3/KK
651 jmp short ktlop ;AN000; 3/3/KK try another range
652
653Notlead: ;AN000; 3/3/KK
654 xor ax,ax ;AN000; 3/3/KK set zero
655 jmp short ktret ;AN000; 3/3/KK
656
657Islead: ;AN000; 3/3/KK
658 xor ax,ax ;AN000; 3/3/KK reset zero
659 inc ax ;AN000; 3/3/KK
660
661ktret: ;AN000; 3/3/KK
662 pop ax ;AN000; 3/3/KK
663 pop si ;AN000; 3/3/KK
664 pop ds ;AN000; 3/3/KK
665 return ;AN000; 3/3/KK
666
667
668; ****************************************************************
669; *
670; * ROUTINE: RESET_MSG_POINTERS
671; *
672; * FUNCTION: Resets addresses for parse and critical error
673; * messages in DOS via INT 2fh. This routine
674; * is invoked before command exits.
675; *
676; * INPUT: none
677; *
678; * OUTPUT: none
679; *
680; ****************************************************************
681
682reset_msg_pointers proc near
683
684assume ds:resgroup, es:nothing
685
686 push es ;AN000; save used registers
687 push ax ;AN000;
688 push dx ;AN000;
689 push di ;AN000;
690;AD060; mov ah,multdos ;AN000; reset parse message pointers
691;AD060; mov al,message_2f ;AN000; call for message retriever
692;AD060; mov dl,set_parse_msg ;AN000; set up parse message address
693;AD060; mov di,pars_msg_off ;AN000; old offset of parse messages
694;AD060; mov es,pars_msg_seg ;AN000; old segment of parse messages
695;AD060; int 2fh ;AN000; go set it
696
697;AD060; mov ah,multdos ;AN000; set up to call DOS through int 2fh
698;AD060; mov al,message_2f ;AN000; call for message retriever
699 mov ax,(multdos shl 8 or message_2f);AN060; reset critical message pointers
700 mov dl,set_critical_msg ;AN000; set up critical error message address
701 mov di,crit_msg_off ;AN000; old offset of critical messages
702 mov es,crit_msg_seg ;AN000; old segment of critical messages
703 int 2fh ;AN000; go set it
704 pop di ;AN000; restore used registers
705 pop dx ;AN000;
706 pop ax ;AN000;
707 pop es ;AN000;
708
709 ret
710
711
712reset_msg_pointers endp
713
714PUBLIC MSG_SERV_ST ;AN000;
715MSG_SERV_ST LABEL BYTE ;AN000;
716
717PUBLIC SYSGETMSG,SYSDISPMSG
718
719ASSUME DS:RESGROUP, ES:RESGROUP
720
721.xlist
722.xcref
723
724INCLUDE SYSMSG.INC ;AN000; include message services
725
726.list
727.cref
728
729MSG_UTILNAME <COMMAND> ;AN000; define utility name
730
731MSG_SERVICES <COMR,NEARmsg,DISK_PROC,GETmsg,DISPLAYmsg,CHARmsg,NUMmsg> ;AC060; include message services macro
732
733PUBLIC RES_CODE_END ;AN000;
734RES_CODE_END LABEL BYTE ;AN000;
735
736include msgdcl.inc
737
738CODERES ENDS
739 END
diff --git a/v4.0/src/CMD/COMMAND/TBATCH.ASM b/v4.0/src/CMD/COMMAND/TBATCH.ASM
new file mode 100644
index 0000000..6ec51b5
--- /dev/null
+++ b/v4.0/src/CMD/COMMAND/TBATCH.ASM
@@ -0,0 +1,1045 @@
1 page 80,132
2; SCCSID = @(#)tbatch.asm 4.5 85/10/01
3; SCCSID = @(#)tbatch.asm 4.5 85/10/01
4TITLE Batch processing routines
5
6
7.xlist
8.xcref
9 INCLUDE comsw.asm
10 INCLUDE DOSSYM.INC
11 INCLUDE comseg.asm
12 INCLUDE comequ.asm
13 include doscntry.inc ;AN000;
14 include version.inc
15.list
16.cref
17
18
19DATARES SEGMENT PUBLIC BYTE ;AC000;
20 EXTRN BATCH:WORD
21 EXTRN Batch_Abort:byte
22 EXTRN call_batch_flag:byte
23 EXTRN ECHOFLAG:BYTE
24 EXTRN forflag:byte
25 EXTRN forptr:word
26 EXTRN IFFlag:BYTE
27 EXTRN In_Batch:byte
28 EXTRN LTPA:WORD
29 EXTRN Nest:word
30 EXTRN next_batch:word
31 EXTRN nullflag:byte
32 EXTRN PIPEFLAG:BYTE
33 EXTRN RES_TPA:WORD
34 EXTRN SINGLECOM:WORD
35 EXTRN SUPPRESS:BYTE ;AC000;
36DATARES ENDS
37
38TRANDATA SEGMENT PUBLIC BYTE ;AC000;
39 EXTRN BADBAT_PTR:WORD
40 EXTRN Extend_buf_ptr:word ;AC000;
41 EXTRN Extend_buf_sub:byte ;AN022;
42 EXTRN msg_disp_class:byte ;AC000;
43 EXTRN NEEDBAT_PTR:WORD
44 EXTRN pausemes_ptr:word ;AC000;
45TRANDATA ENDS
46
47TRANSPACE SEGMENT PUBLIC BYTE ;AC000;
48 EXTRN BatBufPos:WORD
49 EXTRN BATHAND:WORD
50 EXTRN bwdbuf:byte ;AN022;
51 EXTRN BYTCNT:WORD
52 EXTRN COMBUF:BYTE
53 EXTRN EXECPATH:BYTE
54 EXTRN ID:BYTE
55 EXTRN RCH_ADDR:DWORD
56 EXTRN RESSEG:WORD
57 EXTRN string_ptr_2:word ;AC000;
58 EXTRN TPA:WORD
59 EXTRN TRAN_TPA:WORD
60TRANSPACE ENDS
61
62TRANCODE SEGMENT PUBLIC BYTE
63
64ASSUME CS:TRANGROUP,DS:NOTHING,ES:NOTHING,SS:NOTHING
65
66 EXTRN cerror:near
67 EXTRN tcommand:near
68
69;---------------
70
71TRANSPACE SEGMENT PUBLIC BYTE ;AC000;
72 extrn arg:byte ; the arg structure!
73transpace ends
74;---------------
75
76Break <PromptBat - Open or wait for batch file>
77
78;
79; Open the batch file. If we cannot find the batch file. If the media is
80; changeable, we prompt for the change. Otherwise, we terminate the batch
81; file. Leave segment registers alone.
82;
83
84Procedure PromptBat,NEAR
85 ASSUME DS:ResGroup,ES:NOTHING
86 invoke BATOPEN ; attempt to open batch file
87 retnc
88 cmp dx,error_file_not_found ;AN022; Ask for diskette if file not found
89 jz Bat_Remcheck ;AN022;
90 cmp dx,error_path_not_found ;AN022; Ask for diskette if path not found
91 jz Bat_Remcheck ;AN022; Otherwise, issue message and exit
92 invoke output_batch_name ;AN022; set up batch name in bwdbuf
93 jmp short BatDie ;AN022;
94
95Bat_Remcheck: ;AN022; Go see if media is removable
96 CALL [RCH_ADDR] ; DX has error number
97 JZ AskForBat ; Media is removable
98;
99; The media is not changeable. Turn everything off.
100;
101 invoke ForOff
102 invoke PipeOff
103 MOV IfFlag,AL ; No If in progress.
104 MOV DX,OFFSET TRANGROUP:BADBAT_ptr
105
106BatDie:
107 call BatchOff
108 PUSH CS
109 POP DS
110 ASSUME DS:TranGroup
111 invoke std_eprintf ;AC022; display message
112
113;
114; TCOMMAND resets the stack. This is the equivalent of a non-local goto.
115;
116 JMP TCOMMAND ; he cleans off stack
117
118;
119; Ask the user to reinsert the batch file
120;
121ASKFORBAT:
122 ASSUME DS:ResGroup
123 PUSH DS
124 PUSH CS
125 POP DS
126 ASSUME DS:TranGroup
127 MOV DX,OFFSET TRANGROUP:NEEDBAT_ptr ;AN022;
128 invoke std_eprintf ;Prompt for batch file on stderr
129 mov dx,offset trangroup:pausemes_ptr ;AN000; get second part of message
130 invoke std_eprintf ;AN000; print it to stderr
131 CALL GetKeystroke
132 POP DS
133 ASSUME DS:ResGroup
134 jmp PromptBat
135EndProc PromptBat
136
137;****************************************************************
138;*
139;* ROUTINE: Output_batch_name
140;*
141;* FUNCTION: Sets up batch name to be printed on extended error
142;*
143;* INPUT: DX - extended error number
144;*
145;* OUTPUT: Ready to call print routine
146;*
147;****************************************************************
148
149public output_batch_name ;AN022;
150
151Output_batch_name proc near ;AN022;
152
153 push ds ;AN022; save resident segment
154 mov ds,[batch] ;AN022; get batch file segment
155assume DS:nothing ;AN022;
156 mov SI,BatFile ;AN022; get offset of batch file
157 invoke dstrlen ;AN022; get length of string
158 mov di,offset Trangroup:bwdbuf ;AN022; target for batch name
159 rep movsb ;AN022; move the name
160
161 push cs ;AN022; get local segment
162 pop ds ;AN022;
163assume DS:trangroup ;AN022;
164 mov extend_buf_ptr,dx ;AN022; put message number in block
165 mov msg_disp_class,ext_msg_class ;AN022; set up extended error msg class
166 mov dx,offset TranGroup:Extend_Buf_ptr ;AN022; get extended message pointer
167 mov string_ptr_2,offset trangroup:bwdbuf ;AN022; point to substitution
168 mov extend_buf_sub,one_subst ;AN022; set up for one subst
169 pop ds ;AN022; restore data segment
170
171 ret ;AN022; return
172
173Output_batch_name endp ;AN022;
174
175Break <GetKeystroke - get a keystroke and flush queue>
176
177;
178; read the next keystroke. Since there may be several characters in the queue
179; after the one we ask for (function keys/Kanji), we need to flush the queue
180; AFTER waiting.
181;
182Procedure GetKeyStroke,NEAR
183;
184; read any character at any mode, interim mode or not.
185;
186
187 PUSH DX ;AN000; 3/3/KK
188 MOV AX,(ECS_call SHL 8) OR GetInterimMode ;AN000; 3/3/KK
189 INT int_command ;AN000; 3/3/KK
190 PUSH DX ;AN000; save interim state 3/3/KK
191 MOV AX,(ECS_call SHL 8) OR SetInterimMode ;AN000; 3/3/KK
192 MOV DL,InterimMode ;AN000; 3/3/KK
193 INT int_command ;AN000; 3/3/KK
194
195 MOV AX,(STD_CON_INPUT_FLUSH SHL 8) OR STD_CON_INPUT_no_echo
196 INT int_command ; Get character with KB buffer flush
197 MOV AX,(STD_CON_INPUT_FLUSH SHL 8) + 0
198 INT int_command
199
200 MOV AX,(ECS_call SHL 8) OR SetInterimMode ;AN000; 3/3/KK
201 POP DX ;AN000; restore interim state 3/3/KK
202 INT int_command ;AN000; 3/3/KK
203 POP DX ;AN000; 3/3/KK
204
205 return
206EndProc GetKeyStroke
207
208Break <ReadBat - read 1 line from batch file>
209
210;
211; ReadBat - read a single line from the batch file. Perform all substitutions
212; as appropriate
213;
214
215Procedure ReadBat,NEAR
216 ASSUME DS:ResGroup,ES:TranGroup
217 mov suppress,yes_echo ;g initialize line suppress status
218 test byte ptr [Batch_Abort],-1
219 jnz Trying_To_Abort
220 mov byte ptr [In_Batch],1 ; set flag to indicate batch job
221 CALL PromptBat
222
223Trying_To_Abort:
224 MOV DI,OFFSET TRANGROUP:COMBUF+2
225
226;
227; Save position and try to scan for first non delimiter.
228;
229
230TESTNOP:
231 MOV AX,DS
232 MOV DS,Batch
233 ASSUME DS:NOTHING
234 PUSH WORD PTR DS:[BatSeek]
235 PUSH WORD PTR DS:[BatSeek+2] ; save current location.
236 MOV DS,AX
237 ASSUME DS:ResGroup
238 invoke SkipDelim ; skip to first non-delim
239;
240; If the first non-delimiter is not a : (label), we reseek back to the
241; beginning and read the line.
242;
243 CMP AL,':' ; is it a label?
244 POP CX
245 POP DX ; restore position in bat file
246 JZ NopLine ; yes, resync everything.
247 TEST [BATCH],-1 ; are we done with the batch file?
248 JZ RdBat
249
250 CMP AL, NO_ECHO_CHAR ;g see if user wants to suppress line
251 JNZ SET_BAT_POS ;g no - go and set batch file position
252 MOV SUPPRESS, NO_ECHO ;g yes set flag to indicate
253 jmp Rdbat ;g go read batch file
254
255SET_BAT_POS: ;g
256 PUSH DS
257 MOV DS,Batch
258 ASSUME DS:NOTHING
259 MOV WORD PTR DS:[BatSeek],DX ; reseek back to beginning
260 MOV WORD PTR DS:[BatSeek+2],CX
261 POP DS
262 ASSUME DS:ResGroup
263 MOV AX,(LSEEK SHL 8) + 0 ; seek back
264 INT int_command
265 MOV BatBufPos,-1 ; nuke batch buffer position
266 xor cx,cx ; Initialize line length to zero
267 JMP RdBat
268;
269; The first non-delimiter is a :. This line is not echoed and is ignored.
270; We eat characters until a CR is seen.
271;
272
273NOPLINE:
274 CALL SkipToEOL
275 invoke GetBatByt ; eat trailing LF
276 TEST [BATCH],-1 ; are we done with the batch file?
277 JNZ TESTNOP ; no, go get another line
278 return ; Hit EOF
279
280;
281; Read a line into the buffer pointed to by ES:DI. If any %s are seen in the
282; input, we are to consider two special cases:
283;
284; %0 to %9 These represent replaceable parameters from the batch segment
285; %sym% This is a symbol from the environment
286;
287
288RDBAT:
289 invoke GetBatByt
290 inc cx ; Inc the line length
291 cmp cx,COMBUFLEN ; Is it too long?
292 jae TooLong ; Yes - handle it, handle it
293;
294; See if we have a parameter character.
295;
296 CMP AL,'%' ; Check for parameter
297 JZ NEEDPARM
298;
299; no parameter character. Store it as usual and see if we are done.
300;
301
302SAVBATBYT:
303 STOSB
304 CMP AL,0DH ; End of line found?
305 JNZ RDBAT ; no, go for more
306;
307; We have read in an entire line. Decide whether we should echo the command
308; line or not.
309;
310
311Found_EOL:
312 SUB DI,OFFSET TRANGROUP:COMBUF+3
313 MOV AX,DI ; remember that we've not counted the CR
314 MOV ES:[COMBUF+1],AL ; Set length of line
315 invoke GetBatByt ; Eat linefeed
316 invoke BATCLOSE
317 CMP SUPPRESS, NO_ECHO ;G
318 JZ Reset ;G
319 test [echoflag],1 ; To echo or not to echo, that is the
320 jnz try_nextflag
321
322Reset:
323 PUSH CS ; question. (Profound, huh?)
324 POP DS ; Go back to local segment
325 retz ; no echoing here...
326;
327; Echo the command line with appropriate CRLF...
328;
329
330
331try_nextflag:
332 cmp nullflag,nullcommand ;G was there a command last time?
333 jz No_crlf_print ;G no - don't print crlf
334 invoke CRLF2 ;G Print out prompt
335
336no_crlf_print:
337 invoke PRINT_PROMPT ;G
338 PUSH CS ;G change data segment
339 POP DS ;G
340
341ASSUME DS:TRANGROUP
342 mov dx,OFFSET TRANGROUP:COMBUF+2 ; get command line for echoing
343 invoke CRPRINT
344 invoke CRLF2
345 return
346;
347; The line was too long. Eat remainder of input text up until the CR
348;
349TooLong:
350 ASSUME DS:ResGroup
351 cmp al,0dh ; Has the end of the line been reached?
352 jz Ltlcont ; Yes, continue
353 CALL SkipToEOL ; Eat remainder of line
354
355Ltlcont:
356 stosb ; Terminate the command
357 jmp Found_EOL ; Go process the valid part of the line
358;
359; We have found a parameter lead-in character. Check for the 0-9 case first
360;
361
362NEEDPARM:
363 invoke GetBatByt ; get next character
364 CMP AL,'%' ; Check for two consecutive %
365 JZ SAVBATBYT ; if so, replace with a single %
366 CMP AL,0Dh ; Check for end-of-line
367 JZ SAVBATBYT ; yes, treat it normally
368;
369; We have found %<something>. If the <something> is in the range 0-9, we
370; retrieve the appropriate parameter from the batch segment. Otherwise we
371; see if the <something> has a terminating % and then look up the contents
372; in the environment
373;
374PAROK:
375 SUB AL,'0'
376 JB NEEDENV ; look for parameter in the environment
377 CMP AL,9
378 JA NEEDENV
379;
380; We have found %<number>. This is taken from the parameters in the
381; allocated batch area.
382;
383 CBW
384 MOV BX,AX ; move index into AX
385 SHL BX,1 ; convert word index into byte ptr
386 SaveReg <ES>
387 MOV ES,Batch
388;
389; The structure of the batch area is:
390;
391; BYTE type of segment
392; DWORD offset for next line
393; 10 WORD pointers to parameters. -1 is empty parameter
394; ASCIZ file name (with . and ..)
395; BYTES CR-terminated parameters
396; BYTE 0 flag to indicate end of parameters
397;
398; Get pointer to BX'th argument
399;
400 MOV SI,ES:BatParm[BX]
401 RestoreReg <ES>
402;
403; Is there a parameter here?
404;
405 CMP SI,-1 ; Check if parameter exists
406 JNZ Yes_there_is ;G Yes go get it
407 JMP RDBAT ; Ignore if it doesn't
408;
409; Copy in the found parameter from batch segment
410;
411
412Yes_there_is:
413 PUSH DS
414 MOV DS,Batch
415 ASSUME DS:NOTHING
416 dec cx ; Don't count '%' in line length
417
418CopyParm:
419 LODSB ; From resident segment
420 CMP AL,0DH ; Check for end of parameter
421 JZ EndParam
422 inc cx ; Inc the line length
423 cmp cx,COMBUFLEN ; Is it too long?
424 jae LineTooL ; Yes - handle it, handle it
425 STOSB
426 JMP CopyParm
427;
428; We have copied up to the limit. Stop copying and eat remainder of batch
429; line. We need to make sure that the tooLong code isn't fooled into
430; believing that we are at EOL. Clobber AL too.
431;
432
433LineTooL:
434 XOR AL,AL
435 POP DS
436 ASSUME DS:RESGROUP
437 JMP TooLong
438;
439; We have copied in an entire parameter. Go back for more
440;
441
442EndParam:
443 POP DS
444 JMP RDBat
445;
446; We have found % followed by something other than 0-9. We presume that there
447; will be a following % character. In between is an environment variable that
448; we will fetch and replace in the batch line with its value.
449;
450
451NEEDENV:
452 SaveReg <DS,DI>
453 MOV DI,OFFSET TRANGROUP:ID ; temp spot for name
454 ADD AL,'0' ; reconvert character
455 STOSB ; store it in appropriate place
456;
457; loop getting characters until the next % is found or until EOL
458;
459
460GETENV1:
461 invoke GetBatByt ; get the byte
462 STOSB ; store it
463 CMP AL,0Dh ; EOL?
464 JNZ GETENV15 ; no, see if it the term char
465;
466; The user entered a string with a % but no trailing %. We copy the string.
467;
468 mov byte ptr es:[di-1],0 ; nul terminate the string
469 mov si,offset TranGroup:ID ; point to buffer
470 pop di ; point to line buffer
471 push cs
472 pop ds
473 call StrCpy
474IF IBMCOPYRIGHT
475 dec di
476 pop ds
477ELSE
478 pop ds
479 jc LineTooL
480ENDIF
481 jmp SavBatByt
482
483getenv15:
484 CMP AL,'%' ; terminating %?
485 JNZ GETENV1 ; no, go suck out more characters
486 mov al,'=' ; terminate with =
487 MOV ES:[DI-1],al
488;
489; ID now either has a =-terminated string which we are to find in the
490; environment or a non =-terminated string which will not be found in the
491; environment.
492;
493GETENV2:
494 MOV SI,OFFSET TRANGROUP:ID
495 PUSH CS
496 POP DS ; DS:SI POINTS TO NAME
497 ASSUME DS:TRANGROUP
498 PUSH CX
499 INVOKE FIND_NAME_IN_environment
500 ASSUME ES:RESGROUP
501 POP CX
502 PUSH ES
503 POP DS
504 assume ds:resgroup
505 PUSH CS
506 POP ES
507 ASSUME ES:TRANGROUP
508 MOV SI,DI
509 POP DI ; get back pointer to command line
510;
511; If the parameter was not found, there is no need to perform any replacement.
512; We merely pretend that we've copied the parameter.
513;
514IF IBMCOPYRIGHT
515 JC GETENV6
516ELSE
517 jnc GETENV4
518 pop ds
519 jmp rdbat
520ENDIF
521;
522; ES:DI points to command line being built
523; DS:SI points either to nul-terminated environment object AFTER =
524;
525
526GETENV4:
527 ASSUME ES:NOTHING
528 call StrCpy
529
530IF IBMCOPYRIGHT
531 dec di
532
533GETENV6:
534 POP DS ; restore pointer to resgroup
535ELSE
536 pop ds
537 jc LineTooL
538ENDIF
539 JMP RDBAT ; no, go back to batch file
540
541EndProc ReadBat
542
543;
544; SkipToEOL - read from batch file until end of line
545;
546
547Procedure SkipToEOL,NEAR
548
549 ASSUME DS:ResGroup,ES:NOTHING
550
551 TEST Batch,-1
552 retz ; no batch file in effect
553 invoke GetBatByt
554 CMP AL,0Dh ; eol character?
555 JNZ SkipToEOL ; no, go eat another
556 return
557
558EndProc SkipToEOL
559
560Break <Allocate and deallocate the transient portion>
561
562;
563; Free Transient. Modify ES,AX,flags
564;
565
566Procedure Free_TPA,NEAR
567
568ASSUME DS:TRANGROUP,ES:RESGROUP
569
570 PUSH ES
571 MOV ES,[RESSEG]
572 MOV ES,[RES_TPA]
573 MOV AH,DEALLOC
574 INT int_command ; Make lots of free memory
575 POP ES
576
577 return
578
579EndProc Free_TPA
580
581;
582; Allocate transient. Modify AX,BX,DX,flags
583;
584
585Procedure Alloc_TPA,NEAR
586
587ASSUME DS:TRANGROUP,ES:RESGROUP
588
589 PUSH ES
590 MOV ES,[RESSEG]
591 MOV BX,0FFFFH ; Re-allocate the transient
592 MOV AH,ALLOC
593 INT int_command
594 PUSH BX ; Save size of block
595 MOV AH,ALLOC
596 INT int_command
597;
598; Attempt to align TPA on 64K boundary
599;
600 POP BX ; Restore size of block
601 MOV [RES_TPA], AX ; Save segment to beginning of block
602 MOV [TRAN_TPA], AX
603;
604; Is the segment already aligned on a 64K boundary
605;
606 MOV DX, AX ; Save segment
607 AND AX, 0FFFH ; Test if above boundary
608 JNZ Calc_TPA
609 MOV AX, DX
610 AND AX, 0F000H ; Test if multiple of 64K
611 JNZ NOROUND
612
613Calc_TPA:
614 MOV AX, DX
615 AND AX, 0F000H
616 ADD AX, 01000H ; Round up to next 64K boundary
617 JC NOROUND ; Memory wrap if carry set
618;
619; Make sure that new boundary is within allocated range
620;
621 MOV DX, [RES_TPA]
622 ADD DX, BX ; Compute maximum address
623 CMP DX, AX ; Is 64K address out of range?
624 JB NOROUND
625;
626; Make sure that we won't overwrite the transient
627;
628 MOV BX, CS ; CS is beginning of transient
629 CMP BX, AX
630 JB NOROUND
631;
632; The area from the 64K boundary to the beginning of the transient must
633; be at least 64K.
634;
635 SUB BX, AX
636 CMP BX, 4096 ; Size greater than 64K?
637 JAE ROUNDDONE
638
639NOROUND:
640 MOV AX, [RES_TPA]
641
642ROUNDDONE:
643 MOV [LTPA],AX ; Re-compute everything
644 MOV [TPA],AX
645 MOV BX,AX
646 MOV AX,CS
647 SUB AX,BX
648 PUSH BX
649 MOV BX,16
650 MUL BX
651 POP BX
652 OR DX,DX
653 JZ SAVSIZ2
654 MOV AX,-1
655
656SAVSIZ2:
657;
658; AX is the number of bytes free in the buffer between the resident and the
659; transient with a maximum of 64K-1. We round this down to a multiple of 512.
660;
661 CMP AX,512
662 JBE GotSize
663 AND AX,0FE00h ; NOT 511 = NOT 1FF
664
665GotSize:
666 MOV [BYTCNT],AX
667 POP ES
668
669 return
670
671EndProc Alloc_TPA
672
673Break <BatCom - enter a batch file>
674
675;
676; The exec search has determined that the user has requested a batch file for
677; execution. We parse the arguments, create the batch segment, and signal
678; batch processing.
679;
680Procedure BatCom,NEAR
681
682ASSUME DS:TRANGROUP, ES:NOTHING
683
684;
685; Batch parameters are read with ES set to segment of resident part
686;
687
688 MOV ES,[RESSEG]
689ASSUME ES:RESGROUP
690 cmp es:[call_batch_flag],call_in_progress ;AN043; If in CALL,
691 jz skip_ioset ;AN043; redirection was already set up
692 invoke IOSET ; Set up any redirection
693
694skip_ioset: ;AN043;
695 CALL FREE_TPA ; G
696 cmp es:[call_batch_flag],call_in_progress ;G
697 jz getecho ; G if we're in a call, don't execute
698;
699; Since BATCH has lower precedence than PIPE or FOR. If a new BATCH file is
700; being started it MUST be true that no FOR or PIPE is currently in progress.
701; Don't execute if in call
702;
703 invoke ForOff
704
705getecho:
706 invoke PipeOff
707 mov al,EchoFlag ; preserve echo state for chaining
708
709 and al, 1 ; Save current echo state
710 push ax
711
712 xor ax,ax ;G
713 test es:[batch],-1 ;G Are we in a batch file?
714 jz leavebat ;G No, nothing to save
715 mov ax,es:[batch] ;G get current batch segment
716 cmp es:[call_batch_flag],call_in_progress ;G
717 jz leavebat ;G
718;
719; We are in a chained batch file, save batlast from previous batch segment
720; so that if we're in a CALL, we will return to the correct batch file.
721;
722 push es ;G
723 mov es,ax ;G get current batch segment
724 mov ax,es:[batlast] ;G get previous batch segment
725 pop es ;G
726
727leavebat: ;G
728 push ax ;G keep segment until new one created
729 cmp es:[call_batch_flag],call_in_progress ;G are we in a CALL?
730 jz startbat ;G Yes, keep current batch segment
731 call BatchOff ;G No, deallocate old batch segment
732
733;
734; Find length of batch file
735;
736
737startbat: ;G
738 ASSUME ES:RESGROUP
739 MOV es:[CALL_BATCH_FLAG], 0 ;G reset call flag
740 mov SI, OFFSET TRANGROUP:EXECPATH
741
742 mov ax,AppendTruename ;AN042; Get the real path where the batch file
743 int 2fh ;AN042; was found with APPEND
744 mov ah,Find_First ;AN042; The find_first will return it
745 mov dx,si ;AN042; Get the string
746 mov cx,search_attr ;AN042; filetypes to search for
747 int int_command ;AN042;
748
749 invoke DStrLen
750;
751; Allocate batch area:
752; BYTE type of segment
753; WORD segment of last batch file
754; WORD segment for FOR command
755; BYTE FOR flag state on entry to batch file
756; DWORD offset for next line
757; 10 WORD pointers to parameters. -1 is empty parameter
758; ASCIZ file name (with . and ..)
759; BYTES CR-terminated parameters
760; BYTE 0 flag to indicate end of parameters
761;
762; We allocate the maximum size for the command line and use setblock to shrink
763; later when we've squeezed out the extra
764;
765
766 MOV BX,CX ; length of file name.
767 ADD BX,0Fh + (SIZE BatchSegment) + COMBUFLEN + 0Fh
768 ; structure + max len + round up
769 SaveReg <CX>
770 MOV CL,4
771 SHR BX,CL ; convert to paragraphs
772 PUSH BX ;G save size of batch segment
773 MOV AH,ALLOC
774 INT int_command ; Allocate batch segment
775 POP BX ;G get size of batch segment
776;
777; This should *NEVER* return an error. The transient is MUCH bigger than
778; the batch segment. This may not be true, however, in a multitasking system.
779; G This error will occur with nesting of batch files. We also need to
780; G make sure that we don't overlay the transient.
781;
782 jc mem_error ;G not enough memory - exit
783 push ax ;G save batch segment
784 add ax,bx ;G get end of batch segment
785 add ax,20h ;G add some tpa work area
786 mov bx,cs ;G get the transient segment
787 cmp ax,bx ;G do we end before the transient
788 pop ax ;G get batch segment back
789 jb enough_mem ;G we have enough memory - continue
790 push es ;G no we're hitting the transient
791 mov es,ax
792 mov ax,DEALLOC SHL 8 ;G deallocate the batch segment
793 int int_command
794 pop es
795
796mem_error:
797 jmp no_memory ;G Set up for message and exit
798
799enough_mem:
800 MOV [BATCH],AX
801 CALL ALLOC_TPA
802;
803; Initialize batch segment
804;
805 RestoreReg <DX> ; length of name
806 POP AX ;G get saved batch segment back
807 inc es:nest ;G increment # batch files in progress
808 PUSH ES
809 MOV ES,[BATCH]
810ASSUME ES:NOTHING
811 MOV ES:[BatType],BatchType ; signal batch file type
812 MOV ES:[batlast],ax ;G save segment of last batch file
813 push DS ;G
814 mov DS,[resseg] ;G set to resident data
815ASSUME DS:RESGROUP
816 xor ax,ax ;G
817 mov bl,forflag ;G get the current FOR state
818 mov ES:[batforflag],bl ;G save it in the batch segment
819 test bl,-1 ;G are we in a FOR?
820 jz for_not_on ;G no, for segment set to 0
821 mov ax,forptr ;G yes, get current FOR segment
822 mov forflag,0 ;G reset forflag
823
824for_not_on:
825 mov ES:[batforptr],ax ;G save FOR segment in batch segment
826 XOR AX,AX
827 mov forptr,ax ;G make sure for segment is not active
828 mov bl,echoflag ;G
829 pop DS ;G
830
831 mov byte ptr es:[Batechoflag],bl ;G save echo state of parent
832 MOV WORD PTR ES:[BatSeek],AX ; point to beginning of file
833 MOV WORD PTR ES:[BatSeek+2],AX
834;
835; Initialize pointers
836;
837 DEC AX ; put -1 into AX
838 MOV DI,BatParm ; point to parm area
839 MOV BX,DI
840 MOV CX,10
841 REP STOSW ; Init to no parms
842;
843; Move in batch file name
844;
845 MOV CX,DX
846 rep movsb ; including NUL.
847;
848; Now copy the command line into batch segment, parsing the arguments along
849; the way. Segment will look like this:
850;
851; <arg0>CR<arg1>CR...<arg9>CR<arg10>CR...<ARGn>CR 0
852;
853; or, in the case of fewer arguments:
854;
855; <arg0>CR<arg1>CR...<arg6>CR CR CR ... CR 0
856;
857 MOV SI,OFFSET TRANGROUP:COMBUF+2
858 MOV CX,10 ; at most 10 arguments
859;
860; Look for beginning of next argument
861;
862EACHPARM:
863 invoke SCANOFF ; skip to argument
864;
865; AL is first non-delimiter. DS:SI points to char = AL
866;
867 CMP AL,0DH ; end of road?
868 JZ HAVPARM ; yes, no more arguments
869;
870; If CX = 0 then we have stored the most parm we can. Skip store
871;
872 JCXZ MOVPARM ; Only first 10 parms get pointers
873;
874; Go into allocated piece and stick in new argument pointer.
875;
876 MOV ES:[BX],DI ; store batch pointer
877 ADD BX,2 ; advance arg counter
878;
879; Move the parameter into batch segment
880;
881MOVPARM:
882 LODSB ; get byte
883 INVOKE DELIM ; if delimiter
884 JZ ENDPARM ; then done with parm
885 STOSB ; store byte
886 CMP AL,0DH ; if CR then not delimiter
887 JZ HAVPARM ; but end of parm list, finish
888 JMP SHORT MOVPARM
889;
890; We have copied a parameter up until the first separator. Terminate it with
891; CR
892;
893
894ENDPARM:
895 MOV AL,0DH
896 STOSB
897 JCXZ EACHPARM ; if no parameters, don't dec
898 DEC CX ; remember that we've seen one.
899 JMP SHORT EACHPARM
900;
901; We have parsed the entire line. Terminate the arg list
902;
903
904HAVPARM:
905 XOR AL,AL
906 STOSB ; Nul terminate the parms
907;
908; Now we know EXACTLY how big the BATCH segment is. Round up size (from DI)
909; into paragraphs and setblock to the appropriate size
910;
911 LEA BX,[DI+15]
912 MOV CL,4
913 SHR BX,CL
914 MOV AH,SetBlock
915 INT int_command
916
917 POP ES
918ASSUME ES:RESGROUP
919 PUSH ES
920 POP DS ; Simply batch FCB setup
921ASSUME DS:RESGROUP
922 CMP [SINGLECOM],-1
923 JNZ NOBATSING
924 MOV [SINGLECOM],0FFF0H ; Flag single command BATCH job
925
926NOBATSING:
927;
928; Enter the batch file with the current echo state
929;
930 pop ax ; Get original echo state
931 mov echoflag,al ;g restore it
932 JMP TCOMMAND
933
934;
935; The following is executed if there isn't enough memory for batch segment
936;
937
938NO_MEMORY:
939 assume ds:trangroup,es:resgroup
940 pop dx ;g even up our stack
941 pop ax ;g
942 pop ax ;g
943 call Alloc_tpa ;g reallocate memory
944 mov msg_disp_class,ext_msg_class ;AN000; set up extended error msg class
945 mov dx,offset TranGroup:Extend_Buf_ptr ;AC000; get extended message pointer
946 mov Extend_Buf_ptr,error_not_enough_memory ;AN000; get message number in control block
947 jmp cerror ;g print error message and go...
948
949EndProc BatCom
950
951Procedure BatchOff
952
953 ASSUME DS:NOTHING,ES:NOTHING
954
955 SaveReg <AX,ES>
956 PUSH DS ;G
957 PUSH BX ;G
958 MOV ES,ResSeg
959 MOV DS,ResSeg ;G
960 ASSUME ES:ResGroup,DS:Resgroup ;G
961 MOV AX,Batch ; Free the batch segment
962 OR AX,AX
963 JZ nofree
964
965 PUSH ES
966 MOV ES,AX
967 test [echoflag],1 ;G Is echo on?
968 jnz echo_last_line ;G Yes - echo last line in file
969 mov suppress,no_echo ;G no - don't echo last line in file
970
971echo_last_line:
972 MOV BL,ES:[BATECHOFLAG] ;G Get echo state
973 mov [echoflag],bl ;G and restore it
974 MOV BX,ES:[BATFORPTR] ;G Get FOR segment
975 MOV FORPTR,BX ;G and restore it
976 MOV BL,ES:[BATFORFLAG] ;G Get FOR flag
977 MOV FORFLAG,BL ;G and restore it
978 MOV BX,es:[batlast] ;G get old batch segment
979 MOV AH,DEALLOC
980 INT int_command
981 POP ES
982 MOV Next_BATCH,BX ;G reset batch segment
983 DEC es:NEST ;G
984
985 XOR AX,AX
986 MOV Batch,AX ; No batch in progress
987
988NoFree:
989 POP BX ;G
990 pop ds ;G
991 RestoreReg <ES,AX>
992
993 return
994
995EndProc BatchOff
996
997
998IF IBMCOPYRIGHT
999
1000Procedure StrCpy,near
1001
1002 push ax
1003cycle:
1004 lodsb
1005 stosb
1006 or al,al
1007 jnz cycle
1008 pop ax
1009
1010 return
1011
1012EndProc StrCpy
1013
1014ELSE
1015; StrCpy - copy string, checking count in CX against COMBUFLEN
1016; Entry : DS:SI ==> source string
1017; ES:DI ==> destination string
1018; CX = current length of destination string
1019; Exit : string copied, CX updated, Carry set if length limit exceeded
1020Procedure StrCpy,NEAR
1021 push ax
1022ccycle:
1023 lodsb
1024 inc cx
1025 cmp cx,COMBUFLEN
1026 jb ccopy
1027 stc ; set carry to signal error
1028 jmp short ccend
1029ccopy:
1030 stosb
1031 or al,al
1032 jnz ccycle
1033
1034ccend:
1035 dec cx ; discount extra byte
1036 dec di ; back up pointer
1037 pop ax
1038 return ; return carry clear
1039EndProc StrCpy
1040
1041ENDIF
1042
1043TRANCODE ENDS
1044 END
1045
diff --git a/v4.0/src/CMD/COMMAND/TBATCH2.ASM b/v4.0/src/CMD/COMMAND/TBATCH2.ASM
new file mode 100644
index 0000000..501c637
--- /dev/null
+++ b/v4.0/src/CMD/COMMAND/TBATCH2.ASM
@@ -0,0 +1,753 @@
1 page 80,132
2; SCCSID = @(#)tbatch2.asm 4.2 85/07/22
3; SCCSID = @(#)tbatch2.asm 4.2 85/07/22
4TITLE Batch processing routines part II
5
6 INCLUDE comsw.asm
7
8.xlist
9.xcref
10 INCLUDE DOSSYM.INC
11 INCLUDE comseg.asm
12 INCLUDE comequ.asm
13.list
14.cref
15
16
17DATARES SEGMENT PUBLIC BYTE ;AC000;
18 EXTRN BATCH:WORD
19 EXTRN Batch_Abort:byte
20 EXTRN call_batch_flag:byte
21 EXTRN call_flag:byte
22 EXTRN IFFlag:BYTE
23 EXTRN In_Batch:byte
24 EXTRN Nest:word
25 EXTRN PIPEFILES:BYTE
26 EXTRN RETCODE:WORD
27 EXTRN SINGLECOM:WORD
28DATARES ENDS
29
30TRANDATA SEGMENT PUBLIC BYTE ;AC000;
31 EXTRN BADLAB_PTR:WORD
32 EXTRN BatBufLen:WORD
33 EXTRN IFTAB:BYTE
34 EXTRN SYNTMES_PTR:WORD
35TRANDATA ENDS
36
37TRANSPACE SEGMENT PUBLIC BYTE ;AC000;
38 EXTRN arg:byte ; the arg structure!
39 EXTRN BatBuf:BYTE
40 EXTRN BatBufEnd:WORD
41 EXTRN BatBufPos:WORD
42 EXTRN BATHAND:WORD
43 EXTRN COMBUF:BYTE
44 EXTRN DIRBUF:BYTE
45 EXTRN GOTOLEN:WORD
46 EXTRN if_not_count:word
47 EXTRN IFNOTFLAG:BYTE
48 EXTRN RESSEG:WORD
49TRANSPACE ENDS
50
51TRANCODE SEGMENT PUBLIC BYTE
52
53ASSUME CS:TRANGROUP,DS:NOTHING,ES:NOTHING,SS:NOTHING
54
55 EXTRN cerror:near
56 EXTRN docom1:near
57 EXTRN tcommand:near
58
59 public $if,iferlev,goto,shift,ifexists,ifnot,forerror,$call
60
61
62Break <GetBatByt - retrieve a byte from the batch file>
63
64; Get one byte from the batch file and return it in AL. End-of-file returns
65; <CR> and ends batch mode. DS must be set to resident segment.
66; AH, DX destroyed.
67
68Procedure GETBATBYT,NEAR
69
70ASSUME DS:RESGROUP
71
72 SaveReg <BX,CX,DS>
73 test byte ptr [Batch_Abort],-1
74 jnz BatEOF
75 TEST Batch,-1
76 JZ BatEOF
77 PUSH ES
78 MOV ES,Batch
79 ASSUME ES:NOTHING
80 ADD WORD PTR ES:[BatSeek],1
81 ADC WORD PTR ES:[BatSeek+2],0
82 POP ES
83;
84; See if we have bytes buffered...
85;
86 MOV AX,CS
87 MOV DS,AX
88 ASSUME DS:TranGroup
89 MOV BX,BatBufPos
90 CMP BX,-1
91 JNZ UnBuf
92;
93; There are no bytes in the buffer. Let's try to fill it up.
94;
95 MOV DX,OFFSET TranGROUP:BatBuf
96 MOV CX,BatBufLen ; max to read.
97 MOV BX,BatHand
98 MOV AH,READ
99 INT int_command ; Get one more byte from batch file
100 jnc bat_read_ok ;AN022; if no error - continue
101 invoke get_ext_error_number ;AN022; get the error
102 push ds ;AN022; save local segment
103 mov ds,[resseg] ;AN022; get resident segment
104assume ds:resgroup ;AN022;
105 mov dx,ax ;AN022; put error in DX
106 invoke output_batch_name ;AN022; set up to print the error
107 pop ds ;AN022;
108assume ds:trangroup ;AN022;
109 invoke std_eprintf ;AN022; print out the error
110 mov byte ptr combuf+2,end_of_line_in;AN022; terminate the batch line for parsing
111 mov byte ptr combuf+3,end_of_line_out ;AN022; terminate the batch line for output
112 jmp bateof ;AN022; terminate the batch file
113
114bat_read_ok: ;AN022;
115 MOV CX,AX
116 JCXZ BATEOFDS
117 MOV BatBufEnd,CX
118 XOR BX,BX
119 MOV BatBufPos,BX
120;
121; Buffered bytes!
122;
123UnBuf:
124 MOV AL,BatBuf[BX] ; get next byte
125 INC BX
126 CMP BX,BatBufEnd ; beyond end of buffer?
127 JB SetBufPos
128 MOV BX,-1
129
130SetBufPos:
131 MOV BatBufPos,BX
132 CMP AL,1AH ; ^Z for termination?
133 jnz GetByteDone
134
135BatEOFDS:
136 ASSUME DS:TranGroup
137 MOV DS,ResSeg
138 ASSUME DS:ResGroup
139
140BATEOF:
141 invoke BatchOff
142 CALL BATCLOSE
143 MOV AL,0DH ; If end-of-file, then end of line
144 test byte ptr [Batch_Abort],-1
145 mov byte ptr [Batch_Abort],0
146 jz Cont_Get_Byt
147 mov di,offset TRANGROUP:COMBUF+2 ; reset pointer to beginning of buffer
148 xor cx,cx ; zero line length
149 jmp short GetByteDone
150
151Cont_Get_Byt:
152 CMP [SINGLECOM],0FFF0H ; See if we need to set SINGLECOM
153 JNZ GetByteDone
154 CMP NEST,0 ;G See if we have nested batch files
155 JNZ GETBYTEDONE ;G Yes - don't exit just yet
156 MOV [SINGLECOM],-1 ; Cause termination
157
158GetByteDone:
159 RestoreReg <DS,CX,BX>
160
161 return
162
163EndProc GetBatByt
164
165 break <$If - conditional execution>
166assume ds:trangroup,es:trangroup
167
168IFERRORP:
169 POP AX
170IFERROR:
171FORERROR:
172 MOV DX,OFFSET TRANGROUP:SYNTMES_ptr
173 JMP CERROR
174
175$IF:
176;
177; Turn off any pipes in progress.
178;
179 push ds ;AN004; save local DS
180 mov ds,[resseg] ;AN004; get resident segment
181 assume ds:resgroup ;AN004;
182 cmp [PIPEFILES],0 ;AN004; Only turn off if present.
183 jz IFNoPipe ;AN004; no pipe - continue
184 invoke PipeDel ;AN004; turn off piping
185
186IFNoPipe: ;AN004;
187 pop ds ;AN004; get local DS back
188 assume ds:trangroup ;AN004;
189 MOV [IFNOTFLAG],0
190 mov [if_not_count], 0
191 MOV SI,81H
192
193IFREENT:
194 invoke SCANOFF
195 CMP AL,0DH
196 JZ IFERROR
197 MOV BP,SI
198 MOV DI,OFFSET TRANGROUP:IFTAB ; Prepare to search if table
199 MOV CH,0
200
201IFINDCOM:
202 MOV SI,BP
203 MOV CL,[DI]
204 INC DI
205 JCXZ IFSTRING
206 JMP SHORT FIRSTCOMP
207
208IFCOMP:
209 JNZ IF_DIF ;AC000;
210
211FIRSTCOMP:
212 LODSB
213 MOV AH,ES:[DI]
214 INC DI
215 CMP AL,AH
216 JZ IFLP
217 OR AH,20H ; Try lower case
218 CMP AL,AH
219
220IFLP:
221 LOOP IFCOMP
222
223IF_DIF: ;AC000;
224 LAHF
225 ADD DI,CX ; Bump to next position without affecting flags
226 MOV BX,[DI] ; Get handler address
227 INC DI
228 INC DI
229 SAHF
230 JNZ IFINDCOM
231 LODSB
232 CMP AL,0DH
233
234IFERRORJ:
235 JZ IFERROR
236 invoke DELIM
237 JNZ IFINDCOM
238 invoke SCANOFF
239 JMP BX
240
241IFNOT:
242 NOT [IFNOTFLAG]
243 inc [if_not_count]
244 JMP IFREENT
245
246;
247; We are comparing two strings for equality. First, find the end of the
248; first string.
249;
250
251IFSTRING:
252 PUSH SI ; save away pointer for later compare
253 XOR CX,CX ; count of chars in first string
254
255FIRST_STRING:
256 LODSB ; get character
257 CMP AL,0DH ; end of line?
258 JZ IFERRORP ; yes => error
259 invoke DELIM ; is it a delimiter?
260 JZ EQUAL_CHECK ; yes, go find equal sign
261 INC CX ; remember 1 byte for the length
262 JMP FIRST_STRING ; go back for more
263;
264; We have found the end of the first string. Unfortunately, we CANNOT use
265; scanoff to find the next token; = is a valid separator and will be skipped
266; over.
267;
268
269EQUAL_CHECK:
270 CMP AL,'=' ; is char we have an = sign?
271 JZ EQUAL_CHECK2 ; yes, go find second one.
272 CMP AL,0DH ; end of line?
273 JZ IFERRORPj ;AC004; yes, syntax error
274 LODSB ; get next char
275 JMP EQUAL_CHECK
276;
277; The first = has been found. The next char had better be an = too.
278;
279
280EQUAL_CHECK2:
281 LODSB ; get potential = char
282 CMP AL,'=' ; is it good?
283 jnz iferrorpj ; no, error
284;
285; Find beginning of second string.
286;
287 invoke SCANOFF
288 CMP AL,0DH
289 jz iferrorpj
290 POP DI
291;
292; DS:SI points to second string
293; CX has number of chars in first string
294; ES:DI points to first string
295;
296; Perform compare to elicit match
297;
298 REPE CMPSB
299 JZ MATCH ; match found!
300;
301; No match. Let's find out what was wrong. The character that did not match
302; has been advanced over. Let's back up to it.
303;
304 DEC SI
305;
306; If it is EOL, then syntax error
307;
308 CMP BYTE PTR [SI],0DH
309 JZ IFERRORJ
310;
311; Advance pointer over remainder of unmatched text to next delimiter
312;
313
314SKIPSTRINGEND:
315 LODSB
316
317NOTMATCH:
318 CMP AL,0DH
319
320IFERRORJ2:
321 JZ IFERRORJ
322 invoke DELIM
323 JNZ SKIPSTRINGEND
324;
325; Signal that we did NOT have a match
326;
327 MOV AL,-1
328 JMP SHORT IFRET
329
330iferrorpj:
331 jmp iferrorp
332;
333; The compare succeeded. Was the second string longer than the first? We
334; do this by seeing if the next char is a delimiter.
335;
336
337MATCH:
338 LODSB
339 invoke DELIM
340 JNZ NOTMATCH ; not same.
341 XOR AL,AL
342 JMP SHORT IFRET
343
344IFEXISTS:
345ifexist_attr EQU attr_hidden+attr_system
346
347moredelim:
348 lodsb ; move command line pointer over
349 invoke delim ; pathname -- have to do it ourselves
350 jnz moredelim ; 'cause parse_file_descriptor is dumb
351 mov DX, OFFSET TRANGROUP:dirbuf
352 trap set_dma
353 mov BX, 2 ; if(0) [|not](|1) exist[1|2] file(2|3)
354 add BX, [if_not_count]
355 mov AX, OFFSET TRANGROUP:arg.argv
356 invoke argv_calc ; convert arg index to pointer
357 mov DX, [BX].argpointer ; get pointer to supposed filename
358 mov CX, ifexist_attr ; filetypes to search for
359 trap Find_First ; request first match, if any
360 jc if_ex_c ; carry is how to determine error
361 xor AL, AL
362 jmp ifret
363
364if_ex_c:
365 mov AL, -1 ; false 'n' fall through...
366
367IFRET:
368 TEST [IFNOTFLAG],-1
369 JZ REALTEST
370 NOT AL
371
372REALTEST:
373 OR AL,AL
374 JZ IFTRUE
375 JMP TCOMMAND
376
377IFTRUE:
378 invoke SCANOFF
379 MOV CX,SI
380 SUB CX,81H
381 SUB DS:[80H],CL
382 MOV CL,DS:[80H]
383 MOV [COMBUF+1],CL
384 MOV DI,OFFSET TRANGROUP:COMBUF+2
385 CLD
386 REP MOVSB
387 MOV AL,0DH
388 STOSB
389;
390; Signal that an IF was done. This prevents the redirections from getting
391; lost.
392;
393 PUSH DS
394 MOV DS,ResSeg
395 ASSUME DS:RESGROUP
396 MOV IFFlag,-1
397 POP DS
398 ASSUME DS:TRANGROUP
399;
400; Go do the command
401;
402 JMP DOCOM1
403
404iferrorj3:
405 jmp iferrorj2
406
407IFERLEV:
408 MOV BH,10
409 XOR BL,BL
410
411GETNUMLP:
412 LODSB
413 CMP AL,0DH
414 jz iferrorj3
415 invoke DELIM
416 JZ GOTNUM
417 SUB AL,'0'
418 XCHG AL,BL
419 MUL BH
420 ADD AL,BL
421 XCHG AL,BL
422 JMP SHORT GETNUMLP
423
424GOTNUM:
425 PUSH DS
426 MOV DS,[RESSEG]
427ASSUME DS:RESGROUP
428 MOV AH,BYTE PTR [RETCODE]
429 POP DS
430ASSUME DS:TRANGROUP
431 XOR AL,AL
432 CMP AH,BL
433 JAE IFRET
434 DEC AL
435 JMP SHORT IFRET
436
437
438 break <Shift - advance arguments>
439assume ds:trangroup,es:trangroup
440
441;
442; Shift the parameters in the batch structure by 1 and set up the new argument.
443; This is a NOP if no batch in progress.
444;
445
446Procedure Shift,NEAR
447
448 MOV DS,[RESSEG]
449ASSUME DS:RESGROUP
450 MOV AX,[BATCH] ; get batch pointer
451 OR AX,AX ; in batch mode?
452 retz ; no, done.
453 MOV ES,AX ; operate in batch segment
454 MOV DS,AX
455
456ASSUME DS:NOTHING,ES:NOTHING
457
458;
459; Now move the batch args down by 1 word
460;
461 MOV DI,BatParm ; point to parm table
462 LEA SI,[DI+2] ; make source = dest + 2
463 MOV CX,9 ; move 9 parameters
464 REP MOVSW ; SHIFT down
465;
466; If the last parameter (the one not moved) is empty (= -1) then we are done.
467; We have copied it into the previous position
468;
469 CMP WORD PTR [DI],-1 ; if last one was not in use then
470 retz ; No new parm
471;
472; This last pointer is NOT nul. Get it and scan to find the next argument.
473; Assume, first, that there is no next argument
474;
475 MOV SI,[DI]
476 MOV WORD PTR [DI],-1 ; Assume no parm
477;
478; The parameters are CR separated. Scan for end of this parm
479;
480SKIPCRLP:
481 LODSB
482 CMP AL,0DH
483 JNZ SKIPCRLP
484;
485; We are now pointing at next arg. If it is 0 (end of original line) then we
486; are finished. There ARE no more parms and the pointer has been previously
487; initialized to indicate it.
488;
489 CMP BYTE PTR [SI],0
490 retz ; End of parms
491 MOV [DI],SI ; Pointer to next parm as %9
492
493 return
494
495EndProc Shift
496
497;
498; Skip delim reads bytes from the batch file until a non-delimiter is seen.
499; returns char in AL, carry set -> eof
500;
501
502Procedure SkipDelim,NEAR
503
504 ASSUME DS:ResGroup,ES:NOTHING
505 TEST Batch,-1
506 JZ SkipErr ; batch file empty. OOPS!
507 CALL GetBatByt ; get a char
508 invoke Delim ; check for ignoreable chars
509 JZ SkipDelim ; ignore this char.
510 clc
511 return
512
513SkipErr:
514 stc
515 return
516
517EndProc SkipDelim
518
519 break $Call
520
521; CALL is an internal command that transfers control to a .bat, .exe, or
522; .com file. This routine strips the CALL off the command line, sets
523; the CALL_FLAG to indicate a call in progress, and returns control to
524; DOCOM1 in TCODE to reprocess the command line and execute the file
525; being CALLed.
526
527$CALL:
528
529; strip off CALL from command line
530
531 ASSUME DS:trangroup,ES:trangroup
532 push si
533 push di
534 push ax
535 push cx
536 mov si,offset trangroup:combuf+2
537 invoke scanoff ;get to first non-delimeter
538 add si,length_call ;point to char past CALL
539 mov di,offset trangroup:combuf+2
540 mov cx,combuflen-length_call ;get length of buffer
541 rep movsb ;move it
542 pop cx
543 pop ax
544 pop di
545 pop si
546
547
548; set call flag to indicate call in progress
549
550 push ds
551 mov ds,[resseg]
552 ASSUME DS:resgroup,ES:resgroup
553 mov call_flag, call_in_progress
554 mov call_batch_flag, call_in_progress
555;
556; Turn off any pipes in progress.
557;
558 cmp [PIPEFILES],0 ; Only turn off if present.
559 jz NoPipe
560 invoke PipeDel
561NoPipe:
562 pop ds
563
564 ret
565
566 break Goto
567
568GOTO:
569
570assume ds:trangroup,es:trangroup
571 MOV DS,[RESSEG]
572ASSUME DS:RESGROUP
573 TEST [BATCH],-1
574 retz ; If not in batch mode, a nop
575 XOR DX,DX
576 PUSH DS
577 MOV DS,Batch
578 MOV WORD PTR DS:[BatSeek],DX ; Back to start
579 MOV WORD PTR DS:[BatSeek+2],DX ; Back to start
580 POP DS
581
582GotoOpen:
583 invoke promptBat
584 MOV DI,FCB+1 ; Get the label
585 MOV CX,11
586 MOV AL,' '
587 REPNE SCASB
588 JNZ NOINC
589 INC CX
590
591NOINC:
592 SUB CX,11
593 NEG CX
594 MOV [GOTOLEN],CX
595;
596; At beginning of file. Skip to first non-delimiter char
597;
598 CALL SkipDelim
599 JC BadGoto
600 CMP AL,':'
601 JZ CHKLABEL
602
603LABLKLP: ; Look for the label
604 CALL GETBATBYT
605 CMP AL,0AH
606 JNZ LABLKTST
607;
608; At beginning of line. Skip to first non-delimiter char
609;
610 CALL SkipDelim
611 JC BadGoto
612 CMP AL,':'
613 JZ CHKLABEL
614
615LABLKTST:
616 TEST [BATCH],-1
617 JNZ LABLKLP
618
619BadGoto:
620 CALL BATCLOSE
621 PUSH CS
622 POP DS
623 MOV DX,OFFSET TRANGROUP:BADLAB_ptr
624 JMP CERROR
625
626;
627; Found the :. Skip to first non-delimiter char
628;
629
630CHKLABEL:
631 CALL SkipDelim
632 JC BadGoto
633 MOV DI,FCB+1
634 MOV CX,[GOTOLEN]
635 JMP SHORT GotByte
636
637NEXTCHRLP:
638 PUSH CX
639 CALL GETBATBYT
640 POP CX
641
642GotByte:
643 INVOKE TESTKANJ ;AN000; 3/3/KK
644 JZ NOTKANJ1 ;AN000; 3/3/KK
645 CMP AL, ES:[DI] ;AN000; 3/3/KK
646 JNZ LABLKTST ;AN000; 3/3/KK
647 INC DI ;AN000; 3/3/KK
648 DEC CX ;AN000; 3/3/KK
649 JCXZ LABLKTST ;AN000; 3/3/KK
650 PUSH CX ;AN000; 3/3/KK
651 CALL GETBATBYT ;AN000; 3/3/KK
652 POP CX ;AN000; 3/3/KK
653 CMP AL, ES:[DI] ;AN000; 3/3/KK
654 JMP SHORT KNEXTLABCHR ;AN000; 3/3/KK
655
656NOTKANJ1: ;AN000; 3/3/KK
657 OR AL,20H
658 CMP AL,ES:[DI]
659 JNZ TRYUPPER
660 JMP SHORT NEXTLABCHR
661
662TRYUPPER:
663 SUB AL,20H
664 CMP AL,ES:[DI]
665
666KNEXTLABCHR: ;AN000; 3/3/KK
667 JNZ LABLKTST
668
669NEXTLABCHR:
670 INC DI
671 LOOP NEXTCHRLP
672 CALL GETBATBYT
673 cmp [GOTOLEN],8 ; Is the label atleast 8 chars long?
674 jge gotocont ; Yes, then the next char doesn't matter
675 CMP AL,' '
676 JA LABLKTST
677
678gotocont:
679 CMP AL,0DH
680 JZ SKIPLFEED
681
682TONEXTBATLIN:
683 CALL GETBATBYT
684 CMP AL,0DH
685 JNZ TONEXTBATLIN
686
687SKIPLFEED:
688 CALL GETBATBYT
689 CALL BatClose
690
691 return
692
693Procedure BatClose,NEAR
694
695 MOV BX,CS:[BATHAND]
696 CMP BX,5
697 JB CloseReturn
698 MOV AH,CLOSE
699 INT int_command
700
701CloseReturn:
702 mov byte ptr [In_Batch],0 ; reset flag
703 return
704
705EndProc BatClose
706
707;
708; Open the BATCH file, If open fails, AL is drive of batch file (A=1)
709; Also, fills internal batch buffer. If access denied, then AX = -1
710;
711
712Procedure BatOpen,NEAR
713
714ASSUME DS:RESGROUP,ES:TRANGROUP
715
716 PUSH DS
717 MOV DS,[BATCH]
718ASSUME DS:NOTHING
719
720 MOV DX,BatFile
721 MOV AX,OPEN SHL 8
722 INT int_command ; Open the batch file
723 JC SETERRDL
724 MOV DX,WORD PTR DS:[BatSeek]
725 MOV CX,WORD PTR DS:[BatSeek+2]
726 POP DS
727ASSUME DS:RESGROUP
728
729 MOV [BATHAND],AX
730 MOV BX,AX
731 MOV AX,LSEEK SHL 8 ; Go to the right spot
732 INT int_command
733 MOV BatBufPos,-1 ; nuke batch buffer position
734
735 return
736
737SETERRDL:
738 MOV BX,DX
739 invoke get_ext_error_number ;AN022; get the extended error
740 mov dx,ax ;AN022; save extended error in DX
741 MOV AL,[BX] ; Get drive spec
742 SUB AL,'@' ; A = 1
743 POP DS
744 STC ; SUB mucked over carry
745
746 return
747
748EndProc BatOpen
749
750
751TRANCODE ENDS
752 END
753 \ No newline at end of file
diff --git a/v4.0/src/CMD/COMMAND/TCMD1A.ASM b/v4.0/src/CMD/COMMAND/TCMD1A.ASM
new file mode 100644
index 0000000..fd662b3
--- /dev/null
+++ b/v4.0/src/CMD/COMMAND/TCMD1A.ASM
@@ -0,0 +1,598 @@
1 page 80,132
2; SCCSID = @(#)tcmd1a.asm 1.1 85/05/14
3; SCCSID = @(#)tcmd1a.asm 1.1 85/05/14
4TITLE PART4 COMMAND Transient routines.
5
6; Internal commands DIR,PAUSE,ERASE,TYPE,VOL,VER
7
8 INCLUDE comsw.asm
9.xlist
10.xcref
11 INCLUDE DOSSYM.INC
12 INCLUDE comseg.asm
13 INCLUDE comequ.asm ;AC000;
14 include ioctl.inc ;AN000;
15.list
16.cref
17
18DATARES SEGMENT PUBLIC BYTE ;AN020;
19 EXTRN append_flag:byte ;AN020;
20 EXTRN append_state:word ;AN020;
21DATARES ENDS ;AN020;
22
23TRANDATA SEGMENT PUBLIC BYTE ;AC000;
24 EXTRN BadCD_ptr:word
25 EXTRN bits:word
26 EXTRN Bytmes_ptr:word
27 EXTRN comsw:word
28 EXTRN dir_w_syn:word ;AC000;
29 EXTRN dirdat_mo_day:word ;AC000;
30 EXTRN dirdat_yr:word ;AC000;
31 EXTRN dirdattim_ptr:word
32 EXTRN dirhead_ptr:word
33 EXTRN dirtim_hr_min:word ;AC000;
34 EXTRN Dirmes_ptr:word
35 EXTRN disp_file_size_ptr:word
36 EXTRN Dmes_ptr:word
37 EXTRN Extend_buf_ptr:word ;AN000;
38 EXTRN msg_disp_class:byte ;AN000;
39 EXTRN parse_dir:byte ;AC000;
40 EXTRN slash_p_syn:word ;AC000;
41 EXTRN string_buf_ptr:word
42 EXTRN tab_ptr:word ;AC000;
43TRANDATA ENDS
44
45TRANSPACE SEGMENT PUBLIC BYTE ;AC000;
46 EXTRN bytes_free:word
47 EXTRN charbuf:byte
48 EXTRN COM:byte
49 EXTRN Destisdir:byte
50 EXTRN Desttail:word
51 EXTRN dir_num:word
52 EXTRN Dirbuf:byte
53 EXTRN dirflag:byte ;AN015;
54 EXTRN display_ioctl:word ;AC000;
55 EXTRN display_mode:byte ;AC000;
56 EXTRN filecnt:word
57 EXTRN file_size_high:word
58 EXTRN file_size_low:word
59 EXTRN fullscr:word
60 EXTRN ID:byte
61 EXTRN lincnt:byte ;AC000;
62 EXTRN linlen:byte
63 EXTRN linperpag:word ;AC000;
64 EXTRN msg_numb:word ;AN022;
65 EXTRN parse1_addr:dword ;AC000;
66 EXTRN parse1_syn:word ;AC000;
67 EXTRN parse1_type:byte ;AC000;
68 EXTRN pathcnt:word ;AN000;
69 EXTRN pathpos:word ;AN000;
70 EXTRN resseg:word ;AN020;
71 EXTRN srcbuf:byte ;AC000;
72 EXTRN string_ptr_2:word
73TRANSPACE ENDS
74
75TRANCODE SEGMENT PUBLIC BYTE
76
77ASSUME CS:TRANGROUP,DS:NOTHING,ES:NOTHING,SS:NOTHING
78
79;---------------
80
81TRANSPACE SEGMENT PUBLIC BYTE ;AC000;
82 EXTRN arg:byte ; the arg structure!
83TRANSPACE ENDS
84;---------------
85
86 EXTRN cerror:near
87 EXTRN std_printf:near
88
89
90 PUBLIC catalog
91
92
93 break Catalog - Directory command
94assume ds:trangroup,es:trangroup
95
96;
97; The DIR command displays the contents of a directory.
98;
99; ****************************************************************
100; *
101; * ROUTINE: CATALOG - display file(s) in directory
102; *
103; * FUNCTION: PARSE command line for drive, file, or path name.
104; * DIR allows two switches, /P (pause) and /W (wide).
105; * If an error occurs issue and error message and
106; * transfer control to CERROR.
107; *
108; * INPUT: command line at offset 81H
109; *
110; * OUTPUT: none
111; *
112; ****************************************************************
113
114CATALOG:
115
116;
117; Set up DTA for dir search firsts
118;
119 mov dx,offset trangroup:Dirbuf ;AC000; Set Disk transfer address
120 mov ah,Set_DMA ;AC000;
121 int int_command ;AC000;
122;
123; Set up defaults for switches and parse the command line.
124;
125 mov msg_numb,0 ;AN022; initialize message flag
126 mov di,offset trangroup:srcbuf ;AN000; get address of srcbuf
127 mov [pathpos],di ;AN000; this is start of path
128 mov [pathcnt],1 ;AN000; initialize length to 1 char
129 mov al,star ;AN000; initialize srcbuf to *,0d
130 stosb ;AN000;
131 mov al,end_of_line_in ;AN000;
132 stosb ;AN000;
133 mov si,81H ;AN000; Get command line
134 mov di,offset trangroup:parse_dir ;AN000; Get adderss of PARSE_DIR
135 xor cx,cx ;AC000; clear counter for positionals
136 mov ComSw,cx ;AC000; initialize flags
137 mov bits,cx ;AC000; initialize switches
138 mov linperpag,linesperpage ;AC000; Set default for lines per page
139 mov linlen,normperlin ;AC000; Set number of entries per line
140 mov lincnt,normperlin ;AC000;
141
142dirscan:
143 xor dx,dx ;AN000;
144 invoke parse_with_msg ;AC018; call parser
145 cmp ax,end_of_line ;AN000; are we at end of line?
146 jne dirscan_cont ;AN000; No - continue parsing
147 jmp scandone ;AN000; yes - go process
148
149dirscan_cont:
150 cmp ax,result_no_error ;AN000; did we have an error?
151 jz dirscan_cont2 ;AN000; No - continue parsing
152 jmp badparm ;AN000; yes - exit
153
154dirscan_cont2:
155 cmp parse1_syn,offset trangroup:dir_w_syn ;AN000; was /W entered?
156 je set_dir_width ;AN000; yes - go set wide lines
157 cmp parse1_syn,offset trangroup:slash_p_syn ;AN000; was /P entered?
158 je set_dir_pause ;AN000; yes - go set pause at end of screen
159;
160; Must be filespec since no other matches occurred. move filename to srcbuf
161;
162 push si ;AC000; save position in line
163 lds si,parse1_addr ;AC000; get address of filespec
164 push si ;AN000; save address
165 invoke move_to_srcbuf ;AC000; move to srcbuf
166 pop dx ;AC000; get address in DX
167
168;
169; The user may have specified a device. Search for the path and see if the
170; attributes indicate a device.
171;
172 mov ah,Find_First ;AC000; find the file
173 int int_command ;AC000;
174 jnc Dir_check_device ;AN022; if no error - check device
175 invoke get_ext_error_number ;AN022; get the extended error
176 cmp ax,error_no_more_files ;AN022; was error no file found
177 jz Dir_fspec_end ;AC022; yes -> obviously not a device
178 cmp ax,error_path_not_found ;AN022; was error no file found
179 jz Dir_fspec_end ;AC022; yes -> obviously not a device
180 jmp dir_err_setup ;AN022; otherwise - go issue error message
181
182dir_check_device: ;AN022;
183 test byte ptr (DirBuf+find_buf_attr),attr_device ;AC000;
184 jz Dir_fspec_end ;AC000; no, go do normal operation
185 mov ComSw,-2 ;AC000; signal device
186
187dir_fspec_end:
188 pop si ;AC000; restore position in line
189 jmp short dirscan ;AC000; keep parsing
190
191set_dir_width:
192 test byte ptr[bits],SwitchW ;AN018; /W already set?
193 jz ok_set_width ;AN018; no - okay to set width
194 mov ax,moreargs_ptr ;AN018; set up too many arguments
195 invoke setup_parse_error_msg ;AN018; set up an error message
196 jmp badparm ;AN018; exit
197
198ok_set_width:
199 or bits,switchw ;AC000; indicate /w was selected
200 mov linlen,wideperlin ;AC000; Set number of entries per line
201 mov lincnt,wideperlin ;AC000;
202 jmp short dirscan ;AC000; keep parsing
203
204set_dir_pause:
205 test byte ptr[bits],SwitchP ;AN018; /p already set?
206 jz ok_set_pause ;AN018; no - okay to set width
207 mov ax,moreargs_ptr ;AN018; set up too many arguments
208 invoke setup_parse_error_msg ;AN018; set up an error message
209 jmp badparm ;AN018; exit
210
211ok_set_pause:
212 or bits,switchp ;AC000; indicate /p was selected
213 push cx ;AN000; save necessary registers
214 push si ;AN000;
215 mov ax,(IOCTL SHL 8) + generic_ioctl_handle ;AN000; get lines per page on display
216 mov bx,stdout ;AN000; lines for stdout
217 mov ch,ioc_sc ;AN000; type is display
218 mov cl,get_generic ;AN000; get information
219 mov dx,offset trangroup:display_ioctl ;AN000;
220 int int_command ;AN000;
221
222lines_set:
223 dec linperpag ;AN000; lines per actual page should
224 dec linperpag ;AN000; two less than the max
225 mov ax,linperpag ;AN000; get number of lines into
226 mov [fullscr],ax ;AC000; screen line counter
227 pop si ;AN000; restore registers
228 pop cx ;AN000;
229 jmp dirscan ;AC000; keep parsing
230
231;
232; The syntax is incorrect. Report only message we can.
233;
234BadParm:
235 jmp cerror ;AC000; invalid switches get displayed
236
237ScanDone:
238
239;
240; Find and display the volume ID on the drive.
241;
242
243 invoke okvolarg ;AC000;
244 mov [filecnt],0 ;AC000; Keep track of how many files found
245 cmp comsw,0 ;AC000; did an error occur?
246 jnz doheader ;AC000; yes - don't bother to fix path
247
248 mov dirflag,-1 ;AN015; set pathcrunch called from DIR
249 invoke pathcrunch ;AC000; set up FCB for dir
250 mov dirflag,0 ;AN015; reset dirflag
251 jc DirCheckPath ;AC015; no CHDIRs worked.
252 jz doheader ;AC015; chdirs worked - path\*.*
253 mov si,[desttail] ;AN015; get filename back
254 jmp short DoRealParse ;AN015; go parse it
255
256DirCheckPath:
257 mov ax,[msg_numb] ;AN022; get message number
258 cmp ax,0 ;AN022; Is there a message?
259 jnz dir_err_setup ;AN022; yes - there's an error
260 cmp [destisdir],0 ;AC000; Were pathchars found?
261 jz doparse ;AC000; no - no problem
262 inc comsw ;AC000; indicate error
263 jmp short doheader ;AC000; go print header
264
265DirNF:
266 mov ax,error_file_not_found ;AN022; get message number in control block
267
268dir_err_setup:
269 mov msg_disp_class,ext_msg_class ;AN000; set up extended error msg class
270 mov dx,offset TranGroup:Extend_Buf_ptr ;AC000; get extended message pointer
271 mov extend_buf_ptr,ax ;AN022;
272
273DirError:
274 jmp Cerror
275
276;
277; We have changed to something. We also have a file. Parse it into a
278; reasonable form, leaving drive alone, leaving extention alone and leaving
279; filename alone. We need to special case ... If we are at the root, the
280; parse will fail and it will give us a file not found instead of file not
281; found.
282;
283DoParse:
284 mov si,offset trangroup:srcbuf ;AN000; Get address of source
285 cmp byte ptr [si+1],colon_char ;AN000; Is there a drive?
286 jnz dir_no_drive ;AN000; no - keep going
287 lodsw ;AN000; bypass drive
288
289dir_no_drive:
290 cmp [si],".."
291 jnz DoRealParse
292 cmp byte ptr [si+2],0
293 jnz DoRealParse
294 inc ComSw
295 jmp short DoHeader
296
297DoRealParse:
298 mov di,FCB ; where to put the file name
299 mov ax,(Parse_File_Descriptor SHL 8) OR 0EH
300 int int_command
301
302;
303; Check to see if APPEND installed. If it is installed, set all flags
304; off. This will be reset in the HEADFIX routine
305;
306
307DoHeader:
308 mov ax,AppendInstall ;AN020; see if append installed
309 int 2fh ;AN020;
310 cmp al,0 ;AN020; append installed?
311 je DoHeaderCont ;AN020; no - continue
312 mov ax,AppendDOS ;AN020; see if append DOS version right
313 int 2fh ;AN020;
314 cmp ax,-1 ;AN020; append version correct?
315 jne DoHeaderCont ;AN020; no - continue
316 mov ax,AppendGetState ;AN020; Get the state of Append
317 int 2fh ;AN020;
318 push ds ;AN020; save current data segment
319 mov ds,[resseg] ;AN020; get resident segment
320 assume ds:resgroup ;AN020;
321 mov append_state,bx ;AN020; save append state
322 mov append_flag,-1 ;AN020; set append flag
323 xor bx,bx ;AN020; clear out state
324 mov ax,AppendSetState ;AN020; Set the state of Append
325 int 2fh ;AN020; set everything off
326 pop ds ;AN020; save current data segment
327 assume ds:trangroup ;AN020;
328
329;
330; Display the header
331;
332
333DoHeaderCont:
334 mov al,blank ;AN051; Print out a blank
335 invoke print_char ;AN051; before DIR header
336 invoke build_dir_string ; get current dir string
337 mov dx,offset trangroup:Dirhead_ptr
338 invoke printf_crlf ; bang!
339
340;
341; If there were chars left after parse or device, then invalid file name
342;
343 cmp ComSw,0
344 jz DoSearch ; nothing left; good parse
345 jl DirNFFix ; not .. => error file not found
346 invoke RestUDir
347 mov dx,offset TranGroup:BadCD_ptr
348 jmp Cerror ; was .. => error directory not found
349DirNFFix:
350 invoke RestUDir
351 jmp DirNF
352;
353; We are assured that everything is correct. Let's go and search. Use
354; attributes that will include finding directories. perform the first search
355; and reset our directory afterward.
356;
357DoSearch:
358 mov byte ptr DS:[FCB-7],0FFH
359 mov byte ptr DS:[FCB-1],010H
360;
361; Caution! Since we are using an extended FCB, we will *also* be returning
362; the directory information as an extended FCB. We must bias all fetches into
363; DIRBUF by 8 (Extended FCB part + drive)
364;
365 mov ah,Dir_Search_First
366 mov dx,FCB-7
367 int int_command
368
369 push ax ;AN022; save return state
370 inc al ;AN022; did an error occur?
371 pop ax ;AN022; get return state back
372 jnz found_first_file ;AN022; no error - start dir
373 invoke set_ext_error_msg ;AN022; yes - set up error message
374 push dx ;AN022; save message
375 invoke restudir ;AN022; restore user's dir
376 pop dx ;AN022; restore message
377 cmp word ptr Extend_Buf_Ptr,Error_No_More_Files ;AN022; convert no more files to
378 jnz DirCerrorJ ;AN022; file not found
379 mov Extend_Buf_Ptr,Error_File_Not_Found ;AN022;
380
381DirCerrorJ: ;AN022;
382 jmp Cerror ;AN022; exit
383
384;
385; Restore the user's directory. We preserve, though, the return from the
386; previous system call for later checking.
387;
388
389found_first_file:
390 push ax
391 invoke restudir
392 pop ax
393;
394; Main scanning loop. Entry has AL = Search first/next error code. Test for
395; no more.
396;
397DIRSTART:
398 inc al ; FF = file not found
399 jnz Display
400 jmp DirDone ; Either an error or we are finished
401;
402; Note that we've seen a file and display the found file.
403;
404
405Display:
406 inc [filecnt] ; Keep track of how many we find
407 mov si,offset trangroup:dirbuf+8 ; SI -> information returned by sys call
408 call shoname
409;
410; If we are displaying in wide mode, do not output the file info
411;
412 test byte ptr[bits],SwitchW ; W switch set?
413 jz DirTest
414 jmp nexent ; If so, no size, date, or time
415
416;
417; Test for directory.
418;
419DirTest:
420 test [dirbuf+8].dir_attr,attr_directory
421 jz fileent
422;
423; We have a directory. Display the <DIR> field in place of the file size
424;
425 mov dx,offset trangroup:Dmes_ptr
426 call std_printf
427 jmp short nofsiz
428;
429; We have a file. Display the file size
430;
431fileent:
432 mov dx,[DirBuf+8].dir_size_l
433 mov file_size_low,dx
434 mov dx,[DirBuf+8].dir_size_h
435 mov file_size_high,dx
436 mov dx,offset trangroup:disp_file_size_ptr
437 call std_printf
438;
439; Display time and date of last modification
440;
441nofsiz:
442 mov ax,[DirBuf+8].dir_date ; Get date
443;
444; If the date is 0, then we have found a 1.x level diskette. We skip the
445; date/time fields as 1.x did not have them.
446;
447 or ax,ax
448 jz nexent ; Skip if no date
449 mov bx,ax
450 and ax,1FH ; get day
451 mov dl,al
452 mov ax,bx
453 mov cl,5
454 shr ax,cl ; Align month
455 and al,0FH ; Get month
456 mov dh,al
457 mov cl,bh
458 shr cl,1 ; Align year
459 xor ch,ch
460 add cx,80 ; Relative 1980
461 cmp cl,100
462 jb millenium
463 sub cl,100
464
465millenium:
466 xchg dh,dl ;AN000; switch month & day
467 mov DirDat_yr,cx ;AC000; put year into message control block
468 mov DirDat_mo_day,dx ;AC000; put month and day into message control block
469 mov cx,[DirBuf+8].dir_time ; Get time
470 jcxz prbuf ; Time field present?
471 shr cx,1
472 shr cx,1
473 shr cx,1
474 shr cl,1
475 shr cl,1 ; Hours in CH, minutes in CL
476 xchg ch,cl ;AN000; switch hours & minutes
477 mov DirTim_hr_min,cx ;AC000; put hours and minutes into message subst block
478
479prbuf:
480 mov dx,offset trangroup:DirDatTim_ptr
481 call std_printf
482 invoke crlf2 ;AC066;end the line
483 dec byte ptr [fullscr] ;AC066;count the line
484 jnz endif04 ;AN066;IF the last on the screen THEN
485 call check_for_P ;AN066; pause if /P requested
486 endif04: ;AN066;
487 jmp scroll ; If not, just continue
488;AD061; mov DirDat_yr,0 ;AC000; reset year, month and day
489;AD061; mov DirDat_mo_day,0 ;AC000; in control block
490;AD061; mov DirTim_hr_min,0 ;AC000; reset hour & minute in control block
491;
492; We are done displaying an entry. The code between "noexent:" and "scroll:"
493; is only for /W case.
494;
495nexent:
496 mov bl,[lincnt] ;AN066;save for check for first entry on line
497 dec [lincnt] ;count this entry on the line
498 jnz else01 ;AX066;IF last entry on line THEN
499 mov al,[linlen]
500 mov [lincnt],al
501 invoke crlf2
502 cmp [fullscr],0 ;AC066;IF have filled the screen THEN
503 jnz endif02 ;AN066;
504 call check_for_P ;AN066; reinitialize fullscr,
505 endif02: ;AN066; IF P requested THEN pause
506 jmp short endif01 ;AN066;
507 else01: ;AN066;ELSE since screen not full
508 cmp bl,[linlen] ;AN066; IF starting new line THEN
509 jne endif03 ; count the line
510 dec byte ptr [fullscr] ;AN066; ENDIF
511 endif03: ;AC066;We are outputting on the same line, between fields, we tab.
512 mov dx,offset trangroup:tab_ptr ;Output a tab
513 call std_printf
514 endif01: ;AX066;
515;
516; All we need to do now is to get the next directory entry.
517;
518scroll:
519 mov ah,Dir_Search_Next
520 mov dx,FCB-7 ; DX -> Unopened FCB
521 int int_command ; Search for a file to match FCB
522 jmp DirStart
523;
524; If no files have been found, display a not-found message
525;
526DirDone:
527 invoke get_ext_error_number ;AN022; get the extended error number
528 cmp ax,error_no_more_files ;AN022; was error file not found?
529 jnz dir_err_setup_jmp ;AN022; no - setup error message
530 test [filecnt],-1
531 jnz Trailer
532 mov ax,error_file_not_found ;AN022;
533
534dir_err_setup_jmp: ;AN022;
535 jmp dir_err_setup ;AN022; go setup error msg & print it
536;
537; If we have printed the maximum number of files per line, terminate it with
538; CRLF.
539;
540Trailer:
541 mov al,[linlen]
542 cmp al,[lincnt] ; Will be equal if just had CR/LF
543 jz mmessage
544 invoke crlf2
545 cmp [fullscr],0 ;AN066;IF on last line of screen THEN
546 jnz endif06 ;AN066; pause before going on
547 call check_for_P ;AN066; to number and freespace
548 endif06: ;AN066; displays
549
550mmessage:
551 mov dx,offset trangroup:Dirmes_ptr
552 mov si,[filecnt]
553 mov dir_num,si
554 call std_printf
555 mov ah,Get_Drive_Freespace
556 mov dl,byte ptr DS:[FCB]
557 int int_command
558 cmp ax,-1
559 retz
560 mul cx ; AX is bytes per cluster
561 mul bx
562 mov bytes_free,ax ;AC000;
563 mov bytes_free+2,dx ;AC000;
564 MOV DX,OFFSET TRANGROUP:BYTMES_ptr
565 jmp std_printf
566
567shoname:
568 mov di,offset trangroup:charbuf
569 mov cx,8
570 rep movsb
571 mov al,' '
572 stosb
573 mov cx,3
574 rep movsb
575 xor ax,ax
576 stosb
577 push dx
578 mov dx,offset trangroup:charbuf
579 mov string_ptr_2,dx
580 mov dx,offset trangroup:string_buf_ptr
581 call std_printf
582 pop DX
583 return
584
585check_for_P PROC NEAR ;AN066;
586
587test byte ptr[bits],SwitchP ;P switch present?
588jz endif05 ;AN066;
589 mov ax,linperpag ;AN000; transfer lines per page
590 mov [fullscr],ax ;AC000; to fullscr
591 invoke Pause
592endif05:
593ret ;AN066;
594
595check_for_P ENDP ;AN066;
596
597trancode ends
598 end
diff --git a/v4.0/src/CMD/COMMAND/TCMD1B.ASM b/v4.0/src/CMD/COMMAND/TCMD1B.ASM
new file mode 100644
index 0000000..7a45e9d
--- /dev/null
+++ b/v4.0/src/CMD/COMMAND/TCMD1B.ASM
@@ -0,0 +1,730 @@
1 page 80,132
2; SCCSID = @(#)tcmd1b.asm 1.1 85/05/14
3; SCCSID = @(#)tcmd1b.asm 1.1 85/05/14
4TITLE PART4 COMMAND Transient routines.
5
6; Internal commands DIR,PAUSE,ERASE,TYPE,VOL,VER
7
8.xlist
9.xcref
10 INCLUDE DOSSYM.INC
11 INCLUDE comseg.asm
12 INCLUDE comsw.asm ;AC000;
13 INCLUDE comequ.asm
14 INCLUDE ioctl.inc ;AN000;
15 INCLUDE ea.inc ;AN030;
16.list
17.cref
18
19
20TRANDATA SEGMENT PUBLIC BYTE ;AC000;
21 EXTRN badcpmes_ptr:word ;AC022;
22 EXTRN Extend_buf_ptr:word ;AC000;
23 EXTRN Extend_buf_sub:byte ;AN000;
24 EXTRN inornot_ptr:word
25 EXTRN msg_disp_class:byte ;AC000;
26 EXTRN parse_erase:byte ;AC000;
27 EXTRN parse_mrdir:byte ;AC000;
28 EXTRN parse_rename:byte ;AC000;
29 EXTRN parse_vol:byte ;AC000;
30 EXTRN PauseMes_ptr:word
31 EXTRN renerr_ptr:word
32 EXTRN slash_p_syn:word ;AC000;
33 EXTRN volmes_ptr:word ;AC000;
34 EXTRN volmes_ptr_2:word ;AC000;
35 EXTRN volsermes_ptr:word ;AC000;
36 EXTRN xa_cp:byte ;AN030;
37TRANDATA ENDS
38
39TRANSPACE SEGMENT PUBLIC BYTE ;AC000;
40 EXTRN bytcnt:word
41 EXTRN charbuf:byte
42 EXTRN comsw:word
43 EXTRN cpyflag:byte ;AC000;
44 EXTRN curdrv:byte
45 EXTRN destinfo:byte
46 EXTRN destisdir:byte
47 EXTRN dirbuf:byte
48 EXTRN msg_numb:word ;AN022;
49 EXTRN one_char_val:byte
50 EXTRN parse1_addr:dword ;AN000;
51 EXTRN parse1_syn:word ;AN000;
52 EXTRN srcbuf:byte ;AN000;
53 EXTRN string_ptr_2:word ;AN000;
54 EXTRN TPA:word
55 EXTRN vol_drv:byte
56 EXTRN vol_ioctl_buf:byte ;AC000;
57 EXTRN vol_label:byte ;AC000;
58 EXTRN vol_serial:dword ;AC000;
59 EXTRN xa_cp_out:byte ;AN030;
60 EXTRN xa_cp_length:word ;AN030;
61 EXTRN xa_list_attr:word ;AC030;
62 EXTRN zflag:byte
63TRANSPACE ENDS
64
65TRANCODE SEGMENT PUBLIC BYTE
66
67ASSUME CS:TRANGROUP,DS:NOTHING,ES:NOTHING,SS:NOTHING
68
69;---------------
70
71TRANSPACE SEGMENT PUBLIC BYTE ;AC000;
72 EXTRN arg:byte ; the arg structure!
73transpace ends
74;---------------
75
76 EXTRN cerror:near
77 EXTRN error_output:near
78 EXTRN notest2:near
79 EXTRN slashp_erase:near ;AN000;
80 EXTRN std_printf:near
81 EXTRN tcommand:near
82
83 PUBLIC badpath_err ;AN022;
84 PUBLIC crename
85 PUBLIC erase
86 PUBLIC extend_setup ;AN022;
87 PUBLIC Get_ext_error_number ;AN022;
88 PUBLIC Get_file_code_page_tag ;AN000;
89 PUBLIC pause
90 PUBLIC Set_ext_error_msg ;AN000;
91 PUBLIC set_file_code_page ;AN000;
92 PUBLIC typefil
93 PUBLIC volume
94
95
96assume ds:trangroup,es:trangroup
97
98 break Pause
99assume ds:trangroup,es:trangroup
100
101PAUSE:
102 mov dx,offset trangroup:pausemes_ptr
103 call std_printf
104 invoke GetKeystroke
105 invoke crlf2
106 return
107
108 break Erase
109
110;****************************************************************
111;*
112;* ROUTINE: DEL/ERASE - erase file(s)
113;*
114;* FUNCTION: PARSE command line for file or path name and /P
115;* and invoke PATHCRUNCH. If an error occurs, set
116;* up an error message and transfer control to CERROR.
117;* Otherwise, transfer control to NOTEST2 if /P not
118;* entered or SLASHP_ERASE if /P entered.
119;*
120;* INPUT: command line at offset 81H
121;*
122;* OUTPUT: if no error:
123;* FCB at 5ch set up with filename(s) entered
124;* Current directory set to entered directory
125;*
126;****************************************************************
127
128assume ds:trangroup,es:trangroup
129
130ERASE:
131 mov si,81H ;AC000; get command line
132 mov comsw,0 ;AN000; clear switch indicator
133 mov di,offset trangroup:parse_erase ;AN000; Get adderss of PARSE_erase
134 xor cx,cx ;AN000; clear cx,dx
135
136erase_scan:
137 xor dx,dx ;AN000;
138 invoke parse_with_msg ;AC018; call parser
139 cmp ax,end_of_line ;AN000; are we at end of line?
140 jz good_line ;AN000; yes - done parsing
141 cmp ax,result_no_error ;AC000; did we have an error?
142 jnz errj2 ;AC000; yes exit
143
144 cmp parse1_syn,offset trangroup:slash_p_syn ;AN000; was /P entered?
145 je set_erase_prompt ;AN000; yes - go set prompt
146
147;
148; Must be filespec since no other matches occurred. move filename to srcbuf
149;
150 push si ;AC000; save position in line
151 lds si,parse1_addr ;AC000; get address of filespec
152 cmp byte ptr[si+1],colon_char ;AC000; drive specified?
153 jnz Erase_drive_ok ;AC000; no - continue
154 cmp byte ptr[si+2],end_of_line_out ;AC000; was only drive entered?
155 jnz erase_drive_ok ;AC000; no - continue
156 mov ax,error_file_not_found ;AN022; get message number in control block
157 jmp short extend_setup ;AC000; exit
158
159erase_drive_ok:
160 invoke move_to_srcbuf ;AC000; move to srcbuf
161 pop si ;AC000; get position back
162 jmp short erase_scan ;AN000; continue parsing
163
164set_erase_prompt:
165 cmp comsw,0 ;AN018; was /P already entered?
166 jz ok_to_set_erase_prompt ;AN018; no go set switch
167 mov ax,moreargs_ptr ;AN018; set up too many arguments
168 invoke setup_parse_error_msg ;AN018; set up an error message
169 jmp short errj2 ;AN018; exit
170
171ok_to_set_erase_prompt: ;AN018;
172 inc comsw ;AN000; indicate /p specified
173 jmp short erase_scan ;AN000; continue parsing
174
175good_line: ;G We know line is good
176 invoke pathcrunch
177 jnc checkdr
178 mov ax,[msg_numb] ;AN022; get message number
179 cmp ax,0 ;AN022; was message flag set?
180 jnz extend_setup ;AN022; yes - print out message
181 cmp [destisdir],0 ; No CHDIRs worked
182 jnz badpath_err ;AC022; see if they should have
183
184checkdr:
185 cmp comsw,0 ;AN000; was /p specified
186 jz notest2j ;AN000; no - go to notest2
187 jmp slashp_erase ;AN000; yes - go to slashp_erase
188
189notest2j:
190 jmp notest2
191
192badpath_err: ;AN022; "Path not found" message
193 mov ax,error_path_not_found ;AN022; set up error number
194
195extend_setup: ;AN022;
196 mov msg_disp_class,ext_msg_class ;AN022; set up extended error msg class
197 mov dx,offset TranGroup:Extend_Buf_ptr ;AC022; get extended message pointer
198 mov Extend_Buf_ptr,ax ;AN022; get message number in control block
199errj2: ;AC022; exit jump
200 jmp Cerror ;AN022;
201
202 break Rename
203
204; ****************************************************************
205; *
206; * ROUTINE: CRENAME - rename file(s)
207; *
208; * FUNCTION: PARSE command line for one full filespec and one
209; * filename. Invoke PATHCRUNCH on the full filespec.
210; * Make sure the second filespec only contains a
211; * filename. If both openands are valid, attempt
212; * to rename the file.
213; *
214; * INPUT: command line at offset 81H
215; *
216; * OUTPUT: none
217; *
218; ****************************************************************
219
220assume ds:trangroup,es:trangroup
221
222CRENAME:
223
224 mov si,81H ;AC000; Point to command line
225 mov di,offset trangroup:parse_rename;AN000; Get adderss of PARSE_RENAME
226 xor cx,cx ;AN000; clear cx,dx
227 xor dx,dx ;AN000;
228 invoke parse_with_msg ;AC018; call parser
229 cmp ax,result_no_error ;AC000; did we have an error?
230 jz crename_no_parse_error ;AC000; no - continue
231 JMP crename_parse_error ;AC000; Yes, fail. (need long jump)
232
233;
234; Get first file name returned from parse into our buffer
235;
236crename_no_parse_error:
237 push si ;AN000; save position in line
238 lds si,parse1_addr ;AN000; get address of filespec
239 invoke move_to_srcbuf ;AN000; move to srcbuf
240 pop si ;AN000; restore position in line
241
242 xor dx,dx ;AN000; clear dx
243 invoke parse_with_msg ;AC018; call parser
244 cmp ax,result_no_error ;AN000; did we have an error?
245 JNZ crename_parse_error ;AN000; Yes, fail.
246
247;
248; Check the second file name for drive letter colon
249;
250 push si ;AN000; save position in line
251 lds si,parse1_addr ;AC000; get address of path
252
253 mov al,':' ;AC000;
254 cmp [si+1],al ;AC000; Does the 2nd parm have a drive spec?
255 jnz ren_no_drive ;AN000; Yes, error
256 mov msg_disp_class,parse_msg_class ;AN000; set up parse error msg class
257 mov dx,offset TranGroup:Extend_Buf_ptr ;AC000; get extended message pointer
258 mov Extend_Buf_ptr,BadParm_ptr ;AN000; get "Invalid parameter" message number
259
260 pop si ;AN000;
261crename_parse_error: ;AC022;
262 jmp short errj ;AC000;
263
264;
265; Get second file name returned from parse into the fCB. Save
266; character after file name so we can later check to make sure it
267; isn't a path character.
268;
269
270ren_no_drive:
271 mov di,FCB+10H ;AC000; set up to parse second file name
272 mov ax,(Parse_File_Descriptor SHL 8) OR 01H ;AC000;
273 int int_command ;AC000; do the function
274 lodsb ;AC000; Load char after filename
275 mov one_char_val,al ;AN000; save char after filename
276 pop si ;AN000; get line position back
277
278;
279; We have source and target. See if any args beyond.
280;
281
282 mov di,offset trangroup:parse_rename;AC000; get address of parse_rename
283 invoke parse_check_eol ;AC000; are we at end of line?
284 jnz crename_parse_error ;AN000; no, fail.
285
286 invoke pathcrunch
287 mov dx,offset trangroup:badcpmes_ptr
288 jz errj2 ; If 1st parm a dir, print error msg
289 jnc notest3
290 mov ax,[msg_numb] ;AN022; get message number
291 cmp ax,0 ;AN022; was message flag set?
292 jnz extend_setup ;AN022; yes - print out message
293 cmp [destisdir],0 ; No CHDIRs worked
294 jz notest3 ; see if they should have
295 Jmp badpath_err ;AC022; set up error
296
297notest3:
298 mov al,one_char_val ;AN000; move char into AX
299 mov dx,offset trangroup:inornot_ptr ; Load invalid fname error ptr
300 invoke pathchrcmp ; Is the char in al a path sep?
301 jz errj ; Yes, error - 2nd arg must be
302 ; filename only.
303
304 mov ah,FCB_Rename
305 mov dx,FCB
306 int int_command
307 cmp al, 0FFH ; Did an error occur??
308 jnz renameok
309
310 invoke get_ext_error_number ;AN022; get extended error
311 SaveReg <AX> ;AC022; Save results
312 mov al, 0FFH ; Restore original error state
313
314renameok:
315 push ax
316 invoke restudir
317 pop ax
318 inc al
319 retnz
320
321 RestoreReg <AX> ;AC022; get the error number back
322 cmp ax,error_file_not_found ;AN022; error file not found?
323 jz use_renerr ;AN022; yes - use generic error message
324 cmp ax,error_access_denied ;AN022; error file not found?
325 jz use_renerr ;AN022; yes - use generic error message
326 jmp extend_setup ;AN022; need long jump - use extended error
327
328use_renerr:
329 mov dx,offset trangroup:RenErr_ptr ;AC022;
330
331ERRJ:
332 jmp Cerror
333
334ret56: ret
335
336 break Type
337
338;****************************************************************
339;*
340;* ROUTINE: TYPEFIL - Display the contents of a file to the
341;* standard output device
342;*
343;* SYNTAX: TYPE filespec
344;*
345;* FUNCTION: If a valid filespec is found, read the file until
346;* 1Ah and display the contents to STDOUT.
347;*
348;* INPUT: command line at offset 81H
349;*
350;* OUTPUT: none
351;*
352;****************************************************************
353
354assume ds:trangroup,es:trangroup
355
356TYPEFIL:
357 mov si,81H
358 mov di,offset trangroup:parse_mrdir ;AN000; Get adderss of PARSE_MRDIR
359 xor cx,cx ;AN000; clear cx,dx
360 xor dx,dx ;AN000;
361 invoke parse_with_msg ;AC018; call parser
362 cmp ax,result_no_error ;AC000; did we have an error?
363 jnz typefil_parse_error ;AN000; yes - issue error message
364
365 push si ;AC000; save position in line
366 lds si,parse1_addr ;AC000; get address of filespec
367 invoke move_to_srcbuf ;AC000; move to srcbuf
368 pop si ;AC000; get position back
369 mov di,offset trangroup:parse_mrdir ;AC000; get address of parse_mrdir
370 invoke parse_check_eol ;AC000; are we at end of line?
371 jz gottarg ;AC000; yes - continue
372
373typefil_parse_error: ;AN000; no - set up error message and exit
374 jmp Cerror
375
376gottarg:
377 invoke setpath
378 test [destinfo],00000010b ; Does the filespec contain wildcards
379 jz nowilds ; No, continue processing
380 mov dx,offset trangroup:inornot_ptr ; Yes, report error
381 jmp Cerror
382nowilds:
383 mov ax,ExtOpen SHL 8 ;AC000; open the file
384 mov bx,read_open_mode ;AN000; get open mode for TYPE
385 xor cx,cx ;AN000; no special files
386 mov dx,read_open_flag ;AN000; set up open flags
387 mov di,-1 ;AN030; no parm list
388 mov si,offset trangroup:srcbuf ;AN030; get file name
389 int int_command
390 jnc typecont ; If open worked, continue. Otherwise load
391
392Typerr: ;AN022;
393 push cs ;AN022; make sure we have local segment
394 pop ds ;AN022;
395 invoke set_ext_error_msg ;AN022;
396
397Typerr2: ;AN022;
398 mov string_ptr_2,offset trangroup:srcbuf ;AC022; get address of failed string
399 mov Extend_buf_sub,one_subst ;AC022; put number of subst in control block
400 jmp cerror ;AC022; exit
401
402typecont:
403 mov bx,ax ;AC000; get Handle
404 mov cx,stdout ;AN000; set output to STDOUT
405 call set_file_code_page ;AN000; Set code page on output device
406 jc typerr2 ;AN022; exit if error
407
408 mov zflag,0 ; Reset ^Z flag
409 mov ds,[TPA]
410 xor dx,dx
411ASSUME DS:NOTHING
412
413typelp:
414 cmp cs:[zflag],0 ;AC050; Is the ^Z flag set?
415 retnz ; Yes, return
416 mov cx,cs:[bytcnt] ;AC056; No, continue
417 mov ah,read
418 int int_command
419 jc typerr ;AN022; Exit if error
420 mov cx,ax
421 jcxz typelp_ret ;AC000; exit if nothing read
422 push ds
423 pop es ; Check to see if a ^Z was read.
424assume es:nothing
425 xor di,di
426 push ax
427 mov al,1ah
428 repnz scasb
429 pop ax
430 xchg ax,cx
431 cmp ax,0
432 jnz foundz ; Yes, handle it
433 cmp byte ptr [di-1],1ah ; No, double check
434 jnz typecont2 ; No ^Z, continue
435
436foundz:
437 sub cx,ax ; Otherwise change cx so that only those
438 dec cx ; bytes up to but NOT including the ^Z
439 push cs ; will be typed.
440 pop es
441assume es:trangroup
442 not zflag ; Turn on ^Z flag so that the routine
443
444typecont2: ; will quit after this write.
445 push bx
446 mov bx,1
447 mov ah,write
448 int int_command
449 pop bx
450 jc Error_outputj
451 cmp ax,cx
452 jz typelp
453 dec cx
454 cmp ax,cx
455 retz ; One less byte OK (^Z)
456
457Error_outputj:
458 mov bx,1
459 mov ax,IOCTL SHL 8
460 int int_command
461 test dl,devid_ISDEV
462 retnz ; If device, no error message
463 jmp error_output
464
465typelp_ret:
466 ret
467
468 break Volume
469assume ds:trangroup,es:trangroup
470
471;
472; VOLUME command displays the volume ID on the specified drive
473;
474VOLUME:
475
476 mov si,81H
477 mov di,offset trangroup:parse_vol ;AN000; Get adderss of PARSE_VOL
478 xor cx,cx ;AN000; clear cx,dx
479 xor dx,dx ;AN000;
480 invoke parse_with_msg ;AC018; call parser
481 cmp ax,end_of_line ;AC000; are we at end of line?
482 jz OkVolArg ;AC000; Yes, display default volume ID
483 cmp ax,result_no_error ;AC000; did we have an error?
484 jnz BadVolArg ;AC000; Yes, fail.
485;
486; We have parsed off the drive. See if there are any more chars left
487;
488
489 mov di,offset trangroup:parse_vol ;AC000; get address of parse_vol
490 xor dx,dx ;AC000;
491 invoke parse_check_eol ;AC000; call parser
492 jz OkVolArg ;AC000; yes, end of road
493;
494; The line was not interpretable. Report an error.
495;
496badvolarg:
497 jmp Cerror
498;
499; Find the Volume ID on the disk.
500;
501PUBLIC OkVolArg
502OKVOLARG:
503 invoke crlf2
504 mov al,blank ;AN051; Print out a blank
505 invoke print_char ;AN051; before volume message
506 push ds
507 pop es
508;
509; Volume IDs are only findable via extended FCBs or find_first with attributes
510; of volume_id ONLY.
511;
512
513 mov di,FCB-7 ; Point to extended FCB beginning
514 mov al,-1 ; Tag to indicate Extention
515 stosb
516 xor ax,ax ; Zero padding to volume label
517 stosw
518 stosw
519 stosb
520 mov al,attr_volume_ID ; Look for volume label
521 stosb
522 inc di ; Skip drive byte; it is already set
523 mov cx,11 ; fill in remainder of file
524 mov al,'?'
525 rep stosb
526;
527; Set up transfer address (destination of search first information)
528;
529 mov dx,offset trangroup:dirbuf
530 mov ah,set_DMA
531 int int_command
532;
533; Do the search
534;
535 mov dx,FCB-7
536 mov ah,Dir_Search_First
537 int int_command
538
539;********************************
540; Print volume ID info
541
542 push ax ;AC000; AX return from SEARCH_FIRST for VOL ID
543 mov al,DS:[FCB] ;AC000; get drive letter
544 add al,'@'
545 cmp al,'@'
546 jnz drvok
547 mov al,[curdrv]
548 add al,capital_A
549drvok:
550 mov vol_drv,al ;AC000; get drive letter into argument
551 pop ax ;AC000; get return code back
552 or al,al ;AC000; volume label found?
553 jz Get_vol_name ;AC000; volume label exists - go get it
554 mov dx,offset trangroup:VolMes_ptr_2 ;AC000; set up no volume message
555 jmp short print_serial ;AC000; go print it
556
557Get_vol_name:
558 mov di,offset trangroup:charbuf
559 mov dx,di
560 mov si,offset trangroup:dirbuf + 8 ;AN000; 3/3/KK
561 mov cx,11 ;AN000; 3/3/KK
562 rep movsb ;AN000; 3/3/KK
563
564 xor al,al ;AC000; store a zero to terminate the string
565 stosb
566 mov dx,offset trangroup:VolMes_ptr ;AC000; set up message
567
568PRINT_SERIAL:
569
570;
571; Attempt to get the volume serial number from the disk. If an error
572; occurs, do not print volume serial number.
573;
574
575 push dx ;AN000; save message offset
576 mov ax,(GetSetMediaID SHL 8) ;AC036; Get the volume serial info
577 mov bl,DS:[FCB] ;AN000; get drive number from FCB
578 mov dx,offset trangroup:vol_ioctl_buf ;AN000;target buffer
579 int int_command ;AN000; do the call
580 pop dx ;AN000; get message offset back
581 jc printvol_end ;AN000; if error, just go print label
582 call std_printf ;AC000; go print volume message
583 mov al,blank ;AN051; Print out a blank
584 invoke print_char ;AN051; before volume message
585 mov dx,offset trangroup:VolSerMes_ptr ;AN000; get serial number message
586
587printvol_end:
588 jmp std_printf ;AC000; go print and exit
589
590;****************************************************************
591;*
592;* ROUTINE: Set file Code page
593;*
594;* FUNCTION: Check CPSW status, if CPSW is on, get the file's
595;* code page and attempt to invoke it on the
596;* output device.
597;*
598;* INPUT: file handle in BX - unless copyflg is set
599;* handle of output device in CX
600;*
601;* OUTPUT: if carry set (code page invoke failed)
602;* ax = extended error
603;* otherwise
604;* ax modified
605;*
606;*
607;****************************************************************
608
609Set_file_code_page proc near ;AN000;
610
611 push bx ;AN000; save registers
612 push di ;AN000;
613 push dx ;AN000;
614
615 cmp cpyflag,1 ;AN000; were we called from COPY?
616 jz Already_have_cp ;AN000; yes - already have code page
617 call get_file_code_page_tag ;AN000; get the file's code page
618 jc cp_set_error ;AN000; if error - just continue
619
620already_have_cp: ;AN000; See what was returned.
621 mov ax,(file_times SHL 8)+set_XA ;AC030; set code page
622 mov di,offset trangroup:xa_cp_out ;AC030; offset of attr list
623 mov bx,cx ;AN000; get handle of output device
624 int int_command ;AN000;
625 jnc set_file_cp_end ;AN000; all okay - return
626cp_set_error:
627 pop dx ;AC030; we don't restore DX for error -
628 call Set_Ext_Error_msg ;AN000; we return error message
629 jmp short set_file_cp_exit ;AC030; exit
630
631set_file_cp_end: ;AN000; finished
632 pop dx ;AN000; restore registers
633
634set_file_cp_exit:
635 pop di ;AN000;
636 pop bx ;AN000;
637
638 ret ;AN000; return
639
640Set_file_code_page endp ;AN000;
641
642
643;****************************************************************
644;*
645;* ROUTINE: Get file Code page tag
646;*
647;* FUNCTION: Get code page file attribute.
648;*
649;* INPUT: file handle in BX
650;*
651;* OUTPUT: if error - carry set
652;* otherwise - xa_list_attr set to file's code page
653;*
654;* AX and DI modified
655;*
656;****************************************************************
657
658
659Get_file_code_page_tag proc near ;AN000;
660
661 push cx ;AN030;
662 push si ;AN030;
663 push di ;AN030;
664 mov xa_list_attr,0 ;AN030; initialize code page
665 mov ax,(file_times SHL 8)+get_XA ;AC030; get extended attributes
666 mov si,offset trangroup:xa_cp ;AN030; get xa request buffer
667 mov di,offset trangroup:xa_cp_out ;AC030; get xa output buffer
668 mov cx,xa_cp_length ;AN030; length of buffer
669 int int_command ;AN000;
670 pop di ;AN030;
671 pop si ;AN030;
672 pop cx ;AN030;
673
674 ret ;AN000; return
675
676Get_file_code_page_tag endp ;AN000;
677
678
679;****************************************************************
680;*
681;* ROUTINE: Set_ext_error_msg
682;*
683;* FUNCTION: Sets up extended error message for printing
684;*
685;* INPUT: return from INT 21
686;*
687;* OUTPUT: extended error message set up in extended error
688;* buffer.
689;*
690;****************************************************************
691
692Set_ext_error_msg proc near ;AN000;
693
694 call get_ext_error_number ;AC022; get the extended error
695 mov msg_disp_class,ext_msg_class ;AN000; set up extended error msg class
696 mov dx,offset TranGroup:Extend_Buf_ptr ;AC000; get extended message pointer
697 mov Extend_Buf_ptr,ax ;AN000; get message number in control block
698 stc ;AN000; make sure carry is set
699
700 ret ;AN000; return
701
702Set_ext_error_msg endp ;AN000;
703
704;****************************************************************
705;*
706;* ROUTINE: Get_ext_error_number
707;*
708;* FUNCTION: Does get extended error function call
709;*
710;* INPUT: return from INT 21
711;*
712;* OUTPUT: AX - extended error number
713;*
714;****************************************************************
715
716Get_ext_error_number proc near ;AN022;
717
718 SaveReg <BX,CX,DX,SI,DI,BP,ES,DS> ;AN022; save registers
719 mov ah,GetExtendedError ;AN022; get extended error
720 xor bx,bx ;AN022; clear BX
721 int int_command ;AN022;
722 RestoreReg <DS,ES,BP,DI,SI,DX,CX,BX> ;AN022; restore registers
723
724 ret ;AN022; return
725
726Get_ext_error_number endp ;AN022;
727
728trancode ends
729 end
730 \ No newline at end of file
diff --git a/v4.0/src/CMD/COMMAND/TCMD2A.ASM b/v4.0/src/CMD/COMMAND/TCMD2A.ASM
new file mode 100644
index 0000000..9dcb066
--- /dev/null
+++ b/v4.0/src/CMD/COMMAND/TCMD2A.ASM
@@ -0,0 +1,552 @@
1 page 80,132
2; SCCSID = @(#)tcmd2a.asm 4.1 85/06/25
3; SCCSID = @(#)tcmd2a.asm 4.1 85/06/25
4TITLE PART5 COMMAND Transient routines.
5
6 INCLUDE comsw.asm
7
8.xlist
9.xcref
10 INCLUDE DOSSYM.INC
11 INCLUDE comequ.asm
12 INCLUDE comseg.asm
13 include ioctl.inc
14.list
15.cref
16
17
18CODERES SEGMENT PUBLIC BYTE ;AC000;
19CODERES ENDS
20
21DATARES SEGMENT PUBLIC BYTE ;AC000;
22DATARES ENDS
23
24TRANDATA SEGMENT PUBLIC BYTE ;AC000;
25 EXTRN arg_buf_ptr:word
26 EXTRN BadCurDrv:byte ;AC000;
27 EXTRN clsstring:byte
28 EXTRN dback_ptr:word
29 EXTRN display_ioctl:word ;AN000;
30 EXTRN display_width:word ;AN000;
31 EXTRN Extend_buf_ptr:word ;AN049;
32 EXTRN linperpag:word ;AN000;
33 EXTRN msg_disp_class:byte ;AN049;
34 EXTRN nulpath_ptr:word
35 EXTRN prompt_table:word
36 EXTRN string_buf_ptr:word ;AC000;
37 EXTRN vermes_ptr:word
38TRANDATA ENDS
39
40TRANSPACE SEGMENT PUBLIC BYTE ;AC000;
41 EXTRN Arg_Buf:byte
42 EXTRN bwdbuf:byte
43 EXTRN curdrv:byte
44 EXTRN dirchar:byte
45 EXTRN major_ver_num:word
46 EXTRN minor_ver_num:word
47 EXTRN srcxname:byte ;AN049;
48 EXTRN string_ptr_2:word
49TRANSPACE ENDS
50
51TRANCODE SEGMENT PUBLIC BYTE
52
53ASSUME CS:TRANGROUP,DS:NOTHING,ES:NOTHING,SS:NOTHING
54
55;---------------
56
57TRANSPACE SEGMENT PUBLIC BYTE ;AC000;
58 EXTRN arg:byte ; the arg structure!
59transpace ends
60;---------------
61
62 EXTRN cerror:near ;AN049;
63 EXTRN crlf2:near
64 EXTRN drvbad:near
65 EXTRN std_printf:near
66
67 PUBLIC build_dir_for_chdir
68 PUBLIC build_dir_for_prompt
69 PUBLIC build_dir_string
70 PUBLIC cls
71 PUBLIC path
72 PUBLIC print_char
73 PUBLIC print_drive
74 PUBLIC print_version
75 PUBLIC print_b
76 PUBLIC print_back
77 PUBLIC print_eq
78 PUBLIC print_esc
79 PUBLIC print_g
80 PUBLIC print_l
81 PUBLIC print_prompt
82 PUBLIC version
83
84 break Version
85assume ds:trangroup,es:trangroup
86
87VERSION:
88 call crlf2
89 call print_version
90 jmp crlf2
91
92print_version:
93 mov ah,Get_version
94 int int_command
95 push ax
96 xor ah,ah
97 mov major_ver_num,ax
98 pop ax
99 xchg ah,al
100 xor ah,ah
101 mov minor_ver_num,ax
102 mov dx,offset trangroup:vermes_ptr
103 jmp std_printf
104
105print_prompt:
106 push ds
107 push cs
108 pop ds ; MAKE SURE DS IS IN TRANGROUP
109 push es
110 invoke find_prompt ; LOOK FOR PROMPT STRING
111 jc PP0 ; CAN'T FIND ONE
112 cmp byte ptr es:[di],0
113 jnz PP1
114PP0:
115 call print_drive ; USE DEFAULT PROMPT
116 mov al,sym
117 call print_char
118 jmp short PP5
119
120PP1:
121 mov al,es:[di] ; GET A CHAR
122 inc di
123 or al,al
124 jz PP5 ; NUL TERMINATED
125 cmp al,dollar ; META CHARACTER?
126 jz PP2 ; NOPE
127PPP1:
128 call print_char
129 jmp PP1
130
131PP2:
132 mov al,es:[di]
133 inc di
134 mov bx,offset trangroup:prompt_table-3
135 or al,al
136 jz PP5
137
138PP3:
139 add bx,3
140 invoke upconv
141 cmp al,[bx]
142 jz PP4
143 cmp byte ptr [bx],0
144 jnz PP3
145 jmp PP1
146
147PP4:
148 push es
149 push di
150 push cs
151 pop es
152 call [bx+1]
153 pop di
154 pop es
155 jmp PP1
156
157PP5:
158 pop es ; RESTORE SEGMENTS
159 pop ds
160 return
161
162
163print_back:
164 mov dx,offset trangroup:dback_ptr
165 jmp std_printf
166
167print_EQ:
168 mov al,'='
169 jmp short print_char
170
171print_esc:
172 mov al,1BH
173 jmp short print_char
174
175print_G:
176 mov al,rabracket
177 jmp short print_char
178
179print_L:
180 mov al,labracket
181 jmp short print_char
182
183print_B:
184 mov al,vbar
185
186print_char:
187 push es
188 push ds
189 pop es
190 push di
191 push dx
192 mov dl,al ;AC000; Get char into al
193 mov ah,Std_CON_output ;AC000; print the char to stdout
194 int int_command ;AC000;
195 pop dx
196 pop di
197 pop es
198 ret
199
200print_drive:
201 mov ah,Get_Default_drive
202 int int_command
203 add al,capital_A
204 call print_char
205 ret
206
207ASSUME DS:TRANGROUP,ES:TRANGROUP
208
209build_dir_for_prompt:
210 xor dl,dl
211 mov si,offset trangroup:bwdbuf
212 mov di,SI
213 mov al,CurDrv
214 add al,'A'
215 mov ah,':'
216 stosw
217 mov al,[dirchar]
218 stosb
219 xchg si,di
220 mov string_ptr_2,di
221 mov ah,Current_dir
222 int int_command
223 mov dx,offset trangroup:string_buf_ptr
224 jnc DoPrint
225 mov dx,offset trangroup:BadCurDrv
226DoPrint:
227 call std_printf
228
229 ret
230
231build_dir_for_chdir:
232 call build_dir_string
233 mov dx,offset trangroup:bwdbuf
234 mov string_ptr_2,dx
235 mov dx,offset trangroup:string_buf_ptr
236 call std_printf
237 ret
238
239build_dir_string:
240 mov dl,ds:[FCB]
241 mov al,DL
242 add al,'@'
243 cmp al,'@'
244 jnz gotdrive
245 add al,[CURDRV]
246 inc al
247
248gotdrive:
249 push ax
250 mov si,offset trangroup:bwdbuf+3
251 mov ah,Current_dir
252 int int_command
253 jnc dpbisok
254 push cs
255 pop ds
256 jmp drvbad
257
258dpbisok:
259 mov di,offset trangroup:bwdbuf
260 mov dx,di
261 pop ax
262 mov ah,':'
263 stosw
264 mov al,[dirchar]
265 stosb
266
267 ret
268
269 break Path
270assume ds:trangroup,es:trangroup
271
272PATH:
273 xor al,al ;AN049; Set up holding buffer
274 mov di,offset Trangroup:srcxname ;AN049; for PATH while parsing
275 stosb ;AN049; Initialize PATH to null
276 dec di ;AN049; point to the start of buffer
277 invoke PGetarg ; Pre scan for arguments
278 jz disppath ; Print the current path
279 cmp al,semicolon ;AC049; NUL path argument?
280 jnz pathslp ;AC049;
281 inc si ;AN049; point past semicolon
282 jmp short scan_white ;AC049; Yes - make sure nothing else on line
283
284pathslp: ; Get the user specified path
285 lodsb ; Get a character
286 cmp al,end_of_line_in ;AC049; Is it end of line?
287 jz path_eol ;AC049; yes - end of command
288
289 invoke testkanj ;See if DBCS
290 jz notkanj2 ;No - continue
291 stosb ;AC049; Yes - store the first byte
292 lodsb ;skip second byte of DBCS
293
294path_hold: ;AN049;
295 stosb ;AC049; Store a byte in the PATH buffer
296 jmp short pathslp ;continue parsing
297
298notkanj2:
299 invoke upconv ;upper case the character
300 cmp al,semicolon ;AC049; ';' not a delimiter on PATH
301 jz path_hold ;AC049; go store it
302 invoke delim ;delimiter?
303 jnz path_hold ;AC049; no - go store character
304
305scan_white: ;AN049; make sure were at EOL
306 lodsb ;AN049; get a character
307 cmp al,end_of_line_in ;AN049; end of line?
308 jz path_eol ;AN049; yes - go set path
309 cmp al,blank ;AN049; whitespace?
310 jz scan_white ;AN049; yes - continue scanning
311 cmp al,tab_chr ;AN049; whitespace?
312 jz scan_white ;AN049; yes - continue scanning
313
314 mov dx,offset TranGroup:Extend_Buf_ptr ;AN049; no - set up error message
315 mov Extend_Buf_ptr,MoreArgs_ptr ;AN049; get "Too many parameters" message number
316 mov msg_disp_class,parse_msg_class ;AN049; set up parse error msg class
317 jmp cerror ;AN049;
318
319path_eol: ;AN049; Parsing was clean
320 xor al,al ;AN049; null terminate the PATH
321 stosb ;AN049; buffer
322 invoke find_path ;AN049; Find PATH in environment
323 invoke delete_path ;AC049; Delete any offending name
324 invoke scan_double_null ;AC049; Scan to end of environment
325 invoke move_name ;AC049; move in PATH=
326 mov si,offset Trangroup:srcxname ;AN049; Set up source as PATH buffer
327
328store_path: ;AN049; Store the PATH in the environment
329 lodsb ;AN049; Get a character
330 cmp al,end_of_line_out ;AN049; null character?
331 jz got_paths ;AN049; yes - exit
332 invoke store_char ;AN049; no - store character
333 jmp short store_path ;AN049; continue
334
335got_paths: ;AN049; we're finished
336 xor ax,ax ;null terminate the PATH in
337 stosw ; the environment
338 return
339
340disppath:
341 invoke find_path ;AN049;
342 call print_path
343 call crlf2
344 return
345
346print_path:
347 cmp byte ptr es:[di],0
348 jnz path1
349
350path0:
351 mov dx,offset trangroup:nulpath_ptr
352 push cs
353 pop es
354 push cs
355 pop ds
356 jmp std_printf
357
358path1:
359 push es
360 pop ds
361 sub di,5
362 mov si,di
363ASSUME DS:RESGROUP
364 invoke scasb2 ; LOOK FOR NUL
365 cmp cx,0FFH
366 jz path0
367 push cs
368 pop es
369 mov di,offset trangroup:arg_buf
370 mov dx,100h
371 sub dx,cx
372 xchg dx,cx
373 rep movsb
374 mov dx,offset trangroup:arg_buf_ptr
375 push cs
376 pop ds
377 jmp std_printf
378
379ASSUME DS:TRANGROUP
380
381 break Cls
382
383; ****************************************************************
384; *
385; * ROUTINE: CLS
386; *
387; * FUNCTION: Clear the screen using INT 10h. If ANSI.SYS is
388; * installed, send a control string to clear the
389; * screen.
390; *
391; * INPUT: command line at offset 81H
392; *
393; * OUTPUT: none
394; *
395; ****************************************************************
396
397assume ds:trangroup,es:trangroup
398
399ANSI_installed equ 0ffh
400
401CLS:
402 mov ah,Mult_ANSI ;AN000; see if ANSI.SYS installed
403 mov al,0 ;AN000;
404 int 2fh ;AN000;
405 cmp al,ANSI_installed ;AN000;
406 jz ansicls ;AN000; installed - go do ANSI CLS
407
408check_lines:
409 mov ax,(IOCTL SHL 8) + generic_ioctl_handle ;AN000; get lines per page on display
410 mov bx,stdout ;AN000; lines for stdout
411 mov ch,ioc_sc ;AN000; type is display
412 mov cl,get_generic ;AN000; get information
413 mov dx,offset trangroup:display_ioctl ;AN000;
414 int int_command ;AN000;
415 jc no_variable ;AN000; function had error, use default
416 mov ax,linperpag ;AN000; get number of rows returned
417 mov dh,al ;AN000; set number of rows
418 mov ax,display_width ;AN000; get number of columns returned
419 mov dl,al ;AN000; set number of columns
420 jmp short regcls ;AN000; go do cls
421
422no_variable:
423 mov bx,stdout ;AC000; set handle as stdout
424 mov ax,IOCTL SHL 8 ;AC000; do ioctl - get device
425 int int_command ;AC000; info
426 test dl,devid_ISDEV ;AC000; is handle a device
427 jz ANSICLS ;AC000; If a file put out ANSI
428 test dl,devid_SPECIAL ;AC000;
429 jnz cls_normal ;AC000; If not special CON, do ANSI
430
431ansicls:
432 call ansi_cls ;AN000; clear the screen
433 jmp short cls_ret ;AN000; exit
434
435;
436; Get video mode
437;
438
439cls_normal: ;AC000;
440
441 mov ah,get_video_state ;AC000; set up to get video state
442 int video_io_int ;AC000; do int 10h - BIOS video IO
443 cmp al,video_alpha ;AC000; see if in text mode
444 jbe DoAlpha
445 cmp al,video_bw ;AC000; see if black & white card
446 jz DoAlpha
447;
448; We are in graphics mode. Bogus IBM ROM does not scroll correctly. We will
449; be just as bogus and set the mode that we just got. This will blank the
450; screen too.
451;
452 mov ah,set_video_mode ;AC000; set video mode call
453 int video_io_int ;AC000; do int 10h - BIOS video IO
454 jmp short cls_ret ;AC000; exit
455
456DoAlpha:
457;
458; Get video mode and number of columns to scroll
459;
460 mov ah,get_video_state ;AC000; set up to get current video state
461 int video_io_int ;AC000; do int 10h - BIOS video IO
462 mov dl,ah
463 mov dh,linesperpage ;AC000; have 25 rows on the screen
464
465regcls:
466 call reg_cls ;AC000; go clear the screen
467
468cls_ret:
469 ret ;AC000; exit
470
471; ****************************************************************
472; *
473; * ROUTINE: REG_CLS
474; *
475; * FUNCTION: Clear the screen using INT 10H.
476; *
477; * INPUT: DL = NUMBER OF COLUMNS
478; * DH = NUMBER OF ROWS
479; *
480; * OUTPUT: none
481; *
482; ****************************************************************
483
484reg_cls proc near ;AC000;
485
486;
487; Set overscan to black.
488;
489
490 dec dh ;AC000; decrement rows and columns
491 dec dl ;AC000; to zero base
492 push dx ;AN000; save rows,columns
493 mov ah,set_color_palette ;AC000; set up to set the color to blank
494 xor bx,bx
495 int video_io_int ;AC000; do int 10h - BIOS video IO
496 pop dx ;AN000; retore rows,colums
497
498 xor ax,ax ;AC000; zero out ax
499 mov CX,ax ;AC000; an cx
500;
501; Scroll active page
502;
503 mov ah,scroll_video_page ;AC000; set up to scroll page up
504 mov bh,video_attribute ;AC000; attribute for blank line
505 xor bl,bl ;AC000; set BL to 0
506 int video_io_int ;AC000; do int 10h - BIOS video IO
507;
508; Seek to cursor to 0,0
509;
510 mov ah,set_cursor_position ;AC000; set up to set cursor position
511 xor dx,dx ;AC000; row and column 0
512 mov bh,0 ;AC000;
513 int video_io_int ;AC000; do into 10h - BIOS video IO
514
515 ret ;AC000;
516
517reg_cls endp ;AC000;
518
519
520
521; ****************************************************************
522; *
523; * ROUTINE: ANSI_CLS
524; *
525; * FUNCTION: Clear the screen using by writing a control code
526; * to STDOUT.
527; *
528; * INPUT: none
529; *
530; * OUTPUT: none
531; *
532; ****************************************************************
533
534ansi_cls proc near ;AC000;
535
536 mov si,offset trangroup:clsstring
537 lodsb
538 mov cl,al
539 xor ch,ch
540 mov ah,Raw_CON_IO
541clrloop:
542 lodsb
543 mov DL,al
544 int int_command
545 loop clrloop
546 return
547
548ansi_cls endp ;AC000;
549
550trancode ends
551 end
552 \ No newline at end of file
diff --git a/v4.0/src/CMD/COMMAND/TCMD2B.ASM b/v4.0/src/CMD/COMMAND/TCMD2B.ASM
new file mode 100644
index 0000000..4db1f11
--- /dev/null
+++ b/v4.0/src/CMD/COMMAND/TCMD2B.ASM
@@ -0,0 +1,597 @@
1 page 80,132
2; SCCSID = @(#)tcmd2b.asm 4.1 85/09/22
3; SCCSID = @(#)tcmd2b.asm 4.1 85/09/22
4TITLE PART5 COMMAND Transient routines.
5
6.xlist
7.xcref
8 INCLUDE comsw.asm
9 INCLUDE DOSSYM.INC
10 INCLUDE comseg.asm
11 INCLUDE comequ.asm
12.list
13.cref
14
15
16CODERES SEGMENT PUBLIC BYTE ;AC000;
17 EXTRN LODCOM1:NEAR
18CODERES ENDS
19
20DATARES SEGMENT PUBLIC BYTE ;AC000;
21 EXTRN crit_msg_off:word ;AC000;
22 EXTRN crit_msg_seg:word ;AC000;
23 EXTRN IO_SAVE:WORD
24 EXTRN OldTerm:DWORD
25 EXTRN PARENT:WORD
26;AD060; EXTRN pars_msg_off:word ;AC000;
27;AD060; EXTRN pars_msg_seg:word ;AC000;
28 EXTRN PERMCOM:BYTE ;AN045;
29 EXTRN RetCode:WORD
30DATARES ENDS
31
32TRANDATA SEGMENT PUBLIC BYTE ;AC000;
33 EXTRN ACRLF_PTR:WORD ;AN007;
34 EXTRN baddev_ptr:word
35 EXTRN CP_active_Ptr:word
36 EXTRN CP_not_all_Ptr:word
37 EXTRN CP_not_set_Ptr:word
38 EXTRN Extend_buf_ptr:word ;AN000;
39 EXTRN Extend_buf_sub:byte ;AN000;
40 EXTRN inv_code_page:word ;AC000;
41 EXTRN msg_disp_class:byte ;AN000;
42 EXTRN NLSFUNC_Ptr:word ;AC000;
43 EXTRN parse_chcp:byte ;AC000;
44 EXTRN parse_chdir:byte ;AC000;
45 EXTRN parse_ctty:byte ;AC000;
46 EXTRN string_buf_ptr:word ;AC000;
47
48TRANDATA ENDS
49
50TRANSPACE SEGMENT PUBLIC BYTE ;AC000;
51 EXTRN COMBUF:BYTE
52 EXTRN parse_last:word ;AN018;
53 EXTRN parse1_addr:dword ;AC000;
54 EXTRN parse1_type:byte ;AC000;
55 EXTRN RESSEG:WORD
56 EXTRN srcbuf:byte
57 EXTRN srcxname:byte ;AC000;
58 EXTRN string_ptr_2:word
59 EXTRN system_cpage:word
60 EXTRN TRAN_TPA:WORD
61TRANSPACE ENDS
62
63TRANCODE SEGMENT PUBLIC BYTE
64
65ASSUME CS:TRANGROUP,DS:NOTHING,ES:NOTHING,SS:NOTHING
66
67;---------------
68
69TRANSPACE SEGMENT PUBLIC BYTE ;AC000;
70 EXTRN arg:byte ; the arg structure!
71TRANSPACE ENDS
72;---------------
73
74 EXTRN cerror:near
75
76 PUBLIC $exit
77 PUBLIC chcp
78 PUBLIC ctty
79 PUBLIC parse_check_eol ;AN000;
80 PUBLIC parse_with_msg ;AN018;
81 PUBLIC setup_parse_error_msg ;AN018;
82 PUBLIC truename ;AN000;
83
84 break Ctty
85assume ds:trangroup,es:trangroup
86
87; ****************************************************************
88; *
89; * ROUTINE: CTTY - Change console
90; *
91; * SYNTAX: CTTY device
92; *
93; * FUNCTION: If a valid console device is specified, CTTY will
94; * duplicate the device handle to STDIN, STDOUT and
95; * STDERR. This routine returns to LODCOM1.
96; *
97; * INPUT: command line at offset 81H
98; *
99; * OUTPUT: none
100; *
101; ****************************************************************
102
103CTTY:
104 push ds ;AN000; Get local ES
105 pop es ;AN000;
106 mov si,81H ;AC000; Get command argument for CTTY
107
108 mov di,offset trangroup:parse_ctty ;AC000; Get adderss of PARSE_CTTY
109 xor cx,cx ;AC000; clear cx,dx
110 xor dx,dx ;AC000;
111 invoke cmd_parse ;AC000; call parser
112 cmp ax,end_of_line ;AN000; are we at end of line?
113 jz ctty_error ;AN000; yes - error
114 cmp ax,result_no_error ;AN000; did an error occur
115 jnz ctty_error ;AN000; YES -ERROR
116
117 push si ;AN000; save position in line
118 lds si,parse1_addr ;AN000; get address of filespec
119 mov di,offset trangroup:srcbuf ;AN000; get address of srcbuf
120
121ctty_move_filename: ;AN000; put filespec in srcbuf
122 lodsb ;AN000; get a char from buffer
123 stosb ;AN000; store in srcbuf
124 cmp al,end_of_line_out ;AN000; it char a terminator?
125 jnz ctty_move_filename ;AN000; no - keep moving
126 pop si ;AN000; get line position back
127 mov di,offset trangroup:parse_ctty ;AC000; Get adderss of PARSE_CTTY
128 call parse_check_eol ;AN000; are we at end of line?
129 jz nocolon ;AN000; yes - continue
130
131ctty_error:
132 jmp isbaddev ;AC000; yes - exit
133
134nocolon:
135 mov dx,offset trangroup:srcbuf ;AN000; get address of srcbuf
136 MOV AX,(OPEN SHL 8) OR 2 ; Read and write
137 INT int_command ; Open new device
138 JC ISBADDEV
139 MOV BX,AX
140 MOV AX,IOCTL SHL 8
141 INT int_command
142 TEST DL,80H
143 JNZ DEVISOK
144
145CLOSEDEV: ;AN007;
146 MOV AH,CLOSE ; Close initial handle
147 INT int_command
148
149ISBADDEV:
150 MOV DX,OFFSET TRANGROUP:BADDEV_ptr
151 invoke std_printf
152 JMP RESRET
153
154DEVISOK:
155 push dx ;AN007; save device info
156 mov ax,acrlf_ptr ;AN021; get message number for 0d, 0a
157 mov dh,util_msg_class ;AN021; this is a utility message
158 push bx ;AN021; save handle
159 invoke Tsysgetmsg ;AN021; get the address of the message
160 mov dx,si ;AN021; get address into dx
161 mov ax,(write shl 8) ;AN007; write to device
162 mov cx,2 ;AN007; write two bytes
163 int int_command ;AN007;
164 pop bx ;AN021; get back handle
165 pop dx ;AN007; get back device info
166 jc closedev ;AN007; if error, quit
167 XOR DH,DH
168 OR DL,3 ; Make sure has CON attributes
169 MOV AX,(IOCTL SHL 8) OR 1
170 INT int_command
171 PUSH BX ; Save handle
172 MOV CX,3
173 XOR BX,BX
174
175ICLLOOP: ; Close basic handles
176 MOV AH,CLOSE
177 INT int_command
178 INC BX
179 LOOP ICLLOOP
180 POP BX ; Get handle
181 MOV AH,XDUP
182 INT int_command ; Dup it to 0
183 MOV AH,XDUP
184 INT int_command ; Dup to 1
185 MOV AH,XDUP
186 INT int_command ; Dup to 2
187 MOV AH,CLOSE ; Close initial handle
188 INT int_command
189
190RESRET:
191 MOV DS,[RESSEG]
192ASSUME DS:RESGROUP
193 PUSH DS
194 MOV AX,WORD PTR DS:[PDB_JFN_Table] ; Get new 0 and 1
195 MOV [IO_SAVE],AX
196 MOV AX,OFFSET RESGROUP:LODCOM1
197 PUSH AX
198
199ZMMMM PROC FAR
200 RET ; Force header to be checked
201ZMMMM ENDP
202
203 break Chcp
204
205;****************************************************************
206;*
207;* ROUTINE: CHCP - Change code page internal command
208;* (added DOS 3.30 07/21/86)
209;*
210;* SYNTAX: CHCP [xxx]
211;* where xxx is a valid code page
212;*
213;* FUNCTION: If xxx is specified, CHCP will use INT 21H function
214;* 6402H to set the code page to xxxx. If no parameters
215;* are specified, CHCP will use INT 21H function 6401H
216;* to get global code page and display it to the user.
217;*
218;* INPUT: command line at offset 81H
219;*
220;* OUTPUT: none
221;*
222;****************************************************************
223
224NLSFUNC_installed equ 0ffh
225set_global_cp equ 2
226get_global_cp equ 1
227
228assume ds:trangroup,es:trangroup
229
230CHCP:
231 push ds ;AN000; Get local ES
232 pop es ;AN000;
233 mov si,81H ;AC000; Get command argument for CHCP
234
235 mov di,offset trangroup:parse_chcp ;AN000; Get adderss of PARSE_CHCP
236 xor cx,cx ;AC000; clear cx,dx
237 xor dx,dx ;AC000;
238 call parse_with_msg ;AC018; call parser
239 cmp ax,end_of_line ;AN000; are we at end of line?
240
241 jnz setcp ;AC000; no go get number & set code page
242 jmp getcp ;AC000; yes - no parm - get code page
243
244setcp:
245 cmp ax,result_no_error ;AN000; did we have an error?
246 jne cp_error ;AC018; yes - go issue message
247
248 push cx ;AN000; save positional count
249 mov bx,offset trangroup:parse1_addr ;AN000; get number returned
250 mov cx,word ptr [bx] ;AN000; into cx
251 mov system_cpage,cx ;AN000; save user input number
252 pop cx ;AC000; restore positional count
253 mov di,offset trangroup:parse_chcp ;AN000; Get adderss of PARSE_CHCP
254 call parse_check_eol ;AN000; are we at end of line?
255 jnz cp_error ;AC000; no - exit
256
257okset:
258 mov ah,NLSFUNC ;AN000; see if NLSFUNC installed
259 mov al,0 ;AN000;
260 int 2fh ;AN000;
261 cmp al,NLSFUNC_installed ;AN000;
262 jz got_NLS ;AN000; Yes - continue
263 mov dx,offset trangroup:NLSFUNC_ptr ;AN000; no - set up error message
264 jmp short cp_error ;AN000; error exit
265
266got_NLS:
267 mov bx,system_cpage ;AN000; get user input code page
268 mov ah,getsetcdpg ;get/set global code page function
269 mov al,set_global_cp ;minor - set
270 int int_command
271 jnc chcp_return ;no error - exit
272;
273;added for p716
274;
275 cmp ax,error_file_not_found ;p716 was the error file not found?
276 jnz chcp_other_error ;no - country.sys was found
277
278 mov ah,GetExtendedError ;p850 see if error is invalid data
279 xor bx,bx ; which is file was found but CP
280 int int_command ; information was not found.
281 cmp ax,error_invalid_data ;AC000; invalid code page
282 jnz no_countrysys ;no - use file not found
283 mov dx,offset trangroup:inv_code_page ;AN000; get message
284 jmp short cp_error ;AC000; error exit
285
286no_countrysys:
287 mov msg_disp_class,ext_msg_class ;AN000; set up extended error msg class
288 mov dx,offset TranGroup:Extend_Buf_ptr ;AC000; get extended message pointer
289 mov Extend_Buf_ptr,error_file_not_found ;AN000; get message number in control block
290 jmp short cp_error ;AC000; error exit
291
292chcp_other_error:
293;
294; end of p716
295;
296 mov ah,GetExtendedError ;error - see what it is
297 xor bx,bx
298 int int_command
299 cmp ax,65 ;was it access denied?
300 jnz none_set ;no - assume all failed
301 mov dx,offset trangroup:cp_not_all_ptr ;set up message
302 jmp short cp_error ;AC000; error exit
303
304none_set:
305 mov dx,offset trangroup:cp_not_set_ptr ;set up message
306cp_error: ;AN000;
307 jmp cerror ;exit
308
309getcp:
310 mov ah,getsetcdpg ;get/set global code page function
311 mov al,get_global_cp ;minor - get
312 int int_command
313 mov system_cpage,bx ;get active cp for output
314 mov dx,offset trangroup:cp_active_ptr
315 invoke std_printf ;print it out
316
317chcp_return:
318
319 RET
320
321 break TRUENAME ;AN000;
322
323
324; ****************************************************************
325; *
326; * ROUTINE: TRUENAME
327; *
328; * FUNCTION: Entry point for the internal TRUENAME command.
329; * Parses the command line. If a path is found, set
330; * SRCXNAME to path. If only a drive letter is
331; * found, set SRCXNAME to the drive letter. If
332; * no path is found, set the path of SRCXNAME to
333; * dot (.) for current directory. Use the NAME
334; * TRANSLATE system call to get the real name and
335; * then display the real name. If an error occurs
336; * issue an error message and transfer control to
337; * CERROR.
338; *
339; * INPUT: command line at offset 81H
340; *
341; * OUTPUT: none
342; *
343; ****************************************************************
344
345assume ds:trangroup,es:trangroup ;AN000;
346
347TRUENAME: ;AN000; TRUENAME entry point
348 push ds ;AN000; Get local ES
349 pop es ;AN000;
350 mov si,81H ;AN000; Get command line
351 mov di,offset trangroup:parse_chdir ;AN000; Get adderss of PARSE_CHDIR
352 xor cx,cx ;AN000; clear cx,dx
353 xor dx,dx ;AN000;
354 call parse_with_msg ;AC018; call parser
355
356 mov di,offset trangroup:srcxname ;AN000; get address of srcxname
357 cmp ax,end_of_line ;AN000; are we at end of line?
358 je tn_eol ;AN000; yes - go process
359 cmp ax,result_no_error ;AN000; did we have an error?
360 jne tn_parse_error ;AN000; yes - go issue message
361 cmp parse1_type,result_drive ;AN000; was a drive entered?
362 je tn_drive ;AN000; yes - go process
363 jmp short tn_filespec ;AN000; nothing else - must be filespec
364
365tn_eol: ;AN000; no parameters on line
366 mov ah,end_of_line_out ;AN000; set buffer to .
367 mov al,dot_chr ;AN000; for current dir
368 stosw ;AN000; store in srcxname
369 jmp short tn_doit ;AN000; go do command
370
371tn_drive: ;AN000; a drive was entered
372 push si ;AN000; save position in line
373 mov si,offset trangroup:parse1_addr ;AN000; get address of drive
374 lodsb ;AN000; get the drive number
375 add al,"A"-1 ;AN000; convert it to char
376 stosb ;AN000; store it in srcxname
377 mov ax,dot_colon ;AN000; get colon and . and
378 stosw ;AN000; store in srcxname
379 mov al,end_of_line_out ;AN000; put a terminator char
380 stosb ;AN000;
381 pop si ;AN000; get line position back
382 jmp short tn_check_eol ;AN000; check to make sure eol
383
384tn_filespec: ;AN000; a filespec was entered
385 push si ;AN000; save position in line
386 lds si,parse1_addr ;AN000; get address of filespec
387
388tn_move_filename: ;AN000; put filespec in srcxname
389 lodsb ;AN000; get a char from buffer
390 stosb ;AN000; store in srcxname
391 cmp al,end_of_line_out ;AN000; it char a terminator?
392 jnz tn_move_filename ;AN000; no - keep moving
393 pop si ;AN000; get line position back
394
395tn_check_eol: ;AN000; make sure no extra parms
396 mov di,offset trangroup:parse_chdir ;AN000; get address of parse_chdir
397 call parse_check_eol ;AN000; are we at end of line?
398 je tn_doit ;AN000; Yes - do the command
399
400tn_parse_error: ;AN000; A parse error occurred
401 jmp cerror ;AN000; Go to error routine
402
403tn_doit: ;AN000;
404 mov si,offset trangroup:srcxname ;AN000; set up srcxname as source
405 mov di,offset trangroup:combuf ;AN000; set up combuf as target (need big target)
406 mov ah,xnametrans ;AN000; do name translate call
407 int int_command ;AN000;
408 jnc tn_print_xname ;AN000; If no error - print result
409
410 invoke Set_ext_error_msg ;AN000; get extended message
411 mov string_ptr_2,offset trangroup:srcxname ;AN000; get address of failed string
412 mov Extend_buf_sub,one_subst ;AN000; put number of subst in control block
413 jmp cerror ;AN000; Go to error routine
414
415tn_print_xname: ;AN000;
416 mov string_ptr_2,offset Trangroup:combuf ;AN000; Set up address of combuf
417 mov dx,offset trangroup:string_buf_ptr ;AN000; Set up address of print control block
418 invoke crlf2 ;AN000; print a crlf
419 invoke printf_crlf ;AN000; print it out
420
421 ret ;AN000;
422
423 break $Exit
424
425assume ds:trangroup,es:trangroup
426
427$EXIT:
428 push ds ;AN000; save data segment
429 mov ds,[resseg] ;AN000; get resident data segment
430
431assume ds:resgroup ;AN000;
432
433 cmp [permcom],0 ;AN045; is this a permanent COMMAND?
434 jnz no_reset ;AN045; Yes - don't do anything
435;AD060; mov ah,multdos ;AN000; reset parse message pointers
436;AD060; mov al,message_2f ;AN000; call for message retriever
437;AD060; mov dl,set_parse_msg ;AN000; set up parse message address
438;AD060; mov di,pars_msg_off ;AN000; old offset of parse messages
439;AD060; mov es,pars_msg_seg ;AN000; old segment of parse messages
440;AD060; int 2fh ;AN000; go set it
441
442;AD060; mov ah,multdos ;AN000; set up to call DOS through int 2fh
443;AD060; mov al,message_2f ;AN000; call for message retriever
444 mov ax,(multdos shl 8 or message_2f);AN060; reset parse message pointers
445 mov dl,set_critical_msg ;AN000; set up critical error message address
446 mov di,crit_msg_off ;AN000; old offset of critical messages
447 mov es,crit_msg_seg ;AN000; old segment of critical messages
448 int 2fh ;AN000; go set it
449no_reset: ;AN045;
450 pop ds ;AN000; restore local data segment
451
452assume ds:trangroup ;AN000;
453
454 MOV ES,[RESSEG]
455
456assume es:resgroup
457
458 MOV AX,[PARENT]
459 MOV WORD PTR ES:[PDB_Parent_PID],AX
460 MOV AX,WORD PTR OldTerm
461 MOV WORD PTR ES:[PDB_Exit],AX
462 MOV AX,WORD PTR OldTerm+2
463 MOV WORD PTR ES:[PDB_Exit+2],AX
464
465 PUSH ES
466 MOV ES,[TRAN_TPA]
467 MOV AH,DEALLOC
468 INT int_command ; Now running in "free" space
469 POP ES
470
471 MOV AH,Exit
472 MOV AL,BYTE PTR RetCode
473 INT int_command
474
475
476; ****************************************************************
477; *
478; * ROUTINE: PARSE_CHECK_EOL
479; *
480; * FUNCTION: Calls parser to see if end of line occurred.
481; * If not end of line, set up to print parse
482; * error message. ASSUMES NO MORE PARAMETERS ARE
483; * EXPECTED!
484; *
485; * INPUT: DS:SI last output from parser
486; * ES:DI points to parse block
487; * CX last output from parser
488; *
489; * OUTPUT: AX parser return code
490; *
491; * if end of line found
492; * zero flag set
493; * else
494; * MSG_DISPLAY_CLASS set to parse error
495; *
496; ****************************************************************
497
498ASSUME CS:TRANGROUP,DS:TRANGROUP,ES:NOTHING ;AN000;
499
500parse_check_eol Proc near ;AN000;
501
502 xor dx,dx ;AN000;
503 mov [parse_last],si ;AN018; save start of parameter
504 invoke cmd_parse ;AN000; call parser
505 cmp al,end_of_line ;AN000; Are we at end of line?
506 jz parse_good_eol ;AN000; yes - no problem
507
508 cmp ax,result_no_error ;AN018; was any error found?
509 jnz ok_to_setup_pmsg ;AN018; yes - continue
510 inc ax ;AN018; set AX to 1 and turn off zero flag
511
512ok_to_setup_pmsg:
513 call setup_parse_error_msg ;AN018; go set up error message
514
515parse_good_eol:
516 ret ;AN000;
517
518parse_check_eol endp ;AN000;
519
520; ****************************************************************
521; *
522; * ROUTINE: PARSE_WITH_MSG
523; *
524; * FUNCTION: Calls parser. If an error occurred, the error
525; * message is set up.
526; *
527; * INPUT: DS:SI last output from parser
528; * ES:DI points to parse block
529; * CX last output from parser
530; *
531; * OUTPUT: AX parser return code
532; *
533; * if no error
534; * outputs from parser
535; * else
536; * MSG_DISPLAY_CLASS set to parse error
537; * error message set up for STD_PRINTF
538; *
539; ****************************************************************
540
541ASSUME CS:TRANGROUP,DS:TRANGROUP,ES:NOTHING ;AN018;
542
543parse_with_msg Proc near ;AN018;
544
545 mov [parse_last],si ;AN018; save start of parameter
546 invoke cmd_parse ;AN018; call parser
547 cmp al,end_of_line ;AN018; Are we at end of line?
548 jz parse_msg_good ;AN018; yes - no problem
549 cmp ax,result_no_error ;AN018; did an error occur
550 jz parse_msg_good ;AN018; yes - no problem
551
552 call setup_parse_error_msg ;AN018; go set up error message
553
554parse_msg_good:
555 ret ;AN018;
556
557parse_with_msg endp ;AN018;
558
559; ****************************************************************
560; *
561; * ROUTINE: SETUP_PARSE_ERROR_MSG
562; *
563; * FUNCTION: Calls parser. If an error occurred, the error
564; * message is set up.
565; *
566; * INPUT: AX Parse error number
567; * SI Set to past last parameter
568; * Parse_last Set to start of last parameter
569; *
570; * OUTPUT: MSG_DISPLAY_CLASS set to parse error
571; * error message set up for STD_PRINTF
572; *
573; ****************************************************************
574
575ASSUME CS:TRANGROUP,DS:TRANGROUP,ES:NOTHING ;AN018;
576
577SETUP_PARSE_ERROR_MSG Proc near ;AN018;
578
579 mov msg_disp_class,parse_msg_class ;AC018; Set up parse message class
580 mov dx,offset TranGroup:Extend_Buf_ptr ;AC018; get extended message pointer
581 mov byte ptr [si],end_of_line_out ;AC018; terminate the parameter string
582 mov Extend_Buf_ptr,ax ;AC018; get message number in control block
583 cmp ax,lessargs_ptr ;AC018; if required parameter missing
584 jz Setup_parse_msg_ret ;AN018; no subst
585 mov si,[parse_last] ;AC018; get start of parameter
586 mov string_ptr_2,si ;AC018; get address of failed string
587 mov Extend_buf_sub,one_subst ;AC018; put number of subst in control block
588
589setup_parse_msg_ret:
590 inc si ;AN018; make sure zero flag not set
591
592 ret ;AC018;
593
594SETUP_PARSE_ERROR_MSG Endp ;AN018;
595
596trancode ends
597 end
diff --git a/v4.0/src/CMD/COMMAND/TCODE.ASM b/v4.0/src/CMD/COMMAND/TCODE.ASM
new file mode 100644
index 0000000..17ad82d
--- /dev/null
+++ b/v4.0/src/CMD/COMMAND/TCODE.ASM
@@ -0,0 +1,540 @@
1 page 80,132
2; SCCSID = @(#)tcode.asm 1.1 85/05/14
3; SCCSID = @(#)tcode.asm 1.1 85/05/14
4TITLE Part1 COMMAND Transient Routines
5
6 INCLUDE comsw.asm
7.xlist
8.xcref
9 INCLUDE DOSSYM.INC
10 INCLUDE comseg.asm
11 INCLUDE comequ.asm
12.list
13.cref
14
15
16CODERES SEGMENT PUBLIC BYTE ;AC000;
17 EXTRN EXEC_WAIT:NEAR
18CODERES ENDS
19
20DATARES SEGMENT PUBLIC BYTE ;AC000;
21 EXTRN BATCH:WORD
22 EXTRN CALL_BATCH_FLAG:byte
23 EXTRN CALL_FLAG:BYTE
24 EXTRN ECHOFLAG:BYTE
25 EXTRN envirseg:word
26 EXTRN EXTCOM:BYTE
27 EXTRN FORFLAG:BYTE
28 EXTRN IFFLAG:BYTE
29 EXTRN next_batch:word
30 EXTRN nullflag:byte
31 EXTRN PIPEFILES:BYTE
32 EXTRN PIPEFLAG:BYTE
33 EXTRN RE_OUT_APP:BYTE
34 EXTRN RE_OUTSTR:BYTE
35 EXTRN RESTDIR:BYTE
36 EXTRN SINGLECOM:WORD
37 EXTRN VERVAL:WORD
38DATARES ENDS
39
40TRANDATA SEGMENT PUBLIC BYTE ;AC000;
41 EXTRN BadNam_Ptr:word ;AC000;
42TRANDATA ENDS
43
44TRANSPACE SEGMENT PUBLIC BYTE ;AC000;
45 EXTRN APPEND_EXEC:BYTE ;AN041;
46 EXTRN ARG1S:WORD
47 EXTRN ARG2S:WORD
48 EXTRN ARGTS:WORD
49 EXTRN BYTCNT:WORD
50 EXTRN COMBUF:BYTE
51 EXTRN COMSW:WORD
52 EXTRN CURDRV:BYTE
53 EXTRN HEADCALL:DWORD
54 EXTRN IDLEN:BYTE
55 EXTRN INTERNATVARS:BYTE
56 EXTRN PARM1:BYTE
57 EXTRN PARM2:BYTE
58 EXTRN RE_INSTR:BYTE
59 EXTRN RESSEG:WORD
60 EXTRN SPECDRV:BYTE
61 EXTRN STACK:WORD
62 EXTRN SWITCHAR:BYTE
63 EXTRN TPA:WORD
64 EXTRN UCOMBUF:BYTE
65 EXTRN USERDIR1:BYTE
66 IF IBM
67 EXTRN ROM_CALL:BYTE
68 EXTRN ROM_CS:WORD
69 EXTRN ROM_IP:WORD
70 ENDIF
71
72TRANSPACE ENDS
73
74; ********************************************************************
75; START OF TRANSIENT PORTION
76; This code is loaded at the end of memory and may be overwritten by
77; memory-intensive user programs.
78
79TRANCODE SEGMENT PUBLIC BYTE ;AC000;
80
81ASSUME CS:TRANGROUP,DS:NOTHING,ES:NOTHING,SS:NOTHING
82
83 EXTRN $EXIT:NEAR
84 EXTRN DRVBAD:NEAR
85 EXTRN EXTERNAL:NEAR
86 EXTRN FNDCOM:NEAR
87 EXTRN FORPROC:NEAR
88 EXTRN PIPEPROC:NEAR
89 EXTRN PIPEPROCSTRT:NEAR
90
91 PUBLIC COMMAND
92 PUBLIC DOCOM
93 PUBLIC DOCOM1
94 PUBLIC NOPIPEPROC
95 PUBLIC TCOMMAND
96
97 IF IBM
98 PUBLIC ROM_EXEC
99 PUBLIC ROM_SCAN
100 ENDIF
101
102 ORG 0
103ZERO = $
104
105 ORG 100H ; Allow for 100H parameter area
106
107SETDRV:
108 MOV AH,SET_DEFAULT_DRIVE
109 INT int_command
110;
111; TCOMMAND is the recycle point in COMMAND. Nothing is known here.
112; No registers (CS:IP) no flags, nothing.
113;
114
115TCOMMAND:
116 MOV DS,[RESSEG]
117ASSUME DS:RESGROUP
118 MOV AX,-1
119 XCHG AX,[VERVAL]
120 CMP AX,-1
121 JZ NOSETVER2
122 MOV AH,SET_VERIFY_ON_WRITE ; AL has correct value
123 INT int_command
124
125NOSETVER2:
126 CALL [HEADCALL] ; Make sure header fixed
127 XOR BP,BP ; Flag transient not read
128 CMP [SINGLECOM],-1
129 JNZ COMMAND
130
131$EXITPREP:
132 PUSH CS
133 POP DS
134 JMP $EXIT ; Have finished the single command
135ASSUME DS:NOTHING
136;
137; Main entry point from resident portion.
138;
139; If BP <> 0, then we have just loaded transient portion otherwise we are
140; just beginning the processing of another command.
141;
142
143COMMAND:
144
145;
146; We are not always sure of the state of the world at this time. We presume
147; worst case and initialize the relevant registers: segments and stack.
148;
149 ASSUME CS:TRANGROUP,DS:NOTHING,ES:NOTHING,SS:NOTHING
150 CLD
151 MOV AX,CS
152 CLI
153 MOV SS,AX
154ASSUME SS:TRANGROUP
155 MOV SP,OFFSET TRANGROUP:STACK
156 STI
157 MOV ES,AX
158 MOV DS,AX ;AN000; set DS to transient
159ASSUME ES:TRANGROUP,DS:TRANGROUP ;AC000;
160 invoke TSYSLOADMSG ;AN000; preload messages
161 invoke SETSTDINOFF ;AN026; turn off critical error on STDIN
162 invoke SETSTDOUTOFF ;AN026; turn off critical error on STDOUT
163 mov append_exec,0 ;AN041; set internal append state off
164
165 MOV DS,[RESSEG]
166ASSUME DS:RESGROUP
167
168 MOV [UCOMBUF],COMBUFLEN ; Init UCOMBUF
169 MOV [COMBUF],COMBUFLEN ; Init COMBUF (Autoexec doing DATE)
170;
171; If we have just loaded the transient, then we do NOT need to initialize the
172; command buffer. ???? DO WE NEED TO RESTORE THE USERS DIRECTORY ???? I
173; guess not: the only circumstances in which we reload the command processor
174; is after a transient program execution. In this case, we let the current
175; directory lie where it may.
176;
177 OR BP,BP ; See if just read
178 JZ TESTRDIR ; Not read, check user directory
179 MOV WORD PTR [UCOMBUF+1],0D01H ; Reset buffer
180 JMP SHORT NOSETBUF
181
182TESTRDIR:
183 CMP [RESTDIR],0
184 JZ NOSETBUF ; User directory OK
185 PUSH DS
186;
187; We have an unusual situation to handle. The user *may* have changed his
188; directory as a result of an internal command that got aborted. Restoring it
189; twice may not help us: the problem may never go away. We just attempt it
190; once and give up.
191;
192 MOV [RESTDIR],0 ; Flag users dirs OK
193 PUSH CS
194 POP DS
195ASSUME DS:TRANGROUP
196 MOV DX,OFFSET TRANGROUP:USERDIR1
197 MOV AH,CHDIR
198 INT int_command ; Restore users directory
199 POP DS
200ASSUME DS:RESGROUP
201
202NOSETBUF:
203 CMP [PIPEFILES],0
204 JZ NOPCLOSE ; Don't bother if they don't exist
205 CMP [PIPEFLAG],0
206 JNZ NOPCLOSE ; Don't del if still piping
207 INVOKE PIPEDEL
208
209NOPCLOSE:
210 MOV [EXTCOM],0 ; Flag internal command
211 MOV AX,CS ; Get segment we're in
212 MOV DS,AX
213ASSUME DS:TRANGROUP
214
215 PUSH AX
216 MOV DX,OFFSET TRANGROUP:INTERNATVARS
217 MOV AX,INTERNATIONAL SHL 8
218 INT 21H
219 POP AX
220 SUB AX,[TPA] ; AX=size of TPA in paragraphs
221 PUSH BX
222 MOV BX,16
223 MUL BX ; DX:AX=size of TPA in bytes
224 POP BX
225 OR DX,DX ; See if over 64K
226 JZ SAVSIZ ; OK if not
227 MOV AX,-1 ; If so, limit to 65535 bytes
228
229SAVSIZ:
230;
231; AX is the number of bytes free in the buffer between the resident and the
232; transient with a maximum of 64K-1. We round this down to a multiple of 512.
233;
234 CMP AX,512
235 JBE GotSize
236 AND AX,0FE00h ; NOT 511 = NOT 1FF
237
238GotSize:
239 MOV [BYTCNT],AX ; Max no. of bytes that can be buffered
240 MOV DS,[RESSEG] ; All batch work must use resident seg.
241ASSUME DS:RESGROUP
242
243 TEST [ECHOFLAG],1
244 JZ GETCOM ; Don't do the CRLF
245 INVOKE SINGLETEST
246 JB GETCOM
247 TEST [PIPEFLAG],-1
248 JNZ GETCOM
249 TEST [FORFLAG],-1 ; G Don't print prompt in FOR
250 JNZ GETCOM ; G
251 TEST [BATCH], -1 ; G Don't print prompt if in batch
252 JNZ GETCOM ; G
253 INVOKE CRLF2
254
255GETCOM:
256 MOV CALL_FLAG,0 ; G Reset call flags
257 MOV CALL_BATCH_FLAG,0 ; G
258 MOV AH,GET_DEFAULT_DRIVE
259 INT int_command
260 MOV [CURDRV],AL
261 TEST [PIPEFLAG],-1 ; Pipe has highest presedence
262 JZ NOPIPE
263 JMP PIPEPROC ; Continue the pipeline
264
265NOPIPE:
266 TEST [ECHOFLAG],1
267 JZ NOPDRV ; No prompt if echo off
268 INVOKE SINGLETEST
269 JB NOPDRV
270 TEST [FORFLAG],-1 ; G Don't print prompt in FOR
271 JNZ NOPDRV ; G
272 TEST [BATCH], -1 ; G Don't print prompt if in batch
273 JNZ TESTFORBAT ; G
274 INVOKE PRINT_PROMPT ; Prompt the user
275
276NOPDRV:
277 TEST [FORFLAG],-1 ; FOR has next highest precedence
278 JZ TESTFORbat
279 JMP FORPROC ; Continue the FOR
280
281TESTFORBAT:
282 MOV [RE_INSTR],0 ; Turn redirection back off
283 MOV [RE_OUTSTR],0
284 MOV [RE_OUT_APP],0
285 MOV IFFlag,0 ; no more ifs...
286 TEST [BATCH],-1 ; Batch has lowest precedence
287 JZ ISNOBAT
288
289 push es ;AN000; save ES
290 push ds ;AN000; save DS
291 mov ax,mult_shell_get ;AN000; check to see if SHELL has command
292 mov es,[batch] ;AN000; get batch segment
293 mov di,batfile ;AN000; get batch file name
294 push cs ;AN000; get local segment to DS
295 pop ds ;AN000;
296 mov dx,offset trangroup:combuf ;AN000; pass communications buffer
297 int 2fh ;AN000; call the shell
298 cmp al,shell_action ;AN000; does shell have a commmand?
299 pop ds ;AN000; restore DS
300 pop es ;AN000; restore ES
301 jz jdocom1 ;AN000; yes - go process command
302
303 PUSH DS ;G
304 INVOKE READBAT ; Continue BATCH
305 POP DS ;G
306 mov nullflag,0 ;G reset no command flag
307 TEST [BATCH],-1 ;G
308 JNZ JDOCOM1 ;G if batch still in progress continue
309 MOV BX,NEXT_BATCH ;G
310 CMP BX,0 ;G see if there is a new batch file
311 JZ JDOCOM1 ;G no - go do command
312 MOV BATCH,BX ;G get segment of next batch file
313 MOV NEXT_BATCH,0 ;G reset next batch
314JDOCOM1:
315 PUSH CS ;G
316 POP DS ;G
317 JMP SHORT DoCom1 ; echoing already done
318
319ISNOBAT:
320 CMP [SINGLECOM],0
321 JZ REGCOM
322 MOV SI,-1
323 XCHG SI,[SINGLECOM]
324 MOV DI,OFFSET TRANGROUP:COMBUF + 2
325 XOR CX,CX
326
327SINGLELOOP:
328 LODSB
329 STOSB
330 INC CX
331 CMP AL,0DH
332 JNZ SINGLELOOP
333 DEC CX
334 PUSH CS
335 POP DS
336ASSUME DS:TRANGROUP
337 MOV [COMBUF + 1],CL
338;
339; do NOT issue a trailing CRLF...
340;
341 JMP DOCOM1
342
343;
344; We have a normal command.
345; Printers are a bizarre quantity. Sometimes they are a stream and
346; sometimes they aren't. At this point, we automatically close all spool
347; files and turn on truncation mode.
348;
349
350REGCOM:
351 MOV AX,(ServerCall SHL 8) + 9
352 INT 21h
353 MOV AX,(ServerCall SHL 8) + 8
354 MOV DL,1
355 INT 21h
356
357 PUSH CS
358 POP DS ; Need local segment to point to buffer
359 MOV DX,OFFSET TRANGROUP:UCOMBUF
360 MOV AH,STD_CON_STRING_INPUT
361 INT int_command ; Get a command
362 MOV CL,[UCOMBUF]
363 XOR CH,CH
364 ADD CX,3
365 MOV SI,OFFSET TRANGROUP:UCOMBUF
366 MOV DI,OFFSET TRANGROUP:COMBUF
367 REP MOVSB ; Transfer it to the cooked buffer
368
369;---------------
370
371transpace segment
372 extrn arg:byte ; the arg structure!
373transpace ends
374;---------------
375
376
377DOCOM:
378 INVOKE CRLF2
379
380DOCOM1:
381 INVOKE PRESCAN ; Cook the input buffer
382 JZ NOPIPEPROC
383 JMP PIPEPROCSTRT ; Fire up the pipe
384
385nullcomj:
386 jmp nullcom
387
388NOPIPEPROC:
389 invoke parseline
390 jnc OkParse ; user error? or maybe we goofed?
391
392BadParse:
393 PUSH CS
394 POP DS
395 MOV DX,OFFSET TRANGROUP:BADNAM_ptr
396 INVOKE std_eprintf
397 JMP TCOMMAND
398
399OkParse:
400 test arg.argv[0].argflags, MASK wildcard
401 jnz BadParse ; ambiguous commands not allowed
402 cmp arg.argvcnt, 0 ; there WAS a command, wasn't there?
403 jz nullcomj
404 cmp arg.argv[0].arglen, 0 ; probably an unnecessary check...
405 jz nullcomj ; guarantees argv[0] at least x<NULL>
406
407 MOV SI,OFFSET TRANGROUP:COMBUF+2
408 MOV DI,OFFSET TRANGROUP:IDLEN
409 MOV AX,(PARSE_FILE_DESCRIPTOR SHL 8) OR 01H ; Make FCB with blank scan-off
410 INT int_command
411 mov BX, arg.argv[0].argpointer
412 cmp BYTE PTR [BX+1],':' ; was a drive specified?
413 jne short drvgd ; no, use default of zero...
414
415 mov DL, BYTE PTR [BX] ; pick-up drive letter
416 and DL, NOT 20H ; uppercase the sucker
417 sub DL, capital_A ; convert it to a drive number, A=0
418
419 CMP AL,-1 ; See what PARSE said about our drive letter.
420 JZ drvbadj2 ; It was invalid.
421
422 mov DI, arg.argv[0].argstartel
423 cmp BYTE PTR [DI], 0 ; is there actually a command there?
424 jnz drvgd ; if not, we have: "d:", "d:\", "d:/"
425 jmp setdrv ; and set drive to new drive spec
426
427drvbadj2:
428 jmp drvbad
429
430DRVGD:
431 MOV AL,[DI]
432 MOV [SPECDRV],AL
433 MOV AL,' '
434 MOV CX,9
435 INC DI
436 REPNE SCASB ; Count no. of letters in command name
437 MOV AL,8
438 SUB AL,CL
439 MOV [IDLEN],AL ; IDLEN is truly the length
440 MOV DI,81H
441 PUSH SI
442
443 mov si, OFFSET TRANGROUP:COMBUF+2 ; Skip over all leading delims
444 invoke scanoff
445
446do_skipcom:
447 lodsb ; move command line pointer over
448 invoke delim ; pathname -- have to do it ourselves
449 jz do_skipped ; 'cause parse_file_descriptor is dumb
450 cmp AL, 0DH ; can't always depend on argv[0].arglen
451 jz do_skipped ; to be the same length as the user-
452 cmp AL, [SWITCHAR] ; specified command string
453 jnz do_skipcom
454
455do_skipped:
456 dec SI
457 XOR CX,CX
458
459COMTAIL:
460 LODSB
461 STOSB ; Move command tail to 80H
462 CMP AL,13
463 LOOPNZ COMTAIL
464 DEC DI
465 MOV BP,DI
466 NOT CL
467 MOV BYTE PTR DS:[80H],CL
468 POP SI
469
470;-----
471; Some of these comments are sadly at odds with this brave new code.
472;-----
473; If the command has 0 parameters must check here for
474; any switches that might be present.
475; SI -> first character after the command.
476
477 mov DI, arg.argv[0].argsw_word
478 mov [COMSW], DI ; ah yes, the old addressing mode problem...
479 mov SI, arg.argv[1 * SIZE argv_ele].argpointer ; s = argv[1];
480 OR SI,SI ; if (s == NULL)
481 JNZ DoParse
482 MOV SI,BP ; s = bp; (buffer end)
483
484DoParse:
485 MOV DI,FCB
486 MOV AX,(PARSE_FILE_DESCRIPTOR SHL 8) OR 01H
487 INT int_command
488 MOV [PARM1],AL ; Save result of parse
489
490 mov DI, arg.argv[1*SIZE argv_ele].argsw_word
491 mov [ARG1S], DI
492 mov SI, arg.argv[2*SIZE argv_ele].argpointer ; s = argv[2];
493 OR SI,SI ; if (s == NULL)
494 JNZ DoParse2
495 MOV SI,BP ; s = bp; (bufend)1
496
497DoParse2:
498 MOV DI,FCB+10H
499 MOV AX,(PARSE_FILE_DESCRIPTOR SHL 8) OR 01H
500 INT int_command ; Parse file name
501 MOV [PARM2],AL ; Save result
502
503 mov DI, arg.argv[2*SIZE argv_ele].argsw_word
504 mov [ARG2S], DI
505 mov DI, arg.argv[0].argsw_word
506 not DI ; ARGTS doesn't include the flags
507 and DI, arg.argswinfo ; from COMSW...
508 mov [ARGTS], DI
509
510 MOV AL,[IDLEN]
511 MOV DL,[SPECDRV]
512 or DL, DL ; if a drive was specified...
513 jnz externalj1 ; it MUST be external, by this time
514 dec al ; (I don't know why -- old code did it)
515 jmp fndcom ; otherwise, check internal com table
516
517externalj1:
518 jmp external
519
520nullcom:
521 MOV DS,[RESSEG]
522ASSUME DS:RESGROUP
523 TEST [BATCH], -1 ;G Are we in a batch file?
524 JZ nosetflag ;G only set flag if in batch
525 mov nullflag,nullcommand ;G set flag to indicate no command
526
527nosetflag:
528 CMP [SINGLECOM],-1
529 JZ EXITJ
530 JMP GETCOM
531
532EXITJ:
533 JMP $EXITPREP
534
535IF IBM
536 include mshalo.asm
537ENDIF
538
539TRANCODE ENDS
540 END
diff --git a/v4.0/src/CMD/COMMAND/TDATA.ASM b/v4.0/src/CMD/COMMAND/TDATA.ASM
new file mode 100644
index 0000000..c80c588
--- /dev/null
+++ b/v4.0/src/CMD/COMMAND/TDATA.ASM
@@ -0,0 +1,777 @@
1 page 80,132
2; SCCSID = @(#)tdata.asm 4.3 85/05/17
3; SCCSID = @(#)tdata.asm 4.3 85/05/17
4TITLE COMMAND Transient Initialized DATA
5
6; MODIFICATION HISTORY
7;
8; EE 10-20-83 Changed the drive check indicator bytes (DCIB's) in
9; COMTAB to be a flag byte in which bit 0 is now the
10; DCIB(bit) and bit 1 is on if the command can take
11; switches.
12
13fmt macro name,string,args
14 local a
15a db string
16PUBLIC name
17name dw offset trangroup:a
18irp val,<args>
19 dw offset trangroup:val
20endm
21endm
22
23btab macro b,sym
24 db b
25 dw offset trangroup:sym
26 endm
27
28.xlist
29.xcref
30 INCLUDE comsw.asm ;AC000;
31 INCLUDE comseg.asm
32 INCLUDE EA.inc ;AN030;
33 INCLUDE dirent.inc ;AN042;
34.list
35.cref
36
37BREAK MACRO subtitle
38 SUBTTL subtitle
39 PAGE
40ENDM
41
42;
43; WARNING: DO NOT INCLUDE DOSSYM.INC BECAUSE IT DESTROYS THE MACRO 'FMT' THAT
44; has been defined above - RS.
45;
46 INCLUDE CURDIR.INC
47 INCLUDE ERROR.INC
48 INCLUDE ifequ.asm
49 INCLUDE comequ.asm
50
51TRANSPACE SEGMENT PUBLIC BYTE ;AC000;
52 EXTRN arg_buf:BYTE
53 EXTRN bwdbuf:byte
54 EXTRN bytes_free:WORD
55 EXTRN charbuf:byte
56 EXTRN copy_Num:WORD
57 EXTRN cpyflag:BYTE
58 EXTRN DATE_OUTPUT:BYTE ;AC000;
59 EXTRN Dir_Num:WORD
60 EXTRN DRIVE_OUTPUT:BYTE ;AC000;
61 EXTRN file_size_high:WORD
62 EXTRN file_size_low:WORD
63 EXTRN major_ver_num:WORD
64 EXTRN minor_ver_num:WORD
65 EXTRN one_char_val:BYTE
66 EXTRN PARSE1_OUTPUT:BYTE ;AC000;
67 EXTRN srcbuf:byte
68 EXTRN string_ptr_2:WORD
69 EXTRN system_cpage:word
70 EXTRN TIME_OUTPUT:BYTE ;AC000;
71 EXTRN vol_drv:BYTE
72 EXTRN vol_serial:dword ;AN000;
73TRANSPACE ENDS
74
75TRANCODE SEGMENT PUBLIC BYTE ;AC000;
76 EXTRN $CALL:NEAR
77 EXTRN $CHDIR:NEAR
78 EXTRN $EXIT:NEAR
79 EXTRN $FOR:NEAR
80 EXTRN $IF:NEAR
81 EXTRN $MKDIR:NEAR
82 EXTRN $RMDIR:NEAR
83 EXTRN ADD_NAME_TO_ENVIRONMENT:NEAR
84 EXTRN ADD_PROMPT:NEAR
85 EXTRN build_dir_for_prompt:near
86 EXTRN CATALOG:NEAR
87 EXTRN CHCP:NEAR
88 EXTRN CLS:NEAR
89 EXTRN CNTRLC:NEAR
90 EXTRN COPY:NEAR
91 EXTRN CRENAME:NEAR
92 EXTRN CRLF2:NEAR
93 EXTRN CTIME:NEAR
94 EXTRN CTTY:NEAR
95 EXTRN DATE:NEAR
96 EXTRN ECHO:NEAR
97 EXTRN ERASE:NEAR
98 EXTRN GOTO:NEAR
99 EXTRN IFERLEV:NEAR
100 EXTRN IFEXISTS:NEAR
101 EXTRN IFNOT:NEAR
102 EXTRN PATH:NEAR
103 EXTRN PAUSE:NEAR
104 EXTRN PRINT_B:NEAR
105 EXTRN PRINT_BACK:NEAR
106 EXTRN PRINT_DATE:NEAR
107 EXTRN PRINT_CHAR:NEAR
108 EXTRN PRINT_DRIVE:NEAR
109 EXTRN PRINT_EQ:NEAR
110 EXTRN PRINT_ESC:NEAR
111 EXTRN PRINT_G:NEAR
112 EXTRN PRINT_L:NEAR
113 EXTRN PRINT_TIME:NEAR
114 EXTRN PRINT_VERSION:NEAR
115 EXTRN SHIFT:NEAR
116 EXTRN TCOMMAND:NEAR
117 EXTRN TRUENAME:NEAR ;AN000;
118 EXTRN TYPEFIL:NEAR
119 EXTRN VERSION:NEAR
120 EXTRN VOLUME:NEAR
121 EXTRN VERIFY:NEAR
122;
123; WARNING!!! No code may appear after this label!!!!
124;
125PUBLIC TranCodeLast
126TranCodeLast LABEL BYTE
127TRANCODE ENDS
128
129; Data for transient portion
130
131TRANDATA SEGMENT PUBLIC BYTE
132
133 PUBLIC accden_ptr ;AN000;
134 PUBLIC acrlf_ptr ;AN000;
135 PUBLIC arg_buf_ptr ;AN000;
136 PUBLIC badbat_ptr ;AN000;
137 PUBLIC badcd_ptr ;AN000;
138 PUBLIC badCPmes_ptr ;AN000;
139 PUBLIC badcurdrv ;AN000;
140 PUBLIC baddat_ptr ;AN000;
141 PUBLIC baddev_ptr ;AN000;
142 PUBLIC baddrv_ptr ;AN000;
143 PUBLIC badlab_ptr ;AN000;
144 PUBLIC badmkd_ptr ;AN000;
145 PUBLIC badnam_ptr ;AN000;
146 PUBLIC bad_on_off_ptr ;AN000;
147 PUBLIC badPmes_ptr ;AN000;
148 PUBLIC badrmd_ptr ;AN000;
149 PUBLIC badtim_ptr ;AN000;
150 PUBLIC batext
151 PUBLIC bytmes_ptr ;AN000;
152 PUBLIC CLSSTRING
153 PUBLIC comext
154 PUBLIC COMSPECSTR
155 PUBLIC COMTAB
156 PUBLIC copied_ptr ;AN000;
157 PUBLIC cp_active_ptr ;AN000;
158 PUBLIC cp_not_all_ptr ;AN000;
159 PUBLIC cp_not_set_ptr ;AN000;
160 PUBLIC ctrlcmes_ptr ;AN000;
161 PUBLIC curdat_mo_day ;AN000;
162 PUBLIC curdat_ptr ;AN000;
163 PUBLIC curdat_yr ;AN000;
164 PUBLIC curtim_hr_min ;AN000;
165 PUBLIC curtim_ptr ;AN000;
166 PUBLIC curtim_sec_hn ;AN000;
167 PUBLIC dback_ptr ;AN000;
168 PUBLIC del_Y_N_ptr ;AN000;
169 PUBLIC devwmes_ptr ;AN000;
170 PUBLIC dirdattim_ptr ;AN000;
171 PUBLIC dirdat_mo_day ;AN000;
172 PUBLIC dirdat_yr ;AN000;
173 PUBLIC dirhead_ptr ;AN000;
174 PUBLIC dirmes_ptr ;AN000;
175 PUBLIC dirtim_hr_min ;AN000;
176 PUBLIC dirtim_sec_hn ;AN000;
177 PUBLIC DIR_W_SYN ;AN000;
178 PUBLIC disp_file_size_ptr ;AN000;
179 PUBLIC dmes_ptr ;AN000;
180 PUBLIC echomes_ptr ;AN000;
181 PUBLIC enverr_ptr ;AN000;
182 PUBLIC eurdat_ptr ;AN000;
183 PUBLIC exeext
184 PUBLIC extend_buf_off ;AN000;
185 PUBLIC extend_buf_ptr ;AN000;
186 PUBLIC extend_buf_seg ;AN000;
187 PUBLIC extend_buf_sub ;AN000;
188 PUBLIC file_name_ptr ;AN000;
189 PUBLIC fornestmes_ptr ;AN000;
190 PUBLIC fuldir_ptr ;AN000;
191 PUBLIC IFTAB
192 PUBLIC inBdev_ptr ;AN000;
193 PUBLIC inornot_ptr ;AN000;
194 PUBLIC Inv_code_page ;AN000;
195 PUBLIC inval_path_ptr ;AN000;
196 PUBLIC japdat_ptr ;AN000;
197 PUBLIC Losterr_ptr ;AN000;
198 PUBLIC md_exists_ptr ;AN006;
199 PUBLIC msg_cont_flag ;AN000;
200 PUBLIC msg_disp_class ;AN000;
201 PUBLIC needbat_ptr ;AN000;
202 PUBLIC newdat_format ;AN000;
203 PUBLIC newdat_ptr ;AN000;
204 PUBLIC newtim_ptr ;AN000;
205 PUBLIC NLSFUNC_ptr ;AN000;
206 PUBLIC nospace_ptr ;AN000;
207 PUBLIC no_values ;AN000;
208 PUBLIC nulpath_ptr ;AN000;
209 PUBLIC offmes_ptr ;AN000;
210 PUBLIC onmes_ptr ;AN000;
211 PUBLIC overwr_ptr ;AN000;
212 PUBLIC PARSE_BREAK ;AN000;
213 PUBLIC PARSE_CHCP ;AN000;
214 PUBLIC PARSE_CHDIR ;AN000;
215 PUBLIC PARSE_CTTY ;AN000;
216 PUBLIC PARSE_DATE ;AN000;
217 PUBLIC PARSE_DIR ;AN000;
218 PUBLIC PARSE_ERASE ;AN000;
219 PUBLIC PARSE_MRDIR ;AN000;
220 PUBLIC PARSE_RENAME ;AN000;
221 PUBLIC PARSE_TIME ;AN000;
222 PUBLIC PARSE_VOL ;AN000;
223 PUBLIC PATH_TEXT
224 PUBLIC pausemes_ptr ;AN000;
225 PUBLIC pipeEmes_ptr ;AN000;
226 PUBLIC promptdat_moday ;AN000;
227 PUBLIC promptdat_ptr ;AN000;
228 PUBLIC promptdat_yr ;AN000;
229 PUBLIC PROMPT_TABLE
230 PUBLIC PROMPT_TEXT
231 PUBLIC promtim_hr_min ;AN000;
232 PUBLIC promtim_ptr ;AN000;
233 PUBLIC promtim_sec_hn ;AN000;
234 PUBLIC renerr_ptr ;AN000;
235 PUBLIC SLASH_P_SYN ;AN000;
236 PUBLIC string_buf_ptr ;AN000;
237 PUBLIC suremes_ptr ;AN000;
238 PUBLIC switch_list
239 PUBLIC syntmes_ptr ;AN000;
240 PUBLIC tab_ptr ;AN000;
241 PUBLIC TRANDATAEND
242 PUBLIC usadat_ptr ;AN000;
243 PUBLIC verimes_ptr ;AN000;
244 PUBLIC vermes_ptr ;AN000;
245 PUBLIC volmes_ptr ;AN000;
246 PUBLIC volmes_ptr_2 ;AN000;
247 PUBLIC volsermes_ptr ;AN000;
248 PUBLIC WEEKTAB
249 PUBLIC xa_cp ;AN030;
250
251INCLUDE tranmsg.asm
252
253CLSSTRING DB 4,01BH,"[2J" ; ANSI Clear screen
254
255PROMPT_TABLE LABEL BYTE
256 btab "B",Print_B
257 btab "D",PRINT_DATE
258 btab "E",PRINT_ESC
259 btab "G",PRINT_G
260 btab "H",PRINT_BACK
261 btab "L",PRINT_L
262 btab "N",PRINT_DRIVE
263 btab "P",build_dir_for_prompt
264 btab "Q",PRINT_EQ
265 btab "T",PRINT_TIME
266 btab "V",PRINT_VERSION
267 btab "_",CRLF2
268 btab "$",PRINT_CHAR
269 DB 0 ; NUL TERMINATED
270
271IFTAB LABEL BYTE ; Table of IF conditionals
272 DB 3,"NOT" ; First byte is count
273 DW OFFSET TRANGROUP:IFNOT
274 DB 10,"ERRORLEVEL"
275 DW OFFSET TRANGROUP:IFERLEV
276 DB 5,"EXIST"
277 DW OFFSET TRANGROUP:IFEXISTS
278 DB 0
279
280; Table for internal command names
281COMTAB DB 3,"DIR",fSwitchAllowed+fCheckDrive
282 DW OFFSET TRANGROUP:CATALOG ; In TCMD1.ASM
283 DB 4,"CALL",fSwitchAllowed
284 DW OFFSET TRANGROUP:$CALL ; In TBATCH2.ASM
285 DB 4,"CHCP",fSwitchAllowed
286 DW OFFSET TRANGROUP:CHCP ; In TCMD2B.ASM
287 DB 6,"RENAME",fSwitchAllowed+fCheckDrive ;AC018; P3903
288 DW OFFSET TRANGROUP:CRENAME ; In TCMD1.ASM
289 DB 3,"REN",fSwitchAllowed+fCheckDrive ;AC018; P3903
290 DW OFFSET TRANGROUP:CRENAME ; In TCMD1.ASM
291 DB 5,"ERASE",fSwitchAllowed+fCheckDrive
292 DW OFFSET TRANGROUP:ERASE ; In TCMD1.ASM
293 DB 3,"DEL",fSwitchAllowed+fCheckDrive
294 DW OFFSET TRANGROUP:ERASE ; In TCMD1.ASM
295 DB 4,"TYPE",fSwitchAllowed+fCheckDrive ;AC018; P3903
296 DW OFFSET TRANGROUP:TYPEFIL ; In TCMD1.ASM
297 DB 3,"REM",fSwitchAllowed
298 DW OFFSET TRANGROUP:TCOMMAND ; In TCODE.ASM
299 DB 4,"COPY",fSwitchAllowed+fCheckDrive
300 DW OFFSET TRANGROUP:COPY ; In COPY.ASM
301 DB 5,"PAUSE",fSwitchAllowed
302 DW OFFSET TRANGROUP:PAUSE ; In TCMD1.ASM
303 DB 4,"DATE",fSwitchAllowed
304 DW OFFSET TRANGROUP:DATE ; In TPIPE.ASM
305 DB 4,"TIME",fSwitchAllowed ;AC018; P3903
306 DW OFFSET TRANGROUP:CTIME ; In TPIPE.ASM
307 DB 3,"VER",0
308 DW OFFSET TRANGROUP:VERSION ; In TCMD2.ASM
309 DB 3,"VOL",fSwitchAllowed+fCheckDrive ;AC018; P3903
310 DW OFFSET TRANGROUP:VOLUME ; In TCMD1.ASM
311 DB 2,"CD",fSwitchAllowed+fCheckDrive ;AC018; P3903
312 DW OFFSET TRANGROUP:$CHDIR ; In TENV.ASM
313 DB 5,"CHDIR",fSwitchAllowed+fCheckDrive ;AC018; P3903
314 DW OFFSET TRANGROUP:$CHDIR ; In TENV.ASM
315 DB 2,"MD",fSwitchAllowed+fCheckDrive ;AC018; P3903
316 DW OFFSET TRANGROUP:$MKDIR ; In TENV.ASM
317 DB 5,"MKDIR",fSwitchAllowed+fCheckDrive ;AC018; P3903
318 DW OFFSET TRANGROUP:$MKDIR ; In TENV.ASM
319 DB 2,"RD",fSwitchAllowed+fCheckDrive ;AC018; P3903
320 DW OFFSET TRANGROUP:$RMDIR ; In TENV.ASM
321 DB 5,"RMDIR",fSwitchAllowed+fCheckDrive ;AC018; P3903
322 DW OFFSET TRANGROUP:$RMDIR ; In TENV.ASM
323 DB 5,"BREAK",fSwitchAllowed ;AC018; P3903
324 DW OFFSET TRANGROUP:CNTRLC ; In TUCODE.ASM
325 DB 6,"VERIFY",fSwitchAllowed ;AC018; P3903
326 DW OFFSET TRANGROUP:VERIFY ; In TUCODE.ASM
327 DB 3,"SET",fSwitchAllowed
328 DW OFFSET TRANGROUP:ADD_NAME_TO_ENVIRONMENT; In TENV.ASM
329 DB 6,"PROMPT",fSwitchAllowed
330 DW OFFSET TRANGROUP:ADD_PROMPT ; In TENV.ASM
331 DB 4,"PATH",fSwitchAllowed
332 DW OFFSET TRANGROUP:PATH ; In TCMD2.ASM
333 DB 4,"EXIT",0
334 DW OFFSET TRANGROUP:$EXIT ; In TCMD2.ASM
335 DB 4,"CTTY",fCheckDrive+fSwitchAllowed
336 DW OFFSET TRANGROUP:CTTY ; In TCMD2.ASM
337 DB 4,"ECHO",fSwitchAllowed
338 DW OFFSET TRANGROUP:ECHO ; In TUCODE.ASM
339 DB 4,"GOTO",fSwitchAllowed
340 DW OFFSET TRANGROUP:GOTO ; In TBATCH.ASM
341 DB 5,"SHIFT",fSwitchAllowed
342 DW OFFSET TRANGROUP:SHIFT ; In TBATCH.ASM
343 DB 2,"IF",fSwitchAllowed
344 DW OFFSET TRANGROUP:$IF ; In TBATCH.ASM
345 DB 3,"FOR",fSwitchAllowed
346 DW OFFSET TRANGROUP:$FOR ; In TBATCH.ASM
347 DB 3,"CLS",0
348 DW OFFSET TRANGROUP:CLS ; In TCMD2.ASM
349 DB 8,"TRUENAME",fSwitchAllowed+fCheckDrive ;AN000; P3903 changed
350 DW OFFSET TRANGROUP:TRUENAME ;AN000;
351 DB 0 ; Terminate command table
352
353
354comext dB ".COM"
355exeext dB ".EXE"
356batext dB ".BAT"
357
358switch_list DB "VBAPW" ; flags we can recognize
359
360
361XA_cp Label byte ;AN030; list for one extended attribute
362 DW 1 ;AN030;
363 DB EAISBINARY ;AN030; type
364 DW EASYSTEM ;AN030; flags
365 DB 2 ;AN030; name length
366 DB "CP" ;AN030; name
367
368
369
370
371PUBLIC BatBufLen
372BatBufLen DW BatLen
373
374; *****************************************************
375; EMG 4.00
376; DATA STARTING HERE WAS ADDED BY EMG FOR 4.00
377; FOR IMPLEMENTATION OF COMMON PARSE ROUTINE
378; *****************************************************
379
380;
381; COMMON PARSE BLOCKS
382;
383
384;
385; Indicates no value list for PARSE.
386;
387
388NO_VALUES DW 0 ;AN000; no values
389
390;
391; PARSE control block for a required file specification (upper cased)
392;
393
394FILE_REQUIRED LABEL BYTE ;AN000;
395 DW 0200H ;AN000; filespec - required
396 DW 1 ;AN000; capitalize - file table
397 DW TRANGROUP:PARSE1_OUTPUT ;AN000; result buffer
398 DW TRANGROUP:NO_VALUES ;AN000;
399 DB 0 ;AN000; no keywords
400
401;
402; PARSE control block for an optional file specification (upper cased)
403; or drive number
404;
405
406FILE_OPTIONAL LABEL BYTE ;AN000;
407 DW 0301H ;AN000; filespec or drive number
408 ; optional
409 DW 1 ;AN000; capitalize - file table
410 DW TRANGROUP:PARSE1_OUTPUT ;AN000; result buffer
411 DW TRANGROUP:NO_VALUES ;AN000;
412 DB 0 ;AN000; no keywords
413
414;
415; PARSE control block for an optional file specification (upper cased)
416;
417
418FILE_OPTIONAL2 LABEL BYTE ;AN000;
419 DW 0201H ;AN000; filespec or drive number
420 ; optional
421 DW 1 ;AN000; capitalize - file table
422 DW TRANGROUP:PARSE1_OUTPUT ;AN000; result buffer
423 DW TRANGROUP:NO_VALUES ;AN000;
424 DB 0 ;AN000; no keywords
425
426;
427; PARSE control block for an optional /P switch
428;
429
430SLASH_P_SWITCH LABEL BYTE ;AN000;
431 DW 0 ;AN000; no match flags
432 DW 2 ;AN000; capitalize - char table
433 DW TRANGROUP:PARSE1_OUTPUT ;AN000; result buffer
434 DW TRANGROUP:NO_VALUES ;AN000;
435 DB 1 ;AN000; 1 keyword
436SLASH_P_SYN DB "/P",0 ;AN000; /P switch
437
438
439
440; PARSE BLOCK FOR BREAK, VERIFY, ECHO
441
442;
443; The following parse control block can be used for any command which
444; needs only the optional "ON" and "OFF" keywords as operands. Allows
445; the equal sign as an additional delimiter. Returns verified result
446; in PARSE1_OUTPUT. Currently used for the BREAK, VERIFY, and ECHO
447; internal commands.
448;
449
450PARSE_BREAK LABEL BYTE ;AN000;
451 DW TRANGROUP:BREAK_PARMS ;AN000;
452 DB 0 ;AN032; no extra delimiter
453
454BREAK_PARMS LABEL BYTE ;AN000;
455 DB 0,1 ;AN000; 1 positional parm
456 DW TRANGROUP:BREAK_CONTROL1;AN000;
457 DB 0 ;AN000; no switches
458 DB 0 ;AN000; no keywords
459
460BREAK_CONTROL1 LABEL BYTE ;AN000;
461 DW 2001H ;AN000; string value - optional
462 DW 2 ;AN000; capitalize - char table
463 DW TRANGROUP:PARSE1_OUTPUT ;AN000; result buffer
464 DW TRANGROUP:BREAK_VALUES ;AN000;
465 DB 0 ;AN000; no keywords
466
467BREAK_VALUES LABEL BYTE ;AN000;
468 DB 3 ;AN000;
469 DB 0 ;AN000; no ranges
470 DB 0 ;AN000; no numeric values
471 DB 2 ;AN000; 2 string values
472 DB 0 ;AN000; returned if ON
473 DW TRANGROUP:BREAK_ON ;AN000; point to ON string
474 DB 'f' ;AN000; returned if OFF
475 DW TRANGROUP:BREAK_OFF ;AN000; point to OFF string
476
477BREAK_ON DB "ON",0 ;AN000;
478BREAK_OFF DB "OFF",0 ;AN000;
479
480;
481; PARSE BLOCK FOR CHCP
482;
483
484;
485; The following parse control block can be used for any command which
486; needs only one optional three digit decimal parameter for operands.
487; Returns verified result in PARSE1_OUTPUT. Currently used for the
488; CHCP internal command.
489;
490CHCP_MINVAL EQU 100 ;AN000;
491CHCP_MAXVAL EQU 999 ;AN000;
492
493PARSE_CHCP LABEL BYTE ;AN000;
494 DW TRANGROUP:CHCP_PARMS ;AN000;
495 DB 0 ;AN000; no extra delimiter
496
497CHCP_PARMS LABEL BYTE ;AN000;
498 DB 0,1 ;AN000; 1 positional parm
499 DW TRANGROUP:CHCP_CONTROL1 ;AN000;
500 DB 0 ;AN000; no switches
501 DB 0 ;AN000; no keywords
502
503CHCP_CONTROL1 LABEL BYTE ;AN000;
504 DW 8001H ;AN000; numeric value - optional
505 DW 0 ;AN000; no function flags
506 DW TRANGROUP:PARSE1_OUTPUT ;AN000; result buffer
507 DW TRANGROUP:CHCP_VALUES ;AN000;
508 DB 0 ;AN000; no keywords
509
510CHCP_VALUES LABEL BYTE ;AN000;
511 DB 1 ;AN000;
512 DB 1 ;AN000; 1 range
513 DB 1 ;AN000; returned if result
514 DD CHCP_MINVAL,CHCP_MAXVAL ;AN000; minimum & maximum value
515 DB 0 ;AN000; no numeric values
516 DB 0 ;AN000; no string values
517
518
519;
520; PARSE BLOCK FOR DATE
521;
522
523;
524; The following parse control block can be used for any command which
525; needs only an optional date string as an operand. Returns unverified
526; result in DATE_OUTPUT. Currently used for the DATE internal command.
527;
528
529PARSE_DATE LABEL BYTE ;AN000;
530 DW TRANGROUP:DATE_PARMS ;AN000;
531 DB 0 ;AN000; no extra delimiter
532
533DATE_PARMS LABEL BYTE ;AN000;
534 DB 0,1 ;AN000; 1 positional parm
535 DW TRANGROUP:DATE_CONTROL1 ;AN000;
536 DB 0 ;AN000; no switches
537 DB 0 ;AN000; no keywords
538
539DATE_CONTROL1 LABEL BYTE ;AN000;
540 DW 1001H ;AN000; date - optional
541 DW 0 ;AN000; no function flags
542 DW TRANGROUP:DATE_OUTPUT ;AN000; result buffer
543 DW TRANGROUP:NO_VALUES ;AN000;
544 DB 0 ;AN000; no keywords
545
546;
547; PARSE BLOCK FOR TIME
548;
549
550;
551; The following parse control block can be used for any command which
552; needs only an optional time string as an operand. Returns unverified
553; result in TIME_OUTPUT. Currently used for the TIME internal command.
554;
555
556PARSE_TIME LABEL BYTE ;AN000;
557 DW TRANGROUP:TIME_PARMS ;AN000;
558 DB 0 ;AN000; no extra delimiter
559
560TIME_PARMS LABEL BYTE ;AN000;
561 DB 0,1 ;AN000; 1 positional parm
562 DW TRANGROUP:TIME_CONTROL1 ;AN000;
563 DB 0 ;AN000; no switches
564 DB 0 ;AN000; no keywords
565
566TIME_CONTROL1 LABEL BYTE ;AN000;
567 DW 0801H ;AN000; TIME - optional
568 DW 0 ;AN000; no function flags
569 DW TRANGROUP:TIME_OUTPUT ;AN000; result buffer
570 DW TRANGROUP:NO_VALUES ;AN000;
571 DB 0 ;AN000; no keywords
572
573
574;
575; PARSE BLOCK FOR VOL
576;
577
578;
579; The following parse control block can be used for any command which
580; needs only an optional drive letter as an operand. Returns unverified
581; drive number (one based) in DRIVE_OUTPUT. Currently used for the VOL
582; internal command.
583;
584
585PARSE_VOL LABEL BYTE ;AN000;
586 DW TRANGROUP:VOL_PARMS ;AN000;
587 DB 0 ;AN000; no extra delimiter
588
589VOL_PARMS LABEL BYTE ;AN000;
590 DB 0,1 ;AN000; 1 positional parm
591 DW TRANGROUP:DRIVE_CONTROL1;AN000;
592 DB 0 ;AN000; no switches
593 DB 0 ;AN000; no keywords
594
595DRIVE_CONTROL1 LABEL BYTE ;AN000;
596 DW 0101H ;AN000; DRIVE - optional
597 DW 1 ;AN000; capitalize - file table
598 DW TRANGROUP:DRIVE_OUTPUT ;AN000; result buffer
599 DW TRANGROUP:NO_VALUES ;AN000;
600 DB 0 ;AN000; no keywords
601
602
603;
604; PARSE BLOCK FOR MKDIR, RMDIR, TYPE
605;
606
607;
608; The following parse control block can be used for any command which
609; needs only one required file specification as an operand. Returns a
610; pointer to the unverified string in PARSE1_OUTPUT. Currently used
611; for the MKDIR, RMDIR, and TYPE internal commands.
612;
613
614PARSE_MRDIR LABEL BYTE ;AN000;
615 DW TRANGROUP:MRDIR_PARMS ;AN000;
616 DB 0 ;AN000; no extra delimiter
617
618MRDIR_PARMS LABEL BYTE ;AN000;
619 DB 1,1 ;AN000; 1 positional parm
620 DW TRANGROUP:FILE_REQUIRED ;AN000;
621 DB 0 ;AN000; no switches
622 DB 0 ;AN000; no keywords
623
624;
625; PARSE BLOCK FOR CHDIR, TRUENAME
626;
627
628;
629; The following parse control block can be used for any command which
630; needs only one optional file specification an operand. Returns a
631; pointer to the unverified string in PARSE1_OUTPUT. Currently used
632; for the CHDIR and TRUENAME internal commands.
633;
634
635PARSE_CHDIR LABEL BYTE ;AN000;
636 DW TRANGROUP:CHDIR_PARMS ;AN000;
637 DB 0 ;AN000; no extra delimiter
638
639CHDIR_PARMS LABEL BYTE ;AN000;
640 DB 0,1 ;AN000; 1 positional parm
641 DW TRANGROUP:FILE_OPTIONAL ;AN000;
642 DB 0 ;AN000; no switches
643 DB 0 ;AN000; no keywords
644
645;
646; PARSE BLOCK FOR ERASE
647;
648
649;
650; The following parse control block is used for the DEL/ERASE internal
651; commands. This command has one required file specification and an
652; optional switch (/p) as operands. The verified switch or unverified
653; file specification is returned in PARSE1_OUTPUT.
654;
655
656PARSE_ERASE LABEL BYTE ;AN000;
657 DW TRANGROUP:ERASE_PARMS ;AN000;
658 DB 0 ;AN000; no extra delimiter
659
660ERASE_PARMS LABEL BYTE ;AN000;
661 DB 1,1 ;AN000; 1 positional parm
662 DW TRANGROUP:FILE_REQUIRED ;AN000;
663 DB 1 ;AN000; 1 switch
664 DW TRANGROUP:SLASH_P_SWITCH;AN000;
665 DB 0 ;AN000; no keywords
666
667;
668; PARSE BLOCK FOR DIR
669;
670
671;
672; The following parse control block is used for the DIR internal command.
673; This command has one optional file specification and two optional
674; switches (/p and /w) as operands. The verified switch or unverified
675; file specification is returned in PARSE1_OUTPUT.
676;
677
678PARSE_DIR LABEL BYTE ;AN000;
679 DW TRANGROUP:DIR_PARMS ;AN000;
680 DB 0 ;AN000; no extra delimiter
681
682DIR_PARMS LABEL BYTE ;AN000;
683 DB 0,1 ;AN000; 1 positional parm
684 DW TRANGROUP:FILE_OPTIONAL2;AN000;
685 DB 2 ;AN000; 2 switches
686 DW TRANGROUP:SLASH_P_SWITCH;AN000;
687 DW TRANGROUP:DIR_SWITCH1 ;AN000;
688 DB 0 ;AN000; no keywords
689
690DIR_SWITCH1 LABEL BYTE ;AN000;
691 DW 0 ;AN000; no match flags
692 DW 2 ;AN000; capitalize by char table
693 DW TRANGROUP:PARSE1_OUTPUT ;AN000; result buffer
694 DW TRANGROUP:NO_VALUES ;AN000;
695 DB 1 ;AN000; 1 keyword
696DIR_W_SYN DB "/W",0 ;AN000; /W switch
697
698;
699; PARSE BLOCK FOR RENAME
700;
701
702;
703; The following parse control block can be used for any command which
704; needs only two required file specifications as operands. Returns
705; pointers to the unverified string in PARSE1_OUTPUT.
706; Currently used for the RENAME internal command.
707;
708
709PARSE_RENAME LABEL BYTE ;AN000;
710 DW TRANGROUP:RENAME_PARMS ;AN000;
711 DB 0 ;AN000; no extra delimiter
712
713RENAME_PARMS LABEL BYTE ;AN000;
714 DB 2,2 ;AN000; 2 positional parms
715 DW TRANGROUP:FILE_REQUIRED ;AN000;
716 DW TRANGROUP:FILE_REQUIRED ;AN000;
717 DB 0 ;AN000; no switches
718 DB 0 ;AN000; no keywords
719
720;
721; PARSE BLOCK FOR CTTY
722;
723
724;
725; The following parse control block can be used for any command which
726; needs one required device name as an operand. Returns a pointer to
727; unverified string in PARSE1_OUTPUT. Currently used for the CTTY
728; internal command.
729;
730
731PARSE_CTTY LABEL BYTE ;AN000;
732 DW TRANGROUP:CTTY_PARMS ;AN000;
733 DB 0 ;AN000; no extra delimiter
734
735CTTY_PARMS LABEL BYTE ;AN000;
736 DB 1,1 ;AN000; 1 positional parm
737 DW TRANGROUP:CTTY_CONTROL1 ;AN000;
738 DB 0 ;AN000; no switches
739 DB 0 ;AN000; no keywords
740
741CTTY_CONTROL1 LABEL BYTE ;AN000;
742 DW 2000H ;AN000; string value - required
743 DW 11H ;AN000; capitalize - file table
744 ;AN000; remove colon at end
745 DW TRANGROUP:PARSE1_OUTPUT ;AN000; result buffer
746 DW TRANGROUP:NO_VALUES ;AN000;
747 DB 0 ;AN000; no keywords
748
749TRANDATA ENDS
750
751TRANCODE SEGMENT PUBLIC BYTE ;AN000;
752
753.xlist
754.xcref
755
756INCLUDE SYSMSG.INC ;AN000;
757
758.list
759.cref
760
761ASSUME DS:TRANGROUP,ES:TRANGROUP,CS:TRANGROUP
762
763MSG_UTILNAME <COMMAND> ;AN000; define utility name
764
765MSG_SERVICES <COMT,COMMAND.CLF,COMMAND.CL1,COMMAND.CL2> ;AN000; The transient messages
766
767include msgdcl.inc
768
769TRANCODE ENDS ;AN000;
770
771TRANDATA SEGMENT PUBLIC BYTE
772
773TRANDATAEND LABEL BYTE
774
775TRANDATA ENDS ;AN000;
776
777 END
diff --git a/v4.0/src/CMD/COMMAND/TENV.ASM b/v4.0/src/CMD/COMMAND/TENV.ASM
new file mode 100644
index 0000000..e1d43f6
--- /dev/null
+++ b/v4.0/src/CMD/COMMAND/TENV.ASM
@@ -0,0 +1,633 @@
1 page 80,132
2; SCCSID = @(#)tenv.asm 4.2 85/08/16
3; SCCSID = @(#)tenv.asm 4.2 85/08/16
4TITLE Part6 COMMAND Transient routines.
5
6; Environment utilities and misc. routines
7
8 INCLUDE comsw.asm
9
10.xlist
11.xcref
12 INCLUDE DOSSYM.INC
13 INCLUDE comseg.asm
14 INCLUDE comequ.asm
15 INCLUDE DOSCNTRY.INC ;AN000;
16.list
17.cref
18
19
20DATARES SEGMENT PUBLIC BYTE ;AC000;
21 EXTRN comdrv:byte
22 EXTRN comspec_end:word
23 EXTRN comspec_print:word
24 EXTRN cpdrv:byte
25 EXTRN dbcs_vector_addr:dword ;AN000;
26 EXTRN ENVIRSEG:WORD
27 EXTRN fucase_addr:word ;AC000;
28 EXTRN RESTDIR:BYTE
29DATARES ENDS
30
31TRANDATA SEGMENT PUBLIC BYTE ;AC000;
32 EXTRN arg_buf_ptr:word
33 EXTRN comspec:byte
34 EXTRN comspec_flag:byte
35 EXTRN comspecstr:byte
36 EXTRN ENVERR_PTR:WORD
37 EXTRN PATH_TEXT:byte
38 EXTRN PROMPT_TEXT:byte
39 EXTRN SYNTMES_PTR:WORD
40TRANDATA ENDS
41
42TRANSPACE SEGMENT PUBLIC BYTE ;AC000;
43 EXTRN Arg_Buf:BYTE
44 EXTRN RESSEG:WORD
45 EXTRN USERDIR1:BYTE
46TRANSPACE ENDS
47
48TRANCODE SEGMENT PUBLIC byte
49
50ASSUME CS:TRANGROUP,DS:NOTHING,ES:NOTHING,SS:NOTHING
51
52 EXTRN cerror:near
53
54 PUBLIC add_name_to_environment
55 PUBLIC add_prompt
56 PUBLIC delete_path
57 PUBLIC find_name_in_environment
58 PUBLIC find_path
59 PUBLIC find_prompt
60 PUBLIC move_name
61 PUBLIC restudir
62 PUBLIC restudir1
63 PUBLIC scan_double_null
64 PUBLIC scasb2
65 PUBLIC store_char
66 PUBLIC Testkanj ;AN000; 3/3/KK
67 PUBLIC upconv
68
69BREAK <Environment utilities>
70ASSUME DS:TRANGROUP
71
72 break Prompt command
73assume ds:trangroup,es:trangroup
74
75ADD_PROMPT:
76 CALL DELETE_PROMPT ; DELETE ANY EXISTING PROMPT
77 CALL SCAN_DOUBLE_NULL
78
79ADD_PROMPT2:
80 PUSH SI
81 CALL GETARG
82 POP SI
83 retz ; PRE SCAN FOR ARGUMENTS
84 CALL MOVE_NAME ; MOVE IN NAME
85 CALL GETARG
86 PUSH SI
87 JMP SHORT ADD_NAME
88
89
90 break The SET command
91assume ds:trangroup,es:trangroup
92
93;
94; Input: DS:SI points to a CR terminated string
95; Output: carry flag is set if no room
96; otherwise name is added to environment
97;
98
99DISP_ENVj:
100 jmp DISP_ENV
101
102ADD_NAME_TO_ENVIRONMENT:
103 CALL GETARG
104 JZ DISP_ENVj
105;
106; check if line contains exactly one equals sign
107;
108 XOR BX,BX ;= COUNT IS 0
109 PUSH SI ;SAVE POINTER TO BEGINNING OF LINE
110
111EQLP:
112 LODSB ;GET A CHAR
113 CMP AL,13 ;IF CR WE'RE ALL DONE
114 JZ QUEQ
115 CMP AL,'=' ;LOOK FOR = SIGN
116 JNZ EQLP ;NOT THERE, GET NEXT CHAR
117 INC BL ;OTHERWISE INCREMENT EQ COUNT
118 CMP BYTE PTR [SI],13 ;LOOK FOR CR FOLLOWING = SIGN
119 JNZ EQLP
120 INC BH ;SET BH=1 MEANS NO PARAMETERS
121 JMP EQLP ;AND LOOK FOR MORE
122
123QUEQ:
124 POP SI ;RESTORE BEGINNING OF LINE
125 DEC BL ;ZERO FLAG MEANS ONLY ONE EQ
126 JZ ONEQ ;GOOD LINE
127 MOV DX,OFFSET TRANGROUP:SYNTMES_ptr
128 JMP CERROR
129
130ONEQ:
131 PUSH BX
132 CALL DELETE_NAME_IN_ENVIRONMENT
133 POP BX
134 DEC BH
135 retz
136
137 CALL SCAN_DOUBLE_NULL
138 mov bx,di ; Save ptr to beginning of env var name
139 CALL MOVE_NAME
140 push si
141 xchg bx,di ; Switch ptrs to beginning and end of
142 ; env var name
143;
144; We want to special-case COMSPEC. This is to reduce the amount of code
145; necessary in the resident for re-reading the transient. Let's look for
146; COMSPEC=
147;
148 mov si,offset trangroup:comspecstr ; Load ptr to string "COMSPEC"
149 mov cx,4 ; If the new env var is comspec, set
150 repz cmpsw ; the comspec_flag
151;
152; Zero set => exact match
153;
154 jnz not_comspec
155 mov comspec_flag,1
156
157not_comspec:
158 mov di,bx ; Load ptr to end of env var name
159
160ADD_NAME: ; Add the value of the new env var
161 pop si ; to the environment.
162 push si
163
164add_name1:
165 LODSB
166 CMP AL,13
167 jz add_name_ret
168 CALL STORE_CHAR
169 JMP ADD_NAME1
170
171add_name_ret:
172 pop si
173 cmp comspec_flag,0 ; If the new env var is comspec,
174 retz ; copy the value into the
175;
176; We have changed the COMSPEC variable. We need to update the resident
177; pieces necessary to reread in the info. First, skip all delimiters
178;
179 invoke ScanOff
180 mov es,[resseg] ; comspec var in the resident
181 assume es:resgroup
182;
183; Make sure that the printer knows where the beginning of the string is
184;
185 mov di,offset resgroup:comspec
186 mov bx,di
187;
188; Generate drive letter for display
189;
190 xor ax,ax ;g assume no drive first
191 mov comdrv,al ;g
192 push ax ;AN000; 3/3/KK
193 mov al,[si] ;AN000; 3/3/KK
194 call testkanj ;AN000; 3/3/KK
195 pop ax ;AN000; 3/3/KK
196 jnz GotDrive
197 cmp byte ptr [si+1],':' ; drive specified?
198 jnz GotDrive
199 mov al,[si] ; get his specified drive
200 call UpConv ; convert to uppercase
201 sub al,'A' ; convert to 0-based
202 add di,2
203 inc al ; convert to 1-based number
204 mov comdrv,al
205;
206; Stick the drive letter in the prompt message. Nothing special needs to be
207; done here..
208;
209
210 add al,'A'-1
211
212GotDrive: ;g
213 mov comspec_print,di ;g point to beginning of name after drive
214 mov es:cpdrv,al
215;
216; Copy chars until delim
217;
218
219 mov di,bx
220
221copy_comspec:
222 lodsb
223 invoke Delim
224 jz CopyDone
225 cmp al,13
226 jz CopyDone
227 stosb
228 jmp short copy_comspec
229
230CopyDone:
231 xor al,al ; Null terminate the string and quit
232 stosb
233 mov comspec_flag,0
234 dec di
235 mov comspec_end,di
236
237 ret
238
239DISP_ENV:
240 MOV DS,[RESSEG]
241ASSUME DS:RESGROUP
242 MOV DS,[ENVIRSEG]
243ASSUME DS:NOTHING
244 XOR SI,SI
245
246PENVLP:
247 CMP BYTE PTR [SI],0
248 retz
249 mov di,offset trangroup:arg_buf
250
251PENVLP2:
252 LODSB
253 stosb
254 OR AL,AL
255 JNZ PENVLP2
256 mov dx,offset trangroup:arg_buf_ptr
257 push ds
258 push es
259 pop ds
260 invoke printf_crlf
261 pop ds
262 JMP PENVLP
263
264ASSUME DS:TRANGROUP
265
266DELETE_PATH:
267 MOV SI,OFFSET TRANGROUP:PATH_TEXT
268 JMP SHORT DELETE_NAME_IN_environment
269
270DELETE_PROMPT:
271 MOV SI,OFFSET TRANGROUP:PROMPT_TEXT
272
273DELETE_NAME_IN_environment:
274;
275; Input: DS:SI points to a "=" terminated string
276; Output: carry flag is set if name not found
277; otherwise name is deleted
278;
279 PUSH SI
280 PUSH DS
281 CALL FIND ; ES:DI POINTS TO NAME
282 JC DEL1
283 MOV SI,DI ; SAVE IT
284 CALL SCASB2 ; SCAN FOR THE NUL
285 XCHG SI,DI
286 CALL GETENVSIZ
287 SUB CX,SI
288 PUSH ES
289 POP DS ; ES:DI POINTS TO NAME, DS:SI POINTS TO NEXT NAME
290 REP MOVSB ; DELETE THE NAME
291
292DEL1:
293 POP DS
294 POP SI
295 return
296
297FIND_PATH:
298 MOV SI,OFFSET TRANGROUP:PATH_TEXT
299 JMP SHORT FIND_NAME_IN_environment
300
301FIND_PROMPT:
302 MOV SI,OFFSET TRANGROUP:PROMPT_TEXT
303
304FIND_NAME_IN_environment:
305;
306; Input: DS:SI points to a "=" terminated string
307; Output: ES:DI points to the arguments in the environment
308; zero is set if name not found
309; carry flag is set if name not valid format
310;
311 CALL FIND ; FIND THE NAME
312 retc ; CARRY MEANS NOT FOUND
313 JMP SCASB1 ; SCAN FOR = SIGN
314;
315; On return of FIND1, ES:DI points to beginning of name
316;
317FIND:
318 CLD
319 CALL COUNT0 ; CX = LENGTH OF NAME
320 MOV ES,[RESSEG]
321ASSUME ES:RESGROUP
322 MOV ES,[ENVIRSEG]
323ASSUME ES:NOTHING
324 XOR DI,DI
325
326FIND1:
327 PUSH CX
328 PUSH SI
329 PUSH DI
330
331FIND11:
332 LODSB
333 CALL TESTKANJ
334 JZ NOTKANJ3
335 DEC SI
336 LODSW
337 INC DI
338 INC DI
339 CMP AX,ES:[DI-2]
340 JNZ FIND12
341 DEC CX
342 LOOP FIND11
343 JMP SHORT FIND12
344
345NOTKANJ3:
346 CALL UPCONV
347 INC DI
348 CMP AL,ES:[DI-1]
349 JNZ FIND12
350 LOOP FIND11
351
352FIND12:
353 POP DI
354 POP SI
355 POP CX
356 retz
357 PUSH CX
358 CALL SCASB2 ; SCAN FOR A NUL
359 POP CX
360 CMP BYTE PTR ES:[DI],0
361 JNZ FIND1
362 STC ; INDICATE NOT FOUND
363 return
364
365COUNT0:
366 PUSH DS
367 POP ES
368 MOV DI,SI
369
370COUNT1:
371 PUSH DI ; COUNT NUMBER OF CHARS UNTIL "="
372 CALL SCASB1
373 JMP SHORT COUNTX
374
375COUNT2:
376 PUSH DI ; COUNT NUMBER OF CHARS UNTIL NUL
377 CALL SCASB2
378
379COUNTX:
380 POP CX
381 SUB DI,CX
382 XCHG DI,CX
383 return
384
385MOVE_NAME:
386 CMP BYTE PTR DS:[SI],13
387 retz
388 LODSB
389
390;;;; IF KANJI 3/3/KK
391 CALL TESTKANJ
392 JZ NOTKANJ1
393 CALL STORE_CHAR
394 LODSB
395 CALL STORE_CHAR
396 JMP SHORT MOVE_NAME
397
398NOTKANJ1:
399;;;; ENDIF 3/3/KK
400
401 CALL UPCONV
402 CALL STORE_CHAR
403 CMP AL,'='
404 JNZ MOVE_NAME
405 return
406
407GETARG:
408 MOV SI,80H
409 LODSB
410 OR AL,AL
411 retz
412 invoke SCANOFF
413 CMP AL,13
414 return
415
416;
417; Point ES:DI to the final NULL string. Note that in an empty environment,
418; there is NO double NULL, merely a string that is empty.
419;
420SCAN_DOUBLE_NULL:
421 MOV ES,[RESSEG]
422ASSUME ES:RESGROUP
423 MOV ES,[ENVIRSEG]
424ASSUME ES:NOTHING
425 XOR DI,DI
426;
427; Top cycle-point. If the string here is empty, then we are done
428;
429SDN1:
430 cmp byte ptr es:[di],0 ; nul string?
431 retz ; yep, all done
432 CALL SCASB2
433 JMP SDN1
434
435SCASB1:
436 MOV AL,'=' ; SCAN FOR AN =
437 JMP SHORT SCASBX
438SCASB2:
439 XOR AL,AL ; SCAN FOR A NUL
440SCASBX:
441 MOV CX,100H
442 REPNZ SCASB
443 return
444
445TESTKANJ:
446 push ds ;AN000; 3/3/KK
447 push si ;AN000; 3/3/KK
448 push ax ;AN000; 3/3/KK
449 mov ds,cs:[resseg] ;AN000; Get resident segment
450 assume ds:resgroup ;AN000;
451 lds si,dbcs_vector_addr ;AN000; get DBCS vector
452ktlop: ;AN000; 3/3/KK
453 cmp word ptr ds:[si],0 ;AN000; end of Table 3/3/KK
454 je notlead ;AN000; 3/3/KK
455 pop ax ;AN000; 3/3/KK
456 push ax ;AN000; 3/3/KK
457 cmp al, byte ptr ds:[si] ;AN000; 3/3/KK
458 jb notlead ;AN000; 3/3/KK
459 inc si ;AN000; 3/3/KK
460 cmp al, byte ptr ds:[si] ;AN000; 3/3/KK
461 jbe islead ;AN000; 3/3/KK
462 inc si ;AN000; 3/3/KK
463 jmp short ktlop ;AN000; try another range ; 3/3/KK
464Notlead: ;AN000; 3/3/KK
465 xor ax,ax ;AN000; set zero 3/3/KK
466 jmp short ktret ;AN000; 3/3/KK
467Islead: ;AN000; 3/3/KK
468 xor ax,ax ;AN000; reset zero 3/3/KK
469 inc ax ;AN000; 3/3/KK
470ktret: ;AN000; 3/3/KK
471 pop ax ;AN000; 3/3/KK
472 pop si ;AN000; 3/3/KK
473 pop ds ;AN000; 3/3/KK
474 return ;AN000; 3/3/KK
475;------------------------------------- ;3/3/KK
476
477
478; ****************************************************************
479; *
480; * ROUTINE: UPCONV (ADDED BY EMG 4.00)
481; *
482; * FUNCTION: This routine returns the upper case equivalent of
483; * the character in AL from the file upper case table
484; * in DOS if character if above ascii 128, else
485; * subtracts 20H if between "a" and "z".
486; *
487; * INPUT: AL char to be upper cased
488; * FUCASE_ADDR set to the file upper case table
489; *
490; * OUTPUT: AL upper cased character
491; *
492; ****************************************************************
493
494assume ds:trangroup ;AN000;
495
496upconv proc near ;AN000;
497
498 cmp al,80h ;AN000; see if char is > ascii 128
499 jb oth_fucase ;AN000; no - upper case math
500 sub al,80h ;AN000; only upper 128 chars in table
501 push ds ;AN000;
502 push bx ;AN000;
503 mov ds,[resseg] ;AN000; get resident data segment
504assume ds:resgroup ;AN000;
505 lds bx,dword ptr fucase_addr+1 ;AN000; get table address
506 add bx,2 ;AN000; skip over first word
507 xlat ds:byte ptr [bx] ;AN000; convert to upper case
508 pop bx ;AN000;
509 pop ds ;AN000;
510assume ds:trangroup ;AN000;
511 jmp short upconv_end ;AN000; we finished - exit
512
513oth_fucase: ;AN000;
514 cmp al,small_a ;AC000; if between "a" and "z",
515 jb upconv_end ;AC000; subtract 20h to get
516 cmp al,small_z ;AC000; upper case equivalent.
517 ja upconv_end ;AC000;
518 sub al,20h ;AC000; Change lower-case to upper
519
520upconv_end: ;AN000;
521 ret
522
523upconv endp ;AN000;
524
525
526;
527; STORE A CHAR IN environment, GROWING IT IF NECESSARY
528;
529STORE_CHAR:
530 PUSH CX
531 PUSH BX
532 PUSH ES ;AN056;
533 PUSH DS ;AN056; Save local DS
534 MOV DS,[RESSEG] ;AN056; Get resident segment
535 ASSUME DS:RESGROUP ;AN056;
536 MOV ES,[ENVIRSEG] ;AN056; Get environment segment
537 ASSUME ES:NOTHING ;AN056;
538 POP DS ;AN056; Get local segment back
539 ASSUME DS:TRANGROUP ;AN056;
540 CALL GETENVSIZ
541 MOV BX,CX
542 SUB BX,2 ; SAVE ROOM FOR DOUBLE NULL
543 CMP DI,BX
544 JB STORE1
545
546 PUSH AX
547 PUSH CX
548 PUSH BX ; Save Size of environment
549 invoke FREE_TPA
550 POP BX
551 ADD BX,2 ; Recover true environment size
552
553 CMP BX, 8000H ; Don't let environment grow > 32K
554 JB ENVSIZ_OK
555BAD_ENV_SIZE: ;AN056;
556 STC
557 JMP ENVNOSET
558ENVSIZ_OK:
559
560 MOV CL,4
561 SHR BX,CL ; Convert back to paragraphs
562 INC BX ; Try to grow environment by one para
563 MOV CX,ES ;AN056; Get environment segment
564 ADD CX,BX ;AN056; Add in size of environment
565 ADD CX,020H ;AN056; Add in some TPA
566 MOV AX,CS ;AN056; Get the transient segment
567 CMP CX,AX ;AN056; Are we hitting the transient?
568 JNB BAD_ENV_SIZE ;AN056; Yes - don't do it!!!
569 MOV AH,SETBLOCK
570 INT int_command
571ENVNOSET:
572 PUSHF
573 PUSH ES
574 MOV ES,[RESSEG]
575 invoke ALLOC_TPA
576 POP ES
577 POPF
578 POP CX
579 POP AX
580 JNC STORE1
581 POP ES ;AN056;
582 MOV DX,OFFSET TRANGROUP:ENVERR_ptr
583 JMP CERROR
584STORE1:
585 STOSB
586 MOV WORD PTR ES:[DI],0 ; NULL IS AT END
587 POP ES ;AN056;
588 POP BX
589 POP CX
590 return
591
592GETENVSIZ:
593;Get size of environment in bytes, rounded up to paragraph boundry
594;ES has environment segment
595;Size returned in CX, all other registers preserved
596
597 PUSH ES
598 PUSH AX
599 MOV AX,ES
600 DEC AX ;Point at arena
601 MOV ES,AX
602 MOV AX,ES:[arena_size]
603 MOV CL,4
604 SHL AX,CL ;Convert to bytes
605 MOV CX,AX
606 POP AX
607 POP ES
608 return
609
610
611ASSUME DS:TRANGROUP
612
613
614RESTUDIR1:
615 PUSH DS
616 MOV DS,[RESSEG]
617ASSUME DS:RESGROUP
618 CMP [RESTDIR],0
619 POP DS
620ASSUME DS:TRANGROUP
621 retz
622
623RESTUDIR:
624 MOV DX,OFFSET TRANGROUP:USERDIR1
625 MOV AH,CHDIR
626 INT int_command ; Restore users DIR
627 XOR AL,AL
628 invoke SETREST
629RET56:
630 return
631
632trancode ends
633 end
diff --git a/v4.0/src/CMD/COMMAND/TENV2.ASM b/v4.0/src/CMD/COMMAND/TENV2.ASM
new file mode 100644
index 0000000..0c47958
--- /dev/null
+++ b/v4.0/src/CMD/COMMAND/TENV2.ASM
@@ -0,0 +1,663 @@
1 page 80,132
2; SCCSID = @(#)tenv2.asm 1.1 85/05/14
3; SCCSID = @(#)tenv2.asm 1.1 85/05/14
4TITLE Part6 COMMAND Transient routines.
5
6; Environment utilities and misc. routines
7
8 INCLUDE comsw.asm
9
10.xlist
11.xcref
12 INCLUDE DOSSYM.INC
13 INCLUDE comseg.asm
14 INCLUDE comequ.asm
15.list
16.cref
17
18
19DATARES SEGMENT PUBLIC BYTE ;AC000;
20 EXTRN pipeflag:byte
21DATARES ENDS
22
23TRANDATA SEGMENT PUBLIC BYTE ;AC000;
24 EXTRN ACRLF_PTR:WORD
25 EXTRN BadCD_Ptr:WORD
26 EXTRN Badmkd_ptr:word
27 EXTRN BADRMD_PTR:WORD
28 EXTRN Extend_buf_ptr:word ;AN000;
29 EXTRN Extend_buf_sub:byte ;AN022;
30 EXTRN MD_exists_ptr:word ;AN006;
31 EXTRN msg_disp_class:byte ;AC000;
32 EXTRN NOSPACE_PTR:WORD
33 EXTRN parse_chdir:byte ;AC000;
34 EXTRN parse_mrdir:byte ;AC000;
35 EXTRN PIPEEMES_PTR:WORD
36 EXTRN string_buf_ptr:word
37TRANDATA ENDS
38
39TRANSPACE SEGMENT PUBLIC BYTE ;AC000;
40 EXTRN CURDRV:BYTE
41 EXTRN DESTINFO:BYTE
42 EXTRN DESTTAIL:WORD
43 EXTRN DIRCHAR:BYTE
44 EXTRN dirflag:byte ;AN015;
45 EXTRN KPARSE:BYTE ;AC000; 3/3/KK
46 EXTRN msg_numb:word ;AN022;
47 EXTRN parse1_addr:dword ;AC000;
48 EXTRN parse1_type:byte ;AC000;
49 EXTRN PATHPOS:WORD
50 EXTRN RESSEG:WORD
51 EXTRN srcxname:byte ;AC000;
52 EXTRN string_ptr_2:word
53 EXTRN SWITCHAR:BYTE
54 EXTRN USERDIR1:BYTE
55TRANSPACE ENDS
56
57TRANCODE SEGMENT PUBLIC byte
58
59ASSUME CS:TRANGROUP,DS:NOTHING,ES:NOTHING,SS:NOTHING
60
61 EXTRN cerror:near
62
63 PUBLIC $chdir
64 PUBLIC $mkdir
65 PUBLIC $rmdir
66 PUBLIC crlf2
67 PUBLIC crprint
68 PUBLIC delim
69 PUBLIC error_output
70 PUBLIC fcb_to_ascz
71 PUBLIC pathchrcmp
72 PUBLIC pathcrunch
73 PUBLIC savudir
74 PUBLIC savudir1
75 PUBLIC scanoff
76 PUBLIC strcomp
77
78break $Chdir
79
80; ****************************************************************
81; *
82; * ROUTINE: $CHDIR
83; *
84; * FUNCTION: Entry point for CHDIR command. Parse the command
85; * line. If path is found, CHDIR to path. If a drive
86; * letter is found, get and display the current dir
87; * of the specified drive. If nothing is found, get
88; * and display the current dir of the default drive.
89; *
90; * INPUT: command line at offset 81H
91; *
92; * OUTPUT: none
93; *
94; ****************************************************************
95
96assume ds:trangroup,es:trangroup
97
98$CHDIR:
99
100 mov si,81H
101 mov di,offset trangroup:parse_chdir ;AN000; Get adderss of PARSE_CHDIR
102 xor cx,cx ;AN000; clear cx,dx
103 xor dx,dx ;AN000;
104 invoke parse_with_msg ;AC018; call parser
105
106 cmp ax,end_of_line ;AC000; are we at end of line?
107 jz bwdJ ; No args
108 cmp ax,result_no_error ;AC000; did we have an error?
109 jnz ChDirErr ;AC018; yes - exit
110
111 cmp parse1_type,result_drive ;AC000; was a drive entered?
112 jnz REALCD ; no
113;
114; D: was found. See if there is anything more.
115;
116 mov di,offset trangroup:parse_chdir ;AC000; get address of parse_chdir
117 xor dx,dx ;AC000;
118 invoke parse_check_eol ;AC000; call parser
119 jnz ChDirErr ;AC000;
120
121bwdJ:
122 invoke build_dir_for_chdir ; Drive only specified
123 call crlf2
124 return
125
126REALCD:
127
128 push si ;AN000; save position in line
129 lds si,parse1_addr ;AN000; get address of filespec
130 invoke move_to_srcbuf ;AN000; move to srcbuf
131 pop si ;AN000; restore position in line
132 mov di,offset trangroup:parse_chdir ;AC000; get address of parse_chdir
133 xor dx,dx ;AC000;
134 invoke parse_check_eol ;AC000; call parser
135 jnz ChDirErr ;AC000;
136
137 invoke SETPATH
138 TEST [DESTINFO],2
139 JNZ BadChdir
140 MOV AH,CHDIR
141 INT int_command
142 retnc
143
144 invoke get_ext_error_number ;AN022; get the extended error
145 cmp ax,error_path_not_found ;AN022; see if path not found
146 jz BadChDir ;AN022; yes - issue old message
147 call Set_Ext_Error_Subst ;AN022;
148 jmp short chdirerr ;AN022;
149
150BadChDir:
151 MOV DX,OFFSET TRANGROUP:BADCD_ptr
152
153ChDirErr:
154 invoke Std_Eprintf
155 return
156
157break $Mkdir
158
159assume ds:trangroup,es:trangroup
160
161$MKDIR:
162 CALL SETRMMK
163 JC MkDirErr
164 MOV AH,MKDIR
165 INT int_command
166 retnc
167
168 invoke get_ext_error_number ;AN022; get the extended error
169 cmp ax,error_path_not_found ;AN022; see if path not found
170 jz MD_other_err ;AN022; yes - issue old message
171 cmp ax,error_access_denied ;AN022; access denied?
172 jz badmderr ;AN022; yes - see if file exists
173
174 call Set_Ext_Error_Subst ;AN022;
175 jmp short MkDirerr ;AC022; yes - go print it
176
177BADMDERR:
178 mov dx,offset trangroup:srcxname ;AN006; Set Disk transfer address
179 mov ah,Set_DMA ;AN006;
180 int int_command ;AN006;
181 MOV AH,Find_First ;AN006; see if file/dir exists
182 mov cx,attr_directory ;AN006; search for directory
183 INT int_command ;AN006;
184 jc MD_other_err ;AN006; doesn't exist - must be something else
185 mov dl,srcxname.find_buf_attr ;AN006; we found a file/dir
186 test dl,attr_directory ;AN006; was it a directory?
187 jz MD_other_err ;AN006; no - must have been a file
188 mov dx,offset trangroup:MD_exists_ptr ;AN006; set up already exists error
189 jmp short MkDirErr ;AN006; make sure we didn't have network error
190MD_other_err: ;AN006;
191 MOV DX,OFFSET TRANGROUP:BADMKD_ptr
192MkDirErr:
193 invoke Std_Eprintf
194 return
195
196Break <Common MkDir/RmDir set up code>
197
198;****************************************************************
199;*
200;* ROUTINE: SETRMMK
201;*
202;* FUNCTION: Parse routine for the internal MKDIR and RMDIR
203;* commands. Parses the command line for a required
204;* filespec.
205;*
206;* INPUT: command line at offset 81H
207;*
208;* OUTPUT: carry clear
209;* DS:DX points to ASCIIZ argument
210;* carry set
211;* DS:DX has error message pointer
212;*
213;****************************************************************
214
215SETRMMK:
216 mov si,81H
217 mov di,offset trangroup:parse_mrdir ;AN000; Get adderss of PARSE_MRDIR
218 xor cx,cx ;AN000; clear cx,dx
219 xor dx,dx ;AN000;
220 invoke parse_with_msg ;AC000; call parser
221 cmp ax,result_no_error ;AC000; did we have an error?
222 jnz NOARGERR ;AC000; yes - exit
223
224 mov di,offset trangroup:srcxname ;AN000; get address of srcxname
225 push di ;AN000; save address
226 push si ;AN000; save position in line
227 lds si,parse1_addr ;AN000; get address of path
228
229mrdir_move_filename: ;AN000; put filespec in srcxname
230 lodsb ;get a char from buffer
231 stosb ;AN000; store in srcxname
232 cmp al,end_of_line_out ;AC000; it char a terminator?
233 jnz mrdir_move_filename ;AC000; no - keep moving
234 pop si ;AN000; get line position back
235
236;
237; we have scanned an argument. See if any args beyond.
238;
239
240 mov di,offset trangroup:parse_mrdir ;AC000; get address of parse_mrdir
241 invoke parse_check_eol ;AC000; are we at end of line?
242 pop dx ;AC000; get address of SRCXNAME
243 retz ;yes - return no error
244NOARGERR:
245 mov dx,offset TranGroup:Extend_Buf_ptr ;AC000; get extended message pointer
246 XOR AX,AX
247 STC
248 return
249
250break $Rmdir
251
252assume ds:trangroup,es:trangroup
253
254$RMDIR:
255 CALL SETRMMK
256 JC RmDirErr
257 JNZ BADRDERR
258 MOV AH,RMDIR
259 INT int_command
260 retnc
261
262 invoke get_ext_error_number ;AN022; get the extended error
263 cmp ax,error_path_not_found ;AN022; see if path not found
264 jz badrderr ;AN022; yes - issue old message
265 cmp ax,error_access_denied ;AN022; access denied?
266 jz badrderr ;AN022; yes - issue old message
267
268 call Set_Ext_Error_Subst ;AN022;
269 jmp short RmDirerr ;AC022; yes - go print it
270
271BADRDERR:
272 MOV DX,OFFSET TRANGROUP:BADRMD_ptr
273
274RmDirErr:
275 invoke STD_Eprintf
276 return
277
278;****************************************************************
279;*
280;* ROUTINE: Set_ext_error_subst
281;*
282;* FUNCTION: Sets up substitution for extended error
283;*
284;* INPUT: AX - extended error number
285;* DX - offset of string
286;*
287;* OUTPUT: Extend_Buf_Ptr set up for STD_EPRINTF
288;*
289;****************************************************************
290
291Set_ext_error_subst proc near ;AN022;
292
293 mov msg_disp_class,ext_msg_class ;AN022; set up extended error msg class
294 mov string_ptr_2,dx ;AN022; get address of failed string
295 mov Extend_buf_sub,one_subst ;AN022; put number of subst in control block
296 mov dx,offset TranGroup:Extend_Buf_ptr ;AN022; get extended message pointer
297 mov Extend_Buf_ptr,ax ;AN022; get message number in control block
298
299 ret ;AN022; return
300
301Set_ext_error_subst endp ;AN022;
302
303
304
305
306
307Break <SavUDir - preserve the users current directory on a particular drive>
308
309;
310; SavUDir - move the user's current directory on a drive into UserDir1
311; SavUDir1 - move the user's current directory on a drive into a specified
312; buffer
313;
314; Inputs: DL has 1-based drive number
315; ES:DI has destination buffer (SavUDir1 only)
316; Outputs: Carry Clear
317; DS = TranGroup
318; Carry Set
319; AX has error code
320; Registers Modified: AX, SI
321;
322
323SAVUDIR:
324 MOV DI,OFFSET TRANGROUP:USERDIR1
325
326SAVUDIR1:
327 MOV AL,DL
328 ADD AL,'@'
329 CMP AL,'@'
330 JNZ GOTUDRV
331 ADD AL,[CURDRV]
332 INC AL ; A = 1
333
334GOTUDRV:
335 STOSB
336 MOV AH,[DIRCHAR]
337 MOV AL,':'
338 STOSW
339 PUSH ES
340 POP DS
341ASSUME DS:NOTHING
342
343 MOV SI,DI
344 MOV AH,CURRENT_DIR ; Get the Directory Text
345 INT int_command
346 retc
347 PUSH CS
348 POP DS
349ASSUME DS:TRANGROUP
350
351 return
352
353
354CRLF2:
355 PUSH DX
356 MOV DX,OFFSET TRANGROUP:ACRLF_ptr
357
358PR:
359 PUSH DS
360 PUSH CS
361 POP DS
362 invoke std_printf
363 POP DS
364 POP DX
365
366 return
367
368;
369; These routines (SCANOFF, DELIM) are called in batch processing when DS
370; may NOT be TRANGROUP
371;
372ASSUME DS:NOTHING,ES:NOTHING
373
374SCANOFF:
375 LODSB
376 CALL DELIM
377 JZ SCANOFF
378 DEC SI ; Point to first non-delimiter
379 return
380
381;
382; Input: AL is character to classify
383; Output: Z set if delimiter
384; NZ set otherwise
385; Registers modified: none
386;
387
388DELIM:
389 CMP AL,' '
390 retz
391 CMP AL,'='
392 retz
393 CMP AL,','
394 retz
395 CMP AL,';'
396 retz
397 CMP AL,9 ; Check for TAB character
398 retz
399 CMP AL,0ah ; Check for line feed character - BAS
400 return
401
402
403ASSUME DS:TRANGROUP,ES:TRANGROUP
404
405
406FCB_TO_ASCZ: ; Convert DS:SI to ASCIZ ES:DI
407 MOV CX,8
408
409MAINNAME:
410 LODSB
411 CMP AL,' '
412 JZ SKIPSPC
413 STOSB
414
415SKIPSPC:
416 LOOP MAINNAME
417 LODSB
418 CMP AL,' '
419 JZ GOTNAME
420 MOV AH,AL
421 MOV AL,dot_chr
422 STOSB
423 XCHG AL,AH
424 STOSB
425 MOV CL,2
426
427EXTNAME:
428 LODSB
429 CMP AL,' '
430 JZ GOTNAME
431 STOSB
432 LOOP EXTNAME
433
434GOTNAME:
435 XOR AL,AL
436 STOSB
437 return
438
439STRCOMP:
440;
441; Compare ASCIZ DS:SI with ES:DI.
442; SI,DI destroyed.
443;
444 CMPSB
445 retnz ; Strings not equal
446 cmp byte ptr [SI-1],0 ; Hit NUL terminator?
447 retz ; Yes, strings equal
448 jmp short STRCOMP ; Equal so far, keep going
449
450
451CRPRINT:
452 PUSH AX
453 MOV AL,13
454 PUSH CX
455 PUSH DI
456 MOV DI,DX
457 MOV CX,-1
458 PUSH ES
459 PUSH DS
460 POP ES
461
462 REPNZ SCASB ; LOOK FOR TERMINATOR
463 mov byte ptr [di-1],0 ; nul terminate the string
464 POP ES
465 mov string_ptr_2,dx
466 mov dx,offset trangroup:string_buf_ptr
467 invoke std_printf
468 mov ds:byte ptr [di-1],13 ; now put the CR back
469 JC ERROR_OUTPUT
470
471 POP DI
472 POP CX
473 POP AX
474
475 return
476
477ERROR_OUTPUT:
478 PUSH CS
479 POP DS
480ASSUME DS:TRANGROUP
481 MOV ES,[RESSEG]
482ASSUME ES:RESGROUP
483
484 MOV DX,OFFSET TRANGROUP:NOSPACE_ptr
485 CMP [PIPEFLAG],0
486 JZ GO_TO_ERROR
487
488 invoke PipeOff
489 MOV DX,OFFSET TRANGROUP:PIPEEMES_ptr
490GO_TO_ERROR:
491 JMP CERROR
492
493ASSUME DS:TRANGROUP,ES:TRANGROUP
494
495PATHCHRCMP:
496;---- Mod for path invocation ----
497PUBLIC pathchrcmp
498;----
499
500 push ax
501 mov ah,'/'
502 CMP [SWITCHAR],ah
503 JZ NOSLASHT
504 CMP AL,'/'
505 jz pccont
506
507NOSLASHT:
508 CMP AL,'\'
509pccont:
510 pop ax
511
512 return
513
514; Drive taken from FCB
515; User dir saved in userdir1
516;
517; Zero set if path dir, CHDIR to this dir, FCB filled with ?
518; NZ set if path/file, CHDIR to file, FCB has file (parsed fill ' ')
519; [DESTTAIL] points to parse point
520; Carry set if no CHDIRs worked, FCB not altered.
521; DESTISDIR set non zero if PATHCHRs in path (via SETPATH)
522;
523PATHCRUNCH:
524 mov [msg_numb],0 ;AN022; Set up message flag
525 MOV DL,DS:[FCB]
526 CALL SAVUDIR
527 jc pcrunch_cderrJ ;AN022; if error on current dir - report
528
529 invoke SETPATH
530 TEST [DESTINFO],2
531 JNZ TRYPEEL ; If ? or * cannot be pure dir
532
533 MOV AH,CHDIR
534 INT int_command
535 jnc chdir_worked ;AN022; no error - continue
536
537 invoke get_ext_error_number ;AN022; get the extended error
538 cmp ax,error_path_not_found ;AN022; if path not found
539 jz trypeel ;AC022; keep trying
540 cmp ax,error_access_denied ;AN022; if access denied
541 jz trypeel ;AC022; keep trying
542 mov [msg_numb],ax ;AN022; set up message flag
543 jmp peelfail ;AN022; exit with other error
544
545chdir_worked:
546 invoke SETREST1
547 MOV AL,'?' ; *.* is default file spec if pure dir
548 MOV DI,5DH
549 MOV CX,11
550 REP STOSB
551 XOR AL,AL ; Set zero
552 return
553
554pcrunch_cderrj: ;AN022; need this for long jmp
555 jmp pcrunch_cderr ;AN022;
556
557TRYPEEL:
558 MOV SI,[PATHPOS]
559 DEC SI ; Point at NUL
560 MOV AL,[SI-1]
561
562 CMP [KPARSE],0
563 JNZ DELSTRT ; Last char is second KANJI byte, might be '\'
564
565 CALL PATHCHRCMP
566 JZ PEELFAIL ; Trailing '/'
567
568DELSTRT:
569 MOV CX,SI
570 MOV SI,DX
571 PUSH DX
572DELLOOP:
573 CMP SI,CX
574 JZ GOTDELE
575 LODSB
576 invoke TESTKANJ
577 JZ NOTKANJ8
578 INC SI
579 JMP DELLOOP
580
581NOTKANJ8:
582 CALL PATHCHRCMP
583 JNZ DELLOOP
584 MOV DX,SI
585 DEC DX
586 JMP DELLOOP
587
588GOTDELE:
589 MOV SI,DX
590 POP DX
591 CMP SI,DX
592 JZ BADRET
593 MOV CX,SI
594 MOV SI,DX
595DELLOOP2: ; Set value of KPARSE
596 CMP SI,CX
597 JZ TRYCD
598 MOV [KPARSE],0
599 LODSB
600 INVOKE TESTKANJ
601 JZ DELLOOP2
602 INC SI
603 INC [KPARSE]
604 JMP DELLOOP2
605
606TRYCD:
607 push ax
608 mov al,dot_chr
609 CMP BYTE PTR [SI+1],al
610 pop ax
611 JZ PEELFAIL ; If . or .., pure cd should have worked
612 mov al,[si-1]
613 CMP al,':' ; Special case d:\file
614 JZ BADRET
615
616 CMP [KPARSE],0
617 JNZ NOTDOUBLESL ; Last char is second KANJI byte, might be '\'
618
619 CALL PATHCHRCMP
620 JNZ NOTDOUBLESL
621PEELFAIL:
622 STC ; //
623 return
624NOTDOUBLESL:
625 MOV BYTE PTR [SI],0
626 MOV AH,CHDIR
627 INT int_command
628 JNC CDSUCC
629pcrunch_cderr:
630 invoke get_ext_error_number ;AN022; get the extended error
631 mov [msg_numb],ax ;AN022; set up message flag
632 or si,si ;AN022; set up zero flag to not zero
633 stc ;AN022; set up carry flag
634 return
635
636BADRET:
637 MOV AL,[SI]
638 CALL PATHCHRCMP ; Special case 'DIRCHAR'file
639 STC
640 retnz
641 XOR BL,BL
642 XCHG BL,[SI+1]
643 MOV AH,CHDIR
644 INT int_command
645 jc pcrunch_cderr ;AN022; go to error exit
646 MOV [SI+1],BL
647CDSUCC:
648 invoke SETREST1
649 INC SI ; Reset zero
650 MOV [DESTTAIL],SI
651 pushf ;AN015; save flags
652 cmp dirflag,-1 ;AN015; don't do parse if in DIR
653 jz pcrunch_end ;AN015;
654 MOV DI,FCB
655 MOV AX,(PARSE_FILE_DESCRIPTOR SHL 8) OR 02H ; Parse with default drive
656 INT int_command
657pcrunch_end:
658 popf ;AN015; get flags back
659 return
660
661trancode ends
662 end
663 \ No newline at end of file
diff --git a/v4.0/src/CMD/COMMAND/TFOR.ASM b/v4.0/src/CMD/COMMAND/TFOR.ASM
new file mode 100644
index 0000000..8454d5c
--- /dev/null
+++ b/v4.0/src/CMD/COMMAND/TFOR.ASM
@@ -0,0 +1,551 @@
1 page 80,132
2; SCCSID = @(#)tfor.asm 4.1 85/09/17
3; SCCSID = @(#)tfor.asm 4.1 85/09/17
4TITLE Part3 COMMAND Transient Routines
5
6; For loop processing routines
7
8
9.xlist
10.xcref
11 include comsw.asm
12 INCLUDE DOSSYM.INC
13 INCLUDE DEVSYM.INC
14 include comseg.asm
15 include comequ.asm
16.list
17.cref
18
19
20DATARES SEGMENT PUBLIC BYTE ;AC000;
21 EXTRN BATCH:WORD
22 EXTRN ECHOFLAG:BYTE
23 EXTRN FORFLAG:BYTE
24 EXTRN FORPTR:WORD
25 EXTRN NEST:WORD
26 EXTRN NULLFLAG:BYTE
27 EXTRN PIPEFILES:BYTE
28 EXTRN SINGLECOM:WORD
29DATARES ENDS
30
31TRANDATA SEGMENT PUBLIC BYTE ;AC000;
32 EXTRN Extend_buf_ptr:word ;AN000;
33 extrn fornestmes_ptr:word
34 EXTRN msg_disp_class:byte ;AN000;
35 extrn string_buf_ptr:word
36TRANDATA ENDS
37
38TRANSPACE SEGMENT PUBLIC BYTE ;AC000;
39 extrn arg:byte ; the arg structure!
40 EXTRN COMBUF:BYTE
41 EXTRN RESSEG:WORD
42 EXTRN string_ptr_2:word
43TRANSPACE ENDS
44
45TRANCODE SEGMENT PUBLIC BYTE
46
47ASSUME CS:TRANGROUP,DS:NOTHING,ES:NOTHING,SS:NOTHING
48
49 EXTRN cerror:near
50 EXTRN docom:near
51 EXTRN docom1:near
52 EXTRN forerror:near
53 EXTRN tcommand:near
54
55 PUBLIC $for
56 PUBLIC forproc
57
58
59; All batch proccessing has DS set to segment of resident portion
60ASSUME DS:RESGROUP,ES:TRANGROUP
61
62
63FORTERM:
64 push cs ;AN037; Get local segment into
65 pop ds ;AN037; DS, ES
66 push cs ;AN037;
67 pop es ;AN037;
68 call ForOff
69 mov ds,ResSeg
70ASSUME DS:RESGROUP
71 CMP [SINGLECOM],0FF00H
72 JNZ BATCRLF
73 CMP NEST,0 ;G See if we have nested batch files
74 JNZ BATCRLF ;G Yes - don't exit just yet
75 MOV [SINGLECOM],-1 ; Cause a terminate
76 JMP SHORT NOFORP2
77
78BATCRLF:
79 test [ECHOFLAG],1 ;G Is echo on?
80 JZ NOFORP2 ;G no - exit
81 TEST [BATCH], -1 ;G print CRLF if in batch
82 JZ NOFORP2 ;G
83 invoke CRLF2
84
85NOFORP2:
86 JMP TCOMMAND
87
88
89;------
90; For-loop processing. For loops are of the form:
91; for %<loop-variable> in (<list>) do <command>
92; where <command> may contain references of the form %<variable>, which are
93; later substituted with the items in <list>. The for-loop structure is
94; set-up by the procedure '$for'; successive calls to 'forproc' execute
95; <command> once for each item in <list>. All of the information needed for
96; loop processing is stored on a piece of memory gotten from 'alloc'. This
97; structure is actually fairly large, on the order of 700 bytes, and includes
98; a complete copy of the original command-line structure as parsed by
99; 'parseline', loop control variables, and a dma buffer for the
100; 'FindFirst/FindNext' expansion of wildcard filenames in <list>. When loop
101; processing has completed, this chunk of memory is returned to the system.
102;
103; All of the previously defined variables, in 'datares', used for loop
104; processing may be erased. Only one, (DW) ForPtr, need be allocated.
105;
106; The error message, 'for_alloc_mes', should be moved into the file
107; containing all of the other error messages.
108;
109; Referencing the allocated for-loop structure is a little tricky.
110; At the moment, a byte is defined as part of a new segment, 'for_segment'.
111; When 'forproc' actually runs, ES and DS are set to point to the base of the
112; new chunk of memory. References to this byte, 'f', thus assemble correctly
113; as offsets of ES or DS. 'f' would not be necessary, except that the
114; assembler translates an instruction such as 'mov AX, [for_minarg]' as an
115; immediate move of the offset of 'for_minarg' into AX. In other words, in
116; terms of PDP-11 mnemonics, the assembler ACTUALLY assembles
117; mov AX, #for_minarg ; AX := 02CA (for example)
118; instead of
119; mov AX, for_minarg ; AX := [02CA] (contents of 02CA)
120; By using 'f', we pretend that we are actually referencing an allocated
121; structure, and the assembler coughs up the code we want. Notice that it
122; doesn't matter whether we put brackets around the location or not -- the
123; assembler is "smart" enough to know that we want an address instead of the
124; contents of that location.
125;
126; Finally, there now exists the potential to easily implement nested loops.
127; One method would be to have a link field in each for-structure pointing to
128; its parent. Variable references that couldn't be resolved in the local
129; frame would cause a search of prior frames. For-structures would still be
130; allocated and released in exactly the same fashion. The only limit on the
131; number of nested loops would be memory size (although at 700 bytes a pop,
132; memory wouldn't last THAT long). Alternately, a small structure could be
133; maintained in the resident data area. This structure would be an array of
134; control-variable names and pointers to for-structure blocks. This would
135; greatly speed up the resolution of non-local variable references. However,
136; since space in the resident is precious, we would have to compromise on a
137; "reasonable" level of nesting -- 10, 16, 32 levels, whatever. For-structure
138; allocation and de-allocation would have to be modified slightly to take this
139; new structure into account.
140;
141; Oops, just one more thing. Forbuf need not be a part of the for-structure.
142; It could just as well be one structure allocated in 'transpace'. Actually,
143; it may be easier to allocate it as part of 'for_segment'.
144;------
145
146 include fordata.asm
147
148$for_exit:
149 jmp forterm ; exceeding maxarg means all done
150
151forproc:
152assume DS:resgroup
153 mov AX, [ForPtr]
154 mov DS, AX
155 mov ES, AX ; operate in for-info area
156assume DS:for_segment, ES:for_segment
157
158 mov DX, OFFSET fordma
159 trap Set_Dma
160for_begin:
161 cmp f.for_expand, 0 ; non-zero for_expand equals FALSE
162 je for_begin1
163 inc f.for_minarg
164for_begin1:
165 mov BX, f.for_minarg ; current item in <list> to examine
166 cmp BX, f.for_maxarg
167 jg $for_exit ; exceeding maxarg means all done
168 mov AX, OFFSET for_args.argv
169 invoke argv_calc ; compute argv[x] address
170
171 mov CX, [BX].argstartel
172 mov DX, [BX].argpointer
173 test [bx].argflags,00000100b ; Is there a path separator in this arg?
174 jnz forsub ; Yes, argstartel should be correct
175 mov si, [BX].argpointer
176 mov al,lparen
177 cmp byte ptr [si-1],al ; If the current token is the first
178 jnz forsub ; one in the list and originally had
179 inc cx ; the opening paren as its first char,
180 ; the argstartel ptr needs to be
181 ; advanced passed it before the prefix
182 ; length is computed.
183 mov al,':'
184 cmp byte ptr [si+1],al ; If the token begins with "(d:",
185 jnz forsub ; argstartel has to be moved over the
186 add cx,2 ; rest of the prefix as well.
187
188forsub:
189 sub CX, DX ; compute length of pathname prefix
190 cmp f.for_expand, 0 ; are we still expanding a name?
191 je for_find_next ; if so, get next matching filename
192
193 test [BX].argflags, MASK wildcard
194 jnz for_find_first ; should we expand THIS (new) arg?
195 mov CX, [BX].arglen ; else, just copy all of it directly
196 jmp for_smoosh
197
198for_find_first:
199 PUSH CX
200 XOR CX,CX
201 trap Find_First ; and search for first filename match
202 POP CX
203 jmp for_result
204for_find_next:
205 trap Find_Next ; search for next filename match
206
207for_result:
208 mov AX, -1 ; assume worst case
209 jc forCheck
210 mov ax,0
211forCheck: ; Find* returns 0 for SUCCESS
212 mov f.FOR_EXPAND, AX ; record success of findfirst/next
213 or AX, AX ; anything out there?
214 jnz for_begin ; if not, try next arg
215
216for_smoosh:
217 mov SI, [BX].argpointer ; copy argv[arg][0,CX] into destbuf
218 mov DI, OFFSET forbuf ; some days this will be the entire
219 rep movsb ; arg, some days just the path prefix
220
221 cmp f.FOR_EXPAND, 0 ; if we're not expanding, we can
222 jnz for_make_com ; skip the following
223
224 mov SI, OFFSET fordma.find_buf_pname
225for_more: ; tack on matching filename
226 cmp BYTE PTR [SI], 0
227 je for_make_com
228 movsb
229 jnz for_more
230
231for_make_com:
232 xor AL, AL ; tack a null byte onto the end
233 stosb ; of the substitute string
234
235 xor CX, CX ; character count for command line
236 not CX ; negate it -- take advantage of loopnz
237 xor BX, BX ; argpointer
238 mov DI, OFFSET TRANGROUP:COMBUF+2
239 mov bl, f.FOR_COM_START ; argindex
240 mov DH, f.FOR_VAR ; %<for-var> is replaced by [forbuf]
241 ; time to form the <command> string
242 push CS
243 pop ES
244assume ES:trangroup
245
246 mov AX, OFFSET for_args ; translate offset to pointer
247 invoke argv_calc
248 mov si,[bx].arg_ocomptr
249 inc si ; mov ptr passed beginning space
250
251for_make_loop:
252 mov al,[si] ; the <command> arg, byte by byte
253 inc si
254 cmp AL,'%' ; looking for %<control-variable>
255 jne for_stosb ; no % ... add byte to string
256 cmp BYTE PTR [SI], DH ; got the right <variable>?
257 jne for_stosb ; got a %, but wrong <variable>
258 inc SI ; skip over <for-variable>
259
260 push SI
261 mov SI, OFFSET forbuf ; substitute the <item> for <variable>
262 ; to make a final <command> to execute
263sloop:
264 lodsb ; grab all those <item> bytes, and
265 stosb ; add 'em to the <command> string,
266 or AL, AL ; until we run into a null
267 loopnz sloop
268 dec DI ; adjust length and <command> pointer
269 inc CX ; so we can overwrite the null
270
271 pop SI
272 jmp for_make_loop ; got back for more <command> bytes
273for_stosb:
274 stosb ; take a byte from the <command> arg
275 dec CX ; and put it into the <command> to be
276 ; executed (and note length, too)
277 cmp al,0dh ; If not done, loop.
278 jne for_make_loop
279
280for_made_com: ; finished all the <command> args
281 not CL ; compute and record command length
282 mov [COMBUF+1], CL
283
284 mov DS, [RESSEG]
285assume DS:resgroup
286
287 test [ECHOFLAG],1 ; shall we echo this <command>, dearie?
288 jz noecho3
289 cmp nullflag,nullcommand ;G was there a command last time?
290 jz No_crlf_pr ;G no - don't print crlf
291 invoke CRLF2 ;G Print out prompt
292
293no_crlf_pr:
294 mov nullflag,0 ;G reset no command flag
295 push CS
296 pop DS
297 assume DS:trangroup
298 push di
299 invoke PRINT_PROMPT ;G Prompt the user
300 pop di
301 mov BYTE PTR ES:[DI-1],0 ; yeah, PRINT it out...
302 mov string_ptr_2,OFFSET TRANGROUP:COMBUF+2
303 mov dx,offset trangroup:string_buf_ptr
304 invoke std_printf
305 mov BYTE PTR ES:[DI-1], 0DH
306 jmp DoCom
307noecho3: ; run silent, run deep...
308 assume DS:resgroup
309 mov nullflag,0 ;G reset no command flag
310 push CS
311 pop DS
312 assume DS:trangroup
313 jmp docom1
314
315
316fornesterrj: ; no multi-loop processing... yet!
317assume ES:resgroup
318 call ForOff
319 jmp fornesterr
320
321forerrorj:
322 jmp forerror
323
324 break $For
325assume ds:trangroup,es:trangroup
326
327$for:
328 mov ES, [RESSEG]
329assume ES:resgroup
330
331 cmp ForFlag,0 ; is another one already running?
332 jnz fornesterrj ; if flag is set.... boom!
333
334;
335; Turn off any pipes in progress.
336;
337 cmp [PIPEFILES],0 ; Only turn off if present.
338 jz NoPipe
339 invoke PipeDel
340NoPipe:
341 xor DX, DX ; counter (0 <= DX < argvcnt)
342 call nextarg ; move to next argv[n]
343 jc forerrorj ; no more args -- bad forloop
344 cmp AL,'%' ; next arg MUST start with '%'...
345 jne forerrorj
346 mov BP, AX ; save forloop variable
347 lodsb
348 or AL, AL ; and MUST end immediately...
349 jne forerrorj
350
351 call nextarg ; let's make sure the next arg is 'in'
352 jc forerrorj
353 and AX, NOT 2020H ; uppercase the letters
354 cmp AX, in_word
355 jne forerrorj
356 lodsb
357 or AL, AL ; it, too, must end right away
358 je CheckLParen
359;
360; Not null. Perhaps there are no spaces between this and the (:
361; FOR %i in(foo bar...
362; Check for the Lparen here
363;
364 CMP AL,lparen
365 JNZ forerrorj
366;
367; The token was in(... We strip off the "in" part to simulate a separator
368; being there in the first place.
369;
370 ADD [BX].argpointer,2 ; advance source pointer
371 ADD [BX].arg_ocomptr,2 ; advance original string
372 SUB [BX].arglen,2 ; decrement the appropriate length
373;
374; SI now points past the in(. Simulate a nextarg call that results in the
375; current value.
376;
377 MOV ax,[si-1] ; get lparen and next char
378 jmp short lpcheck
379
380CheckLParen:
381 call nextarg ; lparen delimits beginning of <list>
382 jc forerrorj
383lpcheck:
384 cmp al, lparen
385 jne forerrorj
386 cmp ah,0
387 je for_paren_token
388
389 cmp ah, rparen ; special case: null list
390 jne for_list_not_empty
391 jmp forterm
392
393for_list_not_empty:
394 inc [bx].argpointer ; Advance ptr past "("
395 ; Adjust the rest of this argv entry
396 dec [bx].arglen ; to agree.
397 inc si ; Inc si so check for ")" works
398 jmp for_list
399
400for_paren_token:
401 call nextarg ; what have we in our <list>?
402 jc forerrorj
403 cmp ax, nullrparen ; special case: null list
404 jne for_list
405 jmp forterm
406
407forerrorjj:
408 jmp forerror
409
410for_list: ; skip over rest of <list>
411 mov CX, DX ; first arg of <list>
412skip_list:
413 add si,[bx].arglen
414 sub si,3 ; si = ptr to last char of token
415 mov al,rparen
416 cmp byte ptr [si],al ; Is this the last element in <list>
417 je for_end_list ; Yes, exit loop.
418 call nextarg ; No, get next arg <list>
419 jc forerrorjj ; If no more and no rparen, error.
420 jmp skip_list
421for_end_list:
422 mov DI, DX ; record position of last arg in <list>
423 mov byte ptr [si],0 ; Zap the rparen
424 cmp ax,nullrparen ; Was this token only a rparen
425 jz for_do ; Yes, continue
426 inc di ; No, inc position of last arg
427
428for_do:
429 call nextarg ; now we had BETTER find a 'do'...
430 jc forerrorjj
431 and AX, NOT 2020H ; uppercase the letters
432 cmp AX, do_word
433 jne forerrorjj
434 lodsb
435 or AL, AL ; and it had BETTER be ONLY a 'do'...
436 jne forerrorjj
437
438 call nextarg ; on to the beginning of <command>
439 jc forerrorjj ; null <command> not legal
440
441 push AX
442 push BX
443 push CX
444 push DX ; preserve registers against disaster
445 push DI
446 push SI
447 push BP
448 invoke FREE_TPA ; need to make free memory, first
449ASSUME ES:RESGROUP
450 call ForOff
451 mov BX, SIZE for_info - SIZE arg_unit
452 invoke Save_Args ; extra bytes needed for for-info
453 pushf
454 mov [ForPtr], AX
455 invoke ALLOC_TPA ; ALLOC_TPA clobbers registers...
456 popf
457 pop BP
458 pop SI
459 pop DI
460 pop DX
461 pop CX
462 pop BX
463 pop AX
464 jc for_alloc_err
465
466 push ES ; save resgroup seg...
467 push [ForPtr]
468 pop ES
469assume ES:for_segment ; make references to for-info segment
470
471 dec CX ; forproc wants min pointing before
472 dec DI ; first arg, max right at last one
473 mov f.for_minarg, CX
474 mov f.for_maxarg, DI
475 mov f.for_com_start, DL
476 mov f.for_expand, -1 ; non-zero means FALSE
477 mov AX, BP
478 mov f.for_var, AH
479 pop ES
480assume ES:resgroup
481
482 inc [FORFLAG]
483 cmp [SINGLECOM], -1
484 jnz for_ret
485 mov [SINGLECOM], 0FF00H
486for_ret:
487 ret
488
489for_alloc_err:
490 mov msg_disp_class,ext_msg_class ;AN000; set up extended error msg class
491 mov dx,offset TranGroup:Extend_Buf_ptr ;AC000; get extended message pointer
492 mov Extend_Buf_ptr,error_not_enough_memory ;AN000; get message number in control block
493 jmp cerror
494
495nextarg:
496 inc DX ; next argv[n]
497 cmp DX, arg.argvcnt ; make sure we don't run off end
498 jge nextarg_err ; of argv[]...
499 mov BX, DX
500 mov AX, OFFSET TRANGROUP:arg.argv
501 invoke argv_calc ; convert array index to pointer
502 mov SI, [BX].argpointer ; load pointer to argstring
503 lodsw ; and load first two chars
504 clc
505 ret
506nextarg_err:
507 stc
508 ret
509
510
511ASSUME DS:TRANGROUP,ES:TRANGROUP
512
513FORNESTERR:
514 PUSH DS
515 MOV DS,[RESSEG]
516ASSUME DS:RESGROUP
517 MOV DX,OFFSET TRANGROUP:FORNESTMES_ptr
518 CMP [SINGLECOM],0FF00H
519 JNZ NOFORP3
520 MOV [SINGLECOM],-1 ; Cause termination
521NOFORP3:
522 POP DS
523ASSUME DS:TRANGROUP
524 JMP CERROR
525;
526; General routine called to free the for segment. We also clear the forflag
527; too. Change no registers.
528;
529PUBLIC ForOff
530ForOff:
531 assume DS:NOTHING,ES:NOTHING
532 SaveReg <AX,ES>
533 mov es,ResSeg
534 assume es:ResGroup
535 mov AX,ForPtr
536 or ax,ax
537 jz FreeDone
538 push es
539 mov es,ax
540 mov ah,dealloc
541 int 21h
542 pop es
543FreeDone:
544 mov ForPtr,0
545 mov ForFlag,0
546 RestoreReg <ES,AX>
547 return
548
549trancode ends
550 end
551 \ No newline at end of file
diff --git a/v4.0/src/CMD/COMMAND/TMISC1.ASM b/v4.0/src/CMD/COMMAND/TMISC1.ASM
new file mode 100644
index 0000000..4b55aac
--- /dev/null
+++ b/v4.0/src/CMD/COMMAND/TMISC1.ASM
@@ -0,0 +1,655 @@
1 page 80,132
2; SCCSID = @(#)tmisc1.asm 4.1 85/09/22
3; SCCSID = @(#)tmisc1.asm 4.1 85/09/22
4TITLE Part7 COMMAND Transient Routines
5
6; More misc routines
7
8.xlist
9.xcref
10 INCLUDE comsw.asm
11 INCLUDE DOSSYM.INC
12 INCLUDE comseg.asm
13 INCLUDE comequ.asm
14.list
15.cref
16
17
18
19CODERES SEGMENT PUBLIC BYTE ;AC000;
20 EXTRN RSTACK:BYTE
21CodeRes ENDS
22
23DATARES SEGMENT PUBLIC BYTE ;AC000;
24 EXTRN CALL_FLAG:BYTE
25 EXTRN EchoFlag:BYTE
26 EXTRN EXEC_BLOCK:BYTE
27 EXTRN EXTCOM:BYTE
28 EXTRN PIPEFLAG:BYTE
29 EXTRN PIPEPTR:WORD
30 EXTRN PIPESTR:BYTE
31 EXTRN RESTDIR:BYTE
32 EXTRN RE_OUT_APP:BYTE
33 EXTRN RE_OUTSTR:BYTE
34DATARES ENDS
35
36TRANDATA SEGMENT PUBLIC BYTE ;AC000;
37 EXTRN BADDRV_PTR:WORD
38 EXTRN BADNAM_PTR:WORD
39 EXTRN COMTAB:BYTE ;AC000;
40 EXTRN extend_buf_ptr:word ;AN000;
41 EXTRN msg_disp_class:byte ;AN000;
42TRANDATA ENDS
43
44TRANSPACE SEGMENT PUBLIC BYTE ;AC000;
45 EXTRN arg:byte ; the arg structure!
46 EXTRN APPEND_EXEC:BYTE ;AN041;
47 EXTRN CHKDRV:BYTE
48 EXTRN COMBUF:BYTE
49 EXTRN EXECPATH:BYTE
50 EXTRN EXEC_ADDR:DWORD
51 EXTRN FILTYP:BYTE
52 EXTRN IDLEN:BYTE
53 EXTRN KPARSE:BYTE ;AC000;
54 EXTRN PARM1:BYTE
55 EXTRN PARM2:BYTE
56 EXTRN PathPos:word
57 EXTRN RESSEG:WORD
58 EXTRN RE_INSTR:BYTE
59 EXTRN SPECDRV:BYTE
60 EXTRN SWITCHAR:BYTE
61 EXTRN switch_list:byte
62 EXTRN TRAN_TPA:WORD
63
64 IF IBM
65 EXTRN ROM_CALL:BYTE
66 EXTRN ROM_CS:WORD
67 EXTRN ROM_IP:WORD
68 ENDIF
69
70TRANSPACE ENDS
71
72TRANCODE SEGMENT PUBLIC byte
73
74ASSUME CS:TRANGROUP,DS:NOTHING,ES:NOTHING,SS:NOTHING
75
76 EXTRN APPEND_PARSE:NEAR ;AN010;
77 EXTRN BATCOM:NEAR
78 EXTRN DOCOM1:NEAR
79 EXTRN PIPEERRSYN:NEAR
80 EXTRN TCOMMAND:NEAR
81
82 IF IBM
83 EXTRN ROM_EXEC:NEAR
84 EXTRN ROM_SCAN:NEAR
85 ENDIF
86
87 PUBLIC CERROR
88 PUBLIC DRVBAD
89 PUBLIC EXTERNAL
90 PUBLIC FNDCOM
91 PUBLIC PRESCAN
92 PUBLIC SWITCH
93
94
95ASSUME DS:TRANGROUP
96
97;---------------------------
98; We can get rid of this switch processing code if we can take
99; care of the remaining two calls to switch, later in the file.
100; However, I have not checked whether or not any other files use
101; switch -- after all, it IS public!
102;---------------------------
103RETSW:
104 XCHG AX,BX ; Put switches in AX
105 return
106
107SWITCH:
108 XOR BX,BX ; Initialize - no switches set
109SWLOOP:
110 INVOKE SCANOFF ; Skip any delimiters
111 CMP AL,[SWITCHAR] ; Is it a switch specifier?
112 JNZ RETSW ; No -- we're finished
113 OR BX,fSwitch ; Indicate there is a switch specified
114 INC SI ; Skip over the switch character
115 INVOKE SCANOFF
116 CMP AL,0DH
117 JZ RETSW ; Oops
118 INC SI
119; Convert lower case input to upper case
120 INVOKE UPCONV
121 MOV DI,OFFSET TRANGROUP:switch_list
122 MOV CX,SWCOUNT
123 REPNE SCASB ; Look for matching switch
124 JNZ BADSW
125 MOV AX,1
126 SHL AX,CL ; Set a bit for the switch
127 OR BX,AX
128 JMP SHORT SWLOOP
129
130BADSW:
131 JMP SHORT SWLOOP
132
133SWCOUNT EQU 5 ; Length of switch_list
134
135DRVBAD:
136 MOV DX,OFFSET TRANGROUP:BADDRV_ptr
137 JMP CERROR
138
139externalj:
140 jmp EXTERNAL
141
142fndcom: ; search the internal command table
143 OR AL,AL ; Get real length of first arg
144 jz externalj ; If 0, it must begin with "\" so has
145 ; to be external.
146; barryf code starts here
147
148 IF IBM
149 call test_append ; see if APPEND installed
150 je contcom ; not loaded
151
152append_internal:
153 mov cl,TRANGROUP:IDLEN
154 mov ch,0
155 mov pathpos,cx
156 inc append_exec ;AN041; set APPEND to ON
157
158 invoke ioset ; re-direct the o'l io
159
160 mov SI, offset TRANGROUP:IDLEN ; address command name, DS already set
161 mov DX,-1 ; set invoke function
162 mov di,offset TRANGROUP:APPEND_PARSE;AN010; Get the entry point for PARSE for APPEND
163 mov AX,0AE01H
164 int 2FH ; execute command
165 cmp TRANGROUP:IDLEN,0 ; execute requested
166 jne contcom
167 jmp Cmd_done
168
169contcom: ; continue with internal scan
170 ENDIF
171
172; barryf code ends here
173
174 mov DI, OFFSET TRANGROUP:COMTAB
175 XOR CX,CX
176
177findcom:
178 mov SI, offset TRANGROUP:IDLEN+1 ; pointer to command argument
179 mov CL, [DI] ; load length of internal command
180 inc di ; advance past length
181 jcxz externalj ; if it's zero, we're out of internals
182 cmp CL, IDLEN ; that of the command argument
183 jnz abcd ; lengths not equal ==> strings not eq
184 MOV PathPos,CX ; store length of command
185 repz cmpsb
186
187abcd:
188 lahf ; save the good ol' flags
189 add DI, CX ; skip over remaining internal, if any
190 mov AL, BYTE PTR [DI] ; load drive-check indicator byte (DCIB)
191 mov [CHKDRV], AL ; save command flag byte in chkdrv
192 inc DI ; increment DI (OK, OK, I'll stop)
193 mov BX, WORD PTR [DI] ; load internal command address
194 inc DI ; skip over the puppy
195 inc DI
196 sahf ; remember those flags?
197 jnz findcom ; well, if all the cmps worked...
198;
199; All messages get redirected.
200;
201 cmp append_exec,0 ;AN041; APPEND just executed?
202 jnz dont_set_io ;AN041; Yes - this junk is already set
203 invoke ioset ; re-direct the ol' i/o
204
205dont_set_io: ;AN041;
206 invoke SETSTDINON ;AN026; turn on critical error on STDIN
207 invoke SETSTDOUTOFF ;AN026; turn off critical error on STDOUT
208 test [CHKDRV], fCheckDrive ; did we wanna check those drives?
209 jz nocheck
210 mov AL, [PARM1] ; parse_file_descriptor results tell
211 or AL, [PARM2] ; us whether those drives were OK
212 cmp AL, -1
213 jnz nocheck
214 jmp drvbad
215
216
217;
218; The user may have omitted the space between the command and its arguments.
219; We need to copy the remainder of the user's command line into the buffer.
220; Note that thisdoes not screw up the arg structure; it points into COMBUF not
221; into the command line at 80.
222;
223nocheck:
224 call cmd_copy
225
226switcheck:
227 test [CHKDRV], fSwitchAllowed ; Does the command take switches
228 jnz realwork ; Yes, process the command
229 call noswit ; No, check to see if any switches
230 jnz realwork ; None, process the command
231 mov msg_disp_class,parse_msg_class ;AN000; set up parse error msg class
232 MOV DX,OFFSET TranGroup:Extend_Buf_ptr ;AC000; get extended message pointer
233 mov Extend_Buf_ptr,BadSwt_ptr ;AN000; get "Invalid switch" message number
234 jmp CERROR ; Print error and chill out...
235realwork:
236 call BX ; do some real work, at last
237
238; See if we're in a batch CALL command. If we are, reprocess the command line,
239; otherwise, go get another command.
240
241Cmd_done:
242 push cs ; g restore data segment
243 pop ds ; g
244 push ds ; g save data segment
245 mov ds,[resseg] ; g get segment containing call flag
246 ASSUME ds:resgroup
247 cmp call_flag, call_in_progress ; G Is a call in progress?
248 mov call_flag, 0 ; G Either way, reset flag
249 pop ds ; g get data segment back
250 jz incall ; G
251 jmp tcommand ; chill out...
252
253incall:
254 JMP DOCOM1
255
256noswit:
257 push di ; Save di
258 mov di,81h ; di = ptr to command args
259 mov si,80h ; Get address of length of command args
260 lodsb ; Load length
261 mov cl,al ; Move length to cl
262 xor ch,ch ; Zero ch
263 mov al,[SWITCHAR] ; al = switch character
264 cmp al,0 ; Turn off ZF
265 repnz scasb ; Scan for a switch character and return
266 pop di ; with ZF set if one was found
267 ret
268
269EXTERNAL:
270
271IF IBM
272 call test_append ; check to see if append installed
273 je not_barryf ; no - truly external command
274 jmp append_internal ; yes - go to Barryf code
275
276not_barryf:
277
278ENDIF
279
280 MOV [FILTYP],0
281 MOV DL,[SPECDRV]
282 MOV [IDLEN],DL
283IF IBM
284 MOV [ROM_CALL],0
285 PUSH DX
286 MOV DX,OFFSET TRANGROUP:IDLEN
287 CALL ROM_SCAN
288 POP DX
289 JNC DO_SCAN
290 INC [ROM_CALL]
291 JMP PostSave
292DO_SCAN:
293ENDIF
294IF IBM
295PostSave:
296ENDIF
297 MOV DI,OFFSET TRANGROUP:EXECPATH
298 MOV BYTE PTR [DI],0 ; Initialize to current directory
299IF IBM
300 CMP [ROM_CALL],0
301 JZ Research
302 JMP NeoExecute
303ENDIF
304RESEARCH:
305 invoke path_search ; find the mother (result in execpath)
306 or AX, AX ; did we find anything?
307 je badcomj45 ; null means no (sob)
308 cmp AX, 04H ; 04H and 08H are .exe and .com
309 jl rsrch_br1 ; fuckin' sixteen-bit machine ought
310 jmp execute ; to be able to handle a SIXTEEN-BIT
311rsrch_br1: ; DISPLACEMENT!!
312 jmp batcom ; 02H is .bat
313BADCOMJ45:
314 JMP BADCOM
315
316ASSUME DS:TRANGROUP,ES:TRANGROUP
317
318EXECUTE:
319NeoExecute:
320 invoke IOSET
321 invoke SETSTDINOFF ;AN026; turn off critical error on STDIN
322 invoke SETSTDOUTOFF ;AN026; turn off critical error on STDOUT
323 MOV ES,[TRAN_TPA]
324 MOV AH,DEALLOC
325 INT int_command ; Now running in "free" space
326 MOV ES,[RESSEG]
327ASSUME ES:RESGROUP
328 INC [EXTCOM] ; Indicate external command
329 MOV [RESTDIR],0 ; Since USERDIR1 is in transient, insure
330 ; this flag value for re-entry to COMMAND
331 MOV DI,FCB
332 MOV SI,DI
333 MOV CX,052H ; moving (100h-5Ch)/2 = 80h-2Eh
334 REP MOVSW ; Transfer parameters to resident header
335 MOV DX,OFFSET TRANGROUP:EXECPATH
336 MOV BX,OFFSET RESGROUP:EXEC_BLOCK
337 MOV AX,EXEC SHL 8
338IF IBM
339 TEST [ROM_CALL],-1
340 JZ OK_EXEC
341 JMP ROM_EXEC
342OK_EXEC:
343ENDIF
344;
345; we are now running in free space. anything we do from here on may get
346; trashed. Move the stack (also in free space) to allocated space because
347; since EXEC restores the stack, somebody may trash what is on the stack.
348;
349 MOV CX,ES
350 MOV SS,CX
351 MOV SP,OFFSET RESGROUP:RSTACK
352 JMP [EXEC_ADDR] ; Jmp to the EXEC in the resident
353
354BADCOM:
355 PUSH CS
356 POP DS
357 MOV DX,OFFSET TRANGROUP:BADNAM_ptr
358
359CERROR:
360 INVOKE std_eprintf
361 JMP TCOMMAND
362
363;
364; Prescan converts the input buffer into a canonicalized form. All
365; redirections and pipes are removed.
366;
367PRESCAN: ; Cook the input buffer
368
369ASSUME DS:TRANGROUP,ES:TRANGROUP
370
371 XOR CX,CX
372 MOV ES,[RESSEG]
373ASSUME ES:RESGROUP
374 MOV SI,OFFSET TRANGROUP:COMBUF+2
375 MOV DI,SI
376
377CountQuotes:
378 LODSB ; get a byte
379 CMP AL,22h ; is it a quote?
380 JNZ CountEnd ; no, try for end of road
381 INC CH ; bump count
382 JMP CountQuotes ; go get next char
383
384CountEnd:
385 CMP AL,13 ; end of road?
386 JNZ CountQuotes ; no, go back for next char
387
388;;;; IF KANJI 3/3/KK
389 PUSH CX ; save count
390 MOV SI,DI ; get back beginning of buffer
391
392KanjiScan:
393 LODSB ; get a byte
394 INVOKE TestKanj ; is it a leadin byte
395 JZ KanjiQuote ; no, check for quotes
396 MOV AH,AL ; save leadin
397 LODSB ; get trailing byte
398 CMP AX,8140h ; is it Kanji space
399 JNZ KanjiScan ; no, go get next
400 MOV [SI-2],2020h ; replace with spaces
401 JMP KanjiScan ; go get next char
402
403KanjiQuote:
404 CMP AL,22h ; beginning of quoted string
405 JNZ KanjiEnd ; no, check for end
406 DEC CH ; drop count
407 JZ KanjiScan ; if count is zero, no quoting
408
409KanjiQuoteLoop:
410 LODSB ; get next byte
411 CMP AL,22h ; is it another quote
412 JNZ KanjiQuoteLoop ; no, get another
413 DEC CH ; yes, drop count
414 JMP KanjiScan ; go get next char
415
416KanjiEnd:
417 CMP AL,13 ; end of line character?
418 JNZ KanjiScan ; go back to beginning
419 POP CX ; get back original count
420;;;; ENDIF 3/3/KK
421
422 MOV SI,DI ; restore pointer to begining
423
424PRESCANLP:
425 LODSB
426
427;;;; IF KANJI 3/3/KK
428 INVOKE TESTKANJ
429 JZ NOTKANJ6
430 MOV [DI],AL
431 INC DI ; fake STOSB into DS
432 LODSB ; grab second byte
433 MOV [DI],AL ; fake stosb into DS
434 INC DI
435 INC CL
436 INC CL
437 JMP PRESCANLP
438
439NOTKANJ6:
440;;;; ENDIF 3/3/KK
441
442 CMP AL,'"' ; " character
443 JNZ TRYGREATER
444 DEC CH
445 JZ TRYGREATER
446
447QLOOP:
448 MOV [DI],AL
449 INC DI
450 INC CL
451 LODSB
452 CMP AL,'"' ; " character
453 JNZ QLOOP
454 DEC CH
455
456TRYGREATER:
457 CMP AL,rabracket
458 JNZ NOOUT
459;
460; We have found a ">" char. We need to see if there is another ">"
461; following it.
462;
463 CMP BYTE PTR [SI],al
464 JNZ NOAPPND
465 LODSB
466 INC [RE_OUT_APP] ; Flag >>
467
468NOAPPND:
469;
470; Now we attempt to find the file name. First, scan off all whitespace
471;
472 INVOKE SCANOFF
473 CMP AL,labracket ;AN040; was there no filename?
474 JZ REOUT_ERRSET ;AN040; yes - set up error
475 CMP AL,0DH
476 JNZ GOTREOFIL
477;
478; There was no file present. Set us up at end-of-line.
479;
480REOUT_ERRSET: ;AN040; set up for an error
481 mov byte ptr [di], 0dh ; Clobber first ">"
482 MOV WORD PTR [RE_OUTSTR],09H ; Cause an error later
483 JMP PRESCANEND
484
485GOTREOFIL:
486 PUSH DI
487 MOV DI,OFFSET RESGROUP:RE_OUTSTR
488 MOV BX,DI
489 PUSH ES
490
491SETREOUTSTR: ; Get the output redirection name
492 LODSB
493 CMP AL,0DH
494 JZ GOTRESTR
495 INVOKE DELIM
496 JZ GOTRESTR
497 CMP AL,[SWITCHAR]
498 JZ GOTRESTR
499 CMP AL,'"' ;AN033; Is the character a quote?
500 JZ PIPEERRSYNJ5 ;AN033; Yes - get out quick - or system crashes
501 CMP AL,labracket ;AN002; Is char for input redirection
502 JZ ABRACKET_TERM ;AN002; yes - end of string
503 CMP AL,rabracket ;AN002; Is char for output redirection
504 JNZ NO_ABRACKET ;AN002; no - not end of string
505
506abracket_term: ;AN002; have end of string by < or >
507 DEC SI ;AN002; back up over symbol
508 MOV AL,BLANK ;AN002; show delimiter as char
509 JMP SHORT GOTRESTR ;AN002; go process it
510
511no_abracket: ;AN002; not at end of string
512 STOSB ; store it into resgroup
513 JMP SHORT SETREOUTSTR
514
515NOOUT:
516 CMP AL,labracket
517 JNZ CHKPIPE
518 mov bx,si ; Save loc of "<"
519 INVOKE SCANOFF
520 CMP AL,rabracket ;AN040; was there no filename?
521 JZ REIN_ERRSET ;AN040; yes - set up error
522 CMP AL,0DH
523 JNZ GOTREIFIL
524
525REIN_ERRSET: ;AN040; set up for error
526 mov byte ptr [di],0dh ; Clobber "<"
527 MOV WORD PTR [RE_INSTR],09H ; Cause an error later
528 JMP SHORT PRESCANEND
529
530GOTREIFIL:
531 PUSH DI
532 MOV DI,OFFSET TranGROUP:RE_INSTR
533 MOV BX,DI
534 PUSH ES
535 PUSH CS
536 POP ES ; store in TRANGROUP
537 JMP SHORT SETREOUTSTR ; Get the input redirection name
538
539CHKPIPE:
540 MOV AH,AL
541 CMP AH,AltPipeChr
542 JZ IsPipe3
543 CMP AH,vbar
544 JNZ CONTPRESCAN
545
546IsPipe3:
547;
548; Only push the echo flag if we are entering the pipe for the first time.
549;
550 CMP PipeFlag,0
551 JNZ NoEchoPush
552 SHL EchoFlag,1 ; push echo state and turn it off
553NoEchoPush:
554 INC [PIPEFLAG]
555 INVOKE SCANOFF
556 CMP AL,0DH
557 JZ PIPEERRSYNJ5
558 CMP AL,AltPipeChr
559 JZ PIPEERRSYNJ5
560 CMP AL,vbar ; Double '|'?
561 JNZ CONTPRESCAN
562
563PIPEERRSYNJ5:
564 PUSH ES
565 POP DS ; DS->RESGROUP
566 JMP PIPEERRSYN
567
568;
569; Trailing :s are allowed on devices. Check to be sure that there is more
570; than just a : in the redir string.
571;
572GOTRESTR:
573 XCHG AH,AL
574 mov al,':'
575 SUB BX,DI ; compute negatinve of number of chars
576 CMP BX,-1 ; is there just a :?
577 JZ NotTrailCol ; yep, don't change
578 CMP BYTE PTR ES:[DI-1],al ; Trailing ':' OK on devices
579 JNZ NOTTRAILCOL
580 DEC DI ; Back up over trailing ':'
581
582NOTTRAILCOL:
583 XOR AL,AL
584 STOSB ; NUL terminate the string
585 POP ES
586 POP DI ; Remember the start
587
588CONTPRESCAN:
589 MOV [DI],AH ; "delete" the redirection string
590 INC DI
591 CMP AH,0DH
592 JZ PRESCANEND
593 INC CL
594 JMP PRESCANLP
595
596PRESCANEND:
597 CMP [PIPEFLAG],0
598 JZ ISNOPIPE
599 MOV DI,OFFSET RESGROUP:PIPESTR
600 MOV [PIPEPTR],DI
601 MOV SI,OFFSET TRANGROUP:COMBUF+2
602 INVOKE SCANOFF
603
604PIPESETLP: ; Transfer the pipe into the resident
605 LODSB ; pipe buffer
606 STOSB
607 CMP AL,0DH
608 JNZ PIPESETLP
609
610ISNOPIPE:
611 MOV [COMBUF+1],CL
612 CMP [PIPEFLAG],0
613 PUSH CS
614 POP ES
615 return
616
617cmd_copy proc near
618
619 MOV SI,OFFSET TRANGROUP:COMBUF+2
620 INVOKE Scanoff ; advance past separators...
621 add si,PathPos
622 mov di,81h
623 xor cx,cx
624
625CmdCopy:
626 lodsb
627 stosb
628 cmp al,0dh
629 jz CopyDone
630 inc cx
631 jmp CmdCopy
632
633CopyDone:
634 mov byte ptr ds:[80h],cl ; Store count
635
636 ret
637cmd_copy endp
638
639
640test_append proc near
641
642 mov BX,offset TRANGROUP:COMBUF ; barry can address
643 mov SI, offset TRANGROUP:IDLEN ; address command name, DS already set
644 mov DX,-1 ; set install check function
645 mov AX,0AE00H
646 int 2FH ; see if loaded
647 cmp AL,00H
648
649 ret
650
651test_append endp
652
653TRANCODE ENDS
654 END
655 \ No newline at end of file
diff --git a/v4.0/src/CMD/COMMAND/TMISC2.ASM b/v4.0/src/CMD/COMMAND/TMISC2.ASM
new file mode 100644
index 0000000..cc30428
--- /dev/null
+++ b/v4.0/src/CMD/COMMAND/TMISC2.ASM
@@ -0,0 +1,487 @@
1 page 80,132
2; SCCSID = @(#)tmisc2.asm 4.3 85/06/25
3; SCCSID = @(#)tmisc2.asm 4.3 85/06/25
4TITLE Part7 COMMAND Transient Routines
5
6; More misc routines
7
8
9.xlist
10.xcref
11 INCLUDE comsw.asm
12 INCLUDE DOSSYM.INC
13 INCLUDE comseg.asm
14 INCLUDE comequ.asm
15 INCLUDE ioctl.inc
16.list
17.cref
18
19
20CODERES SEGMENT PUBLIC BYTE ;AC000;
21CodeRes ENDS
22
23DATARES SEGMENT PUBLIC BYTE ;AC000;
24 EXTRN IFFlag:BYTE
25 EXTRN PIPEFLAG:BYTE
26 EXTRN RE_OUTSTR:BYTE
27 EXTRN RE_OUT_APP:BYTE
28DATARES ENDS
29
30TRANDATA SEGMENT PUBLIC BYTE ;AC000;
31 EXTRN AccDen_PTR:WORD
32 EXTRN Extend_buf_ptr:word ;AN000;
33 EXTRN FULDIR_PTR:WORD
34 EXTRN msg_disp_class:byte ;AN000;
35TRANDATA ENDS
36
37TRANSPACE SEGMENT PUBLIC BYTE ;AC000;
38 EXTRN DESTINFO:BYTE
39 EXTRN DESTISDIR:BYTE
40 EXTRN KPARSE:BYTE ;AC000;
41 EXTRN ONE_CHAR_VAL:BYTE ;AN011;
42 EXTRN PATHCNT:WORD
43 EXTRN PATHPOS:WORD
44 EXTRN PATHSW:WORD
45 EXTRN RE_INSTR:BYTE
46 EXTRN RESSEG:WORD
47 EXTRN SRCBUF:BYTE
48 EXTRN SWITCHAR:BYTE
49
50 IF IBM
51 EXTRN ROM_CALL:BYTE
52 EXTRN ROM_CS:WORD
53 EXTRN ROM_IP:WORD
54 ENDIF
55
56TRANSPACE ENDS
57
58TRANCODE SEGMENT PUBLIC byte
59
60ASSUME CS:TRANGROUP,DS:NOTHING,ES:NOTHING,SS:NOTHING
61
62 EXTRN CERROR:NEAR
63
64 IF IBM
65 EXTRN ROM_EXEC:NEAR
66 EXTRN ROM_SCAN:NEAR
67 ENDIF
68
69 PUBLIC IOSET
70 PUBLIC MOVE_TO_SRCBUF ;AN000;
71 PUBLIC PGETARG
72 PUBLIC SETPATH
73 PUBLIC TESTDOREIN
74 PUBLIC TESTDOREOUT
75
76
77ASSUME DS:TRANGROUP
78
79SETPATH:
80;
81; Get an ASCIZ argument from the unformatted parms
82; DESTISDIR set if pathchars in string
83; DESTINFO set if ? or * in string
84;
85 MOV AX,[PATHCNT] ;AC000; get length of string
86 MOV SI,[PATHPOS] ;AC000; get start of source buffer
87
88GETPATH:
89 MOV [DESTINFO],0
90 MOV [DESTISDIR],0
91 MOV SI,[PATHPOS]
92 MOV CX,[PATHCNT]
93 MOV DX,SI
94 JCXZ PATHDONE
95 PUSH CX
96 PUSH SI
97 INVOKE SWITCH
98 MOV [PATHSW],AX
99 POP BX
100 SUB BX,SI
101 POP CX
102 ADD CX,BX
103 MOV DX,SI
104
105SKIPPATH:
106
107;;;; IF KANJI 3/3/KK
108 MOV [KPARSE],0
109
110SKIPPATH2:
111;;;; ENDIF 3/3/KK
112
113 JCXZ PATHDONE
114 DEC CX
115 LODSB
116
117;;;; IF KANJI 3/3/KK
118 INVOKE TESTKANJ
119 JZ TESTPPSEP
120 DEC CX
121 INC SI
122 INC [KPARSE]
123 JMP SKIPPATH2
124
125TESTPPSEP:
126;;;; ENDIF 3/3/KK
127
128 INVOKE PATHCHRCMP
129 JNZ TESTPMETA
130 INC [DESTISDIR]
131
132TESTPMETA:
133 CMP AL,'?'
134 JNZ TESTPSTAR
135 OR [DESTINFO],2
136
137TESTPSTAR:
138 CMP AL,star
139 JNZ TESTPDELIM
140 OR [DESTINFO],2
141
142TESTPDELIM:
143 INVOKE DELIM
144 JZ PATHDONEDEC
145 CMP AL,[SWITCHAR]
146 JNZ SKIPPATH
147
148PATHDONEDEC:
149 DEC SI
150
151PATHDONE:
152 XOR AL,AL
153 XCHG AL,[SI]
154 INC SI
155 CMP AL,0DH
156 JNZ NOPSTORE
157 MOV [SI],AL ;Don't loose the CR
158
159NOPSTORE:
160 MOV [PATHPOS],SI
161 MOV [PATHCNT],CX
162 return
163
164PGETARG:
165 MOV SI,80H
166 LODSB
167 OR AL,AL
168 retz
169 CALL PSCANOFF
170 CMP AL,13
171 return
172
173PSCANOFF:
174 LODSB
175 INVOKE DELIM
176 JNZ PSCANOFFD
177 CMP AL,';'
178 JNZ PSCANOFF ; ';' is not a delimiter
179
180PSCANOFFD:
181 DEC SI ; Point to first non-delimiter
182 return
183
184IOSET:
185;
186; ALL REGISTERS PRESERVED
187;
188ASSUME DS:NOTHING,ES:NOTHING,SS:NOTHING
189
190 PUSH DS
191 PUSH DX
192 PUSH AX
193 PUSH BX
194 PUSH CX
195 MOV DS,[RESSEG]
196ASSUME DS:RESGROUP
197
198 CMP [PIPEFLAG],0
199 JNZ NOREDIR ; Don't muck up the pipe
200 TEST IFFlag,-1
201 JNZ NoRedir
202 CALL TESTDOREIN
203 CALL TESTDOREOUT
204
205NOREDIR:
206 POP CX
207 POP BX
208 POP AX
209 POP DX
210 POP DS
211ASSUME DS:NOTHING
212 return
213
214TESTDOREIN:
215
216ASSUME DS:RESGROUP
217
218 CMP [RE_INSTR],0
219 retz
220 PUSH DS
221 PUSH CS
222 POP DS
223 MOV DX,OFFSET tranGROUP:RE_INSTR
224 MOV AX,(OPEN SHL 8)
225 MOV BX,AX
226 INT int_command
227 POP DS
228 JC REDIRERR
229 MOV BX,AX
230 MOV AL,0FFH
231;
232; Mega sleaze!! We move the SFN from the new handle spot into the old stdin
233; spot. We invalidate the new JFN we got.
234;
235 XCHG AL,[BX.PDB_JFN_Table]
236 MOV DS:[PDB_JFN_Table],AL
237
238 return
239;
240; We had some kind of error on the redirection. Figure out what the
241; appropriate message should be; BX has the system call that failed
242;
243REDIRERR:
244 PUSH CS
245 POP DS
246 Call TriageError
247;
248; At this point, we have recognized the network-generated access denied error.
249; The correct message is in DX
250;
251 CMP AX,65
252 JZ CERRORJ ;AC000; just issue message returned
253 CMP BH,OPEN
254 JZ OpenError
255;
256; The error was for a create operation. Report the error as a creation error.
257;
258 MOV DX,OFFSET TranGroup:FULDIR_PTR
259
260CERRORJ:
261 JMP CERROR
262;
263; The system call was an OPEN. Report either file not found or path not found.
264;
265
266OpenError:
267 mov msg_disp_class,ext_msg_class ;AN000; set up extended error msg class
268 mov dx,offset TranGroup:Extend_Buf_ptr ;AC000; get extended message pointer
269 mov Extend_Buf_ptr,ax ;AN000; get message number in control block
270 JMP CERROR
271
272TESTDOREOUT:
273
274ASSUME DS:RESGROUP
275
276 CMP [RE_OUTSTR],0
277 JNZ REOUTEXISTS ;AN017; need long jump
278 JMP NOREOUT ;AN017;
279
280REOUTEXISTS:
281 CMP [RE_OUT_APP],0
282 JZ REOUTCRT
283;
284; The output redirection was for append. We open for write and seek to the
285; end.
286;
287 MOV DX,OFFSET RESGROUP:RE_OUTSTR
288 MOV AX,(OPEN SHL 8) OR 2 ;AC011; Open for read/write
289 PUSH AX
290 INT int_command
291 POP BX
292 JC OpenWriteError
293
294 MOV BX,AX
295 MOV AX,IOCTL SHL 8 ;AN035; Get attributes of handle
296 INT int_command ;AN035;
297 TEST DL,devid_ISDEV ;AN035; Is it a device?
298 JNZ SET_REOUT ;AN035; Yes, don't read from it
299
300 MOV AX,(LSEEK SHL 8) OR 2
301 MOV CX,-1 ;AC011; MOVE TO EOF -1
302 MOV DX,CX ;AC011;
303 INT int_command
304 PUSH CS ;AN011; Get transient seg to DS
305 POP DS ;AN011;
306 assume DS:Trangroup ;AN011;
307 MOV AX,(READ SHL 8) ;AN011; Read one byte from the
308 MOV CX,1 ;AN011; file into one_char_val
309 MOV DX,OFFSET Trangroup:ONE_CHAR_VAL;AN011;
310 INT int_command ;AN011;
311 JC OpenWriteError ;AN011; If error, exit
312 cmp ax,cx ;AN017; Did we read 1 byte?
313 jnz reout_0_length ;AN017; No - file must be 0 length
314
315 cmp one_char_val,01ah ;AN011; Was char an eof mark?
316 mov DS,[resseg] ;AN011; Get resident segment back
317 assume DS:Resgroup ;AN011;
318 JNZ SET_REOUT ;AN011; No, just continue
319 MOV AX,(LSEEK SHL 8) OR 1 ;AN011; EOF mark found
320 MOV CX,-1 ;AN011; LSEEK back one byte
321 MOV DX,CX ;AN011;
322 INT int_command ;AN011;
323 JMP SHORT SET_REOUT
324
325reout_0_length: ;AN017; We have a 0 length file
326 mov DS,[resseg] ;AN017; Get resident segment back
327 assume DS:Resgroup ;AN017;
328 MOV AX,(LSEEK SHL 8) ;AN017; Move to beginning of file
329 XOR CX,CX ;AN017; Offset is 0
330 MOV DX,CX ;AN017;
331 INT int_command ;AN017;
332 JMP SHORT SET_REOUT ;AN017; now finish setting up redirection
333
334OpenWriteError:
335 CMP AX,error_access_denied
336 STC ; preserve error
337 JNZ REOUTCRT ;AN017; need long jump
338 JMP REDIRERR ;AN017;
339
340REOUTCRT:
341 MOV DX,OFFSET RESGROUP:RE_OUTSTR
342 XOR CX,CX
343 MOV AH,CREAT
344 PUSH AX
345 INT int_command
346 POP BX
347 JNC NOREDIRERR ;AC011;
348 JMP REDIRERR ;AC011;
349
350NOREDIRERR: ;AN011;
351 MOV BX,AX
352
353SET_REOUT:
354;
355; Mega sleaze!! We move the SFN from the new handle spot into the old stdout
356; spot. We invalidate the new JFN we got.
357;
358 MOV AL,0FFH
359 XCHG AL,[BX.PDB_JFN_Table]
360 MOV DS:[PDB_JFN_Table+1],AL
361
362NOREOUT:
363 return
364
365;
366; Compute length of string (including NUL) in DS:SI into CX. Change no other
367; registers
368;
369Procedure DSTRLEN,NEAR
370
371 SaveReg <AX>
372 XOR CX,CX
373 CLD
374
375DLoop: LODSB
376 INC CX
377 OR AL,AL
378 JNZ DLoop
379 SUB SI,CX
380 RestoreReg <AX>
381 return
382
383EndProc DSTRLEN
384
385Break <Extended error support>
386
387;
388; TriageError will examine the return from a carry-set system call and
389; return the correct error if applicable.
390;
391; Inputs: outputs from a carry-settable system call
392; No system calls may be done in the interrim
393; Outputs: If carry was set on input
394; carry set on output
395; DX contains trangroup offset to printf message
396; else
397; No registers changed
398;
399
400Procedure TriageError,NEAR
401
402 retnc ; no carry => do nothing...
403 PUSHF
404 SaveReg <BX,CX,SI,DI,BP,ES,DS,AX,DX>
405 MOV AH,GetExtendedError
406 INT 21h
407 RestoreReg <CX,BX> ; restore original AX
408 MOV DX,OFFSET TranGroup:AccDen_PTR
409 CMP AX,65 ; network access denied?
410 JZ NoMove ; Yes, return it.
411 MOV AX,BX
412 MOV DX,CX
413
414NoMove:
415 RestoreReg <DS,ES,BP,DI,SI,CX,BX>
416 popf
417 return
418
419EndProc TriageError
420
421PUBLIC Triage_Init
422Triage_Init proc FAR
423 call TriageError
424 ret
425Triage_Init endp
426
427
428; ****************************************************************
429; *
430; * ROUTINE: MOVE_TO_SRCBUF
431; *
432; * FUNCTION: Move ASCIIZ string from DS:SI to SRCBUF. Change
433; * terminating 0 to 0dH. Set PATHCNT to length of
434; * string. Set PATHPOS to start of SRCBUF.
435; *
436; * INPUT: DS:SI points to ASCIIZ string
437; * ES points to TRANGROUP
438; *
439; * OUTPUT: SRCBUF filled in with string terminated by 0dH
440; * PATHCNT set to length of string
441; * PATHPOS set to start of SRCBUF
442; * CX,AX changed
443; *
444; ****************************************************************
445
446assume es:trangroup,ds:nothing ;AN000;
447
448MOVE_TO_SRCBUF PROC NEAR ;AN000;
449
450 push si ;AN000; save si,di
451 push di ;AN000;
452 push cx ;AN000;
453 mov di,offset TRANGROUP:srcbuf ;AN000; set ES:DI to srcbuf
454 xor cx,cx ;AN000; clear cx for counint
455 mov ax,cx ;AN000; clear ax
456 push di ;AN000; save start of srcbuf
457 lodsb ;AN000; get a character from DS:SI
458
459mts_get_chars: ;AN000;
460 cmp al,0 ;AN000; was it a null char?
461 jz mts_end_string ;AN000; yes - exit
462 stosb ;AN000; no - store it in srcbuf
463 inc cx ;AN000; increment length count
464 lodsb ;AN000; get a character from DS:SI
465 jmp short mts_get_chars ;AN000; go check it
466
467mts_end_string: ;AN000; we've reached the end of line
468 mov al,end_of_line_in ;AN000; store 0dH in srcbuf
469 stosb ;AN000;
470 pop di ;AN000; restore start of srcbuf
471
472 push cs ;AN000; set DS to local segment
473 pop ds ;AN000;
474assume ds:trangroup ;AN000;
475 mov [pathcnt],cx ;AN000; set patchcnt to length count
476 mov [pathpos],di ;AN000; set pathpos to start of srcbuf
477 pop cx ;AN000; restore cx,di,si
478 pop di ;AN000;
479 pop si ;AN000;
480
481 RET ;AN000; exit
482
483MOVE_TO_SRCBUF ENDP ;AN000;
484
485TRANCODE ENDS
486 END
487 \ No newline at end of file
diff --git a/v4.0/src/CMD/COMMAND/TPARSE.ASM b/v4.0/src/CMD/COMMAND/TPARSE.ASM
new file mode 100644
index 0000000..9268017
--- /dev/null
+++ b/v4.0/src/CMD/COMMAND/TPARSE.ASM
@@ -0,0 +1,76 @@
1 page 80,132
2; SCCSID = @(#)tparse.asm 4.1 87/04/28
3; SCCSID = @(#)tparse.asm 4.1 87/04/28
4TITLE COMMAND interface to SYSPARSE
5
6.xlist
7.xcref
8 INCLUDE comseg.asm ;AN000;
9.list
10.cref
11
12TRANSPACE SEGMENT PUBLIC BYTE ;AN000;
13
14 CmpxSW equ 0 ;AN000; do not check complex list
15 KeySW equ 0 ;AN000; do not support keywords
16 Val2SW equ 0 ;AN000; do not Support value definition 2
17 IncSW equ 0 ;AN000; do not include psdata.inc
18 QusSW equ 0 ;AN025; do not include quoted string
19 LFEOLSW equ 0 ;AN044; do not use 0ah as line terminator
20
21.xlist
22.xcref
23
24include psdata.inc ;AN000;
25
26.list
27.cref
28
29TRANSPACE ENDS ;AN000;
30
31TRANCODE SEGMENT PUBLIC BYTE ;AN000;
32
33ASSUME CS:TRANGROUP,DS:NOTHING,ES:NOTHING,SS:NOTHING ;AN054;
34
35; ****************************************************************
36; *
37; * ROUTINE: CMD_PARSE
38; *
39; * FUNCTION: Interface for transient COMMAND to invoke
40; * SYSPARSE.
41; *
42; * INPUT: inputs to SYSPARSE
43; *
44; * OUTPUT: outputs from SYSPARSE
45; *
46; ****************************************************************
47
48 public Cmd_parse ;AN000;
49
50.xlist
51.xcref
52 INCLUDE parse.asm ;AN000;
53.list
54.cref
55
56Cmd_parse Proc near ;AN000;
57
58 call sysparse ;AN000;
59
60 ret ;AN000;
61
62Cmd_parse endp ;AN000;
63
64 public Append_parse ;AN010;
65
66Append_parse Proc Far ;AN010;
67
68 call sysparse ;AN010;
69
70 ret ;AN010;
71
72Append_parse endp ;AN010;
73
74trancode ends ;AN000;
75 end ;AN000;
76 \ No newline at end of file
diff --git a/v4.0/src/CMD/COMMAND/TPIPE.ASM b/v4.0/src/CMD/COMMAND/TPIPE.ASM
new file mode 100644
index 0000000..23f8417
--- /dev/null
+++ b/v4.0/src/CMD/COMMAND/TPIPE.ASM
@@ -0,0 +1,660 @@
1 page 80,132
2; SCCSID = @(#)tpipe.asm 1.1 85/05/14
3; SCCSID = @(#)tpipe.asm 1.1 85/05/14
4TITLE PART8 COMMAND Transient routines.
5
6
7 INCLUDE comsw.asm
8.xlist
9.xcref
10 INCLUDE DOSSYM.INC
11 INCLUDE comseg.asm
12 INCLUDE comequ.asm
13.list
14.cref
15
16
17DATARES SEGMENT PUBLIC BYTE ;AC000;
18 EXTRN ECHOFLAG:BYTE
19 EXTRN InitFlag:byte
20 EXTRN INPIPEPTR:WORD
21 EXTRN OUTPIPEPTR:WORD
22 EXTRN PIPE1:BYTE
23 EXTRN PIPE1T:BYTE
24 EXTRN PIPE2:BYTE
25 EXTRN PIPE2T:BYTE
26 EXTRN PIPEFILES:BYTE
27 EXTRN PIPEFLAG:BYTE
28 EXTRN PIPEPTR:WORD
29 EXTRN RESTDIR:BYTE
30 EXTRN SINGLECOM:WORD
31DATARES ENDS
32
33TRANDATA SEGMENT PUBLIC BYTE ;AC000;
34 EXTRN BADDAT_PTR:WORD
35 EXTRN BADTIM_PTR:WORD
36 EXTRN curdat_mo_day:word ;AN000;
37 EXTRN CURDAT_PTR:WORD
38 EXTRN curdat_yr:word ;AN000;
39 EXTRN curtim_hr_min:word ;AN000;
40 EXTRN CURTIM_PTR:WORD
41 EXTRN curtim_sec_hn:word ;AN000;
42 EXTRN eurdat_ptr:word
43 EXTRN japdat_ptr:word
44 EXTRN newdat_format:word ;AN000;
45 EXTRN NEWDAT_PTR:WORD
46 EXTRN NEWTIM_PTR:WORD
47 EXTRN parse_date:byte ;AN000;
48 EXTRN parse_time:byte ;AN000;
49 EXTRN PIPEEMES_PTR:WORD
50 EXTRN promtim_hr_min:word ;AN000;
51 EXTRN promtim_ptr:word ;AN000;
52 EXTRN promtim_sec_hn:word ;AN000;
53 EXTRN STRING_BUF_PTR:WORD ;AC000;
54 EXTRN SYNTMES_PTR:WORD
55 EXTRN usadat_ptr:word
56
57TRANDATA ENDS
58
59TRANSPACE SEGMENT PUBLIC BYTE ;AC000;
60 EXTRN COMBUF:BYTE
61 EXTRN date_day:byte ;AN000;
62 EXTRN date_month:byte ;AN000;
63 EXTRN date_year:word ;AN000;
64 EXTRN INTERNATVARS:BYTE
65 EXTRN RESSEG:WORD
66 EXTRN time_fraction:byte ;AN000;
67 EXTRN time_hour:byte ;AN000;
68 EXTRN time_minutes:byte ;AN000;
69 EXTRN time_seconds:byte ;AN000;
70TRANSPACE ENDS
71
72TRANCODE SEGMENT PUBLIC BYTE
73ASSUME CS:TRANGROUP,DS:NOTHING,ES:NOTHING,SS:NOTHING
74
75 EXTRN CERROR:NEAR
76 EXTRN NOPIPEPROC:NEAR
77 EXTRN STD_PRINTF:NEAR
78 EXTRN TCOMMAND:NEAR
79 EXTRN TESTDOREIN:NEAR
80 EXTRN TESTDOREOUT:NEAR
81 EXTRN TESTKANJ:NEAR ;AN000;3/3/KK
82 EXTRN TSYSGETMSG:NEAR ;AN000;
83
84 PUBLIC CTIME
85 PUBLIC DATE
86 PUBLIC DATINIT
87 PUBLIC PIPEDEL
88 PUBLIC PIPEERRSYN
89 PUBLIC PIPEPROC
90 PUBLIC PIPEPROCSTRT
91 PUBLIC PRINT_TIME
92 PUBLIC SETREST
93 PUBLIC SETREST1
94 PUBLIC SINGLETEST
95
96SINGLETEST:
97 ASSUME DS:NOTHING
98 push ds
99 MOV DS,ResSeg
100 ASSUME DS:ResGroup
101 CMP [SINGLECOM],0
102 JZ TestDone
103 CMP [SINGLECOM],0EFFFH
104TestDone:
105 pop ds
106 return
107
108
109ASSUME DS:TRANGROUP
110SETREST1:
111 MOV AL,1
112SETREST:
113 PUSH DS
114 MOV DS,[RESSEG]
115ASSUME DS:RESGROUP
116 MOV [RESTDIR],AL
117 POP DS
118ASSUME DS:TRANGROUP
119 return
120
121ASSUME DS:RESGROUP
122
123;
124; Note that we need to handle the same thing that RestDir handles: the
125; requirement that we try only once to restore the user's environment after
126; and INT 24 or the like. If the condition that causes the INT 24 does not
127; disappear, we just give up.
128;
129
130PIPEDEL:
131 assume ds:nothing
132 push ds
133 PUSH DX
134 mov ds,ResSeg
135 assume ds:ResGroup
136 mov DX,OFFSET RESGROUP:PIPE1 ; Clean up in case ^C
137 MOV AH,UNLINK
138 INT int_command
139 MOV DX,OFFSET RESGROUP:PIPE2
140 MOV AH,UNLINK
141 INT int_command
142 POP DX
143 call PipeOff
144 mov PipeFiles,0
145 pop ds
146 return
147
148PIPEERRSYN:
149 MOV DX,OFFSET TRANGROUP:SYNTMES_ptr
150 CALL PIPEDEL
151 PUSH CS
152 POP DS
153 JMP CERROR
154PIPEERR:
155 pushf
156 invoke triageError
157 SaveReg <AX,DX> ; Save results from TriageError
158 MOV DX,OFFSET TRANGROUP:PIPEEMES_ptr
159 CALL PIPEDEL
160 PUSH CS
161 POP DS
162 invoke std_eprintf
163 RestoreReg <DX,AX> ; Restore results from TriageError
164 popf
165 cmp ax, 65
166 jnz tcommandj
167 JMP CERROR
168tcommandj:
169 jmp tcommand
170
171PIPEPROCSTRT:
172ASSUME DS:TRANGROUP,ES:TRANGROUP
173 MOV DS,[RESSEG]
174ASSUME DS:RESGROUP
175 INC [PIPEFILES] ; Flag that the pipe files exist
176 MOV AH,Get_Default_Drive ; Get current drive
177 INT int_command
178 ADD AL,capital_A
179 MOV [PIPE2],AL ; Make pipe files in root of def drv
180 MOV BX,OFFSET RESGROUP:PIPE1
181 MOV [BX],AL
182 xor ah,ah ; nul terminate path names
183 mov [Pipe1T],ah
184 mov [Pipe2T],ah
185 MOV DX,BX
186 XOR CX,CX
187 mov ah,CreateTempFile ; the CreateTemp call
188 INT int_command
189 JC PIPEERR ; Couldn't create
190 MOV BX,AX
191 MOV AH,CLOSE ; Don't proliferate handles
192 INT int_command
193
194 MOV DX,OFFSET RESGROUP:PIPE2
195 mov ah,createTempFile ; the CreateTemp call
196 INT int_command
197 JC PIPEERR
198 MOV BX,AX
199 MOV AH,CLOSE
200 INT int_command
201
202 CALL TESTDOREIN ; Set up a redirection if specified
203 MOV SI,[PIPEPTR]
204 CMP [SINGLECOM],-1
205 JNZ NOSINGP
206 MOV [SINGLECOM],0F000H ; Flag single command pipe
207NOSINGP:
208 JMP SHORT FIRSTPIPE
209
210PIPEPROC:
211ASSUME DS:RESGROUP
212 AND [ECHOFLAG],0FEh ; force current echo to be off
213 MOV SI,[PIPEPTR]
214 LODSB
215 CMP AL,AltPipeChr ; Alternate pipe char?
216 JZ IsPipe1 ; Yes
217 CMP AL,vbar
218 jz IsPipe1
219 jmp PIPEEND ; Pipe done
220IsPipe1:
221 MOV DX,[INPIPEPTR] ; Get the input file name
222 MOV AX,(OPEN SHL 8)
223 INT int_command
224PIPEERRJ:
225 jnc no_pipeerr
226 JMP PIPEERR ; Lost the pipe file
227no_pipeerr:
228 MOV BX,AX
229 MOV AL,0FFH
230 XCHG AL,[BX.PDB_JFN_Table]
231 MOV DS:[PDB_JFN_Table],AL ; Redirect
232
233FIRSTPIPE:
234 MOV DI,OFFSET TRANGROUP:COMBUF + 2
235 XOR CX,CX
236 CMP BYTE PTR [SI],0DH ; '|<CR>'
237 JNZ PIPEOK1
238PIPEERRSYNJ:
239 JMP PIPEERRSYN
240PIPEOK1:
241 mov al,vbar
242 CMP BYTE PTR [SI],al ; '||'
243 JZ PIPEERRSYNJ
244 CMP BYTE PTR [SI],AltPipeChr ; '##' or '|#'?
245 JZ PipeErrSynJ ; Yes, Error
246PIPECOMLP:
247 LODSB
248 STOSB
249
250;;;; IF KANJI 3/3/KK
251 CALL TESTKANJ
252 JZ NOTKANJ5
253 MOVSB
254;
255; Added following 2 commands to the fix pipe bug.
256;
257 inc cx ;AN000; 3/3/KK
258 inc cx ;AN000; 3/3/KK
259;
260 JMP PIPECOMLP
261
262NOTKANJ5:
263;;;; ENDIF ; 3/3/KK
264
265 CMP AL,0DH
266 JZ LASTPIPE
267 INC CX
268 CMP AL,AltPipeChr
269 JZ IsPipe2
270 CMP AL,vbar
271 JNZ PIPECOMLP
272IsPipe2:
273 MOV BYTE PTR ES:[DI-1],0DH
274 DEC CX
275 MOV [COMBUF+1],CL
276 DEC SI
277 MOV [PIPEPTR],SI ; On to next pipe element
278 MOV DX,[OUTPIPEPTR]
279 PUSH CX
280 XOR CX,CX
281 MOV AX,(CREAT SHL 8)
282 INT int_command
283 POP CX
284 JC PIPEERRJ ; Lost the file
285 MOV BX,AX
286 MOV AL,0FFH
287 XCHG AL,[BX.PDB_JFN_Table]
288 MOV DS:[PDB_JFN_Table+1],AL
289 XCHG DX,[INPIPEPTR] ; Swap for next element of pipe
290 MOV [OUTPIPEPTR],DX
291 JMP SHORT PIPECOM
292
293LASTPIPE:
294 MOV [COMBUF+1],CL
295 DEC SI
296 MOV [PIPEPTR],SI ; Point at the CR (anything not '|' will do)
297 CALL TESTDOREOUT ; Set up the redirection if specified
298PIPECOM:
299 PUSH CS
300 POP DS
301 JMP NOPIPEPROC ; Process the pipe element
302
303PIPEEND:
304 CALL PIPEDEL
305 CMP [SINGLECOM],0F000H
306 JNZ NOSINGP2
307 MOV [SINGLECOM],-1 ; Make it return
308NOSINGP2:
309 JMP TCOMMAND
310
311ASSUME DS:TRANGROUP,ES:TRANGROUP
312
313; Date and time are set during initialization and use
314; this routines since they need to do a long return
315
316DATINIT PROC FAR
317 mov cs:[resseg],ds ; SetInitFlag needs resseg initialized
318 PUSH ES
319 PUSH DS ; Going to use the previous stack
320 MOV AX,CS ; Set up the appropriate segment registers
321 MOV ES,AX
322 MOV DS,AX
323 invoke TSYSLOADMSG ;AN000; preload messages
324 invoke SETSTDINON ;AN026; turn on critical error on STDIN
325 invoke SETSTDOUTOFF ;AN026; turn off critical error on STDOUT
326 MOV DX,OFFSET TRANGROUP:INTERNATVARS;Set up internat vars
327 MOV AX,INTERNATIONAL SHL 8
328 INT 21H
329 MOV WORD PTR DS:[81H],13 ; Want to prompt for date during initialization
330 MOV [COMBUF],COMBUFLEN ; Init COMBUF
331 MOV WORD PTR [COMBUF+1],0D01H
332 CALL DATE
333 CALL CTIME
334 POP DS
335 POP ES
336 RET
337DATINIT ENDP
338
339; DATE - Gets and sets the time
340
341
342 break Date
343
344
345; ****************************************************************
346; *
347; * ROUTINE: DATE - Set system date
348; *
349; * FUNCTION: If a date is specified, set the system date,
350; * otherwise display the current system date and
351; * prompt the user for a new date. If an invalid
352; * date is specified, issue an error message and
353; * prompt for a new date. If the user enters
354; * nothing when prompted for a date, terminate.
355; *
356; * INPUT: command line at offset 81H
357; *
358; * OUTPUT: none
359; *
360; ****************************************************************
361
362assume ds:trangroup,es:trangroup
363
364DATE:
365 MOV SI,81H ; Accepting argument for date inline
366 mov di,offset trangroup:parse_date ;AN000; Get adderss of PARSE_DATE
367 xor cx,cx ;AN000; clear counter for positionals
368 xor dx,dx ;AN000;
369 invoke cmd_parse ;AC000; call parser
370 cmp ax,end_of_line ;AC000; are we at end of line?
371 JZ PRMTDAT ;AC000; yes - go ask for date
372 cmp ax,result_no_error ;AN000; did we have an error?
373 jne daterr ;AN000; yes - go issue message
374 JMP COMDAT ;AC000; we have a date
375
376PRMTDAT:
377 ; Print "Current date is
378
379 invoke GetDate ;AN000; get date for output
380 xchg dh,dl ;AN000; switch month & day
381 mov CurDat_yr,cx ;AC000; put year into message control block
382 mov CurDat_mo_day,dx ;AC000; put month and day into message control block
383 mov dx,offset trangroup:CurDat_ptr ;AC000; set up message for output
384 invoke std_printf
385;AD061; mov CurDat_yr,0 ;AC000; reset year, month and day
386;AD061; mov CurDat_mo_day,0 ;AC000; pointers in control block
387
388GET_NEW_DATE: ;AN000;
389 call getdat ;AC000; prompt user for date
390 cmp ax,end_of_line ;AC000; are we at end of line?
391 jz date_end ;AC000; yes - exit
392 cmp ax,result_no_error ;AN000; did we have an error?
393 jne daterr ;AN000; yes - go issue message
394COMDAT:
395 mov cx,date_year ;AC000; get parts of date in
396 mov dh,date_month ;AC000; cx and dx for set
397 mov dl,date_day ;AC000; date function call.
398 push cx ;AC000; save date
399 push dx ;AC000;
400 mov cx,1 ;AC000; set 1 positional entered
401 xor dx,dx ;AN029;
402 invoke cmd_parse ;AN029; call parser
403 cmp al,end_of_line ;AN029; Are we at end of line?
404 pop dx ;AC000; retrieve date
405 pop cx ;AC000;
406 jnz daterr ;AC000; extra stuff on line - try again
407 MOV AH,SET_DATE ;yes - set date
408 INT int_command
409 OR AL,AL
410 JNZ DATERR
411date_end:
412 ret
413
414DATERR:
415 invoke crlf2 ;AN028; print out a blank line
416 MOV DX,OFFSET TRANGROUP:BADDAT_ptr
417 invoke std_printf
418 JMP GET_NEW_DATE ;AC000; get date again
419
420
421; TIME gets and sets the time
422
423 break Time
424
425; ****************************************************************
426; *
427; * ROUTINE: TIME - Set system time
428; *
429; * FUNCTION: If a time is specified, set the system time,
430; * otherwise display the current system time and
431; * prompt the user for a new time. If an invalid
432; * time is specified, issue an error message and
433; * prompt for a new time. If the user enters
434; * nothing when prompted for a time, terminate.
435; *
436; * INPUT: command line at offset 81H
437; *
438; * OUTPUT: none
439; *
440; ****************************************************************
441
442assume ds:trangroup,es:trangroup
443
444CTIME:
445 MOV SI,81H ; Accepting argument for time inline
446 mov di,offset trangroup:parse_time ;AN000; Get adderss of PARSE_time
447 xor cx,cx ;AN000; clear counter for positionals
448 xor dx,dx ;AN000;
449 invoke cmd_parse ;AC000; call parser
450 cmp ax,end_of_line ;AC000; are we at end of line?
451 JZ PRMTTIM ;AC000; yes - prompt for time
452 cmp ax,result_no_error ;AN000; did we have an error?
453 jne timerr ;AN000; yes - go issue message
454 JMP COMTIM ;AC000; we have a time
455
456PRMTTIM:
457 ;Printf "Current time is ... "
458
459 MOV AH,GET_TIME ;AC000; get the current time
460 INT int_command ;AC000; Get time in CX:DX
461 xchg ch,cl ;AN000; switch hours & minutes
462 xchg dh,dl ;AN000; switch seconds & hundredths
463 mov CurTim_hr_min,cx ;AC000; put hours and minutes into message subst block
464 mov CurTim_sec_hn,dx ;AC000; put seconds and hundredths into message subst block
465 mov dx,offset trangroup:CurTim_ptr ;AC000; set up message for output
466 invoke std_printf
467;AD061; mov CurTim_hr_min,0 ;AC000; reset hour, minutes, seconds, and hundredths
468;AD061; mov CurTim_sec_hn,0 ;AC000; pointers in control block
469
470GET_NEW_TIME:
471 call gettim ;AC000;
472 cmp ax,end_of_line ;AC000; are we at end of line?
473 jz time_end ;AC000;
474 cmp ax,result_no_error ;AN000; did we have an error?
475 jne timerr ;AN000; yes - go issue message
476
477COMTIM:
478 mov ch,time_hour ;AC000; get parts of time in
479 mov cl,time_minutes ;AC000; cx and dx for set
480 mov dh,time_seconds ;AC000; time function call
481 mov dl,time_fraction ;AC000;
482 push cx ;AC000; save time
483 push dx ;AC000;
484 mov cx,1 ;AC000; set 1 positional parm entered
485 xor dx,dx ;AN029;
486 invoke cmd_parse ;AN029; call parser
487 cmp al,end_of_line ;AN029; Are we at end of line?
488 pop dx ;AC000; retieve time
489 pop cx ;AC000;
490 jnz timerr ;AC000; extra stuff on line - try again
491
492SAVTIM:
493 MOV AH,SET_TIME
494 INT int_command
495 OR AL,AL
496 JNZ TIMERR ;AC000; if an error occured, try again
497
498TIME_END:
499
500 ret
501
502TIMERR:
503 invoke crlf2 ;AN028; print out a blank line
504 MOV DX,OFFSET TRANGROUP:BADTIM_ptr
505 invoke std_printf ; Print error message
506 JMP GET_NEW_TIME ;AC000; Try again
507
508
509;
510; Set the special flag in the INIT flag to the value in CX.
511;
512SetInitFlag:
513 mov ds,[RESSEG]
514assume ds:resgroup
515 and InitFlag,NOT initSpecial
516 or InitFlag,cL
517 push cs
518 pop ds
519 return
520
521Public PipeOff
522PipeOff:
523 ASSUME DS:NOTHING,ES:NOTHING
524 SaveReg <DS,AX>
525 MOV DS,ResSeg
526 ASSUME DS:RESGroup
527 XOR AL,AL
528 XCHG PipeFlag,AL
529 OR AL,AL
530 JZ PipeOffDone
531 SHR EchoFlag,1
532PipeOffDone:
533 RestoreReg <AX,DS>
534 return
535
536
537PRINT_TIME:
538
539 MOV AH,GET_TIME
540 INT int_command ; Get time in CX:DX
541
542 PUSH ES
543 PUSH CS
544 POP ES
545 xchg ch,cl ;AN000; switch hours & minutes
546 xchg dh,dl ;AN000; switch seconds & hundredths
547 mov promTim_hr_min,cx ;AC000; put hours and minutes into message subst block
548 mov promTim_sec_hn,dx ;AC000; put seconds and hundredths into message subst block
549 mov dx,offset trangroup:promTim_ptr ;AC000; set up message for output
550 invoke std_printf
551;AD061; mov promTim_hr_min,0 ;AC000; reset hour, minutes, seconds, and hundredths
552;AD061; mov promTim_sec_hn,0 ;AC000; pointers in control block
553
554 POP ES
555 return
556
557
558; ****************************************************************
559; *
560; * ROUTINE: GETDAT - Prompt user for date
561; *
562; * FUNCTION: Gets the date format from the COUNTRY DEPENDENT
563; * INFORMATION and issues the "Enter new date"
564; * message with the proper date format. COMBUF
565; * is reset to get a date from the command line.
566; * The PARSE_DATE blocks are then reset and the
567; * PARSE function call is issued.
568; *
569; * INPUT: NONE
570; *
571; * OUTPUT: COMBUF
572; * PARSER RETURN CODES
573; *
574; ****************************************************************
575
576
577GETDAT proc near ;AC000;
578
579 mov ax,(International SHL 8) ; Determine what format the date
580 mov dx,5ch ; should be entered in and
581 int int_command ; print a message describing it
582 mov si,dx
583 lodsw
584 mov dx,usadat_ptr ;AC000; get mm-dd-yy
585 dec ax
586 js printformat
587 mov dx,eurdat_ptr ;AC000; get dd-mm-yy
588 jz printformat
589 mov dx,japdat_ptr ;AC000; get yy-mm-dd
590printformat:
591 mov ax,dx ;AN000; get message number of format
592 mov dh,util_msg_class ;AN000; this is a utility message
593 call Tsysgetmsg ;AN000; get the address of the message
594 mov newdat_format,si ;AN000; put the address in subst block
595 MOV DX,OFFSET TRANGROUP:NEWDAT_ptr ;AC000; get address of message to print
596 invoke std_printf
597 mov newdat_format,no_subst ;AN000; reset subst block
598
599 MOV AH,STD_CON_STRING_INPUT
600 MOV DX,OFFSET TRANGROUP:COMBUF
601 mov cx,initSpecial ; Set bit in InitFlag that indicates
602 call SetInitFlag ; prompting for date.
603 INT int_command ; Get input line
604 xor cx,cx ; Reset bit in InitFlag that indicates
605 call SetInitFlag ; prompting for date.
606 invoke CRLF2
607 MOV SI,OFFSET TRANGROUP:COMBUF+2
608 mov di,offset trangroup:parse_date ;AN000; Get adderss of PARSE_DATE
609 xor cx,cx ;AN000; clear counter for positionals
610 xor dx,dx ;AN000;
611 invoke cmd_parse ;AC000; call parser
612
613 ret
614
615GETDAT endp ;AC000;
616
617
618; ****************************************************************
619; *
620; * ROUTINE: GETTIME - Prompt user for time
621; *
622; * FUNCTION: Gets the time format from the COUNTRY DEPENDENT
623; * INFORMATION and issues the "Enter new time"
624; * message. COMBUF is reset to get a time from the
625; * command line. The PARSE_TIME blocks are then
626; * reset and the PARSE function call is issued.
627; *
628; * INPUT: NONE
629; *
630; * OUTPUT: COMBUF
631; * PARSER RETURN CODES
632; *
633; ****************************************************************
634
635
636GETTIM proc near ;AC000;
637
638 XOR CX,CX ; Initialize hours and minutes to zero
639 MOV DX,OFFSET TRANGROUP:NEWTIM_ptr
640 invoke std_printf
641 MOV AH,STD_CON_STRING_INPUT
642 MOV DX,OFFSET TRANGROUP:COMBUF
643 mov cx,initSpecial ; Set bit in InitFlag that indicates
644 call SetInitFlag ; prompting for time.
645 INT int_command ; Get input line
646 xor cx,cx ; Reset bit in InitFlag that indicates
647 call SetInitFlag ; prompting for time.
648 invoke CRLF2
649 MOV SI,OFFSET TRANGROUP:COMBUF+2
650 mov di,offset trangroup:parse_time ;AN000; Get adderss of PARSE_TIME
651 xor cx,cx ;AN000; clear counter for positionals
652 xor dx,dx ;AN000;
653 invoke cmd_parse ;AC000; call parser
654
655 ret
656
657GETTIM endp ;AC000;
658
659TRANCODE ENDS
660 END
diff --git a/v4.0/src/CMD/COMMAND/TPRINTF.ASM b/v4.0/src/CMD/COMMAND/TPRINTF.ASM
new file mode 100644
index 0000000..c502f83
--- /dev/null
+++ b/v4.0/src/CMD/COMMAND/TPRINTF.ASM
@@ -0,0 +1,365 @@
1 page 80,132
2; SCCSID = @(#)tprintf.asm 4.3 85/07/02
3; SCCSID = @(#)tprintf.asm 4.3 85/07/02
4TITLE COMMAND Transient Printf routine
5
6;****************************************************************
7;*
8;* ROUTINE: STD_PRINTF/STD_EPRINTF
9;*
10;* FUNCTION: Set up to print out a message using SYSDISPMSG.
11;* Set up substitutions if utility message. Make
12;* sure any changes to message variables in TDATA
13;* are reset to avoid reloading the transient.
14;*
15;* INPUT: Msg_Disp_Class - set to message class
16;* Msg_Cont_Flag - set to control flags
17;* DS points to transient segment
18;*
19;* if utility message:
20;* DX points to a block with message number
21;* (word), number of substitutions (byte),
22;* followed by substitution list if there
23;* are substitutions. If substitutions
24;* are not in transient segment they must
25;* be set.
26;* else
27;* AX set to message number
28;*
29;* OUTPUT: none
30;*
31;****************************************************************
32
33.xlist
34.xcref
35 INCLUDE comsw.asm ;AC000;
36 INCLUDE DOSSYM.INC
37 INCLUDE comseg.asm
38 INCLUDE comequ.asm ;AN000;
39 INCLUDE SYSMSG.INC ;AN000;
40.list
41.cref
42
43datares segment public
44 extrn pipeflag:byte
45datares ends
46
47TRANDATA SEGMENT PUBLIC BYTE ;AC000;
48 EXTRN extend_buf_off:word ;AN000;
49 EXTRN Extend_Buf_ptr:word ;AN000;
50 EXTRN Extend_Buf_seg:word ;AN000;
51 EXTRN Msg_Cont_Flag:byte ;AN000;
52 EXTRN Msg_disp_Class:byte ;AN000;
53 EXTRN pipeemes_ptr:word
54TRANDATA ENDS
55
56TRANSPACE SEGMENT PUBLIC BYTE ;AC000;
57 EXTRN msg_flag:byte ;AN022;
58 EXTRN print_err_flag:word ;AN000;
59 EXTRN RESSEG:WORD
60 EXTRN String_ptr_2:word ;AC000;
61 EXTRN Subst_buffer:byte ;AN061;
62;AD061; EXTRN String_ptr_2_sb:word ;AN000;
63
64 ; include data area for message services
65
66 MSG_UTILNAME <COMMAND> ;AN000; define utility name
67
68 MSG_SERVICES <MSGDATA> ;AN000;
69
70PRINTF_HANDLE DW ? ;AC000;
71
72TRANSPACE ENDS ;AC000;
73
74TRANCODE SEGMENT PUBLIC BYTE ;AC000;
75
76 EXTRN cerror:near
77 EXTRN crlf2:near
78 EXTRN tcommand:near ;AN026;
79
80ASSUME CS:TRANGROUP,DS:TRANGROUP,ES:NOTHING,SS:NOTHING ;AC000;
81
82 PUBLIC SETSTDINOFF ;AN026;
83 PUBLIC SETSTDINON ;AN026;
84 PUBLIC SETSTDOUTOFF ;AN026;
85 PUBLIC SETSTDOUTON ;AN026;
86 PUBLIC TSYSGETMSG ;AN000;
87 PUBLIC TSYSLOADMSG ;AN000;
88
89PUBLIC Printf_Init
90printf_init proc far
91 call std_printf
92 ret
93printf_init endp
94
95Public Printf_Crlf
96PRINTF_CRLF:
97 CALL STD_PRINTF
98 CALL CRLF2
99 RET
100
101PUBLIC Std_EPrintf
102STD_EPRINTF:
103 mov Printf_Handle,2 ;AC000;Print to STDERR
104 jmp short NEW_PRINTF ;AC000;
105PUBLIC Std_Printf
106STD_PRINTF:
107 mov Printf_Handle,1 ;AC000;Print to STDOUT
108
109NEW_PRINTF:
110 push ax ;AN000;save registers
111 push bx ;AN000;
112 push cx ;AN000;
113 push es ;AN000;get local ES
114 push ds ;AN000;
115 pop es ;AN000;
116 push di ;AN000;
117 push si ;AN000;
118 push dx ;AN000;
119 assume es:trangroup ;AN000;
120;AD061; mov string_ptr_2_sb,0 ;AN000;initialize
121 mov print_err_flag,0 ;AN000;
122
123UTILITY_SETUP:
124 mov si,dx ;AN000;Get offset of message number
125 lodsw ;AN000;load message number
126 push ax ;AN000;save it
127 lodsb ;AN000;get number of substitutions
128 mov cl,al ;AN000;set up CX as # of subst
129 xor ch,ch ;AN000; SI now points to subst list
130 pop ax ;AN000;get message number back
131 cmp cx,0 ;AN000;Any substitutions?
132 jz READY_TO_PRINT ;AN000;No - continue
133
134;AD061; add dx,Ptr_Seg_Pos ;AN000;Point to position of first segment
135;AD061; push cx ;AN000;save substitution count
136
137;AD061;SET_SUBST:
138;AD061; mov bx,dx ;AN000;get dx into base register
139;AD061; cmp word ptr [bx],0 ;AN000;has segment been set?
140;AD061; jnz SUBST_SEG_SET ;AN000;if not 0, don't replace it
141;AD061; test word ptr [bx+3],date_type ;AN000;if date or time - don't set segment
142;AD061; jnz subst_seg_set ;AN000;yes - skip it
143;AD061; mov word ptr [bx],cs ;AN000;put segment of subst parm in list
144
145;AD061;SUBST_SEG_SET:
146;AD061; add dx,Parm_Block_Size ;AN000;point to position of next segment
147;AD061; loop SET_SUBST ;AN000;keep replacing until complete
148;AD061; pop cx ;AN000;
149
150;AD061;NO_REPLACEMENT:
151;AD061; mov bx,parm_off_pos [si] ;AN000;get subst offset
152;AD061; cmp bx,offset trangroup:string_ptr_2 ;AN000;this is used for double indirection
153;AD061; jnz ready_to_print ;AN000;we already have address
154;AD061; mov dx,string_ptr_2 ;AN000;get address in string_ptr_2
155;AD061; mov parm_off_pos [si],dx ;AN000;put proper address in table
156;AD061; mov string_ptr_2_sb,si ;AN000;save block changed
157
158 mov di,offset trangroup:subst_buffer;AN061; Get address of message subst buffer
159 push di ;AN061; save it
160 push cx ;AN061; save number of subst
161
162MOVE_SUBST:
163 push cx ;AN061;save number of subst
164 mov bx,si ;AN061;save start of sublist
165 mov cx,parm_block_size ;AN061;get size of sublist
166 rep movsb ;AN061;move sublist
167 test byte ptr [bx.$M_S_FLAG],date_type ;AN061;are we doing date/time?
168 jz move_subst_cont ;AN061;no - no need to reset
169 mov word ptr [bx.$M_S_VALUE],0 ;AN061;reset original date or time to 0
170 mov word ptr [bx.$M_S_VALUE+2],0 ;AN061;
171
172MOVE_SUBST_CONT: ;AN061;
173 pop cx ;AN061;get number of subst back
174 loop move_subst ;AN061;move cx sublists
175
176 pop cx ;AN061;get number of subst
177 push ax ;AN061;save message number
178 cmp Msg_Disp_Class,Util_Msg_Class ;AN061;Is this a utility message
179 jz CHECK_FIX ;AN061;YES - go see if substitutions
180 mov msg_flag,ext_msg_class ;AN061;set message flag
181 mov di,offset trangroup:extend_buf_ptr ;AN061; Get address of extended message block
182 xor ax,ax ;AN061;clear ax register
183 stosw ;AN061;clear out message number
184 stosb ;AN061;clear out subst count
185
186CHECK_FIX: ;AN061;
187 pop ax ;AN061;get message number back
188 pop di ;AN061;get start of sublists
189 mov si,di ;AN061;get into SI for msgserv
190 mov bx,si ;AN061;get into BX for addressing
191 push cx ;AN061;save number of subst
192
193SET_SUBST: ;AN061;store the segment of the subst
194 cmp word ptr [bx.$M_S_VALUE+2],0 ;AN061;was it set already?
195 jnz subst_seg_set ;AN061;if not 0, don't replace it
196 test byte ptr [bx.$M_S_FLAG],date_type ;AN061;don't replace if date or time
197 jnz subst_seg_set ;AN061;yes - skip it
198 mov word ptr [bx.$M_S_VALUE+2],cs ;AN061;set segment value
199
200SUBST_SEG_SET: ;AN061;
201 add bx,parm_block_size ;AN061;go to next sublist
202 loop set_subst ;AN061;loop CX times
203 pop cx ;AN061;get number of subst back
204
205 mov bx,si ;AN061;get start of sublist to BX
206 cmp word ptr [bx.$M_S_VALUE],offset trangroup:string_ptr_2 ;AN061;are we using double indirection?
207 jnz ready_to_print ;AN061;no - we already have address
208 mov dx,string_ptr_2 ;AN061;get address in string_ptr_2
209 mov word ptr [bx.$M_S_VALUE],dx ;AN061;put it into the subst block
210
211READY_TO_PRINT:
212 mov bx,Printf_Handle ;AN000;get print handle
213 mov dl,Msg_Cont_Flag ;AN000;set up control flag
214 mov dh,Msg_Disp_Class ;AN000;set up display class
215 mov Msg_Cont_Flag,No_Cont_Flag ;AN061;reset flags to avoid
216 mov Msg_Disp_Class,Util_Msg_Class ;AN061; transient reload
217
218;AD061; push bx ;AN026; save registers
219;AD061; push cx ;AN026;
220;AD061; push dx ;AN026;
221;AD061; push si ;AN026;
222;AD061; push di ;AN026;
223 push ds ;AN026;
224 push es ;AN026;
225
226
227 call SYSDISPMSG ;AN000;call Rod
228
229 pop es ;AN026; restore registers
230 pop ds ;AN026;
231;AD061; pop di ;AN026;
232;AD061; pop si ;AN026;
233;AD061; pop dx ;AN026;
234;AD061; pop cx ;AN026;
235;AD061; pop bx ;AN026;
236
237 jnc Print_success ;AN000; everything went okay
238 mov print_err_flag,ax ;AN000;
239
240print_success:
241;AD061; cmp Msg_Disp_Class,Util_Msg_Class ;AN000;Is this a utility message
242;AD061; jz CHECK_FIX ;AN000;YES - go see if substitutions
243;AD061; mov msg_flag,ext_msg_class ;AN022;set message flag
244;AD061; mov di,offset trangroup:extend_buf_ptr ;AN000; Get address of extended message block
245;AD061; xor ax,ax ;AN000;clear ax register
246;AD061; stosw ;AN000;clear out message number
247;AD061; stosb ;AN000;clear out subst count
248
249;AD061; CHECK_FIX:
250;AD061; pop dx ;AN000;restore dx
251;AD061; cmp cx,0 ;AN000;Any substitutions?
252;AD061; jz NO_FIXUP ;AN000;No - leave
253
254;AD061; mov si,dx ;AN000;Reset changes so transient won't reload
255;AD061; add si,Ptr_Seg_Pos ;AN000;Point to position of first segment
256
257;AD061;FIX_SUBST:
258;AD061; mov word ptr [si],0 ;AN000;reset segment to 0
259;AD061; add si,Parm_Block_Size ;AN000;point to position of next segment
260;AD061; loop FIX_SUBST ;AN000;keep replacing until complete
261;AD061; cmp string_ptr_2_sb,no_subst ;AN000;was double indirection used?
262;AD061; jz no_fixup ;AN000;no - we're finished
263;AD061; mov si,string_ptr_2_sb ;AN000;get offset changed
264;AD061; mov parm_off_pos [si],offset trangroup:string_ptr_2 ;AN000; set address back to string_ptr_2
265
266;AD061;NO_FIXUP:
267;AD061; mov Msg_Cont_Flag,No_Cont_Flag ;AN000;reset flags to avoid
268;AD061; mov Msg_Disp_Class,Util_Msg_Class ;AN000; transient reload
269 pop dx ;AN061;restore dx
270 pop si ;AN000;restore registers
271 pop di ;AN000;
272 pop es ;AN000;restore registers
273 pop cx ;AN000;
274 pop bx ;AN000;
275 pop ax ;AN000;
276 cmp print_err_flag,0 ;AN000; if an error occurred - handle it
277 jnz print_err ;AN000;
278
279 ret ;AC000;
280
281print_err:
282 push cs
283 pop es
284 cmp Printf_Handle,2 ;AN026;Print to STDERR?
285 jnz not_stderr ;AN026;no - continue
286 jmp tcommand ;AN026;Yes - hopless - just exit
287
288not_stderr:
289 mov ax,print_err_flag ;AN026;get extended error number back
290 mov es,[resseg] ; No, set up for error, load the
291assume es:resgroup ; right error msg, and jmp to cerror.
292 test PipeFlag,-1
293 jz go_to_error
294 invoke PipeOff
295 mov dx,offset trangroup:pipeemes_ptr
296 jmp print_err_exit ;AC000;
297
298go_to_error:
299 mov msg_disp_class,ext_msg_class ;AN000; set up extended error msg class
300 mov dx,offset TranGroup:Extend_Buf_ptr ;AC000; get extended message pointer
301 mov Extend_Buf_ptr,ax ;AN000; get message number in control block
302
303PRINT_ERR_EXIT: ;AC000;
304 push cs
305 pop es
306 JMP CERROR
307
308;****************************************************************
309;*
310;* ROUTINE: TSYSLOADMSG
311;*
312;* FUNCTION: Interface to call SYSLOADMSG to avoid duplicate
313;* names since these routines are also used in the
314;* resident.
315;*
316;* INPUT: Inputs to SYSLOADMSG
317;*
318;* OUTPUT: Outputs from SYSLOADMSG
319;*
320;****************************************************************
321
322
323TSYSLOADMSG PROC NEAR ;AN000;
324
325 push bx ;AN000;
326 call sysloadmsg ;AN000; call routine
327 pop bx ;AN000;
328 ret ;AN000; exit
329
330TSYSLOADMSG ENDP ;AN000;
331
332;****************************************************************
333;*
334;* ROUTINE: TSYSGETMSG
335;*
336;* FUNCTION: Interface to call SYSGETMSG to avoid duplicate
337;* names since these routines are also used in the
338;* resident.
339;*
340;* INPUT: Inputs to SYSGETMSG
341;*
342;* OUTPUT: Outputs from SYSGETMSG
343;*
344;****************************************************************
345
346
347TSYSGETMSG PROC NEAR ;AN000;
348
349 push cx ;AN000;
350 call sysgetmsg ;AN000; call routine
351 pop cx ;AN000;
352 ret ;AN000; exit
353
354TSYSGETMSG ENDP ;AN000;
355
356MSG_SERVICES <COMT,NOVERCHECKmsg,NEARmsg,LOADmsg,NOCHECKSTDIN,NOCHECKSTDOUT,GETmsg> ;AC026; The message services
357MSG_SERVICES <COMT,NEARmsg,SETSTDIO,DISPLAYmsg,CHARmsg,NUMmsg,TIMEmsg,DATEmsg> ;AC026; The message services
358
359PRINTF_LAST LABEL WORD
360
361include msgdcl.inc
362
363
364TRANCODE ENDS
365 END
diff --git a/v4.0/src/CMD/COMMAND/TRANMSG.ASM b/v4.0/src/CMD/COMMAND/TRANMSG.ASM
new file mode 100644
index 0000000..38b04ba
--- /dev/null
+++ b/v4.0/src/CMD/COMMAND/TRANMSG.ASM
@@ -0,0 +1,671 @@
1
2;****************************************************
3;* TRANSIENT MESSAGE POINTERS & SUBSTITUTION BLOCKS *
4;****************************************************
5
6msg_disp_class db Util_msg_class
7msg_cont_flag db No_cont_flag
8
9; extended error string output
10;
11Extend_Buf_ptr dw 0 ;AN000;set to no message
12Extend_Buf_sub db 0 ;AN000;set to no substitutions
13 db parm_block_size ;AN000;size of sublist
14 db 0 ;AN000;reserved
15Extend_Buf_off dw OFFSET TranGroup:String_ptr_2 ;AN000;offset of arg
16Extend_Buf_seg dw 0 ;AN000;segment of arg
17 db 0 ;AN000;first subst
18 db Char_field_ASCIIZ ;AN000;character string
19 db 128 ;AN000;maximum width
20 db 0 ;AN000;minimum width
21 db blank ;AN000;pad character
22
23; "Duplicate file name or file not found"
24;
25Renerr_Ptr dw 1002 ;AN000;message number
26 db no_subst ;AN000;number of subst
27
28; "Invalid path or file name"
29;
30BadCPMes_Ptr dw 1003 ;AN000;message number
31 db no_subst ;AN000;number of subst
32
33; "Insufficient disk space"
34;
35NoSpace_Ptr dw 1004 ;AN000;message number
36 db no_subst ;AN000;number of subst
37
38; "Out of environment space"
39;
40EnvErr_Ptr dw 1007 ;AN000;message number
41 db no_subst ;AN000;number of subst
42
43; "File creation error"
44;
45FulDir_Ptr dw 1008 ;AN000;message number
46 db no_subst ;AN000;number of subst
47
48; "Batch file missing",13,10
49;
50BadBat_Ptr dw 1009 ;AN000;message number
51 db no_subst ;AN000;number of subst
52
53; "Insert disk with batch file",13,10
54;
55NeedBat_Ptr dw 1010 ;AN000;message number
56 db no_subst ;AN000;number of subst
57
58; "Bad command or file name",13,10
59;
60BadNam_Ptr dw 1011 ;AN000;message number
61 db no_subst ;AN000;number of subst
62
63
64; "Access denied",13,10
65;
66AccDen_Ptr dw 1014 ;AN000;message number
67 db no_subst ;AN000;number of subst
68
69; "File cannot be copied onto itself",13,10
70;
71OverWr_Ptr dw 1015 ;AN000;message number
72 db no_subst ;AN000;number of subst
73
74; "Content of destination lost before copy",13,10
75;
76LostErr_Ptr dw 1016 ;AN000;message number
77 db no_subst ;AN000;number of subst
78
79; "Invalid filename or file not found",13,10
80;
81InOrNot_Ptr dw 1017 ;AN000;message number
82 db no_subst ;AN000;number of subst
83
84; "%1 File(s) copied",13,10
85;
86Copied_Ptr dw 1018 ;AN000;message number
87 db 1 ;AN000;number of subst
88 db parm_block_size ;AN000;size of sublist
89 db 0 ;AN000;reserved
90 dw OFFSET TranGroup:Copy_num ;AN000;offset of arg
91 dw 0 ;AN000;segment of arg
92 db 1 ;AN000;first subst
93 db Right_Align+Unsgn_Bin_Word ;AN000;binary to decimal
94 db 9 ;AN000;maximum width
95 db 9 ;AN000;minimum width
96 db blank ;AN000;pad character
97
98; "%1 File(s) "
99;
100DirMes_Ptr dw 1019 ;AN000;message number
101 db 1 ;AN000;number of subst
102 db parm_block_size ;AN000;size of sublist
103 db 0 ;AN000;reserved
104 dw OFFSET TranGroup:Dir_num ;AN000;offset of arg
105 dw 0 ;AN000;segment of arg
106 db 1 ;AN000;first subst
107 db Right_Align+Unsgn_Bin_Word ;AN000;binary to decimal
108 db 9 ;AN000;maximum width
109 db 9 ;AN000;minimum width
110 db blank ;AN000;pad character
111
112; "%1 bytes free",13,10
113;
114BytMes_Ptr dw 1020 ;AN000;message number
115 db 1 ;AN000;number of subst
116 db parm_block_size ;AN000;size of sublist
117 db 0 ;AN000;reserved
118 dw OFFSET TranGroup:Bytes_Free ;AN000;offset of arg
119 dw 0 ;AN000;segment of arg
120 db 1 ;AN000;first subst
121 db Right_Align+Unsgn_Bin_DWord ;AN000;long binary to decimal
122 db 10 ;AN000;maximum width
123 db 10 ;AN000;minimum width
124 db blank ;AN000;pad character
125
126; "Invalid drive specification",13,10
127;
128BadDrv_Ptr dw 1021 ;AN000;message number
129 db no_subst ;AN000;number of subst
130
131
132; "Code page %1 not prepared for system",13,10
133;
134CP_not_set_Ptr dw 1022 ;AN000;message number
135 db 1 ;AN000;number of subst
136 db parm_block_size ;AN000;size of sublist
137 db 0 ;AN000;reserved
138 dw OFFSET TranGroup:System_cpage ;AN000;offset of arg
139 dw 0 ;AN000;segment of arg
140 db 1 ;AN000;first subst
141 db Right_Align+Unsgn_Bin_Word ;AN000;binary to decimal
142 db 5 ;AN000;maximum width
143 db 1 ;AN000;minimum width
144 db blank ;AN000;pad character
145
146; "Code page %1 not prepared for all devices",13,10
147;
148CP_not_all_Ptr dw 1023 ;AN000;message number
149 db 1 ;AN000;number of subst
150 db parm_block_size ;AN000;size of sublist
151 db 0 ;AN000;reserved
152 dw OFFSET TranGroup:System_cpage ;AN000;offset of arg
153 dw 0 ;AN000;segment of arg
154 db 1 ;AN000;first subst
155 db Right_Align+Unsgn_Bin_Word ;AN000;binary to decimal
156 db 5 ;AN000;maximum width
157 db 1 ;AN000;minimum width
158 db blank ;AN000;pad character
159
160; "Active code page: %1",13,10
161;
162CP_active_Ptr dw 1024 ;AN000;message number
163 db 1 ;AN000;number of subst
164 db parm_block_size ;AN000;size of sublist
165 db 0 ;AN000;reserved
166 dw OFFSET TranGroup:System_cpage ;AN000;offset of arg
167 dw 0 ;AN000;segment of arg
168 db 1 ;AN000;first subst
169 db Right_Align+Unsgn_Bin_Word ;AN000;binary to decimal
170 db 5 ;AN000;maximum width
171 db 1 ;AN000;minimum width
172 db blank ;AN000;pad character
173
174; "NLSFUNC not installed",13,10
175;
176NLSFUNC_Ptr dw 1025 ;AN000;message number
177 db no_subst ;AN000;number of subst
178
179; "Invalid code page",13,10
180;
181Inv_Code_Page dw 1026 ;AN000;message number
182 db no_subst ;AN000;number of subst
183
184; "Current drive is no longer valid"
185;
186BadCurDrv dw 1027 ;AN000;message number
187 db no_subst ;AN000;number of subst
188
189; "Press any key to continue"
190;
191PauseMes_Ptr dw 1028 ;AN000;message number
192 db no_subst ;AN000;number of subst
193
194; "Label not found",13,10
195;
196BadLab_Ptr dw 1029 ;AN000;message number
197 db no_subst ;AN000;number of subst
198
199; "Syntax error",13,10
200;
201SyntMes_Ptr dw 1030 ;AN000;message number
202 db no_subst ;AN000;number of subst
203
204; "Invalid date",13,10
205;
206BadDat_Ptr dw 1031 ;AN000;message number
207 db no_subst ;AN000;number of subst
208
209; "Current date is %1 %2",13,10
210;
211CurDat_Ptr dw 1032 ;AN000;message number
212 db 2 ;AN000;number of subst
213 db parm_block_size ;AN000;size of sublist
214 db 0 ;AN000;reserved
215 dw OFFSET TranGroup:Arg_Buf ;AN000;offset of arg
216 dw 0 ;AN000;segment of arg
217 db 1 ;AN000;first subst
218 db Char_field_ASCIIZ ;AN000;character string
219 db 3 ;AN000;maximum width
220 db 3 ;AN000;minimum width
221 db blank ;AN000;pad character
222 db parm_block_size ;AN000;size of sublist
223 db 0 ;AN000;reserved
224CurDat_yr dw 0 ;AN000;year
225CurDat_mo_day dw 0 ;AN000;month,day
226 db 2 ;AN000;second subst
227 db DATE_MDY_4 ;AN000;date
228 db 10 ;AN000;maximum width
229 db 10 ;AN000;minimum width
230 db blank ;AN000;pad character
231
232
233; "SunMonTueWedThuFriSat"
234;
235WeekTab dw 1033 ;AN000;message number
236 db no_subst ;AN000;number of subst
237
238; "Enter new date (%1):"
239;
240NewDat_Ptr dw 1034 ;AN000;message number
241 db 1 ;AN000;number of subst
242 db parm_block_size ;AN000;size of sublist
243 db 0 ;AN000;reserved
244NewDat_Format dw 0 ;AN000;offset of replacement
245 dw 0 ;AN000;segment of arg
246 db 1 ;AN000;first subst
247 db Char_field_ASCIIZ ;AN000;character string
248 db 8 ;AN000;maximum width
249 db 8 ;AN000;minimum width
250 db blank ;AN000;pad character
251
252; "Invalid time",13,10
253;
254BadTim_Ptr dw 1035 ;AN000;message number
255 db no_subst ;AN000;number of subst
256
257; "Current time is %1",13,10
258;
259CurTim_Ptr dw 1036 ;AN000;message number
260 db 1 ;AN000;number of subst
261 db parm_block_size ;AN000;size of sublist
262 db 0 ;AN000;reserved
263CurTim_hr_min dw 0 ;AN000;hours,minutes
264CurTim_Sec_hn dw 0 ;AN000;seconds,hundredths
265 db 1 ;AN000;first subst
266 db Right_Align+TIME_HHMMSSHH_Cty ;AC059;time
267 db 12 ;AC059;maximum width
268 db 12 ;AC059;minimum width
269 db blank ;AN000;pad character
270
271; "Enter new time:"
272;
273NewTim_Ptr dw 1037 ;AN000;message number
274 db no_subst ;AN000;number of subst
275
276; ", Delete (Y/N)?",13,10
277;
278Del_Y_N_Ptr dw 1038 ;AN000;message number
279 db no_subst ;AN000;number of subst
280
281; "All files in directory will be deleted!",13,10
282; "Are you sure (Y/N)?",13,10
283;
284SureMes_Ptr dw 1039 ;AN000;message number
285 db no_subst ;AN000;number of subst
286
287; "Microsoft DOS Version %1.%2",13,10
288;
289VerMes_Ptr dw 1040 ;AN000;message number
290 db 2 ;AN000;number of subst
291 db parm_block_size ;AN000;size of sublist
292 db 0 ;AN000;reserved
293 dw OFFSET TranGroup:Major_Ver_Num ;AN000;offset of arg
294 dw 0 ;AN000;segment of arg
295 db 1 ;AN000;first subst
296 db Right_Align+Unsgn_Bin_Word ;AN000;binary to decimal
297 db 1 ;AN000;maximum width
298 db 1 ;AN000;minimum width
299 db blank ;AN000;pad character
300 db parm_block_size ;AN000;size of sublist
301 db 0 ;AN000;reserved
302 dw OFFSET TranGroup:Minor_Ver_Num ;AN000;offset of arg
303 dw 0 ;AN000;segment of arg
304 db 2 ;AN000;second subst
305 db Unsgn_Bin_Word ;AN000;binary to decimal
306 db 2 ;AN000;maximum width
307 db 2 ;AN000;minimum width
308 db "0" ;AN000;pad character
309
310; "Volume in drive %1 has no label",13,10
311;
312VolMes_Ptr_2 dw 1041 ;AN000;message number
313 db 1 ;AN000;number of subst
314 db parm_block_size ;AN000;size of sublist
315 db 0 ;AN000;reserved
316 dw OFFSET TranGroup:vol_drv ;AN000;offset of drive
317 dw 0 ;AN000;segment of arg
318 db 1 ;AN000;first subst
319 db Char_field_Char ;AN000;character
320 db 128 ;AN000;maximum width
321 db 1 ;AN000;minimum width
322 db blank ;AN000;pad character
323
324; "Volume in drive %1 is %2",13,10
325;
326VolMes_Ptr dw 1042 ;AN000;message number
327 db 2 ;AN000;number of subst
328 db parm_block_size ;AN000;size of sublist
329 db 0 ;AN000;reserved
330 dw OFFSET TranGroup:vol_drv ;AN000;offset of drive
331 dw 0 ;AN000;segment of arg
332 db 1 ;AN000;first subst
333 db 00000000b ;AN000;character
334 db 128 ;AN000;maximum width
335 db 1 ;AN000;minimum width
336 db blank ;AN000;pad character
337 db parm_block_size ;AN000;size of sublist
338 db 0 ;AN000;reserved
339 dw OFFSET TranGroup:CHARBUF ;AN000;offset of string
340 dw 0 ;AN000;segment of arg
341 db 2 ;AN000;second subst
342 db Char_field_ASCIIZ ;AN000;character string
343 db 128 ;AN000;maximum width
344 db 1 ;AN000;minimum width
345 db blank ;AN000;pad character
346
347; "Volume Serial Number is %1-%2",13,10
348;
349VolSerMes_Ptr dw 1043 ;AN000;message number
350 db 2 ;AN000;number of subst
351 db parm_block_size ;AN000;size of sublist
352 db 0 ;AN000;reserved
353 dw OFFSET TranGroup:vol_serial+2 ;AN000;offset of serial
354 dw 0 ;AN000;segment of arg
355 db 1 ;AN000;first subst
356 db Right_Align+Bin_Hex_Word ;AN000;binary to hex
357 db 4 ;AN000;maximum width
358 db 4 ;AN000;minimum width
359 db "0" ;AN000;pad character
360 db parm_block_size ;AN000;size of sublist
361 db 0 ;AN000;reserved
362 dw OFFSET TranGroup:vol_serial ;AN000;offset of serial
363 dw 0 ;AN000;segment of arg
364 db 2 ;AN000;second subst
365 db Right_Align+Bin_Hex_Word ;AN000;binary to hex
366 db 4 ;AN000;maximum width
367 db 4 ;AN000;minimum width
368 db "0" ;AN000;pad character
369
370; "Invalid directory",13,10
371;
372BadCD_Ptr dw 1044 ;AN000;message number
373 db no_subst ;AN000;number of subst
374
375; "Unable to create directory",13,10
376;
377BadMkD_Ptr dw 1045 ;AN000;message number
378 db no_subst ;AN000;number of subst
379
380; "Invalid path, not directory,",13,10
381; "or directory not empty",13,10
382;
383BadRmD_Ptr dw 1046 ;AN000;message number
384 db no_subst ;AN000;number of subst
385
386; "Must specify ON or OFF",13,10
387;
388Bad_ON_OFF_Ptr dw 1047 ;AN000;message number
389 db no_subst ;AN000;number of subst
390
391; "Directory of %1",13,10
392;
393DirHead_Ptr dw 1048 ;AN000;message number
394 db 1 ;AN000;number of subst
395 db parm_block_size ;AN000;size of sublist
396 db 0 ;AN000;reserved
397 dw OFFSET TranGroup:BWDBUF ;AN000;offset of arg
398 dw 0 ;AN000;segment of arg
399 db 1 ;AN000;first subst
400 db Char_field_ASCIIZ ;AN000;character string
401 db 128 ;AN000;maximum width
402 db 0 ;AN000;minimum width
403 db blank ;AN000;pad character
404
405; "No Path",13,10
406;
407NulPath_Ptr dw 1049 ;AN000;message number
408 db no_subst ;AN000;number of subst
409
410; "Invalid drive in search path",13,10
411;
412BadPMes_Ptr dw 1050 ;AN000;message number
413 db no_subst ;AN000;number of subst
414
415; "Invalid device",13,10
416;
417BadDev_Ptr dw 1051 ;AN000;message number
418 db no_subst ;AN000;number of subst
419
420; "FOR cannot be nested",13,10
421;
422ForNestMes_Ptr dw 1052 ;AN000;message number
423 db no_subst ;AN000;number of subst
424
425; "Intermediate file error during pipe",13,10
426;
427PipeEMes_Ptr dw 1053 ;AN000;message number
428 db no_subst ;AN000;number of subst
429
430; "Cannot do binary reads from a device",13,10
431;
432InBDev_Ptr dw 1054 ;AN000;message number
433 db no_subst ;AN000;number of subst
434
435; "BREAK is %1",13,10
436;
437CtrlcMes_Ptr dw 1055 ;AN000;message number
438 db 1 ;AN000;number of subst
439 db parm_block_size ;AN000;size of sublist
440 db 0 ;AN000;reserved
441 dw 0 ;AN000;offset of on/off (new)
442 dw 0 ;AN000;segment of arg
443 db 1 ;AN000;first subst
444 db Char_field_ASCIIZ ;AN000;character string
445 db 128 ;AN000;maximum width
446 db 1 ;AN000;minimum width
447 db blank ;AN000;pad character
448
449; "VERIFY is %1",13,10
450;
451VeriMes_Ptr dw 1056 ;AN000;message number
452 db 1 ;AN000;number of subst
453 db parm_block_size ;AN000;size of sublist
454 db 0 ;AN000;reserved
455 dw 0 ;AN000;offset of on/off (new)
456 dw 0 ;AN000;segment of arg
457 db 1 ;AN000;first subst
458 db Char_field_ASCIIZ ;AN000;character string
459 db 128 ;AN000;maximum width
460 db 1 ;AN000;minimum width
461 db blank ;AN000;pad character
462
463; "ECHO is %1",13,10
464;
465EchoMes_Ptr dw 1057 ;AN000;message number
466 db 1 ;AN000;number of subst
467 db parm_block_size ;AN000;size of sublist
468 db 0 ;AN000;reserved
469 dw 0 ;AN000;offset of on/off (new)
470 dw 0 ;AN000;segment of arg
471 db 1 ;AN000;first subst
472 db Char_field_ASCIIZ ;AN000;character string
473 db 128 ;AN000;maximum width
474 db 1 ;AN000;minimum width
475 db blank ;AN000;pad character
476
477; "off"
478;
479OffMes_Ptr dw 1059 ;AN000;message number
480 db no_subst ;AN000;number of subst
481
482; "on"
483;
484OnMes_Ptr dw 1060 ;AN000;message number
485 db no_subst ;AN000;number of subst
486
487; "Error writing to device",13,10
488;
489DevWMes_Ptr dw 1061 ;AN000;message number
490 db no_subst ;AN000;number of subst
491
492; "Invalid path",13,10
493;
494Inval_Path_Ptr dw 1062 ;AN000;message number
495 db no_subst ;AN000;number of subst
496
497; unformatted string output
498;
499arg_Buf_Ptr dw 1063 ;AN000;message number
500 db 1 ;AN000;number of subst
501 db parm_block_size ;AN000;size of sublist
502 db 0 ;AN000;reserved
503 dw OFFSET TranGroup:Arg_Buf ;AN000;offset of arg
504 dw 0 ;AN000;segment of arg
505 db 1 ;AN000;first subst
506 db Char_field_ASCIIZ ;AN000;character string
507 db 128 ;AN000;maximum width
508 db 0 ;AN000;minimum width
509 db blank ;AN000;pad character
510
511; file name output
512;
513File_Name_Ptr dw 1064 ;AN000;message number
514 db 1 ;AN000;number of subst
515 db parm_block_size ;AN000;size of sublist
516 db 0 ;AN000;reserved
517 dw OFFSET TranGroup:SRCBUF ;AN000;offset of arg
518 dw 0 ;AN000;segment of arg
519 db 1 ;AN000;first subst
520 db Char_field_ASCIIZ ;AN000;character string
521 db 128 ;AN000;maximum width
522 db 0 ;AN000;minimum width
523 db blank ;AN000;pad character
524
525; file size output for dir
526;
527Disp_File_Size_Ptr dw 1065 ;AN000;message number
528 db 1 ;AN000;number of subst
529 db parm_block_size ;AN000;size of sublist
530 db 0 ;AN000;reserved
531 dw OFFSET TranGroup:File_size_low ;AN000;offset of arg
532 dw 0 ;AN000;segment of arg
533 db 1 ;AN000;first subst
534 db Right_Align+Unsgn_Bin_DWord ;AN000;long binary to decimal
535 db 10 ;AN000;maximum width
536 db 10 ;AN000;minimum width
537 db blank ;AN000;pad character
538
539; unformatted string output
540; %s
541String_Buf_Ptr dw 1066 ;AN000;message number
542 db 1 ;AN000;number of subst
543 db parm_block_size ;AN000;size of sublist
544 db 0 ;AN000;reserved
545 dw OFFSET TranGroup:String_ptr_2 ;AN000;offset of arg
546 dw 0 ;AN000;segment of arg
547 db 1 ;AN000;first subst
548 db Char_field_ASCIIZ ;AN000;character string
549 db 128 ;AN000;maximum width
550 db 0 ;AN000;minimum width
551 db blank ;AN000;pad character
552 db 0 ;AN000;
553
554; tab character
555;
556Tab_ptr dw 1067 ;AN000;message number
557 db no_subst ;AN000;number of subst
558
559; " <DIR> "
560;
561DMes_Ptr dw 1068 ;AN000;message number
562 db no_subst ;AN000;number of subst
563
564; destructive back space
565;
566Dback_Ptr dw 1069 ;AN000;message number
567 db no_subst ;AN000;number of subst
568
569; carriage return / line feed
570;
571ACRLF_Ptr dw 1070 ;AN000;message number
572 db no_subst ;AN000;number of subst
573
574; output a single character
575;
576;One_Char_Buf_Ptr dw 1071 ;AN000;message number
577; db 1 ;AN000;number of subst
578; db parm_block_size ;AN000;size of sublist
579; db 0 ;AN000;reserved
580; dw OFFSET TranGroup:One_Char_Val ;AN000;offset of charcacter
581; dw 0 ;AN000;segment of arg
582; db 1 ;AN000;first subst
583; db Char_field_Char ;AN000;character
584; db 1 ;AN000;maximum width
585; db 1 ;AN000;minimum width
586; db blank ;AN000;pad character
587
588; "mm-dd-yy"
589;
590USADat_Ptr dw 1072 ;AN000;message number
591 db no_subst ;AN000;number of subst
592
593; "dd-mm-yy"
594;
595EurDat_Ptr dw 1073 ;AN000;message number
596 db no_subst ;AN000;number of subst
597
598; "yy-mm-dd"
599;
600JapDat_Ptr dw 1074 ;AN000;message number
601 db no_subst ;AN000;number of subst
602
603; date string for prompt
604;
605promptDat_Ptr dw 1075 ;AN000;message number
606 db 2 ;AN000;number of subst
607 db parm_block_size ;AN000;size of sublist
608 db 0 ;AN000;reserved
609 dw OFFSET TranGroup:Arg_Buf ;AN000;offset of arg
610 dw 0 ;AN000;segment of arg
611 db 1 ;AN000;first subst
612 db Char_field_ASCIIZ ;AN000;character string
613 db 3 ;AN000;maximum width
614 db 3 ;AN000;minimum width
615 db blank ;AN000;pad character
616 db parm_block_size ;AN000;size of sublist
617 db 0 ;AN000;reserved
618promptDat_yr dw 0 ;AN000;year
619promptDat_moday dw 0 ;AN000;month,day
620 db 2 ;AN000;second subst
621 db DATE_MDY_4 ;AN000;date
622 db 10 ;AN000;maximum width
623 db 8 ;AN000;minimum width
624 db blank ;AN000;pad character
625
626
627; Time for prompt
628;
629promTim_Ptr dw 1076 ;AN000;message number
630 db 1 ;AN000;number of subst
631 db parm_block_size ;AN000;size of sublist
632 db 0 ;AN000;reserved
633PromTim_hr_min dw 0 ;AN000;hours,minutes
634PromTim_Sec_hn dw 0 ;AN000;seconds,hundredths
635 db 1 ;AN000;first subst
636 db Right_Align+TIME_HHMMSSHH_24 ;AC013;time
637 db 11 ;AN000;maximum width
638 db 11 ;AC013;minimum width
639 db blank ;AN000;pad character
640
641; Date and time for DIR
642;
643DirDatTim_Ptr dw 1077 ;AN000;message number
644 db 2 ;AN000;number of subst
645 db parm_block_size ;AN000;size of sublist
646 db 0 ;AN000;reserved
647DirDat_yr dw 0 ;AN000;year
648DirDat_mo_day dw 0 ;AN000;month,day
649 db 1 ;AN000;first subst
650 db Right_Align+DATE_MDY_2 ;AN000;date
651 db 10 ;AN000;maximum width
652 db 8 ;AN000;minimum width
653 db blank ;AN000;pad character
654 db parm_block_size ;AN000;size of sublist
655 db 0 ;AN000;reserved
656DirTim_hr_min dw 0 ;AN000;hours,minutes
657DirTim_Sec_hn dw 0 ;AN000;seconds,hundredths
658 db 2 ;AN000;second subst
659 db Right_align+TIME_HHMM_Cty ;AN000;time
660 db 6 ;AN000;maximum width
661 db 6 ;AN000;minimum width
662 db blank ;AN000;pad character
663
664; "Directory already exists"
665;
666MD_exists_ptr dw 1078 ;AN000;message number
667 db no_subst ;AN000;number of subst
668
669PATH_TEXT DB "PATH="
670PROMPT_TEXT DB "PROMPT="
671comspecstr db "COMSPEC="
diff --git a/v4.0/src/CMD/COMMAND/TSPC.ASM b/v4.0/src/CMD/COMMAND/TSPC.ASM
new file mode 100644
index 0000000..10e5758
--- /dev/null
+++ b/v4.0/src/CMD/COMMAND/TSPC.ASM
@@ -0,0 +1,488 @@
1 page 80,132
2; SCCSID = @(#)tspc.asm 4.1 85/09/22
3; SCCSID = @(#)tspc.asm 4.1 85/09/22
4TITLE COMMAND Transient Uninitialized DATA
5
6 INCLUDE comsw.asm
7.xlist
8.xcref
9 INCLUDE DOSSYM.INC
10 INCLUDE comequ.asm
11 INCLUDE comseg.asm
12 INCLUDE EA.inc ;AN030;
13.list
14.cref
15
16; Uninitialized transient data
17TRANSPACE SEGMENT PUBLIC BYTE
18
19 PUBLIC ALLSWITCH
20 PUBLIC append_exec ;AN041;
21 PUBLIC arg
22 PUBLIC argbufptr
23 PUBLIC ARGC
24 PUBLIC ARG1S
25 PUBLIC ARG2S
26 PUBLIC ARGTS
27 PUBLIC arg_buf
28 PUBLIC ASCII
29 PUBLIC BatBuf
30 PUBLIC BatBufEnd
31 PUBLIC BatBufPos
32 PUBLIC BATHAND
33 PUBLIC BINARY
34 PUBLIC BITS
35 PUBLIC BWDBUF
36 PUBLIC BYTCNT
37 PUBLIC bytes_free
38 PUBLIC CFLAG
39 PUBLIC CHARBUF
40 PUBLIC CHKDRV
41 PUBLIC COM
42 PUBLIC COMBUF
43 PUBLIC comma
44 PUBLIC comptr
45 PUBLIC comspec_flag
46 PUBLIC COMSW
47 PUBLIC CONCAT
48 PUBLIC concat_xa ;AN000;
49 PUBLIC copy_Num
50 PUBLIC CPDATE
51 PUBLIC CPTIME
52 PUBLIC cpyflag
53 PUBLIC CURDRV
54 PUBLIC DATE_DAY ;AN000;
55 PUBLIC DATE_MONTH ;AN000;
56 PUBLIC DATE_OUTPUT ;AN000;
57 PUBLIC DATE_TYPE ;AN000;
58 PUBLIC DATE_YEAR ;AN000;
59 PUBLIC DEST
60 PUBLIC DESTBUF
61 PUBLIC DestClosed
62 PUBLIC DESTDIR
63 PUBLIC DESTFCB
64 PUBLIC DESTFCB2
65 PUBLIC DESTHAND
66 PUBLIC DESTINFO
67 PUBLIC DESTISDEV
68 PUBLIC DESTISDIR
69 PUBLIC DESTNAME
70 PUBLIC DESTSIZ
71 PUBLIC DESTSWITCH
72 PUBLIC DESTTAIL
73 PUBLIC DESTVARS
74 PUBLIC DIRBUF
75 PUBLIC DIRCHAR
76 PUBLIC dirflag ;AN015;
77 PUBLIC Dir_Num
78 PUBLIC display_ioctl ;AN000;
79 PUBLIC display_mode ;AN000;
80 PUBLIC display_width ;AN000;
81 PUBLIC DRIVE_NUMBER ;AN000;
82 PUBLIC DRIVE_OUTPUT ;AN000;
83 PUBLIC DRIVE_TYPE ;AN000;
84 PUBLIC DRIVE_VALUE ;AN000;
85 PUBLIC ELCNT
86 PUBLIC ELPOS
87 PUBLIC EXECPATH
88 PUBLIC EXEC_ADDR
89 PUBLIC EXEFCB
90 PUBLIC expand_star
91 PUBLIC ext_entered ;AN005;
92 PUBLIC ext_open_off ;AN000;
93 PUBLIC ext_open_parms ;AN000;
94 PUBLIC ext_open_seg ;AN000;
95 PUBLIC FBUF
96 PUBLIC FILECNT
97 PUBLIC file_size_high
98 PUBLIC file_size_low
99 PUBLIC FILTYP
100 PUBLIC FIRSTDEST
101 PUBLIC FRSTSRCH
102 PUBLIC FULLSCR
103 PUBLIC GOTOLEN
104 PUBLIC HEADCALL
105 PUBLIC ID
106 PUBLIC IDLEN
107 PUBLIC IFNOTFLAG
108 PUBLIC if_not_count
109 PUBLIC INEXACT
110 PUBLIC INTERNATVARS
111 PUBLIC KPARSE
112 PUBLIC last_arg
113 PUBLIC LINCNT
114 PUBLIC LINLEN
115 PUBLIC linperpag ;AN000;
116 PUBLIC major_ver_num
117 PUBLIC MELCOPY
118 PUBLIC MELSTART
119 PUBLIC minor_ver_num
120 PUBLIC msg_flag ;AN022;
121 PUBLIC msg_numb ;AN022;
122 PUBLIC NOWRITE
123 PUBLIC NXTADD
124 PUBLIC objcnt
125 PUBLIC one_char_val
126 PUBLIC PARM1
127 PUBLIC PARM2
128 PUBLIC parse_last ;AN018;
129 PUBLIC PARSE1_ADDR ;AN000;
130 PUBLIC PARSE1_CODE ;AN000;
131 PUBLIC PARSE1_OUTPUT ;AN000;
132 PUBLIC PARSE1_SYN ;AN000;
133 PUBLIC PARSE1_TYPE ;AN000;
134 PUBLIC PATHCNT
135 PUBLIC pathinfo
136 PUBLIC PATHPOS
137 PUBLIC PATHSW
138 PUBLIC PLUS
139 PUBLIC plus_comma
140 PUBLIC print_err_flag ;AN000;
141 PUBLIC psep_char
142 PUBLIC RCH_ADDR
143 PUBLIC RDEOF
144 PUBLIC RE_INSTR
145 PUBLIC RESSEG
146 PUBLIC SCANBUF
147 PUBLIC SDIRBUF
148 PUBLIC search_best
149 PUBLIC search_best_buf
150 PUBLIC search_curdir_buf
151 PUBLIC search_error
152 PUBLIC SKPDEL
153 PUBLIC SOURCE
154 PUBLIC SPECDRV
155 PUBLIC SRCBUF
156 PUBLIC SRCHAND
157 PUBLIC SRCINFO
158 PUBLIC SRCISDEV
159 PUBLIC SRCISDIR
160 PUBLIC SRCPT
161 PUBLIC SRCSIZ
162 PUBLIC SRCTAIL
163 PUBLIC SRCVARS
164 PUBLIC srcxname
165 PUBLIC src_xa_seg ;AN000;
166 PUBLIC src_xa_size ;AN000;
167 PUBLIC STACK
168 PUBLIC STARTEL
169 PUBLIC string_ptr_2
170;AD061; PUBLIC string_ptr_2_sb ;AN000;
171 PUBLIC subst_buffer ;AN061;
172 PUBLIC SWITCHAR
173 PUBLIC system_cpage
174 PUBLIC TERMREAD
175 PUBLIC TIME_FRACTION ;AN000;
176 PUBLIC TIME_HOUR ;AN000;
177 PUBLIC TIME_MINUTES ;AN000;
178 PUBLIC TIME_OUTPUT ;AN000;
179 PUBLIC TIME_SECONDS ;AN000;
180 PUBLIC TIME_TYPE ;AN000;
181 PUBLIC TPA
182 PUBLIC tpbuf
183 PUBLIC TRANSPACEEND
184 PUBLIC TRAN_TPA
185 PUBLIC trgxname
186 PUBLIC UCOMBUF
187 PUBLIC USERDIR1
188 PUBLIC vol_drv
189 PUBLIC vol_ioctl_buf ;AC030;
190 PUBLIC vol_serial ;AC030;
191 PUBLIC vol_label ;AC030;
192 PUBLIC WRITTEN
193 PUBLIC xa_cp_length ;AN030;
194 PUBLIC xa_cp_out ;AN030;
195 PUBLIC xa_list_attr ;AN030;
196 PUBLIC zflag
197
198 IF IBM
199 PUBLIC ROM_CALL
200 PUBLIC ROM_CS
201 PUBLIC ROM_IP
202 ENDIF
203
204
205 ORG 0
206ZERO = $
207SRCXNAME DB DIRSTRLEN + 20 DUP (?) ;g buffer for name translate
208TRGXNAME DB DIRSTRLEN + 20 DUP (?) ;g buffer for name translate
209UCOMBUF DB COMBUFLEN+3 DUP(?) ; Raw console buffer
210COMBUF DB COMBUFLEN+3 DUP(?) ; Cooked console buffer
211USERDIR1 DB DIRSTRLEN+3 DUP(?) ; Storage for users current directory
212EXECPATH DB COMBUFLEN+3 DUP(?) ; Path for external command
213RE_INSTR DB DIRSTRLEN+3+13 DUP (?) ; path for input to redirection
214
215; Variables passed up from resident
216HEADCALL LABEL DWORD
217 DW ?
218RESSEG DW ?
219TPA DW ?
220SWITCHAR DB ?
221DIRCHAR DB ?
222EXEC_ADDR DD ?
223RCH_ADDR DD ?
224fTest DW ?
225TRAN_TPA DW ?
226
227CHKDRV DB ?
228RDEOF LABEL BYTE ; Misc flags
229IFNOTFLAG LABEL BYTE
230FILTYP DB ?
231CURDRV DB ?
232concat_xa db 0 ;AN000; flag for XA on file concatenations
233CONCAT LABEL BYTE
234PARM1 DB ?
235ARGC LABEL BYTE
236PARM2 DB ?
237COMSW DW ? ; Switches between command and 1st arg
238ARG1S DW ? ; Switches between 1st and 2nd arg
239DESTSWITCH LABEL WORD
240ARG2S DW ? ; Switches after 2nd arg
241ALLSWITCH LABEL WORD
242ARGTS DW ? ; ALL switches except for COMSW
243CFLAG DB ?
244DESTCLOSED LABEL BYTE
245SPECDRV DB ?
246BYTCNT DW ? ; Size of buffer between RES and TRANS
247NXTADD DW ?
248FRSTSRCH DB ?
249LINCNT DB ?
250LINLEN DB ?
251FILECNT DW ?
252CHARBUF DB 80 DUP (?) ;line byte character buffer for xenix write
253DESTFCB2 LABEL BYTE
254IDLEN DB ?
255ID DB 8 DUP(?)
256COM DB 3 DUP(?)
257DEST DB 37 DUP(?)
258DESTNAME DB 11 DUP(?)
259DESTFCB LABEL BYTE
260DESTDIR DB DIRSTRLEN DUP(?) ; Directory for PATH searches
261GOTOLEN LABEL WORD
262BWDBUF LABEL BYTE
263EXEFCB LABEL WORD
264DIRBUF DB DIRSTRLEN+3 DUP(?)
265SDIRBUF DB 12 DUP(?)
266BITS DW ?
267PATHCNT DW ?
268PATHPOS DW ?
269PATHSW DW ?
270FULLSCR DW ?
271comma db 0 ;g flag set if +,, occurs
272plus_comma db 0 ;g flag set if +,, occurs
273dirflag db 0 ;AN015; set when pathcrunch called from DIR
274parse_last dw 0 ;AN018; used to hold parsing position
275
276system_cpage DW 0 ;AC001; used for CHCP variable
277src_XA_size DW 0 ;AN000; size of extended attributes
278src_XA_seg DW 0 ;AN000; segment of extended attributes
279
280ext_open_parms label byte ;AN000; extended open parameter list
281;emg340 ext_open_off dw offset trangroup:srcbuf ;AN000; offset of file name
282ext_open_off dw ? ;AN030; offset of extended attributes
283ext_open_seg dw ? ;AN000; segment of extended attributes
284 dw 0 ;AN000; no additional parameters
285
286XA_cp_out label byte ;AN030; list for one extended attribute
287 DW 1 ;AN030; count of entries
288 DB EAISBINARY ;AN030; ea_type
289 DW EASYSTEM ;AN030; ea_flags
290 DB ? ;AN030; ea_rc
291 DB 2 ;AN030; ea_namelen
292 DW 2 ;AN030; ea_valuelen
293 DB "CP" ;AN030; ea_name
294xa_list_attr DW 0 ;AC030; code page
295xa_cp_length DW $-XA_cp_out ;AN030; length of buffer
296
297
298
299arg_buf db 128 dup (?)
300file_size_low dw ? ;AC000;
301file_size_high dw ? ;AC000;
302string_ptr_2 dw ?
303;AD061;string_ptr_2_sb dw ?
304copy_Num dw ?
305cpyflag db ?
306Dir_Num DW ?
307bytes_free dw ?
308 dw ?
309major_ver_num dw ?
310minor_ver_num dw ?
311one_char_val db ?,0
312vol_drv db ?
313
314IF IBM
315ROM_CALL DB ? ; flag for rom function
316ROM_IP DW ?
317ROM_CS DW ?
318ENDIF
319
320DESTVARS LABEL BYTE
321DESTISDIR DB ?
322DESTSIZ DB ?
323DESTTAIL DW ?
324DESTINFO DB ?
325DESTBUF DB DIRSTRLEN + 20 DUP (?)
326
327DESTHAND DW ?
328DESTISDEV DB ?
329FIRSTDEST DB ?
330MELCOPY DB ?
331MELSTART DW ?
332
333SRCVARS LABEL BYTE
334SRCISDIR DB ?
335SRCSIZ DB ?
336SRCTAIL DW ?
337SRCINFO DB ?
338SRCBUF DB DIRSTRLEN + 20 DUP (?)
339
340SRCHAND DW ?
341SRCISDEV DB ?
342
343SCANBUF DB DIRSTRLEN + 20 DUP (?)
344
345SRCPT DW ?
346INEXACT DB ?
347NOWRITE DB ?
348BINARY DB ?
349WRITTEN DW ?
350TERMREAD DB ?
351ASCII DB ?
352PLUS DB ?
353objcnt db ? ; Used in copy
354CPDATE DW ?
355CPTIME DW ?
356BATHAND DW ? ; Batch handle
357STARTEL DW ?
358ELCNT DB ?
359ELPOS DB ?
360SKPDEL DB ?
361SOURCE DB 11 DUP(?)
362
363ext_entered db 0 ;AN005;
364
365display_ioctl db 0 ;AN000; info level
366 db 0 ;AN000; reserved
367 dw crt_ioctl_ln ;AN000; length of data
368 dw ? ;AN000; control flags
369display_mode db ? ;AN000; display mode, colors
370 db 0 ;AN000; reserved
371 dw ? ;AN023; colors
372 dw ? ;AN000; display width (PELS)
373 dw ? ;AN000; display length (PELS)
374display_width dw ? ;AN000; display width
375linperpag dw linesperpage ;AN000; display length (default to linesperpage)
376
377vol_ioctl_buf label byte ;AN000; buffer for ioctl volume label/serial call
378 dw 0 ;AN000; info level
379vol_serial dd 0 ;AN000; volume serial number
380vol_label db 11 dup (" ") ;AN000; volume label - init to blanks
381 db 8 dup (" ") ;AN000; file system type
382
383expand_star db ?
384comspec_flag db ?
385msg_flag db ? ;AN022; flag set if non-utility message issued
386msg_numb dw 0 ;AN022; set with extended error message issued
387append_exec db 0 ;AN041; set if internal append executed
388print_err_flag dw 0 ;AN000; flag set if error during sysdispmsg
389subst_buffer db parm_block_size*2 dup (0);AN061;
390
391;;;; IF KANJI 3/3/KK
392KPARSE DB ?
393;;;; ENDIF 3/3/KK
394
395; Data declarations taken out of parse.asm
396
397arg arg_unit <> ; pointers, arg count, string buffer
398argbufptr DW ? ; index for argv[].argpointer
399tpbuf DB 128 DUP (?) ; temporary buffer
400LAST_ARG DW ? ; point at which to accumulate switch info
401comptr dw ? ; ptr into combuf
402
403; Data declarations taken out of path.asm
404fbuf find_buf <> ; dma buffer for findfirst/findnext
405pathinfo DW 3 DUP (?) ; ES, SI(old), and SI(new) of user path
406psep_char DB ? ; '/' or '\'
407search_best DB (?) ; best code, best filename so far
408fname_max_len equ 13
409search_best_buf DB fname_max_len DUP (?)
410search_curdir_buf DB 64 DUP (?) ; a place for CurDir info, if successful
411search_error DW (?) ; address of error message to be printed
412
413; Data declarations taken out of tbatch.asm
414if_not_count DW ?
415
416zflag db ? ; Used by typefil to indicate ^Z's
417
418 DW 80H DUP(0) ; Init to 0 to make sure the linker is not fooled
419STACK LABEL WORD
420
421INTERNATVARS internat_block <>
422 DB (internat_block_max - ($ - INTERNATVARS)) DUP (?)
423
424BatBufPos DW ? ; integer position in buffer of next byte
425BatBuf DB BatLen DUP (?)
426BatBufEnd DW ?
427
428; *****************************************************
429; EMG 4.00
430; DATA STARTING HERE WAS ADDED BY EMG FOR 4.00
431; FOR IMPLEMENTATION OF COMMON PARSE ROUTINE
432; *****************************************************
433;
434; COMMON PARSE OUTPUT BLOCKS
435;
436
437
438;
439; Common output blocks for PARSE number, complex, or string values.
440;
441
442PARSE1_OUTPUT LABEL BYTE ;AN000;
443PARSE1_TYPE DB 0 ;AN000; type
444PARSE1_CODE DB 0 ;AN000; return value
445PARSE1_SYN DW 0 ;AN000; es offset of synonym
446PARSE1_ADDR DD 0 ;AN000; numeric value / address
447 ; of string value
448
449;
450; Common output block for PARSE date strings.
451;
452
453DATE_OUTPUT LABEL BYTE ;AN000;
454DATE_TYPE DB 0 ;AN000; type
455 DB 0 ;AN000; return value
456 DW 0 ;AN000; es offset of synonym
457DATE_YEAR DW 0 ;AN000; year
458DATE_MONTH DB 0 ;AN000; month
459DATE_DAY DB 0 ;AN000; day
460
461;
462; Common output block for PARSE time strings.
463;
464
465TIME_OUTPUT LABEL BYTE ;AN000;
466TIME_TYPE DB 0 ;AN000; type
467 DB 0 ;AN000; return value
468 DW 0 ;AN000; es offset of synonym
469TIME_HOUR DB 0 ;AN000; hour
470TIME_MINUTES DB 0 ;AN000; minutes
471TIME_SECONDS DB 0 ;AN000; seconds
472TIME_FRACTION DB 0 ;AN000; hundredths
473
474;
475; Common output block for PARSE drive specifier (one based drive number).
476;
477
478DRIVE_OUTPUT LABEL BYTE ;AN000;
479DRIVE_TYPE DB 0 ;AN000; type
480DRIVE_VALUE DB 0 ;AN000; return value
481 DW 0 ;AN000; es offset of synonym
482DRIVE_NUMBER DB 0 ;AN000; drive number
483 DB 0,0,0 ;AN000; reserved
484
485TRANSPACEEND LABEL BYTE
486
487TRANSPACE ENDS
488 END
diff --git a/v4.0/src/CMD/COMMAND/TUCODE.ASM b/v4.0/src/CMD/COMMAND/TUCODE.ASM
new file mode 100644
index 0000000..6531c44
--- /dev/null
+++ b/v4.0/src/CMD/COMMAND/TUCODE.ASM
@@ -0,0 +1,520 @@
1 page 80,132
2; SCCSID = @(#)tucode.asm 4.2 85/05/31
3; SCCSID = @(#)tucode.asm 4.2 85/05/31
4Title COMMAND Language midifiable Code Transient
5
6
7.xlist
8.xcref
9 INCLUDE dossym.inc
10 INCLUDE comsw.asm
11 INCLUDE comseg.asm
12 INCLUDE comequ.asm
13.list
14.cref
15
16
17DATARES SEGMENT PUBLIC BYTE ;AC000;
18 EXTRN ECHOFLAG:BYTE
19DATARES ENDS
20
21TRANDATA SEGMENT PUBLIC BYTE ;AC000;
22 EXTRN BAD_ON_OFF_ptr:word
23 EXTRN ctrlcmes_ptr:word
24 EXTRN DEL_Y_N_PTR:WORD
25 EXTRN ECHOMES_ptr:word
26 EXTRN extend_buf_ptr:word ;AC000;
27 EXTRN offmes_ptr:word
28 EXTRN onmes_ptr:word
29 EXTRN PARSE_BREAK:BYTE ;AN000;
30 EXTRN promptdat_moday:word ;AC000;
31 EXTRN promptdat_ptr:word ;AC000;
32 EXTRN promptdat_yr:word ;AC000;
33 EXTRN string_buf_ptr:word
34 EXTRN SUREMES_ptr:word
35 EXTRN VERIMES_ptr:BYTE
36 EXTRN WeekTab:word
37TRANDATA ENDS
38
39TRANSPACE SEGMENT PUBLIC BYTE ;AC000;
40 EXTRN arg_buf:byte
41 EXTRN BWDBUF:BYTE
42 EXTRN DEST:BYTE
43 EXTRN destdir:byte
44 EXTRN dirchar:byte
45 EXTRN PARSE1_CODE:BYTE ;AN000;
46 EXTRN RESSEG:WORD
47 EXTRN string_ptr_2:word
48
49TRANSPACE ENDS
50
51TRANCODE SEGMENT PUBLIC BYTE
52
53 EXTRN CERROR:NEAR
54 EXTRN CRLF2:NEAR
55 EXTRN extend_setup:near ;AN022;
56
57 PUBLIC CNTRLC
58 PUBLIC ECHO
59 PUBLIC GetDate
60 PUBLIC NOTEST2
61 PUBLIC PRINT_DATE
62 PUBLIC SLASHP_ERASE ;AN000;
63 PUBLIC VERIFY
64
65ASSUME CS:TRANGROUP,DS:TRANGROUP,ES:TRANGROUP,SS:NOTHING
66
67; ****************************************************************
68; *
69; * ROUTINE: NOTEST2 - execution of DEL/ERASE command
70; *
71; * FUNCTION: Delete files based on user parsed input. Prompt
72; * user for Y/N if necessary. If an error occurs,
73; * set up an error message and go to CERROR.
74; *
75; * INPUT: FCB at 5ch set up with filename(s) entered
76; * Current directory set to entered directory
77; *
78; * OUTPUT: none
79; *
80; ****************************************************************
81;
82; ARE YOU SURE prompt when deleting *.*
83
84NOTEST2:
85 MOV CX,11
86 MOV SI,FCB+1
87
88AMBSPEC:
89 LODSB
90 CMP AL,'?'
91 JNZ ALLFIL
92 LOOP AMBSPEC
93
94ALLFIL:
95 CMP CX,0
96 JNZ NOPRMPT
97
98ASKAGN:
99 MOV DX,OFFSET TRANGROUP:SUREMES_ptr ; "Are you sure (Y/N)?"
100 invoke std_printf
101 MOV SI,80H
102 MOV DX,SI
103 MOV WORD PTR [SI],120 ; zero length
104 MOV AX,(STD_CON_INPUT_FLUSH SHL 8) OR STD_CON_STRING_INPUT
105 INT 21H
106 LODSW
107 OR AH,AH
108 JZ ASKAGN
109 INVOKE SCANOFF
110 call char_in_xlat ;G Convert to upper case
111 retc ;AN000; return if function not supported
112 CMP AL,CAPITAL_N ;G
113 retz
114 CMP AL,CAPITAL_Y ;G
115 PUSHF
116 CALL CRLF2
117 POPF
118 JNZ ASKAGN
119
120NOPRMPT:
121 MOV AH,FCB_DELETE
122 MOV DX,FCB
123 INT 21H
124 INC AL
125 jz eraerr
126 invoke RESTUDIR
127 ret ; If no error, return
128
129eraerr:
130 invoke set_ext_error_msg ;AN022; set up the extended error
131 push dx ;AN022; save message
132 invoke RESTUDIR
133 pop dx ;AN022; restore message
134
135 cmp word ptr extend_buf_ptr,error_no_more_files ;AN022; convert no more files to
136 jnz cerrorj2 ;AN022; file not found
137 mov Extend_Buf_ptr,error_file_not_found ;AN000; get message number in control block
138
139cerrorj2:
140 jmp cerror
141
142
143; ****************************************************************
144; *
145; * ROUTINE: SLASHP_ERASE - execution of DEL/ERASE /P
146; *
147; * FUNCTION: Delete files based on user parsed input. Prompt
148; * user for Y/N where necessary. If an error occurs
149; * set up and error message and transfer control
150; * to CERROR.
151; *
152; * INPUT: FCB at 5ch set up with filename(s) entered
153; * Current directory set to entered directory
154; *
155; * OUTPUT: none
156; *
157; ****************************************************************
158
159ASSUME CS:TRANGROUP,DS:TRANGROUP,ES:TRANGROUP,SS:NOTHING
160
161SLASHP_ERASE: ;AN000; entry point
162 invoke build_dir_string ;AN000; set up current directory string for output
163 mov ah,Set_DMA ;AN000; issue set dta int 21h
164 mov dx,offset trangroup:destdir ;AN000; use Destdir for target
165 int 21H ;AN000;
166 mov ah,Dir_Search_First ;AN000; do dir search first int 21h
167 mov dx,FCB ;AN000; use FCB at 5Ch for target
168 int 21H ;AN000;
169 inc al ;AN000; did an error occur
170 jz eraerr ;AN022; go to error exit
171
172delete_prompt_loop: ;AN000;
173 mov si,offset trangroup:destdir+1 ;AN000; set up FCB as source
174 mov di,offset trangroup:dest ;AN000; set up dest as target
175 mov al,dirchar ;AN000; store a "\" in the first char
176 stosb ;AN000; of DEST
177 invoke fcb_to_ascz ;AN000; convert filename from FCB to ASCIIZ string
178
179slashp_askagn: ;AN000;
180 call crlf2 ;AN000; print out carriage return, line feed
181 mov dx,offset trangroup:bwdbuf ;AN000; print out current directory string
182 mov bx,dx ;AN000; get string pointer in bx
183 cmp byte ptr [bx+3],end_of_line_out ;AN000; see if only D:\,0
184 jnz not_del_root ;AN000; no continue
185 mov byte ptr [bx+2],end_of_line_out ;AN000; yes, get rid of \
186
187Not_del_root: ;AN000;
188 mov string_ptr_2,dx ;AN000;
189 mov dx,offset trangroup:string_buf_ptr ;AN000;
190 invoke std_printf ;AN000;
191 mov dx,offset trangroup:dest ;AN000; print out file name string
192 mov string_ptr_2,dx ;AN000;
193 mov dx,offset trangroup:string_buf_ptr ;AN000;
194 invoke std_printf ;AN000;
195 mov dx,offset trangroup:Del_Y_N_Ptr ;AN000; issue ", Delete (Y/N)?" message
196 invoke std_printf ;AN000;
197 mov si,80H ;AN000; set up buffer for input
198 mov dx,si ;AN000;
199 mov word ptr [si],combuflen ;AN000;
200 mov ax,(std_con_input_flush shl 8) or std_con_string_input ;AN000;
201 int int_command ;AN000; get input from the user
202 lodsw ;AN000;
203 or ah,ah ;AN000; was a character entered?
204 jz slashp_askagn ;AN000; no - ask again
205 invoke scanoff ;AN000; scan off leading delimiters
206 call char_in_xlat ;AN000; yes - upper case it
207 retc ;AN000; return if function not supported
208 cmp al,capital_n ;AN000; was it no?
209 jz next_del_file ;AN000; yes - don't delete file
210 cmp al,capital_y ;AN000; was it yes?
211 jz delete_this_file ;AN000; yes - delete the file
212 jmp short slashp_askagn ;AN000; it was neither - ask again
213
214delete_this_file: ;AN000;
215 mov ah,fcb_delete ;AN000; delete the file
216 mov dx,offset trangroup:destdir ;AN000; use Destdir for target
217 int int_command ;AN000;
218 inc al ;AN000; did an error occur?
219 jnz next_del_file ;AN000; no - get next file
220 jmp eraerr ;AN022; go to error exit - need long jmp
221
222next_del_file: ;AN000;
223 mov ah,dir_search_next ;AN000; search for another file
224 mov dx,FCB ;AN000;
225 int int_command ;AN000;
226 inc al ;AN000; was a file found?
227 jz slash_p_exit ;AN000; no - exit
228 jmp delete_prompt_loop ;AN000; yes - continue (need long jump)
229
230slash_p_exit:
231 invoke get_ext_error_number ;AN022; get the extended error number
232 cmp ax,error_no_more_files ;AN022; was error file not found?
233 jz good_erase_exit ;AN022; yes - clean exit
234 jmp extend_setup ;AN022; go issue error message
235
236good_erase_exit:
237 invoke restudir ;AN000; we're finished - restore user's dir
238 call crlf2 ;AN000; print out carriage return, line feed
239 ret ;AN000; exit
240
241
242;************************************************
243; ECHO, BREAK, and VERIFY commands. Check for "ON" and "OFF"
244
245 break Echo
246
247assume ds:trangroup,es:trangroup
248
249ECHO:
250 CALL ON_OFF
251 JC DOEMES
252 MOV DS,[RESSEG]
253ASSUME DS:RESGROUP
254 JNZ ECH_OFF
255 OR [ECHOFLAG],1
256 RET
257ECH_OFF:
258 AND [ECHOFLAG],NOT 1
259 RET
260
261
262CERRORJ:
263 JMP CERROR
264
265;
266; There was no discrenable ON or OFF after the ECHO. If there is nothing but
267; delimiters on the command line, we issue the ECHO is ON/OFF message.
268;
269
270ASSUME DS:TRANGROUP
271
272DOEMES:
273 cmp cl,0 ;AC000; was anything on the line?
274 jz PEcho ; just display current state.
275 MOV DX,82H ; Skip one char after "ECHO"
276 invoke CRPRINT
277 JMP CRLF2
278
279PECHO:
280 MOV DS,[RESSEG]
281ASSUME DS:RESGROUP
282 MOV BL,[ECHOFLAG]
283 PUSH CS
284 POP DS
285ASSUME DS:TRANGROUP
286 AND BL,1
287 MOV DX,OFFSET TRANGROUP:ECHOMES_ptr
288 JMP SHORT PYN
289
290 break Break
291assume ds:trangroup,es:trangroup
292
293CNTRLC:
294 CALL ON_OFF
295 MOV AX,(SET_CTRL_C_TRAPPING SHL 8) OR 1
296 JC PCNTRLC
297 JNZ CNTRLC_OFF
298 MOV DL,1
299 INT 21H ; Set ^C
300 RET
301
302CNTRLC_OFF:
303 XOR DL,DL
304 INT 21H ; Turn off ^C check
305 RET
306
307PCNTRLC:
308 CMP CL,0 ;AC000; rest of line blank?
309 JNZ CERRORJ ; no, oops!
310
311pccont:
312 XOR AL,AL
313 INT 21H
314 MOV BL,DL
315 MOV DX,OFFSET TRANGROUP:CTRLCMES_ptr
316
317PYN:
318 mov si,offset trangroup:onmes_ptr ;AC000; get ON pointer
319 OR BL,BL
320 JNZ PRINTVAL
321 mov si,offset trangroup:offmes_ptr ;AC000; get OFF pointer
322
323PRINTVAL:
324 push dx ;AN000; save offset of message block
325 mov bx,dx ;AN000; save offset value
326 lodsw ;AN000; get message number of on or off
327 mov dh,util_msg_class ;AN000; this is a utility message
328 invoke Tsysgetmsg ;AN000; get the address of the message
329 add bx,ptr_off_pos ;AN000; point to offset of ON/OFF
330 mov word ptr [bx],si ;AN000; put the offset in the message block
331 pop dx ;AN000; get message back
332 invoke std_printf ;AC000; go print message
333 mov word ptr [bx],0 ;AN000; zero out message pointer
334
335 ret ;AN000; exit
336
337 break Verify
338assume ds:trangroup,es:trangroup
339
340VERIFY:
341 CALL ON_OFF
342 MOV AX,(SET_VERIFY_ON_WRITE SHL 8) OR 1
343 JC PVERIFY
344 JNZ VER_OFF
345 INT 21H ; Set verify
346 RET
347
348VER_OFF:
349 DEC AL
350 INT 21H ; Turn off verify after write
351 RET
352
353PVERIFY:
354 CMP CL,0 ;AC000; is rest of line blank?
355 JNZ CERRORJ ; nope...
356 MOV AH,GET_VERIFY_ON_WRITE
357 INT 21H
358 MOV BL,AL
359 MOV DX,OFFSET TRANGROUP:VERIMES_ptr
360 JMP PYN
361
362; ****************************************************************
363; *
364; * ROUTINE: ON_OFF
365; *
366; * FUNCTION: Parse the command line for an optional ON or
367; * OFF string for the BREAK, VERIFY, and ECHO
368; * routines.
369; *
370; * INPUT: command line at offset 81H
371; * PARSE_BREAK control block
372; *
373; * OUTPUT: If carry is clear
374; * If ON is found
375; * Zero flag set
376; * If OFF is found
377; * Zero flag clear
378; * If carry set
379; * If nothing on command line
380; * CL set to zero
381; * If error
382; * CL contains error value from parse
383; *
384; ****************************************************************
385
386assume ds:trangroup,es:trangroup
387
388ON_OFF:
389 MOV SI,81h
390
391scan_on_off: ;AN032; scan off leading blanks & equal
392 lodsb ;AN032; get a char
393 cmp al,blank ;AN032; if whitespace
394 jz scan_on_off ;AN032; keep scanning
395 cmp al,tab_chr ;AN032; if tab
396 jz scan_on_off ;AN032; keep scanning
397 cmp al,equal_chr ;AN032; if equal char
398 jz parse_on_off ;AN032; start parsing
399 dec si ;AN032; if none of above - back up
400
401parse_on_off: ;AN032; and start parsing
402 mov di,offset trangroup:parse_break ;AN000; Get adderss of PARSE_BREAK
403 xor cx,cx ;AN000; clear cx,dx
404 xor dx,dx ;AN000;
405 invoke cmd_parse ;AC000; call parser
406 cmp ax,end_of_line ;AC000; are we at end of line?
407 jz BADONF ;AC000; yes, return error
408 cmp ax,result_no_error ;AN000; did an error occur
409 jz on_off_there ;AN000; no - continue
410 mov cx,ax ;AN000; yes - set cl to error code
411 jmp short BADONF ;AN000; return error
412
413on_off_there:
414 cmp parse1_code,-1 ;AN014; was a valid positional present?
415 jnz good_on_off ;AN014; yes - continue
416 mov cx,badparm_ptr ;AN014; something other than ON/OFF
417 jmp short BADONF ;AN014; return error
418
419good_on_off: ;AN014;
420 xor ax,ax ;AC000; set up return code for
421 or al,parse1_code ;AC000; ON or OFF in AX
422 pushf ;AN000; save flags
423 mov di,offset trangroup:parse_break ;AN000; Get adderss of PARSE_BREAK
424 xor dx,dx ;AN000;
425 invoke cmd_parse ;AN000; call parser
426 cmp ax,end_of_line ;AN000; are we at end of line?
427 jnz BADONF_flags ;AN000; NO, return error
428 popf ;AN000; restore flags
429 clc ;AC000; no error
430 jmp short on_off_end ;AN000; return to caller
431
432BADONF_flags:
433 mov cx,ax
434 popf
435
436;
437; No discernable ON or OFF has been found. Put an error message pointer in DX
438; and return the error
439;
440BADONF:
441 MOV DX,OFFSET TRANGROUP:BAD_ON_OFF_ptr
442 STC
443
444ON_OFF_END:
445
446 RET
447
448
449
450;*************************************************************************
451; print date
452
453PRINT_DATE:
454 PUSH ES
455 PUSH DI
456 PUSH CS
457 POP ES
458 CALL GetDate ; get date
459 xchg dh,dl ;AN000; switch month & day
460 mov promptDat_yr,cx ;AC000; put year into message control block
461 mov promptDat_moday,dx ;AC000; put month and day into message control block
462 mov dx,offset trangroup:promptDat_ptr ;AC000; set up message for output
463 invoke std_printf
464;AD061; mov promptDat_yr,0 ;AC000; reset year, month and day
465;AD061; mov promptDat_moday,0 ;AC000; pointers in control block
466 POP DI ;AC000; restore di,es
467 POP ES ;AC000;
468 return
469;
470; Do GET DATE system call and set up 3 character day of week in ARG_BUF
471; for output. Date will be returned in CX,DX.
472;
473
474GetDate:
475 mov di,offset trangroup:arg_buf ;AC000; target for day of week
476 MOV AH,GET_DATE ;AC000; get current date
477 INT int_command ;AC000; Get date in CX:DX
478 CBW ;AC000;
479
480 push cx ;AN000; save date returned in
481 push dx ;AN000; CX:DX
482 MOV SI,AX
483 SHL SI,1
484 ADD SI,AX ; SI=AX*3
485 mov cx,si ;AN000; save si
486 mov ax,weektab ;AN000; get message number of weektab
487 mov dh,util_msg_class ;AN000; this is a utility message
488 push di ;AN000; save argument buffer
489 invoke Tsysgetmsg ;AN000; get the address of the message
490 pop di ;AN000; retrieve argument buffer
491 add si,cx ;AC000; get day of week
492 MOV CX,3
493 REP MOVSB
494 mov al,end_of_line_out ;AC000; terminate the string
495 stosb
496 pop dx ;AN000; get back date
497 pop cx ;AN000;
498
499 return
500;g
501;g This routine determines whether the character in AL is a
502;g Yes or No character. On return, if AL=0, the character is
503;g No, if AL=1, the character is Yes.
504;g
505
506assume ds:trangroup
507
508char_in_xlat proc near
509
510 mov dl,al ;AC000; get character into DX
511 xor dh,dh ;AC000;
512 mov ax,(getextcntry SHL 8) + 35 ;AC000; Yes/No char call
513 int int_command ;AC000;
514
515 ret
516
517char_in_xlat endp
518
519TRANCODE ENDS
520 END
diff --git a/v4.0/src/CMD/COMMAND/UINIT.ASM b/v4.0/src/CMD/COMMAND/UINIT.ASM
new file mode 100644
index 0000000..8f3498b
--- /dev/null
+++ b/v4.0/src/CMD/COMMAND/UINIT.ASM
@@ -0,0 +1,270 @@
1 page 80,132
2; SCCSID = @(#)uinit.asm 4.5 85/12/04
3; SCCSID = @(#)uinit.asm 4.5 85/12/04
4TITLE COMMAND Initialization messages
5
6.XCREF
7.XLIST
8include comsw.asm
9include comseg.asm
10include ifequ.asm
11.LIST
12.CREF
13
14addr macro sym,name
15 public name
16 ifidn <name>,<>
17
18 dw offset resgroup:sym
19 else
20
21name dw offset resgroup:sym
22 endif
23 endm
24
25
26ENVIRONMENT SEGMENT PUBLIC PARA ;AC000;
27 EXTRN ECOMSPEC:BYTE
28ENVIRONMENT ENDS
29
30TRANCODE SEGMENT PUBLIC BYTE ;AC000;
31 extrn Printf_init:FAR
32 extrn Triage_Init:FAR
33 extrn append_parse:FAR ;AN054;
34TranCode ENDS
35
36INIT SEGMENT PUBLIC PARA ;AC000;
37
38
39 public icondev
40 public BADCSPFL
41 public COMSPECT
42 public AUTOBAT
43 public fslash
44 public bslash
45 public space
46 public PRDATTM
47 public INITADD
48 public print_add
49 public CHUCKENV
50 public scswitch
51 public ucasea
52 public ECOMLOC
53 public equalsign
54 public lcasea
55 public lcasez
56 public comspstring
57 public EnvSiz
58 public EnvMax
59 public initend
60 public trnsize
61 public resetenv ;AC000;
62 public ext_msg ;AC000;
63 public num_positionals
64 public internat_info
65 public parsemes_ptr
66
67 PUBLIC triage_add
68 PUBLIC oldenv
69 PUBLIC usedenv
70 PUBLIC KAUTOBAT ;AN000; 3/3/KK
71 public eswitch ;AN018;
72 public dswitch ;AN018;
73 public init_parse ;AN054;
74 public old_parse_ptr ;AN057;
75 PUBLIC pars_msg_off ;AN060;
76 PUBLIC pars_msg_seg ;AN060;
77
78include resmsg.equ ;AC000;
79
80
81ICONDEV LABEL BYTE
82 DB "/DEV/"
83 DB "CON",0,0,0,0,0,0 ; Room for 8 char device
84BADCSPFL DB 0
85COMSPECT DB "/COMMAND.COM",0,0
86AUTOBAT DB 0,":\AUTOEXEC.BAT",0,0DH ;AC027;
87KAUTOBAT DB 0,":\KAUTOEXE.BAT",0,0DH ;AC027; 3/3/KK
88
89PRDATTM DB -1 ;Init not to prompt for date time
90INITADD DD ?
91print_add LABEL DWORD
92 DW OFFSET TranGroup:Printf_INIT
93 DW 0
94triage_add LABEL DWORD
95 DW OFFSET TranGroup:Triage_Init
96 DW 0
97CHUCKENV DB 0
98;eg ECOMLOC DW OFFSET ENVIRONMENT:ECOMSPEC-10H
99ECOMLOC DW OFFSET ENVIRONMENT:ECOMSPEC ;eg
100
101COMSPSTRING DB "COMSPEC="
102equalsign db "="
103lcasea db "a"
104lcasez db "z"
105fslash db "/"
106bslash db "\"
107space db " "
108scswitch db "C" ; Single command
109ucasea db "A"
110
111EnvSiz DW 0 ; size user wants to allocate
112EnvMax DW 0 ; maximum size allowed.
113oldenv DW 0 ; envirseg at initialization
114usedenv DW 0 ; amount of envirseg used
115PARS_MSG_OFF DW 0 ;AN060; SAVED PARSE ERROR MESSAGE OFFSET
116PARS_MSG_SEG DW 0 ;AN060; SAVED PARSE ERROR MESSAGE SEGMENT
117
118;Do not separate the following two words. Used to call transient PARSE routine
119
120init_parse label dword ;AN054;
121init_p DW TRANGROUP:APPEND_PARSE ;AN054;
122initend DW 0 ;eg segment address of end of init
123
124;End of data that shouldn't be separated.
125
126trnsize DW 0 ;eg size of transient in paragraphs
127resetenv DB 0 ;eg set if we need to setblck env at endinit
128ext_msg DB 0 ;AN000; set if /MSG switch entered
129eswitch db 0 ;AN018; set if /e was entered
130dswitch db 0 ;AN018; set if /d was entered
131parsemes_ptr dw 0 ;AN000; word to store parse error number
132
133;
134; PARSE BLOCK FOR COMMAND
135;
136PUBLIC PARSE_COMMAND ;AN000;
137PUBLIC COMND1_OUTPUT ;AN000;
138PUBLIC COMND1_TYPE ;AN000;
139PUBLIC COMND1_CODE ;AN000;
140PUBLIC COMND1_SYN ;AN000;
141PUBLIC COMND1_ADDR ;AN000;
142PUBLIC COMMAND_F_SYN ;AN000;
143PUBLIC COMMAND_P_SYN ;AN000;
144PUBLIC COMMAND_C_SYN ;AN000;
145PUBLIC COMMAND_D_SYN ;AN000;
146PUBLIC COMMAND_E_SYN ;AN000;
147PUBLIC COMMAND_M_SYN ;AN000;
148
149;
150; The following parse control block is used for COMMAND. This block is
151; used for parsing during initialization. The sytax for COMMAND is:
152; COMMAND [d:][path][/P][/F][/D][/E:xxxxx][/MSG][/C executable]
153; Anything on the command line after the /C switch will be passed to the
154; executable command, so if /C is used, it must be specified last. The
155; /MSG switch can only be specified if the /P switch is specified.
156;
157
158ENVBIG EQU 32768 ;AN000; maximum environment size
159ENVSML EQU 160 ;AN000; minimum environment size
160
161INTERNAT_INFO LABEL BYTE ;AN000; used for country info after parsing is completed
162PARSE_COMMAND LABEL BYTE ;AN000;
163 DW RESGROUP:COMMAND_PARMS ;AN000;
164 DB 0 ;AN000; no extra delimiter
165
166COMMAND_PARMS LABEL BYTE ;AN000;
167 DB 0,1 ;AN000; 1 positional parm
168 DW RESGROUP:COMMAND_FILE ;AN000;
169 DB 6 ;AN000; 6 switches
170 DW RESGROUP:COMMAND_SWITCH1 ;AN000;
171 DW RESGROUP:COMMAND_SWITCH2 ;AN000;
172 DW RESGROUP:COMMAND_SWITCH3 ;AN000;
173 DW RESGROUP:COMMAND_SWITCH4 ;AN000;
174 DW RESGROUP:COMMAND_SWITCH5 ;AN000;
175 DW RESGROUP:COMMAND_SWITCH6 ;AN000;
176 DB 0 ;AN000; no keywords
177
178COMMAND_FILE LABEL BYTE ;AN000;
179 DW 0201H ;AN000; filespec - optional
180 DW 1 ;AN000; capitalize - file table
181 DW RESGROUP:COMND1_OUTPUT ;AN000; result buffer
182 DW RESGROUP:NO_VAL ;AN000;
183 DB 0 ;AN000; no keywords
184
185COMMAND_SWITCH1 LABEL BYTE ;AN000;
186 DW 0 ;AN000; no match flags
187 DW 2 ;AN000; capitalize by char table
188 DW RESGROUP:COMND1_OUTPUT ;AN000; result buffer
189 DW RESGROUP:NO_VAL ;AN000;
190 DB 1 ;AN000; 1 keyword
191COMMAND_P_SYN DB "/P",0 ;AN000; /P switch
192
193COMMAND_SWITCH2 LABEL BYTE ;AN000;
194 DW 0 ;AN000; no match flags
195 DW 2 ;AN000; capitalize by char table
196 DW RESGROUP:COMND1_OUTPUT ;AN000; result buffer
197 DW RESGROUP:NO_VAL ;AN000;
198 DB 1 ;AN000; 1 keyword
199COMMAND_F_SYN DB "/F",0 ;AN000; /F switch
200
201COMMAND_SWITCH3 LABEL BYTE ;AN000;
202 DW 0 ;AN000; no match flags
203 DW 2 ;AN000; capitalize by char table
204 DW RESGROUP:COMND1_OUTPUT ;AN000; result buffer
205 DW RESGROUP:NO_VAL ;AN000;
206 DB 1 ;AN000; 1 keyword
207COMMAND_D_SYN DB "/D",0 ;AN000; /D switch
208
209COMMAND_SWITCH4 LABEL BYTE ;AN000;
210 DW 8000H ;AN000; numeric value - required
211 DW 0 ;AN000; no function flags
212 DW RESGROUP:COMND1_OUTPUT ;AN000; result buffer
213 DW RESGROUP:COMMAND_E_VAL ;AN000; pointer to value list
214 DB 1 ;AN000; 1 keyword
215COMMAND_E_SYN DB "/E",0 ;AN000; /E switch
216
217COMMAND_E_VAL LABEL BYTE ;AN000;
218 DB 1 ;AN000;
219 DB 1 ;AN000; 1 range
220 DB 1 ;AN000; returned if result
221 DD ENVSML,ENVBIG ;AN000; minimum & maximum value
222 DB 0 ;AN000; no numeric values
223 DB 0 ;AN000; no string values
224
225COMMAND_SWITCH5 LABEL BYTE ;AN000;
226 DW 0 ;AN000; no match flags
227 DW 2 ;AN000; capitalize by char table
228 DW RESGROUP:COMND1_OUTPUT ;AN000; result buffer
229 DW RESGROUP:NO_VAL ;AN000;
230 DB 1 ;AN000; 1 keyword
231COMMAND_C_SYN DB "/C",0 ;AN000; /C switch
232
233COMMAND_SWITCH6 LABEL BYTE ;AN000;
234 DW 0 ;AN000; no match flags
235 DW 2 ;AN000; capitalize by char table
236 DW RESGROUP:COMND1_OUTPUT ;AN000; result buffer
237 DW RESGROUP:NO_VAL ;AN000;
238 DB 1 ;AN000; 1 keyword
239COMMAND_M_SYN DB "/MSG",0 ;AN000; /MSG switch
240
241COMND1_OUTPUT LABEL BYTE ;AN000;
242COMND1_TYPE DB 0 ;AN000; type
243COMND1_CODE DB 0 ;AN000; return value
244COMND1_SYN DW 0 ;AN000; synonym pointer
245COMND1_ADDR DD 0 ;AN000; numeric value / address
246 ; of string value
247
248NO_VAL DB 0 ;AN000; no values
249num_positionals DW 0 ;AN000; counter for positionals
250old_parse_ptr DW 0 ;AN057; SI position before calling parser
251
252.xlist
253.xcref
254
255INCLUDE SYSMSG.INC ;AN000; get message services routine
256
257.list
258.cref
259
260ASSUME DS:RESGROUP,ES:RESGROUP,CS:RESGROUP
261
262MSG_UTILNAME <COMMAND> ;AN000; define utility name
263
264MSG_SERVICES <COMR,COMMAND.CLB> ;AN000; include initialization messages
265
266include msgdcl.inc
267
268INIT ENDS
269
270 END