Search the web
Sign In
New User? Sign Up
AVRButterFly · AVR ButterFly & Beginners Group
? Already a member? Sign in to Yahoo!

Yahoo! Groups Tips

Did you know...
Want to share photos of your group with the world? Add a group photo to Flickr.

Best of Y! Groups

   Check them out and nominate your group.
Having problems with message search? Fill out this form to ensure your group is one of the first to be migrated to the new message search system.

Messages

  Messages Help
Advanced
Messages 992 - 993 of 996   Newest  |  < Newer  |  Older >  |  Oldest
Messages: Show Message Summaries   (Group by Topic) Sort by Date v  
#993 From: "retr0dan" <RetroDan@...>
Date: Tue Nov 10, 2009 6:15 pm
Subject: COMPOSES MUSIC in ASM (266 Bytes)
retr0dan
Offline Offline
Send Email Send Email
 
[CODE]
;---------------------------------------------------------------------;
; MAESTRO.ASM for AVR BUTTERFLY                                       ;
; AUTHOR: DANIEL J. DOREY (RETRODAN)                                  ;
; CREATED: 07-NOV-09 UPDATED: 09-NOV-09                               ;
;                                                                     ;
; THE PROGRAM COMPOSES A SHORT MELODY THEN AS TIME GOES ON THE MELODY ;
; SLOWLY CHANGES; USES TWO TIMERS, ONE TO CREATE TONES & THE OTHER TO ;
; CHANGE NOTES. THE TIMERS RUN IN BACKGROUND USING INTERUPTS. IF YOU  ;
; HAVE LEDS ON PORTB YOU CAN WATCH THE NOTES. USES MY RANDOM NUMBER   ;
; GENERATOR & MY SYNTHETIC DIVISION METHOD TO MULT BY 2/3 & 3/4.      ;
; FOR IMPROVED SOUND HOOK 8 OHM SPEAKER ON BIT 5 OF PORTB TO GROUND   ;
; THROUGH A 220 OHM RESISTOR.                                         ;
;---------------------------------------------------------------------;
.INCLUDE "M169DEF.INC"    ;(BUTTERFLY MCU DEFINITIONS)

.SET MINOTE  = 10         ;SMALLEST (HIGHEST) NOTE ALLOWED
.SET MAXNOT  = 239        ;START NOTE 239=(LOW C)
.SET BARLEN  = 8          ;NOTES IN A BAR OF MUSIC
.SET BARS    = 4          ;BARS BEFORE CHANGES
.SET TEMPO   = 110        ;OVERALL SPEED

;-------------------------;
; DEFINE REGISTERS TO USE ;
;-------------------------;
.DEF A     = R16          ;GENERAL PURPOSE ACCUMULATOR
.DEF B     = R17          ;USED BY RANDOM NUMBER GENERATOR...
.DEF C     = R18          ;
.DEF D     = R19          ;
.DEF E     = R20          ;
.DEF F     = R21          ;
.DEF I     = R22          ;INDEX
.DEF M     = R23          ;BAR/NOTE INDEX
.DEF N     = R24          ;HOLDS CURRENT NOTE TO PLAY

.ORG $0000                ;START-UP & REBOOT VECTOR
    RJMP ON_RESET
.ORG $0008                ;TIMER2 MATCH OCR2A INTERUPT VECTOR
    RJMP ON_INTERUPT2                                          
.ORG $0014                ;TIMER0 MATCH OCR0A INTERUPT VECTOR
    RJMP ON_INTERUPT

;-----------------------------;
; FIRST WE SETUP A STACK AREA ;
;-----------------------------;
ON_RESET: LDI A,LOW(RAMEND)   ;SETUP STACK POINTER...
          OUT SPL,A           ;SO CALLS TO SUBROUTINES...
          LDI A,HIGH(RAMEND)  ;WORK CORRECTLY
          OUT SPH,A
          RCALL SET_MCU_SPEED ;SET MCU SPEED
          LDI A,255           ;OPEN PORTS B FOR OUTPUT
          OUT DDRB,A          ;IF YOU HAVE LEDS ON PORT B

;--------------------------------------------------;
; MAIN ROUTINE: REAL WORK IS DONE DURING INTERUPTS ;
;--------------------------------------------------;
MAIN: RCALL TIM0_MATCH_MODE   ;SETUP TIMER0 FOR SOUND
      RCALL TIM2_32K_CTC_MODE ;SETUP TIMER2 TO PICK NOTES
      RCALL RND_INIT          ;INITIALIZA RANDOM GENERATOR
      RCALL INITNOTES         ;INITIALIZE NOTES OF SONG
      LDI   M,BARS            ;INITIALIZE BARS PER PHRASE
       SEI                    ;ACTIVATE INTERUPTS

