Mail Archives: djgpp/2003/03/03/02:30:17
Tony Richardson <richardson AT evansville DOT edu> 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? */
> }
- Raw text -