]> wirehaze git hosting - MS-DOS.git/blob - v4.0/src/CMD/COMMAND/INIT.ASM

wirehaze git hosting

MZ is back!
[MS-DOS.git] / v4.0 / src / CMD / COMMAND / INIT.ASM
1 page 80,132
2 ; SCCSID = @(#)init.asm 4.13 85/11/03
3 ; SCCSID = @(#)init.asm 4.13 85/11/03
4 TITLE 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
19 ENVIRONSIZ EQU 0A0H ;Must agree with values in EVIRONMENT segment
20 ENVIRONSIZ2 EQU 092H
21
22 ENVBIG EQU 32768
23 ENVSML EQU 160
24 KOREA_COUNTRY_CODE EQU 82
25
26 CODERES 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
33 CODERES ENDS
34
35 DATARES 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
93 DATARES ENDS
94
95 BATARENA SEGMENT PUBLIC PARA ;AC000;
96 BATARENA ENDS
97
98 BATSEG SEGMENT PUBLIC PARA ;AC000;
99 BATSEG ENDS
100
101 ENVARENA SEGMENT PUBLIC PARA ;AC000;
102 ENVARENA ENDS
103
104 ENVIRONMENT SEGMENT PUBLIC PARA ; Default COMMAND environment
105 EXTRN ECOMSPEC:BYTE
106 EXTRN ENVIREND:BYTE
107 EXTRN PATHSTRING:BYTE
108 ENVIRONMENT ENDS
109
110 TAIL SEGMENT PUBLIC PARA
111 EXTRN TRANSTART:WORD
112 TAIL ENDS
113
114 TRANCODE SEGMENT PUBLIC BYTE ;AC000;
115 EXTRN DATINIT:FAR
116 EXTRN printf_init:far
117 TRANCODE ENDS
118
119 TRANSPACE SEGMENT PUBLIC BYTE ;AC000;
120 EXTRN TRANSPACEEND:BYTE
121 TRANSPACE 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
126 BATARENA SEGMENT PUBLIC PARA
127
128 ORG 0
129 DB 10h DUP (?) ;Pad for memory allocation addr mark
130
131 BATARENA ENDS
132
133 BATSEG 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
139 BATSEG ENDS
140
141 ; *******************************************************************
142 ; START OF INIT PORTION
143 ; This code is overlayed the first time the TPA is used.
144
145 INIT 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
197 ASSUME CS:RESGROUP,DS:RESGROUP,ES:RESGROUP,SS:RESGROUP
198
199 ORG 0
200 ZERO = $
201
202
203 CONPROC:
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,
213 here: ; loop forever.
214 Jz here
215 int 20h ; Otherwise, exit.
216
217 ;
218 ; Turn APPEND off during initialization processing
219 ;
220 okdos:
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
236 set_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]
333 TPASET:
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
364 BUILDENV: ; (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
371 ENVIRONPASSED:
372 MOV [ENVIRSEG],AX ; Save the environment's segment and
373 MOV ES,AX ; load into es.
374 ASSUME ES:ENVIRONMENT
375
376 GOTTHEENVIR:
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
389 IUSESLASH:
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
420 NOTWIDENV:
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
425 NOCOMDRV:
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
437 ASSUME 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
454 parse_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
470 parse_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
478 init_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
499 parse_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
507 parse_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
526 SetMSwitchjmp: ;AN018; long jump needed
527 jmp SetMswitch ;AN018;
528
529 ArgsdoneJ3: ;AN018; long jump needed
530 jmp ArgsDone ;AN018;
531
532 SetFSwitch:
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
538 failok:
539 MOV fFail,-1 ;AC000; fail all INT 24s.
540 JMP parse_command_line ;AC000;
541
542 SetPSwitch:
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
552 permcomok:
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
564 Parse_command_line_jmp: ;AN018;
565 JMP parse_command_line ;AC000; keep parsing
566
567 ArgsDoneJump:
568 JMP ArgsDone
569
570 SetDSwitch:
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
579 setdateok:
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
584 SetSSwitch:
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
599 SetESwitch:
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
605 eswitchok:
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
617 SetMSwitch:
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
622 setMswitchok:
623 MOV Ext_msg,set_extended_msg ;AN000; set /MSG switch
624 JMP parse_command_line ;AN000; keep parsing
625
626 ARGSDONEJ:
627 JMP ARGSDONE
628
629 ;
630 ; We have a non-switch character here.
631 ;
632 CHKOTHERARGS:
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
648 BADSETCON: ;AN022;
649 MOV AH,CLOSE ; Close initial handle, wasn't a device
650 INT int_command
651 JMP CHKSRCHSPEC
652
653 ISADEVICE:
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
666 RCCLLOOP: ; 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
685 CHKSRCHSPEC: ; 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
700 countloop:
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
713 COMTRLOOP:
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
741 SETCOMSR:
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
764 INOTROOT:
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
779 SETCOMSRRET:
780 POP CX
781 POP SI
782 POP DS ;AN054;
783 assume ds:resgroup ;AN054;
784
785 ARGSDONEJ2:
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
790 SETCOMSRBAD:
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
796 doprt:
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
809 ARGSDONE:
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
867 COMRETURNS:
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
902 COMSPECNOFND:
903 MOV SI,CS:[ECOMLOC] ;AC062
904 ADD SI,OFFSET RESGROUP:PATHSTRING
905 PUSH CS
906 POP DS
907
908 assume es:resgroup
909 COPYCOMSP:
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
915 COPYCOMSPLOOP:
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
925 assume 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
933 Public EnvMaximum
934 EnvMaximum:
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 ;
954 GOTENVIR:
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
980 Ok_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
992 Trans_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
1009 NOBATCHSEG:
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
1023 MAXOK:
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.
1047 Public Nxtstr
1048 Nxtstr:
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
1063 OKCpyStr:
1064 JMP Nxtstr
1065 EnvExit:
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
1075 EnvNoErr:
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
1090 EnvSet:
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
1101 envsetok:
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
1110 NOPHEAD:
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 ;
1119 dodate:
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
1157 NOAUTSET:
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
1175 NOABAT:
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
1212 NOKABAT: ;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
1217 AccDenErr: ;AN000; yes - put out message
1218 mov DX,ACCDEN ;AC000; get message number
1219 call print_message
1220
1221 openerr:
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
1229 DODTTM:
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
1236 NODTTM:
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
1245 DRV0: ; 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 ;
1259 GetStrLen:
1260 xor cx,cx
1261 NxtChar:
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 ;
1273 setup_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
1286 setup_end:
1287 ret
1288
1289 print_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
1318 PATHCHRCMPR:
1319 push dx
1320 mov dl,fslash
1321 CMP [RSWITCHAR],dl
1322 JZ RNOSLASHT
1323 CMP AL,dl
1324 JZ RET41
1325 RNOSLASHT:
1326 CMP AL,bslash
1327 RET41:
1328 pop dx
1329 RET
1330
1331
1332 IFINDE:
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 ;
1339 IFIND:
1340 CLD
1341 CALL ICOUNT0 ; CX = LENGTH OF NAME
1342 MOV ES,[ENVIRSEG]
1343 XOR DI,DI
1344
1345 IFIND1:
1346 PUSH CX
1347 PUSH SI
1348 PUSH DI
1349
1350 IFIND11:
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
1366 NOTKANJ4:
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
1375 IFIND12:
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
1387 IFIND2:
1388 RET
1389
1390 ICOUNT0:
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
1401 ICOUNTX:
1402 POP CX
1403 SUB DI,CX
1404 XCHG DI,CX
1405 RET
1406
1407 ISCASB1:
1408 MOV AL,equalsign ; SCAN FOR AN =
1409 JMP SHORT ISCASBX
1410
1411 ISCASB2:
1412 XOR AL,AL ; SCAN FOR A NUL
1413
1414 ISCASBX:
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
1437 assume ds:resgroup ;AN000;
1438
1439 iupconv 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
1453 other_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
1460 iupconv_end: ;AN000;
1461 ret
1462
1463 iupconv endp ;AN000;
1464
1465 init_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
1490 CHAR_START EQU 201 ;AN000; first character translate is 1
1491 CHAR_END EQU 207 ;AN000; last is 6
1492
1493 GET_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
1497 MOVEMES: ;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
1521 GET_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
1549 setup_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
1583 permcom_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
1590 no_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
1597 no_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
1604 permcom_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
1614 setup_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
1631 Set_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
1639 Set_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
1656 Set_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
1664 Set_ext_2f endp ;AN060;
1665
1666
1667 ASSUME DS:RESGROUP, ES:RESGROUP
1668
1669 .xlist
1670 .xcref
1671
1672 INCLUDE SYSMSG.INC ;AN000; include message services
1673
1674 .list
1675 .cref
1676
1677 MSG_UTILNAME <COMMAND> ;AN000; define utility name
1678
1679 MSG_SERVICES <COMR,NEARmsg,LOADmsg,NOCHECKSTDIN,NOCHECKSTDOUT> ;AC026; include message services macro
1680
1681 include msgdcl.inc
1682
1683 INIT ENDS
1684
1685 END