📄 crit.asm
字号:
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
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -