;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;; (c) Fredrik Olofsson 2002-04  version 1.0 030427
;;; (ported from AT90S8535 to ATMEGA8535 040904)
;;; http://fredrikolofsson.com
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

.nolist
.include "c:\program files\atmel\avr tools\avrassembler\appnotes\m8535def.inc"
.list

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

;--	analog in					becomes			controller 20-27 ch.1
;--	digital in					becomes			note on/off 60-67 ch.1
;--	note on/off 80-91 ch.1		becomes			digital out

.equ analogIn0=20			;controllerOut value
.equ analogIn1=21
.equ analogIn2=22
.equ analogIn3=23
.equ analogIn4=24
.equ analogIn5=25
.equ analogIn6=26
.equ analogIn7=27
.equ digitalIn0=60			;noteOut (midipitch) value
.equ digitalIn1=61
.equ digitalIn2=62
.equ digitalIn3=63
.equ digitalIn4=64
.equ digitalIn5=65
.equ digitalIn6=66
.equ digitalIn7=67
.equ digitalOut0=80			;noteIn (midipitch) value
.equ digitalOut1=81
.equ digitalOut2=82
.equ digitalOut3=83
.equ digitalOut4=84
.equ digitalOut5=85
.equ digitalOut6=86
.equ digitalOut7=87
.equ digitalOut8=88
.equ digitalOut9=89
.equ digitalOut10=90
.equ digitalOut11=91

.equ velocity=100			;global vel for noteOn msg
.equ channelIn=0			;global midi input channel
.equ channelOut=0			;global midi output channel
.equ clock=8000000			;crystal speed
.equ softwareversion=17		;10=1.0 11=1.1 12=1.2 ... (in hex)
.equ sysexaddress=50		;unit address (in hex)
.equ baudrate=31250
.equ baudkonstant=(clock/(16*baudrate))-1

.def matharglo=R0
.def matharghi=R1
.def matharg2=R2
.def mathreslo=R3
.def mathreshi=R4
.def prescaling=R5
;.def tom=R6
.def currentanalogIn0=R7
.def currentanalogIn1=R8
.def currentanalogIn2=R9
.def currentanalogIn3=R10
.def currentanalogIn4=R11
.def currentanalogIn5=R12
.def currentanalogIn6=R13
.def currentanalogIn7=R14
;.def tom=R15
.def counter1=R15
.def counter2=R6

.def temp=R16
.def sysexflag=R17
.def digitalInFlag=R18
.def anallo=R19
.def analhi=R20
.def analres=R21
.def midiInstatusreg=R22
.def midiInlaststatus=R23
.def midiInbytecounter=R24
.def midiInlastbyte=R25

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
.cseg
.org $000
	rjmp reset
.org $00b
	rjmp uart_rxc
	
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
.org $011
reset:
	clr matharglo
	clr matharghi
	clr matharg2
	clr mathreslo
	clr mathreshi
	clr sysexflag
	clr digitalInFlag
	clr midiInstatusreg
	clr midiInlaststatus
	clr midiInbytecounter
	clr midiInlastbyte
	
	ldi temp,low(RAMEND)			;stack
	out SPL,temp
	ldi temp,high(RAMEND)
	out SPH,temp
	
	ldi temp,baudkonstant			;baudrate
	out UBRRL,temp
	
	sbi UCSRB,TXEN
	sbi UCSRB,RXEN
	sbi UCSRB,RXCIE
	
	ldi temp,0b00111110				;set portD output
	out DDRD,temp
	
	ldi temp,0b11111111				;set portB output
	out DDRB,temp
	
	sbi ADCSRA,ADEN					;enable adc
	cbi ADCSRA,ADFR					;single conversion mode
	ldi temp,6						;default prescaling 0-7
	mov prescaling,temp				;(which gives 2,2,4,8,16,32,64,128)
	rcall setPrescaling
	
	sei
	rjmp main
	
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
uart_rxc:
	in midiInstatusreg,SREG
	rcall midiin
	out SREG,midiInstatusreg
	reti
	
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; midiin
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
midiin:
	push temp
	in temp,UDR						;read byte
	
	cpi temp,0xF0
	breq sysexstart					;jump to sysexstart
	cpi temp,0xF7
	breq sysexstop					;jump to sysexstop
	sbrc sysexflag,0				;if flag is set
	rjmp sysexdata					;jump to sysexdata
	
	sbrs temp,7						;skip if statusbyte
	rjmp runningstatus				;jump to runningstatus
	cpi temp,0xF1
	brge returnTop					;skip other midi cmd (clock etc.) ?
	mov midiInlaststatus,temp
	ldi midiInbytecounter,1
