1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
|
page 80,132
; SCCSID = @(#)tcode.asm 1.1 85/05/14
; SCCSID = @(#)tcode.asm 1.1 85/05/14
TITLE Part1 COMMAND Transient Routines
INCLUDE comsw.asm
.xlist
.xcref
INCLUDE DOSSYM.INC
INCLUDE comseg.asm
INCLUDE comequ.asm
.list
.cref
CODERES SEGMENT PUBLIC BYTE ;AC000;
EXTRN EXEC_WAIT:NEAR
CODERES ENDS
DATARES SEGMENT PUBLIC BYTE ;AC000;
EXTRN BATCH:WORD
EXTRN CALL_BATCH_FLAG:byte
EXTRN CALL_FLAG:BYTE
EXTRN ECHOFLAG:BYTE
EXTRN envirseg:word
EXTRN EXTCOM:BYTE
EXTRN FORFLAG:BYTE
EXTRN IFFLAG:BYTE
EXTRN next_batch:word
EXTRN nullflag:byte
EXTRN PIPEFILES:BYTE
EXTRN PIPEFLAG:BYTE
EXTRN RE_OUT_APP:BYTE
EXTRN RE_OUTSTR:BYTE
EXTRN RESTDIR:BYTE
EXTRN SINGLECOM:WORD
EXTRN VERVAL:WORD
DATARES ENDS
TRANDATA SEGMENT PUBLIC BYTE ;AC000;
EXTRN BadNam_Ptr:word ;AC000;
TRANDATA ENDS
TRANSPACE SEGMENT PUBLIC BYTE ;AC000;
EXTRN APPEND_EXEC:BYTE ;AN041;
EXTRN ARG1S:WORD
EXTRN ARG2S:WORD
EXTRN ARGTS:WORD
EXTRN BYTCNT:WORD
EXTRN COMBUF:BYTE
EXTRN COMSW:WORD
EXTRN CURDRV:BYTE
EXTRN HEADCALL:DWORD
EXTRN IDLEN:BYTE
EXTRN INTERNATVARS:BYTE
EXTRN PARM1:BYTE
EXTRN PARM2:BYTE
EXTRN RE_INSTR:BYTE
EXTRN RESSEG:WORD
EXTRN SPECDRV:BYTE
EXTRN STACK:WORD
EXTRN SWITCHAR:BYTE
EXTRN TPA:WORD
EXTRN UCOMBUF:BYTE
EXTRN USERDIR1:BYTE
IF IBM
EXTRN ROM_CALL:BYTE
EXTRN ROM_CS:WORD
EXTRN ROM_IP:WORD
ENDIF
TRANSPACE ENDS
; ********************************************************************
; START OF TRANSIENT PORTION
; This code is loaded at the end of memory and may be overwritten by
; memory-intensive user programs.
TRANCODE SEGMENT PUBLIC BYTE ;AC000;
ASSUME CS:TRANGROUP,DS:NOTHING,ES:NOTHING,SS:NOTHING
EXTRN $EXIT:NEAR
EXTRN DRVBAD:NEAR
EXTRN EXTERNAL:NEAR
EXTRN FNDCOM:NEAR
EXTRN FORPROC:NEAR
EXTRN PIPEPROC:NEAR
EXTRN PIPEPROCSTRT:NEAR
PUBLIC COMMAND
PUBLIC DOCOM
PUBLIC DOCOM1
PUBLIC NOPIPEPROC
PUBLIC TCOMMAND
IF IBM
PUBLIC ROM_EXEC
PUBLIC ROM_SCAN
ENDIF
ORG 0
ZERO = $
ORG 100H ; Allow for 100H parameter area
SETDRV:
MOV AH,SET_DEFAULT_DRIVE
INT int_command
;
; TCOMMAND is the recycle point in COMMAND. Nothing is known here.
; No registers (CS:IP) no flags, nothing.
;
TCOMMAND:
MOV DS,[RESSEG]
ASSUME DS:RESGROUP
MOV AX,-1
XCHG AX,[VERVAL]
CMP AX,-1
JZ NOSETVER2
MOV AH,SET_VERIFY_ON_WRITE ; AL has correct value
INT int_command
NOSETVER2:
CALL [HEADCALL] ; Make sure header fixed
XOR BP,BP ; Flag transient not read
CMP [SINGLECOM],-1
JNZ COMMAND
$EXITPREP:
PUSH CS
POP DS
JMP $EXIT ; Have finished the single command
ASSUME DS:NOTHING
;
; Main entry point from resident portion.
;
; If BP <> 0, then we have just loaded transient portion otherwise we are
; just beginning the processing of another command.
;
COMMAND:
;
; We are not always sure of the state of the world at this time. We presume
; worst case and initialize the relevant registers: segments and stack.
;
ASSUME CS:TRANGROUP,DS:NOTHING,ES:NOTHING,SS:NOTHING
CLD
MOV AX,CS
CLI
MOV SS,AX
ASSUME SS:TRANGROUP
MOV SP,OFFSET TRANGROUP:STACK
STI
MOV ES,AX
MOV DS,AX ;AN000; set DS to transient
ASSUME ES:TRANGROUP,DS:TRANGROUP ;AC000;
invoke TSYSLOADMSG ;AN000; preload messages
invoke SETSTDINOFF ;AN026; turn off critical error on STDIN
invoke SETSTDOUTOFF ;AN026; turn off critical error on STDOUT
mov append_exec,0 ;AN041; set internal append state off
MOV DS,[RESSEG]
ASSUME DS:RESGROUP
MOV [UCOMBUF],COMBUFLEN ; Init UCOMBUF
MOV [COMBUF],COMBUFLEN ; Init COMBUF (Autoexec doing DATE)
;
; If we have just loaded the transient, then we do NOT need to initialize the
; command buffer. ???? DO WE NEED TO RESTORE THE USERS DIRECTORY ???? I
; guess not: the only circumstances in which we reload the command processor
; is after a transient program execution. In this case, we let the current
; directory lie where it may.
;
OR BP,BP ; See if just read
JZ TESTRDIR ; Not read, check user directory
MOV WORD PTR [UCOMBUF+1],0D01H ; Reset buffer
JMP SHORT NOSETBUF
TESTRDIR:
CMP [RESTDIR],0
JZ NOSETBUF ; User directory OK
PUSH DS
;
; We have an unusual situation to handle. The user *may* have changed his
; directory as a result of an internal command that got aborted. Restoring it
; twice may not help us: the problem may never go away. We just attempt it
; once and give up.
;
MOV [RESTDIR],0 ; Flag users dirs OK
PUSH CS
POP DS
ASSUME DS:TRANGROUP
MOV DX,OFFSET TRANGROUP:USERDIR1
MOV AH,CHDIR
INT int_command ; Restore users directory
POP DS
ASSUME DS:RESGROUP
NOSETBUF:
CMP [PIPEFILES],0
JZ NOPCLOSE ; Don't bother if they don't exist
CMP [PIPEFLAG],0
JNZ NOPCLOSE ; Don't del if still piping
INVOKE PIPEDEL
NOPCLOSE:
MOV [EXTCOM],0 ; Flag internal command
MOV AX,CS ; Get segment we're in
MOV DS,AX
ASSUME DS:TRANGROUP
PUSH AX
MOV DX,OFFSET TRANGROUP:INTERNATVARS
MOV AX,INTERNATIONAL SHL 8
INT 21H
POP AX
SUB AX,[TPA] ; AX=size of TPA in paragraphs
PUSH BX
MOV BX,16
MUL BX ; DX:AX=size of TPA in bytes
POP BX
OR DX,DX ; See if over 64K
JZ SAVSIZ ; OK if not
MOV AX,-1 ; If so, limit to 65535 bytes
SAVSIZ:
;
; AX is the number of bytes free in the buffer between the resident and the
; transient with a maximum of 64K-1. We round this down to a multiple of 512.
;
CMP AX,512
JBE GotSize
AND AX,0FE00h ; NOT 511 = NOT 1FF
GotSize:
MOV [BYTCNT],AX ; Max no. of bytes that can be buffered
MOV DS,[RESSEG] ; All batch work must use resident seg.
ASSUME DS:RESGROUP
TEST [ECHOFLAG],1
JZ GETCOM ; Don't do the CRLF
INVOKE SINGLETEST
JB GETCOM
TEST [PIPEFLAG],-1
JNZ GETCOM
TEST [FORFLAG],-1 ; G Don't print prompt in FOR
JNZ GETCOM ; G
TEST [BATCH], -1 ; G Don't print prompt if in batch
JNZ GETCOM ; G
INVOKE CRLF2
GETCOM:
MOV CALL_FLAG,0 ; G Reset call flags
MOV CALL_BATCH_FLAG,0 ; G
MOV AH,GET_DEFAULT_DRIVE
INT int_command
MOV [CURDRV],AL
TEST [PIPEFLAG],-1 ; Pipe has highest presedence
JZ NOPIPE
JMP PIPEPROC ; Continue the pipeline
NOPIPE:
TEST [ECHOFLAG],1
JZ NOPDRV ; No prompt if echo off
INVOKE SINGLETEST
JB NOPDRV
TEST [FORFLAG],-1 ; G Don't print prompt in FOR
JNZ NOPDRV ; G
TEST [BATCH], -1 ; G Don't print prompt if in batch
JNZ TESTFORBAT ; G
INVOKE PRINT_PROMPT ; Prompt the user
NOPDRV:
TEST [FORFLAG],-1 ; FOR has next highest precedence
JZ TESTFORbat
JMP FORPROC ; Continue the FOR
TESTFORBAT:
MOV [RE_INSTR],0 ; Turn redirection back off
MOV [RE_OUTSTR],0
MOV [RE_OUT_APP],0
MOV IFFlag,0 ; no more ifs...
TEST [BATCH],-1 ; Batch has lowest precedence
JZ ISNOBAT
push es ;AN000; save ES
push ds ;AN000; save DS
mov ax,mult_shell_get ;AN000; check to see if SHELL has command
mov es,[batch] ;AN000; get batch segment
mov di,batfile ;AN000; get batch file name
push cs ;AN000; get local segment to DS
pop ds ;AN000;
mov dx,offset trangroup:combuf ;AN000; pass communications buffer
int 2fh ;AN000; call the shell
cmp al,shell_action ;AN000; does shell have a commmand?
pop ds ;AN000; restore DS
pop es ;AN000; restore ES
jz jdocom1 ;AN000; yes - go process command
PUSH DS ;G
INVOKE READBAT ; Continue BATCH
POP DS ;G
mov nullflag,0 ;G reset no command flag
TEST [BATCH],-1 ;G
JNZ JDOCOM1 ;G if batch still in progress continue
MOV BX,NEXT_BATCH ;G
CMP BX,0 ;G see if there is a new batch file
JZ JDOCOM1 ;G no - go do command
MOV BATCH,BX ;G get segment of next batch file
MOV NEXT_BATCH,0 ;G reset next batch
JDOCOM1:
PUSH CS ;G
POP DS ;G
JMP SHORT DoCom1 ; echoing already done
ISNOBAT:
CMP [SINGLECOM],0
JZ REGCOM
MOV SI,-1
XCHG SI,[SINGLECOM]
MOV DI,OFFSET TRANGROUP:COMBUF + 2
XOR CX,CX
SINGLELOOP:
LODSB
STOSB
INC CX
CMP AL,0DH
JNZ SINGLELOOP
DEC CX
PUSH CS
POP DS
ASSUME DS:TRANGROUP
MOV [COMBUF + 1],CL
;
; do NOT issue a trailing CRLF...
;
JMP DOCOM1
;
; We have a normal command.
; Printers are a bizarre quantity. Sometimes they are a stream and
; sometimes they aren't. At this point, we automatically close all spool
; files and turn on truncation mode.
;
REGCOM:
MOV AX,(ServerCall SHL 8) + 9
INT 21h
MOV AX,(ServerCall SHL 8) + 8
MOV DL,1
INT 21h
PUSH CS
POP DS ; Need local segment to point to buffer
MOV DX,OFFSET TRANGROUP:UCOMBUF
MOV AH,STD_CON_STRING_INPUT
INT int_command ; Get a command
MOV CL,[UCOMBUF]
XOR CH,CH
ADD CX,3
MOV SI,OFFSET TRANGROUP:UCOMBUF
MOV DI,OFFSET TRANGROUP:COMBUF
REP MOVSB ; Transfer it to the cooked buffer
;---------------
transpace segment
extrn arg:byte ; the arg structure!
transpace ends
;---------------
DOCOM:
INVOKE CRLF2
DOCOM1:
INVOKE PRESCAN ; Cook the input buffer
JZ NOPIPEPROC
JMP PIPEPROCSTRT ; Fire up the pipe
nullcomj:
jmp nullcom
NOPIPEPROC:
invoke parseline
jnc OkParse ; user error? or maybe we goofed?
BadParse:
PUSH CS
POP DS
MOV DX,OFFSET TRANGROUP:BADNAM_ptr
INVOKE std_eprintf
JMP TCOMMAND
OkParse:
test arg.argv[0].argflags, MASK wildcard
jnz BadParse ; ambiguous commands not allowed
cmp arg.argvcnt, 0 ; there WAS a command, wasn't there?
jz nullcomj
cmp arg.argv[0].arglen, 0 ; probably an unnecessary check...
jz nullcomj ; guarantees argv[0] at least x<NULL>
MOV SI,OFFSET TRANGROUP:COMBUF+2
MOV DI,OFFSET TRANGROUP:IDLEN
MOV AX,(PARSE_FILE_DESCRIPTOR SHL 8) OR 01H ; Make FCB with blank scan-off
INT int_command
mov BX, arg.argv[0].argpointer
cmp BYTE PTR [BX+1],':' ; was a drive specified?
jne short drvgd ; no, use default of zero...
mov DL, BYTE PTR [BX] ; pick-up drive letter
and DL, NOT 20H ; uppercase the sucker
sub DL, capital_A ; convert it to a drive number, A=0
CMP AL,-1 ; See what PARSE said about our drive letter.
JZ drvbadj2 ; It was invalid.
mov DI, arg.argv[0].argstartel
cmp BYTE PTR [DI], 0 ; is there actually a command there?
jnz drvgd ; if not, we have: "d:", "d:\", "d:/"
jmp setdrv ; and set drive to new drive spec
drvbadj2:
jmp drvbad
DRVGD:
MOV AL,[DI]
MOV [SPECDRV],AL
MOV AL,' '
MOV CX,9
INC DI
REPNE SCASB ; Count no. of letters in command name
MOV AL,8
SUB AL,CL
MOV [IDLEN],AL ; IDLEN is truly the length
MOV DI,81H
PUSH SI
mov si, OFFSET TRANGROUP:COMBUF+2 ; Skip over all leading delims
invoke scanoff
do_skipcom:
lodsb ; move command line pointer over
invoke delim ; pathname -- have to do it ourselves
jz do_skipped ; 'cause parse_file_descriptor is dumb
cmp AL, 0DH ; can't always depend on argv[0].arglen
jz do_skipped ; to be the same length as the user-
cmp AL, [SWITCHAR] ; specified command string
jnz do_skipcom
do_skipped:
dec SI
XOR CX,CX
COMTAIL:
LODSB
STOSB ; Move command tail to 80H
CMP AL,13
LOOPNZ COMTAIL
DEC DI
MOV BP,DI
NOT CL
MOV BYTE PTR DS:[80H],CL
POP SI
;-----
; Some of these comments are sadly at odds with this brave new code.
;-----
; If the command has 0 parameters must check here for
; any switches that might be present.
; SI -> first character after the command.
mov DI, arg.argv[0].argsw_word
mov [COMSW], DI ; ah yes, the old addressing mode problem...
mov SI, arg.argv[1 * SIZE argv_ele].argpointer ; s = argv[1];
OR SI,SI ; if (s == NULL)
JNZ DoParse
MOV SI,BP ; s = bp; (buffer end)
DoParse:
MOV DI,FCB
MOV AX,(PARSE_FILE_DESCRIPTOR SHL 8) OR 01H
INT int_command
MOV [PARM1],AL ; Save result of parse
mov DI, arg.argv[1*SIZE argv_ele].argsw_word
mov [ARG1S], DI
mov SI, arg.argv[2*SIZE argv_ele].argpointer ; s = argv[2];
OR SI,SI ; if (s == NULL)
JNZ DoParse2
MOV SI,BP ; s = bp; (bufend)1
DoParse2:
MOV DI,FCB+10H
MOV AX,(PARSE_FILE_DESCRIPTOR SHL 8) OR 01H
INT int_command ; Parse file name
MOV [PARM2],AL ; Save result
mov DI, arg.argv[2*SIZE argv_ele].argsw_word
mov [ARG2S], DI
mov DI, arg.argv[0].argsw_word
not DI ; ARGTS doesn't include the flags
and DI, arg.argswinfo ; from COMSW...
mov [ARGTS], DI
MOV AL,[IDLEN]
MOV DL,[SPECDRV]
or DL, DL ; if a drive was specified...
jnz externalj1 ; it MUST be external, by this time
dec al ; (I don't know why -- old code did it)
jmp fndcom ; otherwise, check internal com table
externalj1:
jmp external
nullcom:
MOV DS,[RESSEG]
ASSUME DS:RESGROUP
TEST [BATCH], -1 ;G Are we in a batch file?
JZ nosetflag ;G only set flag if in batch
mov nullflag,nullcommand ;G set flag to indicate no command
nosetflag:
CMP [SINGLECOM],-1
JZ EXITJ
JMP GETCOM
EXITJ:
JMP $EXITPREP
IF IBM
include mshalo.asm
ENDIF
TRANCODE ENDS
END
|