; ATtiny13 xBoard v2 project
; METRONOME

.INCLUDE "tn13def.inc"

.DEF	TMP 	= R17
.DEF	SYM  	= R18
.DEF	CNT		= R19

; OUTP port, value
.MACRO OUTP
	LDI R16,@1 			
	OUT @0,R16 	
.ENDM

.CSEG

;Interrupt table
.ORG 0x0000

RJMP init 		; Reset Handler
RETI			; IRQ0 Handler
RETI			; PCINT0 Handler
RJMP TIM0_OVF	; Timer0 Overflow Handler
RETI			; EEPROM Ready Handler
RETI			; Analog Comparator Handler
RETI			; Timer0 CompareA Handler
RETI			; Timer0 CompareB Handler
RETI			; Watchdog Interrupt Handler
RETI			; ADC Conversion Handler

;Main program code
.ORG 0x000A

sym_table:
	; 7 segment display symbol table
	; for ATtiny13 xBoard v2 board
	
	; Q0 = C, Q1 = D, Q2 = dot, Q3 = E,
	; Q4 = F, Q5 = A, Q6 = B,   Q7 = G

	; 0 = segment ON, 1 = sement OFF

	;     qqqqqqqq
	;     01234567

	.DB 0b00100001, 0b01111101
	.DB 0b10101000, 0b00111000
	.DB 0b01110100, 0b00110010
	.DB 0b00100010, 0b01111001
	.DB 0b00100000, 0b00110000
	.DB 0b01100000, 0b00100110
	.DB 0b10100011, 0b00101100
	.DB 0b10100010, 0b11100010
	.DB 0b11111111, 0b00000000
	.DB 0b11011111, 0b11111111

; setdisplay draws the specified 
; symbol on the 7-segment display
; NB! specify SYM prior to call
setdisplay:
	
	; Set control signals
	OUTP DDRB, (1<<PB3) | (1<<PB4)
	
	; Load symbol table address
	LDI ZL, LOW (2*sym_table)
	LDI ZH, HIGH(2*sym_table)

	; Find required symbol
	ADD ZL, SYM

	; Load symbol data to R0
	LPM
	
	; Start iteration
	LDI TMP, 8
	
	back1:
	
		SBRC R0, 0
		RJMP bitset
			; Set segment to 0 (ON)
			OUTP PORTB,(0<<PB3)|(0<<PB4)
			OUTP PORTB,(1<<PB3)|(0<<PB4)
		RJMP bitunset
		bitset:
			; Set segment to 1 (OFF)
			OUTP PORTB,(0<<PB3)|(1<<PB4)
			OUTP PORTB,(1<<PB3)|(1<<PB4)
		bitunset:
		
		LSR R0
		DEC TMP

	BRNE back1	

	; Return to caller
	RET

;Initialization
init:

	; Set button as input, LED as output
	OUTP DDRB, (1<<PB0) | (0<<PB1) | (0<<PB2)
	
main:	

	; Display dot
	LDI SYM, 18
	RCALL setdisplay

	LDI CNT, 0

	; Enable timer overflow interrupt
	OUTP TIMSK0, (1<<TOIE0)
	
	; Wait for keypress
wait:
	SBIC PINB, 1
	RJMP wait

	; Setup the timer
	CLI

	; Set timer tick value
	OUTP TCNT0, 192

	; Set prescaler = 1024
	OUTP TCCR0B, 5
	
	SEI

	; Set loop

loop:
	
	NOP

RJMP loop

TIM0_OVF:

	OUTP TCNT0, 192

	; LED momentary on
	OUTP PORTB, (1<<PB0)
	
	; Increment counter
	INC CNT

	; Check CNT>4
	CPI CNT, 5
	BRNE next1

	; CNT=0
	LDI CNT, 1

next1:

	MOV SYM, CNT
	RCALL setdisplay

	; LED OFF
	OUTP PORTB, (0<<PB0)

	;Return from interrupt
	RETI