returnTop:
	pop temp
	ret
	
;---------------
sysexstart:
	ori sysexflag,0b00000001		;set flag
	ldi midiInbytecounter,0
	rjmp returnTop
	
sysexstop:
	andi sysexflag,0b11111110		;clear flag
	ldi midiInbytecounter,0
	rjmp returnTop
	
sysexdata:
	cpi temp,0xF0					;start again if faulty sysex start
	breq sysexstart
	;cpi temp,0xF1					;stop if faulty data (>240)
	;brge sysexstop				;(doesnt work huh?!!!)
	cpi midiInbytecounter,0			;address
	breq sysexdata0
	cpi midiInbytecounter,1			;model
	breq sysexdata1
	cpi midiInbytecounter,2			;system
	breq sysexdata2
	cpi midiInbytecounter,3			;cmd
	breq sysexdata3
	cpi midiInbytecounter,4			;prescaling data
	breq sysexdata4
	rjmp returnTop
	
sysexreturnTop:
	rjmp returnTop
	
sysexdata0:
	cpi temp,sysexaddress			;address
	brne sysexreturnTop
	inc midiInbytecounter
	rjmp sysexreturn
	
sysexdata1:
	cpi temp,0x00					;model
	brne sysexreturnTop
	inc midiInbytecounter
	rjmp sysexreturn
	
sysexdata2:
	cpi temp,0x7F					;system
	brne sysexreturn
	inc midiInbytecounter
	rjmp sysexreturn
	
sysexdata3:
	cpi temp,0x00					;ping
	breq sysexdata3ping
	cpi temp,0x01					;get_version
	breq sysexdata3get_version
	cpi temp,0x02					;set_prescaler
	breq sysexdata3set_prescaler
	cpi temp,0x03					;get_prescaler
	breq sysexdata3get_prescaler
	rjmp sysexreturn
	
sysexdata4:
	mov prescaling,temp
	rcall setPrescaling
	rjmp sysexreturn
	
sysexdata3ping:
	ldi temp,0xF0
	rcall sysexsend
	ldi temp,sysexaddress
	rcall sysexsend
	ldi temp,0x00
	rcall sysexsend
	ldi temp,0x7F
	rcall sysexsend
	ldi temp,0x00
	rcall sysexsend
	rcall sysexsend
	ldi temp,0xF7
	rcall sysexsend
	rjmp sysexreturn
	
sysexdata3get_version:
	ldi temp,0xF0
	rcall sysexsend
	ldi temp,sysexaddress
	rcall sysexsend
	ldi temp,0x00
	rcall sysexsend
	ldi temp,0x7F
	rcall sysexsend
	ldi temp,0x01
	rcall sysexsend
	ldi temp,softwareversion
	rcall sysexsend
	ldi temp,0xF7
	rcall sysexsend
	rjmp sysexreturn
	
sysexdata3set_prescaler:
	inc midiInbytecounter
	rjmp sysexreturn
	
