;ACC02 ADXL202
; MIDI Note Out

	LIST	P=PIC16F84
	LIST	R=DECIMAL
	include	"p16f84.inc"
	__config _CP_OFF&_PWRTE_ON&_WDT_OFF&_XT_OSC

tx_reg   equ 0x10
tx_lcnt  equ 0x11
tx_wcnt  equ 0x12
out_b    equ 0x13
wcnt1    equ 0x14
wcnt2    equ 0x15
x_cnt    equ 0x16
y_cnt    equ 0x17
x_new    equ 0x18
y_new    equ 0x19
x_old    equ 0x1A
y_old    equ 0x1B
x_pos    equ 0x1C
y_pos    equ 0x1D
lp_cnt   equ 0x1E
xy_num   equ 0x1F
note_num equ 0x20

;PortA 0-4 LED Kathode (LoActive Scan)
;PortB 0-4 LED Anode (HiActive)
;      5   MIDI Out (HiActive)
;      6   X in
;      7   Y in

    org 0
    goto    start
    retfie
    retfie
    retfie
    retfie
start
    bcf     STATUS,RP0
    movlw   0xFF
    movwf   PORTA
    movlw   0x00
    movwf   PORTB

    bsf     STATUS,RP0
    movlw   0xE0
    movwf   TRISA
    movlw   0xC0
    movwf   TRISB
    movlw   0x7F
    movwf   OPTION_REG

    bcf     STATUS,RP0

Main_Loop

    clrf    x_new
X_wait_low
    btfsc   PORTB,6
     goto   X_wait_low
X_rise
    btfss   PORTB,6
     goto   X_rise
X_fall
    incf    x_new,f
    btfsc   PORTB,6
     goto   X_fall

    clrf    y_new
Y_wait_low
    btfsc   PORTB,7
     goto   Y_wait_low
Y_rise
    btfss   PORTB,7
     goto   Y_rise
Y_fall
    incf    y_new,f
    btfsc   PORTB,7
     goto   Y_fall

X_check
    movf    x_old,w	
    subwf   x_new,w     ; d=new-old
     bnc    X_check20
X_check10               ; new>=old
    sublw   1           ; 1-d
     bc     X_check30
    movf    x_new,w     ; 1<d
    movwf   x_old
    decf    x_old,f     ; old = new-1
    goto    X_check30
X_check20               ; new<old
    sublw   0xFF        ; 0xFF-d
     bz     X_check30
    movf    x_new,w     ; d != -1
    movwf   x_old
    incf    x_old,f     ; old = new+1
X_check30

Y_check
    movf    y_old,w	
    subwf   y_new,w     ; d=new-old
     bnc    Y_check20
Y_check10               ; new>=old
    sublw   1           ; 1-d
     bc     Y_check30
    movf    y_new,w     ; 1<d
    movwf   y_old
    decf    y_old,f     ; old = new-1
    goto    Y_check30
Y_check20               ; new<old
    sublw   0xFF        ; 0xFF-d
     bz     Y_check30
    movf    y_new,w     ; d != -1
    movwf   y_old
    incf    y_old,f     ; old = new+1
Y_check30

X_position
    movf    x_old,w
    movwf   x_cnt
    movlw   1
    movwf   x_pos
    clrf    xy_num
    movlw   110
    subwf   x_cnt,f
    skpc
     goto   X_pos_exit
    movlw   3
    movwf   lp_cnt
X_pos_loop
    clrc
    rlf     x_pos,f
    incf    xy_num,f
    movlw   8
    subwf   x_cnt,f
    skpc
     goto   X_pos_exit
    decfsz  lp_cnt,f
     goto   X_pos_loop
    clrc
    rlf     x_pos,f
    incf    xy_num,f
X_pos_exit

Y_position
    movf    y_old,w
    movwf   y_cnt
    movlw   1
    movwf   y_pos
    movlw   114
    subwf   y_cnt,f
    skpc
     goto   Y_pos_exit
    movlw   3
    movwf   lp_cnt
Y_pos_loop
    clrc
    rlf     y_pos,f
    movlw   5
    addwf   xy_num,f
    movlw   8
    subwf   y_cnt,f
    skpc
     goto   Y_pos_exit
    decfsz  lp_cnt,f
     goto   Y_pos_loop
    clrc
    rlf     y_pos,f
    movlw   5
    addwf   xy_num,f
Y_pos_exit
    movf    x_pos,w
    movwf   out_b
    movwf   PORTB
    movlw   0x1F
    xorwf   y_pos,w
    movwf   PORTA

    movf    xy_num,w
    addlw   60
    movwf   xy_num
    subwf   note_num,w
    skpnz
     goto   Main_Loop
    call    Note_Off
    movf    xy_num,w
    movwf   note_num
    call    Note_On
    goto    Main_Loop

Note_On
    movlw   0x90
    call    Midi_Out
    movf    note_num,w
    call    Midi_Out
    movlw   96
    call    Midi_Out
    return
    
Note_Off
    movlw   0x80
    call    Midi_Out
    movf    note_num,w
    call    Midi_Out
    movlw   64
    call    Midi_Out
    return
    
Midi_Out
    movwf   tx_reg
    bsf     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
    bcf     out_b,5
    btfss   tx_reg,0
    bsf     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
    bcf     out_b,5     ;stop bit
    movf    out_b,w
    movwf   PORTB
    call    midi_out_wait
    nop
    return

midi_in_wait
    nop                 ; 5nops@4MHz
    nop
    nop
    nop
    nop
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

    END
