; Hodiny ATmega8A/L 4MHz / 32768Hz
; DANYK
; danyk.cz/avr_hod2.html

.NOLIST
.INCLUDE "m8def.inc"
.LIST

.DEF REG=R16
.DEF REG2=R17
.DEF CIF1=R20
.DEF CIF2=R21
.DEF CIF3=R22
.DEF CIF4=R23
.DEF CIF5=R24
.DEF CIF6=R25

.EQU SMER=DDRD
.EQU PORT=PORTD
.EQU SMER2=DDRC
.EQU PORT2=PORTC
.EQU SMER3=DDRB
.EQU PORT3=PORTB

.EQU STAV_TLAC=0x011B	;stav tlačítek - pamatuje si předchozí stav
.EQU PRODL_TLAC=0x011C	;prodleva tlacitek od dalsi reakce
.EQU DOBA_TLAC=0x0126	;meri dobu stisku tlacitka

.EQU ROK1=0x011F
.EQU ROK2=0x0120
.EQU AUTOCAS=0x0121
.EQU AUTOCASP=0x0122
.EQU JAS=0x0123
.EQU SVITI=0x0124
.EQU DISPVYP=0x0125
.EQU BUDIK=0x0110

.CSEG
.ORG 0
RJMP START

; vnitrni preruseni citacema
.ORG OC2addr
RJMP CITAC

.ORG OVF0addr
RJMP MULTIPLEX


START:
;nastaví port jako výstup
LDI REG,0xFF
OUT SMER,REG
LDI REG,0xFF
OUT PORT,REG

;nastaví port jako výstup
LDI REG,0xFF
OUT SMER2,REG
LDI REG,0xFF
OUT PORT2,REG

;nastaví bity 0,3,4,5 jako vstupy. Pro 3,4,5 aktivuje vnitřní pullup odpory 
;nastaví bit 2 jako výstup a dá počáteční log0. 
;bit 1 mění směr za běhu, výstup je jen při alarmu - potlačí slyšitelné rušení v piezu.
LDI REG,0b00000100
OUT SMER3,REG
LDI REG,0b00111000
OUT PORT3,REG


LDI REG,LOW(RAMEND)
OUT SPL,REG
LDI REG,HIGH(RAMEND)
OUT SPH,REG

; přednastaví registry
LDI REG,0
LDI REG2,0
LDI R18,1
LDI R19,1		;mód
LDI CIF1,0		;hodiny...
LDI CIF2,0
LDI CIF3,0
LDI CIF4,0
LDI CIF5,0
LDI CIF6,0
				
STS 0x0108,REG	;budík...
STS 0x0109,REG
STS 0x010A,REG
STS 0x010B,REG
				
STS 0x0101,REG	;stopky
STS 0x0102,REG
STS 0x0103,REG
STS 0x0104,REG
STS 0x0105,REG
STS 0x0106,REG

STS 0x0112,REG	;odpočet
STS 0x0113,REG
STS 0x0114,REG
STS 0x0115,REG
STS 0x0116,REG
STS 0x0117,REG

STS 0x0119,REG	;kolikátá cifra odpočtu se nařizuje (0-žádná)

STS 0x010D,REG	;datum
STS 0x010F,REG	;datum

STS BUDIK,REG	;zapnutí/vypnutí budíku (0-vyp,1-zap)

STS STAV_TLAC,REG	;stav tlačítek - pamatuje si předchozí stav
STS PRODL_TLAC,REG	;stav tlačítek II - měří prodlevu do další reakce

STS AUTOCASP,REG	;čas už byl posunut (0-ne, 1-ano)
STS DISPVYP,REG	;vypne displej při budíku na baterie (1-vyp)

STS SVITI,REG	;sviti displej (pouziva se v PWM regulaci jasu)

LDI REG,1
STS 0x0118,REG	;pamatuje si zapnutí/vypnutí odpočtu (2-zap,1-vyp)

STS JAS,REG		;jas displeje (0=max)

STS 0x0100,REG	;zapnutí/vypnutí stopek (1-vyp,2-zap)
STS 0x0107,REG	;den v týdnu

STS 0x010C,REG	;datum
STS 0x010E,REG	;datum

STS 0x011D,REG	;přepínač dělění 102-103
STS 0x011E,REG	;změna OCR2

STS AUTOCAS,REG	;automatický čas (0-ne, 1-ano)

STS ROK2,REG	;rok - vyšší cifra (posledního dvojčíslí)

LDI REG,3
STS ROK1,REG	;rok - nižší cifra (posledního dvojčíslí)

LDI REG,10
STS 0x0111,REG	;dělení času 10ti



LDI	REG,0b00000000	; zakaze preruseni CTC OCIE2 a TOV2
OUT	TIMSK,REG    	; 

;nastaví TC2 na asynchronní provoz 
LDI	REG,0b00001000	
OUT	ASSR,REG 

; NASTAVENI CASOVACE A JEHO PRERUSENI
LDI	REG,0b00000011 	; čítač 0 nemá OCR!
OUT TCCR0,REG    	; preddeli 64. řídí multiplex

LDI	REG,0b00000000 	; nastavi c/c na nulovani pri dosazeni porovnavane...
OUT	TCCR1A,REG    	; ...hodnoty (tzv. CTC), OC1A,B nevyuzity, deleni 64
LDI	REG,0b00001011 	; ...
OUT	TCCR1B,REG    	; ...
LDI	REG,0	      	; nastavi porovnavanou hodnotu-horní byte
OUT	OCR1AH,REG     	; 
LDI	REG,41	     	; nastavi porovnavanou hodnotu-dolní byte
OUT	OCR1AL,REG     	; dělí se n+1

