; Підпрограма декодування протоколу RC5 в обробнику зовнішнього переривання на вході INT0 (чи INT1)
; Input - bit IR (interrupt line), активний рівень - низький.
; Out - byte, регістр R7 3 банка (безпосередня адреса ячейки памяті 1Fh),
; Його структура наступна: R7 = Х.С.D5.D4.D3.D2.D1.D0
; D0-D5 - командні біти коду RC5
; C - біт управління
; Х - значення підпрограмою не змінюється. Цей біт зручно використовувати як біт управління для місцевої клавіатури.
; Програма використовує регістровий банк 3. Інші регістри не змінюється.
; Константf CLK_KHZ використовується транслятором при визначенні значень для часових затримок,
; і може складати 4000 - 24000 KHz
; Основна програма повинна містити:
; org    03h            ;INT0 vector (or 13h for INT1 vector)
;    jmp    RC5
; переривання на зовнішньому вході повинно бути дозволено, і налаштоване по спаду (переходу із 1 в 0)
; Номера систем для деяких видів побутової техніки наведені нижче:
; 0 - Телевізор (TV)
; 2 - Телетекст
; 3 - Відеоданні
; 4 - Відеопрогравач (VLP)
; 5 - Кассетний відеомагнітофон (VCR)
; 8 - Відео тюнер (Sat.TV)
; 9 - Відеокамера
; 16 - Аудіо предусилитель
; 17 - Тюнер
; 18 - Магнітофон
; 20 - Компакт-проигравач (CD)
; 21 - Програвач (LP)
; 29 - Освітлення
IR    equ    INT0        ; Або INT1
SYS    equ    0        ; Номер системи
CLK_KHZ equ    11059        ; Тактова чатота (від 4000 до 24000 кГц)
RC5_DF    equ    B.0        ; Флаг даних
RC5_PF    equ    B.1        ; Флаг періода
RC5_N     equ    (1+2*(CLK_KHZ/188))/2
RC5_N1     equ    (1+2*(CLK_KHZ/249))/2
RC5_N2     equ    (1+2*(CLK_KHZ/382))/2
RC5_NT     equ    (1+2*(CLK_KHZ/135))/2
cseg
RC5:                            ; Підпограма декодування протоколу RC5
    push    PSW
    push    ACC
    push    B
    setb    RS0             ; Вибір банку 3
    setb    RS1
    mov    R6,DPH          ; Зберігаємо DPTR
    mov    R5,DPL
    mov    B,#2            ; Установка флагів
    mov    R2,#2        ; ІнІциализацІя байта системи для прийняття 7 бит
    mov    R3,#4        ; ІнІциализацІя байта команди для прийняття 6 бит
    mov    R0,#1Ah        ; Завантаження адреси регіста R2 у банку 3
    mov    R1,#RC5_N       ; Завантаження величини тайм-ауту 2362 мкс
WLow:    jb    IR,WHigh    ; Очікування одиниці на вході INT0 на протязі тайм-ауту
    mov    R4,#16
    djnz    R4,$
    djnz    R1,WLow
    jmp    No_RC5        ; Помилка, закінчився тайм-аут
WHigh:    mov    R1,#RC5_N       ; Завантаження величини тайм-ауту 2362 мкс
Sample:    mov    R4,#8
    djnz    R4,$
Sam1:    mov    R4,#3           ; Точки входа у цикл Sam1 .. Sam3 потрібні для вирівнювання часу виконання різних гілок
    djnz    R4,$
Sam2:    mov    R4,#2
    djnz    R4,$
Sam3:    mov    C,IR        ; Опитування входу
    mov    ACC.0,C
    xrl    A,B
    jnb    ACC.0,Trans     ; Очікування зміни стану
    djnz    R1,Sample    ; Sample IR up to 2362uS
    jmp    No_RC5        ; Помилка, закінчився тайм-аут
Trans:    cpl    RC5_DF        ; Передача зафіксована
    mov    A,R1
    ADD    A,#-RC5_N1
    JC    No_RC5        ; Помилка, час <577.5uS
    mov    A,R1
    ADD    A,#-RC5_N2
    JC    TRANS1
    jb    RC5_PF,No_RC5    ; Помилка, час >1200uS
    jmp    STData
Trans1:    cpl    RC5_PF          ; Інвертування флага періода
    mov    R1,#RC5_N    ; Завантаження величини тайм-ауту 2362 мкс
    jb    RC5_PF,SAM1     ; Прийом біта не завершено, перехід на опитування
STData:    mov    C,RC5_DF
    mov    A,@R0
    rlc    A               ; Збереження біта даних
    mov    @R0,A
    mov    R1,#RC5_N       ; Завантаження величини тайм-ауту 2362 мкс
    jnc    SAM2            ; Прийом системи не завершено, перехід на опитування
    inc    R0              ; Система прийнята, початок прийому команди
    mov    A,R0
    mov    R1,#RC5_N       ; Завантаження величини тайм-ауту 2362 мкс
    jnb    ACC.2,SAM3      ; Прийом системи не завершено, перехід на опитування
    mov    R1,#RC5_N       ; Завантаження величини тайм-ауту мкс
