;-------------------------------------------------
;       AKI-H8 sample : April 1998
;               MIDI in ---> MIDI out (through)
;               MIDI 2nd byte (7bit) LED dislay
;               LED bit7 toggle display
;-------------------------------------------------

;##### Port Defines #####
smr     .equ    h'0fffb0
brr     .equ    h'0fffb1
scr     .equ    h'0fffb2
tdr     .equ    h'0fffb3
ssr     .equ    h'0fffb4
rdr     .equ    h'0fffb5
pbddr   .equ    h'0fffd4
pbdr    .equ    h'0fffd6
iprb    .equ    h'0ffff8

;##### Vector Defines #####
        .section vector,data,locate=h'000000
        .data.l start
        .org    h'0000d0
        .data.l int_rx_error
        .data.l int_rx_full

;##### Work RAM Data Defines #####
        .section ram,data,locate=h'0fef10
timer1  .res.w  1
timer2  .res.w  1
rx_top  .res.w  1
rx_end  .res.w  1
tx_top  .res.w  1
tx_end  .res.w  1
rsb     .res.b  1
channel .res.b  1
dcb     .res.b  1
keyno   .res.b  1
data    .res.b  1
counter .res.b  1
led     .res.b  1
        .org    h'0ff400
rx_fifo .res.b  1024
        .org    h'0ff800
tx_fifo .res.b  1024

;***** Reset --> Initialize --> Main Loop *****
        .section program,code,locate=h'000100
start:
        mov.l   #h'0fff0f,er7           ; stack pointer set
        mov.l   #h'0fef10,er2
        mov.w   #h'0fe0,r1
        mov.b   #0,r0l
_ram_clear:
        mov.b   r0l,@er2
        inc.l   #1,er2
        dec.w   #1,r1
        bne     _ram_clear
        jsr     @sci0_init              ; SCI initialize
        mov.b   #b'11111111,r0l
        mov.b   r0l,@pbddr              ; set : Port[B] all output
        jsr     @wait_500msec
        mov.b   #b'01110000,r0l         ; tx/rx start !
        mov.b   r0l,@scr
        andc    #b'01111111,ccr         ; interrupt enable
loop:
        jsr     @timer_check
        jsr     @tx_midi_check
        jsr     @rx_midi_check
        jmp     @loop

;***** SCI init / MIDI Transmit Routines *****
sci0_init:
        mov.b   #b'00000000,r0l
        mov.b   r0l,@scr
        mov.b   #b'00000000,r0l
        mov.b   r0l,@smr
        mov.b   #15,r0l
        mov.b   r0l,@brr
        mov.w   #500,r0
_sci0_wait:
        dec.w   #1,r0
        bne     _sci0_wait
        mov.b   @ssr,r0l                ; (dummy read)
        mov.b   #0,r0l
        mov.b   r0l,@ssr
        mov.b   #b'00001000,r0l
        mov.b   r0l,@iprb               ; SCI0-int priority UP !
        rts
tx_midi_check:
        mov.w   @tx_top,r1
        mov.w   @tx_end,r6
        cmp.w   r1,r6
        bne     _tx_exist
        rts
_tx_exist:
        btst    #7,@ssr                 ; test TRDE
        bne     _tx_seq
        rts
_tx_seq:
        mov.w   #0,e6
        mov.b   @(tx_fifo,er6),r0l
        mov.b   r0l,@tdr
        bclr    #7,@ssr                 ; Transmit !
        inc.w   #1,r6
        bclr    #2,r6h
        mov.w   r6,@tx_end
        rts
tx_fifo_set:
        mov.w   @tx_top,r6
        mov.w   #0,e6
        mov.b   r0h,@(tx_fifo,er6)      ; transmit data = [r0h]
        inc.w   #1,r6
        bclr    #2,r6h
        mov.w   r6,@tx_top
        rts

;***** Timer / Counter Routines *****
wait_500msec:
        mov.l   #500,er1
_wait_1:
        jsr     @wait_1msec
        sub.l   #1,er1
        bne     _wait_1
        rts
wait_1msec:
        mov.l   #2048,er2
_wait_2:
        sub.l   #1,er2
        bne     _wait_2
        rts
timer_check:
        mov.w   @timer1,r1
        inc.w   #1,r1
        mov.w   r1,@timer1
        beq     _timer_1
        rts
_timer_1:
        mov.w   @timer2,r1
        inc.w   #1,r1
        mov.w   r1,@timer2
        cmp.w   #80,r1
        bne     _timer_2
        mov.w   #0,r1
        mov.w   r1,@timer2
_timer_2:
        mov.b   @counter,r0l
        inc.b   r0l
        mov.b   r0l,@counter
        mov.b   @led,r0l
        bnot    #7,r0l
        mov.b   r0l,@led
        mov.b   r0l,@pbdr               ; write to Port[B]
        rts

;***** Rx Interrupt / MIDI Receive Routines *****
int_rx_error:
        bclr    #5,@ssr
        bclr    #4,@ssr
        rte
int_rx_full:
        push.w  r0
        push.l  er5
        btst    #6,@ssr
        bclr    #6,@ssr
        mov.w   @rx_top,r5
        mov.w   #0,e5
        mov.b   @rdr,r0l
        mov.b   r0l,@(rx_fifo,er5)
        inc.w   #1,r5
        bclr    #2,r5h
        mov.w   r5,@rx_top
        pop.l   er5
        pop.w   r0
        rte
rx_midi_check:
        mov.w   @rx_top,r1
        mov.w   @rx_end,r5
        cmp.w   r1,r5
        bne     _rx_exist
        rts
_rx_exist:
        mov.w   #0,e5
        mov.b   @(rx_fifo,er5),r0h      ; received data = [r0h]
        inc.w   #1,r5
        bclr    #2,r5h
        mov.w   r5,@rx_end
        btst    #7,r0h
        beq     running
        mov.b   r0h,r0l
        and.b   #b'11111000,r0l
        cmp.b   #b'11111000,r0l
        bne     _lower_f8
        rts
_lower_f8:
        and.b   #b'11110000,r0l
        cmp.b   #b'11110000,r0l
        bne     _lower_f0
        mov.b   #0,r0l
        mov.b   r0l,@rsb
        rts
_lower_f0
        mov.b   r0h,r0l
        and.b   #b'00001111,r0l
        mov.b   r0l,@channel
        mov.b   r0h,r0l
        and.b   #b'11110000,r0l
        mov.b   r0l,@rsb
        mov.b   #0,r0l
        mov.b   r0l,@dcb
        rts
running:
        mov.b   @rsb,r0l
        bne     _normal
        rts
_normal:
        cmp.b   #b'11000000,r0l
        beq     _2byte
        cmp.b   #b'11010000,r0l
        beq     _2byte
        mov.b   @dcb,r1l
        bne     _3byte
        inc.b   r1l
        mov.b   r1l,@dcb
        mov.b   r0h,@keyno
        rts
_2byte:
        mov.b   r0h,@data
        mov.b   @channel,r1l
        or.b    r1l,r0l
        mov.b   r0l,r0h
        jsr     @tx_fifo_set
        mov.b   @data,r0h
        jsr     @tx_fifo_set
        jsr     @led_monitor
        rts
_3byte:
        mov.b   #0,r1h
        mov.b   r1h,@dcb
        mov.b   r0h,@data
        mov.b   @channel,r1l
        or.b    r1l,r0l
        mov.b   r0l,r0h
        jsr     @tx_fifo_set
        mov.b   @keyno,r0h
        jsr     @tx_fifo_set
        jsr     @led_monitor
        mov.b   @data,r0h
        jsr     @tx_fifo_set
        rts

led_monitor:
        mov.b   @led,r0l
        mov.b   r0l,r2l
        and.b   #b'10000000,r2l
        mov.b   r0h,r2h
        and.b   #b'01111111,r2h
        or.b    r2l,r2h
        mov.b   r2h,@led
        mov.b   r2h,@pbdr               ; write to Port[B]
        rts

        .end
