$MOD51

Clock_          BIT     p3.0            ; Синхронизация
Data_           BIT     p3.1            ; Данные
Key_            BIT     p3.2
LightStr_       BIT     p3.5
ParitRec        BIT     0
ParitTrn        BIT     1
ParKomF3        BIT     2
KbdOFF          BIT     3
ALARM           BIT     4
BlimSt          BIT     5
FirstByte       BIT     6
ParKomED        BIT     7
HeadBuf         DATA    8h              ; Голова буфера клавиатуры
TailBuf         DATA    9h
BlimCnt1        DATA    0Ah
BlimCnt2        DATA    0Bh
CntDelayKey     DATA    0Ch
CntDelayKey1    DATA    0Dh
Com_2_Oper      DATA    0Eh             ;Код команды для операций с двумя операндами
Nkol            DATA    10h
Speak_c         DATA    11h
CountBit        DATA    12h
Temp1           DATA    13h
Temp2           DATA    14h
LastKod         DATA    15h
FreqFrstKey     DATA    16h        ;Время начала повтора кодов при удержании клавиши
FreqFrstKey1    DATA    17h
FreqPrKey       DATA    18h
CountTimer	DATA	19h

;Memory map
BegStLight      EQU    30H         ;Начало буфера состояний светодиодов
EndStLight      EQU    3FH         ;Конец буфера состояний светодиодов
BegKeySt        EQU    40H         ;Начало буфера состояния маски клавиатуры
EndKeySt        EQU    4FH         ;Конец буфера состояния маски клавиатуры
BegBufKbd       EQU    50H         ;Начало буфера клавиатуры
EndBufKbd       EQU    60H         ;Конец буфера клавиатуры
BegStack        EQU    65H	   ;Start head of stack

;Constant
SpeakLen        EQU    040h        ;Длительность звука после нажатия клавиши
SpeakLen1       EQU    010h        ;Короткая длительность звука после нажатия клавиши
BlimTime        EQU    01h         ;Периуд мигания светодиодов
DelayRW         EQU    0F0h ;0EBh  ;Периуд передачи и приема одного бита
KeyScanCnt      EQU    02h         ;Keys scan counter divider
;FreqPrKey       EQU    04FH        ;Период повторения кодов при удержании клавиши
;FreqFrstKey     EQU    0FFH        ;Время начала повтора кодов при удержании клавиши

                CSEG
                ORG     0000H           ; power on/reset vector
                jmp     start
                ORG     0003H           ; external interrupt 0 vector
                reti                    ; undefined
                ORG     000BH           ; timer 0 overflow vector
                reti                    ; undefined
                ORG     0013H           ; external interrupt 1 vector
                reti                    ; undefined
                ORG     001BH           ; timer 1 overflow vector
                LJMP    TIMER2
                ORG     0030H

start:          MOV     IE,#00H
                MOV     DPTR,#0000H
                MOV     SP,#BegStack
                mov     P1,#11111111b
                mov     P3,#10000011b
;                           | ||  |\ Данные обмена
;                           | ||  \- Синхронизация обмена
;                           | |\---- Запись номера столбца светодиодов, клавиатуры и динамика
;                           | \----- Запись столбцов светодиодов
;                           \------- Чтение состояния клавиатуры
                MOV     TMOD,#12H    ;Режимы таймеров (2 - 8разр с перегрузкой из TH0)
                                     ;                (1 - 16разрядный)
                mov     TH0,#DelayRW
                mov     TL0,#DelayRW
                MOV     TH1,#0F9H    ;Период таймера сканирования клавиатуры и мигания светодиодами
                MOV     TL1,#7CH     ;500Гц (2 ms)
                MOV     IE,#88H      ;Разрешения прерывания от таймера 1
                SETB    TR1          ;Включение таймера 1
                clr     KbdOFF       ;Клавиатура включена

                CLR     A
                MOV     R0,#08H
;Обнуление ОЗУ выше регистров 20h (128 байт)
m0_0:           MOV     @R0,A
                INC     R0  
                CJNE    R0,#80H,m0_0

                mov     HeadBuf,#BegBufKbd
                mov     TailBuf,#BegBufKbd
;                mov     Nkol,#00h     ;Установка номера столбца сканирования
;                mov     LastKod,#00h
                mov     BlimCnt2,#BlimTime
                mov     BlimCnt1,#0FFh
                mov     FreqFrstKey,#0FEh
                mov     FreqFrstKey1,#00h
                mov     FreqPrKey,#020H

                SETB    ALARM         ;Звук включен
;                mov     CntDelayKey,#00h
;                mov     CntDelayKey1,#00h
                CLR     ParKomED
;                mov     Com_2_Oper,#00h
;                mov     BegStLight+7,#0FFh
;                mov     BegStLight+15,#080h
;================== Start cod ===================================================
                mov     a,#0AAh
                call    Trans
                mov     Speak_c,#SpeakLen
;--------------------------------------------------------------------------------

cycle:
                call    Transive     ;Проверка буфера передачи и передача если он не пуст
                call    Recive       ;Прием, если идет команда
                ajmp    cycle        ;Глухой цикл
