void NOINLINE uart_send(uint8_t data) { uint8_t status; // wait until previous byte is transmitted do { BLOCK_INT { status=mem_read(0xe000); } CYCLE_WAIT(4); } while(!(status&0x02)); // send the new one BLOCK_INT { mem_write(0x6001,data); CYCLE_WAIT(4); } }
void uart_init(void) { mem_write(0x6000,0b00000011); // master reset MDELAY(1); mem_write(0x6000,0b10010101); // clock/16 - 8N1 - receive int CYCLE_WAIT(8); mem_read(0xe000); // read status to start the device CYCLE_WAIT(8); }
void uart_update(void) { if(!hardware_getNMIState()) return; BLOCK_INT { uint8_t data,status; status=mem_read(0xe000); CYCLE_WAIT(4); if(!(status&0x80)) { #ifdef DEBUG print("Error: NMI asserted, no UART IRQ\n"); #endif return; } if(!(status&0x01)) { #ifdef DEBUG print("Error: UART IRQ without data\n"); #endif return; } data=mem_read(0xe001); CYCLE_WAIT(4); if(status&0x10) { #ifdef DEBUG print("Error: UART framing error\n"); #endif uart_init(); return; } if(status&0x20) { #ifdef DEBUG print("Warning: UART overrun\n"); #endif } synth_uartEvent(data); } }
static NOINLINE void ffMask(uint8_t set,uint8_t clear) { ff_state|=set; ff_state&=~clear; io_write(0x0e,ff_state); CYCLE_WAIT(4); ++ff_step; }
static void updatePot(p600Pot_t pot) { int8_t i,lower; uint8_t mux,bitDepth,cdv; uint16_t estimate,badMask; uint16_t bit; BLOCK_INT { // successive approximations using DAC and comparator // select pot mux=(pot&0x0f)|(0x20>>(pot>>4)); io_write(0x0a,mux); CYCLE_WAIT(4); // init values estimate=UINT16_MAX; bit=0x8000; bitDepth=potBitDepth[pot]; badMask=16-bitDepth; badMask=(UINT16_MAX>>badMask)<<badMask; // main loop for(i=0;i<=bitDepth;++i) { dac_write(estimate); // let comparator get correct voltage (don't remove me!) CYCLE_WAIT(2); // is DAC value lower than pot value? lower=(io_read(0x09)&0x08)!=0; // adjust estimate if (lower) estimate+=bit; else estimate-=bit; // on to finer changes bit>>=1; } // unselect io_write(0x0a,0xff); CYCLE_WAIT(4); estimate&=badMask; potmux.pots[pot]=estimate; // change detector cdv=estimate>>8; if(abs(potmux.changeDetect[pot]-cdv)>CHANGE_DETECT_THRESHOLD) { potmux.changeDetect[pot]=cdv; potmux.potChanged|=(uint32_t)1<<pot; potmux.lastChanged=pot; } } }
static uint8_t i8253Read(uint8_t a) { CYCLE_WAIT(4); return io_read(a); }
static void i8253Write(uint8_t a,uint8_t v) { io_write(a,v); CYCLE_WAIT(4); }
LOWERCODESIZE void tuner_scalingAdjustment(void) { p600CV_t cv=0; int32_t lo,hi,delta; int8_t i; uint8_t ps=0; prepareSynth(); for(;;) { BLOCK_INT { io_write(0x08,0); CYCLE_WAIT(10); ps=io_read(0x0a); } if(ps&2) //pb1 { cv=(cv+1)%18; } else if(ps&4) //pb2 { cv=(cv+18-1)%18; } tuner.currentCV=cv; sh_setCV(pcResonance,cv>=pcFil1?UINT16_MAX:0,0); for(i=0;i<SYNTH_VOICE_COUNT;++i) { sh_setCV(pcAmp1+i,cv%SYNTH_VOICE_COUNT==i?UINT16_MAX:0,0); sh_setCV(pcFil1+i,UINT16_MAX,0); sh_setCV(pcOsc1A+i,UINT16_MAX,0); sh_setCV(pcOsc1B+i,UINT16_MAX,0); } sh_setCV(pcVolA,cv<pcOsc1B?UINT16_MAX:0,0); sh_setGate(pgASaw,cv<pcOsc1B?UINT16_MAX:0); sh_setCV(pcVolB,cv>=pcOsc1B&&cv<pcFil1?UINT16_MAX:0,0); sh_setGate(pgBSaw,cv>=pcOsc1B&&cv<pcFil1?UINT16_MAX:0); if(cv<pcFil1) { sh_setCV(cv,TUNER_OSC_INIT_OFFSET+3*TUNER_OSC_INIT_SCALE,0); lo=measureAudioPeriod(8); sh_setCV(cv,TUNER_OSC_INIT_OFFSET+7*TUNER_OSC_INIT_SCALE,0); hi=measureAudioPeriod(128); } else { sh_setCV(cv,TUNER_FIL_INIT_OFFSET+5*TUNER_FIL_INIT_SCALE,0); lo=measureAudioPeriod(8); sh_setCV(cv,TUNER_FIL_INIT_OFFSET+9*TUNER_FIL_INIT_SCALE,0); hi=measureAudioPeriod(128); } for(i=0;i<SYNTH_VOICE_COUNT;++i) sh_setCV(pcAmp1+i,0,0); delta=(hi-lo)>>8; #ifdef DEBUG phex16(hi>>16); phex16(hi); print("\n"); phex16(lo>>16); phex16(lo); print("\n"); phex16(delta>>16); phex16(delta); print("\n"); #endif delta=MIN(delta,99); delta=MAX(delta,-99); sevenSeg_setNumber(abs(delta)); led_set(plDot,delta<0,0); for(i=0;i<50;++i) { MDELAY(10); display_update(1); sh_update(); } } }