delorie.com/archives/browse.cgi   search  
Mail Archives: djgpp/1994/04/21/06:24:19

From: kordmann AT ldv01 DOT Uni-Trier DOT DE (Gerhard Kordmann)
Subject: Q : timer reprogramming
To: djgpp AT sun DOT soe DOT clarkson DOT edu
Date: Thu, 21 Apr 1994 11:32:45 +0200 (MSZ)

	Hello everybody,

	I'm trying to find a way to use the soundblaster under djgpp
	without crashing the system (don't we all...)
	As interrupt programming turned out to be buggy, I tried the
	brute force method : Reset the clock speed, wait until it
	changes (the clock, that is) in a loop and then send the
	next byte. This is ugly, probably not very precise and it
	works perfectly. Under Turbo-C 2.0.
	Unfortunately it gives only unpredictable delays, sometimes
	a kind of slow motion playing or crashes as soon as I compile
	with djgcc :-(
	As the code is rather short, I will post it. Only a few
	includes changed compared to the working TC version.
	Does anyone see why this, again, does not work ? Will we ever
	be able to safely play sounds under djgcc ? Will I be
	saved from nervous breakdown ?

		Bye, Koma

	P.S. Ooops, text was written in a 4-space-tab editor, if it looks
	strange on you screen try to change this...


#include <time.h>
#include <dos.h>
#include <std.h>
#include <pc.h>

#define lowbyte(address)	((address) & 255)
#define highbyte(address)	(((address)>>8) & 255)

extern int BASE;			/* The soundcard address, usually 0x220	*/

void write_dsp(unsigned char value,int base);

void SoundPlay(unsigned long rate, char *Data, unsigned long length)
{
	struct time Start_time;
	unsigned long Start_clock;
	unsigned long Ticks_during_action;
	int hund_seconds;
	int timer_value;
	int i;
	unsigned long oldclock, newclock;

	gettime(&Start_time);			/* Save time to reset clock at end	*/
	Start_clock = clock();

	timer_value = 1193180 / rate;	/* timer signals per second / rate	*/
	outportb(0x40, lowbyte(timer_value));	
	outportb(0x40, highbyte(timer_value));	/* set new clock rate		*/

	sb_voice(1);
	for(i=0; i<length;) {
		if((newclock = clock()) != oldclock) {
			oldclock = newclock;
			write_dsp(0x10,BASE);			/* prepare dsp port			*/
			write_dsp(Data[i],BASE);		/* send value				*/
			outportb(0x20,0x20);			/* acknowledge action		*/
			i++;
		}
	}
	sb_voice(0);

	timer_value = 0x0FFFF;               	/* reset timer				*/
	outportb(0x40, lowbyte(timer_value));
	outportb(0x40, highbyte(timer_value)); 

	/* now calculate how much time passed and reset clock, this is		*/
	/*	necessary as the bending of the timer also bends the clock		*/
	Ticks_during_action = clock() - Start_clock;
	hund_seconds = (double)Ticks_during_action / ((double)rate/100) + .5;

	Start_time.ti_hund += hund_seconds;
	if(Start_time.ti_hund > 99) {
		Start_time.ti_sec += Start_time.ti_hund / 100;
		Start_time.ti_hund %= 100;
		if(Start_time.ti_sec > 59) {
			Start_time.ti_min += Start_time.ti_sec / 60;
			Start_time.ti_sec %= 60;
			if(Start_time.ti_min > 59) {
				Start_time.ti_hour += Start_time.ti_min / 60;
				Start_time.ti_min %= 60;
				if(Start_time.ti_hour > 23) {
					Start_time.ti_hour -= 24;
				}
			}
		}								  
	}
	settime(&Start_time);
}



void write_dsp(unsigned char value,int base)
{
	int i;

	for(i=0;i<10000;i++) {				/* poll write status up to 10000	*/
		if(!(inportb(base+0x0C) & 0x80))/*  times until 'not ready' signal	*/
			break;						/*  0x80 disappears					*/
	}
	outportb(base+0x0C,value);			/* now write actual port value		*/
}



- Raw text -


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