Mail Archives: djgpp/1994/10/16/14:57:06
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 <stdio.h>
#include <pc.h>
#include <sys/types.h>
#include <dpmi.h>
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<TableSize; index++)
table[index] = 127*sin(2*PI * index/TableSize)+128;
TimerHandler = NewTimer; /* assign before grabbing interrupt */
TimerInit();
SetTimerFreq(ToneFrequency*TableSize);
while(kbhit() == 0); /* wait until a key is pressed */
TimerUninstall(); /* give timer back to system */
}
void NewTimer() { /* just cycle through a sine wave over and over */
/*** DJGPPers: don't put a printf() in here - it'll crash ***/
static int index = 0;
index = ++index % TableSize;
outportb(PortNumber, table[index]);
}
If anybody finds any bugs, thanks a lot.
PLEASE DON'T SECTION:
If anybody wants to tell me to use the timer thing in /samples, please
don't - I took this from samples and modified it because it wasn't
versatile enough.
If anybody wants to tell me to use any other set of timer routines,
please don't - I know they're out there, but I don't want to use them.
And finally, if you want to criticize my coding style, please don't.
Kimbly
- Raw text -