sysexdata3get_prescaler:
	ldi temp,0xF0
	rcall sysexsend
	ldi temp,sysexaddress
	rcall sysexsend
	ldi temp,0x00
	rcall sysexsend
	ldi temp,0x7F
	rcall sysexsend
	ldi temp,0x03
	rcall sysexsend
	mov temp,prescaling
	rcall sysexsend
	ldi temp,0xF7
	rcall sysexsend
	rjmp sysexreturn
	
sysexreturn:
	rjmp returnTop
	
;---------------
;-- arguments: temp	
sysexsend:
	sbis UCSRA,UDRE
	rjmp sysexsend
	out UDR,temp					;send midi byte
	ret
	
;---------------
runningstatus:
	cpi midiInlaststatus,0x80+(channelIn*16)
	brne runningstatus1
	rjmp innoteoff
runningstatus1:
	cpi midiInlaststatus,0x90+(channelIn*16)
	brne runningstatus2
	rjmp innoteon
runningstatus2:
	cpi midiInlaststatus,0xA0+(channelIn*16)
	brne runningstatus3
	rjmp intouch
runningstatus3:
	cpi midiInlaststatus,0xB0+(channelIn*16)
	brne runningstatus4
	rjmp incontroller
runningstatus4:
	cpi midiInlaststatus,0xC0+(channelIn*16)
	brne runningstatus5
	rjmp inpgmchange
runningstatus5:
	cpi midiInlaststatus,0xD0+(channelIn*16)
	brne runningstatus6
	rjmp inpressure
runningstatus6:
	cpi midiInlaststatus,0xF0+(channelIn*16)
	brne runningstatus7

	rjmp inbend
runningstatus7:
	;!!!more later?
	;songsel
	;songpos
	;start
	;stop
	;cont
	rjmp return
	
;---------------
innoteoff:
	;!!!
	rjmp return
	
;---------------
returnMid:
	pop temp
	ret
	
;---------------
innoteon:							;digital out
	cpi midiInbytecounter,1
	brne innotebyte2
	inc midiInbytecounter
	mov midiInlastbyte,temp
	rjmp return
innotebyte2:
	cpi midiInbytecounter,2
	brne returnMid
	dec midiInbytecounter
	
	cpi midiInlastbyte,digitalOut0	;check if receiving for digitalOut0
	brne innotebyte2next1
	tst temp						;check if velocity 0
	brne innoteset0
	cbi portB,0						;if velo=0 clear bit
	rjmp innotebyte2nextlast
innoteset0:
	sbi portB,0						;if velo>0 set bit
	rjmp innotebyte2nextlast
	
innotebyte2next1:
	cpi midiInlastbyte,digitalOut1	;check if receiving for digitalOut1
	brne innotebyte2next2
	tst temp						;check if velocity 0
	brne innoteset1
	cbi portB,1						;if velo=0 clear bit
	rjmp innotebyte2nextlast
innoteset1:
	sbi portB,1						;if velo>0 set bit
	rjmp innotebyte2nextlast
	
innotebyte2next2:
	cpi midiInlastbyte,digitalOut2	;check if receiving for digitalOut2
	brne innotebyte2next3
	tst temp						;check if velocity 0
	brne innoteset2
	cbi portB,2						;if velo=0 clear bit
	rjmp innotebyte2nextlast
innoteset2:
	sbi portB,2						;if velo>0 set bit
	rjmp innotebyte2nextlast
	
innotebyte2next3:
	cpi midiInlastbyte,digitalOut3	;check if receiving for digitalOut3
	brne innotebyte2next4
	tst temp						;check if velocity 0
	brne innoteset3
	cbi portB,3						;if velo=0 clear bit
	rjmp innotebyte2nextlast
innoteset3:
	sbi portB,3						;if velo>0 set bit
	rjmp innotebyte2nextlast
	
innotebyte2next4:
	cpi midiInlastbyte,digitalOut4	;check if receiving for digitalOut4
	brne innotebyte2next5
	tst temp						;check if velocity 0
	brne innoteset4
	cbi portB,4						;if velo=0 clear bit
	rjmp innotebyte2nextlast