LDI	REG,0b00001011 	; nulovani pri dosazeni porovnavane hodnoty...
OUT TCCR2,REG    	; ...(tzv. CTC), OC0 nevyuzit. preddeli 32
LDI	REG,101	      	; nastavi porovnavanou hodnotu (dělí se n+1)
OUT	OCR2,REG     	; citac 2 ridi cas, bezi asynchronne

LDI	REG,0b10000001	; povoli preruseni CTC OCIE2 a  TOV0
OUT	TIMSK,REG    	; 


CEKEJNAUPDATE:
IN REG,ASSR			;čeká na update OCR2,TCCR2,TCNT2
CPI REG,0b00001000
BRNE CEKEJNAUPDATE

IN REG,TIFR			;vynuluje flagy přerušení TCNT2
SBR REG,6
SBR REG,7
OUT TIFR,REG

SEI ;povoli globalni preruseni

;vypne analog. komparator - neni nikdy vyuzit (setri energii)
LDI	REG,0b10000000	
OUT	ACSR,REG  


;hlavní smyčka
SMYCKA:

IN REG,PINB			;Zjistí stav napájení
ANDI REG,0b00000001
CPI REG,0b00000001
BRNE BATERIE
					;napájení ze sítě
LDI REG,0
STS DISPVYP,REG

LDI	REG,0b10000001	; povoli preruseni CTC OCIE2 a TOV0
OUT	TIMSK,REG    	; 
LDI	REG,0b10000000	;povoli uspani (sleep) a nastavi mód idle
OUT	MCUCR,REG
SEI
SLEEP				;uspí
NOP
CLI
RJMP SMYCKA

BATERIE:			

IN REG,PORT3		;je prave budik?
ANDI REG,0b00000100	;izoluje bit 2
CPI REG,0b00000100	;pokud ne,
BREQ BUDIKBAT		;nepipa

LDI REG,1
STS DISPVYP,REG
					;napájení z baterie
LDS REG,0x011E
CPI REG,0
BREQ NECEKEJOCR2
CEKEJNAOCR2:
IN REG,ASSR			;čeká na update OCR2
SBRC REG,1
RJMP CEKEJNAOCR2
LDI REG,0
STS 0x011E,REG
NECEKEJOCR2:
LDI REG,0b11111111	; vypne displej - oba porty displeje nastaví na stejnou úroveň
OUT PORT,REG
OUT PORT2,REG
LDI	REG,0b10000000	; povoli preruseni pouze CTC OCIE2 
OUT	TIMSK,REG    	; 
LDI	REG,0b10110000	;povoli uspani (sleep) a nastavi mód power save
OUT	MCUCR,REG
SEI
SLEEP				;uspí
NOP
CLI				
RJMP SMYCKA

BUDIKBAT:		;budík při provozu z baterie

LDI REG,1
STS DISPVYP,REG

LDI REG,0b11111111	; vypne displej - oba porty displeje nastaví na stejnou úroveň
OUT PORT,REG
OUT PORT2,REG

LDI	REG,0b10000001	; povoli preruseni CTC OCIE2 a TOV0
OUT	TIMSK,REG    	; 
LDI	REG,0b10000000	;povoli uspani (sleep) a nastavi mód idle
OUT	MCUCR,REG
SEI
SLEEP				;uspí
NOP
CLI
RJMP SMYCKA







MULT:
CPI R18,1
BREQ MULT1
CPI R18,2
BREQ MULT2
CPI R18,3
BREQ MULT3
CPI R18,4
BREQ MULT4
CPI R18,5
BREQ MULT5
CPI R18,6
BREQ MULT6


MULT1:
MOV REG,CIF1
RCALL ZOBRAZ
OUT PORT,REG
LDI REG,0b00000001
OUT PORT2,REG
RET

MULT2:
MOV REG,CIF2
RCALL ZOBRAZ
OUT PORT,REG
LDI REG,0b00000010
OUT PORT2,REG
RET

MULT3:
MOV REG,CIF3
RCALL ZOBRAZ
SUBI REG,128   ;tohle rozsvěcí tečku na nejvyšším bitu
OUT PORT,REG
LDI REG,0b00000100
OUT PORT2,REG
RET

MULT4:
MOV REG,CIF4
RCALL ZOBRAZ
OUT PORT,REG
LDI REG,0b00001000
OUT PORT2,REG
RET

MULT5:
MOV REG,CIF5
RCALL ZOBRAZ
SUBI REG,128   ;tohle rozsvěcí tečku na nejvyšším bitu
OUT PORT,REG
LDI REG,0b00010000
OUT PORT2,REG
RET

MULT6:
MOV REG,CIF6
CPI REG,0
BREQ POTLAC0_A6
RCALL ZOBRAZ
RJMP ZOBRAZ_A6
POTLAC0_A6:
LDI REG,0b11111111
ZOBRAZ_A6:
OUT PORT,REG
LDI REG,0b00100000
OUT PORT2,REG
RET



MULTB:
CPI R18,1
BREQ MULTB1
CPI R18,2
BREQ MULTB2
CPI R18,3
BREQ MULTB3
CPI R18,4
BREQ MULTB4
CPI R18,5
BREQ MULTB5
CPI R18,6
BREQ MULTB6


MULTB1:
LDI REG,0b11000111
OUT PORT,REG
LDI REG,0b00000001
OUT PORT2,REG
RET

MULTB2:
LDI REG,0b10001000
OUT PORT,REG
LDI REG,0b00000010
OUT PORT2,REG
RET

MULTB3:
LDS REG,0x0108
RCALL ZOBRAZ
SUBI REG,128   ;tohle rozsvěcí tečku na nejvyšším bitu
OUT PORT,REG
LDI REG,0b00000100
OUT PORT2,REG
RET

