;Часы на ОЭВМ 89с2051
;Штепенко Евгений (с)2005г beta 2.1

                .linklist
		.symbols
		.chip 8051
;10,11,12,13 indic
hou:	.equ 14h	;часы
min:	.equ 15h	;минуты
;16 своб
sec:	.equ 17h	;сек
hb1:	.equ 18h	;ч буд1
mb1:	.equ 19h	;м буд1
rb1:	.equ 1ah	;реж буд1
onn:	.equ 1bh	;время зажж сост индик
hb2:	.equ 1ch	;ч буд2
mb2:	.equ 1dh	;м буд2
rb2:	.equ 1eh	;реж буд2
off:	.equ 1fh	;время выкл сост индик
hb3:	.equ 20h	;ч буд3
mb3:	.equ 21h	;м буд3
rb3:	.equ 22h	;реж буд3
msc:	.equ 23h
hb4:	.equ 24h	;ч буд4
mb4:	.equ 25h	;м буд4
rb4: 	.equ 26h	;реж буд4

flg:	.equ 27h	;флаги:
pri	.reg 27h.0	;=1 если было прерыв
aex	.reg 27h.1	;=1 автовыход
nhou	.reg 27h.2	;=1 начало часа
k_on	.reg 27h.3	;=1 признак наж кн для автовозвр
nmin	.reg 27h.4	;=1 если началась нов минута
a_pvt	.reg 27h.5	;=1 если автоповтор
p_on	.reg 27h.6	;=1 включ повтора буд
p_bud	.reg 27h.7	;=1 пр повтора буд
mdi:	.equ 28h	;режим индикации
nopl:	.reg 29h.0
nsec:	.reg 29h.1
crr:	.reg 29h.2
nmus:	.equ 2ah	;
;--cold reset

day:	.equ 2bh	;день недели
zer:	.equ 2ch	;зеркало порта Р3
au_ex:	.equ 2dh	;сч времени до автовыхода
bf1:	.equ 30h	;буферы
bf2:	.equ 31h
bf3:	.equ 32h
not1:	.equ 33h	;длит 0
not2:	.equ 34h	;длит 1 в звуке
;35h
t10:	.equ 36h	;сч вр до повтора буд
npr:	.equ 37h	;номер прерывания для дробного коэф
kdl:	.equ 38h	;мл байт коэф
kdh:	.equ 39h	;ст байт коэф
kd:	.equ 3ah	;раб ячейка в пп коррекции
ton:	.equ 3bh	;тональность
bfa:	.equ 3ch	;буфер для акком
buff:	.equ 3dh	;буфер
msk:	.equ 3eh	;маска для пп установки
bkey:	.equ 3fh	;посл нажатая кнопка
nbud:	.equ 40h	;номер будильника
tpk:	.equ 41h
sm_dl:	.equ 42h
sm_tn:	.equ 43h
dlt:	.equ 44h
t30s:	.equ 45h
kyon:	.equal 20h	;
auto:	.equal 20d	;время до автовыхода,сек
alrm:	.equal 35d	;время пиканья будильника в авар реж,сек
tzdk:	.equal 05d
z_auto	.equal 37d 

	mov p3,#efh
	mov psw,#00h
	mov tmod,#01h
	ajmp begin

;прерывание - счет текущего времени
	.org 000bh
int:	push psw	;2 сохр рег призн
	jnb crr,nreg	;2

	clr crr
	clr tcon.4
	mov bfa,a	;1 сохр А
        mov a,tl0	;1 текущ знач мл от таймера	
	add a,kdl	;1 суммир со старт знач мл
	mov tl0,a	;1 назад
	mov a,th0	;1 текущ знач ст
	addc a,kdh	;1 суммир со старт знач ст 
	mov th0,a	;1 назад
	setb tcon.4
	mov a,bfa	;восст А
	sjmp reg0			

nreg:	mov th0,#86h	;2
reg0:	inc msc
	jnb msc.5,exi	;2 

int0:	mov bfa,a
	mov msc,#0h	;восст сч прер
	inc sec		;сек+1
	setb nsec
	djnz npr,int2
	mov npr,#09h
	setb crr
int2:	jnb a_pvt,int3
	djnz tpk,int3
	mov tpk,#01h
int3:	djnz au_ex,intt00;время до автовых
	setb aex	;уст пр автовыхода
intt00: djnz t30s,intt01
	mov t30s,#30d
	jnb p_on,intt01
	setb nmin
intt01	mov a,sec	;чит сек
	clr c		;сбр перен
	subb a,#60d	;уже 60сек
	jc exit		;нет-вых
	mov sec,#00h	;обнул сек
	mov t30s,#30d
	setb nmin	;призн нов мин
	clr p_on
	jnb p_bud,intt1;пр будильн
	inc t10
	mov a,t10
	cjne a,#05h,intt1
	setb p_on
	clr p_bud
