; ATtiny13 project
.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
.ORG 0x0000

RJMP init

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

	; For COMMON ANODE:
	; 0 = segment ON, 1 = sement OFF
	
	; (invert for common cathode)

	;     qqqqqqqq
	;     01234567

	.DB 0b00100001, 0b01111101	; 0, 1
	.DB 0b10101000, 0b00111000  ; 2, 3
	.DB 0b01110100, 0b00110010  ; 4, 5
	.DB 0b00100010, 0b01111001  ; 6, 7
	.DB 0b00100000, 0b00110000  ; 8, 9
	.DB 0b01100000, 0b00100110  ; A, B
	.DB 0b10100011, 0b00101100  ; C, D
	.DB 0b10100010, 0b11100010  ; E, F
	.DB 0b11111111, 0b00000000  ; all_clr, all_set

; 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:
	
	; Set counter to zero and display it
	LDI CNT, 0
	MOV SYM, CNT
	RCALL setdisplay
	RJMP back2
	
	; Wait until button is depressed
back3:
	
	; Turn LED ON
	OUTP PORTB, (1<<PB0)

back31:

	IN R0, PINB
	SBRS R0, 1
	RJMP back31

	; Wait until button is pressed
back2:
	
	; Turn LED OFF
	OUTP PORTB, (0<<PB0)	

back21:

	IN R0, PINB
	SBRC R0, 1
	RJMP back21

	; Increase counter
	INC CNT
	
	; Check CNT>15
	CPI CNT, 16
	BRNE next1
	
	; CNT=0
	LDI CNT, 0;

next1:
	
	MOV SYM, CNT
	RCALL setdisplay

	RJMP back3

RJMP main
	

