;
; PWM wavetable program
; 
; definitions
;
.include "tn13def.inc"
.def temp = R16	; temporary storage
.def temp1 = R17 ; temporary storage
.def sample_count = R18 ;step through samples in wave 
.def cycle_count = R19 ;count number of waves
.equ NUM_WAVES = 255 ;num waves to send
.def delay_count = R20 ;count delay between samples
.def sample_delay = R21 ;store the delay between samples
;
; interrupt vectors
;
.cseg
.org 0
rjmp reset
;.org TIM0_OVF0addr ???
;
; waveform
; first byte = number of samples
;
wave:
   .db 99,191,195,199,203,207,211,215,218,222
   .db 225,229,232,235,238,240,243,245,247,249
   .db 250,252,253,254,254,254,254,254,254,253
   .db 252,251,250,248,246,244,242,239,236,233
   .db 230,227,224,220,216,213,209,205,201,197
   .db 193,189,185,181,177,173,169,166,162,158
   .db 155,152,149,146,143,140,138,136,134,132
   .db 131,130,129,128,128,128,128,128,128,129
   .db 130,132,133,135,137,139,142,144,147,150
   .db 153,157,160,164,167,171,175,179,183,187
;
; notes
; first byte = number of notes
; following notes are specified by the delay between samples
;   and then the number of cycles
;
;notes:
;   .db 18,5,250,5,250,5,250,5,250,5,250,5,250,10,250,10,250,10,250,20,250,20,250,20,250,15,250,30,200,40,100,35,100,35,100,25,200

outputBurst:
	ldi cycle_count, NUM_WAVES

	AnotherCycle:
	ldi zl, low(wave*2)
	ldi zh, high(wave*2)
	lpm sample_count, Z+
	SampleLoop:
		lpm temp, Z+; read sample
		out OCR0B, temp ; update PWM
		mov delay_count, sample_delay
		SampleDelayLoop:
			dec delay_count
			brne SampleDelayLoop
		dec sample_count ; decrease sample count
			brne SampleLoop
		;done with one cycle
		dec cycle_count
		brne AnotherCycle
	ret



delay:
	ldi temp1, 20
	DelayOuter:
		ldi temp, 255
		DelayInner:
			dec temp
			brne DelayInner
		dec temp1
		brne DelayOuter
	ret
	

;
; main program
;
reset:	   
	;
	; initialization
	;
	ldi temp, low(RAMEND)
	out SPL, temp ; set stack pointer to top of RAM
	ldi temp, (1<<CLKPCE)
	ldi temp1, ((0 << CLKPS3) | (0 << CLKPS2) | (0 << CLKPS1) | (0 << CLKPS0))
	out CLKPR, temp ; write CLKPCE to change clock prescaler
	out CLKPR, temp1 ; set clock to 9.6MHz/1
	
	
	;
	; init PWM
	;
	ldi temp, ((1 << COM0B0) | (1 << COM0B1) | (1 << WGM01) | (1 << WGM00))
	out TCCR0A, temp ; set OC0B on compare match and set fast PWM mode, 0xFF TOP
	ldi temp, (1 << CS00)
	out TCCR0B, temp ; set timer 0 prescalar to 1
	sbi DDRB, PB1 ; enable OC0B output pin
	
	;ldi temp, (1 << TOIE0) ; enable timer 0 overflow interrupt
	;out TIMSK0, temp

	;
	; init A/D
	;
	;cbi ADMUX, REFS1 ; use Vcc as reference (huh?)
	cbi ADMUX, REFS0 ; use Vcc as reference
	sbi ADMUX, ADLAR ; left-adjust result
	sbi ADCSRA, ADEN ; enable A/D
	cbi ADCSRA, ADATE ; disable auto-trigger
	cbi ADCSRA, ADIE ; disable A/D interrupt
	sbi ADCSRA, ADPS2 ; set prescaler 64 (110)
	sbi ADCSRA, ADPS1 ; "
	cbi ADCSRA, ADPS0 ; "
	cbi ADMUX, MUX1 ; input on ADC1 (01)
	sbi ADMUX, MUX0 ; "



	MainLoop:
		sbi ADCSRA, ADSC ; start conversion
		ADWait:
			sbic ADCSRA, ADSC ; loop until complete
		rjmp ADWait
		in sample_delay, ADCH
		lsr sample_delay
		lsr sample_delay
		lsr sample_delay
		brcc DONE_LSR ;for rounding
			inc sample_delay
		DONE_LSR:		
		rcall outputBurst
		rcall delay
		rjmp MainLoop