intt1:	inc min		;мин+1
	mov a,min	;чит мин
	clr c		;сбр с
	subb a,#60d	;уже 60 мин
	jc exit		;нет-вых
	mov min,#00h	;обн мин
	inc hou		;час+1
	setb nhou	;начало часа
        mov a,hou       ;чит час
	clr c		;обн перенос
	subb a,#24d	;уже 24 часа
	jc exit		;нет-вых
	mov hou,#00h	;обн час
	mov a,day	;чит день нед
	rl a		;сдвиг
	mov day,a	;назад
	jnb a.7,exit	;не воскр-вых
	mov day,#01h	;понед
exit:	mov a,bfa
exi:	pop psw		;восст рег призн
	setb pri	;признак прер
	reti		;вых


;пп расчета яркости индикатора
briht:	mov a,hou
	mov off,#01h	;загруж исходно высокую ярк
	mov onn,#00h
	clr c		;сбр призн переноса
	subb a,#05d	;нижняя граница
        jc brihn1	;проверяем
	mov a,#22d	;верхняя граница
	clr c		;сбр флага
	subb a,hou
        jnc brihn2	;проверяем
brihn1:	mov off,#9fh	;уст пониж яркость
	mov onn,#60h
brihn2: ret		;выход

too:	anl a,#0fh
	movc a,@a+dptr	
	mov @r0,a
	inc r0
	ret

;пп уст коррекции
korr:	clr a		;зажигаем все!
	mov 10h,a
	mov 11h,a
	mov 12h,a
	mov 13h,a
	inc a		;а=1
	mov mdi,a	;блк повторный вход в режим
korr11:	mov ton,#40h	;тональность
	acall piik	;пищим
	mov ton,#60h	;ниже тональность
	acall piik	;пищим
	acall key	;опр кнопки
	jnz korr11	;не отпустили? еще пищим
	mov dptr,#znak	;начало знакогенератора
	
k2	mov r0,#10h	;начало индик
	mov a,kdh	;ст байт коэф
	swap a		;ст часть
	acall too	;на индик
	mov a,kdh	;ст байт коэф
	acall too	;мл часть
	mov a,kdl	;мл байт коэф
	swap a		;ст часть
	acall too	;на индик
	mov a,kdl	;мл байт коэф
	acall too	;мл часть
		
k21:	acall indic	;индикация
	jb aex,back	;автовыход
	acall keyb	;опрос кн
	mov r2,#1h	;вычитаемое
	mov r3,tpk	;опр время наж кнопку
	cjne r3,#01h,k22;прошло 10 сек
	mov r2,#10h	;новое вычитаемое
k22:	jb a.1,mn	;-1
	jb a.0,pl	;+1
	sjmp k21	;на начало пп

back:	ajmp main1	;выход

mn:	clr c		;сбр флага
	mov a,kdl	;мл часть
	subb a,r2	;вычит 1
	mov kdl,a	;на место
	mov a,kdh	;ст часть
	subb a,#00h	;вычит бит переноса
	mov kdh,a	;на место
	jnz k2		;был заем?
	mov kdl,#ffh	;уст мл=ffH
	sjmp k2		;назад

pl:	mov a,kdl	;мл байт коэф
	add a,r2	;суммируем
	mov kdl,a	;назад мл часть
	mov a,kdh	;ст байт
	addc a,#00h	;суммир бит переноса
	mov kdh,a	;назад
	cjne a,#ffh,k2p	;не переполнилось? 
	mov kdl,#00h	;мл часть сбрасыв
k2p:	ajmp k2		;переход

;======= ХОЛОДНЫЙ СТАРТ ===========
begin:	mov ie,#82h	;режим прерыв
	setb tcon.4	;пуск таймера
	mov au_ex,#auto ;время до автовых
	acall clrscr	;очс индик
	acall key	;опрос кнопок
	jb a.0,reset	;если была наж -сброс
	
gonx:	mov r0,#hou	;начало инф
res1:	mov a,@r0	;пров часы
	clr c		;сбр флажка
	subb a,#24d	;проверяем
	jc nres		;дальше

;пп сброса информации
reset:	mov r0,#14h	;нач адр инф
res2:	mov @r0,#00h	;уничтож
	inc r0		;сл адрес
        cjne r0,#2bh,res2;уже конец
        mov day,#01h    ;понед
	clr a
	mov dptr,#tkf	;табл коэф
	movc a,@a+dptr
	mov kdh,a	;старший
	mov a,#01h
	movc a,@a+dptr
	mov kdl,a     	;младший
	mov ton,#60h
	acall piik  	;пищим низким тоном
        sjmp main1	;на начало

nres:	inc r0		;сл яч
	mov a,@r0	;проверим минуты
	clr c
	subb a,#60d	;проверяем
	jnc reset	;неправильно-переход
	inc r0		;сл яч
	mov a,@r0	;режим
	clr c
	subb a,#04h
	jnc reset
	inc r0		;сл яч
	inc r0		;сч яч
	cjne r0,#28h,res1;уже все?

