.include "tn2313def.inc"

.def	xlr=R1
.def	xhr=R2
.def	zlr=R3
.def	zhr=R4
.def	minuta=R5

.def	loop=r22
.def	temp=r16
.def	temp1=r17
.def	count=r18
.def	fnota=r19
.def	dnota=r20

.def	e=r21
.def	b=R24	
.def	c=R25	
.def	d=r23	

.equ	kdel=239

;-----------ИНИЦИАЛИЗАЦИЯ-----------

.cseg
.org	0

start:	rjmp init
;		rjmp wakeup
reti

		reti
		reti
		reti
		reti
		reti
		reti
		reti
		reti
		reti
		reti
		reti
		rjmp timerdecrement	
		reti
		reti
		reti
		reti
;------------------------------------		

init:

ldi	e, RAMEND
out	SPL, e

;----------выбор тактового сигнала------------------
		ldi e, 0b10000000
		out clkpr, e

		ldi e, 0b00000101
		out clkpr, e

		ldi	e,0x80
		out	ACSR,e

		clr count
		clr xlr
		clr xhr
		clr zlr
		clr zhr
		ldi b,255
		ldi d,255
;----------------------------инициализация портов
		cbi	DDRD,0
		sbi PortD,0
		cbi	DDRD,1
		sbi PortD,1
		cbi	DDRD,2
		sbi PortD,2	



sbi	DDRA,0
sbi PortA,0
	sbi	DDRA,1
    sbi PortA,1
		sbi	DDRD,3
		sbi PortD,3
			sbi	DDRD,4
			sbi PortD,4
				sbi	DDRD,5
				sbi PortD,5
					sbi	DDRD,6
					sbi PortD,6


sbi	DDRB,0
sbi PortB,0
	sbi	DDRB,1
	sbi PortB,1
		sbi	DDRB,2
		sbi PortB,2
			sbi	DDRB,3
			sbi PortB,3
	sbi	DDRB,4
	sbi PortB,4
sbi	DDRB,5
sbi PortB,5
	sbi	DDRB,6
	sbi PortB,6
		sbi	DDRB,7
		sbi PortB,7
;----------------------------инициализация таймера0
	ldi	e, 2
	out	tccr0a, e	
	
	ldi	e, 0x05
	out	tccr0b, e

	ldi	e, kdel
	out	OCR0A, e
;---------------------------инициализация таймера1
	ldi	e, 0
	out	tccr1a, e

	ldi	e, 0x09
	out	tccr1b, e

;-------------------настойка прерываний счетчиков-------------
		sei
		ldi	e, 0
		out	timsk, e

		ldi	e, 0b01
		out	gimsk, e

;************************
;		cbi PinA,1			

		clr xlr
		clr xhr
		clr zlr
		clr zhr

		ldi e,60
		mov minuta,e

;-------------------------------------------------
;                   начало основной программы
;-------------------------------------------------
main:
		in e,SREG
		sbrc e,6
		rcall decrcounter
		
		in	e,PIND
		sbrs e,1
		rcall	timerincrement10min

		in	e,PIND
		sbrs e,0
		rcall	timerincrement1min

		in	e,PIND
		sbrs e,2
		rcall	timerdecrementstart

;--------динамическая индикация

			;cpi	b,0
			;breq	main1
			;dec	b
main1:		;cpi d,0
			;breq	main2
			;dec d
			;rjmp main



		cbi	portA,0
		sbi	portD,3
		cbi	portD,4
		cbi	portD,5
		mov		c,zhr
		rcall	rascod
		rcall zaderjkamin1


		cbi	portA,0
		cbi	portD,3
		sbi	portD,4
		cbi	portD,5
		cbi	portD,6
		mov		c,zlr
		rcall	rascod
		rcall zaderjkamin1
		sbi	portD,6

		cbi	portA,0
		cbi	portD,3
		cbi	portD,4
		sbi	portD,5
		mov		c,xhr
		rcall	rascod
		rcall zaderjkamin1


		sbi	portA,0
		cbi	portD,3
		cbi	portD,4
		cbi	portD,5
		mov		c,xlr
		rcall	rascod
		rcall zaderjkamin1


		rjmp main
main2:  ;rcall son
		rjmp main

;***********************************
;*        Подпрограммы      *
;***********************************


timerincrement10min: 
			in	e,PIND
			sbrs e,1
		    rjmp	timerincrement10min
	

			push count
			ldi count, 7
			rcall m3
			pop count

			rjmp inc2

timerincrement1min:
		in	e,PIND
		sbrs e,0
		rjmp timerincrement1min
		

		push count
		ldi count,7
		rcall m3
		pop count

			mov e,zhr  ;проверка переполнения таймера
			cpi	e,9
			breq inc4

			inc	xlr

			mov e,xlr
			cpi	e,10
			breq	inc1
			ret

inc1:		clr	xlr
inc2:		inc	xhr
			mov e,xhr
			cpi	e,6
			breq inc3
			ret			

inc3:		clr xlr
			clr xhr
			inc zlr
			mov e,zlr
			cpi	e,10
			breq inc4
			ret

inc4:		clr xlr
			clr xhr
			clr zlr
			inc zhr
			mov e,zhr
			cpi	e,10
			breq	inc5
			ret

inc5:		ldi e,9
			mov zhr,e
			ret

timerdecrementstart:			;запуск таймера времени
		in	e,PIND
		sbrs e,2
		rjmp	timerdecrementstart

	
		rcall m3

;		sbi PortA,1

		ldi	e, 0b00000001
		out	timsk, e
		ret

timerdecrement:					;действие по секунде

			mov e,minuta
			cpi e,0
			breq td1

		dec minuta
;		cbi	portA,0
;		cbi	portD,3
;		cbi	portD,4
;		cbi	portD,5
;		rcall zaderjkamin2
;		sbi	portA,0
;		sbi	portD,3
;		sbi	portD,4
;		sbi	portD,5
		reti
		
td1:	set					;установка флага срабатывания минуты
		ldi e,60			;сбрасывание счетчика минуты
		mov minuta,e		;
		reti

decrcounter:
		clt
		mov e,xlr
		cpi	e,0			
		breq	dcrc1
		dec 	xlr
		mov e,xlr
		cpi	e,0			
		breq	prov0
		ret

dcrc1:	mov e,xhr
		cpi	e,0			
		breq	dcrc2
		dec	xhr
		ldi	e,9
		mov xlr,e		
		ret	

dcrc2:	mov e,zlr
		cpi	e,0		
		breq	dcrc3
		dec	zlr
		ldi	e,5
		mov xhr,e
		ldi	e,9
		mov xlr,e
		ret	

dcrc3:	mov e,zhr
		cpi	e,0		
		breq	dcrc4
		dec	zhr
		ldi	e,9
		mov zlr,e
		ret

dcrc4:	;sbi PortA,1
		nop
		nop
		ldi	e, 0b00000000
		out	timsk, e
		
		ldi	e, 0x40;64;
		out	tccr1a, e

		ldi	e, 0x09
		out	tccr1b, e	
		
		rcall m3

		    ldi e, 2
		cpse count,e
		inc count
dcrc5:	ret

;-----------------------------------------
prov0:	mov e,xhr
		cpi	e,0			
		breq	prov2
		rjmp dcrc1
prov2:	mov e,zlr
		cpi	e,0		
		breq	prov3
		rjmp dcrc1
prov3:	mov e,zhr
		cpi	e,0		
		breq	dcrc4
		rjmp dcrc1
;========================М У З Ы К А==========================

m3:		mov	YL, count             ; счетчик мелодий -> YL
		ldi	ZL, low(tabm*2)			;в Z -> начальный адрес "tabm"
		ldi	ZH, high(tabm*2)		;
		rcall	addw				; сложение смещения по счетчику и 
									; начального адреса "tabm"

		lpm	XL, Z+					; извлечение из "tabm"
		lpm XH, Z

;---------------------воспроизведение----------------------------
m4:		mov	ZH, XH					; пересылка в рабочий регистр
		mov ZL, XL					;

m5:		
		ldi	e, 0					; установка таймера1
		out	tccr1a, e

		lpm	temp, Z					; пересылка данных, находящихся 
									; по адресу в Z -> temp
		cpi	temp, 0xFF 				; последняя нота????
		breq	m6				; выход

		andi	temp, 0x1F			; выделяем код тона (И=И)
		mov	fnota, temp				; кидаем его в fnota
		lpm	temp, Z+				; первую ноту в temp
		rol	temp					; 4-кратный круговой сдвиг кода ноты
		rol	temp					;
		rol	temp					;
		rol	temp					;

		andi temp, 0x07				;выделение кода длительности
		mov	dnota, temp				; помещаем его в "dnota"

		rcall nota

		rjmp m5
m6:		ret
;-------------------задержка маленькая сегментарная-------
zaderjkamin1:	
		push d
ldi	d, 255
				
zaderjka1min1:	
			cpi	d,0
			breq	zaderjka2min1
			dec	d
			nop
			rjmp zaderjka1min1	
zaderjka2min1: 
pop d	
ret


;-------------------задержка большая сегментарная-------
zaderjkamin2:	
		push b
		push d

ldi	b, 255
ldi d, 255				
zaderjka1min2:	
			cpi	b,0
			breq	zaderjka2min2
			dec	b
			nop
			rjmp zaderjka1min2	
zaderjka2min2: 
			cpi	d,0
			breq	zaderjka3min2
			dec	d
			ldi	b, 255
			nop
			rjmp zaderjka1min2
zaderjka3min2:
pop b	
pop d	
ret

;-------------------переход ко сну-------
son:
ldi e,0b01100000
out mcucr,e
sleep
ret

;-------------------выход из сна-------
wakeup:
nop
nop
reti

;&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
;раскодирование сегиентов

rascod:
rascod1:	ldi	e,0
			cpse	c,e
			rjmp rascod2	
			cbi portB,0
			sbi portB,1
			cbi portB,2
			cbi portB,4
			cbi portB,5
			cbi portB,6
			cbi portB,7 
			ret

rascod2:	ldi	e,1
			cpse	c,e
			rjmp rascod3
			cbi portB,0
			sbi portB,1
			sbi portB,2
			sbi portB,4
			sbi portB,5
			sbi portB,6
			cbi portB,7 
			ret

rascod3:	ldi	e,2
			cpse	c,e
			rjmp rascod4
			sbi portB,0
			cbi portB,1
			cbi portB,2
			cbi portB,4
			cbi portB,5
			sbi portB,6
			cbi portB,7
			ret

rascod4:	ldi	e,3
			cpse	c,e
			rjmp rascod5
			cbi portB,0
			cbi portB,1
			cbi portB,2
			sbi portB,4
			cbi portB,5
			sbi portB,6
			cbi portB,7
			ret

rascod5:	ldi	e,4
			cpse	c,e
			rjmp rascod6
			cbi portB,0
			cbi portB,1
			sbi portB,2
			sbi portB,4
			sbi portB,5
			cbi portB,6
			cbi portB,7
			ret

rascod6:	ldi	e,5
			cpse	c,e
			rjmp rascod7
			cbi portB,0
			cbi portB,1
			cbi portB,2
			sbi portB,4
			cbi portB,5
			cbi portB,6
			sbi portB,7
			ret

rascod7:	ldi	e,6
			cpse	c,e
			rjmp rascod8
			cbi portB,0
			cbi portB,1
			cbi portB,2
			cbi portB,4
			cbi portB,5
			cbi portB,6
			sbi portB,7
			ret

