;---------------------------------------------------------------------------------------
;                  Программа звонок
;---------------------------------------------------------------------------------------
		LIST p=16f84
;---------------------------------------------------------------------------------------
;Константы
;---------------------------------------------------------------------------------------
W		EQU     H'0000'		;Результат поместить в W
F		EQU     H'0001'		;Результат поместить в F

;------------- STATUS Bits ------------------
IRP                          EQU     H'0007'
RP1                          EQU     H'0006'
RP0                          EQU     H'0005'
NOT_TO                       EQU     H'0004'
NOT_PD                       EQU     H'0003'
Z                            EQU     H'0002'
DC                           EQU     H'0001'
C                            EQU     H'0000'
;--------------------------------------------

;------------- INTCON Bits ------------------
GIE                          EQU     H'0007'
EEIE                         EQU     H'0006'
RTIE                         EQU     H'0005'
INTE	                     EQU     H'0004'
RBIE			     EQU     H'0003'
RTIF                         EQU     H'0002'
INTF                         EQU     H'0001'
RBIF                         EQU     H'0000'
;--------------------------------------------

;---------------- REG_FL --------------------
Fl_Res_Ring                  EQU     H'0002'
Fl_Open                      EQU     H'0001'
Fl_Ring                      EQU     H'0000'
;--------------------------------------------


M_O_INIT	EQU	0x04		;0000.0100b - инициализация OPTION
M_TB_INIT	EQU	0xFD		;1111.1101  - инициализация TRISB
M_I_INIT	EQU	0x98		;1001.1000  - инициализация INTCON

M_RAND		EQU	0xF0		;1111.0000  - маска для случ. числа
M_Dl		EQU	0x07		;0000.0111  - маска для длительности

M_STR0		EQU	0x00		;Страница 0
M_STR1		EQU	0x01		;Страница 1
M_STR2		EQU	0x02		;Страница 2
M_STR3		EQU	0x03		;Страница 3

REZ		EQU	H'0001'		;Вывод к которому подключен динамик

Dl_Pause	EQU	0x01		;Длительность паузы между нотами
Wait_D		EQU	0x5A		;Время ожидания открытия двери (Wait_D*2 сек)

;---------------------------------------------------------------------------------------
;				Таблица векторов
;---------------------------------------------------------------------------------------
VECTOR		CODE
		GOTO	Reset		;Вектор сброса
		RES	3
		GOTO	Int_Prog	;Вектор прерывания
;---------------------------------------------------------------------------------------

;---------------------------------------------------------------------------------------
;				Таблица длительностей
;---------------------------------------------------------------------------------------
Tab_Dl		CODE

Dlit		ADDWF	PCL,F
		DT	0xF4,0x7A,0x3D,0x1E,0x0F
;---------------------------------------------------------------------------------------

;---------------------------------------------------------------------------------------
;					Таблица нот
;---------------------------------------------------------------------------------------
Tab_Note	CODE

R_Note		ADDWF	PCL,F
		DT	0xFB,0xEA,0xDA,0xCB
		DT	0xBC,0xAF,0xA2,0x96,0x8B,0x81,0x76,0x6D,0x64,0x5C,0x54,0x4C
		DT	0x45,0x3E,0x38,0x32,0x2C,0x27,0x22,0x1D,0x19,0x15,0x11,0x0D
		DT	0x09,0x06,0x03,0x00
;---------------------------------------------------------------------------------------

;---------------------------------------------------------------------------------------
;				Таблица коррекции нот
;---------------------------------------------------------------------------------------
Cor_Note	CODE

C_Note		ADDWF	PCL,F
		DT	0x00,0x01,0x01,0x01
		DT	0x07,0x04,0x07,0x07,0x05,0x00,0x07,0x04,0x04,0x00,0x01,0x04
		DT	0x04,0x06,0x03,0x04,0x06,0x04,0x04,0x06,0x02,0x00,0x00,0x02
		DT	0x06,0x03,0x02,0x02
;---------------------------------------------------------------------------------------

;---------------------------------------------------------------------------------------
;Блок основной программы
;---------------------------------------------------------------------------------------
Main_Prog	CODE