main1:  mov sp,#60h	;стек на место
	mov t30s,#30d	;восст сч 30 сек
	mov zer,#efh    ;зеркало Р3
	mov mdi,#00h	;режим индик
	mov ton,#40h	;тональность
	clr nhou	;сбр пр начала часа
	acall clrscr	;очистка индикатора
	acall piik	;пищим
	acall briht	;уст яркости
	setb k_on	;признак наж кн
	ajmp main       ;старт

;пп очистки индикатора
clrscr:	mov r0,#10h	;нач адр индикатора
cl0:	mov @r0,#ffh	;очищаем
	inc r0		;сл яч
	cjne r0,#14h,cl0;уже все?
	ret		;выход


;п/п индикации выв буф 10Н-13Н на индикатор
indic:	acall ups	;проверим ист пит
indics:	mov bf1,r1	;сохр
	mov r1,#10h	;адр буф индик
	mov r2,#7fh	;упр слово для дин инд
ind0:	mov a,r2	;тек разр
	rl a		;сдвиг
	mov r2,a	;запомним
	anl a,zer	;с зеркалом
	orl a,#a0h	;входы ост в 1
	mov p3,a	;на порт
	mov a,@r1	;чит сод буф
	mov p1,a	;в рег сегментов
	mov r7,onn	;время зажж сост
	djnz r7,$
	mov p1,#ffh	;выкл сегм
	mov r7,off	;время выкл сост
	djnz r7,$
	inc r1		;сл яч буф
	cjne r1,#14h,ind0;уже все
	mov r1,bf1	;восст
	ret		;вых


;п/п размещ на индик день нед
dned:	mov dptr,#d_ned	;таблица зн д.нед
	mov r2,#00h	;счетчик обн
	mov a,day	;текущ день нед
d_1:	jb a.0,d_0	;цикл до ближ 1
	rr a		;сл бит
	inc r2		;+ сч
	sjmp d_1	;еще нет
d_0:	mov a,r2	;здесь получ номер дня
	rl a		;умн на 2
	mov r2,a	;сохр
	movc a,@a+dptr	;чит перв знак
	mov 10h,a	;на индик
	mov a,r2	;восст
	inc a		;+1
	movc a,@a+dptr	;чит втор знак
	mov 11h,a	;на индик
	ret		;вых

;п/п установки дня недели
sd1:	acall indic	;индикац
	acall clrscr	;очищ индикатор
	acall dned	;размещ инф
	acall keyb	;опр кн
	jb a.0,sd3	;по кн1 перекл день
	jb a.1,d_nd	;по кн2 назад
	jnb msc.3,sd1	;мигающий бит 2 Гц
	acall clrscr	;гасим
	sjmp sd1	;цикл
sd3:	mov a,day	;текущ день
	rl a		;перекл
	mov day,a	;назад
	jnb a.7,sd1	;если было воскр
	mov day,#01h	;то понед
	sjmp sd1	;назад

;пп индикация дня недели
d_nd:  	acall clrscr	;очистим индикатор
	acall dned	;день нед
	acall keyb	;опр кн
	jb a.0,selmod	;по mode след реж
	jb a.1,sd1	;на уст дня
	ajmp comm	;цикл

;пп установки часов
setcl:	mov r1,#hou	;адрес нач инф тек вр
	acall toind	;размещаем
	anl 11h,#7fh	;зажиг точку постоянно
	mov r0,#10h	;место для мигания
	mov r1,#hou	;начало инф тек вр
	mov msk,#24d	;ограничение
	acall setmod	;установка
	jb a.1,nset	;по set - на уст минут
	acall indic	;индикация
	sjmp setcl	;цикл
nset:	mov r1,#hou	;нач инф
	acall toind	;размещаем
	anl 11h,#7fh	;точка
	mov r0,#12h	;место для мигания
	mov r1,#min	;минуты для уст
	mov msk,#60d	;ограничение
	acall setmod	;установка
	jb a.1,nset1	;по set-выход
	acall indic	;индикация
	sjmp nset	;цикл
nset1:	acall briht	;по выходу установка яркости

;пп тек времени
t_vr:	mov r1,#hou	;адрес начала инф
        acall toind	;размещаем
        jnb msc.4,t_v0	;мигающий бит
        anl 11h,#7fh	;точка
t_v0:	acall keyb	;опр кнопки
        jb a.0,selmod	;по mode-перекл реж
        jb a.1,setcl	;по set-установка часов
	ajmp comm	;цикл

