www.delorie.com/archives/browse.cgi   search  
Mail Archives: djgpp/1994/10/16/14:57:06

Date: Sun, 16 Oct 1994 13:24:44 -0400 (EDT)
From: Kimberley Burchett <OKRA AT max DOT tiac DOT net>
Subject: timer int problems
To: DJGPP Mailing List <djgpp AT sun DOT soe DOT clarkson DOT edu>

  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 -


  webmaster     delorie software   privacy  
  Copyright © 2019   by DJ Delorie     Updated Jul 2019