Date: Sun, 16 Oct 1994 13:24:44 -0400 (EDT) From: Kimberley Burchett Subject: timer int problems To: DJGPP Mailing List I want to play around with the timer interrupt. I'm going to change the frequency, so I don't want to chain it to the old one. However in order to keep things working correctly, I do want to call the old handler when appropriate. But all I have is a _go32_dpmi_seginfo block I've named OldTimerSegInfo. If I try to call OldTimerSegInfo.pm_offset(), it crashes. The code I have will work (kindof) if I chain the interrupt, but not if I just set it. What I mean by work is I do get a tone out of the printer port, but the computer won't respond to anything. (the test program is supposed to put a sine-wave out of the printer port, through a DAC, into my stereo. I've gotten it working in Pascal). I'm not sure if you need to see the code, but just in case, here it is. If you want to keep it, go ahead. If you're going to write back to me, please read the "please don't" section at the end of this letter. Here's my timer unit (timer.c): /* a few routines to handle the system timer interrupt */ #ifndef _TIMER_C_ #define _TIMER_C_ #include "timer.h" /************ This is timer.h: #ifndef _TIMER_H_ #define _TIMER_H_ #include #include #include #include void (*TimerHandler)(); void TimerInit(void); void TimerUninstall(void); void SetTimerFreq(int frequency); #include "timer.c" #endif ************/ static void TimerInternalHandler(void); /*takes care of calling old handler*/ static _go32_dpmi_seginfo OldTimerSegInfo,NewTimerSegInfo; static long clock_ticks, counter; void TimerInit(void) { printf("grabbing timer interrupt\n"); _go32_dpmi_get_protected_mode_interrupt_vector(8, &OldTimerSegInfo); NewTimerSegInfo.pm_offset = (int)TimerInternalHandler; NewTimerSegInfo.pm_selector = _go32_my_cs(); _go32_dpmi_set_protected_mode_interrupt_vector(8, &NewTimerSegInfo); } void TimerUninstall(void) { /* Restore the normal clock frequency */ outportb(0x43, 0x34); outportb(0x40, 0); outportb(0x40, 0); printf("releasing timer interrupt\n"); _go32_dpmi_set_protected_mode_interrupt_vector(8, &OldTimerSegInfo); } void SetTimerFreq(int frequency) { /* Do some initialization */ clock_ticks = 0; counter = 0x1234DD / frequency; /* Set the PIT channel 0 frequency */ outportb(0x43, 0x34); outportb(0x40, counter % 256); outportb(0x40, counter / 256); } static void TimerInternalHandler() { TimerHandler(); /* call user's handler */ /* Adjust the count of clock ticks */ clock_ticks += counter; /* Is it time for the BIOS handler to do it's thing? */ if (clock_ticks >= 0x10000) { clock_ticks -= 0x10000; asm("pushf"); /* old handler will iret, so push flags */ OldTimerSegInfo.pm_offset(); } else /* if not, just acknowledge the interrupt */ outportb(0x20, 0x20); } #endif Here's a test program called sound.c: /* this program should grab control of the timer interrupt and use it to output a sine wave to the printer port where I have a DAC plugged into some speakers. So if it works, I'll get a 220Hz tone. */ #include "timer.h" #include "trig.h" #define PIT_FREQ 0x1234DD #define PortNumber 0x3bc /* printer port */ #define ToneFrequency 220 /* a low A */ #define TableSize 63 /* 63 steps in the sine wave table */ void NewTimer(); int table[TableSize]; /* table to hold precalculated sine wave */ int main() { int index; for (index=0; index