home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Power Programming
/
powerprogramming1994.iso
/
progtool
/
cmplngmg
/
cl89apr1.arc
/
ERROR.ARC
/
CE.ASM
next >
Wrap
Assembly Source File
|
1989-02-02
|
7KB
|
246 lines
{bt
;---------------------------------------------------------------------
; CE.ASM - Critical Error Handler
;
; To assemble: masm /ml ce;
;
; externally accessible functions:
;
; getCEasker - get address of current asker function
; setCEasker - set new asker function
; CE_trap - interrupt 24h handler
;---------------------------------------------------------------------
_DATA segment word public 'DATA'
_DATA ends
DGROUP group _DATA
_TEXT segment byte public 'CODE'
assume cs:_TEXT
AskerAddr dd 0 ; far ptr to current asker fcn
Action dw ? ; 'C', 'R', 'I' or 'A'
ErrorCode dw ? ; error code in DI
CallerAddr dd ?
CallerFlags dw ?
;---------------------------------------------------------------------
; setCEasker - change asker function
;
; C usage:
;
; void far setCEasker(askerfcnptr fcn);
;
; where:
; fcn is the address of the new asker
;---------------------------------------------------------------------
public _setCEasker
_setCEasker proc far
push bp
mov bp, sp
mov ax, [bp+6]
mov word ptr cs: AskerAddr, ax
mov ax, [bp+8];
mov word ptr cs: AskerAddr + 2, ax
pop bp
ret
_setCEasker endp
;---------------------------------------------------------------------
; getCEasker - return far ptr to current asker fcn
;
; C usage:
;
; askerfcnptr far getCEasker(void)
;
;---------------------------------------------------------------------
public _getCEasker
_getCEasker proc far
mov ax, word ptr cs: AskerAddr
mov dx, word ptr cs: AskerAddr + 2
ret
_getCEasker endp
;---------------------------------------------------------------------
; CE_trap - Critical Error trap
;
; This function calls the asker function whenever a critical
; error occurs. The asker function must return either 'R' or
; 'C' in ax.
;---------------------------------------------------------------------
public _CE_trap
_CE_trap proc far
sti
; First call the asker function to see what to do
push ax ; save entry regs and flags
push bx
push cx
push dx
push si
push di
push bp
push ds
push es
pushf
mov dx, ax ; set up DS for asker function
mov ax, DGROUP
mov ds, ax
push si ; push C arguments
push bp
push di
push dx ; ( pushing previous value of ax)
call cs: AskerAddr ; call asker function. On return ax
; will be 'C', 'R', 'I' or 'A'
add sp, 8 ; remove args from stack
mov word ptr cs: Action, ax ; save return val
popf ; restore entry state
pop es
pop ds
pop bp
pop di
pop si
pop dx
pop cx
pop bx
pop ax
; Stack and registers are now in state they were upon entry
; and Action contains 'C', 'R', 'I' or 'A' for Cancel, Retry
; Ignore or Abort
mov ax, cs: Action ; see what asker said to do
cmp ax, 'C'
je Cancel
cmp ax, 'R'
jne Ignore
mov al, 1 ; Retry operation
iret
Ignore:
cmp ax, 'I'
jne Abort
mov al, 0 ; Ignore Error
iret
Abort:
mov al, 2 ; Abort
iret
Cancel:
; Cancel operation and go directly to
; application that called 21h in
; the first place
; convert error code to standard
; return code and save it
add di, 13h
mov word ptr cs: ErrorCode, di
; Save caller's return address
push bp
mov ax, [bp+1ah]
mov word ptr cs: CallerAddr, ax
mov ax, [bp+1ch]
mov word ptr cs: CallerAddr+2, ax
; Set caller's CF and save flags
mov ax, [bp+1eh]
or ax, 1 ; set cf in flag image
mov word ptr cs: CallerFlags, ax
; Place address of label Stabilize
; on stack in place of caller's
; return address
mov ax, offset cs: Stabilize
mov [bp+1ah], ax
push cs
pop ax
mov [bp+1ch], ax
pop bp
add sp, 6 ; pop DOS IP, CS and flags
pop ax ; restore applications registers
pop bx
pop cx
pop dx
pop si
pop di
pop bp
pop ds
pop es
iret ; transfer to Stabilize
Stabilize:
; When we get here we are officially out of handler and
; back into application.
push bx ; Save applications registers
push cx
push dx
push si
push di
push bp
push ds
push es
; Call harmless DOS function to
; stabilize
mov ah, 19h ; Get Current Drive
int 21h
pop es ; Restore applications registers
pop ds
pop bp
pop di
pop si
pop dx
pop cx
pop bx
; Set stack up for IRET to appl
; Push applications flags w/ CF set
mov ax, word ptr cs: CallerFlags
push ax
; Push return address
mov ax, word ptr cs: CallerAddr+2
push ax
mov ax, word ptr cs: CallerAddr
push ax
; Put Error Code in ax
mov ax, word ptr cs: ErrorCode
iret ; Transfer back to application
_CE_trap endp
_TEXT ends
END
{et