MAINL:RCALL RND_BYTE          ;RANDOMIZE THINGS
       RJMP MAINL             ;GO ROUND, ENDLESS LOOP


;--------[ I N T E R U P T   R O U T I N E S ]-----------

;-------------------------------------------;
; TIMER2 INTERUPT ROUTINE USED TO MAKE TONE ;
;-------------------------------------------;
ON_INTERUPT: PUSH A           ;SAVE FOR LATER RESTORE
             IN A,SREG        ;SAVE CPU STATUS
             PUSH A
              RCALL SPEAKER   ;SEND BIT TO SPEAKER
NOSEC:       POP A
             OUT SREG,A       ;RESTORE CPU STATUS
             POP A            ;RESTORE CONTENTS OF A
              RETI

;----------------------------------;
; FLIP THE SPEAKER BIT 5 ON PORT B ;
;----------------------------------;
SPEAKER:     SBI DDRB,5       ;SET SPKR PORT B FOR OUTPUT
             PUSH F
             LDI F,0b0010_0000
             IN  A,PORTB      ;READ PORT WITH SPEAKER
             EOR A,F          ;FLIP THE SPEAKER BIT
             OUT PORTB,A      ;WRITE OUT TO SPEAKER
             POP F
              RET

;-----------------------------------------------;
; TIMER0 INTERUPT ROUTINE GRAB A NOTE & PLAY IT ;              
;-----------------------------------------------;
ON_INTERUPT2: PUSH A           ;SAVE A FOR LATER RESTORE
              IN A,SREG        ;SAVE CPU STATUS
              PUSH A
               RCALL FETCHNOTE ;GRAB A NOTE TO PLAY
               OUT OCR0A,N     ;SAVE IT FOR TIMER2
               OUT PORTB,N     ;IF YOU HAVE LEDS ON PORTB
              POP A            ;RESTORE CPU STATUS
              OUT SREG,A
              POP A            ;RESTORE A
               RETI

;--------------------------------------------------------;
; PUT TIMER0 INTO COMPARE (CTC) MODE & SET THE PRESCALER ;
; 0=OFF 1=/1 2=/8 3=/64 4=/256 5=/1024                   ;
;--------------------------------------------------------;
TIM0_MATCH_MODE:
      LDI A,2           ;1=OVF, 2=OCF0A MATCH - SET TIMER MODE
      STS TIMSK0,A      
      LDI A,0b0011_1011 ;PRESCALE 1=/1 10=/8 11=/64 100=/256 101=/1024
      OUT TCCR0A,A      ;XXXX_1XXX=MATCH ON
       RET

;-----------------------------------------------------------------;
; SET TIMER2 TO 32.768KHz CLOCK & COMPARE(CTC) MODE               ;
; SET PRESCALER 0=OFF 1=/1 2=/8 3=/32 4=/64 5=/128 6=/256 7=/1024 ;
;-----------------------------------------------------------------;
TIM2_32K_CTC_MODE:
      LDI A,TEMPO       ;SET COMPARE VALUE (TEMPO)
      STS OCR2A,A
      LDI A,8           ;SWITCH TIMER2 CLOCK TO 32.768KHz
      STS ASSR,A   
      LDI A,2           ;1=OVF, 2=OCF0A MATCH - SET TIMER MODE
      STS TIMSK2,A      ;SET TIMER INTO OVF (OVERFLOW) MODE
      LDI A,0b0011_1100 ;SET PRESCALE & INTERUPT MODE
      STS TCCR2A,A
       RET

;---------[ S U B R O U T I N E S ]------------

;---------------------------;
; INITIALIZE NOTES IN MDATA ;
;---------------------------;
INITNOTES: RCALL INPOINT    ;SET POINTER
           LDI I,BARLEN     ;GET LENGTH OF A BAR
INLUPE:    LD N,Y           ;GRAB A NOTE
           RCALL CHNGNOTE   ;RANDOM NOTE CHANGE
           ST Y+,N          ;SAVE NEW NOTE
           DEC I            ;DONE YET?
            BRNE INLUPE
           ST Y,I           ;MARK THE END WITH A ZERO
           RCALL INPOINT    ;RESET POINTER
            RET

