;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; (c) Fredrik Olofsson 2005  version 1.0 050301
; f@fredrikolofsson.com  http://www.fredrikolofsson.com
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

.nolist
.include "c:\program files\atmel\avr tools\avrassembler\appnotes\2313def.inc"
.list

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

.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 digitalIn8= 68
.equ digitalIn9= 69
.equ digitalIn10= 70
.equ digitalIn11= 71

.equ velocity= 80		;for noteon msg
.equ channelOut= 0			;midi channel for sending
.equ clock= 4000000
.equ baudrate= 31250
.equ baudkonstant= (clock/(16*baudrate))-1

.def temp= R16
.def digitalInFlag1= R17
.def digitalInFlag2= R18

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
.cseg
.org 0x00

	ldi temp,low(RAMEND)	;stack
	out spl,temp
	
	ldi temp,baudkonstant
	out UBRR,temp
	ldi temp,0b00001000		;set tx output
	out UCR,temp
	
	clr digitalInFlag1
	clr digitalInFlag2

;---------------
main:
	sbis pinD,0
	rcall playdigitalIn0on
	sbic pinD,0
	rcall playdigitalIn0off
	sbis pinD,2
	rcall playdigitalIn1on
	sbic pinD,2
	rcall playdigitalIn1off
	sbis pinD,3
	rcall playdigitalIn2on
	sbic pinD,3
	rcall playdigitalIn2off
	sbis pinD,4
	rcall playdigitalIn3on
	sbic pinD,4
	rcall playdigitalIn3off
	sbis pinD,5
	rcall playdigitalIn4on
	sbic pinD,5
	rcall playdigitalIn4off
	sbis pinD,6
	rcall playdigitalIn5on
	sbic pinD,6
	rcall playdigitalIn5off
	
	sbis pinB,0
	rcall playdigitalIn6on
	sbic pinB,0
	rcall playdigitalIn6off
	sbis pinB,1
	rcall playdigitalIn7on
	sbic pinB,1
	rcall playdigitalIn7off
	sbis pinB,4
	rcall playdigitalIn8on
	sbic pinB,4
	rcall playdigitalIn8off
	sbis pinB,5
	rcall playdigitalIn9on
	sbic pinB,5
	rcall playdigitalIn9off
	sbis pinB,6
	rcall playdigitalIn10on
	sbic pinB,6
	rcall playdigitalIn10off
	sbis pinB,7
	rcall playdigitalIn11on
	sbic pinB,7
	rcall playdigitalIn11off
	rjmp main

;---------------
playdigitalIn0on:
	sbrc digitalInFlag1,0			;skip if bit x in register is 0
	ret
	ldi temp,digitalIn0
	rcall sendNoteOn
	ori digitalInFlag1,0b00000001	;set flag
	ret
playdigitalIn0off:
	sbrs digitalInFlag1,0			;skip if, bit x in register is 1
	ret
	ldi temp,digitalIn0
	rcall sendNoteOff
	andi digitalInFlag1,0b11111110	;clear flag
	ret

playdigitalIn1on:
	sbrc digitalInFlag1,1			;skip if bit x in register is 0
	ret
	ldi temp,digitalIn1
	rcall sendNoteOn
	ori digitalInFlag1,0b00000010	;set flag
	ret
playdigitalIn1off:
	sbrs digitalInFlag1,1			;skip if, bit x in register is 1
	ret
	ldi temp,digitalIn1
	rcall sendNoteOff
	andi digitalInFlag1,0b11111101	;clear flag
	ret

playdigitalIn2on:
	sbrc digitalInFlag1,2			;skip if bit x in register is 0
	ret
	ldi temp,digitalIn2
	rcall sendNoteOn
	ori digitalInFlag1,0b00000100	;set flag
	ret
playdigitalIn2off:
	sbrs digitalInFlag1,2			;skip if, bit x in register is 1
	ret
	ldi temp,digitalIn2
	rcall sendNoteOff
	andi digitalInFlag1,0b11111011	;clear flag
	ret

playdigitalIn3on:
	sbrc digitalInFlag1,3			;skip if bit x in register is 0
	ret
	ldi temp,digitalIn3
	rcall sendNoteOn
	ori digitalInFlag1,0b00001000	;set flag
	ret
playdigitalIn3off:
	sbrs digitalInFlag1,3			;skip if, bit x in register is 1
	ret
	ldi temp,digitalIn3
	rcall sendNoteOff
	andi digitalInFlag1,0b11110111	;clear flag
	ret

playdigitalIn4on:
	sbrc digitalInFlag1,4			;skip if bit x in register is 0
	ret
	ldi temp,digitalIn4
	rcall sendNoteOn
	ori digitalInFlag1,0b00010000	;set flag
	ret
