#include <hidef.h>      /* common defines and macros */
#include <mc9s12c32.h>     /* derivative information */
#pragma LINK_INFO DERIVATIVE "mc9s12c32"
#define SONGSIZE 10	//There are 10 notes in this song
void music_isr(void);
void music_init(void);

char getnoteflag, noteptr, note_number;
long int dur_nr_half_cycles;
long int SIXTEENTHNOTE = 300000;   // SIXTEENTHNOTE = nr of timer ticks for 0.2 sec sixteenth note
int tone_val, dur_counter;
const char duration[SONGSIZE]={2,2,3,1,  1, 1, 2, 2, 3, 4};	//This is the RHIT fight song, 
const char     tone[SONGSIZE]={6,7,8,10,11,13,15,13,11,25};	//"Dear Old Rose!"

const int tone_table[25]={6818,6435,6074,5733, 5412, 5108, 4821,	
	        		4550, 4295, 4054, 3827, 3612, 3409, 3218,
              3037, 2867, 2706, 2554, 2411, 2148, 2027,	
              2027, 1806, 1705, 1609};
					
void main(void)
{
	music_init();
	for(;;);
}

void music_init()
{ getnoteflag = 1;		// Set getnoteflag = 1, so first interrupt will fetch a note 
			                // from tone[] and duration[] arrays.
  noteptr = 0;		    // Make noteptr point to first note in tone[ ] and duration[ ].
  dur_counter = 0;		// Clear Duration Counter, which counts nr.of half cycles a note is played.
  DDRM_DDRM0 = 1;     // Make PTM0 an output (this is the output pin that will play music)
  PTM_PTM0 = 0;       // Set PTM0 low.
  TSCR2 = 3;          // Assuming 24 MHz bus clock, Tick time = 8/24E6 = 333.3333 ns
  TSCR1 = 0x80;       // Turn on timer
  TIOS = 1;           // Make TC0 an Output Compare
  TC0 = TCNT + 25;    // Schedule first TC0 interrupt in 25 timer ticks
  TFLG1 = 1;          // Clear TC0 interrupt flag
  TIE = 1;            // Locally Enable TC0 interrupts
  EnableInterrupts;   // Globally Enable TC0 interrupts
}  

// This interrupt routine is entered every time an output compare on TC0 occurs
// This should be every half of a note cycle.
void interrupt music_isr( ) 
{ TFLG1 = 1;                //Relax TC0 interrupt
	if(getnoteflag == 1)
		{
			getnoteflag = 0;				
			note_number = tone[noteptr];		//Look up the number of the next note
			if(note_number > 24) note_number = 25;	// If an invalid note number (> 24) is entered,
								                              // make it a rest = 25.
			tone_val = tone_table[note_number];  	// tone_val = nr of ticks in half cycle of note 
			dur_nr_half_cycles = duration[noteptr]*(SIXTEENTHNOTE / tone_val); 
      // SIXTEENTHNOTE sets the speed at which
      //the musical composition is played. Note 'dur_nr_cycles" 
      // is the number of cycles in the note. 
			dur_counter = 0;	// Reset duration counter
			noteptr++;				// Increment noteptr.
			if(noteptr > SONGSIZE) noteptr = 0;	// If song complete, wrap back to beginning.
		}
    else
		{	
			if (note_number < 25) PTM_PTM0 = ~PTM_PTM0;	// Toggle PTM0 output pin
			dur_counter++;				// increment duration counter
			if(dur_counter > dur_nr_half_cycles) getnoteflag = 1;
								            // Set getnoteflag = 1 if at the end of the not	
		}

	TC0 = TC0 + tone_val;     // Schedule next TC0 interrupt											
}