Category : Files from Magazines
Archive   : VOL10N08.ZIP
Filename : BALLGAME.C

 
Output of file : BALLGAME.C contained in archive : VOL10N08.ZIP
[[Code Box]]
[[BALLGAME.C, COMPLETE LISTING, INCLUDE MAGNET LOGO]]



#include
#include

/* The following are the frequencies for each note. An S following the note
means that the note is a sharp (#). */
#define S 0.0 /* Silence */
#define C1 261.63
#define CS1 277.18
#define D1 293.66
#define DS1 311.13
#define E1 329.63
#define F1 349.23
#define FS1 369.99
#define G1 392.0
#define GS1 415.3
#define A1 440.0
#define AS1 466.16
#define B1 493.88
#define C2 523.25
#define CS2 554.37
#define D2 587.33
#define DS2 622.25
#define E2 659.26
#define F2 698.46
#define FS2 739.99
#define G2 783.99
#define GS2 830.61
#define A2 880.0
#define AS2 932.33
#define B2 987.77

/* The following are the durations of the notes. To make the song go faster,
make the definition of E smaller. To make the song go slower, make the
definition of E larger. A P in the second position of the name means that
this note is half again as large as the one preceding it. */
#define E 0.125 // Eighth note
#define EP (E*1.5) // dotted 8th
#define Q (E*2.0) // quarter note
#define QP (E*3.0) // dotted quarter
#define H (Q*2.0) // half note
#define HP (Q*3.0) // dotted half
#define W (H*2.0) // whole note
#define WP (H*3.0) // dotted whole

/* The following define the duration of each note (or conversely, the amount
of silence between notes. */
#define LEGATO 1.0
#define NORMAL 0.875
#define STACCATO 0.75

/* Changing this definition changes the duration of the notes for the entire
song. */
#define NOTE_DUR NORMAL

/* How much must we speed up the timer. The value works fine for the tempo
I've defined here. If you play a faster song, you might consider
increasing this value. */
#define CLOCK_INC 4

#define NUM_NOTES 61
static double notes[NUM_NOTES] =
{
C1, C2, A1, G1, E1, G1, D1,
C1, C2, A1, G1, E1, G1, GS1,
A1, GS1, A1, E1, F1, G1, A1, F1, D1,
A1, A1, A1, B1, C2, D2, B1, A1, G1, F1, D1,
C1, C2, A1, G1, E1, G1, D1,
C1, D1, E1, F1, G1, A1, A1, B1,
C2, C2, C2, B1, A1, G1, FS1, G1, A1, B1, C2
};
static double sizes[NUM_NOTES] =
{
H, Q, Q, Q, Q, HP, HP,
H, Q, Q, Q, Q, W, Q,
Q, Q, Q, Q, Q, Q, H, Q, HP,
H, Q, Q, Q, Q, Q, Q, Q, Q, Q, Q,
H, Q, Q, Q, Q, HP, HP,
H, Q, Q, Q, Q, W, Q, Q,
HP, HP, Q, Q, Q, Q, Q, Q, HP, HP, W
};

volatile long click = 0;
void (interrupt far *orig_int)(void); /* function pointer to the original interrupt
*/

void init_clock(void);
void reset_clock(void);
void sleep(double how_long);
void sound(double freq, double duration);

void main(void)
{
int i;

init_clock();
for(i = 0; i < NUM_NOTES; i++)
sound(notes[i], sizes[i]);
reset_clock();
}

void interrupt far new_int(void)
{
if((++click % CLOCK_INC) == 0)
(*orig_int)();
outp(0x20, 0x20);
}

void init_clock(void)
{
/*
Increase the 8253 timer's channel 0 output by a factor of CLOCK_INC.
*/

union

{
long divisor;
unsigned char c[2];
} count;

/* Install the new interrupt routine. */

orig_int = _dos_getvect(0x08);
_dos_setvect(0x08, new_int);

/* Increase the timer speed. */
count.divisor = (long)65536 / CLOCK_INC;
outp(0x43, 0x36); /* tell 8253 that count is coming */
outp(0x40, count.c[0]); /* send low-order byte */
outp(0x40, count.c[1]); /* send high-order byte */
}

void reset_clock(void)
{
/*
Return clock to it's original speed.
*/

/* Reinstall the old interrupt routine. */
_dos_setvect(0x08, orig_int);

/* Slow down the clock. */
outp(0x43, 0x36); /* tell 8253 that count is coming */
outp(0x40, (char)0); /* send low-order byte */
outp(0x40, (char)0); /* send high-order byte */
}

void sleep(double how_long)
{
long i,
orig,
new;

orig = click;
i = (long)((how_long * (18.2 * CLOCK_INC)) + orig);
new = click;
while(new < i)
new = click;
}

void sound(double freq, double duration)
{
/*
Beep the speaker using the specified frequency.
*/

double off,
play;
union
{
long divisor;
unsigned char c[2];
} count;
int p;

play = duration * NOTE_DUR;
off = duration - play;

if(freq != S)
count.divisor = (long)(1193180 / freq); /* compute the proper count */
else
count.divisor = 0;
outp(0x43, 0xb6); /* tell 8253 that count is coming */
outp(0x42, count.c[0]); /* send low-order byte */
outp(0x42, count.c[1]); /* send high-order byte */
p = inp(0x61); /* get existing bit pattern */
if(freq != S)
outp(0x61, p | 3); /* turn on bits 0 and 1 */
else
outp(0x61, p);

sleep(play);

outp(0x61, p); /* restore original bits to turn off speaker */

sleep(off);
}









Figure D: Executing this program will play "Take Me Out to the Ball Game". To play music on a PC the 8253 timer chip must be reprogrammed; BALLGAME causes it to run four times faster than normal. However, it is written so as not to affect the time-of-day clock. 

  3 Responses to “Category : Files from Magazines
Archive   : VOL10N08.ZIP
Filename : BALLGAME.C

  1. Very nice! Thank you for this wonderful archive. I wonder why I found it only now. Long live the BBS file archives!

  2. This is so awesome! 😀 I’d be cool if you could download an entire archive of this at once, though.

  3. But one thing that puzzles me is the “mtswslnkmcjklsdlsbdmMICROSOFT” string. There is an article about it here. It is definitely worth a read: http://www.os2museum.com/wp/mtswslnk/