;================== Функция передачи ==================================================
Transive:
                JB      KbdOFF,m1_8
                mov     a,CntDelayKey  ;Если счетчик повторения клавишь не ноль то ждать
                jnz     m1_8
                mov     a,CntDelayKey1 ;Если счетчик повторения клавишь не ноль то ждать
                jnz     m1_8
                JNB     Clock_,m1_8  ;Проверка занятости линии
                JNB     Data_,m1_8
                mov     a,HeadBuf
                CJNE    a,TailBuf,m1_0  ;проверка буфера передачи на пустоту
m1_8:           ajmp    BUSY
m1_0:
                mov     CntDelayKey ,FreqFrstKey   ;Загрузка значения ожидания для выдачи следующего кода после первого
                mov     CntDelayKey1,FreqFrstKey1  ;Загрузка значения ожидания для выдачи следующего кода после первого
                jbc     FirstByte,m1_4
                mov     CntDelayKey, FreqPrKey     ;Загрузка значения ожидания для выдачи следующего кода
                mov     CntDelayKey1,#0h           ;Загрузка значения ожидания для выдачи следующего кода
m1_4:           mov     R0,HeadBuf
                inc     R0                 ;
                CJNE    R0,#EndBufKbd,m1_1 ;Заворачивание буфера
                mov     R0,#BegBufKbd      ;
m1_1:           mov     R1,HeadBuf       ;
                mov     a,@R1
                anl     a,#10000000b     ;
                jz      m1_5             ;Если код отжатия то отправить сразу и удалить из буфера
		
		mov     a,@R1
		call    ScanTabl
                
m1_9:		mov     HeadBuf,R0       ;Удалить из буфера если код отжатия
                ajmp    BUSY
m1_5:           mov     a,R0
                CJNE    a,TailBuf,m1_2  ;В буфере один байт или нет
;                mov     R1,HeadBuf       ;Если в буфере один байт и не код отжатия то отправить без удаления
	      	mov     a,@R1
		call    ScanTabl
m1_10:          ajmp    BUSY
m1_2:           mov     a,@R0
                anl     a,#10000000b
                jz      m1_3             ;Следующий код отжатия?
                mov     a,@R0
                anl     a,#01111111b
                mov     b,@R1
                CJNE    a,b,m1_6         ;Если код отжатия равен коду нажатия, то отправить
;Посылка кода нажатия, а следом кода отжатия этой же клавишы с удалением обоих с буфера
	      	mov     a,@R0
		call    ScanTabl
		
                inc     R0
                CJNE    R0,#EndBufKbd,m1_7    ;Заворачивание буфера
                mov     R0,#BegBufKbd         ;
m1_7:           mov     HeadBuf,R0
                ajmp    BUSY
;Посылка кода отжатия не поовторяющейся клавишы с сохранением повторения
m1_6:		
     		mov     a,@R0
		call    ScanTabl		
                mov     a,@R1
                mov     @R0,a
                mov     HeadBuf,R0
                ajmp    BUSY
m1_3:
     		mov     a,@R0             ;!!!! (or @R1)
		call    ScanTabl
		
                mov     HeadBuf,R0
BUSY:           ret
;------------------------------------------------------------------------------------------
ScanTabl:
                push    ACC
		push    03

		mov     R3,a
                anl     a,#10000000b     ;
                jz      m6_1             ;Если код отжатия то отправить сразу и удалить из буфера
		mov     a,R3
                anl     a,#01111111b
		mov     R3,a
                mov     dptr, #PopKey1          
                movc    a, @a+dptr
                jz      m6_2                  ;Если код 00h т.е клавиша не привязана
                call    Trans
                mov     a,R3
                mov     dptr, #PopKey2          
                movc    a, @a+dptr
                jz      m6_2                  ;Если код 00h т.е клавиша не привязана
                call    Trans
                mov     a,R3
                mov     dptr, #PopKey3          
                movc    a, @a+dptr
                jz      m6_2                  ;Если код 00h т.е клавиша не привязана
                call    Trans
                ;mov     a,R3
                ;mov     dptr, #PopKey4          
                ;movc    a, @a+dptr
                ;jz      m6_2                  ;Если код 00h т.е клавиша не привязана
                ;call    Trans
		sjmp    m6_2
                
m6_1:		mov     a,R3
		mov     dptr, #PushKey1          
                movc    a, @a+dptr
                jz      m6_2                   ;Если код 00h т.е клавиша не привязана
                call    Trans
                mov     a,R3
                mov     dptr, #PushKey2          
                movc    a, @a+dptr
                jz      m6_2                  ;Если код 00h т.е клавиша не привязана
                call    Trans
                mov     a,R3
                mov     dptr, #PushKey3          
                movc    a, @a+dptr
                jz      m6_2                  ;Если код 00h т.е клавиша не привязана
                call    Trans
                ;mov     a,R3
                ;mov     dptr, #PushKey4          
                ;movc    a, @a+dptr
                ;jz      m6_2                  ;Если код 00h т.е клавиша не привязана
                ;call    Trans 

m6_2:		
		pop     03
		pop     ACC
                ret

;------------------------------------------------------------------------------------------
Trans:          push    ACC
                push    03               ;R3
m2_3:           JNB     Data_,$
                JNB     Clock_,m2_3
                clr     ParitRec
                add     a,#00H
                jb      p,m2_0           ;Определение четности передаваемого байта
                setb    ParitRec