innoteset4:
	sbi portB,4						;if velo>0 set bit
	rjmp innotebyte2nextlast
	
innotebyte2next5:
	cpi midiInlastbyte,digitalOut5	;check if receiving for digitalOut5
	brne innotebyte2next6
	tst temp						;check if velocity 0
	brne innoteset5
	cbi portB,5						;if velo=0 clear bit
	rjmp innotebyte2nextlast
innoteset5:
	sbi portB,5						;if velo>0 set bit
	rjmp innotebyte2nextlast
	
innotebyte2next6:
	cpi midiInlastbyte,digitalOut6	;check if receiving for digitalOut6
	brne innotebyte2next7
	tst temp						;check if velocity 0
	brne innoteset6
	cbi portB,6						;if velo=0 clear bit
	rjmp innotebyte2nextlast
innoteset6:
	sbi portB,6						;if velo>0 set bit
	rjmp innotebyte2nextlast
	
innotebyte2next7:
	cpi midiInlastbyte,digitalOut7	;check if receiving for digitalOut7
	brne innotebyte2next8
	tst temp						;check if velocity 0
	brne innoteset7
	cbi portB,7						;if velo=0 clear bit
	rjmp innotebyte2nextlast
innoteset7:
	sbi portB,7						;if velo>0 set bit
	rjmp innotebyte2nextlast
	
innotebyte2next8:
	cpi midiInlastbyte,digitalOut8	;check if receiving for digitalOut8
	brne innotebyte2next9
	tst temp						;check if velocity 0
	brne innoteset8
	cbi portD,2						;if velo=0 clear bit
	rjmp innotebyte2nextlast
innoteset8:
	sbi portD,2						;if velo>0 set bit
	rjmp innotebyte2nextlast

innotebyte2next9:
	cpi midiInlastbyte,digitalOut9	;check if receiving for digitalOut9
	brne innotebyte2next10
	tst temp						;check if velocity 0
	brne innoteset9
	cbi portD,3						;if velo=0 clear bit
	rjmp innotebyte2nextlast
innoteset9:
	sbi portD,3						;if velo>0 set bit
	rjmp innotebyte2nextlast

innotebyte2next10:
	cpi midiInlastbyte,digitalOut10	;check if receiving for digitalOut10
	brne innotebyte2next11
	tst temp						;check if velocity 0
	brne innoteset10
	cbi portD,4						;if velo=0 clear bit
	rjmp innotebyte2nextlast
innoteset10:
	sbi portD,4						;if velo>0 set bit
	rjmp innotebyte2nextlast

innotebyte2next11:
	cpi midiInlastbyte,digitalOut11	;check if receiving for digitalOut11
	brne innotebyte2next12
	tst temp						;check if velocity 0
	brne innoteset11
	cbi portD,5						;if velo=0 clear bit
	rjmp innotebyte2nextlast
innoteset11:
	sbi portD,5						;if velo>0 set bit
	rjmp innotebyte2nextlast

innotebyte2next12:
innotebyte2nextlast:
	rjmp return
	
;---------------
intouch:
	;!!!
	rjmp return
	
;---------------
incontroller:
	;was analogOut
	rjmp return
	
;---------------
inpgmchange:
	;!!!
	rjmp return
	
;---------------
inpressure:
	;!!!
	rjmp return
	
;---------------
inbend:
	;!!!
	rjmp return
	