;пп индикации секунд
m_sec:  acall clrscr	;очистка индик
	mov r0,#12h	;место на индикаторе
	mov a,sec	;чит секунды
	acall hexdec	;размещаем
	anl 11h,#7fh	;зажиг точку
        acall keyb	;опрос кнопок
        jb a.0,selmod	;по mode-перекл режима
	acall kkey2	;быстрый опрос кн set
	jnc clrms	;по наж-сброс секунд
        sjmp comm1	;цикл

;пп сброса секунд
clrms:	mov sec,#00h	;секунды в 0
	mov msc,#00h	;доли сек в 0
        sjmp comm1	;цикл

mainn:	mov mdi,#00h	;реж текущ вр
	clr aex		;сбр пр автовых
        sjmp main	;на гор старт

d_ndp:	ajmp d_nd	;длинный переход

;пп перекл режима
s_mod:	mov a,@r1	;счит режим
	jnz tbud	;не нулевой-на вр буд
selmod:	inc mdi		;переключ режима
	anl mdi,#07h	;ограничиваем
comm:   jb aex,mainn	;автовыход
comm1:	jnb nhou,tind	;начало часа
	acall briht	;уст яркость
	acall dtone	;звуковой сигнал
	clr nhou	;не начало
tind:	jb nmin,chek

;=========== Горячий старт ===============
;начало главной процедуры
main:	acall indic	;индикация
;анализ текущего режима индикации
	mov a,mdi	;чит режим
	jz t_vr		;a=0	на тек время
	dec a
	jz m_sec	;a=1	индик секунд
	dec a
	jz d_ndp	;a=2	день недели
	dec a
	cjne a,#04h,r_bud;будильники
	sjmp mainn	

r_bud:  mov nbud,a	;номер
	rl a		;умн на 4
	rl a
	add a,#18h	;+18Н получим начало инф буд
	mov bf3,a	;сохраняем

r_bud1:	mov a,nbud
	inc a		;чтобы номер начин не с 0
	mov r0,#10h	;начало индикатора
	acall hexdec	;размещаем
	mov 10h,#83h	;буква b
	mov r1,bf3	;восст нач инф
	inc r1		;сл яч
	inc r1		;еще
	mov a,@r1	;здесь режим
	acall hexdec	;размещ
	mov 12h,#ffh	;не нужн гасим
	acall indic	;индикац
	acall keyb	;опрос кн
	jb a.0,selmd	;по кн1 на переключ
	jb a.1,selrg	;перекл режима буд
	ajmp comm	;на гор старт
selmd:	ajmp s_mod
selrg:	inc @r1		;перекл режим
	mov a,@r1	;читаем режим
	anl a,#03h	;сбр ненужн биты
	mov @r1,a	;назад
	sjmp r_bud1	;цикл


;пп время текущ будильника
tbud:	mov r1,bf3	;чит адрес нач инф
	acall toind	;размещ
	acall indic	;индикац
	jb aex,mainn	;по автовыходу
	acall keyb	;опрос кнопок
	jb a.0,selmod	;по mode-перекл реж
	jb a.1,sttb	;по set-установка
	sjmp tbud	;цикл

;пп установки часов будильника
sttb:	mov msk,#24d	;уст пред знач
	mov r1,bf3	;восст нач адр инф
	acall toind	;размещ
	mov r1,bf3	;восст
	mov r0,#10h	;место мигающ цифры
	acall setmod	;пп установки
	jb a.1,sttb1	;по set-сл режим
	acall indic	;индикац
	sjmp sttb	;цикл

;пп уст минут будильника
sttb1:	mov msk,#60d	;уст пред знач
	mov r1,bf3	;восст нач адрес инф
	acall toind	;размещ
	mov r1,bf3	;восст
	inc r1		;адрес минут
	mov r0,#12h	;место мигающ цифры
	acall setmod	;пп установки
	jb a.1,tbud	;по set-назад
	acall indic	;индикац
	sjmp sttb1	;цикл

;пп проверки будильников
chek:	clr nmin	;сбр флаг мин
	jb p_on,soundr
        acall chkb	;проверяем будильники
        jc sound        ;cраб
        ajmp main


;пп музыкальной системы
sound:	clr nsec       ;ждем новой секунды
dt1:	acall indic
	jnb nsec,dt1

	setb p_bud	;уст признаки
	setb p_on
	mov t10,#0h	;сбр сч минут до повторов
	inc nmus	;номер мелодии +
	mov a,nmus
	clr c
	subb a,#0ah
	jc soundr
	mov nmus,#00h
soundr:	mov r1,#hou	;текущ время
        acall toind     ;размещ
	mov r2,#77h	;для дин индик
	mov r3,#00h	;номер разр
	anl 11h,#7fh	;зажиг точку
	mov a,t10	;на какой мин повтора
	rr a		
	rr a
	inc a
	anl a,#03h      ;получаем номер повтора
	mov r0,a	