m2_0:           mov     R3, #09H         ;Загрузка счетчика переданных битов
                mov     TL0,#DelayRW     ;Загрузка таймера 0 для передачи
                setb    TR0              ;Включение таймера 0
                clr     ET1
                clr     C
;Передача байта
NextBit:        mov     Data_,C
                JNB     Clock_,m2_1      ;Синхро линия сброшена, возможна встречная передача, выход
                JNB     TF0,$
                CLR     TF0
                CLR     Clock_
                JNB     TF0,$
                CLR     TF0
                nop
                JNB     TF0,$
                CLR     TF0
                SETB    Clock_
;                CLR     C
                RRC     A
                JNB     TF0,$
                CLR     TF0
                DJNZ    R3,NextBit
                mov     c,ParitRec        ;Передача паритета
                MOV     Data_,C
                JNB     Clock_,m2_1      ;Синхро линия сброшена, возможна встречная передача, выход
                JNB     TF0,$
                CLR     TF0
                CLR     Clock_
                JNB     TF0,$
                CLR     TF0
                nop
                JNB     TF0,$
                CLR     TF0
                SETB    Clock_
                JNB     TF0,$
                CLR     TF0
                SETB    Data_
                JNB     TF0,$
                CLR     TF0
                CLR     Clock_
                JNB     TF0,$
                CLR     TF0
                nop
                JNB     TF0,$
                CLR     TF0
                SETB    Clock_
                JNB     TF0,$
		;---- timeout -----
                CLR     TF0
                JNB     TF0,$		
                CLR     TF0
                JNB     TF0,$
		;------------------		
                sjmp    m2_2

m2_1:           SETB    Clock_
                SETB    Data_
m2_2:      	CLR     TF0
                CLR     TR0
                SETB    ET1
                pop     03          ;R3
                pop     ACC
                ret

;===================== Функция приема ====================================================
Recive:
;                JNB     Data_,m3_4             ;Идут данные внешней команды не принимать
;                JB      Clock_,m3_4            ;Идет синхронизация внешней команды

                JNB     Clock_,m3_4            ;Идут данные внешней команды не принимать
                JB      Data_,m3_4             ;Идет синхронизация внешней команды

                MOV     TL0,#DelayRW           ;Загрузка таймера 0 для передачи
                MOV     R3,#09H
                SETB    TR0                    ;Включение таймера 0
                clr     ET1                    ;Запрещение прерываний от таймера 1
                jnb     Clock_,$               ;Возможно подождать установки C в 1
                CLR     C
m3_1:           RRC     A
                JNB     TF0,$                  ;Попытаться ловить по данным (старт бит)
                CLR     TF0
                CLR     Clock_
                JNB     TF0,$
                CLR     TF0
                nop
                JNB     TF0,$
                CLR     TF0
                SETB    Clock_
                JNB     TF0,$
                CLR     TF0
                MOV     C,Data_
                DJNZ    R3,m3_1
                MOV     ParitTrn,C
                JNB     TF0,$
                CLR     TF0
                CLR     Clock_
                JNB     TF0,$
                CLR     TF0
                nop
                JNB     TF0,$
                CLR     TF0
                SETB    Clock_
                CLR     Data_
                JNB     TF0,$
                CLR     TF0
                nop
                JNB     TF0,$
                CLR     TF0
                CLR     Clock_
                JNB     TF0,$
                CLR     TF0
                nop
                JNB     TF0,$
                CLR     TF0
                SETB    Data_
                SETB    Clock_
                CLR     TR0
                SETB    ET1                    ;Включение таймера 0

                ADD     A,#00H
                JNB     P,m3_2
                JB      ParitTrn,m3_0
                sjmp    m3_3
m3_2:           JNB     ParitTrn,m3_0
m3_3:           call    decode_com
                ret
m3_0:           mov     Speak_c,#SpeakLen1      ;Пищать если ошибка приема
m3_4:           ret
;---------------- Декодирование команд ---------------------------------------------------
m4_31:          mov     R1,A
                RL      A
                RL      A
                RL      A
                ORL     A,#07h
                mov     FreqPrKey,A
                mov     A,R1
                ANL     A,#60h
                mov     FreqFrstKey1,#0h
                CJNE    A,#0H,m4_32
                mov     FreqFrstKey,#07Fh
m4_32:          CJNE    A,#20H,m4_33
                mov     FreqFrstKey,#0FFh
m4_33:          CJNE    A,#40H,m4_34
                mov     FreqFrstKey,#07Fh
                mov     FreqFrstKey1,#1h
m4_34:          CJNE    A,#60H,m4_35
                mov     FreqFrstKey,#0FFh
                mov     FreqFrstKey1,#1h
m4_35:          sjmp    m4_18                            ;Непосредственное отправление

decode_com:     JBC     ParKomED,m4_2                   ;Параметры команды F3
                JBC     ParKomF3,m4_31
                CJNE    A,#0EDH,m4_1                    ;Команда управлением светодиодами
                SETB    ParKomED
m4_18:          MOV     A,#0FAh
                sjmp    m4_16                            ;Непосредственное отправление
m4_1:           CJNE    A,#0F3H,m4_22                    ;Команда самодиагностики
                SETB    ParKomF3
                sjmp    m4_18
