;############################################################################### ; # ; avrmusicbox V0.38 zweistimmige Klangerzeugung (Spieluhr) mit ATMEGA8/88 # ; (c)2006 Jörg Wolfram joerg@jcwolfram.de # ; # ; Dieses Programm ist freie Software. Sie können es unter den Bedingungen # ; der GNU General Public License, wie von der Free Software Foundation # ; veröffentlicht, weitergeben und/oder modifizieren, entweder gemäss # ; Version 2 der Lizenz oder (nach Ihrer Option) jeder späteren Version. # ; # ; Die Veröffentlichung dieses Programms erfolgt in der Hoffnung, daß es # ; Ihnen von Nutzen sein wird, aber OHNE IRGENDEINE GARANTIE, auch ohne die # ; implizite Garantie der MARKTREIFE oder der VERWENDBARKEIT FÜR EINEN # ; BESTIMMTEN ZWECK. Details finden Sie in der GNU General Public License. # ; # ; Sie sollten ein Exemplar der GNU General Public License zusammen mit # ; diesem Programm erhalten haben. Falls nicht, schreiben Sie an die Free # ; Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110, # ; USA. # ; # ; Jede Nutzung der Software/Informationen nonkonform zur GPL oder ausserhalb # ; des Geltungsbereiches der GPL ist untersagt! # ; # ;############################################################################### ;set controller type (08 or 88) .define ctype 88 ;############################################################################### ; system ram ;############################################################################### ;------------------------------------------------------------------------------- ; data for channel 1 ;------------------------------------------------------------------------------- ;sysram+0 position wave LSB ;sysram+1 position wave MSB ;sysram+2 increment wave LSB ;sysram+3 increment wave MSB ;sysram+4 wavetable LSB ;sysram+5 wavetable MSB ;sysram+6 position envelope LSB ;sysram+7 position Envelope MSB ;sysram+8 increment envelope LSB ;sysram+9 increment envelope MSB ;sysram+10 envelope table LSB ;sysram+11 envelope table MSB ;sysram+12 volume ;sysram+13 pitch shift (halftones) ;------------------------------------------------------------------------------- ; data for channel 2 ;------------------------------------------------------------------------------- ;sysram+16 position wave LSB ;sysram+17 position wave MSB ;sysram+18 increment wave LSB ;sysram+19 increment wave MSB ;sysram+20 wavetable LSB ;sysram+21 wavetable MSB ;sysram+22 position envelope LSB ;sysram+23 position Envelope MSB ;sysram+24 increment envelope LSB ;sysram+25 increment envelope MSB ;sysram+26 envelope table LSB ;sysram+27 envelope table MSB ;sysram+28 volume ;sysram+29 pitch shift (halftones) ;the sum of the volumes for both channels must not exceed 255! ;------------------------------------------------------------------------------- ; data for music sequencer ;------------------------------------------------------------------------------- ;sysram+32 store address for begin of notes ;sysram+33 store address for begin of notes ;sysram+34 actual speed ;sysram+35 selected song ;sysram+36 00/ff -> play/"preview" ;sysram+37 Merker für verses ;sysram+38 store song Volume 1 ;sysram+39 store song Volume 2 ;sysram+40 button was pressed until playing ;------------------------------------------------------------------------------- ;header: ;16 bytes text (can be used for LC-Display) ;1 byte count of verses, if bit 6 is set, the last two reduces volume ;1 byte speed (click frequency divider) ;2 bytes volume channel 1 and 2 ;music data (will be repeated for each verse): ; 0CNNNNNN note for channel C ; 1111dddd Delta-Clicks, 11110000 means end ; 1000Ceee envelope speed für channel C ; 1001C000 vvvvvvvv volume für channel C ; 1010C000 nnnnnnnn pitch shift for channel C ; 1011C000 llllllll hhhhhhhh address wavetable for channel C ; 1100Cxxx llllllll hhhhhhhh address envelopetable for channel C ; 11100000 end of "preview" ; 11101111 filling byte ;------------------------------------------------------------------------------- .include "definitions/interrupts.inc" .include "definitions/registers.inc" ;r0 and r1 are used for multiplications .def speed1 =r2 ;selected speed .def byte0 =r3 ;0x00 as constant .def byte127 =r4 ;0x7f as constant .def byte128 =r5 ;0x80 as constant .def byte254 =r6 ;0xfe as constant .def epl =r7 ;envelope-pointer low .def eph =r8 ;envelope-pointer high .def wal =r9 ;wave offset for DDS low .def wah =r10 ;wave offset for DDS high .def eal =r11 ;envelope offset low .def eah =r12 ;envelope offset high .def verse =r13 ;verse counter .def sreg =r14 ;save SREG .def sigl =r15 ;LSB of audio signal .def temp1 =r16 ;temporary register for isr .def temp2 =r17 ;temporary register for isr .def sigh =r18 ;MSB of audio signal .def temp =r19 ;temporary register .def anfno =r20 ;note request .def anfev =r21 ;envelope request .def deltac =r22 ;delta-click counter .def status =r23 ;channel- und clickstatus .def wpl =r24 ;wavepointer low .def wph =r25 ;wavepointer high .if ctype == 08 .equ ddstab = 0x100 ;dds offsets .equ eofftab = 0xf0 ;envelope offsets .equ sysram = 0x80 ;system variables .equ stack = 0x7f ;stack .endif .if ctype == 88 .equ ddstab = 0x100 ;dds offsets .equ eofftab = 0x200 ;envelope offsets .equ sysram = 0x240 ;system variables .equ stack = 0x3ff ;stack .endif .cseg ;############################################################################### ; jump to initialization ;############################################################################### .org 0x00 rjmp init ;############################################################################### ; the external interrupt 1 disables himself, its only needed for wakeup from ; power down mode ;############################################################################### .org INT1addr .if ctype == 88 out EIMSK,byte0 .endif .if ctype == 08 out GICR,byte0 .endif reti .org OVF1addr .include "routines/timerint.inc" ;############################################################################### ; initialize ;############################################################################### init: cli ;disable interrupts ldi temp,HIGH(stack) ;stack out SPH,temp ldi temp,LOW(stack) out SPL,temp ldi temp,0x00 mov byte0,temp ;0-byte used as constant ldi temp,0x7f mov byte127,temp ;0x7f-byte used as constant ldi temp,0x80 mov byte128,temp ;0x80-byte used as constant ldi temp,0xfe mov byte254,temp ;0xfe-byte used as constant ldi ZH,HIGH(wtab1*2) ;start wavetable ldi ZL,LOW(wtab1*2) sts sysram+4,ZL sts sysram+5,ZH sts sysram+20,ZL sts sysram+21,ZH ldi ZH,HIGH(etab1*2) ;start envelope-table ldi ZL,LOW(etab1*2) sts sysram+10,ZL sts sysram+11,ZH sts sysram+26,ZL sts sysram+27,ZH mov status,byte0 ;clear all requests .if ctype == 88 in temp,MCUCR andi temp,0xef ;enable pullups out MCUCR,temp calibration: ldi temp,0x40 sts OSCCAL,temp .endif .if ctype == 08 in temp,SFIOR ori temp,0x04 ;enable pullups out SFIOR,temp calibration: ldi temp,0xa8 out OSCCAL,temp .endif ;------------------------------------------------------------------------------- ; port configuration ;------------------------------------------------------------------------------- ldi temp,0xff ;outputs out DDRB,temp ;port B direction ldi temp,0x00 out PORTB,temp ;set ldi temp,0xff ;outputs out DDRC,temp ;port C direction ldi temp,0x00 out PORTC,temp ;set ldi temp,0xf7 ;outputs except PD3 out DDRD,temp ;port D direction ldi temp,0x08 out PORTD,temp ;set ;------------------------------------------------------------------------------- ; interrupt and timer configuration for mega88 ;------------------------------------------------------------------------------- .if ctype == 88 ldi temp,0x00 ;interrupts level-tr sts EICRA,temp ldi temp,0x05 ;sleep-mode pwrdown out SMCR,temp out EIMSK,byte0 ;disable external interrupts ldi temp,0x01 sts TIMSK1,temp ;enable timer 1 overflow ldi temp,0xa2 ;FAST-PWM-Mode 8 Bit (channel A + B) sts TCCR1A,temp ldi temp,0x19 ;FAST-PWM-Mode sts TCCR1B,temp ldi temp,0x00 sts ICR1H,temp ldi temp,0xff sts ICR1L,temp mov sigh,byte127 mov sigl,byte0 sts OCR1AH,byte0 ;MSB-value sts OCR1AL,sigh ;LSB-value sts OCR1BH,byte0 ;MSB-value sts OCR1BL,sigh ;LSB-value ldi temp,0xa3 ;Konfiguration Timer 0 out TCCR0A,temp ldi temp,0x01 ;Konfiguration Timer 0 out TCCR0B,temp out OCR0B,byte127 out OCR0A,byte127 sts sysram+35,byte0 ;Startvalue song sts sysram+40,byte0 .endif ;------------------------------------------------------------------------------- ; interrupt and timer configuration for mega8 ;------------------------------------------------------------------------------- .if ctype == 08 ldi temp,0xa0 ;sleepmode pwrdown / interrupts level-tr out MCUCR,temp out GICR,byte0 ;disable external interrupts ldi temp,0x04 out TIMSK,temp ;enable timer 1 overflow ldi temp,0xf2 ;FAST-PWM-Mode 8 Bit (channel A + B) out TCCR1A,temp ldi temp,0x19 ;FAST-PWM-Mode for timer 2 out TCCR1B,temp ldi temp,0x00 out ICR1H,temp ldi temp,0xff out ICR1L,temp mov sigh,byte127 mov sigl,byte0 out OCR1AH,byte0 ;MSB-value out OCR1AL,sigh ;LSB-value out OCR1BH,byte0 ;MSB-value out OCR1BL,sigh ;LSB-value ldi temp,0x79 ;Konfiguration Timer 2 out TCCR2,temp out OCR2,byte127 sts sysram+35,byte0 ;Startvalue song sts sysram+40,byte0 .endif ;------------------------------------------------------------------------------- ; copy tables to RAM ;------------------------------------------------------------------------------- cli koptab: ldi ZH,HIGH(ztab*2) ;address of dds-offsets in ROM ldi ZL,LOW(ztab*2) ldi YH,HIGH(ddstab) ;address of table in RAM ldi YL,LOW(ddstab) ldi temp1,128 ;counter koptab1: lpm temp,Z+ ;read from ROM st Y+,temp ;write to RAM dec temp1 ;next value brne koptab1 ;loop ldi ZH,HIGH(eadd*2) ;address of envelope-offsets in ROM ldi ZL,LOW(eadd*2) ldi YH,HIGH(eofftab) ;address of table in RAM ldi YL,LOW(eofftab) ldi temp1,16 ;counter koptab2: lpm temp,Z+ ;read from ROM st Y+,temp ;write to RAM dec temp1 ;next value brne koptab2 ;loop ;------------------------------------------------------------------------------- ; the player ;------------------------------------------------------------------------------- .include "routines/player.inc" .include "routines/sequencer.inc" ;############################################################################### ;the area of tables ;############################################################################### .include "tables/musictables.inc" eadd: .db 0x00,0x04,0x00,0x02,0x55,0x01,0x00,0x01 .db 0xab,0x00,0x80,0x00,0x55,0x00,0x40,0x00 ;------------------------------------------------------------------------------- ;music-data ;- Der Mond ist aufgegangen ;- Schlaf, Kindlein schlaf ;- Guten Abend, Gute Nacht ;- Die Blümelein sie schlafen ;- Weisst du wieviel Sternlein stehen ;- Wer hat die schönsten Schaefchen ;------------------------------------------------------------------------------- .include "music/definitions.inc" md1: .include "music/der_mond_ist_aufgegangen" ;Song 1 md2: .include "music/schlaf_kindlein_schlaf" ;Song 2 md3: .include "music/guten_abend_gut_nacht" ;Song 3 md4: .include "music/die_bluemelein_sie_schlafen" ;Song 4 md5: .include "music/weisst_du_wieviel_sternlein_stehen" ;Song 5 md6: .include "music/emptysong" ;Song 6