;----------------------------------------------------------- ; ; 2 voice MIDI chime : September 1998 ; ; MIDI = 1ch, 2ch ; PWM = program Change 0/1 (0-127) ; Decay Speed = program Change 2/3 (0-127) ; ;----------------------------------------------------------- ;##### 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 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 GRB0 .equ h'0fff6C TCR1 .equ h'0fff6E TIOR1 .equ h'0fff6F TIER1 .equ h'0fff70 TSR1 .equ h'0fff71 TCNT1 .equ h'0fff72 GRA1 .equ h'0fff74 GRB1 .equ h'0fff76 TCR2 .equ h'0fff78 TIOR2 .equ h'0fff79 TIER2 .equ h'0fff7A TSR2 .equ h'0fff7B TCNT2 .equ h'0fff7C GRA2 .equ h'0fff7E GRB2 .equ h'0fff80 TCR3 .equ h'0fff82 TIOR3 .equ h'0fff83 TIER3 .equ h'0fff84 TSR3 .equ h'0fff85 TCNT3 .equ h'0fff86 GRA3 .equ h'0fff88 GRB3 .equ h'0fff8A BRA3 .equ h'0fff8C BRB3 .equ h'0fff8E TCR4 .equ h'0fff92 TIOR4 .equ h'0fff93 TIER4 .equ h'0fff94 TSR4 .equ h'0fff95 TCNT4 .equ h'0fff96 GRA4 .equ h'0fff98 GRB4 .equ h'0fff9A BRA4 .equ h'0fff9C BRB4 .equ h'0fff9E dadr0 .equ h'0fffdc dadr1 .equ h'0fffdd dacr .equ h'0fffde dastcr .equ h'0fff5c ;##### 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 timer3 .res.w 1 rx_top .res.w 1 rx_end .res.w 1 pitch0 .res.w 1 pitch1 .res.w 1 env0 .res.w 1 env1 .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 tone0 .res.b 1 tone1 .res.b 1 speed0 .res.b 1 speed1 .res.b 1 .org h'0ff400 rx_fifo .res.b 512 ;***** Constant Table Defines ***** .section rom,data,locate=h'001000 table_p: .data.w 61156,57722,54482,51424,48538,45814,43242,40816,38524,36362,34322,32396 ; 00-11 .data.w 61156,57722,54482,51424,48538,45814,43242,40816,38524,36362,34322,32396 ; 12-23 .data.w 61156,57722,54482,51424,48538,45814,43242,40816,38524,36362,34322,32396 ; 24-35 .data.w 30578,28861,27241,25712,24269,22907,21621,20408,19262,18181,17161,16198 ; 36-47 .data.w 15289,14430,13620,12856,12134,11453,10810,10204,9631,9090,8580,8099 ; 48-59 .data.w 7644,7215,6810,6428,6067,5726,5405,5102,4815,4545,4290,4049 ; 60-71 .data.w 3822,3607,3405,3214,3033,2863,2702,2551,2407,2272,2145,2024 ; 72-83 .data.w 1911,1803,1702,1607,1516,1431,1351,1275,1203,1136,1072,1012 ; 84-95 .data.w 955,901,851,803,758,715,675,637,601,568,536,506 ; 96-107 .data.w 477,450,425,401,379,357,337,318,300,284,268,253 ; 108-119 .data.w 238,225,212,200,189,178,168,159 ; 120-127 ;***** Reset --> Initialize --> Main Loop ***** .section program,code,locate=h'002000 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 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 mov.b #b'01000011,r0l ; Initialize TCR0 mov.b r0l,@TCR0 ; clock= 2MHz mov.b #b'01000011,r0l ; Initialize TCR1 mov.b r0l,@TCR1 ; clock= 2MHz mov.b #b'00000011,r0l mov.b r0l,@tmdr ; PWM mode mov.b #b'00010010,r0l ; Initialize TIOR0 mov.b r0l,@TIOR0 ; mov.b #b'00010010,r0l ; Initialize TIOR1 mov.b r0l,@TIOR1 ; bset #0,@tstr ; Start ITU ch0 bset #1,@tstr ; Start ITU ch1 mov.b #b'11100000,r0l mov.b r0l,@dacr mov.b #64,r0l mov.b r0l,@tone0 mov.b r0l,@tone1 mov.b r0l,@speed0 mov.b r0l,@speed1 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 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: jsr @envelope_check 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 #1,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 #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 @channel,r1l or.b r1l,r0l cmp.b #h'0c0,r0l beq _tc0 cmp.b #h'0c1,r0l beq _tc1 cmp.b #h'0c2,r0l beq _tc2 cmp.b #h'0c3,r0l beq _tc3 rts _tc0: mov.b r0h,@tone0 mov.w @pitch0,r2 mov.b r0h,r3h shal.b r3h bset #0,r3h mov.b #h'ff,r3l extu.l er3 mulxu.w r2,er3 mov.w e3,@GRA0 ; New Frequency ! rts _tc1: mov.b r0h,@tone1 mov.w @pitch1,r2 mov.b r0h,r3h shal.b r3h bset #0,r3h mov.b #h'ff,r3l extu.l er3 mulxu.w r2,er3 mov.w e3,@GRA1 ; New Frequency ! rts _tc2: mov.b r0h,@speed0 rts _tc3: mov.b r0h,@speed1 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'090,r0l beq _ch0 cmp.b #h'091,r0l beq _ch1 rts _ch0: cmp.b #0,r0h bne _ok_ch0 rts _ch1: cmp.b #0,r0h bne _ok_ch1 rts _ok_ch0: mov.b @keyno,r0l shal.b r0l extu.w r0 extu.l er0 mov.w @(table_p,er0),r2 mov.w r2,@GRB0 ; New Frequency ! mov.w r2,@pitch0 mov.b @tone0,r3h shal.b r3h bset #0,r3h mov.b #h'ff,r3l extu.l er3 mulxu.w r2,er3 mov.w e3,@GRA0 ; New Frequency ! mov.w #h'FFFF,r1 mov.w r1,@env0 ; New Envelope ! rts _ok_ch1: mov.b @keyno,r0l shal.b r0l extu.w r0 extu.l er0 mov.w @(table_p,er0),r2 mov.w r2,@GRB1 ; New Frequency ! mov.w r2,@pitch1 mov.b @tone1,r3h shal.b r3h bset #0,r3h mov.b #h'ff,r3l extu.l er3 mulxu.w r2,er3 mov.w e3,@GRA1 ; New Frequency ! mov.w #h'FFFF,r1 mov.w r1,@env1 ; New Envelope ! rts ;***** Envelope check ***** envelope_check: mov.w @env0,r2 mov.b @speed0,r3h shal.b r3h bset #0,r3h mov.b #h'ff,r3l extu.l er3 mulxu.w r2,er3 mov.w e3,@env0 ; New Envelope ! mov.w @env1,r2 mov.b @speed1,r3h shal.b r3h bset #0,r3h mov.b #h'ff,r3l extu.l er3 mulxu.w r2,er3 mov.w e3,@env1 ; New Envelope ! mov.w @env0,r1 mov.b r1h,@dadr0 mov.w @env1,r1 mov.b r1h,@dadr1 ; D/A output ! rts .end