MULTB4:
LDS REG,0x0109
RCALL ZOBRAZ
OUT PORT,REG
LDI REG,0b00001000
OUT PORT2,REG
RET

MULTB5:
LDS REG,0x010A
RCALL ZOBRAZ
SUBI REG,128   ;tohle rozsvěcí tečku na nejvyšším bitu
OUT PORT,REG
LDI REG,0b00010000
OUT PORT2,REG
RET

MULTB6:
LDS REG,0x010B
CPI REG,0
BREQ POTLAC0_B6
RCALL ZOBRAZ
RJMP ZOBRAZ_B6
POTLAC0_B6:
LDI REG,0b11111111
ZOBRAZ_B6:
OUT PORT,REG
LDI REG,0b00100000
OUT PORT2,REG
RET



MULTC:
CPI R18,1
BREQ MULTC1
CPI R18,2
BREQ MULTC2
CPI R18,3
BREQ MULTC3
CPI R18,4
BREQ MULTC4
CPI R18,5
BREQ MULTC5
CPI R18,6
BREQ MULTC6


MULTC1:
LDS REG,0x0101
RCALL ZOBRAZ
OUT PORT,REG
LDI REG,0b00000001
OUT PORT2,REG
RET

MULTC2:
LDS REG,0x0102
RCALL ZOBRAZ
SUBI REG,128   ;tohle rozsvěcí tečku na nejvyšším bitu
OUT PORT,REG
LDI REG,0b00000010
OUT PORT2,REG
RET

MULTC3:
LDS REG,0x0103
RCALL ZOBRAZ
OUT PORT,REG
LDI REG,0b00000100
OUT PORT2,REG
RET

MULTC4:
LDS REG,0x0104
RCALL ZOBRAZ
SUBI REG,128   ;tohle rozsvěcí tečku na nejvyšším bitu
OUT PORT,REG
LDI REG,0b00001000
OUT PORT2,REG
RET

MULTC5:
LDS REG,0x0105
RCALL ZOBRAZ
OUT PORT,REG
LDI REG,0b00010000
OUT PORT2,REG
RET

MULTC6:
LDS REG,0x0106
RCALL ZOBRAZ
SUBI REG,128   ;tohle rozsvěcí tečku na nejvyšším bitu
OUT PORT,REG
LDI REG,0b00100000
OUT PORT2,REG
RET


MULTG:

CPI R18,1
BRNE MULTG2
;MULTG1:

LDS REG,0x0112
RCALL ZOBRAZ
LDS REG2,0x0119
CPI REG2,1
BRNE HOPG1
LDS REG2,0x0111
SBRC REG2,0
LDI REG,0b11111111
HOPG1:
LDS REG2,0x0118
SBRC REG2,0
SUBI REG,128   ;tohle rozsvěcí tečku na nejvyšším bitu
OUT PORT,REG
LDI REG,0b00000001
OUT PORT2,REG
RET

MULTG2:
CPI R18,2
BRNE MULTG3

LDS REG,0x0113
RCALL ZOBRAZ
LDS REG2,0x0119
CPI REG2,2
BRNE HOPG2
LDS REG2,0x0111
SBRC REG2,0
LDI REG,0b11111111
HOPG2:
OUT PORT,REG
LDI REG,0b00000010
OUT PORT2,REG
RET

MULTG3:
CPI R18,3
BRNE MULTG4

LDS REG,0x0114
RCALL ZOBRAZ
LDS REG2,0x0119
CPI REG2,3
BRNE HOPG3
LDS REG2,0x0111
SBRC REG2,0
LDI REG,0b11111111
HOPG3:
LDS REG2,0x011A
SBRS REG2,1
SUBI REG,128   ;tohle rozsvěcí tečku na nejvyšším bitu
OUT PORT,REG
LDI REG,0b00000100
OUT PORT2,REG
RET

MULTG4:
CPI R18,4
BRNE MULTG5

LDS REG,0x0115
RCALL ZOBRAZ
LDS REG2,0x0119
CPI REG2,4
BRNE HOPG4
LDS REG2,0x0111
SBRC REG2,0
LDI REG,0b11111111
HOPG4:
OUT PORT,REG
LDI REG,0b00001000
OUT PORT2,REG
RET

MULTG5:
CPI R18,5
BRNE MULTG6

LDS REG,0x0116
RCALL ZOBRAZ
LDS REG2,0x0119
CPI REG2,5
BRNE HOPG5
LDS REG2,0x0111
SBRC REG2,0
LDI REG,0b11111111
HOPG5:
LDS REG2,0x011A
SBRS REG2,1
SUBI REG,128   ;tohle rozsvěcí tečku na nejvyšším bitu
OUT PORT,REG
LDI REG,0b00010000
OUT PORT2,REG
RET

MULTG6:
LDS REG,0x0117
RCALL ZOBRAZ
LDS REG2,0x0119
CPI REG2,6
BRNE HOPG6
LDS REG2,0x0111
SBRC REG2,0
LDI REG,0b11111111
HOPG6:
OUT PORT,REG
LDI REG,0b00100000
OUT PORT2,REG
RET





ZOBRAZ:

CPI REG,0
BREQ ZOBRAZ0
CPI REG,1
BREQ ZOBRAZ1
CPI REG,2
BREQ ZOBRAZ2
CPI REG,3
BREQ ZOBRAZ3
CPI REG,4
BREQ ZOBRAZ4
CPI REG,5
BREQ ZOBRAZ5
CPI REG,6
BREQ ZOBRAZ6
CPI REG,7
BREQ ZOBRAZ7
CPI REG,8
BREQ ZOBRAZ8
CPI REG,9
BREQ ZOBRAZ9

LDI REG,0b10111111  ;odchytí číslo mimo 0-9 a zobrazí jako "-"
RET

ZOBRAZ0:
LDI REG,0b11000000
RET

ZOBRAZ1:
LDI REG,0b11111001
RET

ZOBRAZ2:
LDI REG,0b10100100
RET

ZOBRAZ3:
LDI REG,0b10110000
RET

ZOBRAZ4:
LDI REG,0b10011001
RET

ZOBRAZ5:
LDI REG,0b10010010
RET

ZOBRAZ6:
LDI REG,0b10000010
RET

ZOBRAZ7:
LDI REG,0b11111000
RET

ZOBRAZ8:
LDI REG,0b10000000
RET

ZOBRAZ9:
LDI REG,0b10010000
RET





ZOBRAZDEN:

CPI REG,1
BREQ ZOBRAZDEN1
CPI REG,2
BREQ ZOBRAZDEN2
CPI REG,3
BREQ ZOBRAZDEN3
CPI REG,4
BREQ ZOBRAZDEN4
CPI REG,5
BREQ ZOBRAZDEN5
CPI REG,6
BREQ ZOBRAZDEN6
CPI REG,7
BREQ ZOBRAZDEN7


ZOBRAZDEN1:
LDI REG,0b10100011
LDI REG2,0b10001100
RET

ZOBRAZDEN2:
LDI REG,0b10000111
LDI REG2,0b11000001
RET

ZOBRAZDEN3:
LDI REG,0b10000111
LDI REG2,0b10010010
RET

ZOBRAZDEN4:
LDI REG,0b10000111
LDI REG2,0b11000110
RET

ZOBRAZDEN5:
LDI REG,0b10001000
LDI REG2,0b10001100
RET

ZOBRAZDEN6:
LDI REG,0b10100011
LDI REG2,0b10010010
RET

ZOBRAZDEN7:
LDI REG,0b10000110
LDI REG2,0b10101011
RET



ZOBRAZBUDIK:

CPI REG,0
BREQ ZOBRAZBUDIK0
CPI REG,1
BREQ ZOBRAZBUDIK1
CPI REG,2
BREQ ZOBRAZBUDIK2
CPI REG,3
BREQ ZOBRAZBUDIK3

ZOBRAZBUDIK0:
LDI REG,0b11110111
RET

ZOBRAZBUDIK1:
LDI REG,0b11111001
RET

ZOBRAZBUDIK2:
LDI REG,0b10010010
RET

ZOBRAZBUDIK3:
LDI REG,0b11111000
RET



ZOBRAZAC:

CPI REG,0
BREQ ZOBRAZAC0
CPI REG,1
BREQ ZOBRAZAC1

ZOBRAZAC0:
LDI REG,0b11110111
LDI REG2,0b11110111
RET

ZOBRAZAC1:
LDI REG,0b10100110
LDI REG2,0b10001000
RET


                ;tenhle zázrak dělá počítání do 23:59:59
PRIDEJS:
INC CIF1		;zvýší cifru 1
CPI CIF1,10		;ověří, jestli tam neni 10
BRLO KONEC   	;pokud ne, celé to končí
LDI CIF1,0		;pokud ano, vynuluje jí to
INC CIF2		;a zvýší cifru 2
CPI CIF2,6		;ověří, jestli tam neni 6
BRLO KONEC		;pokud ne, celé to končí
LDI CIF2,0		;pokud ano, vynuluje jí to
;PRIDEJM:
INC CIF3		;zvýší cifru 3
CPI CIF3,10		;ověří, jestli tam neni 10
BRLO KONECATEST   	;pokud ne, celé to končí
LDI CIF3,0		;pokud ano, vynuluje jí to
INC CIF4		;a zvýší cifru 4
CPI CIF4,6		;ověří, jestli tam neni 6
BRLO KONECATEST		;pokud ne, celé to končí
LDI CIF4,0		;pokud ano, vynuluje jí to
;PRIDEJH:
INC CIF5		; zvýší cifru 5
RCALL TAUTOCAS	;automatický čas
CPI CIF5,10		;ověří, jestli tam neni 10
BRLO KONTR24	;pokud ne, skočí na kontrolu 24
LDI CIF5,0		;pokud ano, vynuluje jí to
INC CIF6		;a zvýší cifru 6
KONTR24:
CPI CIF5,4		;kontrola, zda cifra 5 není 4
BRLO KONECATEST
CPI CIF6,2		;a zda současně cifra 6 není 2
BRLO KONECATEST
LDI CIF5,0 		;pokud ano, je 24 hodin, dojde k...
LDI CIF6,0		;...nulování obou cifer
RCALL DALSIDEN
RCALL DALSIDENT
KONECATEST:
RCALL BUDIKTEST
KONEC:
RET


				;tenhle zázrak dělá počítání dne a měsíce