m4_22:          CJNE    A,#0FFH,m4_6                    ;Команда самодиагностики
                MOV     HeadBuf,#BegBufKbd
                MOV     TailBuf,#BegBufKbd
                mov     LastKod,#00h
                MOV     A,#0FAh
                call    Trans
                mov     a,#0AAh
                sjmp    m4_16                            ;Непосредственное отправление
;                call    Trans
;                LJMP    m4_0
m4_6:           CJNE    A,#0EEH,m4_17                  ;Команда эхо
                MOV     A,#0EEH
m4_16: ;         MOV     R4,#4BH                        ;Отправление ответа без очереди
       ;         DJNZ    R4,$
                call    Trans
                AJMP    m4_0
m4_17:          CJNE    A,#0F5H,m4_11                    ;Команда выключения клавиатуры
                SETB    KbdOFF
                mov     LastKod,#00h
                SJMP    m4_18                           ;Непосредственное подтверждение
m4_11:          CJNE    A,#0F4H,m4_12                    ;Команда включения клавиатуры
                MOV     TailBuf,#BegBufKbd
                MOV     HeadBuf,#BegBufKbd
                CLR     KbdOFF
                SJMP    m4_18                           ;Непосредственное подтверждение
m4_12:          CJNE    A,#0FEH,m4_15                    ;Команда, повтор последнего кода клавиши
                MOV     A,LastKod
                SJMP    m4_16                            ;Непосредственное отправление
m4_15:          CJNE    A,#0F6H,m4_36                    ;Команда, повтор последнего кода клавиши
                SJMP    m4_18                           ;Непосредственное подтверждение
m4_36:          mov     Speak_c,#SpeakLen                ;Пищать если код не опознан
                AJMP    m4_0
m4_2:           mov     R1,A
                mov     a,Com_2_Oper
                jz      m4_20
                mov     Com_2_Oper,#00h
                mov     R2,a
                MOV     A,R1
                ANL     A,#00111000b
                MOV     R0,#BegStLight
                RR      A
                RR      A
                RR      A
                ADD     A,R0
                MOV     R0,A
                MOV     A,R1
                ANL     A,#07H
                inc     A
                mov     R3,A
                setb    c
                mov     A,#00h
m4_3:           RLC     A
                djnz    R3,m4_3
                mov     R1,A
                CJNE    R2,#02H,m4_4          ;Команда постоянного свечения
                ORL     A,@R0
                MOV     @R0,A
                MOV     A,R0
                ADD     A,#08H
                MOV     R0,A
                MOV     A,R1
                CPL     A
                ANL     A,@R0
                MOV     @R0,A
                ljmp    m4_18                            ;Непосредственное отправление
m4_4:           CJNE    R2,#03H,m4_5          ;Команда мигания
                MOV     A,R0
                ADD     A,#08H
                MOV     R0,A
                MOV     A,R1
                ORL     A,@R0
                MOV     @R0,A
                ljmp    m4_18                            ;Непосредственное отправление
m4_5:           CPL     A                     ;Команда тушения
                ANL     A,@R0
                MOV     @R0,A
                MOV     A,R0
                ADD     A,#08H
                MOV     R0,A
                MOV     A,R1
                CPL     A
                ANL     A,@R0
                MOV     @R0,A
                ljmp    m4_18                            ;Непосредственное отправление

m4_20:          CJNE    R1,#01H,m4_21          ;Команда гашения
m4_23:          mov     Com_2_Oper,R1
m4_28:          LJMP    m4_18                            ;Непосредственное отправление
m4_21:          CJNE    R1,#02H,m4_24          ;Зажечь светодиод
                sjmp    m4_23
m4_24:          CJNE    R1,#03H,m4_25          ;Замигать светодиод
                sjmp    m4_23
m4_25:          CJNE    R1,#04H,m4_26          ;Замигать светодиод
                MOV     R0,#BegStLight
m4_8:           MOV     @R0,#00H                        ;Обнуление области 60h - 6Eh - состояния  светодиодов
                INC     R0
                CJNE    R0,#EndStLight,m4_8
                sJMP    m4_28                            ;Непосредственное отправление
m4_26:          CJNE    R1,#05H,m4_27          ;Выключить звук
                CLR     ALARM
                sjmp    m4_28
m4_27:          CJNE    R1,#06H,m4_29          ;Включить звук
                SETB    ALARM
                sjmp    m4_28
m4_29:          CJNE    R1,#07H,m4_28          ;Проверить ключь
                setb    Key_
                mov     a,#0FAh
                call    Trans
                jb      Key_,m4_30
                mov     a,#31h                  ;N
                call    Trans
                mov     a,#44h                  ;O
                call    Trans
                sjmp    m4_0
m4_30:          mov     a,#35h                  ;Y
                call    Trans
                mov     a,#24h                  ;E
                call    Trans
                mov     a,#1Bh                  ;S
                call    Trans
                sjmp    m4_0
m4_0:           ret

;Обработчик прерывания от таймера. Отвечает за свечение светодиодов,
;сканирование клавиатуры и пищания зумера
TIMER2:
                PUSH    PSW
                PUSH    ACC
                push    00            ;R0
                push    01            ;R1

                MOV     TH1,#0F9H    ;Период таймера сканирования клавиатуры и мигания светодиодами
                MOV     TL1,#7CH     ;500Гц (2 ms)

;m5_19:          mov     B,Nkol
;                mov     a,b

