.module REDUX; .include ; .include ; .global handle_MIDI_controller; .external process_midi; { signal processing variables here } { internal variables } .var last_input; .var last_output; .init last_output:0; { parameters here } .var/dm B; {quantization bits per sample} .var/dm L; {L least-significant bits thrown away} .var/dm M; {throw away every M bits} .var/dm N; {per N bits} .var/dm mTemp; .var/dm nTemp; {.var/dm/circ M[127] decimation ratio LUT} {.var/dm/circ N[127] decimation ratio LUT} { codec init variables } .var/dm/ram/circ rx_buf[3]; { Status + L data + R data } .var/dm/ram/circ tx_buf[3]; { Cmd + L data + R data } .var/dm/ram/circ init_cmds[13]; .var/dm stat_flag; .init tx_buf: 0xc000, 0x0000, 0x0000; { Initially set MCE } .init init_cmds:0xc007,0xc107,0xc288,0xc388,0xc488,0xc588,0xc680,0xc780, 0xc85c,0xc909,0xca00,0xcc40,0xcd00; { Interrupt vector table } jump start; rti; rti; rti; {00: reset } rti; rti; rti; rti; {04: IRQ2 } rti; rti; rti; rti; {08: IRQL1 } rti; rti; rti; rti; {0c: IRQL0 } ar = dm(stat_flag); {10: SPORT0 tx } ar = pass ar; if eq rti; jump next_cmd; jump input_samples; {14: SPORT1 rx } rti; rti; rti; rti; rti; rti; rti; {18: IRQE } rti; rti; rti; rti; {1c: BDMA } jump irq1isr;rti; rti; rti; {20: SPORT1 tx or IRQ1 } rti; rti; rti; rti; {24: SPORT1 rx or IRQ0 } rti; rti; rti; rti; {28: timer } rti; rti; rti; rti; {2c: power down } { ADSP 2181 intialization } start: m7 = 0; l7 = 0; ax0 = b#0000100000000000; dm (System_Control_Reg) = ax0; { shut down sport 0 } i7 = 0x3fe8; { restore monitor timer handler } ar = pm (i7, m7); { px implicit } i7 = 0x28; pm (i7, m7) = ar; i5 = ^rx_buf;l5 = %rx_buf; i6 = ^tx_buf;l6 = %tx_buf; i3 = ^init_cmds;l3 = %init_cmds; m1 = 1;m5 = 1; {================== S E R I A L P O R T #0 S T U F F ==================} ax0 = b#0000110011010111; dm (SPORT0_Autobuf) = ax0; ax0 = 0; dm (SPORT0_RFSDIV) = ax0; ax0 = 0; dm (SPORT0_SCLKDIV) = ax0; ax0 = b#1000011000001111; dm (SPORT0_Control_Reg) = ax0; ax0 = b#0000000000000111; dm (SPORT0_TX_Channels0) = ax0; ax0 = b#0000000000000111; dm (SPORT0_TX_Channels1) = ax0; ax0 = b#0000000000000111; dm (SPORT0_RX_Channels0) = ax0; ax0 = b#0000000000000111; dm (SPORT0_RX_Channels1) = ax0; {============== S Y S T E M A N D M E M O R Y S T U F F ==============} ax0 = b#0001100000000000; dm (System_Control_Reg) = ax0; ifc = b#00000011111111; { clear pending interrupt } nop; icntl = b#00010; mstat = b#1000000; { ADSP 1847 Codec intialization } ax0 = 1; dm(stat_flag) = ax0; { clear flag } ena ints; { enable transmit interrupt } imask = b#0001000000; ax0 = dm (i6, m5); { start interrupt } tx0 = ax0; check_init: ax0 = dm (stat_flag); { wait for entire init } af = pass ax0; { buffer to be sent to } if ne jump check_init; { the codec } ay0 = 2; check_aci1: ax0 = dm (rx_buf); { once initialized, wait for codec } ar = ax0 and ay0; { to come out of autocalibration } if eq jump check_aci1; { wait for bit set } check_aci2: ax0 = dm (rx_buf); { wait for bit clear } ar = ax0 and ay0; if ne jump check_aci2; idle; ay0 = 0xbf3f; { unmute left DAC } ax0 = dm (init_cmds + 6); ar = ax0 AND ay0; dm (tx_buf) = ar; idle; ax0 = dm (init_cmds + 7); { unmute right DAC } ar = ax0 AND ay0; dm (tx_buf) = ar; idle; ifc = b#00000011111111; { clear any pending interrupt } nop; l0=0; l1=0; l2=0; l3=0; l4=0; l7=0; imask = b#0000100101; { enable rx0 interrupt } call set_baud_31250; { set serial port to MIDI baud rate } call init_params; { initialize anything you need here } jump main_loop; { begin main codec loop! } set_baud_31250: .const CRYSTAL_FREQ_IN_kHZ= 16670; { Crystal speed related constant. } .const MIDIPERIOD = (CRYSTAL_FREQ_IN_kHZ * 2000 / (3 * 31250)) - 1; ax0=MIDIPERIOD; { autobaud not used } dm(TCOUNT)=ax0; dm(TPERIOD)=ax0; { interrupts generated at 3x baudrate } rts; { transmit interrupt used for Codec initialization } next_cmd: ena sec_reg; ax0 = dm (i3, m1); { fetch next control word and } dm (tx_buf) = ax0; { place in transmit slot 0 } ax0 = i3; ay0 = ^init_cmds; ar = ax0 - ay0; if gt rti; { rti if more control words still waiting } ax0 = 0xaf00; { else set done flag and } dm (tx_buf) = ax0; { remove MCE if done initialization } ax0 = 0; dm (stat_flag) = ax0; { reset status flag } rti; { MIDI serial port ISR - actually just enables timer, which calls timer interrupt to read the serial port } irq1isr: pop sts; ena timer; { start timer now } rts; { note rts } { do any dynamic memory/variable initializing you need to here } init_params: ax0 = 16; ay0 = 16; ar = ay0 - ax0; dm(B) = ax0; dm(L) = ar; ax0 = 128; ay0 = 8; dm(M) = ax0; dm(N) = ay0; dm(mTemp) = ax0; dm(nTemp) = ay0; nop; nop; nop; rts; { command loop - check for incoming data on serial port } main_loop: ar = dm (CHAR_WAITING_FLAG); { check serial port for MIDI data } none = pass ar; if ne jump main_loop; call process_midi; { if MIDI byte received } jump main_loop; { SPORT0 interrupt handler -- this is called at 44.1KHz } input_samples: ena sec_reg; { use shadow register bank } my0 = dm(rx_buf +1); { read a/d converters } my1 = dm(rx_buf +2); { leave left/right values in my0,my1 } {----------------------SAMPLE DECIMATION SECTION-------------------} {------------------------------------------------------------------} ay1 = dm(mTemp); {grab mTemp} ax1 = 1; {output M samples} ar = ay1-ax1; {decrement by 1} if eq jump throwout; {if its zero, start throwing put samples} dm(mTemp) = ar; {else, store mTemp and output} jump output; throwout: ay1 = dm(nTemp); {grab nTemp} ax1 = 1; {throw out N samples ar = ay1-ax1; {decrement by 1} if ne jump toss; {if its zero, reset to N} ar = dm(M); {reset mTemp to M} dm(mTemp) = ar; ar = dm(N); {reset nTemp to N} toss: dm(nTemp) = ar; {else, store nTemp} my0 = 0; {if M=0 and N!=0, output is 0} my1 = 0; {I think dm(last_output) should go here} output: mr0 = my0; mr1 = my1; {------------------------BIT QUANTIZING SECTION-------------------------} {-----------------------------------------------------------------------} ay0 = dm(L); ax0 = 0; ar = ax0 - ay0; se = ar; sr = ashift mr0 (hi); {shift right by L bits} se = ay0; sr = ashift sr1 (hi); {shift left by L bits} mr0 = sr1; {requantized left sample} se = ar; sr = ashift mr1 (hi); {shift right by L bits} se = ay0; sr = ashift sr1(hi); {shift left by L bits} mr1 = sr1; {requantized right sample} dm(tx_buf+ 1)=mr0; { write d/a converters } dm(tx_buf+ 2)=mr1; { write left/right values from my0, my1 } { save output value (for possible feedback) } dm(last_output)=mr1; {--------------------------------END------------------------------------} thatwasfun: rti; { Here is where MIDI messages are used to set variables in your Effect! } handle_MIDI_controller: ax1 = dm(midi_cont); ar = dm(midi_val); ay1 = 1;none = ax1-ay1;if eq jump set_bitdepth; ay1 = 2;none = ax1-ay1;if eq jump set_samplerate; ay1 = 127;none = ax1-ay1;if eq jump set_blah127; rts; set_bitdepth: ar = dm(midi_val); sr = lshift ar by -3(lo); ar = sr0; dm(B) = ar; ax0 = sr0; ay0 = 16; ar = ay0 - ax0; dm(B) = ax0; dm(L) = ar; rts; set_samplerate: ax1 = dm(midi_val); ay1 = 126; ar = ay1 - ax1; dm(M) = ar; ay0 = 1; dm(N) = ay0; rts; set_blah127: ay1 = dm(midi_val); rts; .endmod;