processor 16F685
include "P16F685.INC"

__config _INTRC_OSC_NOCLKOUT & _WDT_OFF & _BOR_OFF & _CP_OFF & _MCLRE_OFF & _IESO_OFF

;0x20-0x29 reserved for oscillator countdown timers
osc_tmr equ 0x20
;0x2A-0x2E reserved for oscillator indexes to table
osc_ind equ 0x2A
comp_loop_len equ .5
KEY equ .36

;0x30-0x36 reserved for pwm period
pwm_tmr equ 0x30
;0x37-0x39 reserved for pwm index1 (on period)
pwm_ind equ 0x37
;0x3A-0x3C reserved for pwm state (on or off)
;pwm_state equ 0x3A  information alread in PORTC

cblock 0x40
BEAT_INT
BEAT_NO
BAR_NO
BASE
CTYPE
PROG_SEL

I
MASK
TEMP
TEMP2

TMR
endc

cblock 0x70 ; access region
TMR1U
endc

org 0x00
goto main

org 0x04
incfsz TMR1U
nop
btfss TMR1U, 3 ; if TMR1U%8 == 0
goto $+3
bcf TMR1U, 3
bsf BEAT_INT,0
bcf PIR1, TMR1IF
retfie

main:
banksel OSCCON
movlw b'01110111'
;        |||		control frequency
movwf OSCCON  ; 8Mhz operation. No start-up timer
PERIOD = 1/(8000000/4) ; should be a half-microsecond

banksel CM1CON0 ; Turn comparators off
movlw b'00000111'
movwf CM1CON0

banksel CM2CON0 ; Turn comparators off
movlw b'00000111'
movwf CM2CON0

banksel ANSEL
clrf ANSEL  ; Turn off ADC

banksel ANSELH
clrf ANSELH ; more ADC

banksel CCP1CON
movlw b'00000000'
movwf CCP1CON ; Turn off ccp1

banksel T1CON
movlw b'00000001'
movwf T1CON ; turn on tmr1 ,  

banksel OPTION_REG
movlw b'10000000' ;prescale 2:1
movwf OPTION_REG

banksel PIE1
bsf PIE1, TMR1IE ; enable interrupt


banksel INTCON
bsf INTCON, PEIE

banksel TRISC
clrf TRISC ; all outputs

banksel 0
bsf INTCON, GIE


bsf BEAT_INT, 0
clrf BEAT_NO
clrf CTYPE
clrf BASE
clrf BAR_NO
clrf PROG_SEL

; init motors
movlw .2
movwf pwm_ind
movlw .0
movwf pwm_ind+1
movlw .1
movwf pwm_ind+2

main_loop:

btfsc BEAT_INT, 0
call on_beat


clrf I
movlw 0x01
movwf MASK

movfw TMR0
movwf TMR
movlw 0x02
movwf TMR0
movlw 0x02
movwf PCLATH
comp_loop:
	bcf STATUS, C
	rlf I, W
	movwf FSR
	addlw osc_tmr
	movwf FSR
	
	movfw TMR
	;addwf TMR0, W
	subwf INDF, F

	btfsc STATUS, C ; had to carry?
	goto comp_continue 	;no
	incf FSR ; goto high value ; yes
	decfsz INDF
	goto comp_continue	; no
	;swap and reload
	movfw MASK
	xorwf PORTC, F

	movfw I	
	addlw osc_ind
	movwf FSR
	movfw INDF
	call per_tableL
	movwf TEMP
	movfw INDF
	call per_tableH
	movwf TEMP2
	rlf I, W
	addlw osc_tmr
	movwf FSR
	movfw TEMP
	addwf INDF ; theres the negative result already in there
	incf FSR
	movlw 0
	btfsc STATUS, C ; if we had to carry from before
	movlw .1
	addwf TEMP2, W
	movwf INDF

	comp_continue:
	incf I
	bcf STATUS,C
	rlf MASK
	movfw I
	sublw comp_loop_len
	btfss STATUS, Z
	goto comp_loop

