9 #define x r24 //==a1==Mh
18 #define Ml t //mod3 vars
20 #define a1 x //mul_ vars
47 .org 0x0000 ; RESET interrupt
50 .org 0x0004 ; PCINT0 interrupt
51 CBI PCICR, 0 ; disable interrupt
53 .org 0x0008 ; TIM0_OVF interrupt
57 .byte 0x84, 0x9d, 0xb0, 0x69, 0x9d, 0x84, 0x69, 0x58
58 .byte 0x75, 0x8c, 0xb0, 0x69, 0x8c, 0x75, 0x69, 0x58
60 mod3: ; mod3(Mh.Ml) -> t
64 ADC Mh, Mh ; store carry in Mh
103 ADD Xlo, t ; NOTE: notes are positioned so that hi8(notes) never changes
108 ; begin of mulitiplication:
117 ; BRCC skip2 -- this bit is always zero
145 BRCC skip6 ;sbrc t, NNN
160 MOV t, a1 ;;TODO: use a1 in loop: directly
163 main: ; setup routine
164 ; NOTE: clr i0 moved to .ord 0x0
167 CLR acc ; we output a dummy sample before the actual first one
168 LDI Xhi, hi8(FLASHM + notes) ; never changes
169 LDI one, 1 ; mostly for clearing TIM0_OVF bit
173 OUT SPL, x ; init stack ptr
175 OUT PUEB, zero ; disable pullups
177 OUT DDRB, x ; PORTB0:pwm, PORTB2:debug
179 OUT CCP, x ; change protected ioregs
180 OUT CLKPSR, one ; clock prescaler 1/2 (4Mhz)
181 LDI x, 0xa7 ; determined by trial-and-error (->PORTB2)
182 OUT OSCCAL, x ; set oscillator calibration
183 OUT WDTCSR, zero; turn off watchdog
185 ;set timer/counter0 to 8bit fastpwm, non-inverting, no prescaler
190 OUT TIMSK0, one ; enable tim0_ovf
195 CPI i2, 0x78>>5 ; 16m23 -- one loop
203 CLR i2 ; clear halt condition
206 ; disable timer0, set all pins as input+pullup to conserve battery.
207 LDI x, 0x08 ; disable timer clock
209 ;OUT PRR, one ; ยง8.3: only helps in idle and active modes
212 sbi PORTB, 0 ; force pin high, so pcint triggers on connect to ground --- XXX TODO: this does not work reliably for PORTB0
213 sbi PORTB, 2 ; force pin high, so pcint triggers on connect to ground (works reliably for portb2)
222 SBI PCMSK, 2 ; listen for pin change on the audio out pin (i.e. wake up when a audio sink is connected)
224 OUT PCICR, one ; enable PCINT0
226 ;enter power-down-mode
227 LDI x, 0x05 ; sleep mode: power-down, enabled
230 OUT SMCR, one ; sleep mode: idle, enabled
235 SBI PCIFR, 0 ; clear interrupt
236 OUT PUEB, zero ; remove pullups
237 LDI x, 0x05 ; restore output pins
239 ;OUT PRR, zero ; reenable periphials
241 OUT TCCR0B, x ; reenable timer0
246 OUT OCR0AL, acc ; start by outputting a sample, because routine has variable runtime
248 SBI PORTB, 2 ; to measure runtime
373 SWAP acc ; acc<<4, to be passed to OCR0AL
380 CBI PORTB, 2 ; end runtime measurement
382 OUT TIFR0, one ; clear pending interrupt (routine takes two intr.cycles)
383 RETI ; reenables interrupts