;---------------------------------------------------------------------------------------
;				Подпрограмма задержки
;---------------------------------------------------------------------------------------
;Delay=(8Note+W+400) mkc
;------------------------
Del_Ed		
		SUBLW	0x07	;(7-KOR) -> W
		ADDWF	PCL,F
		NOP		;KOR
		NOP
		NOP
		NOP
		NOP
		NOP
		NOP		;KOR
		INCF	Note,W
		MOVWF	TEMP1	;(Note+1) -> TEMP1
Del_Ed1
		DECFSZ	TEMP1,F	;(3Note+2) mkc
		GOTO	Del_Ed1
		INCF	Note,W	;(Note+1) -> TEMP1
		MOVWF	TEMP1
Del_Ed2
		DECFSZ	TEMP1,F	;(5Note+4) mkc
		GOTO	Del_Ed3
		GOTO	Del_Ed4
Del_Ed3
		GOTO	Del_Ed2
Del_Ed4
		MOVLW	0x7E	;381 mkc
		MOVWF	TEMP1
Del_Ed5
		DECFSZ	TEMP1
		GOTO	Del_Ed5
		NOP
		NOP
		RETURN
;---------------------------------------------------------------------------------------

;---------------------------------------------------------------------------------------
;   Инициализация
;---------------------------------------------------------------------------------------
Reset
		CLRWDT			;Очистить сторожевой таймер и делитель
		BANKSEL	OPTION_REG
		MOVLW	M_O_INIT
		MOVWF	OPTION_REG	;Инициализация OPTION
		BCF	PORTB,REZ	;Инициализация PORTB
		MOVLW	M_TB_INIT
		MOVWF	TRISB		;Инициализация TRISB
		MOVLW	M_I_INIT
		MOVWF	INTCON		;Инициализация INTCON
		CLRF	REG_FL		;REG_FL=0

;---------------------------------------------------------------------------------------
;Основной код
;---------------------------------------------------------------------------------------
Lab1
		BTFSC	REG_FL,Fl_Ring		;Fl_Ring=0 ?
		GOTO	Lab2			;нет
		BTFSS	REG_FL,Fl_Open		;Fl_Open=0 ?
		GOTO	Lab1			;да
		BTFSS	REG_FL,Fl_Res_Ring	;Fl_Res_Ring=0 ?
		GOTO	Lab5			;да
		BANKSEL	RTCC
		MOVF	RTCC,W			;Считать случайное число
		ANDLW	M_RAND			;В W - номер мелодии
		BCF	INTCON,INTE		;Запрет INT
		CALL	PLAY			;Играть мелодию
		BCF	INTCON,INTF		;Сброс флага запроса INT
		BSF	INTCON,INTE		;Разрешить INT
		BCF	REG_FL,Fl_Res_Ring	;Fl_Res_Ring=0
Lab5
		BCF	REG_FL,Fl_Open		;Fl_Open=0
		GOTO	Lab1
Lab2
		BCF	REG_FL,Fl_Open		;Fl_Open=0
		BSF	REG_FL,Fl_Res_Ring	;Fl_Res_Ring=1
		BANKSEL	RTCC
		MOVF	RTCC,W			;Считать случайное число
		ANDLW	M_RAND			;В W - номер мелодии
		BCF	INTCON,INTE		;Запрет INT
		CALL	PLAY			;Играть мелодию
		BCF	INTCON,INTF		;Сброс флага запроса INT
		BSF	INTCON,INTE		;Разрешить INT
		BCF	REG_FL,Fl_Ring		;Fl_Ring=0
		MOVLW	Wait_D
		MOVWF	TEMP1			;TEMP1=Wait_D
		BSF	INTCON,RTIE		;Разрешить TIMER
Lab3
		CLRF	Dl_Note			;Dl_Note=0