;Погасить светодиоды
                mov     P1,#0FFh
                setb    LightStr_
                sjmp    $+2
                clr     LightStr_


;Выставить следующий ряд сканирования
m5_3:           mov     b,Nkol
                mov     A,Speak_c
                jnz     m5_17
m5_14:          mov     a,#080H
                sjmp    m5_12
m5_17:          mov     a,#00H
m5_12:          ORL     A,B
                mov     P1,A
                ;setb    P3.4
                ;sjmp    $+2
                ;clr     P3.4
		;--- tst1 ---
                setb    P3.4
                sjmp    $+2
                clr     P3.4
                sjmp    $+2
                setb    P3.4
                sjmp    $+2
                clr     P3.4
		;--- tst1 ---
;Если номер ряда более 8 то не засвечивать светодиоды
                clr     c
                mov     a,b
                subb    a,#8
                jc      m5_13
                sjmp    m5_21
m5_13:
;Выдать состояне светодиодов
                mov     a,b
                add     a,#BegStLight
                mov     R0,A
                mov     A,@R0
                jnb     BlimSt,m5_15
                mov     R1,a
                mov     a,b
                add     a,#BegStLight
                add     a,#08h
                mov     R0,a
                mov     a,R1
                xrl     a,@R0
m5_15:          cpl     A
                mov     P1,A
                setb    LightStr_
                sjmp    $+2
                clr     LightStr_
;Если идут данные от контроллера клавиатуры, то выйти
;                JB      Data_,m5_21
;                ljmp    m5_2
m5_21:
                mov     P1,#0FFh
                sjmp    $+2
                clr     P3.7
                sjmp    $+2
                setb    P3.7
                sjmp    $+2
                clr     P3.7
		
		mov     A,P1
                
		setb    P3.7
                cpl     A
                mov     Temp1,a

                mov     a,#BegKeySt
                add     a,B
                mov     R0,a
                mov     a,@R0
                cjne    A,Temp1,m5_0  ;генерация скан кода
m5_9:           inc     Nkol
                mov     a,Nkol
                clr     c
                subb    a,#16
                jnc     m5_1        ;a>=16
                mov     a,Nkol
                clr     c
                subb    a,#9
                jnc     m5_3        ;a>=8
                ljmp    m5_2

m5_1:           mov     Nkol,#0h
                ljmp    m5_3

m5_0:           mov     CountBit,#08h
                mov     a,@R0
                mov     @R0,Temp1
                mov     R0,a
m5_10:          mov     a,Temp1
                rlc     a
                mov     Temp1,a
                jc      m5_4
                mov     Temp2,#80h
                mov     a,R0
                rlc     a
                mov     R0,a
                jnc     m5_5
                sjmp    m5_6
m5_4:           mov     Temp2,#00h
                mov     a,R0
                rlc     a
                mov     R0,a
                jc      m5_5
m5_6:           mov     a,Nkol
                rl      a
                rl      a
                rl      a
                mov     b,CountBit
                dec     b
                orl     a,b
		
                orl     a,Temp2
                mov     Temp2,a
		
		mov     R4,a
		anl     a,#80h
		jz      m5_23
		mov     a,R4
                mov     dptr, #PopKey1          
                movc    a, @a+dptr
                jz      m5_20                  ;Если код 00h т.е клавиша не привязана
		sjmp    m5_24
m5_23:		mov     a,R4
                mov     dptr, #PushKey1          
                movc    a, @a+dptr
                jz      m5_20                  ;Если код 00h т.е клавиша не привязан
m5_24:		mov     a,R4

                mov     a,TailBuf
                inc     a
                CJNE    a,#EndBufKbd,m5_7
                MOV     a,#BegBufKbd
m5_7:           CJNE    a,HeadBuf,m5_8
                sjmp    m5_5
m5_8:           mov     R1,TailBuf
                mov     @R1,Temp2
                mov     TailBuf,a
                mov     LastKod,Temp2
;Генерация звука
                mov     a,Temp2
                ANL     a,#080h
                jnz     m5_5
                jnb     ALARM,m5_5
                mov     Speak_c,#SpeakLen
                setb    FirstByte
m5_5:           mov     CntDelayKey,#00       ;Выдать символ сразу если не удержание
                mov     CntDelayKey1,#00       ;Выдать символ сразу если не удержание
m5_20:          djnz    CountBit,m5_10
                ljmp    m5_9

m5_2:
                mov     a,CntDelayKey         ;Выдержка повторения генерации клавиш
                jnz     m5_22
                mov     a,CntDelayKey1         ;Выдержка повторения генерации клавиш
                jz      m5_18
m5_22:          clr     c
                mov     a,CntDelayKey
                subb    a,#1
                mov     CntDelayKey,a
                mov     a,CntDelayKey1
                subb    a,#0
                mov     CntDelayKey1,a

;m5_22:          dec     CntDelayKey
;                mov     a,CntDelayKey
;                jnz     m5_18

;                dec     CntDelayKey1
m5_18:
                mov     a,Speak_c             ;Выдержка пищания
                jz      m5_11
                dec     Speak_c
m5_11:
                dec     BlimCnt1
                mov     a,BlimCnt1            ;Генератор мигания
                jnz     m5_16
                dec     BlimCnt2
                mov     a,BlimCnt2            ;Генератор мигания
                jnz     m5_16
                mov     BlimCnt2,#BlimTime
                cpl     BlimSt

