;----------------------------------------------------------- ; ; MIDI --> Train Control : June 2006 ; ; for Shimada [1] ; ;----------------------------------------------------------- ;##### 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 paddr .equ h'0fffd1 padr .equ h'0fffd3 iprb .equ h'0ffff8 tstr .equ h'0fff60 tsnc .equ h'0fff61 tmdr .equ h'0fff62 tfcr .equ h'0fff63 toer .equ h'0fff90 tocr .equ h'0fff91 tcr0 .equ h'0fff64 tior0 .equ h'0fff65 tier0 .equ h'0fff66 tsr0 .equ h'0fff67 tcnt0 .equ h'0fff68 gra0 .equ h'0fff6a ;##### Vector Defines ##### .section vector,data,locate=h'000000 .data.l start .org h'000060 .data.l int_timer0 .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 timer3 .res.w 1 rx_top .res.w 1 rx_end .res.w 1 rsb .res.b 1 channel .res.b 1 dcb .res.b 1 keyno .res.b 1 data .res.b 1 flag .res.b 1 pa_data .res.b 1 speed .res.b 1 counter .res.b 1 density .res.b 1 .org h'0ff400 rx_fifo .res.b 1024 ;***** Reset --> Initialize --> Main Loop ***** .section program,code,locate=h'001000 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 mov.b #b'00100011,r0l mov.b r0l,@tcr0 ; Timer0 init : 2MHz clock bclr #0,@tsr0 ; Clear IMFA bset #0,@tier0 ; timer INT set mov.w #200,r0 ; 0.1msec INT mov.w r0,@gra0 jsr @sci0_init ; SCI initialize mov.b #b'11111111,r0l mov.b r0l,@paddr ; set : Port[A] all output mov.b #b'00000000,r0l mov.b r0l,@pa_data mov.b r0l,@padr ; off mov.b #32,r0l mov.b r0l,@speed mov.b r0l,@density jsr @wait_500msec mov.b #b'01110000,r0l ; tx/rx start ! mov.b r0l,@scr bset #0,@tstr ; timer start ! andc.b #b'01111111,ccr ; interrupt enable loop: jsr @timer_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 ;***** 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 int_timer0: push.w r0 mov.b #1,r0l mov.b r0l,@flag btst #0,@tsr0 bclr #0,@tsr0 ; Clear IMFA pop.w r0 rte timer_check: mov.b @flag,r0l cmp.b #0,r0l bne _timer_event rts _timer_event: mov.b #0,r0l mov.b r0l,@flag jsr @led_check jsr @motor_check rts led_check: mov.w @timer1,r0 inc.w #1,r0 mov.w r0,@timer1 cmp.w #1280,r0 beq t128msec rts t128msec: mov.w #0,r0 mov.w r0,@timer1 mov.w @timer2,r0 inc.w #1,r0 mov.w r0,@timer2 cmp.w #8,r0 beq t1sec rts t1sec: mov.w #0,r0 mov.w r0,@timer2 mov.b @pa_data,r1l mov.b r1l,r2l and.b #b'00001111,r2l xor.b #b'00010000,r1l and.b #b'00010000,r1l or.b r2l,r1l mov.b r1l,@pa_data mov.b r1l,@padr 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: rts _3byte: mov.b #0,r1h mov.b r1h,@dcb mov.b r0h,@data mov.b @rsb,r0l cmp.b #h'a0,r0l ; A* event ? beq _hit_01 rts _hit_01: mov.b #15,r0l mov.b @channel,r1l cmp.b r1l,r0l beq _hit_02 ; AF ? rts _hit_02: mov.b @keyno,r1l cmp.b #0,r1l beq _hit_03 cmp.b #1,r1l beq _hit_04 cmp.b #2,r1l beq _hit_05 cmp.b #3,r1l beq _hit_06 cmp.b #4,r1l beq _hit_07 rts _hit_03: mov.b @pa_data,r1l mov.b r1l,r2l and.b #b'00011110,r2l mov.b @data,r0l cmp.b #0,r0l beq _bit0_clear _bit0_set: mov.b #b'00000001,r1l bra _03_mix _bit0_clear: mov.b #0,r1l _03_mix: or.b r2l,r1l mov.b r1l,@pa_data mov.b r1l,@padr rts _hit_04: mov.b @pa_data,r1l mov.b r1l,r2l and.b #b'00011101,r2l mov.b @data,r0l cmp.b #0,r0l beq _bit1_clear _bit1_set: mov.b #b'00000010,r1l bra _04_mix _bit1_clear: mov.b #0,r1l _04_mix: or.b r2l,r1l mov.b r1l,@pa_data mov.b r1l,@padr rts _hit_05: mov.b @pa_data,r1l mov.b r1l,r2l and.b #b'00011011,r2l mov.b @data,r0l cmp.b #0,r0l beq _bit2_clear _bit2_set: mov.b #b'00000100,r1l bra _05_mix _bit2_clear: mov.b #0,r1l _05_mix: or.b r2l,r1l mov.b r1l,@pa_data mov.b r1l,@padr rts _hit_06: mov.b @data,r1l cmp.b #0,r1l bne _06_cont rts _06_cont: mov.b r1l,@speed rts _hit_07: mov.b @data,r1l mov.b r1l,@density rts motor_check: mov.b @counter,r0l inc.b r0l mov.b r0l,@counter cmp.b #128,r0l bne _speed_check mov.b #0,r0l mov.b r0l,@counter mov.b @pa_data,r1l mov.b r1l,r2l and.b #b'00010111,r2l mov.b #b'00001000,r1l or.b r2l,r1l mov.b r1l,@pa_data mov.b r1l,@padr rts _speed_check: mov.b @speed,r1l cmp.b r1l,r0l beq _speed_hit rts _speed_hit: mov.b @pa_data,r1l and.b #b'00010111,r1l mov.b r1l,@pa_data mov.b r1l,@padr rts .end