playdigitalIn4off:
	sbrs digitalInFlag1,4			;skip if, bit x in register is 1
	ret
	ldi temp,digitalIn4
	rcall sendNoteOff
	andi digitalInFlag1,0b11101111	;clear flag
	ret

playdigitalIn5on:
	sbrc digitalInFlag1,5			;skip if bit x in register is 0
	ret
	ldi temp,digitalIn5
	rcall sendNoteOn
	ori digitalInFlag1,0b00100000	;set flag
	ret
playdigitalIn5off:
	sbrs digitalInFlag1,5			;skip if, bit x in register is 1
	ret
	ldi temp,digitalIn5
	rcall sendNoteOff
	andi digitalInFlag1,0b11011111	;clear flag
	ret

playdigitalIn6on:
	sbrc digitalInFlag2,0			;skip if bit x in register is 0
	ret
	ldi temp,digitalIn6
	rcall sendNoteOn
	ori digitalInFlag2,0b00000001	;set flag
	ret
playdigitalIn6off:
	sbrs digitalInFlag2,0			;skip if, bit x in register is 1
	ret
	ldi temp,digitalIn6
	rcall sendNoteOff
	andi digitalInFlag2,0b11111110	;clear flag
	ret

playdigitalIn7on:
	sbrc digitalInFlag2,1			;skip if bit x in register is 0
	ret
	ldi temp,digitalIn7
	rcall sendNoteOn
	ori digitalInFlag2,0b00000010	;set flag
	ret
playdigitalIn7off:
	sbrs digitalInFlag2,1			;skip if, bit x in register is 1
	ret
	ldi temp,digitalIn7
	rcall sendNoteOff
	andi digitalInFlag2,0b11111101	;clear flag
	ret

playdigitalIn8on:
	sbrc digitalInFlag2,2			;skip if bit x in register is 0
	ret
	ldi temp,digitalIn8
	rcall sendNoteOn
	ori digitalInFlag2,0b00000100	;set flag
	ret
playdigitalIn8off:
	sbrs digitalInFlag2,2			;skip if, bit x in register is 1
	ret
	ldi temp,digitalIn8
	rcall sendNoteOff
	andi digitalInFlag2,0b11111011	;clear flag
	ret

playdigitalIn9on:
	sbrc digitalInFlag2,3			;skip if bit x in register is 0
	ret
	ldi temp,digitalIn9
	rcall sendNoteOn
	ori digitalInFlag2,0b00001000	;set flag
	ret
playdigitalIn9off:
	sbrs digitalInFlag2,3			;skip if, bit x in register is 1
	ret
	ldi temp,digitalIn9
	rcall sendNoteOff
	andi digitalInFlag2,0b11110111	;clear flag
	ret

playdigitalIn10on:
	sbrc digitalInFlag2,4			;skip if bit x in register is 0
	ret
	ldi temp,digitalIn10
	rcall sendNoteOn
	ori digitalInFlag2,0b00010000	;set flag
	ret
playdigitalIn10off:
	sbrs digitalInFlag2,4			;skip if, bit x in register is 1
	ret
	ldi temp,digitalIn10
	rcall sendNoteOff
	andi digitalInFlag2,0b11101111	;clear flag
	ret

playdigitalIn11on:
	sbrc digitalInFlag2,5			;skip if bit x in register is 0
	ret
	ldi temp,digitalIn11
	rcall sendNoteOn
	ori digitalInFlag2,0b00100000	;set flag
	ret
playdigitalIn11off:
	sbrs digitalInFlag2,5			;skip if, bit x in register is 1
	ret
	ldi temp,digitalIn11
	rcall sendNoteOff
	andi digitalInFlag2,0b11011111	;clear flag
	ret



;--------------------------------
;-- arguments: temp(note)
;-- variables: velocity,channelOut
sendNoteOn:
	push temp
	ldi temp,144+(channelOut*16)
sendNoteOn1:
	sbis USR,UDRE
	rjmp sendNoteOn1
	out UDR,temp					;send status byte
	pop temp
sendNoteOn2:
	sbis USR,UDRE
	rjmp sendNoteOn2
	out UDR,temp					;send note
	ldi temp,velocity
sendNoteOn3:
	sbis USR,UDRE
	rjmp sendNoteOn3
	out UDR,temp					;send velocity
	ret

;--------------------------------
;-- arguments: temp(note)
;-- variables: channelOut
sendNoteOff:
	push temp
	ldi temp,144+(channelOut*16)
sendNoteOff1:
	sbis USR,UDRE
	rjmp sendNoteOff1
	out UDR,temp					;send status byte
	pop temp
sendNoteOff2:
	sbis USR,UDRE
	rjmp sendNoteOff2
	out UDR,temp					;send note
	ldi temp,0
sendNoteOff3:
	sbis USR,UDRE
	rjmp sendNoteOff3
	out UDR,temp					;send velocity
	ret