m5_16:          pop     01                 ;R1
                pop     00                 ;R0
                POP     ACC
                POP     PSW
                RETI
;Команды клавиатуре (перед каждым байтом послать 0EDh)
;01h 00xxxxxxb - погасить светодиод c указанным номером;
;02h 00xxxxxxb - зажечь светодиод c указанным номером;
;03h 00xxxxxxb - змигать светодиодом c указанным номером;
;04h  - Погасить все светодиоды;
;05h  - Выключить звук при нажатии клавишы;
;06h  - Включить звук при нажатии клавишы;
;07h  - Проверить  состояние ключа. Если ключ присутствует отпровляются сканкоды символов "YES" иначе "NO";

;/-------------------------------------------------\
;| |0  1  2  3  4  5  6  7  8  9  A  B  C  D  E  F |
;|-|-----------------------------------------------|
;|0|   43 41 3F 3D 3B 3C 58 64 44 42 40 3E 0F 29 59|
;|1|65 38 2A 70 1D 10 02 5A 66 71 2C 1F 1E 11 03 5B|
;|2|67 2E 2D 20 12 05 04 5C 68 39 2F 21 14 13 06 5D|
;|3|69 31 30 23 22 15 07 5E 6A 72 32 24 16 08 09 5F|
;|4|6B 33 25 17 18 0B 0A 60 6C 34 35 26 27 19 0C 61|
;|5|6D 73 28 74 1A 0D 62 6E 3A 36    1B 75 2B 63 76|
;|6|55 56 77 78 79 7A 0E 7B 7C 4F 7D 4B 47 7E 7F 6F|
;|7|52 53 50 4C 4D 48 01 45 57 4E 51 4A 37 49 46 54|
;\-------------------------------------------------/