sdf2:	setb c
	acall piik      ;столько раз пищим
	acall paus
	djnz r0,sdf2 
	mov dptr,#tmus	;таблица начал мелод
	mov a,nmus	;текущ номер мелод
	rl a		;умн на2
	mov r5,a	;сохраним смещение
	movc a,@a+dptr	;чит старший
	mov r4,a	;сохраним
	mov a,r5	;восст смещ
	inc a		;+1
	movc a,@a+dptr	;читаем младш
	mov dpl,a	;уст указатель
	mov dph,r4
	acall paus	;пауза
ssu:	;mov r3,sm_dl
	;inc r3
ssu1	;acall indic
	;acall indic
	acall key   	;кнопки
	jnz exssu1	;нажата - выход
	;djnz r3,ssu1
	clr nopl	;сбр признака
	clr a		;сбр смещ
	movc a,@a+dptr	;чит ноту
	mov r4,a
	push dph	;запомним указатель
	push dpl
	anl a,#f0h	;старшая часть
	jb a.7,uprav	;бит7=1 - управление
	swap a		;иначе - длительность
	add a,sm_dl	;+ смещение
	mov dptr,#dlit	;табл длит
	movc a,@a+dptr	;читаем длит
	mov dlt,a	;сохр длит
	sjmp ssu02

uprav:	jb a.6,uprt	;бит6=1 - управл тональностью
	swap a		;8-В -смещение ряда длительностей
	anl a,#03h
	mov sm_dl,a
	sjmp ssu02


uprt:	cjne a,#f0h,uprt01;F-выход
	ajmp exssu
uprtt:	mov a,r4	;восст
	anl a,#0fh	;мл часть
	swap a		;такое же управл
	setb nopl	;не играем
uprt01	cjne a,#c0h,uprt1;с - октава 1
	mov sm_tn,#00h	;смещение=0
	sjmp ssu02
uprt1:	cjne a,#d0h,uprt2;d - октава 2
	mov sm_tn,#12d	;смещение=12
	sjmp ssu02
uprt2:	cjne a,#e0h,uprt3;e - октава 3
	mov sm_tn,#24d	;смещение=24
	sjmp ssu02
uprt3:  sjmp pause
exssu:	pop a
	pop a
	ajmp main

exssu1:	clr p_on	;все сбрасываем
	clr p_bud
	ajmp main1

ssu02:	jb nopl,nx_not	;не играем-сл нота
	mov r6,dlt	;длительность
	mov a,r4	;восст нот
	anl a,#0ch	;две ст еденицы-управл тон
	cjne a,#0ch,ssu03	
	sjmp uprtt	
ssu03:	mov dptr,#nnot	;таблица нот
	mov a,r4	;восст
	anl a,#0fh	;мл часть
	add a,sm_tn	;+смещение
	movc a,@a+dptr	;читаем
	mov not1,a	;нота
	mov not2,a	;и сюда
note:   clr pri		;сбр пр прерывания

nn00:	acall indi      ;19	индикация
	mov r4,not1     ;1	дл 0
n_0:	acall ups	;6 проверка ист пит
	djnz r4,n_0	;8*not
	setb zer.4      ;1	уст 1
	acall indi      ;19	индикация
	mov r4,not2	;1	дл 1
n_01:	acall ups	;6 пров ист пит
	djnz r4,n_01    ;8*not
	clr zer.4	;1	уст 0
	jnb pri,nn00  ;2 пищим пока не было прерыв
n_02:   ;inc not1	;затух звук
	;dec not2
	djnz r6,note	;пров длительн по кол прер
nx_not:	pop dpl		;восст указ
	pop dph
	mov p1,#ffh
	inc dptr   	;указатель+1
	ajmp ssu	

;пауза вместо ноты
pause:	clr pri		;бит прерыв
paus0:  acall indi	;дин индик
	jnb pri,paus0	;ждем прер
	djnz r6,pause	;закончилась
	sjmp nx_not	;дальше

;пп установки мигающ цифры
setmod:	mov tpk,#tzdk
	acall keyb	;опрос
	jb a.0,ss1	;по кн1-увелич миг цифры
	jnb msc.3,st_m	;мигающ бит
	mov @r0,#ffh	;гасим знакоместо
	inc r0		;+ указатель
	mov @r0,#ffh	;и это
st_m:	ret
ss1:	inc @r1		;ув значение
	mov a,@r1	;счит
	cjne a,msk,exs	;прверяем на пред значение
	mov @r1,#00h	;если достигло
exs:	clr a
	ret		;выход

;пп подчи звуковго сигнала в соотв с битом С
tnn:	jc hi		;бит=1 -переход
	mov r6,#20h	;длительн
	mov ton,#60h	;тональность
	sjmp ntnn	;переход
hi:	mov ton,#40h	;тональность
	mov r6,#30h	;длительность
ntnn:	mov a,onn	;текущ знач яркости
	cpl a		;инвертируем
	anl a,#40h	;если день а=40н
	add a,r6	;увелич длит
	mov r6,a	;задаем
	acall piik2	;пищим
