; ***************************************************************************** ; This program plays the anthem of the United States. ; Author: Dr. Han-Way Huang ; Date: 07/20/2004 ; ***************************************************************************** #include "c:\miniide\hcs12.inc" G3 equ 7653 ; delay count to generate G3 note (with 1:8 prescaler) A3 equ 6818 ; delay count to generate A3 note (with 1:8 prescaler) B3 equ 6074 ; delay count to generate B3 note (with 1:8 prescaler) C4 equ 5733 ; delay count to generate C4 note (with 1:8 prescaler) D4 equ 5108 ; delay count to generate D4 note (with 1:8 prescaler) E4 equ 4551 ; delay count to generate E4 note (with 1:8 prescaler) F4 equ 4295 ; delay count to generate F4 note (with 1:8 prescaler) F4S equ 4054 ; delay count to generate F4S note (with 1:8 prescaler) G4 equ 3827 ; delay count to generate G4 note (with 1:8 prescaler) A4 equ 3409 ; delay count to generate A4 note (with 1:8 prescaler) B4F equ 3218 ; delay count to generate B4F note (with 1:8 prescaler) B4 equ 3037 ; delay count to generate B4 note (with 1:8 prescaler) C5 equ 2867 ; delay count to generate C5 note (with 1:8 prescaler) D5 equ 2554 ; delay count to generate D5 note (with 1:8 prescaler) E5 equ 2275 ; delay count to generate E5 note (with 1:8 prescaler) F5 equ 2148 ; delay count to generate F5 note (with 1:8 prescaler) notes equ 68 toggle equ $04 ; value to toggle the TC5 pin org $1000 delay ds.w 1 ; store the delay for output compare operation rep_cnt ds.b 1 ; repeat the song this many times ip ds.b 1 ; remaining notes to be played org $2000 lds #$2000 movw #oc5_isr,UserTimerCh5 movb #$FF,DDRB movb #$90,TSCR1 ; enable TCNT, fast timer flag clear movb #$03,TSCR2 ; set main timer prescaler to 8 bset TIOS,$20 ; enable OC5 movb #toggle,TCTL1 ; select toggle for OC5 pin action ldx #score ; use as a pointer to score table ldy #duration ; points to duration table movb #1,rep_cnt ; play the song twice movb #notes,ip movw 2,x+,delay ; start with zeroth note ldd TCNT ; play the first note addd delay ; " std TC5 ; " bset TIE, $20 ; enable OC5 interrupt cli ; " forever pshy ; save duration table pointer in stack ldy 0,y ; get the duration of the current note jsr delayby10ms ; " puly ; get the duration pointer from stack iny ; move the duration pointer iny ; " ldd 2,x+ ; get the next note, move pointer std delay ; " dec ip bne forever dec rep_cnt beq done ; if not finish playing, re-establish ldx #score ; pointers and loop count ldy #duration ; " movb #notes,ip ; " movw 0,x,delay ; get the first note delay count ldd TCNT ; play the first note addd #delay ; " std TC5 bra forever done swi ; ************************************************************************** ; The OC5 interrupt service routine simply starts a new OC5 operation. ; ************************************************************************** oc5_isr ldd TC5 addd delay std TC5 rti ; *************************************************************************** ; The following subroutine creates a time delay which is equal to [Y] times ; 10 ms. The timer prescaler is 1:8. ; *************************************************************************** delayby10ms bset TIOS,$01 ; enable OC0 ldd TCNT again1 addd #60000 ; start an output compare operation std TC0 ; with 10 ms time delay wait_lp1 brclr TFLG1,$01,wait_lp1 ldd TC0 dbne y,again1 bclr TIOS,$01 ; disable OC0 rts ; ************************************************************************** ; This table determines the frequency of each note. ; ************************************************************************** score dw A4,D4,E4,A4,A4,G4,E4,D4,D5,E5,D5,B4,A4 dw G4,E4,G4,B4,A4,D5,B4,D5,A4,G4,G4,B4,B4,G4 dw E4,A4,A4,G4,E4,D4,E4,E4,E4,B4,A4 dw E4,D4,B3,A3,B3,D4,A4,A4,B4,D5,F4S,A4,F4S,E4,F4S,A4 dw D4,D4,E4,G4,G4,E4,G4,E4,D4,B3,D4,E4,G4,D4 ; ************************************************************************** ; Each of the following entries multiplied by 10 ms gives the ; duration of a note. ; ************************************************************************** duration dw 40,40,20,20,20,10,10,80,20,20,20,20,80 dw 20,20,20,20,80,20,10,10,40,20,10,10,30,10 dw 20,20,20,10,10,80,20,20,20,20,80 dw 20,20,20,10,10,80,20,20,20,20,80,20,20,20,10,10 dw 80,30,10,20,20,20,20,20,20,20,20,20,20,80 end