.INCLUDE	"2313def.inc"
.DEF	Step=r20
.DEF	FreqIndex=r21
.DEF	FreqDelay=r22
.DEF	SSREG=r23

.CSEG

.ORG	0
	rjmp	Reset

.ORG	OVF0addr
	in	SSREG,SREG
	dec	FreqDelay
	out	SREG,SSREG
	reti

Reset:
	ldi	r30,$DF
        out	SPL,r30
	; настройка направления работы линий порта B
	ldi	r30,$08
	out	DDRB,r30
	; режим работы таймера 0 с максимальным предварительным делением
	; здесь же разрешаем прерывания
	ldi	r30,$05
	out	TCCR0,r30
	ldi	r30,$02
	out	TIMSK,r30
	sei
	; режим работы таймера 1 на переключение внешнего вывода,
	; выбор коэффициента предварительного деления тактовой частоты 1:1
	; и автоматический сброс таймера при совпадении
        ldi	r30,$40
        out	TCCR1A,r30
        ldi	r30,$09
        out	TCCR1B,r30
	; установка номера шага на начало
	clr	Step



ReadNote:	; чтение длительности и номера одной ноты
	ldi	r31,High(2*ProgramTab)	; FreqIndex = Lo ProgramTab[Step]
	ldi	r30,Low(2*ProgramTab)	; FreqDelay = Hi ProgramTab[Step]
	mov	r0,Step                 ; Step++
	lsl	r0
	add	r30,r0
	inc	Step
	lpm
	mov	FreqIndex,r0
	inc	r30
	lpm
	sbrc	r0,7
	rjmp	SleepReset		; если старший бит установлен, то
	mov	FreqDelay,r0            ; это означает что мелодия закончилась

		
SetFreq:        ; настройка таймера 1 на вывод частоты текущей ноты
	ldi	r31,High(2*SoundTab)	; OCR1A = SoundTab[FreqIndex]
	ldi	r30,Low(2*SoundTab)
	lsl	FreqIndex
        add	r30,FreqIndex
        lpm

;      out	OCR1AL,r0	; Закоментареный блок заменен блоком ниже
;      inc	r30		; ошибку нашел и исправил
;      lpm			; Сергей Романец. Вильнюс, Литва.
;      out	OCR1AH,r0

       mov	r16,r0
       inc	r30
       lpm
       out	OCR1AH,r0
       out	OCR1AL,r16



Wait:	tst	FreqDelay	; Ожидаем заданное время пока проигрывается
	brne	Wait		; текущая нота
	rjmp	ReadNote

SleepReset:
        ldi	r30,$3F		; подготовка к переходу в режим Power Down
        out	MCUCR,r30
	sleep			; отключение микроконтроллера
	rjmp	Reset		; эта команда в данной версии программы не 
				; должна исполнятся никогда

.ORG	$100
SoundTab:
; Таблица констант соответствующим нотам.
; Желательно выровнять таблицу по границе 256 байт, чтобы упростить программу
; отказавшись от операций с 16 битными словами.
.DW 11364,10292,9322,8443,7647,6926,6273    ; 440 Гц - нота "ля"
.DW 5682,5146,4661,4222,3824,3463,3137      ; вторая октава
.DW 2841,2573,2330,2111,1912,1732,1568      ; третья октава
; при необходимости таблицу можно продолжить.


ProgramTab:
; Таблица последовательности нот,
; формат таблицы: байт длительности/кода операции, байт номера частоты.
; В этом примере записано проигрывание гаммы.
.DW	$1001, $1002, $1003, $1004, $1005, $1006, $1007
.DW	$1008, $1009, $100A, $100B, $100C, $100D, $100E
.DW	$200D, $200B, $2009, $2007, $2005, $2003, $2001
.DW	$8000


.EXIT

