#include "c:\miniide\hcs12.inc" 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) 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) B4S equ 3218 ; 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 38 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 org $2000 lds #$2000 movb #$90,tscr1 ; enable TCNT, fast timer flag clear movb #$03,tscr2 ; set main timer prescaler to 8 bset tios,BIT5 ; enable OC5 movb #toggle,tctl1 ; select toggle for OC5 pin action movb #2,rep_cnt ; play the song twice repeat ldx #score ; use as a pointer to score table ldy #duration ; points to duration table movw 2,x+,delay ; start with zeroth note ldd tcnt ; play the first note addd delay ; " std tc5 ; " bset tie,OC5 ; enable OC5 interrupt cli ; " forever pshy ; save duration table pointer in stack movb #$AA,portb ldy 0,y ; get the duration of the current note bne continue dec rep_cnt beq done ; if not finish playing, re-establish bra repeat continue 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 ; " 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 C4,A4,G4,A4,F4,C4,C4,C5,B4S,C5,A4,A4,F4 dw D5,D5,D5,C5,A4,C5,C5,B4S,A4,B4S,C5,A4,F4 dw D5,F5,D5,C5,A4,C5,C5,B4S,A4,B4S,C5,A4,0 ; ************************************************************************** ; Each of the following entries multiplied by 10 ms gives the ; duration of a note. ; ************************************************************************** duration dw 40,80,40,40,80,40,40,80,40,40,80,40,40 dw 80,40,40,80,40,40,40,20,20,40,40,120,40 dw 80,40,40,80,40,40,40,20,20,40,40,120,0 org UserTimerCh5 ; establish the SRAM vector address for OC5 fdb oc5_isr end