2 ; SCCSID = @(#)rucode.asm 4.5 85/07/22
3 ; SCCSID = @(#)rucode.asm 4.5 85/07/22
4 TITLE COMMAND Language modifiable
Code Resident
9 INCLUDE DOSSYM
.INC ;AC000;
10 include doscntry
.inc ;AC000;
11 DEBUG
= 0 ; NEED TO SET IT TO WHAT IT IS IN DOSSYM.INC
18 include resmsg
.equ
;AN000;
25 DATARES
SEGMENT PUBLIC BYTE ;AC000;
27 EXTRN badfat_block
:byte ;AC000;
28 EXTRN badfat_subst
:byte ;AC000;
29 EXTRN Batch_Abort
:byte
31 EXTRN COMSPEC
:BYTE ;AN060;
32 EXTRN com_xlat_addr
:word
33 EXTRN crit_err_info
:byte
34 EXTRN crit_msg_off
:word ;AC000;
35 EXTRN crit_msg_seg
:word ;AC000;
36 EXTRN dbcs_vector_addr
:dword ;AN000;
37 EXTRN devemes_block
:byte ;AC000;
38 EXTRN devemes_subst
:byte ;AC000;
40 EXTRN deve_op_off
:word ;AC000;
41 EXTRN disp_class
:byte ;AC000;
43 EXTRN drvnum_block
:byte ;AC000;
44 EXTRN drvnum_op_off
:word ;AC000;
45 EXTRN drvnum_subst
:byte ;AC000;
46 EXTRN err15mes_block
:byte ;AC000;
47 EXTRN err15mes_subst
:byte ;AC000;
53 EXTRN ignore_char
:byte
57 ;AD054; EXTRN MESBAS:BYTE
59 EXTRN number_subst
:byte ;AC000;
62 ;AD060; EXTRN pars_msg_off:word ;AC000;
63 ;AD060; EXTRN pars_msg_seg:word ;AC000;
80 CODERES
SEGMENT PUBLIC BYTE
87 PUBLIC ITESTKANJ
;AN000;
88 PUBLIC RESET_MSG_POINTERS
;AC000;
91 ASSUME
CS:RESGROUP
,DS:NOTHING
,ES:NOTHING
,SS:NOTHING
94 ; AskEnd - prompt the user to see if he should terminate the batch file. If
95 ; any system call returns with carry set or if RPRINT returns with carry set,
96 ; we jump to the top and start over.
98 ; Returns: carry set if response indicates that the batch file should
100 ; carry clear otherwise.
105 MOV DX,ENDBATMES
;AC000; get batch terminate question
107 MOV AX,(STD_CON_INPUT_FLUSH
SHL 8)+STD_CON_INPUT
109 call in_char_xlat
;g change to upper case
111 retz
; carry is clear => no free
114 stc ; carry set => free batch
118 ASSUME
DS:NOTHING
,ES:NOTHING
,SS:NOTHING
119 ; ******************************************************
120 ; THIS IS THE DEFAULT DISK ERROR HANDLING CODE
121 ; AVAILABLE TO ALL USERS IF THEY DO NOT TRY TO
122 ; INTERCEPT INTERRUPT 24H.
123 ; ******************************************************
127 PUSH SI ;AN000; save si
137 MOV DI,OFFSET RESGROUP
:DEVENAM
139 ADD SI,SDEVNAME
; Suck up device name (even on Block)
143 POP DI ; Stack just contains DS and ES
147 POP DS ; Set up local data segment
153 MOV CRIT_ERR_INFO
,AH ;G save so we know if R,I,F are valid
155 ADD AL,'A' ; Compute drive letter (even on character)
157 TEST AH,80H
; Check if hard disk error
159 TEST [CDEVAT
],DEVTYP
SHR 8
167 MOV SI,MWRITE
;AC000;
172 MOV WORD PTR [IOTYP
],AX
174 MOV WORD PTR [IOTYP
+2],AX
177 mov olderrno
,di ; keep code in a safe place
179 PUSH DS ; GetExtendedError likes to STOMP
185 mov ah,GetExtendedError
; get extended error code
193 mov word ptr cs:[RemMsg
],di ;AC000; save pointer to remote message
194 mov word ptr cs:[RemMsg
+2],es ;AC000; (only used on code 15)
197 mov di,ax ; REAL error code to DI
199 ; DI is now the correct error code. Classify things to see what we are
200 ; allowed to report. We convert DI into a 0-based index into a message table.
201 ; This presumes that the int 24 errors (oldstyle) and new errors (sharing and
202 ; the like) are contiguous.
204 SUB DI,error_write_protect
206 MOV DI,error_Gen_failure
-error_write_protect
208 ; DI now has the mapped error code. Old style errors are:
209 ; FOOBAR <read|writ>ing drive ZZ.
210 ; New style errors are:
212 ; We need to figure out which the particular error belongs to.
216 mov ErrType
,0 ; assume Old style
217 cmp di,error_FCB_Unavailable
-error_write_protect
219 cmp di,error_sharing_buffer_exceeded
-error_write_protect
223 mov ErrType
,1 ; must be new type
227 cmp di,error_handle_disk_full
-error_write_protect
;AC026;
228 ; If the error message is unknown
229 jbe NormalError
; redirector, continue. Otherwise,
231 ; We do not know how to handle this error. Ask IFSFUNC if she knows
232 ; how to handle things
235 ;input to IFSFUNC: AL=1
236 ; BX=extended error number
238 ;output from IFSFUNC: AL=error type (0 or 1)
239 ; 0=<message> error (read/writ)ing (drive/device) xxx
240 ; Abort, Retry, Ignore
242 ; Abort, Retry, Ignore
243 ; ES:DI=pointer to message text
244 ; carry set=>no message
246 MOV DI,AX ; retrieve correct extended error...
247 mov ax,0500h ; Is the redir there?
250 jnz NoHandler
; No, go to NoHandler
252 mov bx,di ; Get ErrType and ptr to error msg ;AC063;
263 mov cx,-1 ; Find the end of the error msg and turn
264 xor al,al ; the high byte on for rprint
268 or byte ptr [di-2],80h
269 call rprint
; Print the message
270 and byte ptr [di-2], NOT 80h
; Restore msg to original condition
272 mov byte ptr [di-1],'$'
273 MOV AH,Std_con_string_output
;AC000; Print the message
275 mov byte ptr [di-1],0 ; Restore msg to original condition
278 pop ds ; Clean up and continue processing
279 jmp short CheckErrType
281 NoHandler: ; Redir isn't available or doesn't
282 mov ErrType
,0 ; recognize the error. Reset vars and
283 mov di,olderrno
; regs to unextended err and continue
284 mov ERRCD_24
,di ; normally.
288 ;AD054; MOV DI,WORD PTR [DI+MESBAS] ; Get pointer to error message
289 add DI,error_write_protect
;AN054;
290 XCHG DI,DX ; May need DX later
291 MOV DISP_CLASS
,EXT_CRLF_CLASS
;AN054; printing extended error class
292 CALL RPRINT
; Print error type
295 cmp ErrType
,0 ; Check error style...
297 call CRLF
; if new style then done printing
302 MOV AX,SI ;AN000; get reading/writing for message
303 MOV DH,UTIL_MSG_CLASS
;AN000; this is a utility message
304 CALL SYSGETMSG
;AN000; get the message
307 TEST [CDEVAT
],DEVTYP
SHR 8
309 MOV DX,DEVEMES
;AC000; get message number for device message
310 MOV DEVE_OP_OFF
,SI ;AN000; put address of read/write in subst block
311 MOV AL,DEVEMES_SUBST
;AN000; get number of substitutions
312 MOV NUMBER_SUBST
,AL ;AN000;
313 MOV SI,OFFSET RESGROUP
:DEVEMES_BLOCK
;AN000; get address of subst block
315 CALL RPRINT
;AC000; print the message
316 JMP SHORT ASK
; Don't ralph on COMMAND
319 MOV DX,DRVNUM
;AN000; get drive message number
320 MOV DRVNUM_OP_OFF
,SI ;AN000; put address of read/write in subst block
321 MOV AL,DRVNUM_SUBST
;AN000; get number of substitutions
322 MOV NUMBER_SUBST
,AL ;AN000;
323 MOV SI,OFFSET RESGROUP
:DRVNUM_BLOCK
;AN000; get address of subst block
328 JMP GETCOMDSK2
; If error loading COMMAND, re-prompt
331 cmp [ERRCD_24
],15 ; Wait! Error 15 has an extra message
339 mov di,offset resgroup
:VolName
340 mov cx,16 ;AC000; extra message volume name & serial number
348 mov dx,Err15Mes
;AC000; get message number
349 MOV AL,ERR15MES_SUBST
;AN000; get number of substitutions
350 MOV NUMBER_SUBST
,AL ;AN000;
351 MOV SI,OFFSET RESGROUP
:ERR15MES_BLOCK
;AN000; get address of subst block
354 ; PRINT OUT ABORT, RETRY, IGNORE, FAIL MESSAGE. ONLY PRINT OUT OPTIONS
358 MOV DX,REQ_ABORT
;AC000;G print out abort message
360 TEST CRIT_ERR_INFO
,RETRY_ALLOWED
;G is retry allowed?
362 MOV DX,REQ_RETRY
;AC000;G yes,print out retry message
366 TEST CRIT_ERR_INFO
,IGNORE_ALLOWED
;G is ignore allowed?
368 MOV DX,REQ_IGNORE
;AC000;G yes,print out ignore message
372 TEST CRIT_ERR_INFO
,FAIL_ALLOWED
;G is FAIL allowed?
374 MOV DX,REQ_FAIL
;AC000;G yes,print out FAIL message
378 MOV DX,REQ_END
;AC000;G terminate the string
381 ; If the /f switch was given, we fail all requests...
385 MOV AH,3 ; signal fail
389 MOV AX,(STD_CON_INPUT_FLUSH
SHL 8)+STD_CON_INPUT
390 INT 21H
; Get response
392 invoke TestKanjR
;AN000; 3/3/KK
393 jz notkanj
;AN000; 3/3/KK
394 MOV AX,(STD_CON_INPUT
SHL 8) ;AN000; eat the 2nd byte of ECS code 3/3/KK
395 INT 21H
;AN000; 3/3/KK
396 CALL CRLF
;AN000; 3/3/KK
397 JMP ASK
;AN000; 3/3/KK
399 notkanj: ;AN000; 3/3/KK
401 CALL IN_CHAR_XLAT
;G Convert to upper case
402 MOV AH,0 ; Return code for ignore
403 TEST CRIT_ERR_INFO
,IGNORE_ALLOWED
;G is IGNORE allowed?
405 CMP AL,ignore_char
; Ignore?
409 INC AH ; return code for retry
410 TEST CRIT_ERR_INFO
,RETRY_ALLOWED
;G is RETRY allowed?
412 CMP AL,retry_char
; Retry?
416 INC AH ; return code for abort - always allowed
417 CMP AL,abort_char
; Abort?
418 JZ abort_process
;G exit user program
419 INC AH ;G return code for fail
420 TEST CRIT_ERR_INFO
,FAIL_ALLOWED
;G is FAIL allowed?
422 CMP AL,fail_char
;G fail?
432 test InitFlag
,initINIT
; Was command initialization interrupted
433 jz AbortCont
; No, handle it normally
434 cmp PERMCOM
,0 ; Is this the top level process?
435 jz JustExit
; Yes, just exit
436 mov dx,Patricide
;AC000; No, load ptr to error msg
437 call RPRINT
; Print it
440 jmp DeadInTheWater
; Loop until the user reboots
444 call reset_msg_pointers
;AN000; reset critical & parse message addresses
445 mov ax,[PARENT
] ; Load real parent PID
446 mov word ptr ds:[PDB_Parent_PID
],ax ; Put it back where it belongs
447 mov ax,(Exit
SHL 8) OR 255
451 test byte ptr [In_Batch
],-1 ; Are we accessing a batch file?
453 mov byte ptr [Batch_Abort
],1 ; set flag for abort
462 MOV [SINGLECOM
],-1 ; Make sure SINGLECOM exits
465 CMP [ERRCD_24
],0 ; Write protect
467 CMP [ERRCD_24
],2 ; Drive not ready
468 JNZ EEXIT
; Don't abort the FOR
471 MOV [FORFLAG
],0 ; Abort a FOR in progress
474 MOV [SINGLECOM
],-1 ; Make sure SINGLECOM exits
483 POP SI ;AN000; restore registers
489 MOV DX,BADFAT
;AC000;
490 MOV AL,BADFAT_SUBST
;AN000; get number of substitutions
491 MOV NUMBER_SUBST
,AL ;AN000;
492 MOV SI,OFFSET RESGROUP
:BADFAT_BLOCK
;AN000; get address of subst block
496 MOV DX,OFFSET RESGROUP
:ERRMES
503 ;*********************************************
504 ; Print routines for Tokenized resident messages
506 ASSUME
DS:RESGROUP
,SS:RESGROUP
509 MOV DX,NEWLIN
;AC000;
512 ; RPRINT prints out a message on the user's console. We clear carry before
513 ; each system call. We do this so that the ^C checker may change things so
514 ; that carry is set. If we detect a system call that returns with carry set,
517 ; Inputs: DX has the message number as an offset from DS.
518 ; Outputs: Carry clear: no carries detected in the system calls
519 ; Carry set: at least one system call returned with carry set
520 ; Registers modified: none
526 ; If we are not tokenized, the message consists of a $-terminated string.
527 ; Use CPM io to output it.
532 PUSH BX ;AC000; save BX register
533 PUSH CX ;AC000; save CX register
534 PUSH DX ;AC000; save DX register
535 MOV AX,DX ;AC000; get message number
536 MOV DH,DISP_CLASS
;AC000; get display class
537 MOV DL,NO_CONT_FLAG
;AN000; set control flags off
538 MOV BX,NO_HANDLE_OUT
;AC000; set message handler to use function 1-12
539 XOR CH,CH ;AC000; clear upper part of cx
540 MOV CL,NUMBER_SUBST
;AC000; set number of substitutions
541 CALL SYSDISPMSG
;AC000; display the message
542 MOV DISP_CLASS
,UTIL_MSG_CLASS
;AC000; reset display class
543 MOV NUMBER_SUBST
,NO_SUBST
;AC000; reset number of substitutions
544 POP DX ;AC000; restore registers
553 ; If we are tokenized, output character-by-character. If there is a digit in
554 ; the output, look up that substring in the tokenization table. Use the high
555 ; bit to determine the end-of-string.
564 PUSH AX ; save for EOS testing
571 CBW ; DS must be RESGROUP if we get here
572 SHL AX,1 ; clear carry
574 MOV DX,[SI + OFFSET RESGroup
:MesADD
]
581 MOV AH,STD_CON_OUTPUT
587 JC RPrint5
; Abnormal termination?
588 TEST AL,80h
; High bit set indicates end (carry clear)
592 RestoreReg
<SI,DX,AX>
598 ;g This routine returns the upper case of the character in AL
599 ;g from the upper case table in DOS if character if above
600 ;g ascii 128, else subtract 20H if between "a" and "z"
605 in_char_xlat proc
near
607 cmp al,80h
;g see if char is above ascii 128
608 jb other_xlat
;g no - upper case math
609 sub al,80h
;g only upper 128 characters in table
612 lds bx,dword ptr com_xlat_addr
+1 ;g get table address
613 add bx,2 ;g skip over first word, of table
614 xlat ds:byte ptr [bx] ;g convert to upper case
617 jmp short in_char_xlat_end
;g we finished - exit
620 cmp al,'a' ;g if between "a" and "z", subtract
621 jb in_char_xlat_end
;g 20h to get upper case
622 cmp al,'z' ;g equivalent.
623 ja in_char_xlat_end
;g
624 sub al,20h
;g Lower-case changed to upper-case
631 ;---------------------- DBCS lead byte check. this is resident code ; 3/3/KK
634 TestKanjR: ;AN000; 3/3/KK
635 push ds ;AN000; 3/3/KK
636 push si ;AN000; 3/3/KK
637 push ax ;AN000; 3/3/KK
638 lds si,dbcs_vector_addr
;AN000; GET DBCS VECTOR
640 ktlop: ;AN000; 3/3/KK
641 cmp word ptr ds:[si],0 ;AN000; 3/3/KK end of Lead Byte Table
642 je notlead
;AN000; 3/3/KK
643 pop ax ;AN000; 3/3/KK
644 push ax ;AN000; 3/3/KK
645 cmp al, byte ptr ds:[si] ;AN000; 3/3/KK
646 jb notlead
;AN000; 3/3/KK
647 inc si ;AN000; 3/3/KK
648 cmp al, byte ptr ds:[si] ;AN000; 3/3/KK
649 jbe islead
;AN000; 3/3/KK
650 inc si ;AN000; 3/3/KK
651 jmp short ktlop
;AN000; 3/3/KK try another range
653 Notlead: ;AN000; 3/3/KK
654 xor ax,ax ;AN000; 3/3/KK set zero
655 jmp short ktret
;AN000; 3/3/KK
657 Islead: ;AN000; 3/3/KK
658 xor ax,ax ;AN000; 3/3/KK reset zero
659 inc ax ;AN000; 3/3/KK
661 ktret: ;AN000; 3/3/KK
662 pop ax ;AN000; 3/3/KK
663 pop si ;AN000; 3/3/KK
664 pop ds ;AN000; 3/3/KK
665 return
;AN000; 3/3/KK
668 ; ****************************************************************
670 ; * ROUTINE: RESET_MSG_POINTERS
672 ; * FUNCTION: Resets addresses for parse and critical error
673 ; * messages in DOS via INT 2fh. This routine
674 ; * is invoked before command exits.
680 ; ****************************************************************
682 reset_msg_pointers proc
near
684 assume
ds:resgroup
, es:nothing
686 push es ;AN000; save used registers
690 ;AD060; mov ah,multdos ;AN000; reset parse message pointers
691 ;AD060; mov al,message_2f ;AN000; call for message retriever
692 ;AD060; mov dl,set_parse_msg ;AN000; set up parse message address
693 ;AD060; mov di,pars_msg_off ;AN000; old offset of parse messages
694 ;AD060; mov es,pars_msg_seg ;AN000; old segment of parse messages
695 ;AD060; int 2fh ;AN000; go set it
697 ;AD060; mov ah,multdos ;AN000; set up to call DOS through int 2fh
698 ;AD060; mov al,message_2f ;AN000; call for message retriever
699 mov ax,(multdos
shl 8 or message_2f
);AN060; reset critical message pointers
700 mov dl,set_critical_msg
;AN000; set up critical error message address
701 mov di,crit_msg_off
;AN000; old offset of critical messages
702 mov es,crit_msg_seg
;AN000; old segment of critical messages
703 int 2fh
;AN000; go set it
704 pop di ;AN000; restore used registers
712 reset_msg_pointers endp
714 PUBLIC MSG_SERV_ST
;AN000;
715 MSG_SERV_ST
LABEL BYTE ;AN000;
717 PUBLIC SYSGETMSG
,SYSDISPMSG
719 ASSUME
DS:RESGROUP
, ES:RESGROUP
724 INCLUDE SYSMSG
.INC ;AN000; include message services
729 MSG_UTILNAME
<COMMAND
> ;AN000; define utility name
731 MSG_SERVICES
<COMR
,NEARmsg
,DISK_PROC
,GETmsg
,DISPLAYmsg
,CHARmsg
,NUMmsg
> ;AC060; include message services macro
733 PUBLIC RES_CODE_END
;AN000;
734 RES_CODE_END
LABEL BYTE ;AN000;