+; rgb_mali.asm
+;
+; 3 leds (red, green, blue) on different ports.
+; cm mode: continuous mixed colors
+; rgb mode: keep one special color
+;
+; modes switchable by uart
+;
+; author: hackbard@hackdaworld.dyndns.org
+
+
+.include "../include/2313def.inc"
+
+; defines & equals
+.def zero = r0
+.def one = r1
+.def tmp = r16
+.def uart_count = r17
+.def count = r18
+.def R = r19
+.def G = r20
+.def B = r21
+.def mode r22
+.equ cm 0
+.equ rgb 1
+.def OUTR = r23
+.def FULLR = r24
+.equ LED_R PD2
+.equ LED_G PD3
+.equ LED_B PD4
+.equ LED_PORT PORTD
+
+;
+; interrupt voctors
+;
+; reset
+rjmp INIT
+; int0
+reti
+; int1
+reti
+; timer/counter capt 1
+reti
+; timer/counter compare
+reti
+; timer/counter overflow 1
+reti
+; timer/counter overflow 0
+reti
+; uart rx complete
+rjmp UART_RECEIVE
+; uart data register empty
+reti
+; uart tx complete
+reti
+; analog comparator
+reti
+
+;
+; init routine
+;
+INIT:
+; alloc stack pointer
+ldi r16,low(RAMEND)
+out SPL,r16
+; enable uart + rx complete interrupt
+ldi tmp,51 ; 9600 baud, 0,2% error @ 8mhz
+out UBRR,tmp
+ldi tmp,((1<<RXCIE)|(1<<RXEN))
+out UCR,tmp
+; init registers
+ldi tmp,1
+mov one,tmp
+ldi tmp,0
+mov zero,tmp
+ldi uart_count,0
+ldi count,0
+ldi R,0xff
+ldi G,0xff
+ldi B,0xff
+; led pins are outputs
+ldi tmp,((1<<LED_R)|(1<<LED_G)|(1<<LED_B))
+out DDRD,tmp
+; enable interrupts (global=
+sei
+; jump to main
+rjmp MAIN
+
+;
+; main routine
+;
+MAIN:
+; jumpt to main loop
+rjmp LOOP
+
+:
+; main loop
+;
+LOOP:
+; reset lights if loop starts
+cpi count,0
+breq RESET_LEDS
+; now check leds
+rjmp CHECK_RED
+
+;
+; reset leds
+;
+ldi OUTR,((1<<LED_R)|(1<<LED_G)|(LED_B))
+add count,one
+ret
+
+;
+; check red + jump to green check
+;
+CHECK_RED:
+cp count,R
+breq SWITCH_OFF_R
+rjmp CHECK_GREEN
+
+;
+; switch of red led
+;
+SWITCH_OFF_R:
+subi OUTR,(1<<LED_R)
+rjmp CHECK_GREEN
+
+;
+; check green + jump to blue check
+;
+CHECK_GREEN:
+cp count,G
+breq SWITCH_OFF_G
+rjmp CHECK_BLUE
+
+;
+; switch of green led
+;
+SWITCH_OFF_G:
+subi OUTR,(1<<LED_G)
+rjmp CHECK_BLUE
+
+;
+; check blue + "do the light"
+;
+CHECK_BLUE:
+cp count,B
+breq SWITCH_OFF_B
+rjmp LIGHT
+
+;
+; switch of blue led
+;
+SWITCH_OFF_G:
+sub OUTR,(1<<LED_B)
+rjmp LIGHT
+
+;
+; light it up
+;
+LIGHT:
+ldi FULLR,0xff
+sub FULLR,OUTR
+out LED_PORT,FULLR
+
+rjmp INC_COUNT
+
+;
+; increase counter + jump back to main loop
+;
+add counter,one
+rjmp LOOP
+
+;
+; receive from uart
+;
+UART_RECEIVE:
+reti
+