home *** CD-ROM | disk | FTP | other *** search
- Page ,132
- ;****************************************************************
- ;* File Id. Int24a.Asm *
- ;* Author. Stan Milam. *
- ;* Date Written. 11/05/89. *
- ;* *
- ;* (c) Copyright 1989, 1990 by Stan Milam *
- ;* *
- ;* Comments: This code will act as an interrupt handler for *
- ;* interrupt 24, the DOS Critical Interrupt. It will preserve *
- ;* the stack, restore the applications DS & ES register and pass*
- ;* information about the critical error to a C function that *
- ;* will use a pop-up menu window to give information and accept *
- ;* input to the user. *
- ;* *
- ;* Added code to switch stacks to allow interrupt to be called *
- ;* by a child process. Stack at time of DOS interrupt is stored*
- ;* at offset 0x2e of Program Segment Prefix. *
- ;* Added code to FAIL the operation when return code is 3 even *
- ;* in DOS versions before 3.1. *
- ;* *
- ;* If C function returns -1 (0xffff) we must call the original *
- ;* Int 24. *
- ;* *
- ;* Research material: *
- ;* PC Tech Journal, April 1987, Exception Handling *
- ;* Advanced MS-DOS, Second Edition, by Ray Duncan *
- ;* MS-DOS Encyclopedia *
- ;****************************************************************
- ;
- Dosseg ;Declare Normal Segmentation
- IFDEF POWERC
- .Model Large ;Large Model for Power C
- ELSE
- .Model Large,C ;And Turbo & MSC
- ENDIF
- Extrn old_int24:Dword ;Address of old interrupt
- Extrn _psp:Word ;Segment Address of PSP
- .Code
- Extrn Critical_Interrupt:Far
- ;
- ; Declare storage in the code segment to save ES & DS
- ;
- old_es Dw 0
- old_ds Dw 0
- save_ss Dw ?
- save_sp Dw ?
- Page
- ;
- ;****************************************************************
- ;* Int24 *
- ;* *
- ;* This routine will be entered when interrupt 24 is generated *
- ;* by DOS. *
- ;* *
- ;* Major Goals: Save stack, Restore application DS & ES, push *
- ;* information on stack & call C routine, return to DOS with *
- ;* return information in AX *
- ;* If -1 (0xffff) is returned by C routine then restore regs & *
- ;* invoke the original INT 24 handler. *
- ;****************************************************************
- ;
- Public Int24
- Int24 Proc Far
- Push Bp ;Set up the stack frame
- Mov Bp,Sp
- Push Ds ;Preserve the registers
- Push Es
- Push Bx
- Push Cx
- Mov Cx,[Bp] ;Save Bp because we swithc stacks
- IFDEF POWERC
- Push Cs:[old_ds] ;Restore Data Segment
- Pop Ds
- Mov Bx,_psp ;Get PSP Address in Es so
- Mov Es,Bx ;We can switch stacks.
- ELSE
- Mov Bx,@Data ;This the way we restore DS &
- Mov Ds,Bx ;get the PSP address in Turbo C
- Mov Bx,Seg _psp ;and Microsoft C.
- Mov Es,Bx ;This method accomodates all of
- Mov Bx,Es:[_psp] ;the different memory models.
- Mov Es,Bx
- ENDIF
- Mov Cs:[save_ss],Ss ;Save Stack address in Code Seg
- Mov Cs:[save_sp],Sp ;So we can switch
- Mov Ss,Es:[30h] ;Switch stacks, this allows
- Mov Sp,Es:[2eh] ;Child process to use interrupt
- Sub Sp,0eh ;Protect Stack if not child
- Sti ;Start Interrupts
- Push Dx ;Now save every thing else
- Push Si
- Push Di
- ;
- ;These next 4 pushes are parms to C function
- ;
- Push Cx ;Bp:Si is far pointer to
- Push Si ;Device Header
- Push Di ;Di & Ax are parms to C
- Push Ax ;routine. Info passed by DOS.
- Call Critical_Interrupt ;Call C routine
- Cli ;Turn off interrupts
- Cmp Ax,0FFFFh ;Was -1 returned?
- Jne Norm_Exit ;No, so return with value in Ax
- Page
- ;
- ;**************************************************************
- ;* This part of the code is going to call the orininal INT 24 *
- ;* To do this we must maintain Ds & Es becuase the pointer to *
- ;* the old INT 24 is stored in the Data Segment of our *
- ;* program. However, we restore all other registers. Notice *
- ;* the strange manipulations of the stack that had to be made *
- ;* to preserve Ds & Es. *
- ;**************************************************************
- ;
- IFDEF POWERC
- Push Ds ;Force Es & DS to be same
- Pop Es ;To point at old interrupt
- ELSE
- Mov Ax,Seg old_int24 ;Get Segment address for
- Mov Es,Ax ;Old interrupt
- ENDIF
- Pop Ax ;Else restore registers as they
- Add Sp,+6 ;were upon entry and call the
- Pop Di ;original INT 24 handler (Except
- Pop Si ;for Es & Ds)
- Pop Dx
- Mov Ss,Cs:[save_ss] ;Switch stacks back
- Mov Sp,Cs:[save_sp]
- Pop Cx ;
- Pop Bx
- Mov Sp,Bp
- Pop Bp ;Restored everything but Ds & Es
- Sub Sp,+6 ;Save Bp,Es,Ds
- Pushf ;Push flags to fake an interrupt
- Call Es:Dword Ptr old_int24 ;Call to old INT 24
- Pop Es ;Finally, Restore Ds & Es!
- Pop Ds
- Pop Bp
- Jmp Exit
- Norm_Exit:
- Mov Bx,Ax ;Restore Ah to the way it was
- Pop Ax ;When we entered leaving return
- Mov Al,Bl ;Code in Al.
- Add Sp,+6 ;Remove Parms to C code
- Pop Di ;Restore Registers but return
- Pop Si ;User action in Ax
- Pop Dx
- Mov Ss,Cs:[save_ss] ;Switch stacks back
- Mov Sp,Cs:[save_sp]
- Pop Cx ;Be sure to restore these
- Pop Bx
- Pop Es
- Pop Ds
- Mov Sp,Bp
- Pop Bp
- Exit:
- Cmp Al,3 ;Was it a FAIL request?
- Je Fail ;Yes it was
- Iret ;Not a FAIL--Return to Dos
- Page
- ;
- ;**************************************************************
- ;* FAIL *
- ;* *
- ;* Since the FAIL option does not exist in versions of DOS *
- ;* before 3.1 I have written my own fail operation. Simply *
- ;* restores registers, move 0xffff into Ax (?), set the carry *
- ;* flag, and RET 2 back to the interrupted program. *
- ;**************************************************************
- ;
- Fail: Add Sp,6 ;Remove DOS return address
- Pop Bx ;Restore program registers
- Pop Bx
- Pop Cx
- Pop Dx
- Pop Si
- Pop Di
- Pop Bp
- Pop Ds
- Pop Es
- Mov Ax,0ffffh ;Error return code
- Stc ;Set Carry flag
- Sti ;Start interrupts again
- Ret 2 ;Return to DOS remove Flags
- Int24 Endp
-
- IFDEF POWERC
- Page
- ;
- ;********************************************************************
- ;* _Save_ES_DS_ *
- ;* *
- ;* Here we save Es & Ds values in the Code Segment so we can re- *
- ;* trieve and restore them when the interrupt occurs. If we do not *
- ;* reset these registers our C code will not work. This routine is *
- ;* called by the installation routine set_int24(). *
- ;********************************************************************
- ;
- Public _Save_ES_DS_
- _Save_ES_DS_ Proc Far
- Push Es ;Save Es on Stack
- Pop Cs:[old_es] ;Pop it into our Code Segment
- Push Ds ;Same thing with Ds
- Pop Cs:[old_ds]
- Ret
- _Save_ES_DS_ Endp
- ENDIF
- End