;Notes -- The Critical Error Handler (int 24h) can be freely set and
;         reset by any program that wants to.  DOS makes it easy to
;         do so by automatically restoring the previous handler upon
;         exit.  Thus you don't have to worry about cleaning up the
;         vector before exiting.  You cannot use Int 27h to install
;         a critical interrupt handler as a TSR, because DOS also 
;         restores the old handler with 27h just as it does with a 
;         normal exit.  If you want to, you can change the vector that
;         DOS restores to point to your own routine.  Upon building the
;         PSP, DOS stores the old critical error handler address at offset,
;         12h in the PSP.  (More specifically, it is stored in Offset/Segment
;         format, (4 bytes) beginning at offset 12h of the PSP.  so.....
;         if you want to change the vector that DOS restores, put your own
;         handler's segment at PSP + 14h and its offset at PSP 12h.
;
;         This (resetting the PSP vector) is only necessary if your program 
;         goes TSR, and not if it is a stand-alone program.
;
;The rest of this program deals with the more normal case, installing a
;        custom critical error handler for just the currently running program.




CSEG	SEGMENT	PARA	PUBLIC 'CODE'
	ASSUME CS:CSEG,DS:CSEG,ES:CSEG,SS:CSEG
	ORG	100H
	
PROGRAM	PROC	NEAR
	
START:
	MOV	DX,OFFSET NEWINT24	;load the address of our handler
	MOV	AX,2524H		;into the interrupt vector table
	INT	21H			;and execute the interrupt change
	
;-------------------------------------------------------------------------
;  Here I put the main part of my program,
;          doing whatever it is supposed to do
;
;  NOTE:  You do NOT have to save & reset the INT 24h
;         vector at the end of the program.
;         It is automatically restored by DOS
;         from the PSP upon exit.
;
;  NOTE:  Your program should check the ERRFLAG code
;         after performing any operation which can
;	  produce a critical error (disk, printer, or
;         device request) and should take the appropriate
;         action (inform the user, abort the program, or 
;         whatever)
;--------------------------------------------------------------------------

EXIT:	MOV	AX,4C00H
	INT	21H
PROGRAM	ENDP


ERRFLAG		DB 0			;a flag which will be incremented by
                                        ;  one each time there is a 
					;  a critical error.  The main program
					;  must decide what to do when it
					;  finds this flag set.
					;  i.e. continue, alert user, etc.
					;  (and of course reset the flag to
					;  zero when finished)

;--------------------------------------------------------------------------
;  Here is the interrupt procedure to intercept the critical error handler
;--------------------------------------------------------------------------

NEWINT24	PROC FAR
	ASSUME	CS:NOTHING,DS:NOTHING,ES:NOTHING	;don't know where they
							;  will be upon entry
	STI				;enable the interrupts which are
					;  automatically disabled upon entry
	INC	ERRFLAG			;set my own error flag for some later
					;  action by main program
	XOR	AL,AL			;tell DOS to ignore the error
	IRET				;send it back to where it came
	
NEWINT24	ENDP

;--------------------------------------------------------------------------
;  End of the interrupt procedure to intercept the critical error handler
;--------------------------------------------------------------------------

CSEG	ENDS
	END	PROGRAM
	