WLW:    jb    IR,TRM        ; Останній біт, очікування одиниці на вході
    mov    R4,#16
    djnz    R4,$
    djnz    R1,WLW        ; Wait up to 2362uS for IR = 1
    jmp    No_RC5        ; Помилка, закінчився тайм-аут
TRM:    mov    R1,#RC5_NT      ; Завантаження величини тайм-ауту 3000 мкс
TERM:    jnb    IR,No_RC5    ; Помилка, якщо на вході зафіксовано низький рівень
    mov    R4,#16
    djnz    R4,$
    djnz    R1,TERM
    mov    A,R2        ; Номер системи і біт управління в R2
    anl    A,#1Fh          ; Виділення номеру системи
    cjne    A,#SYS,No_RC5    ; Перевірка номеру системи
    mov    DPTR,#RC_Tab    ; Завантаження адреси таблиці
    mov    A,R3            ; Завантаження коду команди
    movc    A,@A+DPTR    ; Перекодування
    mov    R3,A            ; Збереження нового коду
    mov    A,R2            ; Номер системи і біт управління у R2
    anl    A,#20h          ; Виділення біта управління
    rl    A
    rl    A               ; Зсув біту управління у розряд D7
    orl    A,R3            ; Суміщення коду команди і біта управління
    mov    R3,A            ; Збереження результату
    mov    A,R7
    anl    A,#40h          ; Виділення біта управління місцевої клавіатури
    orl    A,R3            ; Суміщення коду команди і бітов управління
    mov    R7,A            ; Збереження результату
No_RC5:                ; Очищення флагу переривань
IF    IR=INT0
    clr    IE0
ELSE
    clr    IE1
ENDIF
    mov    DPL,R5
    mov    DPH,R6
    pop    B
    pop    ACC
    pop    PSW
    reti
    
RC_Tab:                         ; Таблиця кодів на 64 коди, це макимальна кількість. Щоб мікроконтроллер не реагував на непотрібні кнопки - просто закоментуйте зайві коди
    db    00h        ; key code 000H, key function - 0
    db    01h        ; key code 001H, key function - 1
    db    02h        ; key code 002H, key function - 2
    db    03h        ; key code 003H, key function - 3
    db    04h        ; key code 004H, key function - 4
    db    05h        ; key code 005H, key function - 5
    db    06h        ; key code 006H, key function - 6
    db    07h        ; key code 007H, key function - 7
    db    08h        ; key code 008H, key function - 8
    db    09h        ; key code 009H, key function - 9
    db    0Ah        ; key code 00AH, key function - 10
    db    0Bh        ; key code 00BH, key function - none
    db    0Ch        ; key code 00CH, key function - Черговий режим
    db    0Dh        ; key code 00DH, key function - mute
    db    0Eh        ; key code 00EH, key function - none
    db    0Fh        ; key code 00FH, key function - Дисплей
    db    10h        ; key code 010H, key function - FFD або гучність +
    db    11h        ; key code 011H, key function - REW або гучність -
    db    12h        ; key code 012H, key function - none
    db    13h        ; key code 013H, key function - none
    db    14h        ; key code 014H, key function - none
    db    15h        ; key code 015H, key function - none
    db    16h        ; key code 016H, key function - none
    db    17h        ; key code 017H, key function - none
    db    18h        ; key code 018H, key function - none
    db    19h        ; key code 019H, key function - none
    db    1Ah        ; key code 01AH, key function - none
    db    1Bh        ; key code 01BH, key function - none
    db    1Ch        ; key code 01CH, key function - none
    db    1Dh        ; key code 01DH, key function - none
    db    1Eh        ; key code 01EH, key function - OPEN або пошук вперед
    db    1Fh        ; key code 01FH, key function - пошук назад
    db    20h        ; key code 020H, key function - SEEK FFD
    db    21h        ; key code 021H, key function - SEEK REW
    db    22h        ; key code 022H, key function - SYNCHRO
    db    23h        ; key code 023H, key function - none
    db    24h        ; key code 024H, key function - none
    db    25h        ; key code 025H, key function - none
    db    26h        ; key code 026H, key function - none
    db    27h        ; key code 027H, key function - none
    db    28h        ; key code 028H, key function - none
    db    29h        ; key code 029H, key function - none
    db    2Ah        ; key code 02AH, key function - none
    db    2Bh        ; key code 02BH, key function - none
    db    2Ch        ; key code 02CH, key function - none
    db    2Dh        ; key code 02DH, key function - none
    db    2Eh        ; key code 02EH, key function - none
    db    2Fh        ; key code 02FH, key function - none
    db    30h        ; key code 030H, key function - none
    db    31h        ; key code 031H, key function - none
    db    32h        ; key code 032H, key function - none
    db    33h        ; key code 033H, key function - none
    db    34h        ; key code 034H, key function - none
    db    35h        ; key code 035H, key function - none
    db    36h        ; key code 036H, key function - none
    db    37h        ; key code 037H, key function - none
    db    38h        ; key code 038H, key function - PLAY
    db    39h        ; key code 039H, key function - none
    db    3Ah        ; key code 03AH, key function - none
    db    3Bh        ; key code 03BH, key function - PAUSE
    db    3Ch        ; key code 03CH, key function - none
    db    3Dh        ; key code 03DH, key function - none
    db    3Eh        ; key code 03EH, key function - none
    db    3Fh        ; key code 03FH, key function - STOP
end