📄 erproc.asm
字号:
MOV BX,errnum ;Pick up the error code
OR BX,BX ; Check if BX = 0
JZ ILL_FC ;Brif so - Illegal function call error
OR BH,BH ; See if gt 255
JZ SERR_5 ;Jump if okay
ILL_FC:
MOV BX,BE_ILLFUN ; Else change to illegal function call
SERR_5:
JMP SHORT B$RUNERR ; Jump to runtime error handler
cEnd nogen
SUBTTL 8086 Error Interrupt Vectors
PAGE
;***
; B$DIV0, B$OVFR - Divide by zero and Overflow interupt/exceptions
;
;Purpose:
; Hardware exception handlers for Divide by Zero and Overflow processor
; execptions.
;
;Entry:
; Return address and flags on the stack.
;
;Exit:
; Doesn't. Vectors to error handler.
;
;Uses:
;
;******************************************************************************
cProc B$DIV0,<FAR,PUBLIC>
cBegin
MOV CL,BE_DIVIDE0 ;[BL] = Basic error code
JMP SHORT EXCEPTION ;Go process
cEnd nogen
cProc B$OVFR,<FAR,PUBLIC>
cBegin
MOV CL,BE_OVERFLOW ;[BL] = Basic error code
CMP [b$cCSubs],0 ;Executing within interpeted code?
JZ EXCEPTION ;Then the error code is correct
CMP BP,[b$curframe] ;Executing within compiled code?
JZ EXCEPTION ;Then the error code is correct
MOV CL,BE_ILLFUN ;Else error within runtime, Illegal Function
EXCEPTION:
POP AX ; [AX] = IP of exception
POP DX ; [DX] = CS of exception
POPF ; Restore interrupt status
PUSH DX ; CS of exception
PUSH AX ; IP of exception
CALL B$GETDS ; [BX] = Data segment
.erre ID_SSEQDS ; Assert SS = DS
MOV ES,BX ; restore extra segment
MOV DS,BX ; restore data segment
XOR BH,BH
MOV BL,CL ; [BX] = error number
cEnd nogen ; fall into B$RUNERR
SUBTTL B$RUNERR - Runtime internal error handler
PAGE
;***
; B$RUNERR - Runtime Internal Error Handler
;
;Purpose:
; Declare an error. Transfers control to the appropriate environment handler to
; process ON ERROR if appropriate.
;
;
; NOTE: FAR PROC's in Windows save an odd BP value in the frame.
; The actual pointer is 1 less. AND w/NOT 1 realigns if even OR odd.
;
;Entry:
; [BP] = frame pointer. If equal to [b$curframe], the far address of the
; error is assumed to be on the top of the stack, and a new frame is
; created.
; [BX] = BASIC or internal error number.
;
;Exit:
; None. Transfer of control is either handled by environment specific ON ERROR
; handler, or we jump to an environment specific fatal error handler, B$FERROR.
;
;******************************************************************************
labelNP <PUBLIC,__BRUNERR> ; Quicklib compatibility label
cProc B$RUNERR,<NEAR,PUBLIC>
cBegin
MOV b$errinfo,0 ; Entry this way assumes no supplemental
labelNP <PUBLIC,B$RUNERRINFO>
MOV CX,[b$errvec] ; see if error during input
JCXZ BRUNERR_5 ; Jump if not
JMP CX ; [CX] = address to branch to, [BX] = err#
BRUNERR_5:
MOV DX,BX ; [DX] = the error number
MOV CX,BP ; [CX] = current frame pointer
CMP CX,[b$curframe]; See if it is the top level frame
JNZ BRUNERR_20 ; Jump if not, we already have a frame
BRUNERR_15:
PUSH BP ; create the frame
MOV BP,SP
MOV BX,BP ; [BX] = pointer to error frame
JMP SHORT BRUNERR_30
;
; Walk the frame chain to look for the top level frame.
;
BRUNERR_20:
MOV BX,CX ; [BX] = current frame pointer
JCXZ BRUNERR_15 ; Jump if end of chain found (make best ofit)
MOV CX,[BX] ; [CX] = next frame in chain
CMP CX,[b$curframe] ; See if top level frame found
JNZ BRUNERR_20 ; jump if not done with stack walk
;
; Terminate any I/O operation that was in progress, and determine whether this
; error can be trapped.
;
; [BX] = pointer to frame containing return address of basic-level error
; [DX] = error number
;
BRUNERR_30:
PUSH BX ; Push frame parameter to B$FERROR
MOV [b$errnum],DX ; Save error number
PUSH BX ; save frame parameter around call
MOV SI,OFFSET DGROUP:b$err_disp ; get dispatch table addr
CALL FAR PTR B$COMP_DISP ; do table dispatches
MOV b$PRFG,0 ; clear print using flag
CALL __fpreset ; Unconditionally reset Math Support
POP BX ; restore BX = frame parameter
CMP BYTE PTR [b$errnum+1], HIGH FE_NOTHINGBASE ; = 98h?
JE RUNERR_40 ; skip on error handling for 9800h range
cCALL B$ONERR ; do on error handling
CMP [b$cCSubs],0 ;See if we were interpreting at the time
JNZ RUNERR_35
MOV WORD PTR [b$errmod+2],0 ; 0 = error in interpreter
JMP SHORT RUNERR_40
RUNERR_35:
POP BX ; Restore frame parameter to BX
PUSH BX ; Push frame parameter to B$FERROR again
PUSH BX ; Push frame parameter to B$CONERR
cCALL B$CONERR ; set up b$errmod, b$errlin, etc.
;
; On error handler returned. The error could not be trapped. Handle fatal error
; as appropriate.
;
RUNERR_40:
MOV [b$inonerr],FALSE ;No longer in on error
cCall B$FERROR ;Process fatal error (param pushed way above)
DbHalt ER_TEXT,<B$FERROR returned>
cEnd B$RUNERR
SUBTTL C Startup error handler
PAGE
;***
; FatalError -- Print fatal error message to STDOUT and die. [40]
;
;Purpose:
; Added with revision [29] to handle C startup errors.
; Prints specified C startup message to STDOUT.
; Jumps to the termination routine specified by __aexit_rtn.
; Currently, the possible routines are:
; _exit, __exit, and B$terminate (all in CRT0DAT.ASM)
; If the routines are moved to another segment besides _TEXT,
; __aexit_rtn will have to be made into a FAR pointer.
;
; Also handles Non-C startup errors such as those produced in the
; CHAIN function, when memory is so screwed up that normal recovery
; is impossible.
;
;Entry:
; DS = SS = DGROUP
; BX = error number
;Exit:
; If C startup message, returns via routine specified by __aexit_rtn.
; Otherwise, returns directly to DOS without doing any C termination.
;
;Uses:
; All
;Exceptions:
; None
;******************************************************************************
cProc FatalError,<FAR>
cBegin
PUSH BX ; save error number
MOV AX,FE_STARTUPEND ; CR/LF,"runtime error"
CALL PUTNUM ; print the message
POP AX ; AX = error message number
CALL PUTNUM ; print the message
MOV AL,255 ; return code = -1
PUSH AX ; put it on the stack for termination routine
; (must be preserved, too).
PUSH AX ; space on stack as if we CALLED exit routine
PUSH AX ; FAR (to set up its frame correctly)
MOV BX,SEG _exit ; termination function segment
PUSH BX ; (functions are FAR, but called NEAR)
PUSH __aexit_rtn ; termination function offset
RET ; RETF will jump to error routine
cEnd <nogen>
;***
; B$PUTNUM -- print error message to STDOUT..
;
;Purpose:
; Used to print messages using DOS when PRINT support may not be there.
; Added with revision [29].
; Modified to be used with all fatal errors [31].
;
; Gets the message text associated with an error message number, and
; prints the text to STDOUT.
;
;Entry:
; DS = SS = DGROUP
; AX = error number
;Exit:
; None
;Uses:
; Per convention
;Preserves:
; SI
;Exceptions:
;
;******************************************************************************
cProc PUTNUM,<NEAR>,<SI>
cBegin
cCall __FMSG_TEXT,AX ; returns DX:AX = message address
mov si,ax ; DX:SI = message address
PUTNUM_15:
push ds ; save DS
mov ds,dx ; DS:SI = message address
lodsb ; AL = next character to print
pop ds ; restore DS
or al,al ; check for null
jz PUTNUM_20 ; brif at end of string
cCall B$PUTCHR ; print the character
jmp SHORT PUTNUM_15 ; and go back for more...
PUTNUM_20:
cEnd
;***
; B$PUTCHR -- print char to stdout
;
;Purpose:
; print char to stdout
;Entry:
; AL = char to print
;Exit:
; None
;Uses:
; AX
;Exceptions:
; None
;******************************************************************************
cProc B$PUTCHR,<PUBLIC,NEAR>,<DX>
cBegin
mov dx,ax
callos DCIO ; display the character through DOS
cEnd
;***
; B$PUTUI - Write an unsigned 16-bit integer to console
; Moved here with revision [62]
;
;Purpose:
; Write an unsigned 16-bit integer to console via DOS
;
;Entry:
; [AX] = 16-bit unsigned integer to be printed
; [CX] = Near offset of routine to call to print characters.
;
;Exit:
; None.
;
;Uses:
; Per convention.
;****
cProc B$PUTUI <PUBLIC,NEAR>
cBegin
MOV BX,10 ; prepare to divide by 10
XOR DX,DX ; null marks end of string
PUTUI_5:
PUSH DX ; save digit on stack
XOR DX,DX
DIV BX ; using BX forces 16-bit quotient capability
ADD DL,'0' ; add 30H for ASCII '0'
OR AX,AX ; check if there are more digits to print
JNZ PUTUI_5 ; brif
MOV AX,DX
PUTUI_10: ; print the string
cCall CX ; print a digit
POP AX ; get next digit
OR AX,AX ; more digits to print?
JNZ PUTUI_10 ; brif
cEnd
sEnd ; ER_TEXT
sBegin _TEXT
assumes CS,_TEXT
;***
;__amsg_exit, B$amsg_exit -- print C fatal startup message and terminate
;
;Purpose:
; Moved here with revision [48]
;
;Entry:
; AX = C startup error message number
;
;Exit:
;
;Uses:
;
;Preserves:
;
;Exceptions:
;
;******************************************************************************
labelNP <PUBLIC,__amsg_exit>
cProc amsg_exit,<NEAR>
cBegin
XCHG AX,BX ; BX = BASIC error number
MOV BH,FE_STARTUPBASE SHR 8 ; BH = 9Ah (C startup error)
PUSH SS ; set DS = SS = DGROUP
POP DS
JMP FAR PTR FatalError ; print error message and terminate
cEnd <nogen>
sEnd ; _TEXT
END
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -