;-------------------------------------------------
;
;       AKI-H8 startup module for C : April 1998
;
;               ( MIDI transmit/receive FIFO )
;
;-------------------------------------------------

;##### Common Defines for C interface #####
        .import _c_initial, _c_main
        .import _c_midi_rx
        .export _tx_d, _status, _keyno, _data
        .export _tx_fifo_set

;##### SCI/Int 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
iprb    .equ    h'0ffff8

;##### Work RAM Data Defines #####
        .section ram,data,locate=h'0fef10
rx_top  .res.w  1
rx_end  .res.w  1
tx_top  .res.w  1
tx_end  .res.w  1
rsb     .res.b  1
dcb     .res.b  1
channel .res.b  1
_tx_d   .res.b  1
_status .res.b  1
_keyno  .res.b  1
_data   .res.b  1
        .org    h'0ff000
rx_fifo .res.b  1024
        .org    h'0ff400
tx_fifo .res.b  1024

;##### Vector/Routines Area #####
        .section program,code,locate=h'000000
        .org    h'000000
        .data.l start
        .org    h'0000d0
        .data.l int_rx_error
        .data.l int_rx_full
        .org    h'000100
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
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
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
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   @_tx_d,r0h
        mov.b   r0h,@(tx_fifo,er6)
        inc.w   #1,r6
        bclr    #2,r6h
        mov.w   r6,@tx_top
        rts
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,@_status
        jsr     @_c_midi_rx
        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,@_status
        jsr     @_c_midi_rx
        rts

;##### Main Program #####
start:
        mov.l   #h'0fff10,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
        jsr     @_c_initial             ; C initialize module
        jsr     @wait_500msec
        mov.b   #b'01110000,r0l         ; tx/rx start !
        mov.b   r0l,@scr
        andc    #b'01111111,ccr         ; interrupt enable
loop:
        jsr     @_c_main
        jsr     @tx_midi_check
        jsr     @rx_midi_check
        jmp     @loop

        .end