paus:	mov r5,#3h	;пауза между сигналами
hi0	clr pri		;признак прер
paus9	acall indic	;пп индик
	jnb pri,paus9	;ждем прер
	djnz r5,hi0	;сч -1
	ret

;пп подачи двухтонального двоичного сигнала каждый час
dtone:	mov a,hou	;новый час
	mov b,#13d	;делитель
	div ab		;делим
	add a,b		;суммир
	swap a
	mov buff,#04h	;кол-во бит
dt0:	rlc a		;сдвиг
	mov bf2,a	;запомним
	acall tnn	;пищим
	mov a,bf2	;восст
	djnz buff,dt0	;все биты?
	ret		;вых

;пп размещ инф из буф(r1) на индикатор

toind:	mov r0,#10h	;буфер индик
	mov a,@r1	;читаем
	acall hexdec	;переводим и размещ
	inc r1		;сл яч
	mov a,@r1	;чит
	acall hexdec	;размещ
	mov a,10h
	cjne a,#88h,to_0
	mov 10h,#ffh
to_0:	ret		;выход

;пп опроса кнопок
key:	clr a           ;исх сост
	acall kkey1	;опрос
	cpl c		;инв сч бит
	mov a.0,c	;запомн
	acall kkey2	;опрос
	cpl c		;инв сч бит
	mov a.1,c	;запомн
	ret		;вых

;пп опред наж кнопки с автоповтором
keyb:	acall key	;опрос кнопок
	jz exkey	;ни одной
	jb k_on,k_otp
	mov bkey,a	;запоминаем
	mov r3,#kyon	;время регистрации нажатой кнопки
keyb0:	acall key	;опрашив
	cjne a,bkey,exkey	;не такое-выход
	acall indic	;индикация
	djnz r3,keyb0	;время не закончилось-назад
	sjmp keypr

k_otp:	jb a_pvt,apk	;переход по автоповтору
	mov r3,#z_auto	;задерж до автоповтора
keyb11: clr pri		; прерываний
keyb1:	acall key	;опрос кн
	jz exkey	;уже отпустили
	acall indic	;индикация
	jnb pri,keyb1
	djnz r3,keyb11	;
	setb a_pvt	;вр закончилось,а кн не отп
	mov a,mdi	;пров режим
	jnz apk		;не реж тек вр-перех
	mov a,bkey
	cjne a,#02h,apk;кнопка SET
	ajmp korr	;переход на корректор
apk:	mov r3,tpk	;задержка при автоповторе
apk2:	clr pri
apk1:	acall indic
	acall key
	jz exkey
	jnb pri,apk1
	djnz r3,apk2 
keypr:	setb k_on	;признак
	mov au_ex,#auto ;восст сч до автовых
	clr aex		;сбр пр автовых
	mov a,bkey
	ret		;вых

;выход по ненаж кн
exkey:	mov tpk,#tzdk	;уст задерж при автоповторе
        clr k_on	;сбр признака 
	clr a_pvt	;пр автоповтора
	clr a
	mov bkey,a	;обн буф наж кн
	ret

;собственно опрос кнопок
kkey1:	setb p3.3 	;не нужен
	clr p3.2	;нужен
kkey:	setb p3.5	;вход
	mov c,p3.5	;читаем сост
	ret		;выход
kkey2:	clr p3.3	;нужен
	setb p3.2	;не нужен
	sjmp kkey	;читаем

;п/п переводит и размещает(@r0) на индик число(a)
hexdec:	mov dptr,#znak	;знакоген
	anl a,#7fh	;фильтр
	mov b,#0ah	;делитель
	div ab		;делим
	acall too	;размещ
	mov a,b		;мл часть
	acall too	;размещ
	ret		;вых

bud:    .db 00h,7fh,7fh,1fh	;фильтр дней нед для буд

;проверка будильников: если по выходу С=1 то сработал будильник
chkb:   mov r0,#hb1     ;нач табл буд
ch_0:	mov a,@r0	;час
	cjne a,hou,n_h	;не совп-перех
	inc r0		;указатель дальше
	mov a,@r0	;читаем мин
	cjne a,min,n_m	;не совп-перех
	inc r0		;указатель дальше
        mov dptr,#bud	;табл фильтров дней нед
        mov a,@r0	;чит режим
        mov r2,a	;сохр
	movc a,@a+dptr	;чит фильтр
	anl a,day	;фильтруем
        jnz sig         ;осталось-играем
nb_d:	inc r0		;сл яч
	inc r0		;сл яч
	cjne r0,#28h,ch_0;уже все
        clr c		;сброс флага
        ret		;выход
sig:    mov a,r2	;восст режим
	cjne a,#01h,n_sig;режим 1?
	mov @r0,#00h	;сбрасываем
n_sig:	setb c		;уст признак
        ret		;выход