;---------------
return:
	pop temp
	ret
	
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; main
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
main:
	rcall ain
	rcall din
	rcall dout
	rjmp main
	
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ain
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
ain:
	rcall setMuxChannel0			;0
	rcall adcin
	rcall playanalogIn0
	rcall setMuxChannel1			;1
	rcall adcin
	rcall playanalogIn1
	rcall setMuxChannel2			;2
	rcall adcin
	rcall playanalogIn2
	rcall setMuxChannel3			;3
	rcall adcin
	rcall playanalogIn3
	rcall setMuxChannel4			;4
	rcall adcin
	rcall playanalogIn4
	rcall setMuxChannel5			;5
	rcall adcin
	rcall playanalogIn5
	rcall setMuxChannel6			;6
	rcall adcin
	rcall playanalogIn6
	rcall setMuxChannel7			;7
	rcall adcin
	rcall playanalogIn7
	ret
	
;---------------
adcin:
	sbi ADCSRA,ADSC					;start conversion
adcinwait:
	sbis ADCSRA,ADIF
	rjmp adcinwait
	sbi ADCSRA,ADIF
	in anallo,ADCL					;read voltage
	in analhi,ADCH
	mov matharglo,anallo			;analres / 8
	mov matharghi,analhi
	ldi temp,8
	mov matharg2,temp
	rcall divide
	mov analres,mathreslo
	ret
	
;---------------
playanalogIn0:
	cp currentanalogIn0,analres		;compare with last send value
	breq playanalogInskip			;skip if equal
	mov currentanalogIn0,analres	;update last sent value
	ldi temp,analogIn0				;load controller number
	rcall sendController
	ret
playanalogIn1:
	cp currentanalogIn1,analres		;compare with last sent value
	breq playanalogInskip			;skip if equal
	mov currentanalogIn1,analres	;update last sent value
	ldi temp,analogIn1
	rcall sendController
	ret
playanalogIn2:
	cp currentanalogIn2,analres		;compare with last sent value
	breq playanalogInskip			;skip if equal
	mov currentanalogIn2,analres	;update last sent value
	ldi temp,analogIn2
	rcall sendController
	ret
playanalogIn3:
	cp currentanalogIn3,analres		;compare with last sent value
	breq playanalogInskip			;skip if equal
	mov currentanalogIn3,analres	;update last sent value
	ldi temp,analogIn3
	rcall sendController
	ret
playanalogIn4:
	cp currentanalogIn4,analres		;compare with last sent value
	breq playanalogInskip			;skip if equal
	mov currentanalogIn4,analres	;update last sent value
	ldi temp,analogIn4
	rcall sendController
	ret
playanalogIn5:
	cp currentanalogIn5,analres		;compare with last sent value
	breq playanalogInskip			;skip if equal
	mov currentanalogIn5,analres	;update last sent value
	ldi temp,analogIn5
	rcall sendController
	ret
playanalogIn6:
	cp currentanalogIn6,analres		;compare with last sent value
	breq playanalogInskip			;skip if equal
	mov currentanalogIn6,analres	;update last sent value
	ldi temp,analogIn6
	rcall sendController
	ret
playanalogIn7:
	cp currentanalogIn7,analres		;compare with last sent value
	breq playanalogInskip			;skip if equal
	mov currentanalogIn7,analres	;update last sent value
	ldi temp,analogIn7
	rcall sendController

playanalogInskip:
	ret
	
;--------------------------------
;-- arguments: temp(controller number),analres(controller value)
;-- variables: channelOut
sendController:
	push temp
	ldi temp,176+(channelOut*16)
sendController1:
	sbis UCSRA,UDRE
	rjmp sendController1
	out UDR,temp					;send status byte
	pop temp
sendController2:
	sbis UCSRA,UDRE
	rjmp sendController2
	out UDR,temp					;send controller number