clrf I
;movlw 0x1
;movwf MASK ; TESTING ONLY
; mask already in correct place
pwm_loop_len equ .3
pwm_loop:
	bcf STATUS, C
	rlf I, W
	movwf FSR
	addlw pwm_tmr
	movwf FSR
	
	movfw TMR
	;addwf TMR0, W
	subwf INDF, F

	btfsc STATUS, C ; had to carry?
	goto pwm_continue 	;no
	incf FSR ; goto high value ; yes
	decfsz INDF
	goto pwm_continue	; no
	;swap and reload
	movfw MASK
	xorwf PORTC, F
	andwf PORTC, W
	movlw pwm_offL ; "off" on pulse length
	movwf TEMP
	movlw pwm_offH
	movwf TEMP2

	btfsc STATUS, Z ; is pin now off?
	goto pwm_load_off ; yes - need to use off length
					  ; no - need to load given index
	
	movfw I	
	addlw pwm_ind
	movwf FSR
	movfw INDF
	call pwm_tableL
	movwf TEMP
	movfw INDF
	call pwm_tableH
	movwf TEMP2

	pwm_load_off:
	rlf I, W
	addlw pwm_tmr
	movwf FSR
	movfw TEMP
	addwf INDF ; theres the negative result already in there
	incf FSR
	movlw 0
	btfsc STATUS, C ; if we had to carry from before
	movlw .1
	addwf TEMP2, W
	movwf INDF

	pwm_continue:
	incf I
	bcf STATUS,C
	rlf MASK
	movfw I
	sublw pwm_loop_len
	btfss STATUS, Z
	goto pwm_loop

goto main_loop

on_beat:

movlw 0x01
movwf PCLATH
clrf I

incf BEAT_NO
btfss BEAT_NO, 2 ; fourth beat
goto beat_cont
bcf BEAT_NO, 2
incf BAR_NO

; for now just go one by one through melodies
btfss BAR_NO, 4 ; every 16 bars
goto beat_cont
bcf BAR_NO, 4
; pick a number between 1 and 8!
movlw 0x07
andwf TMR1L, W
movwf PROG_SEL

beat_cont:
movfw PROG_SEL
call prog_select
movwf BASE

beat_loop:
	movfw I
	addlw osc_ind
	movwf FSR

	movfw I
	call osc_select
	addwf BASE, W
	movwf INDF
	
	incf I
	movfw I
	sublw comp_loop_len
	btfss STATUS, Z
	goto beat_loop

;manually set motors
movlw .1
btfss pwm_ind, 1 ; is two already?
movlw .2		; yes
movwf pwm_ind	; no

movlw .1
btfss pwm_ind+2, 1
movlw .2
movwf pwm_ind+2

bcf BEAT_INT, 0
return

org 0x100
osc_select:
addwf PCL
retlw KEY+0
goto chd_select
retlw KEY+7
goto melody_select
goto bass_select 

chd_select:
btfss CTYPE, 0
retlw KEY+4;major
retlw KEY+3;minor

bass_select:
btfss BEAT_NO, 0
retlw KEY
retlw KEY+.7

melody_select: ; throw a random gen in heres
;pick a number between 0 and 2
movlw 0x03
andwf TMR1L, W
btfsc STATUS, Z
addlw .3 ; the root note will be biased
xorlw 0x03
call osc_select ; get the chord
; randomly subtract 12
btfsc TMR0, 0 ; try to randomize a little :/
addlw (.256-.12)
return ; w is already loaded :D


mel_sel_cont:
retlw KEY

prog_select:
addwf PCL
goto prog_minor ; fixed
goto prog_1m3f44f ; last broken
goto prog_1145 ; last broken
goto prog_124 ; _not broken!
goto prog_50s ; maybe ...?
goto prog_blues ; works
goto prog_major_full ; works
goto prog_minor_full ; 2nd note off 

