Date: Thu, 3 Aug 95 13:16:01 PST
From: "Jerzy Tarasiuk" <JT@zfja-gate.fuw.edu.pl>
To: Warren Downs <downwa@wwc.edu>
Subject: Re: Real mode IDT switching
==============================================================================
> Date: Fri, 28 Jul 1995 08:53:07 -0700

> Could you send me example code how to do this?  It would be nice for _any_
> program that tries to take over interrupts-- your program would _really_
> have the interrupt!

An example must have quite a lot of code: in the new IDT almost every
vector points to code like PUSH SI, CALL INTR and at label INTR there
is POP SI, SUB SI,OFFSET INTR01; this way I get SI=offset of interrupt
vector in original IDT; next few instructions put the vector on stack
and restore SI and other registers used (must push few more to obtain
vector address on stack) and then execute far return.
INTR00:	PUSH	SI
	CALL	INTR
INTR01:	PUSH	SI
	CALL	INTR
INTR02:	PUSH	SI
...
INTR:	POP	SI
	SUB	SI,OFFSET INTR01
	...		; finding proper code left as exercise
INTRF	PROC	FAR
	RET
INTRF	ENDP

IDT	DD	INTR00
	DD	INTR01
	DD	INTR02
	...
	DD	INTRFF

After this all is prepared, you can execute the following:
	MOV	AX,SEG IDT
	ROL	AX,4
	MOV	DX,AX
	AND	AL,0F0h
	XOR	DX,AX
	ADD	AX,OFFFSET IDT
	ADC	DL,DH
	PUSH	BP
	MOV	BP,SP
	PUSH	DX
	PUSH	AX
	PUSH	0400h
	LIDT	[BP-6]
	MOV	SP,BP
	POP	BP
and if your code is correct, it shouldn't affect anything as far
as IDT and interrupt procedures are kept unchanged. You can now
set any vector in IDT to point to your code and end the code by
jump to proper INTxx label - the code will be executed before
respestive interrupt code and it will be completely transparent
to every program not using IDT. 

> Also, would this work on a '286?  Just curious.

Yes, it works. I made a program slowing down PC/AT using it.
