#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) C4S equ 5411 ; delay count to generate C4S 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) 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 #1,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,$20 ;BIT5 ; 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 ; 20 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 D4,B3,G3,B3,D4,G4,B4,A4,G4,B3,C4S dw D4,D4,D4,B4,A4,G4,F4S,E4,F4S,G4,G4,D4,B3,G3 dw D4,B3,G3,B3,D4,G4,B4,A4,G4,B3,C4S dw D4,D4,D4,B4,A4,G4,F4S,E4,F4S,G4,G4,D4,B3,G3 dw B4,B4,B4,C5,D5,D5,C5,B4,A4,B4,C5,C5,C5,B4,A4,G4 dw F4S,E4,F4S,G4,B3,C4S,D4,D4,G4,G4,G4,F4S dw E4,E4,E4,A4,C5,B4,A4,G4,G4,F4S,D4,D4 dw G4,A4,B4,C5,D5,G4,A4,B4,C5,A4,G4 ,0 ; ************************************************************************** ; Each of the following entries multiplied by 10 ms gives the ; duration of a note. ; ************************************************************************** duration dw 30,10,40,40,40,80,30,10,40,40,40 dw 80,20,20,60,20,40,80,20,20,40,40,40,40,40 dw 30,10,40,40,40,80,30,10,40,40,40,80,20,20 dw 60,20,40,80,20,20,40,40,40,40,40,20,20 dw 40,40,40,80,20,20,40,40,40,80,40,60,20,40 dw 80,20,20,40,40,40,80,40,40,40,20,20 dw 40,40,40,40,20,20,20,20,40,80,20,20 dw 60,20,20,20,80,20,20,60,20,40,80 ,0 org UserTimerCh5 ; establish the SRAM vector address for OC5 fdb oc5_isr end