Lab4
		MOVF	Dl_Note,W
		SUBLW	0xFF
		BTFSS	STATUS,Z		;Dl_Note=0xFF ?
		GOTO	Lab6			;нет
		DECFSZ	TEMP1,F			;(TEMP1-1) = 0 ?
		GOTO	Lab3			;нет
		BCF	INTCON,RTIE		;Запретить TIMER
		BTFSS	REG_FL,Fl_Open		;Fl_Open=0 ?
		GOTO	Lab1			;да
		BCF	REG_FL,Fl_Open		;Fl_Open=0
		BCF	REG_FL,Fl_Res_Ring	;Fl_Res_Ring=0
		GOTO	Lab1
Lab6
		BTFSS	REG_FL,Fl_Ring		;Fl_Ring=0 ?
		GOTO	Lab4			;да
		BCF	INTCON,RTIE		;Запретить TIMER
		GOTO	Lab2

;---------------------------------------------------------------------------------------
;				Подпрограмма PLAY
;---------------------------------------------------------------------------------------
; W 	 - номер мелодии
; Melody - таблица мелодий
; Dlit   - таблица длительностей
; R_Note - таблица нот
;---------------------------------
PLAY
		MOVWF	N_Note		;W -> N_Note
		BCF	STATUS,C	;C=0
		RLF	N_Note,F	;В N_Note адрес 1 ноты выбранной мелодии
		BTFSC	STATUS,C	;Перенос ?
		GOTO	STR_3		;Да
		MOVLW	M_STR2		;Нет. Установить стр.2
		MOVWF	REG_STR
		GOTO	L_PLAY1
STR_3
		MOVLW	M_STR3		;Установить стр.3
		MOVWF	REG_STR
L_PLAY1
		CLRF	Dl_Note		;Dl_Note = 0
		MOVF	REG_STR,W	;Выбор страницы
		MOVWF	PCLATH
		MOVF	N_Note,W	;Номер ноты в W
		CALL	Melody		;Считать ноту
		MOVWF	TEMP1		;Сохранить ноту в TEMP1
		XORLW	0x07
		BTFSC	STATUS,Z	;Конец мелодии ?
		GOTO	END_PLAY	;Да
		MOVLW	M_STR0		;Установка страницы 0
		MOVWF	PCLATH
		MOVLW	M_Dl		;Выделить длительность
		ANDWF	TEMP1,W
		CALL	Dlit		;Считать код длительности
		MOVWF	Dl		;и поместить его в Dl
		BCF	STATUS,C	;Выделить ноту
		RRF	TEMP1,F
		BCF	STATUS,C
		RRF	TEMP1,F
		BCF	STATUS,C
		RRF	TEMP1,F
		MOVF	TEMP1,W
		CALL	C_Note
		MOVWF	Correct		;Поместить коррекцию в Correct
		MOVF	TEMP1,W
		CALL	R_Note
		MOVWF	Note		;Поместить ноту в Note
		BANKSEL	RTCC
		CLRF	RTCC		;Очистить таймер
		BSF	INTCON,RTIE	;Разрешить прерывание от таймера
		CLRF	RTCC		;Очистить таймер
L_PLAY2
		BANKSEL	PORTB
		BSF	PORTB,REZ	;1 -> PORTB,REZ
		MOVF	Correct,W
		CALL	Del_Ed		;Задержка
		BCF	PORTB,REZ	;0 -> PORTB,REZ
		MOVF	Correct,W
		CALL	Del_Ed		;Задержка
		MOVF	Dl,W
		SUBWF	Dl_Note,W	;(Dl_Note-Dl) -> W
		BTFSS	STATUS,C	;Dl_Note >=Dl
		GOTO	L_PLAY2		;Нет
		CLRF	RTCC		;Очистить таймер
		CLRF	Dl_Note		;Dl_Note=0
L_PLAY3
		MOVLW	Dl_Pause	;Выдержать паузу между нотами
		SUBWF	Dl_Note,W	;(Dl_Note-Dl_Pause) -> W
		BTFSS	STATUS,C	;Dl_Note >=Dl
		GOTO	L_PLAY3		;Нет
		BCF	INTCON,RTIE	;Запрещение прерывания от таймера
		INCF	N_Note,F	;Следующая нота
		GOTO	L_PLAY1
END_PLAY		
		RETURN
;---------------------------------------------------------------------------------------

