vr0z05@unido.UUCP (04/04/85)
Hello folks, is there anybody in net-land who is able to help me? the following program will not work, but why not? (TURBO-PASCAL V.2.0 on IBM-PC/XT) >PROGRAM TEST; >type REGPACK = record > AX,BX,CX,DX,BP,SI,DI,DS,ES,FLAGS : integer; > end; >var RECPACK : REGPACK; >procedure INTR_TEST; >begin > inline($FB/$CF) {STI/IRET} >end; >begin > RECPACK.AX := ($25 shl 8) + $50; > RECPACK.DS := cseg; > RECPACK.DX := ofs(INTR_TEST); > intr($21,RECPACK); > intr($50,RECPACK); >end. The program starts correct, changes the interrupt-vector $50 to the address of INTR_TEST, then calls via INT the procedure INTR_TEST and executes it (until now nothing wrong), but after that the program hangs (no BREAK, no RESET will work, only POWER OFF/ON). Helpfull hints to Uwe Hoch University of Dortmund Computer Science Department(IRB) P.O. Box 500500 D-4600 Dortmund 50 West-Germany via mail or uucp. Thanks in advance!
stekas@hou2g.UUCP (J.STEKAS) (04/08/85)
Here are several tips in writing interupt handling routines for MS-DOC PCs using TURBO Pascal. There have been several requests. 1) TURBO begins each procedure with from 6-8 bytes of stack pointer manipulations. This makes the location of the first line of code hard to find. The solution is to pad the beginning of the interupt routine with a bunch of NOPs and set the interupt vector in the middle. 2) The manual give INLINE statements to save and restore registers at the entry and exit of your routine. What it doesn't tell you is that you must also save DS, *set* it, and restore it upon exit. This must be done in case an interupt occurs while a system function is being executed and DS does not point to the TURBO data segment. The code looks something like this: { Globals } type AnyPtr = ^Integer ; var MyDSegPtr : AnyPtr ; { Will point to MyDseg } const MyDSeg : Integer = $1111 ; { Value will be reset } Procedure IntHand ; begin INLINE($90/$90/$90/$90/$90/$90) ; { Wide NOP Target } INLINE( Borland's entry inline ) ; INLINE( $1E/ { push ds } $2E/$A1/MyDSeg/ { mov ax, cs:MyDSeg } $8E/D8 ) ; { mov ds, ax } { Your Code here } INLINE($1F); { pop DS } INLINE( Borland's Exit ) ; end; Procedure SetUp ; var TableEnt : ^AnyPtr ; begin MyDSegPtr := Addr( MyDSeg ) ; MyDSegPtr^ := DSEG ; { We have reset the constant! } TableEnt := Ptr($00,$10) ; { ^vector table entry } TableEnt^ := Ptr(Cseg, Ofs(IntHand)+10) ; { Point into NOPs } end; Hope this helps some of you. - Jim ihnp4!hou2g!stekas