home *** CD-ROM | disk | FTP | other *** search
- Page ,132
- ;****************************************************************
- ;* File Id. INT29A.ASM *
- ;* Author. Stan Milam. *
- ;* Date Written. 11/05/89. *
- ;* *
- ;* (c) Copyright 1991 by Stan Milam *
- ;* *
- ;* 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 & Zortech
- ENDIF
- Extrn _psp:Word ;Segment Address of PSP
- Extrn old_int29:dword
- .Code
- Extrn Int29c:Far
- ;
- ; Declare storage in the code segment to save ES & DS
- ;
- int29_es Dw 0
- int29_ds Dw 0
- save_ss Dw ?
- save_sp Dw ?
- Page
- ;
- ;****************************************************************
- ;* Int29 *
- ;* *
- ;* This routine will be entered when interrupt 29 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 Int29
- Int29 Proc Far
- Push Bp ;Set up the stack frame
- Mov Bp,Sp
- Push Ds ;Preserve the registers
- Push Es
- Push Di
- Push Si
- Push Ax
- Push Bx
- Push Cx
- Push Dx
- IFDEF POWERC
- Push Cs:[int29_ds] ;Restore Data Segment
- Pop Ds
- ELSE
- Mov Bx,@Data ;This the way we restore DS &
- Mov Ds,Bx ;get the PSP address in Turbo C
- ENDIF
- 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
- ;
- ;The following code saves the stack registers in the code segment, and
- ;restores the stack registers to the values found in the PSP of the program
- ;which was their value when the DOS interrupt occured. This way we can use
- ;our stack without fear of blowing DOS out of the water.
- ;
- 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
- Sti ;Start the interrupts
- ;
- ;These next push is a the character to print.
- ;It is passed to the C function.
- ;
- Push Ax
- Call Int29c
- Pop Bx ;Remove parm in Bx
- Mov ss,cs:[save_ss] ;Switch stack back
- Mov sp,cs:[save_sp]
- Cmp Ax,1 ;Check for good return
- Je GoodExit ;If good return get out.
- Mov Ax,Bx ;Else....
- Mov Bx,Seg old_int29 ; Setup to call original int 29
- Mov Es,Bx
- Pushf ;Push flags to fake an interrupt
- Call Es:Dword Ptr [old_int29]
- GoodExit:
- Pop Dx ;Restore registers
- Pop Cx
- Pop Bx
- Pop Ax
- Pop Si
- Pop Di
- Pop Es
- Pop Ds
- Pop Bp
- Iret
- Int29 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_int29(). *
- ;********************************************************************
- ;
- Public Save_Int29_Regs
- Save_Int29_Regs Proc Far
- Push Es ;Save Es on Stack
- Pop Cs:[int29_es] ;Pop it into our Code Segment
- Push Ds ;Same thing with Ds
- Pop Cs:[int29_ds]
- Ret
- Save_Int29_Regs Endp
- ENDIF
- End
-