;---------------------------------------------------------------------------------------
;				Обработчик прерывания
;---------------------------------------------------------------------------------------
Int_Prog
		BTFSS	INTCON,INTF	;Ring ?
		GOTO	INT_1		;нет
		BTFSS	INTCON,INTE	;Запрещено INT ?
		GOTO	INT_1		;Да
		BCF	INTCON,INTF	;Сброс запроса "звонок"
		BSF	REG_FL,Fl_Ring	;Fl_Ring=1
		RETFIE
INT_1
		BTFSS	INTCON,RBIF	;Open ?
		GOTO	INT_2		;нет
		BTFSS	INTCON,RBIE	;Запрещено RBI ?
		GOTO	INT_2		;Да
		MOVF	PORTB,F		;Сброс запроса "open"
		BCF	INTCON,RBIF	
		BSF	REG_FL,Fl_Open	;Fl_Open=1
		RETFIE
INT_2
		BTFSS	INTCON,RTIF	;Переполнение таймера ?
		GOTO	END_INT		;нет
		BTFSS	INTCON,RTIE	;Запрещено RTI ?
		GOTO	END_INT		;да
		BCF	INTCON,RTIF	;Сброс флага переполнения таймера
		INCF	Dl_Note,F	;Dl_Note=Dl_Note+1
END_INT
		RETFIE
;---------------------------------------------------------------------------------------

;---------------------------------------------------------------------------------------
;				Таблица мелодий
;---------------------------------------------------------------------------------------
		CODE	0x1FF
Melody		ADDWF	PCL,F

Melody_1	CODE
		DT 0x7A,0x83,0x92,0xA2,0x82,0x6A,0xA2,0x93,0x83,0x7A,0x83,0x92,0xA2
		DT 0x82,0x6A,0x69,0x07
Melody_2	CODE
		DT 0x32,0x43,0x4A,0x5B,0x6A,0x4B,0x32,0x82,0x93,0x82,0x73,0x6A,0x5B
		DT 0x4A,0x42,0x5B,0x92,0x73,0x6A,0x5B,0x4A,0x43,0x4B,0x5A,0x23,0x69
		DT 0x07
Melody_3	CODE
		DT 0xA2,0x9C,0xA4,0xAB,0xA3,0x83,0x84,0x7C,0x6A,0x83,0xA3,0xA3,0xCA
		DT 0xA3,0xBB,0xB3,0xAA,0x07
Melody_4	CODE
		DT 0x69,0x4B,0x5B,0x69,0x5B,0x6B,0x8B,0xAA,0xA3,0x91,0x6B,0x93,0xAB
		DT 0x8A,0x93,0xA3,0x93,0x73,0xA2,0x93,0x5B,0x6B,0x8B,0xAA,0xA3,0x91
		DT 0x07
Melody_5	CODE
		DT 0x42,0x83,0x6B,0x7A,0x6B,0x5B,0x53,0x6B,0x5B,0x53,0x5A,0x42,0x42
		DT 0x83,0x6B,0x7A,0x6B,0x5B,0x53,0x6B,0x5B,0x53,0x42,0x07
Melody_6	CODE
		DT 0x33,0x4B,0x6A,0x33,0x93,0x93,0x83,0x73,0x6B,0x4B,0x31,0x4B,0x5B
		DT 0x6A,0x6B,0x83,0x73,0x43,0x5B,0x49,0x07
Melody_7	CODE
		DT 0x6B,0x92,0x93,0x93,0x93,0x8B,0x93,0xA2,0x8B,0x6A,0x6B,0xAA,0x92
		DT 0x4B,0x4B,0x5B,0x5B,0x69,0x07
Melody_8	CODE
		DT 0x32,0x59,0x53,0x5B,0x6A,0x52,0x32,0x69,0x5B,0x6B,0x7A,0x5A,0x5A
		DT 0x81,0x6B,0x83,0x7A,0x5A,0x7A,0x6A,0x52,0x32,0x59,0x07
Melody_9	CODE
		DT 0x33,0x33,0x5A,0x53,0x6B,0x5B,0x5A,0x52,0x33,0x33,0x82,0x6B,0x93
		DT 0x83,0x79,0x5B,0x5B,0xA2,0x93,0x83,0xA3,0x92,0x7A,0x33,0x33,0x7A
		DT 0x6B,0x83,0x53,0x59,0x07