DALSIDEN:
LDS REG,0x010E 	;načte jednotky dnů
INC REG			;iknrementuje je to
STS 0x010E,REG	;uloží
CPI REG,10		;zjistí, jestli už to není 10
BRLO KONTR31A	;pokud ne, pokračuje kontrolou, zda není konec měsíce
LDI REG,0		;jinak se vynuluje
STS 0x010E,REG	;...a uloží
LDS REG,0x010F	;načtou se desítky dnů
INC REG			;inkrementujou se
STS 0x010F,REG	;uloží se
KONTR31A:		;kontrola konce měsíce
RCALL KOLIKMADNI;zde se volá cosi, co vrácí počet dnů aktuálního měsíce	
LDS REG,0x010F	;načtou se desítky dnů
CP REG,REG2		;porovnají s max. desítkama dnů daného měsíce
BRLO KONECDENA 	;pokud nepřekročily maximum,konec
RCALL KOLIKMADNI;
LDS REG2,0x010E	;načte jednotky dnů
CP REG2,REG		;porovná je s maximální hodnotou daného měsíce
BRLO KONECDENA	;pokud nepřekročily, konec
LDI REG,1		;pokud ano, tak jednotky dnů = 1
STS 0x010E,REG	;uloží
LDI REG,0		;a desítky dnů = 0
STS 0x010F,REG	;uloží
DALSIMESIC:		;zvýšení měsíce
LDS REG,0x010C
INC REG
STS 0x010C,REG
CPI REG,10
BRLO KONTR12A
LDI REG,0
STS 0x010C,REG
LDS REG,0x010D
INC REG
STS 0x010D,REG
KONTR12A:
LDS REG,0x010D
CPI REG,1
BRLO KONECDENA
LDS REG,0x010C
CPI REG,3
BRLO KONECDENA
LDI REG,1
STS 0x010C,REG
LDI REG,0
STS 0x010D,REG
RCALL DALSIROK
KONECDENA:
RET

;počítání roku
DALSIROK:
LDS REG,ROK1
INC REG
STS ROK1,REG
CPI REG,10	
BRLO KONECROKN
LDI REG,0
STS ROK1,REG

LDS REG,ROK2
INC REG
STS ROK2,REG
CPI REG,10
BRLO KONECROKN
LDI REG,0
STS ROK2,REG
KONECROKN:
RET


DALSIDENT:		;zvýšení dne v týdnu (1-pondělí až 7-neděle)
LDS REG,0x0107
INC REG
STS 0x0107,REG
CPI REG,8
BRLO KONECDENT
LDI REG,1
STS 0x0107,REG
KONECDENT:
RET


BUDIKTEST:		;zjištuje, zda má nastat alarm - porovná s akt. časem
LDS REG,BUDIK
CPI REG,0
BREQ NEBUDIT
CPI REG,1
BREQ TESTUJBUDIK
CPI REG,3
BREQ TESTUJBUDIK
LDS REG,0x0107	;zjistí den v týdnu
CPI REG,6
BRSH NEBUDIT
TESTUJBUDIK:
LDS REG,0x0108
CP REG,CIF3
BRNE NEBUDIT
LDS REG,0x0109
CP REG,CIF4
BRNE NEBUDIT
LDS REG,0x010A
CP REG,CIF5
BRNE NEBUDIT
LDS REG,0x010B
CP REG,CIF6
BRNE NEBUDIT
SBI PORT3,2		;zapne budík
LDS REG,BUDIK
CPI REG,1		;pokud je budík jednoráz., po spuštění signálu ho to vypne
BRNE NEBUDIT
LDI REG,0
STS BUDIK,REG
NEBUDIT:
RET


KOLIKMADNI:		;tenhle zázrak vrací max. počet dnů akt. měsíce + 1
LDS REG,0x010C
LDS REG2,0x010D
CPI REG2,0
BREQ DO9
INC REG
INC REG
INC REG
DO9:			;měsíce 10-12 jsou stejné jako 3-5, proto tu nejsou.
CPI REG,1
BREQ MESIC1
CPI REG,2
BREQ MESIC2
CPI REG,3
BREQ MESIC3
CPI REG,4
BREQ MESIC4
CPI REG,5
BREQ MESIC5
CPI REG,6
BREQ MESIC6
CPI REG,7
BREQ MESIC7
CPI REG,8
BREQ MESIC8
CPI REG,9
BREQ MESIC9

MESIC1:
LDI REG2,3
LDI REG,2
RET
MESIC2:
RCALL JEPRESTUPNY
CPI REG2,0
BRNE PRESTUNOR
LDI REG2,2
LDI REG,9
RET
PRESTUNOR:
LDI REG2,3
LDI REG,0
RET
MESIC3:
LDI REG2,3
LDI REG,2
RET
MESIC4:
LDI REG2,3
LDI REG,1
RET
MESIC5:
LDI REG2,3
LDI REG,2
RET
MESIC6:
LDI REG2,3
LDI REG,1
RET
MESIC7:
LDI REG2,3
LDI REG,2
RET
MESIC8:
LDI REG2,3
LDI REG,2
RET
MESIC9:
LDI REG2,3
LDI REG,1
RET



JEPRESTUPNY:	;zjišťuje, zda je přestupný rok (ano - REG2=1)
LDS REG2,ROK2
LDS REG,ROK1
ANDI REG2,0b00000001
CPI REG2,1
BRNE LICHADES
INC REG
INC REG
LICHADES:
LDI REG2,1
CPI REG,0
BREQ PRESTUP
CPI REG,4
BREQ PRESTUP
CPI REG,8
BREQ PRESTUP
LDI REG2,0
PRESTUP:
RET



TAUTOCAS:		;kontrola, zda nemá automaticky změnit čas
LDS REG,AUTOCAS ;je zapnutý automatický čas?
CPI REG,0
BREQ POSUNNE
LDS REG,0x010F	;desítky dnů
CPI REG,0
BREQ POSUNNE
CPI REG,1
BREQ POSUNNE
CPI REG,3
BREQ POSUNDAL
LDS REG,0x010E	;jednotky dnů
CPI REG,5
BRLO POSUNNE
POSUNDAL:

LDS REG,0x0107	;den v týdnu
CPI REG,7
BRNE POSUNNE

LDS REG,0x010C	;jednotky měsíce
CPI REG,3
BREQ POSUNLET

LDS REG,0x010C
CPI REG,0
BREQ POSUNZIM

