home *** CD-ROM | disk | FTP | other *** search
- {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