;mini-MOYA

	LIST	P=PIC16F84A
	LIST	R=DECIMAL
	include	"p16f84a.inc"
	__config _CP_OFF&_PWRTE_ON&_WDT_OFF&_HS_OSC

led_buf equ 0x10
pwm_saw equ 0x11
rxd     equ 0x12
status  equ 0x13
dat_cnt equ 0x14
key_num equ 0x15
key_bas equ 0x16
value7  equ 0x28
value6  equ 0x29
value5  equ 0x2A
value4  equ 0x2B
value3  equ 0x2C
value2  equ 0x2D
value1  equ 0x2E
value0  equ 0x2F


    org 0
    goto    start
    retfie
    retfie
    retfie
    retfie
start
    bcf     STATUS,RP0
    movlw   0xFF
    movwf   PORTA
    movwf   PORTB

    bsf     STATUS,RP0
    movlw   0xFF
    movwf   TRISA           ; RA4-0: In
    movlw   0x00
    movwf   TRISB           ; RB7-0: Out
    movlw   0xFF
    movwf   OPTION_REG
    bcf     STATUS,RP0

    movlw   0x90;A0            ; PolyKeyPres
    movwf   status
    movfw   PORTA
    movlw   60
    movwf   key_bas
    clrf    value0
    clrf    value1
    clrf    value2
    clrf    value3
    clrf    value4
    clrf    value5
    clrf    value6
    clrf    value7
    clrf    pwm_saw
    clrf    dat_cnt

  movlw 0x10
  movwf value1
  movlw 0x20
  movwf value2
  movlw 0x30
  movwf value3
  movlw 0x40
  movwf value4
  movlw 0x50
  movwf value5
  movlw 0x60
  movwf value6
  movlw 0x70
  movwf value7

IdlePwm
    call    PWM
IdleLoop
    btfsc   PORTA,0
     goto   IdlePwm
StartBit
    call    PWM
    nop
    call    PWM
    call    PWM
    movlw   0x80
    movwf   rxd
DataBit
    rrf     PORTA,w
    rrf     rxd,f
    skpnc
     goto   StopBit
    call    PWM
    nop
    nop
    nop
    nop
    nop
    nop
    nop
    call    PWM
    nop
    goto    DataBit

StopBit
    call    PWM
    nop
    nop
    nop
    nop
    nop
    call    PWM
    nop
    nop
    nop
    nop
    nop
    rrf     PORTA,w
    skpc
     goto   IdleLoop    ; StopBitError
ParseMidi
    rlf     rxd,w
    skpc
     goto   ParseData
ParseStatus
    movfw   rxd
    sublw   0xF7
    skpc
     goto   IdleLoop    ; Status > 0xF7 (RealTime)
    clrf    dat_cnt
    movfw   rxd
    subwf   status,w
    skpz
     goto   IdleLoop    ; Not the Status
    movlw   2
    movwf   dat_cnt     ; dat_cnt=2
    goto    IdleLoop

ParseData
    movfw   dat_cnt
    skpnz
     goto   IdleLoop    ; Invalid Data
    decf    dat_cnt,f
    skpnz
     goto   SecondData
FirstData
    movfw   rxd
    movwf   key_num
    goto    IdleLoop

SecondData
    movlw   2
    movwf   dat_cnt     ; dat_cnt=2
    movfw   key_bas
    subwf   key_num,w   ; key_num - key_bas
    skpc
     goto   IdleLoop    ; w < 0
    sublw   7           ; 7 - w
    skpc
     goto   IdleLoop    ; w > 7
    addlw   value7
    movwf   FSR
    movfw   rxd
    movwf   INDF
    goto    IdleLoop


PWM
    movfw   value0
    subwf   pwm_saw,w
    rrf     led_buf,f
    movfw   value1
    subwf   pwm_saw,w
    rrf     led_buf,f
    movfw   value2
    subwf   pwm_saw,w
    rrf     led_buf,f
    movfw   value3
    subwf   pwm_saw,w
    rrf     led_buf,f
    movfw   value4
    subwf   pwm_saw,w
    rrf     led_buf,f
    movfw   value5
    subwf   pwm_saw,w
    rrf     led_buf,f
    movfw   value6
    subwf   pwm_saw,w
    rrf     led_buf,f
    movfw   value7
    subwf   pwm_saw,w
    rrf     led_buf,f
    movfw   led_buf
    movwf   PORTB
    incf    pwm_saw,w
    andlw   0x7F
    movwf   pwm_saw
    return

    END