prog_minor: ; indexes on bar_no
movfw BAR_NO
andlw 0x03
movwf TEMP
rlf TEMP, W
addwf PCL
bsf CTYPE, 0
retlw .0
bcf CTYPE, 0
retlw .8
bcf CTYPE, 0
retlw .3
bcf CTYPE, 0
retlw .10

prog_1m3f44f: ; indexes on bar_no
movfw BAR_NO
andlw 0x03
movwf TEMP
rlf TEMP, W
addwf PCL
bsf CTYPE, 0
retlw 0
bcf CTYPE, 0
retlw 3
bcf CTYPE, 0
retlw 5
bcf CTYPE, 0
retlw 8

prog_1145: ; indexes on bar_no
movfw BAR_NO
andlw 0x03
movwf TEMP
rlf TEMP, W
addwf PCL
bcf CTYPE, 0
retlw 0
bcf CTYPE, 0
retlw 0
bcf CTYPE, 0
retlw 7
bcf CTYPE, 0
retlw 8 

prog_124: ; indexes on bar_no
movfw BAR_NO
andlw 0x03
movwf TEMP
rlf TEMP, W
addwf PCL
bcf CTYPE, 0
retlw 0
bcf CTYPE, 0
retlw 2
bcf CTYPE, 0
retlw 5
bcf CTYPE, 0
retlw 7

prog_50s: ; indexes on bar_no
movfw BAR_NO
andlw 0x03
movwf TEMP
rlf TEMP, W
addwf PCL
bcf CTYPE, 0
retlw 0
bcf CTYPE, 0
retlw .253 ;9-12
bcf CTYPE, 0
retlw 5
bcf CTYPE, 0
retlw .251 ;7-12

prog_blues: ; indexes on bar_no
movfw BAR_NO
andlw 0x03
movwf TEMP
rlf TEMP, W
addwf PCL
bcf CTYPE, 0
retlw 0
bcf CTYPE, 0
retlw 5
bcf CTYPE, 0
retlw 0
bcf CTYPE, 0
retlw .251;7-12

prog_major_full: ; indexes on bar_no
movfw BAR_NO
andlw 0x07 ; mod8
movwf TEMP
rlf TEMP, W
addwf PCL
bcf CTYPE, 0
retlw 0
bcf CTYPE, 0
retlw 0
bsf CTYPE, 0
retlw 4
bsf CTYPE, 0
retlw 4
bsf CTYPE, 0
retlw 2
bsf CTYPE, 0
retlw 2
bcf CTYPE, 0
retlw .251 ;7-12
bcf CTYPE, 0
retlw .251 ;7-12

prog_minor_full: ; indexes on bar_no
movfw BAR_NO
andlw 0x07 ; mod8
movwf TEMP
rlf TEMP, W
addwf PCL
bsf CTYPE, 0
retlw 0
bsf CTYPE, 0
retlw 0
bcf CTYPE, 0
retlw .10
bcf CTYPE, 0
retlw 3
bcf CTYPE, 0
retlw 8
bsf CTYPE, 0
retlw 5
bcf CTYPE, 0
retlw 7
bcf CTYPE, 0
retlw 7

org 0x200
pwm_offL equ (.17556%.256)
pwm_offH equ (.17556/.256)

pwm_tableL:
addwf PCL
retlw 	(.1447%.256); stall-750
retlw 	(.964%.256) ; BW - 500
retlw 	(.1931%.256); FW-1000

pwm_tableH:
addwf PCL
retlw (.1447/.256)	; stall
retlw (.964/.256) ; BW
retlw (.1931/.256)	; FW


