// Emacs style mode select -*- C++ -*- //----------------------------------------------------------------------- // // Copyright(C) 2001-2003 Simon Howard // // This program is free software; you can redistribute it and/or modify it // under the terms of the GNU General Public License as published by the // Free Software Foundation; either version 2 of the License, or (at your // option) any later version. This program is distributed in the hope that // it will be useful, but WITHOUT ANY WARRANTY; without even the implied // warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See // the GNU General Public License for more details. You should have // received a copy of the GNU General Public License along with this // program; if not, write to the Free Software Foundation, Inc., 59 Temple // Place - Suite 330, Boston, MA 02111-1307, USA. // //----------------------------------------------------------------------- // // PC Speaker Code // //----------------------------------------------------------------------- // sopwith note: this is a small library i wrote a while back to // drive the pc speaker code. it is api compatible with the pc // speaker "emulation" code i wrote for sopwith, so will probably // be of use #include #include //#define DEBUG #define CLOCK_FREQ 1193280 #define PPI_PORT 97 #define TIMER_PORT_1 66 #define TIMER_PORT_2 67 static int speaker_on = 0; // // Turn the speaker off // void Speaker_Off() { // if already off, dont turn off if(!speaker_on) return; #ifdef DEBUG puts("turn speaker off"); #endif // turn off speaker outportb(PPI_PORT, inportb(PPI_PORT) & ~3); speaker_on = 0; } // // Turn the speaker on // // (this is kinda internal) // void Speaker_On() { if(speaker_on) return; #ifdef DEBUG puts("turn speaker on"); #endif // turn on speaker outportb(PPI_PORT, inportb(PPI_PORT) | 3); speaker_on = 1; } static unsigned int speaker_initted = 0; // // Shutdown the speaker // void Speaker_Shutdown() { if(!speaker_initted) return; #ifdef DEBUG puts("shutdown"); #endif // turn the speaker off before we finish Speaker_Off(); speaker_initted = 0; } // // Initialise the speaker // void Speaker_Init() { if(speaker_initted) return; speaker_on = 0; speaker_initted = 1; { static int firsttime = 1; if(firsttime) { atexit(Speaker_Shutdown); firsttime = 0; } } } // // Play a particular tone to the speaker // // count: This determines the frequency. count is // the number of clock ticks between speaker // pulses. Hence clock_freq/count == tone // frequency // void Speaker_Output(unsigned short count) { // init if we havent already Speaker_Init(); Speaker_On(); // get timer ready // 182 is the code to indicate a new count value outportb(TIMER_PORT_2, 182); // send value to other port outportb(TIMER_PORT_1, count & 255); outportb(TIMER_PORT_1, (count >> 8) & 255); } // // Play a sound // // This should be identical to the BASIC SOUND function // duration = 1/18th's of a second // void Speaker_Sound(int freq, int duration) { clock_t duration_clocks = duration * CLOCKS_PER_SEC / 18.2; clock_t endtime; // turn speaker on int count = CLOCK_FREQ / freq; Speaker_Output(count); // delay for(endtime = clock() + duration_clocks; clock() < endtime; ); // turn speaker off Speaker_Off(); } //----------------------------------------------------------------------- // // $Log: pcsound.c,v $ // Revision 1.1.1.1 2003/02/14 19:03:34 fraggle // Initial Sourceforge CVS import // // // sdh 14/2/2003: change license header to GPL // //-----------------------------------------------------------------------