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