;------------------------------------------------- ; ; CQ-Book2 TTL-DSP controller : January 1999 ; ;------------------------------------------------- ;##### 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 p1ddr .equ h'0fffc0 p1dr .equ h'0fffc2 p2ddr .equ h'0fffc1 p2dr .equ h'0fffc3 p3ddr .equ h'0fffc4 p3dr .equ h'0fffc6 paddr .equ h'0fffd1 padr .equ h'0fffd3 pbddr .equ h'0fffd4 pbdr .equ h'0fffd6 iscr .equ h'0ffff4 ier .equ h'0ffff5 ;##### Vector Defines ##### .section vector,data,locate=h'000000 .data.l start .org h'000030 .data.l int_irq0 .org h'0000d0 .data.l int_rx_error .data.l int_rx_full ;##### Work RAM Data Defines ##### .section ram,data,locate=h'0fef10 rx_top .res.w 1 rx_end .res.w 1 ev_top .res.w 1 ev_end .res.w 1 timer1 .res.w 1 timer2 .res.w 1 rsb .res.b 1 dcb .res.b 1 channel .res.b 1 keyno .res.b 1 data .res.b 1 counter .res.b 1 led .res.b 1 ch .res.b 1 prog .res.b 1 flag .res.b 1 init .res.b 1 enum .res.b 1 result .res.b 1 active .res.b 1 ctr .res.b 1 assign .res.b 16 .org h'0ff400 rx_fifo .res.b 1024 ev_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,@p1ddr ; set : Port[1] all output mov.b r0l,@p2ddr ; set : Port[2] all output mov.b r0l,@p3ddr ; set : Port[3] all output mov.b r0l,@pbddr ; set : Port[B] all output mov.b #b'10111111,r0l mov.b r0l,@paddr ; set : Port[A] bit6=input mov.b #0,r0l mov.b r0l,@p1dr mov.b r0l,@p2dr ; all key bit = OFF mov.b #b'11111111,r0l mov.b r0l,@padr mov.b #b'00000001,r0l mov.b r0l,@ier mov.b r0l,@iscr ; IRQ0 down edge enable mov.b #3,r0l mov.b r0l,@enum ; default Envelope Speed mov.b #b'10000000,r1h mov.l #0,er0 _init_assign: mov.b r1h,@(assign,er0) inc.b r1h inc.b r0l cmp.b #16,r0l bne _init_assign jsr @wait_500msec mov.b #b'01010000,r0l ; rx start ! mov.b r0l,@scr andc #b'01111111,ccr ; interrupt enable jsr @dsp_initial loop: jsr @timer_check jsr @event_check jsr @rx_midi_check bra loop ;***** SCI init 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 ;***** Hand-Shake IRQ0 ***** int_irq0: push.w r0 mov.b @flag,r0l beq _irq_exit mov.b #b'01111111,r0l mov.b r0l,@padr mov.b #b'11111111,r0l mov.b r0l,@padr mov.b @padr,r0l btst #6,r0l bne _irq_exit mov.b #0,r0l mov.b r0l,@flag _irq_exit: pop.w r0 rte ;***** 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 #50,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,@p3dr ; write to Port[3] 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,@p3dr ; write to Port[3] 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 cmp.b #h'c0,r0l ; MIDI 1CH Prog ? beq _program cmp.b #h'cf,r0l ; MIDI 16CH Envelope Speed ? beq _envelope rts _program: mov.b @data,r0l and.b #b'00000111,r0l shll.b r0l shll.b r0l shll.b r0l shll.b r0l mov.b r0l,@prog mov.b r0l,r0h jsr @led_monitor mov.b @data,r0l and.b #b'00000111,r0l mov.b #0,r0h mov.w #0,e0 mov.b @(env_speed,er0),r1h mov.b r1h,@enum ; Envelope Speed rts env_speed: .data.b 3,4,2,6,5,4,3,1 _envelope: mov.b @data,r0l inc.b r0l mov.b r0l,@enum mov.b r0l,r0h 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 cmp.b #h'90,r0l ; MIDI 1CH On ? beq _90 cmp.b #h'80,r0l ; MIDI 1CH off ? beq _off rts _90: cmp.b #0,r0h ; velocity=0 ? beq _off _on: jsr @on_event_sequence rts _off: jsr @off_event_sequence rts ;***** Assigner / Handling for DSP Interface ***** off_event_sequence: mov.b #1,r0l mov.b r0l,@result jsr @off_assigner mov.b @result,r0l beq _off_key rts _off_key: mov.b @ch,r0l btst #3,r0l bne _off_8 mov.b #0,r0h mov.w #0,e0 mov.b @(off_key_bit,er0),r1l mov.b @p1dr,r0l and.b r1l,r0l mov.b r0l,@p1dr rts _off_8: and.b #b'00000111,r0l mov.b #0,r0h mov.w #0,e0 mov.b @(off_key_bit,er0),r1l mov.b @p2dr,r0l and.b r1l,r0l mov.b r0l,@p2dr rts off_key_bit: .data.b b'11111110,b'11111101,b'11111011,b'11110111 .data.b b'11101111,b'11011111,b'10111111,b'01111111 on_event_sequence: mov.b #1,r0l mov.b r0l,@result jsr @on_assigner mov.b @result,r0l beq _on_key rts _on_key: jsr @ev_fifo_set mov.b @keyno,r0h jsr @led_monitor mov.b @ch,r0l btst #3,r0l bne _on_8 mov.b #0,r0h mov.w #0,e0 mov.b @(on_key_bit,er0),r1l mov.b @p1dr,r0l or.b r1l,r0l mov.b r0l,@p1dr rts _on_8: and.b #b'00000111,r0l mov.b #0,r0h mov.w #0,e0 mov.b @(on_key_bit,er0),r1l mov.b @p2dr,r0l or.b r1l,r0l mov.b r0l,@p2dr rts on_key_bit: .data.b 1,2,4,8,16,32,64,128 off_assigner: mov.b @keyno,r2l ; [R2L] MIDI off Keyno mov.l #0,er0 ; [R0L] check assigner ch _off_loop_1: mov.b @(assign,er0),r1l cmp.b r2l,r1l beq _off_hit_1 inc.b r0l cmp.b #16,r0l bne _off_loop_1 rts _off_hit_1: mov.b r0l,@ch ; this CH ! mov.b #16,r1h mov.b @active,r2h sub.b r2h,r1h ; 16 - active or.b #b'10000000,r1h mov.b r1h,@(assign,er0) ; newest empty CH mov.b @active,r0l dec.b r0l mov.b r0l,@active mov.b #0,r0l mov.b r0l,@result ; normal return rts on_assigner: mov.b @active,r0l cmp.b #16,r0l ; 16 CH full ? bne _on_empty rts _on_empty: mov.b @keyno,r2l ; [R2L] MIDI ON Keyno mov.l #0,er0 ; [R0L] check assigner ch _on_loop_1: mov.b @(assign,er0),r1l cmp.b r2l,r1l beq _on_error inc.b r0l cmp.b #16,r0l bne _on_loop_1 mov.b #0,r0l ; [R0L] check assigner ch _on_loop_2: mov.b @(assign,er0),r1l btst #7,r1l beq _on_next cmp.b #b'10000000,r1l ; oldest empty CH ? beq _on_hit_1 dec.b r1l mov.b r1l,@(assign,er0) ; shift to older CH bra _on_next _on_hit_1: mov.b r0l,@ch ; this CH ! mov.b r2l,@(assign,er0) ; Keyno set to [assign] _on_next: inc.b r0l cmp.b #16,r0l bne _on_loop_2 mov.b @active,r0l inc.b r0l mov.b r0l,@active mov.b #0,r0l mov.b r0l,@result ; normal return _on_error: rts ev_fifo_set: mov.w @ev_top,r4 mov.w #0,e4 mov.b @ch,r1l mov.b r1l,@(ev_fifo,er4) ; MSB=0 : (1) CH inc.w #1,r4 bclr #2,r4h mov.b @keyno,r0l shal.b r0l mov.b #0,r0h mov.w #0,e0 mov.w @(f_number,er0),r1 mov.b r1h,@(ev_fifo,er4) ; (2) fnum H inc.w #1,r4 bclr #2,r4h mov.b r1l,@(ev_fifo,er4) ; (3) fnum L inc.w #1,r4 bclr #2,r4h mov.b @ch,r1l or.b #b'10000000,r1l mov.b r1l,@(ev_fifo,er4) ; MSB=1 : (1) CH inc.w #1,r4 bclr #2,r4h mov.b @data,r1l shlr.b r1l shlr.b r1l shlr.b r1l mov.b @prog,r1h or.b r1h,r1l mov.b r1l,@(ev_fifo,er4) ; (2) prg,touch inc.w #1,r4 bclr #2,r4h mov.b @enum,r1l mov.b r1l,@(ev_fifo,er4) ; (3) ENVnum inc.w #1,r4 bclr #2,r4h mov.w r4,@ev_top rts f_number: .data.w 21,23,24,26,27,29,31,32 ; 0-8 .data.w 34,36,39,41,43,46,49,52 ; 9-15 .data.w 55,58,62,65,69,73,78,82 ; 16-23 .data.w 87,93,98,104,110,117,124,131 ; 24-31 .data.w 139,147,156,165,175,186,197,208 ; 32-39 .data.w 221,234,248,263,278,295,312,331 ; 40-47 .data.w 351,372,394,417,442,468,496,526 ; 48-55 .data.w 557,590,625,662,702,744,788,835 ; 56-63 .data.w 884,937,993,1052,1114,1181,1251,1325 ; 64-71 .data.w 1404,1488,1576,1670,1769,1874,1986,2104 ; 72-79 .data.w 2229,2362,2502,2651,2809,2976,3153,3340 ; 80-87 .data.w 3539,3749,3972,4209,4459,4724,5005,5303 ; 88-95 .data.w 5618,5952,6306,6681,7078,7499,7945,8418 ; 96-103 .data.w 8918,9448,10010,10606,11236,11904,12612,13362 ; 104-111 .data.w 14157,14999,15891,16836,17837,18897,20021,21212 ; 112-119 .data.w 22473,23809,25225,26725,28314,29998,31782,32767 ; 120-127 ;***** Event Check / DSP transfer ***** event_check: mov.b @flag,r0l beq _event_go rts _event_go: mov.w @ev_top,r1 mov.w @ev_end,r3 cmp.w r1,r3 bne _ev_exist rts _ev_exist: mov.w #0,e3 mov.b @(ev_fifo,er3),r1h ; data (1) -> [r1h] inc.w #1,r3 bclr #2,r3h mov.b @(ev_fifo,er3),r1l ; data (2) -> [r1l] inc.w #1,r3 bclr #2,r3h mov.b @(ev_fifo,er3),r2h ; data (3) -> [r2h] inc.w #1,r3 bclr #2,r3h mov.w r3,@ev_end btst #7,r1h ; fnum / Enum ? bne _ev_env _ev_fn: mov.b r1h,@pbdr mov.b #b'11111011,r0l mov.b r0l,@padr mov.b #b'11111111,r0l mov.b r0l,@padr ; mode = 00 latch mov.b r1l,@pbdr mov.b #b'11111101,r0l mov.b r0l,@padr mov.b #b'11111111,r0l mov.b r0l,@padr ; fnum H latch mov.b r2h,@pbdr mov.b #b'11111110,r0l mov.b r0l,@padr mov.b #b'11111111,r0l mov.b r0l,@padr ; fnum L latch mov.b #1,r0l mov.b r0l,@flag rts _ev_env: and.b #b'00001111,r1h or.b #b'00100000,r1h mov.b r1h,@pbdr mov.b #b'11111011,r0l mov.b r0l,@padr mov.b #b'11111111,r0l mov.b r0l,@padr ; mode = 10 latch mov.b r1l,@pbdr mov.b #b'11111101,r0l mov.b r0l,@padr mov.b #b'11111111,r0l mov.b r0l,@padr ; prog+touch mov.b r2h,@pbdr mov.b #b'11111110,r0l mov.b r0l,@padr mov.b #b'11111111,r0l mov.b r0l,@padr ; ENV speed mov.b #1,r0l mov.b r0l,@flag rts ;***** DSP Initialize Routine ***** dsp_initial: mov.b #0,r0l mov.b r0l,@init _dsp_loop_1: jsr @init_check_1 mov.b @init,r0l inc.b r0l mov.b r0l,@init cmp.b #16,r0l bne _dsp_loop_1 mov.b #0,r0l mov.b r0l,@init _dsp_loop_2: jsr @init_check_2 mov.b @init,r0l inc.b r0l mov.b r0l,@init cmp.b #16,r0l bne _dsp_loop_2 mov.b #0,r0l mov.b r0l,@init _dsp_loop_3: jsr @init_check_3 mov.b @init,r0l inc.b r0l mov.b r0l,@init cmp.b #16,r0l bne _dsp_loop_3 mov.b #0,r0l mov.b r0l,@init _dsp_loop_4: jsr @init_check_4 mov.b @init,r0l inc.b r0l mov.b r0l,@init cmp.b #16,r0l bne _dsp_loop_4 rts init_check_1: mov.b @flag,r0l bne init_check_1 mov.b @init,r2h mov.b r2h,@pbdr mov.b #b'11111011,r0l mov.b r0l,@padr mov.b #b'11111111,r0l mov.b r0l,@padr ; mode = 00 latch mov.b #0,r1h mov.b r1h,@pbdr mov.b #b'11111110,r0l mov.b r0l,@padr mov.b #b'11111111,r0l mov.b r0l,@padr ; data L mov.b r1h,@pbdr mov.b #b'11111101,r0l mov.b r0l,@padr mov.b #b'11111111,r0l mov.b r0l,@padr ; data H mov.b #1,r0l mov.b r0l,@flag _init_wait_1: mov.b @flag,r0l bne _init_wait_1 rts init_check_2: mov.b @flag,r0l bne init_check_2 mov.b @init,r2h or.b #b'00010000,r2h mov.b r2h,@pbdr mov.b #b'11111011,r0l mov.b r0l,@padr mov.b #b'11111111,r0l mov.b r0l,@padr ; mode = 01 latch mov.b #0,r1h mov.b r1h,@pbdr mov.b #b'11111110,r0l mov.b r0l,@padr mov.b #b'11111111,r0l mov.b r0l,@padr ; data L mov.b r1h,@pbdr mov.b #b'11111101,r0l mov.b r0l,@padr mov.b #b'11111111,r0l mov.b r0l,@padr ; data H mov.b #1,r0l mov.b r0l,@flag _init_wait_2: mov.b @flag,r0l bne _init_wait_2 rts init_check_3: mov.b @flag,r0l bne init_check_3 mov.b @init,r2h or.b #b'00100000,r2h mov.b r2h,@pbdr mov.b #b'11111011,r0l mov.b r0l,@padr mov.b #b'11111111,r0l mov.b r0l,@padr ; mode = 10 latch mov.b #0,r1h mov.b r1h,@pbdr mov.b #b'11111110,r0l mov.b r0l,@padr mov.b #b'11111111,r0l mov.b r0l,@padr ; data L mov.b r1h,@pbdr mov.b #b'11111101,r0l mov.b r0l,@padr mov.b #b'11111111,r0l mov.b r0l,@padr ; data H mov.b #1,r0l mov.b r0l,@flag _init_wait_3: mov.b @flag,r0l bne _init_wait_3 rts init_check_4: mov.b @flag,r0l bne init_check_4 mov.b @init,r2h or.b #b'00110000,r2h mov.b r2h,@pbdr mov.b #b'11111011,r0l mov.b r0l,@padr mov.b #b'11111111,r0l mov.b r0l,@padr ; mode = 11 latch mov.b #0,r1h mov.b r1h,@pbdr mov.b #b'11111110,r0l mov.b r0l,@padr mov.b #b'11111111,r0l mov.b r0l,@padr ; data L mov.b r1h,@pbdr mov.b #b'11111101,r0l mov.b r0l,@padr mov.b #b'11111111,r0l mov.b r0l,@padr ; data H mov.b #1,r0l mov.b r0l,@flag _init_wait_4: mov.b @flag,r0l bne _init_wait_4 rts .end