mirror of
https://github.com/SEPPDROID/DR-DOS-OpenDOS.git
synced 2025-10-22 07:54:28 +00:00
590 lines
15 KiB
NASM
590 lines
15 KiB
NASM
; File : $Workfile: CRIT.ASM$
|
|
;
|
|
; Description :
|
|
;
|
|
; Original Author : DIGITAL RESEARCH
|
|
;
|
|
; Last Edited By : $CALDERA$
|
|
;
|
|
;-----------------------------------------------------------------------;
|
|
; Copyright Work of Caldera, Inc. All Rights Reserved.
|
|
;
|
|
; THIS WORK IS A COPYRIGHT WORK AND CONTAINS CONFIDENTIAL,
|
|
; PROPRIETARY AND TRADE SECRET INFORMATION OF CALDERA, INC.
|
|
; ACCESS TO THIS WORK IS RESTRICTED TO (I) CALDERA, INC. EMPLOYEES
|
|
; WHO HAVE A NEED TO KNOW TO PERFORM TASKS WITHIN THE SCOPE OF
|
|
; THEIR ASSIGNMENTS AND (II) ENTITIES OTHER THAN CALDERA, INC. WHO
|
|
; HAVE ACCEPTED THE CALDERA OPENDOS SOURCE LICENSE OR OTHER CALDERA LICENSE
|
|
; AGREEMENTS. EXCEPT UNDER THE EXPRESS TERMS OF THE CALDERA LICENSE
|
|
; AGREEMENT NO PART OF THIS WORK MAY BE USED, PRACTICED, PERFORMED,
|
|
; COPIED, DISTRIBUTED, REVISED, MODIFIED, TRANSLATED, ABRIDGED,
|
|
; CONDENSED, EXPANDED, COLLECTED, COMPILED, LINKED, RECAST,
|
|
; TRANSFORMED OR ADAPTED WITHOUT THE PRIOR WRITTEN CONSENT OF
|
|
; CALDERA, INC. ANY USE OR EXPLOITATION OF THIS WORK WITHOUT
|
|
; AUTHORIZATION COULD SUBJECT THE PERPETRATOR TO CRIMINAL AND
|
|
; CIVIL LIABILITY.
|
|
;-----------------------------------------------------------------------;
|
|
;
|
|
; *** Current Edit History ***
|
|
; *** End of Current Edit History ***
|
|
;
|
|
; $Log$
|
|
; CRIT.ASM 1.11 94/12/01 10:05:21
|
|
; Changed critical error message display so that the default message
|
|
; is 'I/O error' and that all share-related codes are converted to
|
|
; 'File sharing conflict'
|
|
;
|
|
; CRIT.ASM 1.9 93/09/10 15:56:08
|
|
; Use device driver header at BP:SI instead of AH to determine if disk/char device
|
|
; That way we get "device NETWORK" rather than "drive D" on VLM critical errors
|
|
; ENDLOG
|
|
;
|
|
; 19/Sep/88 Move the messages into a separate module
|
|
; 15/Dec/88 Critical Error messages processed by STDERR
|
|
; 06/Apr/89 DR DOS version taken from PCMODE & put in COMMAND.COM
|
|
; 10/Aug/89 Issue INT 2F's so application can give it's own error message
|
|
; 08/Sep/89 'No FCBs' message
|
|
; 02/Nov/89 abort_char etc become ABS rather than CHAR (saves a few bytes)
|
|
; 13/Nov/89 Reduced number of external messages referenced to one
|
|
; (crit_top) to aid Dual Language Support.
|
|
; 12/Feb/90 Changed code to avoid problems with double byte character sets.
|
|
; 8/Mar/90 Remove extra pair of CR/LF's that were output after error
|
|
; 20/Apr/90 DLS data into R_TEXT for Watcom C v7.0
|
|
; 9/May/90 Critical errors go to STDERR on command PSP, not current_psp
|
|
|
|
include msdos.equ
|
|
include mserror.equ
|
|
include driver.equ
|
|
;
|
|
dataOFFSET equ offset DGROUP:
|
|
|
|
|
|
PSP_XFTPTR equ es:dword ptr 34h ; from i:PSP.DEF
|
|
|
|
; Critical Error responses from the default INT 24 handler and
|
|
; the DO_INT24 routine.
|
|
;
|
|
ERR_IGNORE equ 0 ; Ignore Error
|
|
ERR_RETRY equ 1 ; Retry the Operation
|
|
ERR_ABORT equ 2 ; Terminate the Process
|
|
ERR_FAIL equ 3 ; Fail Function
|
|
;
|
|
OK_FAIL equ 00001000b ; Fail is a Valid Response
|
|
OK_RETRY equ 00010000b ; Retry is a Valid Response
|
|
OK_IGNORE equ 00100000b ; Ignore is a valid Response
|
|
OK_RIF equ 00111000b ; All Responsese are Valid
|
|
OK_RI equ 00110000b ; Retry and Ignore are Valid
|
|
OK_RF equ 00011000b ; Retry and Fail are Valid
|
|
;
|
|
;
|
|
; The following equates allow us to access the users registers
|
|
; and flags during normal system call emulation.
|
|
;
|
|
;NOTE:- The users INT21 structure is not normally available because of the
|
|
; stack switch which occurs on entry and only the general purpose
|
|
; registers are copied to the new stack.
|
|
;
|
|
dos_AX equ word ptr 0[bp]
|
|
dos_BX equ word ptr 2[bp]
|
|
dos_CX equ word ptr 4[bp]
|
|
dos_DX equ word ptr 6[bp]
|
|
dos_SI equ word ptr 8[bp]
|
|
dos_DI equ word ptr 10[bp]
|
|
dos_BP equ word ptr 12[bp]
|
|
dos_DS equ word ptr 14[bp]
|
|
dos_ES equ word ptr 16[bp]
|
|
;
|
|
;
|
|
;
|
|
ifdef CDOSTMP
|
|
DGROUP GROUP R_TEXT
|
|
|
|
R_TEXT SEGMENT byte public 'CDOS_DATA'
|
|
|
|
else
|
|
|
|
DGROUP GROUP _DATA, R_TEXT, ED_TEXT
|
|
|
|
R_TEXT SEGMENT byte public 'CDOS_DATA'
|
|
R_TEXT ENDS
|
|
|
|
_DATA SEGMENT byte public 'DATA'
|
|
|
|
endif
|
|
extrn _country:WORD
|
|
extrn __psp:WORD
|
|
|
|
ifdef DLS
|
|
TEXT_LEN equ 320 ; it needs to be this size for Japanese
|
|
|
|
Public _crit_msgs
|
|
|
|
; crit_table gives offset into crit_msgs table.
|
|
|
|
crit_table db 0 ; (00) Write to Read Only Disk
|
|
db 2 ; (01) Unknown Unit
|
|
db 4 ; (02) Drive Not Ready
|
|
db 2 ; (03) Unknown Command
|
|
db 6 ; (04) Data Error (CRC)
|
|
db 2 ; (05) Bad Request Length Structure
|
|
db 8 ; (06) Seek Error
|
|
db 10 ; (07) Unknown Media Type
|
|
db 12 ; (08) Sector Not Found
|
|
db 14 ; (09) Printer Out Of Paper
|
|
db 2 ; (0A) Write Fault
|
|
db 2 ; (0B) Read Fault
|
|
db 2 ; (0C) General Failure
|
|
db 16 ; (0D) File Sharing Error
|
|
db 16 ; (0E) Locking Error
|
|
db 18 ; (0F) FCB Unavailable
|
|
|
|
_crit_msgs dw TEXT_LEN ; size of this message buffer
|
|
crit_top dw 0,0,0,0,0,0,0,0,0,0
|
|
msg_crlf dw 0
|
|
readmsg dw 0
|
|
writemsg dw 0
|
|
drivemsg dw 0
|
|
charmsg dw 0
|
|
abort_char dw 0
|
|
abort_msg dw 0
|
|
retry_char dw 0
|
|
retry_msg dw 0
|
|
ignore_char dw 0
|
|
ignore_msg dw 0
|
|
fail_char dw 0
|
|
fail_msg dw 0
|
|
prompt_msg dw 0
|
|
dw 0 ; end of list
|
|
|
|
public _crit_text
|
|
_crit_text db TEXT_LEN dup(?) ; message text is placed here
|
|
|
|
CRIT_LEN equ $-crit_top
|
|
|
|
|
|
else
|
|
|
|
extrn msg0:byte, msg2:byte, msg3:byte, msg4:byte
|
|
extrn msg6:byte, msg7:byte, msg8:byte
|
|
extrn msg20:byte, msg21:byte, msg22:byte
|
|
|
|
crit_top dw offset DGROUP:msg0 ; (00) Write to Read Only Disk
|
|
dw offset DGROUP:msg3 ; (01) Unknown Unit
|
|
dw offset DGROUP:msg2 ; (02) Drive Not Ready
|
|
dw offset DGROUP:msg3 ; (03) Unknown Command
|
|
dw offset DGROUP:msg4 ; (04) Data Error (CRC)
|
|
dw offset DGROUP:msg3 ; (05) Bad Request Length Structure
|
|
dw offset DGROUP:msg6 ; (06) Seek Error
|
|
dw offset DGROUP:msg7 ; (07) Unknown Media Type
|
|
dw offset DGROUP:msg8 ; (08) Sector Not Found
|
|
dw offset DGROUP:msg21 ; (09) Printer Out Of Paper
|
|
dw offset DGROUP:msg3 ; (0A) Write Fault
|
|
dw offset DGROUP:msg3 ; (0B) Read Fault
|
|
dw offset DGROUP:msg3 ; (0C) General Failure
|
|
dw offset DGROUP:msg20 ; (0D) File Sharing Error
|
|
dw offset DGROUP:msg20 ; (0E) Locking Error
|
|
dw offset DGROUP:msg22 ; (0F) FCB Unavailable
|
|
|
|
|
|
Extrn msg_crlf:byte
|
|
Extrn readmsg:byte, writemsg:byte, drivemsg:byte, charmsg:byte
|
|
Extrn abort_char:byte, abort_msg:byte
|
|
Extrn retry_char:byte, retry_msg:byte
|
|
Extrn ignore_char:byte, ignore_msg:byte
|
|
Extrn fail_char:byte, fail_msg:byte, prompt_msg:byte
|
|
endif
|
|
ifndef CDOSTMP
|
|
_DATA ends
|
|
ED_TEXT SEGMENT para public 'CDATA'
|
|
endif
|
|
|
|
assume cs:DGROUP, ds:nothing, es:nothing, ss:nothing
|
|
;
|
|
; This is the default critical error handler which will prompt
|
|
; the user with an error message and wait for a response. This handler
|
|
; is usually replaced by the DOS application
|
|
;
|
|
; +++++++++++++++++++++++++++++++
|
|
; Int 24 - Critical Error Handler
|
|
; +++++++++++++++++++++++++++++++
|
|
;
|
|
; INT 24 Critical Error:-
|
|
; On Entry:- AH/7 0 = Disk Device
|
|
; AH/5 0 = IGNORE is an Invalid Response
|
|
; AH/4 0 = RETRY in an Invalid Response
|
|
; AH/3 0 = FAIL is an Invalid Response
|
|
; AH/2-1 00= DOS Area
|
|
; 01= File Allocation Table
|
|
; 10= Directory
|
|
; 11= Data
|
|
; AH/0 0 = Read, 1 = Write
|
|
;
|
|
; AL Failing Disk Drive if AH/7 == 0
|
|
; BP:SI Device Header Control Block
|
|
; DI High Byte DRNET server (inverted, CDOS only)
|
|
; Low Byte Error Code
|
|
;
|
|
; On Exit:- AL 0 = IGNORE Error
|
|
; 1 = RETRY the Operation
|
|
; 2 = TERMINATE using INT 23
|
|
; 3 = FAIL the current DOS function
|
|
;
|
|
;
|
|
|
|
Public com_criterr
|
|
com_criterr:
|
|
;
|
|
; This is called by the int24 handler 'critical_error', in CSTART.ASM.
|
|
;
|
|
sti
|
|
cld
|
|
push es
|
|
push ds
|
|
push bp
|
|
push di
|
|
push si
|
|
push dx
|
|
push cx
|
|
push bx
|
|
push ax
|
|
|
|
mov bp,sp
|
|
mov ah,MS_P_GETPSP
|
|
int DOS_INT ; Get PSP into DS
|
|
mov ds,cs:__psp
|
|
mov al,ds:byte ptr 1ah ; use COMMAND STDERR for Console INPUT
|
|
mov ah,al ; and OUTPUT
|
|
mov es,bx
|
|
lds bx,PSP_XFTPTR ; Get the handle table pointer
|
|
push word ptr [bx] ; Save the current Values
|
|
mov word ptr [bx],ax
|
|
|
|
push cs
|
|
pop ds ; DS == CS
|
|
call i24_crlf ;output carriage return - line feed
|
|
|
|
mov ah,MS_F_ERROR
|
|
xor bx,bx
|
|
int DOS_INT ; Get extended error code
|
|
mov cx,ax ; Get the Real Error Code (ie INT21/59)
|
|
mov bx,0Fh ; assume FCB unavailable
|
|
cmp al,-(ED_NOFCBS) ; if FCB exhausted/closed then generate
|
|
je int24_e10 ; a more appropriate error message
|
|
dec bx
|
|
dec bx
|
|
cmp al,-(ED_SHAREFAIL) ; check for sharing failure which
|
|
je int24_e10 ; is forced to be a DRIVE NOT READY
|
|
cmp al,-(ED_NOLOCKS) ; check for sharing buffer overflow
|
|
je int24_e10
|
|
dec bx ; BX = 0Ch, default error
|
|
mov ax,dos_DI ; get the REAL error code
|
|
cmp ax,0Eh ; is it a sensible value ?
|
|
ja int24_e10 ; no, return GENERAL FAILURE
|
|
xchg ax,bx ; yes, use it
|
|
int24_e10:
|
|
call int24_errmsg ; print out the offending error msg
|
|
call i24_crlf ; Print CR/LF
|
|
|
|
;
|
|
; This section of the Critical Error handler prints the correct
|
|
; prompt repeatedly until the user responds with a correct
|
|
; response. This value is returned to the PCMODE.
|
|
;
|
|
i24_query:
|
|
ifdef DLS
|
|
mov dx,abort_msg ; Print "Abort" as this is always
|
|
else
|
|
mov dx,dataOFFSET abort_msg ; Print "Abort" as this is always
|
|
endif
|
|
call i24_print ; a valid response
|
|
|
|
test bh,OK_RETRY
|
|
jz i24_q10 ; Display ", Retry" if RETRY
|
|
ifdef DLS
|
|
mov dx,retry_msg ; is a Valid Response
|
|
else
|
|
mov dx,dataOFFSET retry_msg ; is a Valid Response
|
|
endif
|
|
call i24_print
|
|
|
|
i24_q10:
|
|
test bh,OK_IGNORE
|
|
jz i24_q20 ; Display ", Ignore" if IGNORE
|
|
ifdef DLS
|
|
mov dx,ignore_msg ; is a valid response
|
|
else
|
|
mov dx,dataOFFSET ignore_msg ; is a valid response
|
|
endif
|
|
call i24_print
|
|
|
|
i24_q20:
|
|
test bh,OK_FAIL
|
|
jz i24_q30 ; Display ", Fail" if FAIL is
|
|
ifdef DLS
|
|
mov dx,fail_msg ; a valid response
|
|
else
|
|
mov dx,dataOFFSET fail_msg ; a valid response
|
|
endif
|
|
call i24_print
|
|
|
|
i24_q30:
|
|
ifdef DLS
|
|
mov dx,prompt_msg
|
|
else
|
|
mov dx,dataOFFSET prompt_msg
|
|
endif
|
|
call i24_print
|
|
|
|
mov ah,MS_C_FLUSH ; Clear type ahead buffer
|
|
mov al,MS_C_READ ; and then get a character
|
|
int DOS_INT
|
|
|
|
; In case we get double byte characters...
|
|
; If we had access to the dbcs_lead() routine (in the non-resident code)
|
|
; we could test for a double byte character and consume the second byte.
|
|
; Since we can't do this I have used the following code, which simply
|
|
; consumes and displays all bytes in type-ahead buffer.
|
|
push ax ; save first character received
|
|
dbcs_loop:
|
|
mov ah, MS_C_RAWIO ; char in type-ahead buffer?
|
|
mov dl, 0FFh
|
|
int DOS_INT
|
|
jz dbcs_exit ; no - exit loop
|
|
mov dl, al
|
|
mov ah, MS_C_WRITE ; yes - display char
|
|
int DOS_INT
|
|
jmp short dbcs_loop ; loop until type-ahead buffer empty
|
|
dbcs_exit:
|
|
pop ax ; restore the first character
|
|
|
|
; Check that character lies in the range 'a' <= ch <= 'z' before anding it
|
|
; with 5Fh to uppercase it (incase the character is a DBCS lead byte).
|
|
|
|
cmp al, 'a' ; ch < 'a' ?
|
|
jb uc_done ; yes - skip upper casing
|
|
cmp al, 'z' ; ch > 'z' ?
|
|
ja uc_intl ; yes - may be intl
|
|
and al, 5Fh ; uppercase ch
|
|
jmp short uc_done
|
|
uc_intl:
|
|
cmp al, 80h ; international char?
|
|
jb uc_done
|
|
; ch >= 80h -- call international routine
|
|
UCASE equ 18 ; offset of dword ptr to uppercase func
|
|
call dword ptr [_country+UCASE]
|
|
uc_done:
|
|
|
|
push ax
|
|
call i24_crlf
|
|
pop dx
|
|
|
|
mov ah,bh
|
|
xor al,al ; AL == 0 IGNORE Error
|
|
ifdef DLS
|
|
test ah,OK_IGNORE
|
|
jz i24_q40 ; Is it a valid response
|
|
mov bx,ignore_char
|
|
cmp dl,[bx]
|
|
else
|
|
test bh,OK_IGNORE
|
|
jz i24_q40 ; Is it a valid response
|
|
cmp dl,ignore_char
|
|
endif
|
|
jz i24_exit
|
|
|
|
i24_q40:
|
|
inc ax ; AL == 1 RETRY Function
|
|
ifdef DLS
|
|
test ah,OK_RETRY
|
|
jz i24_q50 ; Is it a valid response
|
|
mov bx,retry_char
|
|
cmp dl,[bx]
|
|
else
|
|
test bh,OK_RETRY
|
|
jz i24_q50 ; Is it a valid response
|
|
cmp dl,retry_char
|
|
endif
|
|
jz i24_exit
|
|
|
|
i24_q50:
|
|
inc ax ; AL == 2 ABORT Process
|
|
ifdef DLS
|
|
mov bx,abort_char
|
|
cmp dl,[bx]
|
|
else
|
|
cmp dl,abort_char
|
|
endif
|
|
jz i24_exit
|
|
|
|
inc ax ; AL == 3 FAIL Function
|
|
ifdef DLS
|
|
test ah,OK_FAIL
|
|
jz i24_query_again ; Is it a valid response
|
|
mov bx,fail_char
|
|
cmp dl,[bx]
|
|
jz i24_exit
|
|
i24_query_again:
|
|
mov bh, ah ; restore valid response bit set
|
|
jmp i24_query
|
|
else
|
|
test bh,OK_FAIL
|
|
jz i24_query_again ; Is it a valid response
|
|
cmp dl,fail_char
|
|
jz i24_exit
|
|
i24_query_again:
|
|
jmp i24_query
|
|
endif
|
|
|
|
|
|
i24_exit:
|
|
mov dos_AX,ax
|
|
mov ah,MS_P_GETPSP
|
|
int DOS_INT ; Get PSP into DS
|
|
mov es,bx
|
|
lds bx,PSP_XFTPTR ; the handle table pointer
|
|
pop word ptr [bx] ; Restore the original handle Values
|
|
|
|
pop ax
|
|
pop bx
|
|
pop cx
|
|
pop dx
|
|
pop si
|
|
pop di
|
|
pop bp
|
|
pop ds
|
|
pop es
|
|
|
|
ret
|
|
|
|
int24_errmsg:
|
|
; Print out an appropriate error message (eg. "Drive not ready")
|
|
; Call INT 2F functions in case system extentions (eg. CDROM) wish to
|
|
; give another error message.
|
|
push bx ; save error code
|
|
push cx
|
|
mov ax,500h
|
|
int 2fh ; query if user msg handler installed
|
|
cmp al,0ffh ; yes if FF returned
|
|
pop cx
|
|
pop bx
|
|
jne int24_errmsg10
|
|
push bx
|
|
push cx
|
|
if 0
|
|
; the DOS 3 way
|
|
mov ah,5 ; OK. now we ask for a message
|
|
mov al,cl ; with the error code in AL
|
|
else
|
|
; the DOS 5 way
|
|
mov ax,501h
|
|
mov bx,cx
|
|
endif
|
|
int 2fh ; ES:DI -> msg
|
|
pop cx
|
|
pop bx
|
|
jc int24_errmsg10 ; did they give us a msg ?
|
|
mov si,di ; ES:SI -> msg
|
|
mov ah,MS_C_WRITE ; write it out
|
|
int24_errmsg1:
|
|
lods es:byte ptr [si] ; get a character
|
|
test al,al ; until end of an ASCIIZ string
|
|
jz int24_errmsg2
|
|
mov dl,al ; character into DL
|
|
int DOS_INT ; write it
|
|
jmp short int24_errmsg1
|
|
int24_errmsg2:
|
|
mov bx,dos_AX ; get original AX for Abort/Retry etc
|
|
ret
|
|
|
|
int24_errmsg10:
|
|
; No-one wants to supply a message - we'd better generate one ourselves
|
|
;
|
|
xor bh,bh
|
|
ifdef DLS
|
|
mov bl, crit_table[bx]
|
|
else
|
|
shl bx,1
|
|
endif
|
|
mov dx, crit_top[bx]
|
|
call i24_print
|
|
|
|
mov bx,dos_AX ; Get the Original AX
|
|
test bh,01h ; check to see if the error occured
|
|
jnz prwrite ; while reading or writing
|
|
ifdef DLS
|
|
mov dx,readmsg ; print 'reading'
|
|
else
|
|
mov dx,dataOFFSET readmsg ; print 'reading'
|
|
endif
|
|
jmp short prread
|
|
prwrite:
|
|
ifdef DLS
|
|
mov dx,writemsg ; print 'writing'
|
|
else
|
|
mov dx,dataOFFSET writemsg ; print 'writing'
|
|
endif
|
|
prread:
|
|
call i24_print ; appropriate string
|
|
;; test bh,80h
|
|
mov es,dos_BP ; ES:SI = driver header
|
|
test es:DH_ATTRIB[si],DA_CHARDEV
|
|
jz disk_error ; Was this a DISK error
|
|
|
|
;
|
|
; For Character Device errors print the failing Device Name
|
|
; and then prompt the user for a valid response.
|
|
;
|
|
;character_error:
|
|
ifdef DLS
|
|
mov dx,charmsg
|
|
else
|
|
mov dx,dataOFFSET charmsg
|
|
endif
|
|
call i24_print
|
|
|
|
;; mov es,dos_BP ; ES:SI = driver header
|
|
mov cx,8 ; Print the 8 Character device name
|
|
char_name:
|
|
mov dl,DH_NAME[si] ; Get the next character and
|
|
mov ah,MS_C_WRITE ; display on the console
|
|
int DOS_INT
|
|
inc si ; Increment the character pointer
|
|
loop char_name ; and Loop till complete name displayed
|
|
ret ; Now query the user
|
|
|
|
;
|
|
; For DISK errors print the failing drive code and then
|
|
; prompt the user for a valid response.
|
|
;
|
|
disk_error:
|
|
ifdef DLS
|
|
mov dx,drivemsg ;
|
|
else
|
|
mov dx,dataOFFSET drivemsg ;
|
|
endif
|
|
call i24_print ; print 'drive d'
|
|
mov dl,bl ; Get the Drive Code
|
|
add dl,'A' ; convert drive to ascii
|
|
mov ah,MS_C_WRITE ; print the drive
|
|
int DOS_INT
|
|
ret
|
|
|
|
i24_crlf:
|
|
ifdef DLS
|
|
mov dx,msg_crlf
|
|
else
|
|
mov dx,dataOFFSET msg_crlf
|
|
endif
|
|
|
|
i24_print:
|
|
mov ah,MS_C_WRITESTR
|
|
int DOS_INT
|
|
ret
|
|
|
|
ifdef CDOSTMP
|
|
R_TEXT ENDS
|
|
else
|
|
ED_TEXT ENDS
|
|
endif
|
|
end
|