Melody_10	CODE
		DT 0x22,0x23,0x32,0x23,0x69,0x6A,0x6B,0x72,0x6B,0x31,0x32,0x43,0x5B
		DT 0x4B,0x33,0x21,0x23,0x43,0x5B,0x72,0x43,0x49,0x07
Melody_11	CODE
		DT 0x5A,0x59,0x42,0x4A,0x42,0x32,0x21,0x42,0x5A,0x4A,0x42,0x59,0x32
		DT 0x4A,0x42,0x32,0x21,0x22,0x21,0x07
Melody_12	CODE
		DT 0x5A,0x42,0x4A,0x32,0x42,0x22,0x32,0x22,0x32,0x42,0x21,0x22,0x42
		DT 0x4A,0x32,0x42,0x22,0x32,0x22,0x32,0x42,0x21,0x07
Melody_13	CODE
		DT 0xAB,0xAB,0xA3,0xA3,0x93,0x93,0x93,0xA3,0xAB,0xAB,0xA3,0xA3,0x92
		DT 0x92,0x83,0x83,0x7B,0x7B,0x6B,0x6B,0x6B,0x7B,0x83,0x83,0x7B,0x7B
		DT 0x6A,0x6A,0x07
Melody_14	CODE
		DT 0x7B,0x7B,0xBA,0xB2,0xA1,0xAB,0xAB,0xA2,0x93,0x84,0x7C,0x69,0xA3
		DT 0xA3,0x92,0xA3,0x94,0x84,0x7A,0x92,0x5B,0x5B,0x6A,0x7A,0xA1,0x07
Melody_15	CODE
		DT 0xA1,0xAA,0xCB,0xA1,0x6B,0x7B,0x82,0xA3,0x7A,0x83,0x69,0x6B,0x59
		DT 0xBA,0xCB,0xB9,0xA1,0xA3,0xA1,0x92,0x83,0xA1,0x07
Melody_16	CODE
		DT 0x41,0x4A,0x43,0x81,0x7B,0x6B,0x61,0x7B,0x63,0x41,0x41,0x4A,0x43
		DT 0x91,0x83,0x7B,0x69,0x82,0x93,0xA2,0x07
;---------------------------------------------------------------------------------------

;---------------------------------------------------------------------------------------
Page_0		UDATA
INDIR		RES	1
RTCC		RES	1
PCL		RES	1
STATUS		RES	1
FSR		RES	1
PORTA		RES	1
PORTB		RES	1
		RES	1
EEDATA		RES	1
EEADR		RES	1
PCLATH		RES	1
INTCON		RES	1
;---------------------------------------------------------------------------------------
		
;---------------------------------------------------------------------------------------
Page_1		UDATA
		RES	1
OPTION_REG	RES	1
		RES	3
TRISA		RES	1
TRISB		RES	1
		RES	1
EECON1		RES	1
EECON2		RES	1
		RES	2
;---------------------------------------------------------------------------------------

;---------------------------------------------------------------------------------------
;Переменные программы
;---------------------------------------------------------------------------------------
RON		UDATA
REG_FL		RES	1	;Флаги: звонок,открыли дверь,сброс звонка
N_Note		RES	1	;Номер ноты
REG_STR		RES	1	;Регистр страницы
Dl_Note		RES	1	;Фактическая длительность ноты
Dl		RES	1	;Заданная длительность ноты
Note		RES	1	;Нота
TEMP1		RES	1	;Регистр временного хранения
Correct		RES	1	;Коррекция ноты
;---------------------------------------------------------------------------------------

;---------------------------------------------------------------------------------------
;				Конфигурация процессора
;---------------------------------------------------------------------------------------
CONFIG		CODE
		DW 0x3FF1	;XT,WDT - Off,PWRTE - On,CP - Off
;---------------------------------------------------------------------------------------
;				Индивидуальная метка
;---------------------------------------------------------------------------------------
IDLOCS		CODE
		DW 0x3FFF
		DW 0x3FFF
		DW 0x3FFF

		END