rascod8:	ldi	e,7
			cpse	c,e
			rjmp rascod9
			cbi portB,0
			sbi portB,1
			sbi portB,2
			sbi portB,4
			cbi portB,5
			sbi portB,6
			cbi portB,7
			ret

rascod9:	ldi	e,8
			cpse	c,e
			rjmp rascod10
			cbi portB,0
			cbi portB,1
			cbi portB,2
			cbi portB,4
			cbi portB,5
			cbi portB,6
			cbi portB,7
			ret
			
rascod10:	ldi	e,9
			cpse	c,e
			rjmp rascod11
			cbi portB,0
			cbi portB,1
			cbi portB,2
			sbi portB,4
			cbi portB,5
			cbi portB,6
			cbi portB,7
rascod11:	ret




;  Программа 16-тиразрядного сложения 
addw: 	push YH
		lsl	YL
		ldi	YH,0
		add	ZL, YL
		add	ZH, YH

		pop YH
		ret

; Подпрограмма исполнения одной ноты
nota:   push ZH
        push ZL  
		push YL
		push temp

		cpi fnota, 0x00
		breq nt1

		mov YL, fnota				; fnota ->YL
		ldi ZL, low(tabkd*2)		; адрес "tabkd" -> Z
		ldi ZH, high(tabkd*2)		;
		rcall addw					; переход на нужный адрес
		
		lpm temp, Z+				;извлечение в temp и temp1 нужного 
		lpm temp1, Z				;коэффициента деления
		out OCR1AH, temp1
		out OCR1AL, temp

		ldi	e, 0x40					;установка таймера1
		out	tccr1a, e				;


nt1:	rcall	wait
		
		ldi	e, 0
		out	tccr1a, e

		ldi dnota, 0
		rcall wait
		
		pop temp 
		pop YL
		pop ZL
		pop ZH
		ret

; Подпрограмма формирования задержки

wait:   push ZH
        push ZL  
		push YH
		push YL

		mov	YL, dnota
		ldi ZL, low(tabz*2)
		ldi ZH, high(tabz*2)
		rcall addw

		lpm YL, Z+
		lpm YH, Z
		clr ZL
		clr ZH

				; Цикл задержки
w1: 	ldi	loop, 255
w2:		dec loop
		cpi loop, 0
		brne w2
		
		adiw r30, 1
		cp YL, ZL
		brne W1
		
		cp YH, ZH
		brne W1		

		pop YL
		pop YH
		pop ZL
		pop ZH
		ret


; **********************************
; Таблица длительности задержек

;tabz:   .dw	128,256,512,1024,2048,4096,8192
;tabz:   .dw	     64,128,256,512, 1024,2048,4096
;tabz:   .dw	     32,64,128,256,512,1024,2048
;tabz:   .dw	     16,32,64,128,256,512,1024
tabz:   .dw	     4,8,16,32,64,128,256
; **********************************
; Таблица коэффициентов деления

tabkd:	.dw 0
;		.dw 304,286,270,256,242,228,214,202,192,180,170,160
;		.dw 152,144,136,128,120,114,108,102,96,90,86,80
;		.dw 76,72,68,64,60,58,54,50
		.dw 152,143,135,128,121,114,107,101,97,90,85,80
		.dw	 76,72,68,64,60,57,54,51,48,45,43,40
		.dw 38,36,34,30,29,27,25



; **********************************
; Таблица начал всех мелодий

tabm:	.dw	mel1*2,mel2*2,mel3*2


; **********************************
; Таблица мелодий

mel1: ;.db 137,142,110,111,110,108,138,138,138,143,111,113,112,255
.db 109,109,143,141,146,177,109,109,143,141,148,178,109,109,153,150,146,145,143,119,119,150,146,148,178,109,109
.db 143,141,146,177,109,109,143,141,148,178,109,109,153,150,146,145,143,119,119,150,146,148,178,109,109,178,255




mel2:	.db 77,77,255

mel3:	.db 77,78,79,255