; Маска клавиатуры:
;/---------------------------------------------------------------------------\
;| | 0  | 1  | 2  | 3   | 4 | 5 | 6 | 7 | 8 | 9   | 10  |11    | 12   | 13   |
;|-|----|----|----|-----|---|---|---|---|---|-----|--------------------------|
;|0|Стоп|Пуск|Закр|Стоп | 1 | 9 | 17| 25|<1>|Возвр|Доп  |Д2    | Д1   |      |
;|1| -  |Del>|Del<|Откр | 2 | 10| 18| 26|<2>| Р   |least|Груп  |Мнем  | ВО   |
;|2| +  | *  | /  |Кв 1 | 3 | 11| 19| 27|<3>| А   |les  |Граф 3|Граф 2|Граф 1|
;|3| 9  | 8  | 7  |Кв 2 | 4 | 12| 20| 28|<4>| К   |tab  |Руч ВВ| ТАБЛ | ПЕЧ  |
;|4| 6  | 5  | 4  |Кв 3 | 5 | 13| 21| 29|<5>| АП  |more | Ф3   | Ф2   | Ф1   |
;|5| 3  | 2  | 1  |Ввод | 6 | 14| 22| 30|<6>| УВМ |most | Ф6   | Ф5   | Ф4   |
;|6| .  | 0  |Ввод|     | 7 | 15| 23| 31|<7>| Up  |Down | ?    | РЕК  | ПОМ  |
;|7|    |    |    |     | 8 | 16| 24| 32|<8>|Left |Right|      |Лист >|Лист <|
;\---------------------------------------------------------------------------/
; Светодиоды:
; /----------------------------------\
; | | 0 | 1 | 2 | 3 | 4  |   5  | 6  |
; |-|---|---|---|---|----|------|----|
; |0| 1 | 9 |17 |25 |Закр|Квит 1|Д1  |
; |1| 2 |10 |18 |26 |    |Квит 2|Д2  |
; |2| 3 |11 |19 |27 |Откр|Квит 3|Пит |
; |3| 4 |12 |20 |28 |Пуск| ИМ   |    |
; |4| 5 |13 |21 |29 |Стоп| З    |    |
; |5| 6 |14 |22 |30 |    |      |    |
; |6| 7 |15 |23 |31 |    |      |    |
; |7| 8 |16 |24 |32 |    |      |    |
; \----------------------------------/
PushKey1:
db 09h,00h, 00h,7Dh,74h,7Ah, 00h, 00h ;0 - 7
db 01h,00h, 00h,75h,73h,72h, 00h, 00h ;8 -0F
db 79h,00h,0E0h,6Ch,6Bh,69h, 00h, 00h ;10-17
db 7Ch,7Bh, 54h,5Bh,4Bh,5Ah, 00h, 00h ;18-1F
db 16h,1Eh, 26h,25h,2Eh,36h, 3Dh, 3Eh ;20-27
db 15h,1Dh, 24h,2Dh,2Ch,35h, 3Ch, 43h ;28-2F
db 00h,00h, 00h,00h,00h,00h, 00h, 00h ;30-37
db 00h,00h, 00h,00h,00h,00h, 00h, 00h ;38-3F
db 05h,06h, 04h,0Ch,03h,0Bh, 02h, 0Ah ;40-47
db 76h,46h, 45h,4Eh,52h,00h,0E0h,0E0h ;48-4F
db 12h,1Ah, 41h,0Dh,49h,22h,0E0h,0E0h ;50-57
db 5Dh,42h, 31h,3Bh,44h,2Bh, 4Ah, 00h ;58-5F
db 0Eh,3Ah, 32h,23h,1Bh,4Ch, 00h,0E0h ;60-67
db 00h,4Dh, 2Ah,34h,1Ch,21h, 33h,0E0h ;68-6F
db 00h,00h, 00h,00h,00h,00h, 00h, 00h ;70-77
db 00h,00h, 00h,00h,00h,00h, 00h, 00h ;78-7F
PushKey2:
db 00h,00h,00h,00h,00h,00h,00h,00h ;0 - 7
db 00h,00h,00h,00h,00h,00h,00h,00h ;8 -0F
db 00h,00h,4Ah,00h,00h,00h,00h,00h ;10-17
db 00h,00h,00h,00h,00h,00h,00h,00h ;18-1F
db 00h,00h,00h,00h,00h,00h,00h,00h ;20-27
db 00h,00h,00h,00h,00h,00h,00h,00h ;28-2F
db 00h,00h,00h,00h,00h,00h,00h,00h ;30-37
db 00h,00h,00h,00h,00h,00h,00h,00h ;38-3F
db 00h,00h,00h,00h,00h,00h,00h,00h ;40-47
db 00h,00h,00h,00h,00h,00h,75h,74h ;48-4F
db 00h,00h,00h,00h,00h,00h,72h,6Bh ;50-57
db 00h,00h,00h,00h,00h,00h,00h,00h ;58-5F
db 00h,00h,00h,00h,00h,00h,00h,7Ah ;60-67
db 00h,00h,00h,00h,00h,00h,00h,7Dh ;68-6F
db 00h,00h,00h,00h,00h,00h,00h,00h ;70-77
db 00h,00h,00h,00h,00h,00h,00h,00h ;78-7F
PushKey3:
db 00h,00h,00h,00h,00h,00h,00h,00h ;0 - 7
db 00h,00h,00h,00h,00h,00h,00h,00h ;8 -0F
db 00h,00h,00h,00h,00h,00h,00h,00h ;10-17
db 00h,00h,00h,00h,00h,00h,00h,00h ;18-1F
db 00h,00h,00h,00h,00h,00h,00h,00h ;20-27
db 00h,00h,00h,00h,00h,00h,00h,00h ;28-2F
db 00h,00h,00h,00h,00h,00h,00h,00h ;30-37
db 00h,00h,00h,00h,00h,00h,00h,00h ;38-3F
db 00h,00h,00h,00h,00h,00h,00h,00h ;40-47
db 00h,00h,00h,00h,00h,00h,00h,00h ;48-4F
db 00h,00h,00h,00h,00h,00h,00h,00h ;50-57
db 00h,00h,00h,00h,00h,00h,00h,00h ;58-5F
db 00h,00h,00h,00h,00h,00h,00h,00h ;60-67
db 00h,00h,00h,00h,00h,00h,00h,00h ;68-6F
db 00h,00h,00h,00h,00h,00h,00h,00h ;70-77
db 00h,00h,00h,00h,00h,00h,00h,00h ;78-7F 
;PushKey4:
;db 00h,00h,00h,00h,00h,00h,00h,00h ;0 - 7
;db 00h,00h,00h,00h,00h,00h,00h,00h ;8 -0F
;db 00h,00h,00h,00h,00h,00h,00h,00h ;10-17
;db 00h,00h,00h,00h,00h,00h,00h,00h ;18-1F
;db 00h,00h,00h,00h,00h,00h,00h,00h ;20-27
;db 00h,00h,00h,00h,00h,00h,00h,00h ;28-2F
;db 00h,00h,00h,00h,00h,00h,00h,00h ;30-37
;db 00h,00h,00h,00h,00h,00h,00h,00h ;38-3F
;db 00h,00h,00h,00h,00h,00h,00h,0Ah ;40-47
;db 00h,00h,00h,00h,00h,00h,00h,00h ;48-4F
;db 00h,00h,00h,00h,00h,00h,00h,00h ;50-57
;db 00h,00h,00h,00h,00h,00h,00h,00h ;58-5F
;db 00h,00h,00h,00h,00h,00h,00h,00h ;60-67
;db 00h,00h,00h,00h,00h,00h,00h,00h ;68-6F
;db 00h,00h,00h,00h,00h,00h,00h,00h ;70-77
;db 00h,00h,00h,00h,00h,00h,00h,00h ;78-7F 