sendController3:
	sbis UCSRA,UDRE
	rjmp sendController3
	out UDR,analres					;send controller value
	ret
	
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; din
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
din:
	sbis pinC,0						;if (pin == 0)
	rcall playdigitalIn0on			; button down
	sbic pinC,0						;if (pin == 1)
	rcall playdigitalIn0off			; button up
	sbis pinC,1						;if (pin == 0)
	rcall playdigitalIn1on			; button down
	sbic pinC,1						;if (pin == 1)
	rcall playdigitalIn1off			; button up
	sbis pinC,2						;if (pin == 0)
	rcall playdigitalIn2on			; button down
	sbic pinC,2						;if (pin == 1)
	rcall playdigitalIn2off			; button up
	sbis pinC,3						;if (pin == 0)
	rcall playdigitalIn3on			; button down
	sbic pinC,3						;if (pin == 1)
	rcall playdigitalIn3off			; button up
	sbis pinC,4						;if (pin == 0)
	rcall playdigitalIn4on			; button down
	sbic pinC,4						;if (pin == 1)
	rcall playdigitalIn4off			; button up
	sbis pinC,5						;if (pin == 0)
	rcall playdigitalIn5on			; button down
	sbic pinC,5						;if (pin == 1)
	rcall playdigitalIn5off			; button up
	sbis pinC,6						;if (pin == 0)
	rcall playdigitalIn6on			; button down
	sbic pinC,6						;if (pin == 1)
	rcall playdigitalIn6off			; button up
	sbis pinC,7						;if (pin == 0)
	rcall playdigitalIn7on			; button down
	sbic pinC,7						;if (pin == 1)
	rcall playdigitalIn7off			; button up
	ret
	
;---------------
playdigitalIn0on:
	sbrc digitalInFlag,0			;skip if bit x in register is 0
	ret
	ldi temp,digitalIn0
	;mov temp,analres
	rcall sendNoteOn
	ori digitalInFlag,0b00000001	;set flag
	ret
playdigitalIn0off:
	sbrs digitalInFlag,0			;skip if, bit x in register is 1
	ret
	ldi temp,digitalIn0
	rcall sendNoteOff
	andi digitalInFlag,0b11111110	;clear flag
	ret
;---------------
 playdigitalIn1on:
	sbrc digitalInFlag,1			;skip if bit x in register is 0
	ret
	ldi temp,digitalIn1
	rcall sendNoteOn
	ori digitalInFlag,0b00000010	;set flag
	ret
playdigitalIn1off:
	sbrs digitalInFlag,1			;skip if bit x in register is 1
	ret
	ldi temp,digitalIn1
	rcall sendNoteOff
	andi digitalInFlag,0b11111101	;clear flag
	ret
;---------------
playdigitalIn2on:
	sbrc digitalInFlag,2			;skip if bit x in register is 0
	ret
	ldi temp,digitalIn2
	rcall sendNoteOn
	ori digitalInFlag,0b00000100	;set flag
	ret
playdigitalIn2off:
	sbrs digitalInFlag,2			;skip if bit x in register is 1
	ret
	ldi temp,digitalIn2
	rcall sendNoteOff
	andi digitalInFlag,0b11111011	;clear flag
	ret
;---------------
playdigitalIn3on:
	sbrc digitalInFlag,3			;skip if bit x in register is 0
	ret
	ldi temp,digitalIn3
	rcall sendNoteOn
	ori digitalInFlag,0b00001000	;set flag
	ret
playdigitalIn3off:
	sbrs digitalInFlag,3			;skip if bit x in register is 1
	ret
	ldi temp,digitalIn3
	rcall sendNoteOff
	andi digitalInFlag,0b11110111	;clear flag
	ret
;---------------
playdigitalIn4on:
	sbrc digitalInFlag,4			;skip if bit x in register is 0
	ret
	ldi temp,digitalIn4
	rcall sendNoteOn
	ori digitalInFlag,0b00010000	;set flag
	ret
playdigitalIn4off:
	sbrs digitalInFlag,4			;skip if bit x in register is 1
	ret
	ldi temp,digitalIn4
	rcall sendNoteOff
	andi digitalInFlag,0b11101111	;clear flag
	ret
;---------------
playdigitalIn5on:
	sbrc digitalInFlag,5			;skip if bit x in register is 0
	ret
	ldi temp,digitalIn5
	rcall sendNoteOn
	ori digitalInFlag,0b00100000	;set flag
	ret