RJMP POSUNNE

POSUNLET:		;pokud je 02 hodin, posune na 03
CPI CIF5,2
BRNE POSUNNE
CPI CIF6,0
BRNE POSUNNE
LDI CIF5,3
LDI CIF6,0
RET

POSUNZIM:		;pokud je 02 hodin, posune na 03
LDS REG,AUTOCASP ;je zapnutý automatický čas?
CPI REG,1
BREQ POSUNNE
CPI CIF5,3
BRNE POSUNNE
CPI CIF6,0
BRNE POSUNNE
LDI CIF5,2
LDI CIF6,0
LDI REG,1
STS AUTOCASP,REG
RET

POSUNNE:
LDI REG,0
STS AUTOCASP,REG
RET



                ;tenhle zázrak dělá odpočet 99:59:59 - 00:00:00
ODPOCTI:

LDS REG,0x0112
DEC REG
STS 0x0112,REG
CPI REG,255
BRNE ODPOCKONEC
LDI REG,9
STS 0x0112,REG

LDS REG,0x0113
DEC REG
STS 0x0113,REG
CPI REG,255
BRNE ODPOCKONEC
LDI REG,5
STS 0x0113,REG

LDS REG,0x0114
DEC REG
STS 0x0114,REG
CPI REG,255
BRNE ODPOCKONEC
LDI REG,9
STS 0x0114,REG

LDS REG,0x0115
DEC REG
STS 0x0115,REG
CPI REG,255
BRNE ODPOCKONEC
LDI REG,5
STS 0x0115,REG

LDS REG,0x0116
DEC REG
STS 0x0116,REG
CPI REG,255
BRNE ODPOCKONEC
LDI REG,9
STS 0x0116,REG

LDS REG,0x0117
DEC REG
STS 0x0117,REG
CPI REG,255
BRNE ODPOCKONEC

RCALL BUM

ODPOCKONEC:
RET


BUM:			;odpočet skončil :)
LDI REG,0
STS 0x0117,REG
STS 0x0116,REG
STS 0x0115,REG
STS 0x0114,REG
STS 0x0113,REG
STS 0x0112,REG
LDI REG,1
STS 0x0118,REG
SBI PORT3,2		;zapne poplach
RET

		
		
					
TLACITKA:			;Zjištění stavu tlačítek. f je 100Hz
LDS REG,PRODL_TLAC	;počítadlo prodlevy do další reakce
CPI REG,0
BREQ UZJE0
DEC REG
STS PRODL_TLAC,REG
UZJE0:

LDS REG2,STAV_TLAC  ;Do REG2 načte předchozí stav tlačítek
IN REG,PINB			;Zjistí stav tlačítek
ANDI REG,0b00111000
STS STAV_TLAC,REG  	;Uloží ho pro příští test

CP REG2,REG			;pokud předchozí stav = současný, TL už nereaguje znovu
BREQ NEREAGOVAT

LDS REG2,PRODL_TLAC	;pokud neuplynula minimální prodleva, nereaguje znovu
CPI REG2,0
BRNE NEREAGOVAT

SBRS REG,3
RJMP NA_TLAC1
SBRS REG,4
RJMP NA_TLAC2
SBRS REG,5
RJMP NA_TLAC3

RJMP NEREAGOVAT

NA_TLAC1:
RCALL TLAC1
RJMP NEREAGOVAT
NA_TLAC2:
RCALL TLAC2
RJMP NEREAGOVAT
NA_TLAC3:
RCALL TLAC3

NEREAGOVAT:

LDI REG2,5			;určuje prodlevu do další reakce (x 10ms)

;stisknutí/držení tlačítka nastaví prodlevu do další reakce
SBRS REG,3
STS PRODL_TLAC,REG2
SBRS REG,4
STS PRODL_TLAC,REG2
SBRS REG,5
STS PRODL_TLAC,REG2

;tady zacina vyhodnoceni dlouheho stisku
CPI REG,0b00111000
BREQ NIC_NEDRZI
LDS REG2,DOBA_TLAC
INC REG2
STS DOBA_TLAC,REG2
NIC_NEDRZI:
LDS REG2,PRODL_TLAC
CPI REG2,0
BRNE PRODL_NE0
LDI REG2,0
STS DOBA_TLAC,REG2
PRODL_NE0:
LDS REG2,DOBA_TLAC
CPI REG2,100
BRNE NE100

LDI REG2,92
STS DOBA_TLAC,REG2

SBRS REG,3
RJMP NA_TLAC1_D
SBRS REG,4
RJMP NA_TLAC2_D
SBRS REG,5
RJMP NA_TLAC3_D
RJMP NE100

NA_TLAC1_D:
RCALL TLAC1
RJMP NE100
NA_TLAC2_D:
RCALL TLAC2
RJMP NE100
NA_TLAC3_D:
;RCALL TLAC3_D

NE100:
RET




; tlačítko nařizování hodin (dne v měsíci)
TLAC2:

LDS REG,DISPVYP
SBRC REG,0
RET

CPI R19,1
BREQ NAMOD1H
CPI R19,2
BREQ NAMOD3H
CPI R19,3
BREQ NAMOD7H

NAMOD1H:
RJMP MOD1H
NAMOD3H:
RJMP MOD3H
NAMOD7H:
RJMP MOD7H


MOD1H:
INC CIF5		; zvýší cifru 5
CPI CIF5,10		;ověří, jestli tam neni 10
BRLO KONTR24A	;pokud ne, skočí na kontrolu 24
LDI CIF5,0		;pokud ano, vynuluje jí to
INC CIF6		;a zvýší cifru 6
KONTR24A:
CPI CIF5,4		;kontrola, zda cifra 5 není 4
BRLO KONECH
CPI CIF6,2		;a zda současně cifra 6 není 2
BRLO KONECH
LDI CIF5,0 		;pokud ano, je 24 hodin, dojde k...
LDI CIF6,0		;...nulování obou cifer
KONECH:
RCALL BUDIKTEST
RET

