;KoroKoro Rx 1
; Ir In / MIDI Out

	LIST	P=PIC16F84
	LIST	R=DECIMAL
	include	"p16f84.inc"
	__config _CP_OFF&_PWRTE_ON&_WDT_OFF&_XT_OSC

;---------------------------------------
;PortA 0-4 LED Kathode (LoActive Scan)
;PortB 0-4 LED Anode (HiActive)
;      5   MIDI Out (LoActive)
;      6   in
;      7   Ir In
;---------------------------------------

    cblock  0x0c

    rx_data1
    rx_data2
    bit_cnt
    dly_cnt
    led_num
    led_a
    led_b
    out_b
    note_num
    tx_reg
    tx_lcnt
    tx_wcnt
    err_cnt1
    err_cnt2

    endc

;---------------------------------------
IRRX    equ 7       ; PORTB.7 : IR RX

;---------------------------------------
    org 0
    goto    start
    retfie
    retfie
    retfie
    retfie
start
    bcf     STATUS,RP0
    movlw   0xFF
    movwf   PORTA
    movlw   0x20
    movwf   out_b
    movwf   PORTB

    bsf     STATUS,RP0
    movlw   0xE0
    movwf   TRISA
    movlw   0xC0
    movwf   TRISB
    movlw   0x7F
    movwf   OPTION_REG

    bcf     STATUS,RP0
    clrf    note_num

MainLoop1
    movlw   0xff
    movwf   PORTA
    movlw   0x20
    movwf   out_b
    movwf   PORTB

    movf    note_num,w
    skpnz
     goto   MainLoop2
    call    Note_Off
    clrf    note_num

MainLoop2
    movlw   40
    movwf   err_cnt1
WaitRx1
    decf    err_cnt1
    skpnz
     goto   MainLoop1
    clrf    err_cnt2
WaitRx2
    decf    err_cnt2
    skpnz
     goto   WaitRx1
    btfsc   PORTB,IRRX      ; wait for IRRX==0
     goto   WaitRx2

;---------------------------------------
    call    Dly405cyc
    btfsc   PORTB,IRRX      ; if IRRX==0
     goto   MainLoop2       ; then abort

    movlw   5
    movwf   bit_cnt
RxDataLoop10
    call    Dly825cyc
    setc
    btfsc   PORTB,IRRX
    clrc
    rrf     rx_data1,f
    decfsz  bit_cnt,f
     goto   RxDataLoop10

;---------------------------------------
    movlw   7
    movwf   bit_cnt
RxDataLoop20
    call    Dly825cyc
    clrc
    btfsc   PORTB,IRRX
    setc
    rrf     rx_data2,f
    decfsz  bit_cnt,f
     goto   RxDataLoop20

    rrf     rx_data1,f
    rrf     rx_data1,f
    rrf     rx_data1,w
    andlw   0x1f
    movwf   rx_data1

    rrf     rx_data2,f
    rrf     rx_data2,w
    andlw   0x1f
    movwf   rx_data2

    movf    rx_data1,w
    xorwf   rx_data2,w
    skpz
     goto   MainLoop1

;---------------------------------------
LED_Out
    movf    rx_data1,w
    sublw   24            ; led_num = 24-rx_data
    movwf   led_num
    movlw   1
    movwf   led_a
    movwf   led_b

loop1
    movlw   5
    subwf   led_num,f
    skpc
     goto   loop2
    clrc
    rlf     led_b,f
    goto    loop1
loop2
    movlw   5
    addwf   led_num,f

loop3
    movlw   1
    subwf   led_num,f
    skpc
     goto   loop4
    clrc
    rlf     led_a,f
    goto    loop3
loop4
    comf    led_a,w
    movwf   PORTA
    movfw   led_b
    iorlw   0x20
    movwf   out_b
    movwf   PORTB

;---------------------------------------
MIDI_Note
    movf    rx_data1,w
    addlw   60
    movwf   rx_data1
    subwf   note_num,w
    skpnz
     goto   MainLoop2

    movf    note_num,w
    skpnz
     goto   new_note
    call    Note_Off
new_note
    movf    rx_data1,w
    movwf   note_num
    call    Note_On
    goto    MainLoop2

;---------------------------------------
Note_On
    movlw   0x90
    call    Midi_Out
    movf    note_num,w
    call    Midi_Out
    movlw   96
    call    Midi_Out
    return

Note_Off
    movlw   0x90
    call    Midi_Out
    movf    note_num,w
    call    Midi_Out
    movlw   0
    call    Midi_Out
    return

Midi_Out
    movwf   tx_reg
    bcf     out_b,5     ;start bit
    movf    out_b,w
    movwf   PORTB
    call    midi_out_wait
    nop
    nop
    movlw   8
    movwf   tx_lcnt
midi_out_loop
    btfsc   tx_reg,0
    bsf     out_b,5
    btfss   tx_reg,0
    bcf     out_b,5
    movf    out_b,w
    movwf   PORTB
    call    midi_out_wait
    rrf     tx_reg,f
    decfsz  tx_lcnt,f
     goto   midi_out_loop
midi_out_stop_bit
    nop
    nop
    nop
    nop
    bsf     out_b,5     ;stop bit
    movf    out_b,w
    movwf   PORTB
    call    midi_out_wait
    nop
    return

midi_out_wait           ; 20@4MHz 68@10MHz
    nop
    nop
    movlw   5           ; 5@4MHz  21@10MHz
    movwf   tx_wcnt
midi_wait_loop
    decfsz  tx_wcnt,f
     goto   midi_wait_loop
    return

;---------------------------------------
Dly825cyc
    movlw   205
    movwf   dly_cnt
Dly820cycLoop
    nop
    decfsz  dly_cnt,f
     goto   Dly820cycLoop
    return

;---------------------------------------
Dly405cyc
    movlw   100
    movwf   dly_cnt
Dly400cycLoop
    nop
    decfsz  dly_cnt,f
     goto   Dly400cycLoop
    return

;---------------------------------------

    END