playdigitalIn5off:
	sbrs digitalInFlag,5			;skip if bit x in register is 1
	ret
	ldi temp,digitalIn5
	rcall sendNoteOff
	andi digitalInFlag,0b11011111	;clear flag
	ret
;---------------
playdigitalIn6on:
	sbrc digitalInFlag,6			;skip if bit x in register is 0
	ret
	ldi temp,digitalIn6
	rcall sendNoteOn
	ori digitalInFlag,0b01000000	;set flag
	ret
playdigitalIn6off:
	sbrs digitalInFlag,6			;skip if bit x in register is 1
	ret
	ldi temp,digitalIn6
	rcall sendNoteOff
	andi digitalInFlag,0b10111111	;clear flag
	ret
;---------------
playdigitalIn7on:
	sbrc digitalInFlag,7			;skip if bit x in register is 0
	ret
	ldi temp,digitalIn7
	rcall sendNoteOn
	ori digitalInFlag,0b10000000	;set flag
	ret
playdigitalIn7off:
	sbrs digitalInFlag,7			;skip if bit x in register is 1
	ret
	ldi temp,digitalIn7
	rcall sendNoteOff
	andi digitalInFlag,0b01111111	;clear flag
	ret
	
;--------------------------------
;-- arguments: temp(note)
;-- variables: velocity,channelOut
sendNoteOn:
	push temp
	ldi temp,144+(channelOut*16)
sendNoteOn1:
	sbis UCSRA,UDRE
	rjmp sendNoteOn1
	out UDR,temp					;send status byte
	pop temp
sendNoteOn2:
	sbis UCSRA,UDRE
	rjmp sendNoteOn2
	out UDR,temp					;send note
	ldi temp,velocity
sendNoteOn3:
	sbis UCSRA,UDRE
	rjmp sendNoteOn3
	out UDR,temp					;send velocity
	ret
	
;--------------------------------
;-- arguments: temp(note)
;-- variables: channelOut
sendNoteOff:
	push temp
	ldi temp,144+(channelOut*16)
sendNoteOff1:
	sbis UCSRA,UDRE
	rjmp sendNoteOff1
	out UDR,temp					;send status byte
	pop temp
sendNoteOff2:
	sbis UCSRA,UDRE
	rjmp sendNoteOff2
	out UDR,temp					;send note
	ldi temp,0
sendNoteOff3:
	sbis UCSRA,UDRE
	rjmp sendNoteOff3
	out UDR,temp					;send velocity
	ret
		
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; dout
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
dout:
	; located in midiin/innote
	ret
	
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; math
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;-- arguments: matharglo,matharghi
;-- returns  : mathreslo,mathreshi
;-- registers: mathreslo,mathreshi,matharghi,matharglo
;-- variables: 
mult:
	push temp
	clr temp
	clr mathreslo
	clr mathreshi
mult1:
	clc
	ror matharghi
	brcc mult2
	add mathreslo,matharglo
	adc mathreshi,temp
mult2:
	clc
	rol matharglo
	rol temp
	tst matharghi
	brne mult1
	pop temp
	ret
	
;---------------
;-- arguments: matharglo,matharghi,matharg2
;-- returns  : mathreslo
;-- registers: mathreslo,mathreshi,matharglo,matharghi,matharg2
;-- variables: 
divide:
	push temp
	clr temp
	clr mathreslo
	clr mathreshi
	inc mathreslo
divide1:
	clc
	rol matharglo
	rol matharghi
	rol temp
	brcs divide2
	cp temp,matharg2
	brcs divide3
divide2:
	sub temp,matharg2
	sec
	rjmp divide4
divide3:
	clc
