diff options
Diffstat (limited to 'src/emu/sound/ics2115.c')
-rw-r--r-- | src/emu/sound/ics2115.c | 622 |
1 files changed, 311 insertions, 311 deletions
diff --git a/src/emu/sound/ics2115.c b/src/emu/sound/ics2115.c index 0ef07217ad5..5dea9e6a2b5 100644 --- a/src/emu/sound/ics2115.c +++ b/src/emu/sound/ics2115.c @@ -23,42 +23,42 @@ void ics2115_device::static_set_irqf(device_t &device, void (*irqf)(device_t *de ics2115_device::ics2115_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) : device_t(mconfig, ICS2115, "ICS2115", tag, owner, clock), - device_sound_interface(mconfig, *this), - m_irq_cb(NULL) + device_sound_interface(mconfig, *this), + m_irq_cb(NULL) { } void ics2115_device::device_start() { - m_rom = *region(); - m_timer[0].timer = machine().scheduler().timer_alloc(FUNC(timer_cb_0), this); - m_timer[1].timer = machine().scheduler().timer_alloc(FUNC(timer_cb_1), this); - m_stream = machine().sound().stream_alloc(*this, 0, 2, 33075); - - //Exact formula as per patent 5809466 - //This seems to give the ok fit but it is not good enough. - /*double maxvol = ((1 << volume_bits) - 1) * pow(2., (double)1/0x100); - for (int i = 0; i < 0x1000; i++) { - m_volume[i] = floor(maxvol * pow(2.,(double)i/256 - 16) + 0.5); - }*/ - - //austere's table, derived from patent 5809466: - //See section V starting from page 195 - //Subsection F (column 124, page 198) onwards - for (int i = 0; i<4096; i++) { - m_volume[i] = ((0x100 | (i & 0xff)) << (volume_bits-9)) >> (15 - (i>>8)); - } - - //u-Law table as per MIL-STD-188-113 - UINT16 lut[8]; - UINT16 lut_initial = 33 << 2; //shift up 2-bits for 16-bit range. - for(int i = 0; i < 8; i++) - lut[i] = (lut_initial << i) - lut_initial; + m_rom = *region(); + m_timer[0].timer = machine().scheduler().timer_alloc(FUNC(timer_cb_0), this); + m_timer[1].timer = machine().scheduler().timer_alloc(FUNC(timer_cb_1), this); + m_stream = machine().sound().stream_alloc(*this, 0, 2, 33075); + + //Exact formula as per patent 5809466 + //This seems to give the ok fit but it is not good enough. + /*double maxvol = ((1 << volume_bits) - 1) * pow(2., (double)1/0x100); + for (int i = 0; i < 0x1000; i++) { + m_volume[i] = floor(maxvol * pow(2.,(double)i/256 - 16) + 0.5); + }*/ + + //austere's table, derived from patent 5809466: + //See section V starting from page 195 + //Subsection F (column 124, page 198) onwards + for (int i = 0; i<4096; i++) { + m_volume[i] = ((0x100 | (i & 0xff)) << (volume_bits-9)) >> (15 - (i>>8)); + } + + //u-Law table as per MIL-STD-188-113 + UINT16 lut[8]; + UINT16 lut_initial = 33 << 2; //shift up 2-bits for 16-bit range. + for(int i = 0; i < 8; i++) + lut[i] = (lut_initial << i) - lut_initial; for(int i = 0; i < 256; i++) { - UINT8 exponent = (~i >> 4) & 0x07; - UINT8 mantissa = ~i & 0x0f; - INT16 value = lut[exponent] + (mantissa << (exponent + 3)); - m_ulaw[i] = (i & 0x80) ? -value : value; + UINT8 exponent = (~i >> 4) & 0x07; + UINT8 mantissa = ~i & 0x0f; + INT16 value = lut[exponent] + (mantissa << (exponent + 3)); + m_ulaw[i] = (i & 0x80) ? -value : value; } save_item(NAME(m_timer[0].period)); @@ -107,7 +107,7 @@ void ics2115_device::device_reset() m_active_osc = 31; m_osc_select = 0; m_reg_select = 0; - m_vmode = 0; + m_vmode = 0; memset(m_voice, 0, sizeof(m_voice)); m_timer[0].timer->adjust(attotime::never); m_timer[1].timer->adjust(attotime::never); @@ -136,7 +136,7 @@ void ics2115_device::device_reset() int ics2115_voice::update_volume_envelope() { int ret = 0; - if(vol_ctrl.done || vol_ctrl.stop) + if(vol_ctrl.done || vol_ctrl.stop) return ret; if(vol_ctrl.invert) { @@ -151,7 +151,7 @@ int ics2115_voice::update_volume_envelope() return ret; if(vol_ctrl.irq) { - vol_ctrl.irq_pending = true; + vol_ctrl.irq_pending = true; ret = 1; } @@ -205,27 +205,27 @@ int ics2115_voice::update_oscillator() osc.acc += osc.fc << 2; osc.left = osc.end - osc.acc; } - // > instead of >= to stop crackling? + // > instead of >= to stop crackling? if(osc.left > 0) return ret; if(osc_conf.irq) { osc_conf.irq_pending = true; - ret = 1; + ret = 1; } if(osc_conf.loop) { if(osc_conf.loop_bidir) osc_conf.invert = !osc_conf.invert; - //else - // printf("click!\n"); + //else + // printf("click!\n"); if(osc_conf.invert) { osc.acc = osc.end + osc.left; - osc.left = osc.acc - osc.start; - } + osc.left = osc.acc - osc.start; + } else { osc.acc = osc.start - osc.left; - osc.left = osc.end - osc.acc; - } + osc.left = osc.end - osc.acc; + } } else { state.on = false; osc_conf.stop = true; @@ -240,106 +240,106 @@ int ics2115_voice::update_oscillator() //TODO: proper interpolation for uLaw (fill_output doesn't use this) and 8-bit samples (looping) stream_sample_t ics2115_device::get_sample(ics2115_voice& voice) { - UINT32 curaddr = ((voice.osc.saddr << 20) & 0xffffff) | (voice.osc.acc >> 12); - UINT32 nextaddr; - - if (voice.state.on && voice.osc_conf.loop && !voice.osc_conf.loop_bidir && - (voice.osc.left < (voice.osc.fc <<2))) { - //printf("C?[%x:%x]", voice.osc.left, voice.osc.acc); - nextaddr = ((voice.osc.saddr << 20) & 0xffffff) | (voice.osc.start >> 12); - } - else - nextaddr = curaddr + 2; - - - INT16 sample1, sample2; - if (voice.osc_conf.eightbit) { - sample1 = ((INT8)m_rom[curaddr]) << 8; - sample2 = ((INT8)m_rom[curaddr + 1]) << 8; - } - else { - sample1 = m_rom[curaddr + 0] | (((INT8)m_rom[curaddr + 1]) << 8); - sample2 = m_rom[nextaddr+ 0] | (((INT8)m_rom[nextaddr+ 1]) << 8); - //sample2 = m_rom[curaddr + 2] | (((INT8)m_rom[curaddr + 3]) << 8); - } - - //no need for interpolation since it's around 1 note a cycle? - //if(voice.osc.fc >> 10) - // return sample1; - - //linear interpolation as in US patent 6,246,774 B1, column 2 row 59 - //LEN=1, BLEN=0, DIR=0, start+end interpolation - INT32 sample, diff; - UINT16 fract; - diff = sample2 - sample1; - fract = (voice.osc.acc >> 3) & 0x1ff; - - sample = (((INT32)sample1 << 9) + diff * fract) >> 9; - //sample = sample1; - return sample; + UINT32 curaddr = ((voice.osc.saddr << 20) & 0xffffff) | (voice.osc.acc >> 12); + UINT32 nextaddr; + + if (voice.state.on && voice.osc_conf.loop && !voice.osc_conf.loop_bidir && + (voice.osc.left < (voice.osc.fc <<2))) { + //printf("C?[%x:%x]", voice.osc.left, voice.osc.acc); + nextaddr = ((voice.osc.saddr << 20) & 0xffffff) | (voice.osc.start >> 12); + } + else + nextaddr = curaddr + 2; + + + INT16 sample1, sample2; + if (voice.osc_conf.eightbit) { + sample1 = ((INT8)m_rom[curaddr]) << 8; + sample2 = ((INT8)m_rom[curaddr + 1]) << 8; + } + else { + sample1 = m_rom[curaddr + 0] | (((INT8)m_rom[curaddr + 1]) << 8); + sample2 = m_rom[nextaddr+ 0] | (((INT8)m_rom[nextaddr+ 1]) << 8); + //sample2 = m_rom[curaddr + 2] | (((INT8)m_rom[curaddr + 3]) << 8); + } + + //no need for interpolation since it's around 1 note a cycle? + //if(voice.osc.fc >> 10) + // return sample1; + + //linear interpolation as in US patent 6,246,774 B1, column 2 row 59 + //LEN=1, BLEN=0, DIR=0, start+end interpolation + INT32 sample, diff; + UINT16 fract; + diff = sample2 - sample1; + fract = (voice.osc.acc >> 3) & 0x1ff; + + sample = (((INT32)sample1 << 9) + diff * fract) >> 9; + //sample = sample1; + return sample; } bool ics2115_voice::playing() { - return state.on && !((vol_ctrl.done || vol_ctrl.stop) && osc_conf.stop); + return state.on && !((vol_ctrl.done || vol_ctrl.stop) && osc_conf.stop); } void ics2115_voice::update_ramp() { - //slow attack - if (state.on && !osc_conf.stop) { - if (state.ramp < 0x40) - state.ramp += 0x1; - else - state.ramp = 0x40; - } - //slow release - else { - if (state.ramp) - state.ramp -= 0x1; - } + //slow attack + if (state.on && !osc_conf.stop) { + if (state.ramp < 0x40) + state.ramp += 0x1; + else + state.ramp = 0x40; + } + //slow release + else { + if (state.ramp) + state.ramp -= 0x1; + } } int ics2115_device::fill_output(ics2115_voice& voice, stream_sample_t *outputs[2], int samples) { - bool irq_invalid = false; - UINT16 fine = 1 << (3*(voice.vol.incr >> 6)); - voice.vol.add = (voice.vol.incr & 0x3F)<< (10 - fine); - - for (int i = 0; i < samples; i++) { - UINT32 volacc = (voice.vol.acc >> 10) & 0xffff; - UINT32 volume = (m_volume[volacc >> 4] * voice.state.ramp) >> 6; - UINT16 vleft = volume; //* (255 - voice.vol.pan) / 0x80]; - UINT16 vright = volume; //* (voice.vol.pan + 1) / 0x80]; - - //From GUS doc: - //In general, it is necessary to remember that all voices are being summed in to the - //final output, even if they are not running. This means that whatever data value - //that the voice is pointing at is contributing to the summation. - //(austere note: this will of course fix some of the glitches due to multiple transition) - stream_sample_t sample; - if(voice.osc_conf.ulaw) { - UINT32 curaddr = ((voice.osc.saddr << 20) & 0xffffff) | (voice.osc.acc >> 12); - sample = m_ulaw[m_rom[curaddr]]; - } - else - sample = get_sample(voice); + bool irq_invalid = false; + UINT16 fine = 1 << (3*(voice.vol.incr >> 6)); + voice.vol.add = (voice.vol.incr & 0x3F)<< (10 - fine); - //15-bit volume + (5-bit worth of 32 channel sum) + 16-bit samples = 4-bit extra - if (!m_vmode || voice.playing()) { - //if (voice.playing()) { - outputs[0][i] += (sample * vleft) >> (5 + volume_bits - 16); - outputs[1][i] += (sample * vright) >> (5 + volume_bits - 16); - } - - voice.update_ramp(); - if (voice.playing()) { - if (voice.update_oscillator()) - irq_invalid = true; - if (voice.update_volume_envelope()) - irq_invalid = true; - } - } - return irq_invalid; + for (int i = 0; i < samples; i++) { + UINT32 volacc = (voice.vol.acc >> 10) & 0xffff; + UINT32 volume = (m_volume[volacc >> 4] * voice.state.ramp) >> 6; + UINT16 vleft = volume; //* (255 - voice.vol.pan) / 0x80]; + UINT16 vright = volume; //* (voice.vol.pan + 1) / 0x80]; + + //From GUS doc: + //In general, it is necessary to remember that all voices are being summed in to the + //final output, even if they are not running. This means that whatever data value + //that the voice is pointing at is contributing to the summation. + //(austere note: this will of course fix some of the glitches due to multiple transition) + stream_sample_t sample; + if(voice.osc_conf.ulaw) { + UINT32 curaddr = ((voice.osc.saddr << 20) & 0xffffff) | (voice.osc.acc >> 12); + sample = m_ulaw[m_rom[curaddr]]; + } + else + sample = get_sample(voice); + + //15-bit volume + (5-bit worth of 32 channel sum) + 16-bit samples = 4-bit extra + if (!m_vmode || voice.playing()) { + //if (voice.playing()) { + outputs[0][i] += (sample * vleft) >> (5 + volume_bits - 16); + outputs[1][i] += (sample * vright) >> (5 + volume_bits - 16); + } + + voice.update_ramp(); + if (voice.playing()) { + if (voice.update_oscillator()) + irq_invalid = true; + if (voice.update_volume_envelope()) + irq_invalid = true; + } + } + return irq_invalid; } void ics2115_device::sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples) @@ -352,8 +352,8 @@ void ics2115_device::sound_stream_update(sound_stream &stream, stream_sample_t * ics2115_voice& voice = m_voice[osc]; #ifdef ICS2115_ISOLATE - if(osc != ICS2115_ISOLATE) - continue; + if(osc != ICS2115_ISOLATE) + continue; #endif /* #ifdef ICS2115_DEBUG @@ -370,36 +370,36 @@ void ics2115_device::sound_stream_update(sound_stream &stream, stream_sample_t * irq_invalid = true; #ifdef ICS2115_DEBUG - if(voice.playing()) { - printf("%d", osc); - if (voice.osc_conf.invert) - printf("+"); - else if ((voice.osc.fc >> 1) > 0x1ff) - printf("*"); - printf(" "); - - /*int min = 0x7fffffff, max = 0x80000000; - double average = 0; - for (int i = 0; i < samples; i++) { - if (outputs[0][i] > max) max = outputs[0][i]; - if (outputs[0][i] < min) min = outputs[0][i]; - average += fabs(outputs[0][i]); - } - average /= samples; - average /= 1 << 16; - printf("<Mi:%d Mx:%d Av:%g>", min >> 16, max >> 16, average);*/ - } + if(voice.playing()) { + printf("%d", osc); + if (voice.osc_conf.invert) + printf("+"); + else if ((voice.osc.fc >> 1) > 0x1ff) + printf("*"); + printf(" "); + + /*int min = 0x7fffffff, max = 0x80000000; + double average = 0; + for (int i = 0; i < samples; i++) { + if (outputs[0][i] > max) max = outputs[0][i]; + if (outputs[0][i] < min) min = outputs[0][i]; + average += fabs(outputs[0][i]); + } + average /= samples; + average /= 1 << 16; + printf("<Mi:%d Mx:%d Av:%g>", min >> 16, max >> 16, average);*/ + } #endif } #ifdef ICS2115_DEBUG - printf("|"); + printf("|"); #endif //rescale for (int i = 0; i < samples; i++) { - outputs[0][i] >>= 16; - outputs[1][i] >>= 16; + outputs[0][i] >>= 16; + outputs[1][i] >>= 16; } if(irq_invalid) @@ -412,20 +412,20 @@ UINT16 ics2115_device::reg_read() { UINT16 ret; ics2115_voice& voice = m_voice[m_osc_select]; - switch(m_reg_select) { + switch(m_reg_select) { case 0x00: // [osc] Oscillator Configuration ret = voice.osc_conf.value; ret <<= 8; break; case 0x01: // [osc] Wavesample frequency - // freq = fc*33075/1024 in 32 voices mode, fc*44100/1024 in 24 voices mode + // freq = fc*33075/1024 in 32 voices mode, fc*44100/1024 in 24 voices mode //ret = v->Osc.FC; ret = voice.osc.fc; break; case 0x02: // [osc] Wavesample loop start high - //TODO: are these returns valid? might be 0x00ff for this one... + //TODO: are these returns valid? might be 0x00ff for this one... ret = (voice.osc.start >> 16) & 0xffff; break; @@ -473,23 +473,23 @@ UINT16 ics2115_device::reg_read() { /* DDP3 code (trap15's reversal) */ /* 0xA13's work: - res = read() & 0xC3; - if(!(res & 2)) res |= 1; - e = d = res; - */ + res = read() & 0xC3; + if(!(res & 2)) res |= 1; + e = d = res; + */ /* 0xA4F's work: - while(!(read() & 1)) - */ + while(!(read() & 1)) + */ case 0x0D: // [osc] Volume Envelope Control //ret = v->Vol.Ctl | ((v->state & FLAG_STATE_VOLIRQ) ? 0x81 : 1); // may expect |8 on voice irq with &40 == 0 // may expect |8 on reg 0 on voice irq with &80 == 0 // ret = 0xFF; - if (!m_vmode) - ret = voice.vol_ctrl.irq ? 0x81 : 0x01; - else - ret = 0x01; - //ret = voice.vol_ctrl.value | 0x1; + if (!m_vmode) + ret = voice.vol_ctrl.irq ? 0x81 : 0x01; + else + ret = 0x01; + //ret = voice.vol_ctrl.value | 0x1; ret <<= 8; break; @@ -500,20 +500,20 @@ UINT16 ics2115_device::reg_read() { case 0x0F:{// [osc] Interrupt source/oscillator ret = 0xff; for (int i = 0; i <= m_active_osc; i++) { - ics2115_voice& v = m_voice[i]; - if (v.osc_conf.irq_pending || v.vol_ctrl.irq_pending) { + ics2115_voice& v = m_voice[i]; + if (v.osc_conf.irq_pending || v.vol_ctrl.irq_pending) { ret = i | 0xe0; ret &= v.vol_ctrl.irq_pending ? (~0x40) : 0xff; ret &= v.osc_conf.irq_pending ? (~0x80) : 0xff; recalc_irq(); if (v.osc_conf.irq_pending) { - v.osc_conf.irq_pending = 0; - ret &= ~0x80; - } - if (v.vol_ctrl.irq_pending) { - v.vol_ctrl.irq_pending = 0; - ret &= ~0x40; - } + v.osc_conf.irq_pending = 0; + ret &= ~0x80; + } + if (v.vol_ctrl.irq_pending) { + v.vol_ctrl.irq_pending = 0; + ret &= ~0x40; + } break; } } @@ -530,7 +530,7 @@ UINT16 ics2115_device::reg_read() { case 0x40: // Timer 0 clear irq case 0x41: // Timer 1 clear irq - //TODO: examine this suspect code + //TODO: examine this suspect code ret = m_timer[m_reg_select & 0x1].preset; m_irq_pending &= ~(1 << (m_reg_select & 0x1)); recalc_irq(); @@ -554,24 +554,24 @@ UINT16 ics2115_device::reg_read() { default: #ifdef ICS2115_DEBUG - printf("ICS2115: Unhandled read %x\n", m_reg_select); + printf("ICS2115: Unhandled read %x\n", m_reg_select); #endif - ret = 0; + ret = 0; break; } return ret; } void ics2115_device::reg_write(UINT8 data, bool msb) { - ics2115_voice& voice = m_voice[m_osc_select]; + ics2115_voice& voice = m_voice[m_osc_select]; - switch(m_reg_select) { + switch(m_reg_select) { case 0x00: // [osc] Oscillator Configuration if(msb) { - voice.osc_conf.value &= 0x80; + voice.osc_conf.value &= 0x80; voice.osc_conf.value |= data & 0x7f; - } - break; + } + break; case 0x01: // [osc] Wavesample frequency // freq = fc*33075/1024 in 32 voices mode, fc*44100/1024 in 24 voices mode @@ -592,7 +592,7 @@ void ics2115_device::reg_write(UINT8 data, bool msb) { case 0x03: // [osc] Wavesample loop start low if(msb) voice.osc.start = (voice.osc.start & 0xffff00ff) | (data << 8); - // This is unused? + // This is unused? //else //voice.osc.start = (voice.osc.start & 0xffffff00) | (data & 0); break; @@ -607,7 +607,7 @@ void ics2115_device::reg_write(UINT8 data, bool msb) { case 0x05: // [osc] Wavesample loop end low if(msb) voice.osc.end = (voice.osc.end & 0xffff00ff) | (data << 8); - // lsb is unused? + // lsb is unused? break; case 0x06: // [osc] Volume Increment @@ -616,13 +616,13 @@ void ics2115_device::reg_write(UINT8 data, bool msb) { break; case 0x07: // [osc] Volume Start - if (!msb) - voice.vol.start = data << (10+8); + if (!msb) + voice.vol.start = data << (10+8); break; case 0x08: // [osc] Volume End - if (!msb) - voice.vol.end = data << (10+8); + if (!msb) + voice.vol.end = data << (10+8); break; case 0x09: // [osc] Volume accumulator @@ -630,15 +630,15 @@ void ics2115_device::reg_write(UINT8 data, bool msb) { voice.vol.regacc = (voice.vol.regacc & 0x00ff) | (data << 8); else voice.vol.regacc = (voice.vol.regacc & 0xff00) | data; - voice.vol.acc = voice.vol.regacc << 10; + voice.vol.acc = voice.vol.regacc << 10; break; case 0x0A: // [osc] Wavesample address high #ifdef ICS2115_DEBUG #ifdef ICS2115_ISOLATE - if(m_osc_select == ICS2115_ISOLATE) + if(m_osc_select == ICS2115_ISOLATE) #endif - printf("<%d:oa:H[%d]=%x>", m_osc_select, msb, data); + printf("<%d:oa:H[%d]=%x>", m_osc_select, msb, data); #endif if(msb) voice.osc.acc = (voice.osc.acc & 0x00ffffff) | (data << 24); @@ -649,9 +649,9 @@ void ics2115_device::reg_write(UINT8 data, bool msb) { case 0x0B: // [osc] Wavesample address low #ifdef ICS2115_DEBUG #ifdef ICS2115_ISOLATE - if(m_osc_select == ICS2115_ISOLATE) + if(m_osc_select == ICS2115_ISOLATE) #endif - printf("<%d:oa:L[%d]=%x>", m_osc_select, msb, data); + printf("<%d:oa:L[%d]=%x>", m_osc_select, msb, data); #endif if(msb) voice.osc.acc = (voice.osc.acc & 0xffff00ff) | (data << 8); @@ -666,47 +666,47 @@ void ics2115_device::reg_write(UINT8 data, bool msb) { case 0x0D: // [osc] Volume Envelope Control if(msb) { - voice.vol_ctrl.value &= 0x80; + voice.vol_ctrl.value &= 0x80; voice.vol_ctrl.value |= data & 0x7F; - } + } break; case 0x0E: // Active Voices - //Does this value get added to 1? Not sure. Could trace for writes of 32. - if(msb) { + //Does this value get added to 1? Not sure. Could trace for writes of 32. + if(msb) { m_active_osc = data & 0x1F; // & 0x1F ? (Guessing) - } - break; - //2X8 ? + } + break; + //2X8 ? case 0x10: // [osc] Oscillator Control - //Could this be 2X9? - //[7 R | 6 M2 | 5 M1 | 4-2 Reserve | 1 - Timer 2 Strt | 0 - Timer 1 Strt] - - if (msb) { - voice.osc.ctl = data; - if (!data) - keyon(); - //guessing here - else if(data == 0xf) { + //Could this be 2X9? + //[7 R | 6 M2 | 5 M1 | 4-2 Reserve | 1 - Timer 2 Strt | 0 - Timer 1 Strt] + + if (msb) { + voice.osc.ctl = data; + if (!data) + keyon(); + //guessing here + else if(data == 0xf) { #ifdef ICS2115_DEBUG #ifdef ICS2115_ISOLATE - if (m_osc_select == ICS2115_ISOLATE) + if (m_osc_select == ICS2115_ISOLATE) #endif - if (!voice.osc_conf.stop || !voice.vol_ctrl.stop) - printf("[%02d STOP]\n", m_osc_select); + if (!voice.osc_conf.stop || !voice.vol_ctrl.stop) + printf("[%02d STOP]\n", m_osc_select); #endif - if (!m_vmode) { - voice.osc_conf.stop = true; - voice.vol_ctrl.stop = true; - //try to key it off as well! - voice.state.on = false; - } - } + if (!m_vmode) { + voice.osc_conf.stop = true; + voice.vol_ctrl.stop = true; + //try to key it off as well! + voice.state.on = false; + } + } #ifdef ICS2115_DEBUG - else - printf("ICS2115: Unhandled* data write %d onto 0x10.\n", data); + else + printf("ICS2115: Unhandled* data write %d onto 0x10.\n", data); #endif - } + } break; case 0x11: // [osc] Wavesample static address 27-20 @@ -714,11 +714,11 @@ void ics2115_device::reg_write(UINT8 data, bool msb) { //v->Osc.SAddr = data; voice.osc.saddr = data; break; - case 0x12: - //Could be per voice! -- investigate. - if (msb) - m_vmode = data; - break; + case 0x12: + //Could be per voice! -- investigate. + if (msb) + m_vmode = data; + break; case 0x40: // Timer 1 Preset case 0x41: // Timer 2 Preset if(!msb) { @@ -736,7 +736,7 @@ void ics2115_device::reg_write(UINT8 data, bool msb) { break; case 0x4A: // IRQ Enable - if(!msb) { + if(!msb) { m_irq_enabled = data; recalc_irq(); } @@ -747,111 +747,111 @@ void ics2115_device::reg_write(UINT8 data, bool msb) { m_osc_select = data % (1+m_active_osc); } break; - default: + default: #ifdef ICS2115_DEBUG - printf("ICS2115: Unhandled write %x onto %x(%d) [voice = %d]\n", data, m_reg_select, msb, m_osc_select); + printf("ICS2115: Unhandled write %x onto %x(%d) [voice = %d]\n", data, m_reg_select, msb, m_osc_select); #endif - break; - } + break; + } } //UINT8 ics2115_device::read (offs_t offset) READ8_DEVICE_HANDLER(ics2115_device::read) { - ics2115_device *chip = downcast<ics2115_device *>(device); - UINT8 ret = 0; - - switch(offset) { - case 0: - //TODO: check this suspect code - if (chip->m_irq_on) { - ret |= 0x80; - if (chip->m_irq_enabled && (chip->m_irq_pending & 3)) - ret |= 1; - for (int i = 0; i <= chip->m_active_osc; i++) { - if (//chip->m_voice[i].vol_ctrl.irq_pending || - chip->m_voice[i].osc_conf.irq_pending) { - ret |= 2; - break; - } - } - } - - break; - case 1: - ret = chip->m_reg_select; - break; - case 2: - ret = (UINT8)(chip->reg_read()); - break; - case 3: - ret = chip->reg_read() >> 8; - break; - default: + ics2115_device *chip = downcast<ics2115_device *>(device); + UINT8 ret = 0; + + switch(offset) { + case 0: + //TODO: check this suspect code + if (chip->m_irq_on) { + ret |= 0x80; + if (chip->m_irq_enabled && (chip->m_irq_pending & 3)) + ret |= 1; + for (int i = 0; i <= chip->m_active_osc; i++) { + if (//chip->m_voice[i].vol_ctrl.irq_pending || + chip->m_voice[i].osc_conf.irq_pending) { + ret |= 2; + break; + } + } + } + + break; + case 1: + ret = chip->m_reg_select; + break; + case 2: + ret = (UINT8)(chip->reg_read()); + break; + case 3: + ret = chip->reg_read() >> 8; + break; + default: #ifdef ICS2115_DEBUG - printf("ICS2115: Unhandled memory read at %x\n", offset); + printf("ICS2115: Unhandled memory read at %x\n", offset); #endif - break; - } - return ret; + break; + } + return ret; } //UINT8 ics2115_device::write(offs_t offset, UINT8 data) WRITE8_DEVICE_HANDLER(ics2115_device::write) { - ics2115_device *chip = downcast<ics2115_device *>(device); - switch(offset) { - case 1: - chip->m_reg_select = data; - break; - case 2: - chip->reg_write(data,0); - break; - case 3: - chip->reg_write(data,1); - break; - default: + ics2115_device *chip = downcast<ics2115_device *>(device); + switch(offset) { + case 1: + chip->m_reg_select = data; + break; + case 2: + chip->reg_write(data,0); + break; + case 3: + chip->reg_write(data,1); + break; + default: #ifdef ICS2115_DEBUG - printf("ICS2115: Unhandled memory write %02x to %x\n", data, offset); + printf("ICS2115: Unhandled memory write %02x to %x\n", data, offset); #endif - break; - } + break; + } } void ics2115_device::keyon() { #ifdef ICS2115_ISOLATE - if (m_osc_select != ICS2115_ISOLATE) - return; + if (m_osc_select != ICS2115_ISOLATE) + return; #endif - //set initial condition (may need to invert?) -- does NOT work since these are set to zero even - m_voice[m_osc_select].state.on = true; - //no ramp up... - m_voice[m_osc_select].state.ramp = 0x40; + //set initial condition (may need to invert?) -- does NOT work since these are set to zero even + m_voice[m_osc_select].state.on = true; + //no ramp up... + m_voice[m_osc_select].state.ramp = 0x40; #ifdef ICS2115_DEBUG - printf("[%02d vs:%04x ve:%04x va:%04x vi:%02x vc:%02x os:%06x oe:%06x oa:%06x of:%04x SA:%02x oc:%02x][%04x]\n", m_osc_select, - m_voice[m_osc_select].vol.start >> 10, - m_voice[m_osc_select].vol.end >> 10, - m_voice[m_osc_select].vol.acc >> 10, - m_voice[m_osc_select].vol.incr, - m_voice[m_osc_select].vol_ctrl.value, - m_voice[m_osc_select].osc.start >> 12, - m_voice[m_osc_select].osc.end >> 12, - m_voice[m_osc_select].osc.acc >> 12, - m_voice[m_osc_select].osc.fc, - m_voice[m_osc_select].osc.saddr, - m_voice[m_osc_select].osc_conf.value, - m_volume[(m_voice[m_osc_select].vol.acc >> 14)] - ); + printf("[%02d vs:%04x ve:%04x va:%04x vi:%02x vc:%02x os:%06x oe:%06x oa:%06x of:%04x SA:%02x oc:%02x][%04x]\n", m_osc_select, + m_voice[m_osc_select].vol.start >> 10, + m_voice[m_osc_select].vol.end >> 10, + m_voice[m_osc_select].vol.acc >> 10, + m_voice[m_osc_select].vol.incr, + m_voice[m_osc_select].vol_ctrl.value, + m_voice[m_osc_select].osc.start >> 12, + m_voice[m_osc_select].osc.end >> 12, + m_voice[m_osc_select].osc.acc >> 12, + m_voice[m_osc_select].osc.fc, + m_voice[m_osc_select].osc.saddr, + m_voice[m_osc_select].osc_conf.value, + m_volume[(m_voice[m_osc_select].vol.acc >> 14)] + ); #endif - //testing memory corruption issue with mame stream - //printf("m_volume[0x%x]=0x%x\n", mastervolume, m_volume[mastervolume]); + //testing memory corruption issue with mame stream + //printf("m_volume[0x%x]=0x%x\n", mastervolume, m_volume[mastervolume]); } void ics2115_device::recalc_irq() { - //Suspect + //Suspect bool irq = (m_irq_pending & m_irq_enabled); for(int i = 0; (!irq) && (i < 32); i++) irq |= m_voice[i].vol_ctrl.irq_pending && m_voice[i].osc_conf.irq_pending; @@ -864,7 +864,7 @@ TIMER_CALLBACK( ics2115_device::timer_cb_0 ) { ics2115_device *chip = (ics2115_device *)ptr; chip->m_irq_pending |= 1 << 0; - chip->recalc_irq(); + chip->recalc_irq(); } TIMER_CALLBACK( ics2115_device::timer_cb_1 ) @@ -877,11 +877,11 @@ TIMER_CALLBACK( ics2115_device::timer_cb_1 ) void ics2115_device::recalc_timer(int timer) { //Old regression-based formula (minus constant) - //UINT64 period = m_timer[timer].preset * (m_timer[timer].scale << 16) / 60; + //UINT64 period = m_timer[timer].preset * (m_timer[timer].scale << 16) / 60; - //New formula based on O.Galibert's reverse engineering of ICS2115 card firmware - UINT64 period = ((m_timer[timer].scale & 0x1f) + 1) * (m_timer[timer].preset + 1); - period = (period << (4 + (m_timer[timer].scale >> 5)))*78125/2646; + //New formula based on O.Galibert's reverse engineering of ICS2115 card firmware + UINT64 period = ((m_timer[timer].scale & 0x1f) + 1) * (m_timer[timer].preset + 1); + period = (period << (4 + (m_timer[timer].scale >> 5)))*78125/2646; if(m_timer[timer].period != period) { m_timer[timer].period = period; |