summaryrefslogtreecommitdiff
path: root/v4.0/src/CMD/COMMAND/TCODE.ASM
diff options
context:
space:
mode:
Diffstat (limited to 'v4.0/src/CMD/COMMAND/TCODE.ASM')
-rw-r--r--v4.0/src/CMD/COMMAND/TCODE.ASM540
1 files changed, 540 insertions, 0 deletions
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