per_tableL:
addwf PCL
retlw 0x83 ; 0 : 55.00 Hz
retlw 0x85 ; 1 : 58.27 Hz
retlw 0xa3 ; 2 : 61.74 Hz
retlw 0xdd ; 3 : 65.41 Hz
retlw 0x2f ; 4 : 69.30 Hz
retlw 0x9a ; 5 : 73.42 Hz
retlw 0x1c ; 6 : 77.78 Hz
retlw 0xb3 ; 7 : 82.41 Hz
retlw 0x5f ; 8 : 87.31 Hz
retlw 0x1d ; 9 : 92.50 Hz
retlw 0xee ; 10 : 98.00 Hz
retlw 0xd0 ; 11 : 103.83 Hz
retlw 0xc1 ; 12 : 110.00 Hz
retlw 0xc2 ; 13 : 116.54 Hz
retlw 0xd2 ; 14 : 123.47 Hz
retlw 0xee ; 15 : 130.81 Hz
retlw 0x18 ; 16 : 138.59 Hz
retlw 0x4d ; 17 : 146.83 Hz
retlw 0x8e ; 18 : 155.56 Hz
retlw 0xda ; 19 : 164.81 Hz
retlw 0x2f ; 20 : 174.61 Hz
retlw 0x8f ; 21 : 185.00 Hz
retlw 0xf7 ; 22 : 196.00 Hz
retlw 0x68 ; 23 : 207.65 Hz
retlw 0xe1 ; 24 : 220.00 Hz
retlw 0x61 ; 25 : 233.08 Hz
retlw 0xe9 ; 26 : 246.94 Hz
retlw 0x77 ; 27 : 261.63 Hz
retlw 0x0c ; 28 : 277.18 Hz
retlw 0xa7 ; 29 : 293.66 Hz
retlw 0x47 ; 30 : 311.13 Hz
retlw 0xed ; 31 : 329.63 Hz
retlw 0x98 ; 32 : 349.23 Hz
retlw 0x47 ; 33 : 369.99 Hz
retlw 0xfc ; 34 : 392.00 Hz
retlw 0xb4 ; 35 : 415.30 Hz
retlw 0x70 ; 36 : 440.00 Hz
retlw 0x31 ; 37 : 466.16 Hz
retlw 0xf4 ; 38 : 493.88 Hz
retlw 0xbc ; 39 : 523.25 Hz
retlw 0x86 ; 40 : 554.37 Hz
retlw 0x53 ; 41 : 587.33 Hz
retlw 0x24 ; 42 : 622.25 Hz
retlw 0xf6 ; 43 : 659.26 Hz
retlw 0xcc ; 44 : 698.46 Hz
retlw 0xa4 ; 45 : 739.99 Hz
retlw 0x7e ; 46 : 783.99 Hz
retlw 0x5a ; 47 : 830.61 Hz
retlw 0x38 ; 48 : 880.00 Hz
retlw 0x18 ; 49 : 932.33 Hz
retlw 0xfa ; 50 : 987.77 Hz
retlw 0xde ; 51 : 1046.50 Hz
retlw 0xc3 ; 52 : 1108.73 Hz
retlw 0xaa ; 53 : 1174.66 Hz
retlw 0x92 ; 54 : 1244.51 Hz
retlw 0x7b ; 55 : 1318.51 Hz
retlw 0x66 ; 56 : 1396.91 Hz
retlw 0x52 ; 57 : 1479.98 Hz
retlw 0x3f ; 58 : 1567.98 Hz
retlw 0x2d ; 59 : 1661.22 Hz
retlw 0x1c ; 60 : 1760.00 Hz
retlw 0x0c ; 61 : 1864.66 Hz
retlw 0xfd ; 62 : 1975.53 Hz
retlw 0xef ; 63 : 2093.00 Hz
retlw 0xe1 ; 64 : 2217.46 Hz
retlw 0xd5 ; 65 : 2349.32 Hz
retlw 0xc9 ; 66 : 2489.02 Hz
retlw 0xbe ; 67 : 2637.02 Hz
retlw 0xb3 ; 68 : 2793.83 Hz
retlw 0xa9 ; 69 : 2959.96 Hz
retlw 0x9f ; 70 : 3135.96 Hz
retlw 0x96 ; 71 : 3322.44 Hz


