summaryrefslogtreecommitdiff
path: root/v2.0/source/TCODE.ASM
diff options
context:
space:
mode:
authorGravatar Rich Turner1983-08-12 17:53:34 -0700
committerGravatar Rich Turner2018-09-21 17:53:34 -0700
commit80ab2fddfdf30f09f0a0a637654cbb3cd5c7baa6 (patch)
treeee4357f7f3dd0f2ded59b9c6e7384432d85e7ec9 /v2.0/source/TCODE.ASM
parentMS-DOS v1.25 Release (diff)
downloadms-dos-80ab2fddfdf30f09f0a0a637654cbb3cd5c7baa6.tar.gz
ms-dos-80ab2fddfdf30f09f0a0a637654cbb3cd5c7baa6.tar.xz
ms-dos-80ab2fddfdf30f09f0a0a637654cbb3cd5c7baa6.zip
MS-DOS v2.0 Release
Diffstat (limited to 'v2.0/source/TCODE.ASM')
-rw-r--r--v2.0/source/TCODE.ASM1088
1 files changed, 1088 insertions, 0 deletions
diff --git a/v2.0/source/TCODE.ASM b/v2.0/source/TCODE.ASM
new file mode 100644
index 0000000..dfe6ca5
--- /dev/null
+++ b/v2.0/source/TCODE.ASM
@@ -0,0 +1,1088 @@
1TITLE PART1 - COMMAND Transient routines.
2
3 INCLUDE COMSW.ASM
4
5.xlist
6.xcref
7 INCLUDE DOSSYM.ASM
8 INCLUDE DEVSYM.ASM
9 INCLUDE COMSEG.ASM
10.list
11.cref
12
13 INCLUDE COMEQU.ASM
14
15
16DATARES SEGMENT PUBLIC
17 EXTRN BATCH:WORD,BATLOC:DWORD,PARMBUF:BYTE
18 EXTRN RESTDIR:BYTE,EXTCOM:BYTE,ECHOFLAG:BYTE
19 EXTRN SINGLECOM:WORD,VERVAL:WORD,FORFLAG:BYTE
20 EXTRN RE_INSTR:BYTE,RE_OUT_APP:BYTE,PIPE1:BYTE,PIPE2:BYTE
21 EXTRN RE_OUTSTR:BYTE,PIPEFLAG:BYTE,PIPEFILES:BYTE,PIPEPTR:WORD
22 EXTRN INPIPEPTR:WORD,OUTPIPEPTR:WORD,EXEC_BLOCK:BYTE,ENVIRSEG:WORD
23DATARES ENDS
24
25TRANDATA SEGMENT PUBLIC
26 EXTRN BADBAT:BYTE,NEEDBAT:BYTE,BADNAM:BYTE
27 EXTRN SYNTMES:BYTE,BADDRV:BYTE,BYTMES_POST:BYTE
28 EXTRN DIRMES_PRE:BYTE,DIRMES_POST:BYTE,BYTMES_PRE:BYTE
29 EXTRN NOTFND:BYTE,PIPEEMES:BYTE,BADPMES:BYTE,COMTAB:BYTE
30TRANDATA ENDS
31
32TRANSPACE SEGMENT PUBLIC
33 EXTRN UCOMBUF:BYTE,COMBUF:BYTE,USERDIR1:BYTE,EXECPATH:BYTE
34 EXTRN DIRCHAR:BYTE,EXEC_ADDR:DWORD,RCH_ADDR:DWORD,CHKDRV:BYTE
35 EXTRN CURDRV:BYTE,PARM1:BYTE,PARM2:BYTE,COMSW:WORD,ARG1S:WORD
36 EXTRN ARG2S:WORD,ARGTS:WORD,SPECDRV:BYTE,BYTCNT:WORD,IDLEN:BYTE
37 EXTRN DIRBUF:BYTE,ID:BYTE,COM:BYTE,LINCNT:BYTE,INTERNATVARS:BYTE
38 EXTRN HEADCALL:DWORD,RESSEG:WORD,TPA:WORD,SWITCHAR:BYTE
39 EXTRN STACK:WORD,FILTYP:BYTE,FILECNT:WORD,LINLEN:BYTE
40
41
42 IF KANJI
43 EXTRN KPARSE:BYTE
44 ENDIF
45TRANSPACE ENDS
46
47; ********************************************************************
48; START OF TRANSIENT PORTION
49; This code is loaded at the end of memory and may be overwritten by
50; memory-intensive user programs.
51
52TRANCODE SEGMENT PUBLIC PARA
53ASSUME CS:TRANGROUP,DS:NOTHING,ES:NOTHING,SS:NOTHING
54
55
56 EXTRN SCANOFF:NEAR,DELIM:NEAR,SAVUDIR:NEAR,SAVUDIR1:NEAR
57 EXTRN PATHCHRCMP:NEAR,PRINT:NEAR,RESTUDIR:NEAR
58 EXTRN CRLF2:NEAR,PRINT_PROMPT:NEAR,GETBATBYT:NEAR,PRESCAN:NEAR
59 EXTRN CRPRINT:NEAR,DISP32BITS:NEAR,FCB_TO_ASCZ:NEAR
60 EXTRN ERROR_PRINT:NEAR,FREE_TPA:NEAR,ALLOC_TPA:NEAR
61 EXTRN $EXIT:NEAR,FORPROC:NEAR,FIND_NAME_IN_ENVIRONMENT:NEAR
62 EXTRN UPCONV:NEAR,BATOPEN:NEAR,BATCLOSE:NEAR,IOSET:NEAR,FIND_PATH:NEAR
63 EXTRN TESTDOREIN:NEAR,TESTDOREOUT:NEAR
64
65 PUBLIC SWLIST,CERROR,SETREST1,DOCOM,DOCOM1,DRVBAD,NOTFNDERR
66 PUBLIC COMMAND,TCOMMAND,SWITCH,PIPEERRSYN,GETKEYSTROKE,SETREST
67 PUBLIC CHKCNT
68
69
70 IF KANJI
71 EXTRN TESTKANJ:NEAR
72 ENDIF
73
74 ORG 0
75ZERO = $
76
77 ORG 100H ; Allow for 100H parameter area
78
79SETDRV:
80 MOV AH,SET_DEFAULT_DRIVE
81 INT int_command
82TCOMMAND:
83 MOV DS,[RESSEG]
84ASSUME DS:RESGROUP
85 MOV AX,-1
86 XCHG AX,[VERVAL]
87 CMP AX,-1
88 JZ NOSETVER2
89 MOV AH,SET_VERIFY_ON_WRITE ; AL has correct value
90 INT int_command
91NOSETVER2:
92 CALL [HEADCALL] ; Make sure header fixed
93 XOR BP,BP ; Flag transient not read
94 CMP [SINGLECOM],-1
95 JNZ COMMAND
96$EXITPREP:
97 PUSH CS
98 POP DS
99 JMP $EXIT ; Have finished the single command
100ASSUME DS:NOTHING
101COMMAND:
102 CLD
103 MOV AX,CS
104 MOV SS,AX
105ASSUME SS:TRANGROUP
106 MOV SP,OFFSET TRANGROUP:STACK
107 MOV ES,AX
108ASSUME ES:TRANGROUP
109 MOV DS,[RESSEG]
110ASSUME DS:RESGROUP
111 STI
112
113 MOV [UCOMBUF],COMBUFLEN ; Init UCOMBUF
114 MOV [COMBUF],COMBUFLEN ; Init COMBUF (Autoexec doing DATE)
115 OR BP,BP ; See if just read
116 JZ TESTRDIR ; Not read, check user directory
117 MOV WORD PTR [UCOMBUF+1],0D01H ; Reset buffer
118 JMP SHORT NOSETBUF
119TESTRDIR:
120 CMP [RESTDIR],0
121 JZ NOSETBUF ; User directory OK
122 PUSH DS
123 PUSH CS
124 POP DS
125ASSUME DS:TRANGROUP
126 MOV DX,OFFSET TRANGROUP:USERDIR1
127 MOV AH,CHDIR
128 INT int_command ; Restore users directory
129 POP DS
130ASSUME DS:RESGROUP
131NOSETBUF:
132 CMP [PIPEFILES],0
133 JZ NOPCLOSE ; Don't bother if they don't exist
134 CMP [PIPEFLAG],0
135 JNZ NOPCLOSE ; Don't del if still piping
136 CALL PIPEDEL
137NOPCLOSE:
138 MOV [EXTCOM],0 ; Flag internal command
139 MOV [RESTDIR],0 ; Flag users dirs OK
140 MOV AX,CS ; Get segment we're in
141 MOV DS,AX
142ASSUME DS:TRANGROUP
143 PUSH AX
144 MOV DX,OFFSET TRANGROUP:INTERNATVARS
145 MOV AX,INTERNATIONAL SHL 8
146 INT 21H
147 POP AX
148 SUB AX,[TPA] ; AX=size of TPA in paragraphs
149 MOV DX,16
150 MUL DX ; DX:AX=size of TPA in bytes
151 OR DX,DX ; See if over 64K
152 JZ SAVSIZ ; OK if not
153 MOV AX,-1 ; If so, limit to 65535 bytes
154SAVSIZ:
155 MOV [BYTCNT],AX ; Max no. of bytes that can be buffered
156 MOV DS,[RESSEG] ; All batch work must use resident seg.
157ASSUME DS:RESGROUP
158 TEST [ECHOFLAG],-1
159 JZ GETCOM ; Don't do the CRLF
160 CALL SINGLETEST
161 JB GETCOM
162 CALL CRLF2
163GETCOM:
164 MOV AH,GET_DEFAULT_DRIVE
165 INT int_command
166 MOV [CURDRV],AL
167 TEST [ECHOFLAG],-1
168 JZ NOPDRV ; No prompt if echo off
169 CALL SINGLETEST
170 JB NOPDRV
171 CALL PRINT_PROMPT ; Prompt the user
172NOPDRV:
173 TEST [PIPEFLAG],-1 ; Pipe has highest presedence
174 JZ NOPIPE
175 JMP PIPEPROC ; Continue the pipeline
176NOPIPE:
177 TEST [FORFLAG],-1 ; FOR has next highest precedence
178 JZ TESTFORBAT
179 JMP FORPROC ; Continue the FOR
180TESTFORBAT:
181 MOV [RE_INSTR],0 ; Turn redirection back off
182 MOV [RE_OUTSTR],0
183 MOV [RE_OUT_APP],0
184 TEST [BATCH],-1 ; Batch has lowest precedence
185 JZ ISNOBAT
186 JMP READBAT ; Continue BATCH
187
188ISNOBAT:
189 CMP [SINGLECOM],0
190 JZ REGCOM
191 MOV SI,-1
192 XCHG SI,[SINGLECOM]
193 MOV DI,OFFSET TRANGROUP:COMBUF + 2
194 XOR CX,CX
195SINGLELOOP:
196 LODSB
197 STOSB
198 INC CX
199 CMP AL,0DH
200 JNZ SINGLELOOP
201 DEC CX
202 PUSH CS
203 POP DS
204ASSUME DS:TRANGROUP
205 MOV [COMBUF + 1],CL
206 JMP DOCOM
207
208REGCOM:
209 PUSH CS
210 POP DS ; Need local segment to point to buffer
211 MOV DX,OFFSET TRANGROUP:UCOMBUF
212 MOV AH,STD_CON_STRING_INPUT
213 INT int_command ; Get a command
214 MOV CL,[UCOMBUF]
215 XOR CH,CH
216 ADD CX,3
217 MOV SI,OFFSET TRANGROUP:UCOMBUF
218 MOV DI,OFFSET TRANGROUP:COMBUF
219 REP MOVSB ; Transfer it to the cooked buffer
220 JMP DOCOM
221
222; All batch proccessing has DS set to segment of resident portion
223ASSUME DS:RESGROUP,ES:TRANGROUP
224
225NEEDENV:
226 PUSH DS
227 PUSH SI
228 PUSH DI
229
230 MOV DI,OFFSET TRANGROUP:ID
231 ADD AL,"0"
232 STOSB
233GETENV1:
234 CALL GETBATBYT
235 STOSB
236 CMP AL,13
237 JZ GETENV2
238 CMP AL,"%"
239 JNZ GETENV1
240 MOV BYTE PTR ES:[DI-1],"="
241GETENV2:
242 MOV SI,OFFSET TRANGROUP:ID
243 PUSH CS
244 POP DS ; DS:SI POINTS TO NAME
245ASSUME DS:TRANGROUP,ES:RESGROUP
246 CALL FIND_NAME_IN_environment
247 PUSH ES
248 POP DS
249 PUSH CS
250 POP ES
251ASSUME DS:RESGROUP,ES:TRANGROUP
252 MOV SI,DI
253 POP DI ; get back pointer to command line
254 JNC GETENV4
255
256GETENV3: ; Parameter not found
257 PUSH CS
258 POP DS
259 MOV SI,OFFSET TRANGROUP:ID
260
261GETENV4:
262 LODSB ; From resident segment
263 OR AL,AL ; Check for end of parameter
264 JZ GETENV6
265 CMP AL,13
266 JZ GETENV6
267 CMP AL,"="
268 JZ GETENVX
269 STOSB
270 JMP GETENV4
271
272GETENVX:
273 MOV AL,"%"
274 STOSB
275GETENV6:
276 POP SI
277 POP DS
278 CMP AL,13
279 JZ SAVBATBYTJ
280 JMP RDBAT
281
282NEEDPARM:
283 CALL GETBATBYT
284 CMP AL,"%" ; Check for two consecutive %
285 JZ SAVBATBYTJ
286 CMP AL,13 ; Check for end-of-line
287 JNZ PAROK
288SAVBATBYTJ:
289 JMP SAVBATBYT
290PAROK:
291 SUB AL,"0"
292 JB NEEDENV ; look for parameter in the environment
293 CMP AL,9
294 JA NEEDENV
295
296 CBW
297 MOV SI,AX
298 SHL SI,1 ; Two bytes per entry
299 PUSH ES
300 PUSH DI
301 MOV ES,[BATCH]
302 XOR CX,CX
303 MOV AX,CX
304 MOV DI,CX
305 DEC CX
306 REPNZ SCASB
307 ADD DI,SI
308 MOV SI,ES:[DI]
309 POP DI
310 POP ES
311 CMP SI,-1 ; Check if parameter exists
312 JZ RDBAT ; Ignore if it doesn't
313RDPARM:
314 LODSB ; From resident segment
315 CMP AL,0DH ; Check for end of parameter
316 JZ RDBAT
317 STOSB
318 JMP RDPARM
319
320PROMPTBAT:
321 MOV DX,OFFSET TRANGROUP:NEEDBAT
322 CALL [RCH_ADDR]
323 JZ AskForBat ; Media is removable
324NoAskForBat:
325 MOV ES,[BATCH] ; Turn off batch
326 MOV AH,DEALLOC
327 INT int_command ; free up the batch piece
328 MOV [BATCH],0 ; AFTER DEALLOC in case of ^C
329 MOV [FORFLAG],0 ; Turn off for processing
330 MOV [PIPEFLAG],0 ; Turn off any pipe
331 PUSH CS
332 POP DS
333 MOV DX,OFFSET TRANGROUP:BADBAT
334 CALL ERROR_PRINT ; Tell user no batch file
335 JMP TCOMMAND
336
337ASKFORBAT:
338 PUSH CS
339 POP DS
340 CALL ERROR_PRINT ; Prompt for batch file
341 CALL GetKeystroke
342 JMP TCOMMAND
343;**************************************************************************
344; read the next keystroke
345
346GetKeystroke:
347 MOV AX,(STD_CON_INPUT_FLUSH SHL 8) OR STD_CON_INPUT_no_echo
348 INT int_command ; Get character with KB buffer flush
349 MOV AX,(STD_CON_INPUT_FLUSH SHL 8) + 0
350 INT int_command
351 return
352
353READBAT:
354 CALL BATOPEN
355 JC PROMPTBAT
356 MOV DI,OFFSET TRANGROUP:COMBUF+2
357TESTNOP:
358 CALL GETBATBYT
359 CMP AL,':' ; Label/Comment?
360 JNZ NOTLABEL
361NOPLINE: ; Consume the line
362 CALL GETBATBYT
363 CMP AL,0DH
364 JNZ NOPLINE
365 CALL GETBATBYT ; Eat Linefeed
366 TEST [BATCH],-1
367 JNZ TESTNOP
368 JMP TCOMMAND ; Hit EOF
369
370RDBAT:
371 CALL GETBATBYT
372NOTLABEL:
373 CMP AL,"%" ; Check for parameter
374 JNZ SAVBATBYT
375 JMP NEEDPARM
376SAVBATBYT:
377 STOSB
378 CMP AL,0DH
379 JNZ RDBAT
380 SUB DI,OFFSET TRANGROUP:COMBUF+3
381 MOV AX,DI
382 MOV ES:[COMBUF+1],AL ; Set length of line
383 CALL GETBATBYT ; Eat linefeed
384 CALL BATCLOSE
385 TEST [ECHOFLAG],-1
386 PUSH CS
387 POP DS ; Go back to local segment
388 JZ NOECHO2
389ASSUME DS:TRANGROUP
390 MOV DX,OFFSET TRANGROUP:COMBUF+2
391 CALL CRPRINT
392DOCOM:
393; All segments are local for command line processing
394 CALL CRLF2
395DOCOM1:
396
397NOECHO2:
398 CALL PRESCAN ; Cook the input buffer
399 JZ NOPIPEPROC
400 JMP PIPEPROCSTRT ; Fire up the pipe
401NOPIPEPROC:
402 MOV SI,OFFSET TRANGROUP:COMBUF+2
403 MOV DI,OFFSET TRANGROUP:IDLEN
404 MOV AX,(PARSE_FILE_DESCRIPTOR SHL 8) OR 01H ; Make FCB with blank scan-off
405 INT int_command
406 CMP AL,1 ; Check for ambiguous command name
407 JZ BADCOMJ1 ; Ambiguous commands not allowed
408 CMP AL,-1
409 JNZ DRVGD
410 JMP DRVBAD
411
412BADCOMJ1:
413 JMP BADCOM
414
415DRVGD:
416 MOV AL,[DI]
417 MOV [SPECDRV],AL
418 MOV AL," "
419 MOV CX,9
420 INC DI
421 REPNE SCASB ; Count no. of letters in command name
422 MOV AL,9
423 SUB AL,CL
424 MOV [IDLEN],AL
425 MOV DI,81H
426 XOR CX,CX
427 PUSH SI
428COMTAIL:
429 LODSB
430 STOSB ; Move command tail to 80H
431 CMP AL,13
432 LOOPNZ COMTAIL
433 NOT CL
434 MOV BYTE PTR DS:[80H],CL
435 POP SI
436; If the command has 0 parameters must check here for
437; any switches that might be present.
438; SI -> first character after the command.
439 CALL SWITCH ; Is the next character a SWITCHAR
440 MOV [COMSW],AX
441 MOV DI,FCB
442 MOV AX,(PARSE_FILE_DESCRIPTOR SHL 8) OR 01H
443 INT int_command
444 MOV [PARM1],AL ; Save result of parse
445
446PRBEG:
447 LODSB
448 CMP AL,[SWITCHAR]
449 JZ PRFIN
450 CMP AL,13
451 JZ PRFIN
452 CALL DELIM
453 JNZ PRBEG
454PRFIN:
455 DEC SI
456 CALL SWITCH
457 MOV [ARG1S],AX
458 MOV DI,FCB+10H
459 MOV AX,(PARSE_FILE_DESCRIPTOR SHL 8) OR 01H
460 INT int_command ; Parse file name
461 MOV [PARM2],AL ; Save result
462 CALL SWITCH
463 MOV [ARG2S],AX
464 OR AX,[ARG1S]
465 MOV [ARGTS],AX
466SWTLP: ; Find any remaining switches
467 CMP BYTE PTR [SI],0DH
468 JZ GOTALLSW
469 INC SI
470 CALL SWITCH
471 OR [ARGTS],AX
472 JMP SHORT SWTLP
473
474GOTALLSW:
475 MOV AL,[IDLEN]
476 MOV DL,[SPECDRV]
477 OR DL,DL ; Check if drive was specified
478 JZ OK
479 JMP DRVCHK
480OK:
481 DEC AL ; Check for null command
482 JNZ FNDCOM
483 MOV DS,[RESSEG]
484ASSUME DS:RESGROUP
485 CMP [SINGLECOM],-1
486 JZ EXITJ
487 JMP GETCOM
488
489EXITJ:
490 JMP $EXITPREP
491ASSUME DS:TRANGROUP
492
493RETSW:
494 XCHG AX,BX ; Put switches in AX
495 return
496
497SWITCH:
498 XOR BX,BX ; Initialize - no switches set
499SWLOOP:
500 CALL SCANOFF ; Skip any delimiters
501 CMP AL,[SWITCHAR] ; Is it a switch specifier?
502 JNZ RETSW ; No -- we're finished
503 OR BX,GOTSWITCH ; Indicate there is a switch specified
504 INC SI ; Skip over the switch character
505 CALL SCANOFF
506 CMP AL,0DH
507 JZ RETSW ; Oops
508 INC SI
509; Convert lower case input to upper case
510 CALL UPCONV
511 MOV DI,OFFSET TRANGROUP:SWLIST
512 MOV CX,SWCOUNT
513 REPNE SCASB ; Look for matching switch
514 JNZ BADSW
515 MOV AX,1
516 SHL AX,CL ; Set a bit for the switch
517 OR BX,AX
518 JMP SHORT SWLOOP
519
520BADSW:
521 JMP SHORT SWLOOP
522
523SWLIST DB "VBAPW"
524SWCOUNT EQU $-SWLIST
525
526DRVBAD:
527 MOV DX,OFFSET TRANGROUP:BADDRV
528 JMP CERROR
529
530FNDCOM:
531 MOV SI,OFFSET TRANGROUP:COMTAB ; Prepare to search command table
532 MOV CH,0
533FINDCOM:
534 MOV DI,OFFSET TRANGROUP:IDLEN
535 MOV CL,[SI]
536 JCXZ EXTERNAL
537 REPE CMPSB
538 LAHF
539 ADD SI,CX ; Bump to next position without affecting flags
540 SAHF
541 LODSB ; Get flag for drive check
542 MOV [CHKDRV],AL
543 LODSW ; Get address of command
544 JNZ FINDCOM
545 MOV DX,AX
546 CMP [CHKDRV],0
547 JZ NOCHECK
548 MOV AL,[PARM1]
549 OR AL,[PARM2] ; Check if either parm. had invalid drive
550 CMP AL,-1
551 JZ DRVBAD
552NOCHECK:
553 CALL IOSET
554 CALL DX ; Call the internal
555COMJMP:
556 JMP TCOMMAND
557
558SETDRV1:
559 JMP SETDRV
560
561DRVCHK:
562 DEC DL ; Adjust for correct drive number
563 DEC AL ; Check if anything else is on line
564 JZ SETDRV1
565EXTERNAL:
566 MOV [FILTYP],0
567 MOV DL,[SPECDRV]
568 MOV [IDLEN],DL
569 CALL SAVUDIR ; Drive letter already checked
570 MOV AL,'?'
571 MOV DI,OFFSET TRANGROUP:COM
572 STOSB ; Look for any extension
573 STOSB
574 STOSB
575 MOV DX,OFFSET TRANGROUP:DIRBUF ; Command will end up here
576 MOV AH,SET_DMA
577 INT int_command
578 PUSH ES
579 CALL FIND_PATH
580 MOV SI,DI
581 POP ES
582
583 MOV DI,OFFSET TRANGROUP:EXECPATH
584 MOV BYTE PTR [DI],0 ; Initialize to current directory
585RESEARCH:
586 MOV AH,DIR_SEARCH_FIRST
587COMSRCH:
588 PUSH CS
589 POP DS
590 MOV DX,OFFSET TRANGROUP:IDLEN
591 INT int_command
592 OR AL,AL
593 MOV AH,DIR_SEARCH_NEXT ; Do search-next next
594 JNZ PATHCHK
595 CMP WORD PTR [DIRBUF+9],4F00H + "C"
596 JNZ CHKEXE
597 CMP [DIRBUF+11],"M"
598 JNZ CHKEXE
599 OR [FILTYP],4
600 JMP EXECUTE ; If we find a COM were done
601
602CHKEXE:
603 CMP WORD PTR [DIRBUF+9],5800H + "E"
604 JNZ CHKBAT
605 CMP [DIRBUF+11],"E"
606 JNZ CHKBAT
607 OR [FILTYP],1 ; Flag an EXE found
608 JMP COMSRCH ; Continue search
609
610CHKBAT:
611 CMP WORD PTR [DIRBUF+9],4100H + "B"
612 JNZ COMSRCH
613 CMP [DIRBUF+11],"T"
614 JNZ COMSRCH
615 OR [FILTYP],2 ; Flag BAT found
616 JMP COMSRCH ; Continue search
617
618PATHCHK:
619 TEST [FILTYP],1
620 JZ TESTBAT
621 MOV WORD PTR [DIRBUF+9],5800H+"E"
622 MOV [DIRBUF+11],"E"
623 JMP EXECUTE ; Found EXE
624
625TESTBAT:
626 TEST [FILTYP],2
627 JZ NEXTPATH ; Found nothing, try next path
628 MOV WORD PTR [DIRBUF+9],4100H+"B"
629 MOV [DIRBUF+11],"T"
630 MOV DX,OFFSET TRANGROUP:DIRBUF ; Found BAT
631 MOV AH,FCB_OPEN
632 INT int_command
633 OR AL,AL
634 JZ BATCOMJ ; Bat exists
635 CALL RESTUDIR
636 JMP BADCOM
637
638BATCOMJ:
639 JMP BATCOM
640
641NEXTPATH:
642 MOV DX,OFFSET TRANGROUP:USERDIR1 ; Restore users dir
643 MOV AH,CHDIR
644 INT int_command
645 MOV DS,[RESSEG]
646ASSUME DS:RESGROUP
647 MOV [RESTDIR],0
648BADPATHEL:
649 MOV DI,OFFSET TRANGROUP:EXECPATH ; Build a full path here
650 MOV DX,SI
651 MOV DS,[ENVIRSEG] ; Point into environment
652ASSUME DS:NOTHING
653 LODSB
654
655 IF KANJI
656 MOV [KPARSE],0
657 ENDIF
658
659 OR AL,AL
660 JZ BADCOMJ ; NUL, command not found
661 XOR BL,BL ; Make BL a NUL
662PSKIPLP: ; Get the path
663 STOSB
664 OR AL,AL
665 JZ LASTPATH
666 CMP AL,';'
667 JZ GOTNEXTPATH
668 CMP DI,15+DirStrLen+(OFFSET TRANGROUP:EXECPATH)
669 JB OKPath
670SKIPPathElem:
671 LODSB ; scan to end of path element
672 OR AL,AL
673 JZ BadPathEl
674 CMP AL,';'
675 JZ BadPathEl
676 JMP SkipPathElem
677
678OKPath:
679 IF KANJI
680 MOV [KPARSE],0
681 CALL TESTKANJ
682 JZ NXTPTCHR
683 INC [KPARSE]
684 MOVSB
685NXTPTCHR:
686 ENDIF
687
688 LODSB
689 JMP SHORT PSKIPLP
690
691BADCOMJ:
692 JMP BADCOM
693
694LASTPATH:
695 MOV BYTE PTR ES:[DI-1],';' ; Fix up the NUL in EXECPATH
696 DEC SI ; Point to the NUL in PATHSTRING
697 MOV BL,[SI-1] ; Change substi char to char before NUL
698
699GOTNEXTPATH:
700 DEC DI ; Point to the end of the dir
701 PUSH BX
702 PUSH SI
703 PUSH DX
704 MOV SI,DX
705 XOR DL,DL
706 CMP BYTE PTR [SI+1],DRVCHAR
707 JNZ DEFDRVPATH ; No drive spec
708 MOV DL,[SI]
709 SUB DL,'@'
710DEFDRVPATH:
711 PUSH DS
712 PUSH CS
713 POP DS
714ASSUME DS:TRANGROUP
715 MOV [IDLEN],DL ; New drive
716 PUSH DI
717 CALL SAVUDIR ; Save the users dir
718 POP DI
719 JNC PATHTRY
720 MOV DX,OFFSET TRANGROUP:BADPMES ; Tell the user bad stuff in path
721 CALL PRINT
722PATHTRY:
723 POP DS
724ASSUME DS:NOTHING
725 POP DX
726 POP SI
727 POP BX
728 XCHG BL,[SI-1] ; Stick in NUL, or same thing if LASTPATH
729CDPATH:
730 MOV AH,CHDIR
731 INT int_command
732 MOV [SI-1],BL ; Fix the path string back up
733 MOV DS,[RESSEG]
734ASSUME DS:RESGROUP
735 INC [RESTDIR] ; Say users dir needs restoring
736 JNC ResearchJ
737 JMP BADPATHEL ; Ignore a directory which doesn't exist
738ResearchJ:
739 JMP RESEARCH ; Try looking in this one
740
741BATCOM:
742ASSUME DS:TRANGROUP
743; Batch parameters are read with ES set to segment of resident part
744 CALL IOSET ; Set up any redirection
745 MOV ES,[RESSEG]
746ASSUME ES:RESGROUP
747;Since BATCH has lower precedence than PIPE or FOR. If a new BATCH file
748;is being started it MUST be true that no FOR or PIPE is currently in
749;progress.
750 MOV [FORFLAG],0 ; Turn off for processing
751 MOV [PIPEFLAG],0 ; Turn off any pipe
752 TEST [BATCH],-1
753 JNZ CHAINBAT ; Don't need allocation if chaining
754 CALL FREE_TPA
755ASSUME ES:RESGROUP
756 MOV BX,6 ; 64 + 32 bytes
757 MOV AH,ALLOC
758 INT int_command ; Suck up a little piece for batch processing
759 MOV [BATCH],AX
760 CALL ALLOC_TPA
761CHAINBAT:
762 PUSH ES
763 MOV ES,[BATCH]
764ASSUME ES:NOTHING
765 MOV DL,[DIRBUF]
766 XOR DI,DI
767 CALL SAVUDIR1 ; ES:DI set up, get dir containing Batch file
768 XOR AX,AX
769 MOV CX,AX
770 DEC CX
771 REPNZ SCASB ; Find the NUL
772 DEC DI ; Point at the NUL
773 MOV AL,[DIRCHAR]
774 CMP AL,ES:[DI-1]
775 JZ NOPUTSLASH
776 STOSB
777NOPUTSLASH:
778 MOV SI,OFFSET TRANGROUP:DIRBUF+1
779 CALL FCB_TO_ASCZ ; Tack on batch file name
780 MOV AX,-1
781 MOV BX,DI
782 MOV CX,10
783 REP STOSW ; Init Parmtab to no parms
784 POP ES
785ASSUME ES:RESGROUP
786 CALL RESTUDIR
787 MOV SI,OFFSET TRANGROUP:COMBUF+2
788 MOV DI,OFFSET RESGROUP:PARMBUF
789 MOV CX,10
790EACHPARM:
791 CALL SCANOFF
792 CMP AL,0DH
793 JZ HAVPARM
794 JCXZ MOVPARM ; Only first 10 parms get pointers
795 PUSH ES
796 MOV ES,[BATCH]
797 MOV ES:[BX],DI ; Set pointer table to point to actual parameter
798 POP ES
799 INC BX
800 INC BX
801MOVPARM:
802 LODSB
803 CALL DELIM
804 JZ ENDPARM ; Check for end of parameter
805 STOSB
806 CMP AL,0DH
807 JZ HAVPARM
808 JMP SHORT MOVPARM
809ENDPARM:
810 MOV AL,0DH
811 STOSB ; End-of-parameter marker
812 JCXZ EACHPARM
813 DEC CX
814 JMP SHORT EACHPARM
815HAVPARM:
816 XOR AL,AL
817 STOSB ; Nul terminate the parms
818 XOR AX,AX
819 PUSH ES
820 POP DS ; Simply batch FCB setup
821ASSUME DS:RESGROUP
822 MOV WORD PTR [BATLOC],AX ; Start at beginning of file
823 MOV WORD PTR [BATLOC+2],AX
824 CMP [SINGLECOM],-1
825 JNZ NOBATSING
826 MOV [SINGLECOM],0FFF0H ; Flag single command BATCH job
827NOBATSING:
828 JMP TCOMMAND
829ASSUME DS:TRANGROUP,ES:TRANGROUP
830
831EXECUTE:
832 CALL RESTUDIR
833NeoExecute:
834 CMP BYTE PTR [DI],0 ; Command in current directory
835 JZ NNSLSH
836 MOV AL,[DI-1]
837
838 IF KANJI
839 CMP [KPARSE],0
840 JNZ StuffPath ; Last char is second KANJI byte, might be '\'
841 ENDIF
842
843 CALL PATHCHRCMP
844 JZ HAVEXP ; Don't double slash
845StuffPath:
846 MOV AL,[DIRCHAR]
847 STOSB
848 JMP SHORT HAVEXP
849
850NNSLSH:
851 MOV AL,[DIRBUF] ; Specify a drive
852 ADD AL,'@'
853 STOSB
854 MOV AL,DRVCHAR
855 STOSB
856HAVEXP:
857 MOV SI,OFFSET TRANGROUP:DIRBUF+1
858 CALL FCB_TO_ASCZ ; Tack on the filename
859 CALL IOSET
860 MOV ES,[TPA]
861 MOV AH,DEALLOC
862 INT int_command ; Now running in "free" space
863 MOV ES,[RESSEG]
864ASSUME ES:RESGROUP
865 INC [EXTCOM] ; Indicate external command
866 MOV [RESTDIR],0 ; Since USERDIR1 is in transient, insure
867 ; this flag value for re-entry to COMMAND
868 MOV DI,FCB
869 MOV SI,DI
870 MOV CX,052H
871 REP MOVSW ; Transfer parameters to resident header
872 MOV DX,OFFSET TRANGROUP:EXECPATH
873 MOV BX,OFFSET RESGROUP:EXEC_BLOCK
874 MOV AX,EXEC SHL 8
875 JMP [EXEC_ADDR] ; Jmp to the EXEC in the resident
876
877BADCOM:
878 PUSH CS
879 POP DS
880 MOV DX,OFFSET TRANGROUP:BADNAM
881CERROR:
882 CALL ERROR_PRINT
883 JMP TCOMMAND
884
885SINGLETEST:
886ASSUME DS:RESGROUP
887 CMP [SINGLECOM],0
888 JZ RET5
889 CMP [SINGLECOM],0EFFFH
890 return
891
892
893ASSUME DS:TRANGROUP
894SETREST1:
895 MOV AL,1
896SETREST:
897 PUSH DS
898 MOV DS,[RESSEG]
899ASSUME DS:RESGROUP
900 MOV [RESTDIR],AL
901 POP DS
902ASSUME DS:TRANGROUP
903RET5:
904 return
905
906CHKCNT:
907 TEST [FILECNT],-1
908 JNZ ENDDIR
909NOTFNDERR:
910 MOV DX,OFFSET TRANGROUP:NOTFND
911 JMP CERROR
912
913ENDDIR:
914; Make sure last line ends with CR/LF
915 MOV AL,[LINLEN]
916 CMP AL,[LINCNT] ; Will be equal if just had CR/LF
917 JZ MESSAGE
918 CALL CRLF2
919MESSAGE:
920 MOV DX,OFFSET TRANGROUP:DIRMES_PRE
921 CALL PRINT
922 MOV SI,[FILECNT]
923 XOR DI,DI
924 CALL DISP32BITS
925 MOV DX,OFFSET TRANGROUP:DIRMES_POST
926 CALL PRINT
927 MOV AH,GET_DRIVE_FREESPACE
928 MOV DL,BYTE PTR DS:[FCB]
929 INT int_command
930 CMP AX,-1
931 retz
932 MOV DX,OFFSET TRANGROUP:BYTMES_PRE
933 CALL PRINT
934 MUL CX ; AX is bytes per cluster
935 MUL BX
936 MOV DI,DX
937 MOV SI,AX
938 CALL DISP32BITS
939 MOV DX,OFFSET TRANGROUP:BYTMES_POST
940 JMP PRINT
941
942ASSUME DS:RESGROUP
943
944PIPEDEL:
945 PUSH DX
946 MOV DX,OFFSET RESGROUP:PIPE1 ; Clean up in case ^C
947 MOV AH,UNLINK
948 INT int_command
949 MOV DX,OFFSET RESGROUP:PIPE2
950 MOV AH,UNLINK
951 INT int_command
952 XOR AX,AX
953 MOV WORD PTR [PIPEFLAG],AX ; Pipe files and pipe gone
954 MOV [ECHOFLAG],1 ; Make sure ^C to pipe doesn't leave ECHO OFF
955 POP DX
956 return
957
958PIPEERRSYN:
959 MOV DX,OFFSET TRANGROUP:SYNTMES
960 JMP SHORT PIPPERR
961PIPEERR:
962 MOV DX,OFFSET TRANGROUP:PIPEEMES
963PIPPERR:
964 CALL PIPEDEL
965 PUSH CS
966 POP DS
967 JMP CERROR
968
969PIPEPROCSTRT:
970ASSUME DS:TRANGROUP,ES:TRANGROUP
971 MOV DS,[RESSEG]
972ASSUME DS:RESGROUP
973 INC [PIPEFILES] ; Flag that the pipe files exist
974 MOV AH,19H ; Get current drive
975 INT int_command
976 ADD AL,'A'
977 MOV [PIPE2],AL ; Make pipe files in root of def drv
978 MOV BX,OFFSET RESGROUP:PIPE1
979 MOV [BX],AL
980 MOV DX,BX
981 XOR CX,CX
982 MOV AH,CREAT
983 INT int_command
984 JC PIPEERR ; Couldn't create
985 MOV BX,AX
986 MOV AH,CLOSE ; Don't proliferate handles
987 INT int_command
988 MOV DX,OFFSET RESGROUP:PIPE2
989 MOV AH,CREAT
990 INT int_command
991 JC PIPEERR
992 MOV BX,AX
993 MOV AH,CLOSE
994 INT int_command
995 CALL TESTDOREIN ; Set up a redirection if specified
996 MOV [ECHOFLAG],0 ; No echo on pipes
997 MOV SI,[PIPEPTR]
998 CMP [SINGLECOM],-1
999 JNZ NOSINGP
1000 MOV [SINGLECOM],0F000H ; Flag single command pipe
1001NOSINGP:
1002 JMP SHORT FIRSTPIPE
1003
1004PIPEPROC:
1005ASSUME DS:RESGROUP
1006 MOV [ECHOFLAG],0 ; No echo on pipes
1007 MOV SI,[PIPEPTR]
1008 LODSB
1009 CMP AL,'|'
1010 JNZ PIPEEND ; Pipe done
1011 MOV DX,[INPIPEPTR] ; Get the input file name
1012 MOV AX,(OPEN SHL 8)
1013 INT int_command
1014PIPEERRJ:
1015 JC PIPEERR ; Lost the pipe file
1016 MOV BX,AX
1017 MOV AL,0FFH
1018 XCHG AL,[BX.PDB_JFN_Table]
1019 MOV DS:[PDB_JFN_Table],AL ; Redirect
1020FIRSTPIPE:
1021 MOV DI,OFFSET TRANGROUP:COMBUF + 2
1022 XOR CX,CX
1023 CMP BYTE PTR [SI],0DH ; '|<CR>'
1024 JNZ PIPEOK1
1025PIPEERRSYNJ:
1026 JMP PIPEERRSYN
1027PIPEOK1:
1028 CMP BYTE PTR [SI],'|' ; '||'
1029 JZ PIPEERRSYNJ
1030PIPECOMLP:
1031 LODSB
1032 STOSB
1033
1034 IF KANJI
1035 CALL TESTKANJ
1036 JZ NOTKANJ5
1037 MOVSB
1038 JMP PIPECOMLP
1039
1040NOTKANJ5:
1041 ENDIF
1042
1043 CMP AL,0DH
1044 JZ LASTPIPE
1045 INC CX
1046 CMP AL,'|'
1047 JNZ PIPECOMLP
1048 MOV BYTE PTR ES:[DI-1],0DH
1049 DEC CX
1050 MOV [COMBUF+1],CL
1051 DEC SI
1052 MOV [PIPEPTR],SI ; On to next pipe element
1053 MOV DX,[OUTPIPEPTR]
1054 PUSH CX
1055 XOR CX,CX
1056 MOV AX,(CREAT SHL 8)
1057 INT int_command
1058 POP CX
1059 JC PIPEERRJ ; Lost the file
1060 MOV BX,AX
1061 MOV AL,0FFH
1062 XCHG AL,[BX.PDB_JFN_Table]
1063 MOV DS:[PDB_JFN_Table+1],AL
1064 XCHG DX,[INPIPEPTR] ; Swap for next element of pipe
1065 MOV [OUTPIPEPTR],DX
1066 JMP SHORT PIPECOM
1067
1068LASTPIPE:
1069 MOV [COMBUF+1],CL
1070 DEC SI
1071 MOV [PIPEPTR],SI ; Point at the CR (anything not '|' will do)
1072 CALL TESTDOREOUT ; Set up the redirection if specified
1073PIPECOM:
1074 PUSH CS
1075 POP DS
1076 JMP NOPIPEPROC ; Process the pipe element
1077
1078PIPEEND:
1079 CALL PIPEDEL
1080 CMP [SINGLECOM],0F000H
1081 JNZ NOSINGP2
1082 MOV [SINGLECOM],-1 ; Make it return
1083NOSINGP2:
1084 JMP TCOMMAND
1085
1086TRANCODE ENDS
1087 END
1088