#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include <windows.h>

typedef unsigned char u8;
typedef unsigned int u16;

#define OUTP(p, v) _outp((u16) (p), v)
#define INP(p) _inp(p)
#define SLEEP(ms) Sleep(ms)

#define MAX_NOTES 666
#define TIME 150

struct note 
{
	int freq;
	char name[2];
};

/*
 * These are the frequencies for each note.
 */
struct note notes[] = {
	440, "A4",
	587, "D5",
	294, "D4",
	523, "C5",
	262, "C4",
	659, "E5",
	698, "F5",
	349, "F4",
	784, "G5",
	392, "G4",
	440, "B4",
};

void startnote(unsigned freq)
{
	unsigned short cnt = 1193280 / freq; 
    OUTP(0x43, 0xB6);				/* prepare timer */
    OUTP(0x42, (u8)cnt);			
    OUTP(0x42, (u8) (((u16) (cnt) >> 8) & 0xFF));		
    OUTP(0x61, INP(0x61) | 0x03);		/* turn speaker on */
}

void stopnote()
{
	OUTP(0x61, INP(0x61) & 0xFC); /* turn speaker off */
}

void playnote(unsigned freq, unsigned time) 
{
	startnote(freq);
	SLEEP(time);
	stopnote();
}

void play(char n[2], unsigned time)
{
	int c;
	for (c = 0; c < sizeof(notes)/sizeof(struct note); c++) {
		if (!strncasecmp(n, notes[c].name, 2)) {
			/* i know this is stupid! */
			if (isupper(n[0])) {
				time *= 2;
			}
			//printf("%s", notes[c].name);
			playnote(notes[c].freq, time);
		}
	}
}

void playfile(char *file)
{
	char my_notes[MAX_NOTES][2];
	FILE *fp = fopen(file, "r");
	int c, count = 0;

	if (!fp) {
		puts("Could not open file, terminating...\n");
		return;
	}
	while (!feof(fp)) {
		fread(my_notes[count], 2, 1, fp);
		count++;
	}

	for (c = 0; c < count; c++) {
		play(my_notes[c], TIME);
	}
}
	
int main(int argc, char **argv) 
{
	playfile("fotd.snd");
}
