// halt_osc: handle halting an oscillator // chip = chip ptr // onum = oscillator # // type = 1 for 0 found in sample data, 0 for hit end of table size private void es5503_halt_osc(ES5503Chip chip, int onum, int type, ref UInt32 accumulator, int resshift) { ES5503Osc pOsc = chip.oscillators[onum]; ES5503Osc pPartner = chip.oscillators[onum ^ 1]; int mode = (pOsc.control >> 1) & 3; int partnerMode = (pPartner.control >> 1) & 3; // if 0 found in sample data or mode is not free-run, halt this oscillator if ((mode != (int)MODE.FREE) || (type != 0)) { pOsc.control |= 1; } else // preserve the relative phase of the oscillator when looping { UInt16 wtsize = (UInt16)(pOsc.wtsize - 1); UInt32 altram = accumulator >> resshift; if (altram > wtsize) { altram -= wtsize; } else { altram = 0; } accumulator = altram << resshift; } // if we're in swap mode or we're the even oscillator and the partner is in swap mode, // start the partner. if ((mode == (int)MODE.SWAP) || ((partnerMode == (int)MODE.SWAP) && ((onum & 1) == 0))) { pPartner.control &= 0xff; // ~1; // clear the halt bit pPartner.accumulator = 0; // and make sure it starts from the top (does this also need phase preservation?) } // IRQ enabled for this voice? if ((pOsc.control & 0x08) != 0) { pOsc.irqpend = 1; if (chip.irq_func != null) { chip.irq_func(chip.irq_param, 1); } } }
private byte es5503_r(ES5503Chip info, byte offset) { byte retval; int i; ES5503Chip chip = info; if (offset < 0xe0) { byte osc = (byte)(offset & 0x1f); switch (offset & 0xe0) { case 0: // freq lo return((byte)(chip.oscillators[osc].freq & 0xff)); case 0x20: // freq hi return((byte)(chip.oscillators[osc].freq >> 8)); case 0x40: // volume return(chip.oscillators[osc].vol); case 0x60: // data return(chip.oscillators[osc].data); case 0x80: // wavetable pointer return((byte)((chip.oscillators[osc].wavetblpointer >> 8) & 0xff)); case 0xa0: // oscillator control return(chip.oscillators[osc].control); case 0xc0: // bank select / wavetable size / resolution retval = 0; if ((chip.oscillators[osc].wavetblpointer & 0x10000) != 0) { retval |= 0x40; } retval |= (byte)(chip.oscillators[osc].wavetblsize << 3); retval |= chip.oscillators[osc].resolution; return(retval); } } else // global registers { switch (offset) { case 0xe0: // interrupt status retval = chip.rege0; if (chip.irq_func != null) { chip.irq_func(chip.irq_param, 0); } // scan all oscillators for (i = 0; i < chip.oscsenabled; i++) { if (chip.oscillators[i].irqpend != 0) { // signal this oscillator has an interrupt retval = (byte)(i << 1); chip.rege0 = (byte)(retval | 0x80); // and clear its flag chip.oscillators[i].irqpend = 0; break; } } // if any oscillators still need to be serviced, assert IRQ again immediately for (i = 0; i < chip.oscsenabled; i++) { if (chip.oscillators[i].irqpend != 0) { if (chip.irq_func != null) { chip.irq_func(chip.irq_param, 1); } break; } } return((byte)(retval | 0x41)); case 0xe1: // oscillator enable return((byte)((chip.oscsenabled - 1) << 1)); case 0xe2: // A/D converter if (chip.adc_func != null) { return(chip.adc_func(chip.adc_param, 0)); } break; } } return(0); }