From: "Ben Peddell" Newsgroups: comp.os.msdos.djgpp References: <2f64dfca DOT 0302261148 DOT 4ac4fb9d AT posting DOT google DOT com> Subject: Re: Hooking Interrupts Lines: 67 X-Priority: 3 X-MSMail-Priority: Normal X-Newsreader: Microsoft Outlook Express 5.00.2615.200 X-MimeOLE: Produced By Microsoft MimeOLE V5.00.2615.200 Message-ID: <5iD8a.59347$jM5.151252@newsfeeds.bigpond.com> Date: Mon, 3 Mar 2003 14:35:45 +1000 NNTP-Posting-Host: 144.134.89.173 X-Trace: newsfeeds.bigpond.com 1046675713 144.134.89.173 (Mon, 03 Mar 2003 18:15:13 EST) NNTP-Posting-Date: Mon, 03 Mar 2003 18:15:13 EST Organization: Telstra BigPond Internet Services (http://www.bigpond.com) To: djgpp AT delorie DOT com DJ-Gateway: from newsgroup comp.os.msdos.djgpp Reply-To: djgpp AT delorie DOT com Tony Richardson wrote in message news:2f64dfca DOT 0302261148 DOT 4ac4fb9d AT posting DOT google DOT com... > This is probably a stupid question ... > > I'm trying to get a better understanding of protected mode > and real mode interrupts. > > I've written my own interrupt routine to replace the > protected mode timer ISR. I don't want to chain into > the original ISR because I want to double the timer > rate and then call the original ISR every other time > my ISR is run. I installed the old ISR as protected > mode interrupt 0x81. How do invoke this interrupt? > Do I use int86()? The reference manual seems to imply > that this would invoke the real mode ISR. _dpmi_int() > also seems to run the real mode ISR. > __dpmi_int() uses DPMI to invoke a V86 interrupt, whilst int86() invokes a protected mode interrupt directly, which is usually reflected as a V86 interrupt, unless hooked by something else (e.g. your code). (_int86(), which is called by int86() when ivec != 0x21, has an INT n instruction in self-modifying code which alters the interrupt number to ivec.) You could use int86(), or you could make your own asm code. asm ("int $0x81"); The latter would be much faster, since you don't need to pass anything to the old ISR, since it could have been invoked anywhere (due to the nature of hardware interrupts). > I've included relevant code below. I would appreciate > constructive criticism. > > Thanks, > Tony Richardson > richardson AT evansville DOT edu > > > ================= main() code ====================== > file://load the address of the old timer ISR into the OldISR structure > _go32_dpmi_get_protected_mode_interrupt_vector(0x08, &OldISR); > _go32_dpmi_set_protected_mode_interrupt_vector(0X81, &OldISR); > > file://point NewISR to the proper selector:offset for handler function > NewISR.pm_offset = (int)TickHandler; > NewISR.pm_selector = _go32_my_cs(); > > // Double the tick rate > count = 32768; > disable(); > outportb(TICK_T0_8254_CWR, TICK_T0_8254_CTR0_MODE3); > outportb(TICK_T0_8254_CTR0, count & 0xFF); > outportb(TICK_T0_8254_CTR0, (count >> 8) & 0xFF); > _go32_dpmi_set_protected_mode_interrupt_vector(0x08, &NewISR); > enable(); > > ================= TickHandler() code ====================== > TickCtr++; > // every other tick we want to call the old ISR > if(TickCtr >= 2) { > TickCtr = 0; > int86(0x81, ®s, ®s); /* What do I use here? */ > }