MOD3H:			;nuluje stopky
LDS REG,0x0100
CPI REG,2
BREQ STOPKYSTOP
LDI REG,0
STS 0x0101,REG
STS 0x0102,REG
STS 0x0103,REG
STS 0x0104,REG
STS 0x0105,REG
STS 0x0106,REG
STOPKYSTOP:
LDI REG,1
STS 0x0100,REG
RET

MOD7H:
LDS REG,0x0118	;pamatuje si zapnutí/vypnutí odpočtu
LDI REG,1		;před nařizováním vypne odpočet
STS 0x0118,REG
LDS REG,0x0119	;která cifra se právě nařizuje. 0-žádná
CPI REG,0
BRNE KONEC7H
LDI REG,7
KONEC7H:
DEC REG
STS 0x0119,REG
RET

; tlačítko nařizování minut (při něm se nulují vteřiny) a měsíce
TLAC1:

LDS REG,DISPVYP
SBRC REG,0
RET

CPI R19,1
BREQ NAMOD1M
CPI R19,2
BREQ NAMOD3M
CPI R19,3
BREQ NAMOD7M


NAMOD1M:
RJMP MOD1M
NAMOD3M:
RJMP MOD3M
NAMOD7M:
RJMP MOD7M


MOD1M:
INC CIF3		;zvýší cifru 3
CPI CIF3,10		;ověří, jestli tam neni 10
BRLO KONECM   	;pokud ne, celé to končí
LDI CIF3,0		;pokud ano, vynuluje jí to
INC CIF4		;a zvýší cifru 4
CPI CIF4,6		;ověří, jestli tam neni 6
BRLO KONECM		;pokud ne, celé to končí
LDI CIF4,0
KONECM:
LDI CIF1,0
LDI CIF2,0
LDI REG,10
STS 0x0111,REG
RCALL BUDIKTEST
RET

MOD3M:
LDS REG,0x0100	;pamatuje si zapnutí/vypnutí stopek
DEC REG
BRNE ZPET3M
LDI REG,2
ZPET3M:
STS 0x0100,REG
RET

MOD7M:
LDS REG,0x0119
CPI REG,0
BREQ ODPOCNARIZ0
CPI REG,1
BREQ ODPOCNARIZ1
CPI REG,2
BREQ ODPOCNARIZ2
CPI REG,3
BREQ ODPOCNARIZ3
CPI REG,4
BREQ ODPOCNARIZ4
CPI REG,5
BREQ ODPOCNARIZ5
CPI REG,6
BREQ ODPOCNARIZ6
ODPOCNARIZ0:
LDS REG,0x0118	;pamatuje si zapnutí/vypnutí odpočtu
DEC REG
BRNE ZPET7M
LDI REG,2
ZPET7M:
STS 0x0118,REG
RET
ODPOCNARIZ1:
LDS REG,0x0112
INC REG
CPI REG,10
BRLO ODPOCKON1
LDI REG,0
ODPOCKON1:
STS 0x0112,REG
RET
ODPOCNARIZ2:
LDS REG,0x0113
INC REG
CPI REG,6
BRLO ODPOCKON2
LDI REG,0
ODPOCKON2:
STS 0x0113,REG
RET
ODPOCNARIZ3:
LDS REG,0x0114
INC REG
CPI REG,10
BRLO ODPOCKON3
LDI REG,0
ODPOCKON3:
STS 0x0114,REG
RET
ODPOCNARIZ4:
LDS REG,0x0115
INC REG
CPI REG,6
BRLO ODPOCKON4
LDI REG,0
ODPOCKON4:
STS 0x0115,REG
RET
ODPOCNARIZ5:
LDS REG,0x0116
INC REG
CPI REG,10
BRLO ODPOCKON5
LDI REG,0
ODPOCKON5:
STS 0x0116,REG
RET
ODPOCNARIZ6:
LDS REG,0x0117
INC REG
CPI REG,10
BRLO ODPOCKON6
LDI REG,0
ODPOCKON6:
STS 0x0117,REG
RET




; tlačítko 3 - volba módu, zastavení budíku
TLAC3:
IN REG,PORT3		;je prave budik?
ANDI REG,0b00000100
CPI REG,0b00000100	;pokud ano,
BREQ MODKONEC		;vypne se a neprepina mod

;pamatuje si mód
DEC R19
BRNE MODKONEC
LDI R19,3
MODKONEC:
CBI PORT3,2			;vypne budik
RET


; přerušení řídící čas (f=10Hz)
CITAC:

LDS REG,0x011D	;přepínač dělení 102-103
DEC REG
BRNE NENULA
LDI REG,10		;cyklus 
NENULA:
STS 0x011D,REG

CPI REG,10
BREQ DELI103

CPI REG,6
BREQ DELI102

RJMP DELKONEC

DELI103:
LDI	REG2,102	      	; nastavi porovnavanou hodnotu (dělí se n+1=103)
OUT	OCR2,REG2		; uloží do OCR2
LDI REG,1
STS 0x011E,REG

RJMP DELKONEC

DELI102:
LDI	REG2,101	      	; nastavi porovnavanou hodnotu (dělí se n+1=102)
OUT	OCR2,REG2		; uloží do OCR2
LDI REG,1
STS 0x011E,REG

DELKONEC:

LDS REG,0x0111	;odpočet desetin s
DEC REG
BRNE NIC

