;-----------------------------------------------------------
;
;       RS232C <---> MIDI converter : July 1998
;
;-----------------------------------------------------------

;##### 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
smr1    .equ    h'0fffb8
brr1    .equ    h'0fffb9
scr1    .equ    h'0fffba
tdr1    .equ    h'0fffbb
ssr1    .equ    h'0fffbc
rdr1    .equ    h'0fffbd
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
        .org    h'0000e0
        .data.l int_rx_error1
        .data.l int_rx_full1

;##### Work RAM Data Defines #####
        .section ram,data,locate=h'0fef10
timer1          .res.w  1
timer2          .res.w  1
timer3          .res.w  1
rx_top          .res.w  1
rx_end          .res.w  1
tx_top          .res.w  1
tx_end          .res.w  1
rx_top1         .res.w  1
rx_end1         .res.w  1
tx_top1         .res.w  1
tx_end1         .res.w  1
rsb             .res.b  1
channel         .res.b  1
dcb             .res.b  1
keyno           .res.b  1
data            .res.b  1
rsb1            .res.b  1
channel1        .res.b  1
dcb1            .res.b  1
keyno1          .res.b  1
data1           .res.b  1
counter         .res.b  1
led             .res.b  1
        .org    h'0ff400
rx_fifo         .res.b  512
        .org    h'0ff600
tx_fifo         .res.b  512
        .org    h'0ff800
rx_fifo1        .res.b  512
        .org    h'0ffa00
tx_fifo1        .res.b  512

;***** 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              ; SCI0 initialize
        jsr     @sci1_init              ; SCI1 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
        mov.b   r0l,@scr1
        andc    #b'01111111,ccr         ; interrupt enable
loop:
        jsr     @timer_check
        jsr     @tx_midi_check
        jsr     @rx_midi_check
        jsr     @tx_midi_check1
        jsr     @rx_midi_check1
        jmp     @loop

;***** SCI init, RS232C/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
        rts
sci1_init:
        mov.b   #b'00000000,r0l
        mov.b   r0l,@scr1
        mov.b   #b'00000000,r0l
        mov.b   r0l,@smr1
        mov.b   #25,r0l                 ; 19200
        mov.b   r0l,@brr1
        mov.w   #500,r0
_sci1_wait:
        dec.w   #1,r0
        bne     _sci1_wait
        mov.b   @ssr1,r0l               ; (dummy read)
        mov.b   #0,r0l
        mov.b   r0l,@ssr1
        mov.b   #b'00001100,r0l
        mov.b   r0l,@iprb               ; SCI0/1-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    #1,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    #1,r6h
        mov.w   r6,@tx_top
        rts
tx_midi_check1:
        mov.w   @tx_top1,r1
        mov.w   @tx_end1,r6
        cmp.w   r1,r6
        bne     _tx_exist1
        rts
_tx_exist1:
        btst    #7,@ssr1                ; test TRDE
        bne     _tx_seq1
        rts
_tx_seq1:
        mov.w   #0,e6
        mov.b   @(tx_fifo1,er6),r0l
        mov.b   r0l,@tdr1
        bclr    #7,@ssr1                ; Transmit !
        inc.w   #1,r6
        bclr    #1,r6h
        mov.w   r6,@tx_end1
        rts
tx_fifo_set1:
        mov.w   @tx_top1,r6
        mov.w   #0,e6
        mov.b   r0h,@(tx_fifo1,er6)     ; transmit data = [r0h]
        inc.w   #1,r6
        bclr    #1,r6h
        mov.w   r6,@tx_top1
        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, RS232C/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    #1,r5h
        mov.w   r5,@rx_top
        pop.l   er5
        pop.w   r0
        rte
int_rx_error1:
        bclr    #5,@ssr1
        bclr    #4,@ssr1
        rte
int_rx_full1:
        push.w  r0
        push.l  er5
        btst    #6,@ssr1
        bclr    #6,@ssr1
        mov.w   @rx_top1,r5
        mov.w   #0,e5
        mov.b   @rdr1,r0l
        mov.b   r0l,@(rx_fifo1,er5)
        inc.w   #1,r5
        bclr    #1,r5h
        mov.w   r5,@rx_top1
        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    #1,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_set1
        mov.b   @data,r0h
        jsr     @tx_fifo_set1
        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_set1
        mov.b   @keyno,r0h
        jsr     @tx_fifo_set1
        jsr     @led_monitor
        mov.b   @data,r0h
        jsr     @tx_fifo_set1
        rts

rx_midi_check1:
        mov.w   @rx_top1,r1
        mov.w   @rx_end1,r5
        cmp.w   r1,r5
        bne     _rx_exist1
        rts
_rx_exist1:
        mov.w   #0,e5
        mov.b   @(rx_fifo1,er5),r0h     ; received data = [r0h]
        inc.w   #1,r5
        bclr    #1,r5h
        mov.w   r5,@rx_end1
        btst    #7,r0h
        beq     running1
        mov.b   r0h,r0l
        and.b   #b'11111000,r0l
        cmp.b   #b'11111000,r0l
        bne     _lower_f81
        rts
_lower_f81:
        and.b   #b'11110000,r0l
        cmp.b   #b'11110000,r0l
        bne     _lower_f01
        mov.b   #0,r0l
        mov.b   r0l,@rsb1
        rts
_lower_f01:
        mov.b   r0h,r0l
        and.b   #b'00001111,r0l
        mov.b   r0l,@channel1
        mov.b   r0h,r0l
        and.b   #b'11110000,r0l
        mov.b   r0l,@rsb1
        mov.b   #0,r0l
        mov.b   r0l,@dcb1
        rts
running1:
        mov.b   @rsb1,r0l
        bne     _normal1
        rts
_normal1:
        cmp.b   #b'11000000,r0l
        beq     _2byte1
        cmp.b   #b'11010000,r0l
        beq     _2byte1
        mov.b   @dcb1,r1l
        bne     _3byte1
        inc.b   r1l
        mov.b   r1l,@dcb1
        mov.b   r0h,@keyno1
        rts
_2byte1:
        mov.b   r0h,@data1
        mov.b   @channel1,r1l
        or.b    r1l,r0l
        mov.b   r0l,r0h
        jsr     @tx_fifo_set
        mov.b   @data1,r0h
        jsr     @tx_fifo_set
        jsr     @led_monitor
        rts
_3byte1:
        mov.b   #0,r1h
        mov.b   r1h,@dcb1
        mov.b   r0h,@data1
        mov.b   @channel1,r1l
        or.b    r1l,r0l
        mov.b   r0l,r0h
        jsr     @tx_fifo_set
        mov.b   @keyno1,r0h
        jsr     @tx_fifo_set
        jsr     @led_monitor
        mov.b   @data1,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