n_h:	inc r0		;+ указатель
n_m:	inc r0		;+ указатель
	sjmp nb_d	;ост будильники

;п/п быстрой дин индик
indi:	mov a,r2	;1 текущ разряд
	rl a            ;1 перекл
	mov r2,a        ;1 сохр
	orl a,#f0h      ;1 фильтр
	anl a,zer       ;1 зеркало
	mov p1,#ffh     ;2 рег сегм
	mov p3,a        ;1 вкл текущ знакоместо
	mov a,r3        ;1 номер разр
	anl a,#03h      ;1 фильтр
	orl a,#10h      ;1 суммир с нач буф
	mov r1,a        ;1 сохр
	mov a,@r1       ;1 достаем
	mov p1,a        ;1 в рег сегм
	inc r3          ;1 +разр
	ret             ;2+2call

gomain:	ajmp gonx	;переход
exups:	ret		;выход-питание в порядке

;проверка источника питания
ups:	jb p3.7,exups	;2

	mov r7,#3d	;задержка, чтобы не хлопало, если медлено снижается
up:	clr pri		;очищ бит прерыв
	jnb pri,$	;ждем прерыв
	djnz r7,up	;два раза
	jb p3.7,exups	;еще проверка

;напряжение сети точно пропало
	mov sp,#60h	;стек на место
ups0:	mov zer,#efh	;зеркало порта
	mov p1,#ffh	;порт в исх сост
	mov p3,#efh	;и этот кроме вых на динамик
	mov ton,#40h	;тональность
	mov mdi,#01h	;чтоб не войти в реж корр
ups1:	jnb nsec,$	;ждем новой сек
	clr nsec
	jb p3.7,gomain	;не появилось ли?
tff:	jb nmin,tff1	;новая минута
tff3:	acall key	;кнопки
	jz ups1		;не наж -назад
	sjmp tff2	;индикация

tff1:	clr nmin	;сбр флаг мин
	jb p_on,alrr
        acall chkb	;проверяем будильники
        jc alr        ;cраб
	
tff2:	acall show	;показываем
	mov a,msc	;пол секунды
	clr c
	subb a,#16d	;16 прерыв - 0.5 сек
	jc tff2 
        sjmp tff3

;пп звонка в аварийном режиме
alr:	setb p_bud	;будильник сработал
	setb p_on	;пищим сейчас
	mov t10,#0h	;сброс задержки перед повторами
alrr:	mov bf3,#10d	;10 раз
pipi0:	clr nsec
	acall piik	;пищим
	acall show	;пауза
	acall piik	;еще пищим
;	acall show	;еще пауза
	jnb nsec,$	;ждем новой секунды
	acall key	;кнопки
	jnz pipie	;нажаты -выход
	djnz bf3,pipi0
	sjmp ups1	

pipie:	clr p_bud	;все сбрасываем
	clr p_on	
	sjmp ups1

;пп индикации в авар режиме
show    mov r1,#hou	;размещ
	acall toind
	anl 11h,#7fh	;точка
	setb nopl	;не пищать
	acall show1	;дальше уже есть
	ret

;пп звукового сигнала
piik:	clr nopl	;будет звук
show1:	mov r6,#00h	;длительность
piik2:	mov r2,#77h	;инф для пп indi
	mov r3,#00h	;и это
piik1:	acall indi	;индикация
	mov r4,ton	;длит 0
	djnz r4,$	
	jb nopl,piik3	;пищать /не пищать
	setb zer.4	;уст 1
piik3	acall indi	;индикац
	mov r4,ton	;длит 1
	djnz r4,$
	jb nopl,piik4   ;пищать /не пищать
	clr zer.4	;уст 0
piik4	djnz r6,piik1	;длительность 
	mov p1,#ffh	;выкл порт сегм
	ret

;знакогенератор
znak:	.db 88h,deh,a4h,94h,d2h,91h,81h,dch
        .db 80h,90h,c0h,83h,a7h,86h,a1h,e1h

;знакогенератор дней недели
d_ned:	.db c8h,c2h,80h,c2h,a9h,e0h,d2h,e9h
	.db c8h,c0h,a9h,81h,80h,a9h


;таблица длительностей
dlit:	.db  2,  3,  4,  6,  8, 12, 17, 23, 35, 48, 72
;sm_dl=8     16  16.  8   8.  4   4.  2   2.  -   -  -
;sm_dl=9      -  16  16.  8   8.  4   4.  2   2.  -  -
;sm_dl=a      -   -  16  16.  8   8.  4   4.  2   2. -
;sm_dl=b      -   -   -  16  16.  8   8.  4   4.  2  2.

;таблица начал медодий
tmus:	.defw mus0,mus1,mus2,mus3,mus4,mus5,mus6,mus7,mus8,mus9