RCALL PRIDEJS

LDI	REG,41			;dělitel frekvence do repro
SUB REG,CIF1 		;frekvence se mění po sekundách
SUB REG,CIF1   	
OUT	OCR1AL,REG 		;nastavení dělitele

LDI	REG,0	      	; nulování čítače 1
OUT	TCNT1H,REG     	; 
LDI	REG,0	     	; 
OUT	TCNT1L,REG     	;

LDS REG,0x0118	;pamatuje si zapnutí/vypnutí odpočtu
CPI REG,2
BRNE ODPOCETNIC
RCALL ODPOCTI 
ODPOCETNIC:
LDI REG,10		;dělí se n, nikoliv n+1
NIC:
STS 0x0111,REG 

LDS REG,0x0100	;pamatuje si zapnutí/vypnutí stopek
CPI REG,2
BRNE STOPNIC

LDS REG,0x0101	;inkrementace stopek
INC REG
STS 0x0101,REG
CPI REG,10	
BRLO STOPNIC
LDI REG,0
STS 0x0101,REG

LDS REG,0x0102
INC REG
STS 0x0102,REG
CPI REG,10	
BRLO STOPNIC
LDI REG,0
STS 0x0102,REG

LDS REG,0x0103
INC REG
STS 0x0103,REG
CPI REG,6
BRLO STOPNIC
LDI REG,0
STS 0x0103,REG

LDS REG,0x0104
INC REG
STS 0x0104,REG
CPI REG,10	
BRLO STOPNIC
LDI REG,0
STS 0x0104,REG

LDS REG,0x0105
INC REG
STS 0x0105,REG
CPI REG,6
BRLO STOPNIC
LDI REG,0
STS 0x0105,REG

LDS REG,0x0106
INC REG
STS 0x0106,REG
CPI REG,10	
BRLO STOPNIC
LDI REG,0
STS 0x0106,REG

STOPNIC:		;sem to přeskočí, pokud jsou stopky zastavené

LDS REG,0x011A	;generátor 2Hz bllikání
DEC REG
BRNE NIC2HZ
LDI REG,5		;dělí se n, nikoliv n+1
NIC2HZ:
STS 0x011A,REG

;pípání
LDI	REG2,0b00000000	;odpojení výstupu OC1A
IN REG,PORT3		;je prave budik?
ANDI REG,0b00000100	;izoluje bit 2
CPI REG,0b00000100	;pokud ne,
BRNE NEPIPAT		;nepipa

LDS REG,0x011A		;2Hz přerušování tónu
SBRC REG,0
RJMP NEPIPAT
LDI	REG2,0b01000000	;přepínání (toggle) výstupu OC1A
SBI SMER3,1			;nastaví PB1 jako výstup (během pípnutí)
RJMP PIPATO
NEPIPAT:
CBI SMER3,1			;nastaví PB1 jako vstup (aby bylo uplný ticho)
PIPATO:
OUT TCCR1A,REG2		;nastavení přepínání (toggle) výstupu OC1A
RETI



; přerušení řídící multiplex (f přerušení = 600Hz)
MULTIPLEX:

LDS REG,SVITI	;stav PWM displeje
LDS REG2,JAS		;regulace jasu

CPI REG2,0
BREQ JAS0
CPI REG2,1
BREQ JAS1
CPI REG2,2
BREQ JAS2
CPI REG2,3
BREQ JAS3
CPI REG2,4
BREQ JAS4
CPI REG2,5
BREQ JAS5

JAS0:
LDI REG2,152
RJMP KONECJAS
JAS1:
LDI REG2,204
RJMP KONECJAS
JAS2:
LDI REG2,230
RJMP KONECJAS
JAS3:
LDI REG2,243
RJMP KONECJAS
JAS4:
LDI REG2,249
RJMP KONECJAS
JAS5:
LDI REG2,252
KONECJAS:



CPI REG,1
BREQ PWM0
CPI REG,0
BREQ PWM1

PWM0:		;zhasnout pwm displeje

LDI REG,255 ;spočítá dobu pwm0 (zbytek do PWM1) 
SUB REG,REG2
LDI REG2,103
SUB REG2,REG
LDI REG,255
SUB REG,REG2

OUT TCNT0,REG   	; dělitel je (256-REG)

LDI REG,0
STS SVITI,REG

LDS REG,DISPVYP		;má být displej vypnut?
CPI REG,1
BREQ NEMULT			;pokud ano, přeskočí se proces multiplexu

LDI REG,0b00000000	; vypne displej
OUT PORT2,REG

RETI

PWM1:		;rozsvítit PWM displeje

OUT TCNT0,REG2    	; dělitel je (256-REG)

LDI REG,1
STS SVITI,REG

DEC R18
BRNE MULTHOP
LDI R18,6
RCALL TLACITKA     ;Frekvence multiplexu a testu tlačítek je 100Hz
MULTHOP:

LDS REG,DISPVYP		;má být displej vypnut?
CPI REG,1
BREQ NEMULT			;pokud ano, přeskočí se proces multiplexu

RCALL MULTIPLEX1

NEMULT:

RETI


MULTIPLEX1:

LDI REG,0b00000000
OUT PORT2,REG

CPI R19,1
BREQ MOD1

CPI R19,2
BREQ MOD3

CPI R19,3
BREQ MOD7

MOD1:		;hodiny
RCALL MULT
RJMP MULTZAVER

MOD2:		;budik
RCALL MULTB
RJMP MULTZAVER

MOD3:		;stopky
RCALL MULTC
RJMP MULTZAVER

MOD7:		;odpočet
RCALL MULTG
RJMP MULTZAVER

MULTZAVER:
RET