;-------------------------;
; FETCH A NOTE FROM MDATA ;
;-------------------------;
FETCHNOTE: LD N,Y+         ;GET NOTE & INCREMENT POINTER
           CPI N,0         ;CHECK IF WE HIT A ZERO
            BRNE FNXIT     ;IF SO THEN...
           RCALL INPOINT   ;RE-SET NOTE POINTER...
           DEC M           ;GET A NEW STRUC VALUE
            BRNE FNXIT     ;IF ZERO...
           LDI M,BARS      ;RESET BARS
           RCALL PIKNOTE   ;PICK A NOTE & CHANGE IT
FNXIT:      RET

;-----------------------------;
; RESET THE MDATA POINTER (Y) ;
;-----------------------------;
INPOINT: LDI YH,HIGH(MDATA)
         LDI YL,LOW(MDATA)
          RET

;---------------------------;
; PICK A NOTE AND CHANGE IT ;
;---------------------------;
 PIKNOTE: RCALL INPOINT   ;RESET POINTER
          RCALL RND_BYTE  ;RANDOM NUMBER 0-7
          ANDI  A,7
          ADD   YL,A      ;ADD TO POINTER AS OFFEST
          LD    N,Y       ;FETCH THAT NOTE
          RCALL CHNGNOTE  ;RANDOMIZE IT AND...
          ST    Y,N       ;SAVE IT BACK
          RCALL INPOINT   ;RESET POINTER
           RET

;-----------------------------------------------------;
; CHANGE A NOTE IN N BY EITHER MULTIPLY BY 2/3 OR 3/4 ;
; RESETS NOTE IF TOO HIGH                             ;
;-----------------------------------------------------;
CHNGNOTE: RCALL RND_BYTE    ;DO EITHER 2/3 OR 3/4
           BRPL CNSKIP
          RCALL MUL3DIV4    ;MUL N BY 2/3
           RJMP CHKIT
CNSKIP:   RCALL MUL2DIV3    ;MUL N BY 3/4
CHKIT:    CPI N,MINOTE      ;CHECK IF TOO HIGH...
          BRSH CNXIT
          LDI N,MAXNOT      ;IF SO RESET...
           RJMP CHNGNOTE    ;THEN RANDOMIZE
CNXIT:    RCALL RND_BYTE
           BRPL CHNGNOTE  
            RET

;-------------------;
; MULTIPLY N BY 2/3 ;
;-------------------;
MUL2DIV3: LDI A,170
          MUL N,A
          MOV N,R0
           RET

;-------------------;
; MULTIPLY N BY 3/4 ;
;-------------------;
MUL3DIV4: LDI A,192
          MUL N,A
          MOV N,R0
           RET

;------------------------;
; SET THE MAIN MCU SPEED ;
;------------------------;
SET_MCU_SPEED:
         LDI  A,128    ;SET THE MCU CLOCK SPEED
         STS  CLKPR,A
         LDI  A,2      ;0=8MHz 1=4MHz 2=2MHz 3=1MHz
         STS  CLKPR,A  ;BUTTERFLY RUNS AT 2MHZ OUT-OF-THE-BOX
          RET

;-------------------------------------;
; RANDOM: USING A SLIGHTLY MODIFIED   ;
;         LINEAR CONGRUENCY GENERATOR ;
;-------------------------------------;
RND_INIT: LDI A,97     ;USE PRIME NUMBERS AS SEED
          LDI B,89
          LDI C,101
          LDI D,193
RND_BYTE: MUL A,C      ;MULTIPLY PRIME
          MUL B,D
          MOVW A:B,R0:R1
          ADD A,E      ;ADD IN PRIMES
          ADC B,F
          MOVW E:F,C:D ;MIXEM UP
          MOVW C:D,A:B
           RET

;-------------[ D A T A   A R E A ]-------------
.DSEG
.ORG $100

;----------------------;
; SONG NOTES DATA AREA ;
;----------------------;

MDATA: .DB 0,0,0,0,0,0,0,0
       .DB 0,0,0,0,0,0,0,0
[/CODE]


Messages 992 - 993 of 996   Newest  |  < Newer  |  Older >  |  Oldest
Advanced
Add to My Yahoo!      XML What's This?

Copyright © 2009 Yahoo! Inc. All rights reserved.
Privacy Policy - Terms of Service - Guidelines - Help