;таблицы нот мелодий
;bach c64
mus0:	.db 9dh,46h,27h,24h,46h,e2h,22h,21h,dbh,2ah,2ah,5bh,44h,26h,22h,44h
	.db 0fh,06h,07h,26h,24h,22h,21h,42h,cbh,d6h,27h,24h,46h,e2h,22h,21h
	.db dbh,2ah,4bh,09h,07h,06h,04h,49h,07h,06h,04h,02h,27h,24h,26h,22h
	.db 44h,41h,52h,f0h

;carmen
mus1:	.db 8dh,29h,2fh,28h,2fh,27h,27h,2fh,27h,26h,2fh,25h,2fh,24h,24h,2fh
	.db 24h,43h,42h,40h,8ch,2bh,d0h,42h,40h,cbh,dfh,29h,2fh,28h,2fh,27h
	.db 27h,2fh,27h,26h,2fh,25h,2fh,24h,24h,2fh,24h,42h,40h,cbh,29h,2bh
	.db 8dh,40h,cbh,49h,f0h

;vals
mus2:	.db 8dh,41h,50h,21h,50h,21h,20h,24h,47h,4fh,41h,50h,21h,50h,21h,20h
	.db 25h,48h,4fh,41h,50h,21h,50h,21h,20h,24h,47h,4fh,48h,55h,0eh,21h
	.db 20h,0dh,3ah,2fh,08h,07h,45h,40h,45h,f0h

;equador
mus3:	.db 9dh,2ah,0fh,25h,0fh,0eh,21h,20h,23h,20h,d8h,2ah,0fh,25h,0fh,0eh
	.db 21h,20h,23h,20h,d8h,e1h,0fh,0dh,28h,0fh,0eh,25h,23h,25h,23h,d8h
	.db e1h,0fh,0dh,2ah,0fh,0eh,21h,20h,21h,20h,d8h,3ah,f0h

;we wish
mus4:	.db 9dh,42h,47h,27h,29h,27h,26h,44h,40h,44h,49h,29h,2bh,29h,27h,46h
	.db 42h,46h,4bh,2bh,e0h,dbh,29h,47h,44h,42h,44h,49h,46h,57h,f0h

;popcorn
mus5:   .db 9eh,20h,dah,e0h,d7h,23h,27h,40h,0eh,20h,dah,e0h,d7h,23h,27h,40h
	.db 0eh,20h,22h,23h,00h,23h,00h,23h,22h,0dh,0ah,0eh,22h,0dh,0ah,0eh
	.db 22h,20h,dah,27h,2ah,0eh,40h,f0h

;bach12
mus6:	.db 9dh,27h,26h,24h,22h,2bh,2fh,29h,6fh,27h,26h,24h,22h,e0h,2fh,dbh
	.db 6fh,0eh,22h,dbh,29h,27h,e4h,20h,22h,dbh,29h,27h,e0h,d9h,e0h,dbh
	.db 29h,27h,29h,26h,37h,f0h

;varjag
mus7:	.db aeh,00h,40h,32h,0dh,09h,0eh,40h,32h,0dh,09h,0eh,40h,0dh,3ah,09h
	.db 5ah,0fh,00h,40h,24h,27h,4ah,29h,27h,55h,27h,59h,29h,0eh,42h,22h
	.db 02h,0fh,22h,20h,dah,29h,47h,37h,0ah,0eh,52h,22h,40h,34h,02h,20h
	.db dah,29h,27h,55h,2fh,35h,f0h

;ex dorogi
mus8:;	.db adh,69h,42h,4ah,67h,47h,40h,0eh,20h,dah,79h,22h,25h,49h,45h,47h
;	.db 64h,0ch,29h,29h,49h,0dh,25h,24h,62h,f0h

;letka-enka
;mus9:
	.db 9dh,47h,4fh,42h,4fh,27h,2fh,27h,23h,42h,40h,0ch,2bh,2fh,d2h,2fh
	.db cbh,2fh,d2h,2fh,20h,2fh,23h,2fh,67h,48h,25h,28h,0eh,00h,0fh,00h
	.db 0fh,20h,dbh,0eh,40h,0dh,37h,0fh,47h,43h,45h,22h,23h,25h,25h,47h
	.db 20h,0fh,20h,0fh,20h,f0h

;vot kto-to s gorochki
mus9:	.db 9ch,44h,d0h,cbh,69h,44h,0dh,64h,40h,cbh,69h,49h,d9h,47h,45h,44h
	.db 45h,67h,45h,64h,4fh,c9h,d9h,47h,45h,44h,45h,67h,45h,45h,64h,44h,45h
	.db 44h,42h,40h,42h,64h,42h,0ch,69h,f0h

;коф деления для нот
nnot:	.db 236,223,210,198,188,176,166,157,148,139,131,124
	.db 117,110,104,98,93,87,82,77,73,68,64,61
	.db 57,54,51,48,45,42,40,37,35,33,31,29

	.org 7feh
tkf:	.db 70h,00h 