per_tableH:
addwf PCL
retlw 0x23 ; 0 : 55.00 Hz
retlw 0x21 ; 1 : 58.27 Hz
retlw 0x1f ; 2 : 61.74 Hz
retlw 0x1d ; 3 : 65.41 Hz
retlw 0x1c ; 4 : 69.30 Hz
retlw 0x1a ; 5 : 73.42 Hz
retlw 0x19 ; 6 : 77.78 Hz
retlw 0x17 ; 7 : 82.41 Hz
retlw 0x16 ; 8 : 87.31 Hz
retlw 0x15 ; 9 : 92.50 Hz
retlw 0x13 ; 10 : 98.00 Hz
retlw 0x12 ; 11 : 103.83 Hz
retlw 0x11 ; 12 : 110.00 Hz
retlw 0x10 ; 13 : 116.54 Hz
retlw 0x0f ; 14 : 123.47 Hz
retlw 0x0e ; 15 : 130.81 Hz
retlw 0x0e ; 16 : 138.59 Hz
retlw 0x0d ; 17 : 146.83 Hz
retlw 0x0c ; 18 : 155.56 Hz
retlw 0x0b ; 19 : 164.81 Hz
retlw 0x0b ; 20 : 174.61 Hz
retlw 0x0a ; 21 : 185.00 Hz
retlw 0x09 ; 22 : 196.00 Hz
retlw 0x09 ; 23 : 207.65 Hz
retlw 0x08 ; 24 : 220.00 Hz
retlw 0x08 ; 25 : 233.08 Hz
retlw 0x07 ; 26 : 246.94 Hz
retlw 0x07 ; 27 : 261.63 Hz
retlw 0x07 ; 28 : 277.18 Hz
retlw 0x06 ; 29 : 293.66 Hz
retlw 0x06 ; 30 : 311.13 Hz
retlw 0x05 ; 31 : 329.63 Hz
retlw 0x05 ; 32 : 349.23 Hz
retlw 0x05 ; 33 : 369.99 Hz
retlw 0x04 ; 34 : 392.00 Hz
retlw 0x04 ; 35 : 415.30 Hz
retlw 0x04 ; 36 : 440.00 Hz
retlw 0x04 ; 37 : 466.16 Hz
retlw 0x03 ; 38 : 493.88 Hz
retlw 0x03 ; 39 : 523.25 Hz
retlw 0x03 ; 40 : 554.37 Hz
retlw 0x03 ; 41 : 587.33 Hz
retlw 0x03 ; 42 : 622.25 Hz
retlw 0x02 ; 43 : 659.26 Hz
retlw 0x02 ; 44 : 698.46 Hz
retlw 0x02 ; 45 : 739.99 Hz
retlw 0x02 ; 46 : 783.99 Hz
retlw 0x02 ; 47 : 830.61 Hz
retlw 0x02 ; 48 : 880.00 Hz
retlw 0x02 ; 49 : 932.33 Hz
retlw 0x01 ; 50 : 987.77 Hz
retlw 0x01 ; 51 : 1046.50 Hz
retlw 0x01 ; 52 : 1108.73 Hz
retlw 0x01 ; 53 : 1174.66 Hz
retlw 0x01 ; 54 : 1244.51 Hz
retlw 0x01 ; 55 : 1318.51 Hz
retlw 0x01 ; 56 : 1396.91 Hz
retlw 0x01 ; 57 : 1479.98 Hz
retlw 0x01 ; 58 : 1567.98 Hz
retlw 0x01 ; 59 : 1661.22 Hz
retlw 0x01 ; 60 : 1760.00 Hz
retlw 0x01 ; 61 : 1864.66 Hz
retlw 0x00 ; 62 : 1975.53 Hz
retlw 0x00 ; 63 : 2093.00 Hz
retlw 0x00 ; 64 : 2217.46 Hz
retlw 0x00 ; 65 : 2349.32 Hz
retlw 0x00 ; 66 : 2489.02 Hz
retlw 0x00 ; 67 : 2637.02 Hz
retlw 0x00 ; 68 : 2793.83 Hz
retlw 0x00 ; 69 : 2959.96 Hz
retlw 0x00 ; 70 : 3135.96 Hz
retlw 0x00 ; 71 : 3322.44 Hz

end