PopKey1:
db 0F0h, 00h, 00h,0F0h,0F0h,0F0h, 00h, 00h ;0 - 7
db 0F0h, 00h, 00h,0F0h,0F0h,0F0h, 00h, 00h ;8 -0F
db 0F0h, 00h,0E0h,0F0h,0F0h,0F0h, 00h, 00h ;10-17
db 0F0h,0F0h,0F0h,0F0h,0F0h,0F0h, 00h, 00h ;18-1F
db 0F0h,0F0h,0F0h,0F0h,0F0h,0F0h,0F0h,0F0h ;20-27
db 0F0h,0F0h,0F0h,0F0h,0F0h,0F0h,0F0h,0F0h ;28-2F
db  00h, 00h, 00h, 00h, 00h, 00h, 00h, 00h ;30-37
db  00h, 00h, 00h, 00h, 00h, 00h, 00h, 00h ;38-3F
db 0F0h,0F0h,0F0h,0F0h,0F0h,0F0h,0F0h,0F0h ;40-47
db 0F0h,0F0h,0F0h,0F0h,0F0h, 00h,0E0h,0E0h ;48-4F
db 0F0h,0F0h,0F0h,0F0h,0F0h,0F0h,0E0h,0E0h ;50-57
db 0F0h,0F0h,0F0h,0F0h,0F0h,0F0h,0F0h, 00h ;58-5F
db 0F0h,0F0h,0F0h,0F0h,0F0h,0F0h, 00h,0E0h ;60-67
db  00h,0F0h,0F0h,0F0h,0F0h,0F0h,0F0h,0E0h ;68-6F
db  00h, 00h, 00h, 00h, 00h, 00h, 00h, 00h ;70-77
db  00h, 00h, 00h, 00h, 00h, 00h, 00h, 00h ;78-7F
PopKey2:
db 09h,00h, 00h,7Dh,74h,7Ah, 00h, 00h ;0 - 7
db 01h,00h, 00h,75h,73h,72h, 00h, 00h ;8 -0F
db 79h,00h,0F0h,6Ch,6Bh,69h, 00h, 00h ;10-17
db 7Ch,7Bh, 54h,5Bh,4Bh,5Ah, 00h, 00h ;18-1F
db 16h,1Eh, 26h,25h,2Eh,36h, 3Dh, 3Eh ;20-27
db 15h,1Dh, 24h,2Dh,2Ch,35h, 3Ch, 43h ;28-2F
db 00h,00h, 00h,00h,00h,00h, 00h, 00h ;30-37
db 00h,00h, 00h,00h,00h,00h, 00h, 00h ;38-3F
db 05h,06h, 04h,0Ch,03h,0Bh, 02h, 0Ah ;40-47
db 76h,46h, 45h,4Eh,52h,00h,0F0h,0F0h ;48-4F
db 12h,1Ah, 41h,0Dh,49h,22h,0F0h,0F0h ;50-57
db 5Dh,42h, 31h,3Bh,44h,2Bh, 4Ah, 00h ;58-5F
db 0Eh,3Ah, 32h,23h,1Bh,4Ch, 00h,0F0h ;60-67
db 00h,4Dh, 2Ah,34h,1Ch,21h, 33h,0F0h ;68-6F
db 00h,00h, 00h,00h,00h,00h, 00h, 00h ;70-77
db 00h,00h, 00h,00h,00h,00h, 00h, 00h ;78-7F
PopKey3:
db  00h,00h,00h,00h,00h,00h, 00h, 00h ;0 - 7
db  00h,00h,00h,00h,00h,00h, 00h, 00h ;8 -0F
db  00h,00h,4Ah,00h,00h,00h, 00h, 00h ;10-17
db  00h,00h,00h,00h,00h,00h, 00h, 00h ;18-1F
db  00h,00h,00h,00h,00h,00h, 00h, 00h ;20-27
db  00h,00h,00h,00h,00h,00h, 00h, 00h ;28-2F
db  00h,00h,00h,00h,00h,00h, 00h, 00h ;30-37
db  00h,00h,00h,00h,00h,00h, 00h, 00h ;38-3F
db  00h,00h,00h,00h,00h,00h, 00h, 00h ;40-47
db  00h,00h,00h,00h,00h,00h, 75h, 74h ;48-4F
db  00h,00h,00h,00h,00h,00h, 72h, 6Bh ;50-57
db  00h,00h,00h,00h,00h,00h, 00h, 00h ;58-5F
db  00h,00h,00h,00h,00h,00h, 00h, 7Ah ;60-67
db  00h,00h,00h,00h,00h,00h, 00h, 7Dh ;68-6F
db  00h,00h,00h,00h,00h,00h, 00h, 00h ;70-77
db  00h,00h,00h,00h,00h,00h, 00h, 00h ;78-7F
;PopKey4:
;db 00h,00h,00h,00h,00h,00h,00h,00h ;0 - 7
;db 00h,00h,00h,00h,00h,00h,00h,00h ;8 -0F
;db 00h,00h,00h,00h,00h,00h,00h,00h ;10-17
;db 00h,00h,00h,00h,00h,00h,00h,00h ;18-1F
;db 00h,00h,00h,00h,00h,00h,00h,00h ;20-27
;db 00h,00h,00h,00h,00h,00h,00h,00h ;28-2F
;db 00h,00h,00h,00h,00h,00h,00h,00h ;30-37
;db 00h,00h,00h,00h,00h,00h,00h,00h ;38-3F
;db 00h,00h,00h,00h,00h,00h,00h,00h ;40-47
;db 00h,00h,00h,00h,00h,00h,00h,00h ;48-4F
;db 00h,00h,00h,00h,00h,00h,00h,00h ;50-57
;db 00h,00h,00h,00h,00h,00h,00h,00h ;58-5F
;db 00h,00h,00h,00h,00h,00h,00h,00h ;60-67
;db 00h,00h,00h,00h,00h,00h,00h,00h ;68-6F
;db 00h,00h,00h,00h,00h,00h,00h,00h ;70-77
;db 00h,00h,00h,00h,00h,00h,00h,00h ;78-7F 


END