divide4:
	rol mathreslo
	rol mathreshi
	brcc divide1
	pop temp
	ret
	
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; setPrescaling
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;-- arguments: prescaling
;-- changes  : ADCSRA bits 0-2
;-- registers: ADCSRA
;-- variables: 
setPrescaling:
	push temp
	ldi temp,0
	cp prescaling,temp
	breq setPrescaling0
	ldi temp,1
	cp prescaling,temp
	breq setPrescaling1
	ldi temp,2
	cp prescaling,temp
	breq setPrescaling2
	ldi temp,3
	cp prescaling,temp
	breq setPrescaling3
	ldi temp,4
	cp prescaling,temp
	breq setPrescaling4
	ldi temp,5
	cp prescaling,temp
	breq setPrescaling5
	ldi temp,6
	cp prescaling,temp
	breq setPrescaling6
	ldi temp,7
	cp prescaling,temp
	breq setPrescaling7
setPrescalingReturn:
	pop temp
	ret
	
setPrescaling0:
	cbi ADCSRA,0						;prescaling 000=2
	cbi ADCSRA,1						; --
	cbi ADCSRA,2						; --
	rjmp setPrescalingReturn
setPrescaling1:
	sbi ADCSRA,0						;prescaling 001=2
	cbi ADCSRA,1						; --
	cbi ADCSRA,2						; --
	rjmp setPrescalingReturn
setPrescaling2:
	cbi ADCSRA,0						;prescaling 010=4
	sbi ADCSRA,1						; --
	cbi ADCSRA,2						; --
	rjmp setPrescalingReturn
setPrescaling3:
	sbi ADCSRA,0						;prescaling 011=8
	sbi ADCSRA,1						; --
	cbi ADCSRA,2						; --
	rjmp setPrescalingReturn
setPrescaling4:
	cbi ADCSRA,0						;prescaling 100=16
	cbi ADCSRA,1						; --
	sbi ADCSRA,2						; --
	rjmp setPrescalingReturn
setPrescaling5:
	sbi ADCSRA,0						;prescaling 101=32
	cbi ADCSRA,1						; --
	sbi ADCSRA,2						; --
	rjmp setPrescalingReturn
setPrescaling6:
	cbi ADCSRA,0						;prescaling 110=64
	sbi ADCSRA,1						; --
	sbi ADCSRA,2						; --
	rjmp setPrescalingReturn
setPrescaling7:	
	sbi ADCSRA,0						;prescaling 111=128
	sbi ADCSRA,1						; --
	sbi ADCSRA,2						; --
	rjmp setPrescalingReturn
	
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; setMuxChannel
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;-- arguments: 
;-- changes  : ADMUX bits 0-2
;-- registers: ADMUX
;-- variables: 
setMuxChannel0:	
	cbi ADMUX,0						;channel 000=0
	cbi ADMUX,1						; --
	cbi ADMUX,2						; --
	ret
setMuxChannel1:
	sbi ADMUX,0						;channel 001=1
	cbi ADMUX,1						; --
	cbi ADMUX,2						; --
	ret
setMuxChannel2:
	cbi ADMUX,0						;channel 010=2
	sbi ADMUX,1						; --
	cbi ADMUX,2						; --
	ret
setMuxChannel3:
	sbi ADMUX,0						;channel 011=3
	sbi ADMUX,1						; --
	cbi ADMUX,2						; --
	ret
setMuxChannel4:
	cbi ADMUX,0						;channel 100=4
	cbi ADMUX,1						; --
	sbi ADMUX,2						; --
	ret
setMuxChannel5:
	sbi ADMUX,0						;channel 101=5
	cbi ADMUX,1						; --
	sbi ADMUX,2						; --
	ret
setMuxChannel6:
	cbi ADMUX,0						;channel 110=6
	sbi ADMUX,1						; --
	sbi ADMUX,2						; --
	ret
setMuxChannel7:
	sbi ADMUX,0						;channel 111=7
	sbi ADMUX,1						; --
	sbi ADMUX,2						; --
	ret
