diff options
author | 2019-03-26 11:13:37 +1100 | |
---|---|---|
committer | 2019-03-26 11:13:37 +1100 | |
commit | 97b67170277437131adf6ed4d60139c172529e4f (patch) | |
tree | 7a5cbf608f191075f1612b1af15832c206a3fe2d /src/devices/sound/ics2115.cpp | |
parent | b380514764cf857469bae61c11143a19f79a74c5 (diff) |
(nw) Clean up the mess on master
This effectively reverts b380514764cf857469bae61c11143a19f79a74c5 and
c24473ddff715ecec2e258a6eb38960cf8c8e98e, restoring the state at
598cd5227223c3b04ca31f0dbc1981256d9ea3ff.
Before pushing, please check that what you're about to push is sane.
Check your local commit log and ensure there isn't anything out-of-place
before pushing to mainline. When things like this happen, it wastes
everyone's time. I really don't need this in a week when real work⢠is
busting my balls and I'm behind where I want to be with preparing for
MAME release.
Diffstat (limited to 'src/devices/sound/ics2115.cpp')
-rw-r--r-- | src/devices/sound/ics2115.cpp | 517 |
1 files changed, 312 insertions, 205 deletions
diff --git a/src/devices/sound/ics2115.cpp b/src/devices/sound/ics2115.cpp index 12062e9a509..9ce19fe649f 100644 --- a/src/devices/sound/ics2115.cpp +++ b/src/devices/sound/ics2115.cpp @@ -15,9 +15,9 @@ //#define ICS2115_ISOLATE 6 // device type definition -DEFINE_DEVICE_TYPE(ICS2115, ics2115_device, "ics2115", "ICS2115") +DEFINE_DEVICE_TYPE(ICS2115, ics2115_device, "ics2115", "ICS2115 WaveFront Synthesizer") -ics2115_device::ics2115_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) +ics2115_device::ics2115_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) : device_t(mconfig, ICS2115, tag, owner, clock), device_sound_interface(mconfig, *this), m_stream(nullptr), m_rom(*this, DEVICE_SELF), @@ -36,26 +36,26 @@ void ics2115_device::device_start() //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++) { + 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++) { + 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_t lut[8]; - uint16_t lut_initial = 33 << 2; //shift up 2-bits for 16-bit range. - for(int i = 0; i < 8; i++) + u16 lut[8]; + u16 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_t exponent = (~i >> 4) & 0x07; - uint8_t mantissa = ~i & 0x0f; - int16_t value = lut[exponent] + (mantissa << (exponent + 3)); + for (int i = 0; i < 256; i++) + { + u8 exponent = (~i >> 4) & 0x07; + u8 mantissa = ~i & 0x0f; + s16 value = lut[exponent] + (mantissa << (exponent + 3)); m_ulaw[i] = (i & 0x80) ? -value : value; } @@ -73,7 +73,8 @@ void ics2115_device::device_start() save_item(NAME(m_active_osc)); save_item(NAME(m_vmode)); - for(int i = 0; i < 32; i++) { + for (int i = 0; i < 32; i++) + { save_item(NAME(m_voice[i].osc_conf.value), i); save_item(NAME(m_voice[i].state.value), i); save_item(NAME(m_voice[i].vol_ctrl.value), i); @@ -108,14 +109,15 @@ void ics2115_device::device_reset() m_vmode = 0; m_irq_on = false; memset(m_voice, 0, sizeof(m_voice)); - for(auto & elem : m_timer) + for (auto & elem : m_timer) { elem.timer->adjust(attotime::never); elem.period = 0; elem.scale = 0; elem.preset = 0; } - for(auto & elem : m_voice) { + for (auto & elem : m_voice) + { elem.osc_conf.value = 2; elem.osc.fc = 0; elem.osc.acc = 0; @@ -127,7 +129,7 @@ void ics2115_device::device_reset() elem.vol.incr = 0; elem.vol.start = 0; elem.vol.end = 0; - elem.vol.pan = 0x7F; + elem.vol.pan = 0x7f; elem.vol_ctrl.value = 1; elem.vol.mode = 0; elem.state.value = 0; @@ -138,40 +140,47 @@ void ics2115_device::device_reset() int ics2115_device::ics2115_voice::update_volume_envelope() { int ret = 0; - if(vol_ctrl.bitflags.done || vol_ctrl.bitflags.stop) + if (vol_ctrl.bitflags.done || vol_ctrl.bitflags.stop) return ret; - if(vol_ctrl.bitflags.invert) { + if (vol_ctrl.bitflags.invert) + { vol.acc -= vol.add; vol.left = vol.acc - vol.start; - } else { + } + else + { vol.acc += vol.add; vol.left = vol.end - vol.acc; } - if(vol.left > 0) + if (vol.left > 0) return ret; - if(vol_ctrl.bitflags.irq) { + if (vol_ctrl.bitflags.irq) + { vol_ctrl.bitflags.irq_pending = true; ret = 1; } - if(osc_conf.bitflags.eightbit) + if (osc_conf.bitflags.eightbit) return ret; - if(vol_ctrl.bitflags.loop) { - if(vol_ctrl.bitflags.loop_bidir) + if (vol_ctrl.bitflags.loop) + { + if (vol_ctrl.bitflags.loop_bidir) vol_ctrl.bitflags.invert = !vol_ctrl.bitflags.invert; - if(vol_ctrl.bitflags.invert) + if (vol_ctrl.bitflags.invert) vol.acc = vol.end + vol.left; else vol.acc = vol.start - vol.left; - } else { + } + else + { state.bitflags.on = false; vol_ctrl.bitflags.done = true; - if(vol_ctrl.bitflags.invert) + if (vol_ctrl.bitflags.invert) vol.acc = vol.end; else vol.acc = vol.start; @@ -180,7 +189,7 @@ int ics2115_device::ics2115_voice::update_volume_envelope() return ret; } -/*uint32_t ics2115_device::ics2115_voice::next_address() +/*u32 ics2115_device::ics2115_voice::next_address() { //Patent 6,246,774 B1, Column 111, Row 25 //LEN BLEN DIR BC NextAddress @@ -198,40 +207,49 @@ int ics2115_device::ics2115_voice::update_volume_envelope() int ics2115_device::ics2115_voice::update_oscillator() { int ret = 0; - if(osc_conf.bitflags.stop) + if (osc_conf.bitflags.stop) return ret; - if(osc_conf.bitflags.invert) { + if (osc_conf.bitflags.invert) + { osc.acc -= osc.fc << 2; osc.left = osc.acc - osc.start; - } else { + } + else + { osc.acc += osc.fc << 2; osc.left = osc.end - osc.acc; } // > instead of >= to stop crackling? - if(osc.left > 0) + if (osc.left > 0) return ret; - if(osc_conf.bitflags.irq) { + if (osc_conf.bitflags.irq) + { osc_conf.bitflags.irq_pending = true; ret = 1; } - if(osc_conf.bitflags.loop) { - if(osc_conf.bitflags.loop_bidir) + if (osc_conf.bitflags.loop) + { + if (osc_conf.bitflags.loop_bidir) osc_conf.bitflags.invert = !osc_conf.bitflags.invert; //else - // printf("click!\n"); + // logerror("click!\n"); - if(osc_conf.bitflags.invert) { + if (osc_conf.bitflags.invert) + { osc.acc = osc.end + osc.left; osc.left = osc.acc - osc.start; } - else { + else + { osc.acc = osc.start - osc.left; osc.left = osc.end - osc.acc; } - } else { + } + else + { state.bitflags.on = false; osc_conf.bitflags.stop = true; - if(!osc_conf.bitflags.invert) + if (!osc_conf.bitflags.invert) osc.acc = osc.end; else osc.acc = osc.start; @@ -242,41 +260,44 @@ int ics2115_device::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_t curaddr = ((voice.osc.saddr << 20) & 0xffffff) | (voice.osc.acc >> 12); - uint32_t nextaddr; + u32 curaddr = ((voice.osc.saddr << 20) & 0xffffff) | (voice.osc.acc >> 12); + u32 nextaddr; if (voice.state.bitflags.on && voice.osc_conf.bitflags.loop && !voice.osc_conf.bitflags.loop_bidir && - (voice.osc.left < (voice.osc.fc <<2))) { - //printf("C?[%x:%x]", voice.osc.left, voice.osc.acc); + (voice.osc.left < (voice.osc.fc <<2))) + { + //logerror("C?[%x:%x]", voice.osc.left, voice.osc.acc); nextaddr = ((voice.osc.saddr << 20) & 0xffffff) | (voice.osc.start >> 12); } else nextaddr = curaddr + 2; - int16_t sample1, sample2; - if (voice.osc_conf.bitflags.eightbit) { - sample1 = ((int8_t)m_rom[curaddr]) << 8; - sample2 = ((int8_t)m_rom[curaddr + 1]) << 8; + s16 sample1, sample2; + if (voice.osc_conf.bitflags.eightbit) + { + sample1 = ((s8)m_rom[curaddr]) << 8; + sample2 = ((s8)m_rom[curaddr + 1]) << 8; } - else { - sample1 = m_rom[curaddr + 0] | (((int8_t)m_rom[curaddr + 1]) << 8); - sample2 = m_rom[nextaddr+ 0] | (((int8_t)m_rom[nextaddr+ 1]) << 8); - //sample2 = m_rom[curaddr + 2] | (((int8_t)m_rom[curaddr + 3]) << 8); + else + { + sample1 = m_rom[curaddr + 0] | (((s8)m_rom[curaddr + 1]) << 8); + sample2 = m_rom[nextaddr+ 0] | (((s8)m_rom[nextaddr+ 1]) << 8); + //sample2 = m_rom[curaddr + 2] | (((s8)m_rom[curaddr + 3]) << 8); } //no need for interpolation since it's around 1 note a cycle? - //if(voice.osc.fc >> 10) + //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_t sample, diff; - uint16_t fract; + s32 sample, diff; + u16 fract; diff = sample2 - sample1; fract = (voice.osc.acc >> 3) & 0x1ff; - sample = (((int32_t)sample1 << 9) + diff * fract) >> 9; + sample = (((s32)sample1 << 9) + diff * fract) >> 9; //sample = sample1; return sample; } @@ -286,16 +307,19 @@ bool ics2115_device::ics2115_voice::playing() return state.bitflags.on && !((vol_ctrl.bitflags.done || vol_ctrl.bitflags.stop) && osc_conf.bitflags.stop); } -void ics2115_device::ics2115_voice::update_ramp() { +void ics2115_device::ics2115_voice::update_ramp() +{ //slow attack - if (state.bitflags.on && !osc_conf.bitflags.stop) { + if (state.bitflags.on && !osc_conf.bitflags.stop) + { if (state.bitflags.ramp < 0x40) state.bitflags.ramp += 0x1; else state.bitflags.ramp = 0x40; } //slow release - else { + else + { if (state.bitflags.ramp) state.bitflags.ramp -= 0x1; } @@ -304,14 +328,15 @@ void ics2115_device::ics2115_voice::update_ramp() { int ics2115_device::fill_output(ics2115_voice& voice, stream_sample_t *outputs[2], int samples) { bool irq_invalid = false; - uint16_t fine = 1 << (3*(voice.vol.incr >> 6)); - voice.vol.add = (voice.vol.incr & 0x3F)<< (10 - fine); + u16 fine = 1 << (3*(voice.vol.incr >> 6)); + voice.vol.add = (voice.vol.incr & 0x3f)<< (10 - fine); - for (int i = 0; i < samples; i++) { - uint32_t volacc = (voice.vol.acc >> 10) & 0xffff; - uint32_t volume = (m_volume[volacc >> 4] * voice.state.bitflags.ramp) >> 6; - uint16_t vleft = volume; //* (255 - voice.vol.pan) / 0x80]; - uint16_t vright = volume; //* (voice.vol.pan + 1) / 0x80]; + for (int i = 0; i < samples; i++) + { + u32 volacc = (voice.vol.acc >> 10) & 0xffff; + u32 volume = (m_volume[volacc >> 4] * voice.state.bitflags.ramp) >> 6; + u16 vleft = volume; //* (255 - voice.vol.pan) / 0x80]; + u16 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 @@ -319,22 +344,26 @@ int ics2115_device::fill_output(ics2115_voice& voice, stream_sample_t *outputs[2 //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.bitflags.ulaw) { - uint32_t curaddr = ((voice.osc.saddr << 20) & 0xffffff) | (voice.osc.acc >> 12); + if (voice.osc_conf.bitflags.ulaw) + { + u32 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()) { + 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.playing()) + { if (voice.update_oscillator()) irq_invalid = true; if (voice.update_volume_envelope()) @@ -350,71 +379,77 @@ void ics2115_device::sound_stream_update(sound_stream &stream, stream_sample_t * memset(outputs[1], 0, samples * sizeof(stream_sample_t)); bool irq_invalid = false; - for(int osc = 0; osc <= m_active_osc; osc++) { + for (int osc = 0; osc <= m_active_osc; osc++) + { ics2115_voice& voice = m_voice[osc]; #ifdef ICS2115_ISOLATE - if(osc != ICS2115_ISOLATE) + if (osc != ICS2115_ISOLATE) continue; #endif /* #ifdef ICS2115_DEBUG - uint32_t curaddr = ((voice.osc.saddr << 20) & 0xffffff) | (voice.osc.acc >> 12); + u32 curaddr = ((voice.osc.saddr << 20) & 0xffffff) | (voice.osc.acc >> 12); stream_sample_t sample; - if(voice.osc_conf.bitflags.ulaw) + if (voice.osc_conf.bitflags.ulaw) sample = m_ulaw[m_rom[curaddr]]; else sample = get_sample(voice); - printf("[%06x=%04x]", curaddr, (int16_t)sample); + logerror("[%06x=%04x]", curaddr, (s16)sample); #endif */ - if(fill_output(voice, outputs, samples)) + if (fill_output(voice, outputs, samples)) irq_invalid = true; #ifdef ICS2115_DEBUG - if(voice.playing()) { - printf("%d", osc); + if (voice.playing()) + { + logerror("%d", osc); if (voice.osc_conf.bitflags.invert) - printf("+"); + logerror("+"); else if ((voice.osc.fc >> 1) > 0x1ff) - printf("*"); - printf(" "); + logerror("*"); + logerror(" "); /*int min = 0x7fffffff, max = 0x80000000; double average = 0; - for (int i = 0; i < samples; i++) { + 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);*/ + logerror("<Mi:%d Mx:%d Av:%g>", min >> 16, max >> 16, average);*/ } #endif } #ifdef ICS2115_DEBUG - printf("|"); + logerror("|"); #endif //rescale - for (int i = 0; i < samples; i++) { + for (int i = 0; i < samples; i++) + { outputs[0][i] >>= 16; outputs[1][i] >>= 16; } - if(irq_invalid) + if (irq_invalid) recalc_irq(); } //Helper Function (Reads off current register) -uint16_t ics2115_device::reg_read() { - uint16_t ret; +u16 ics2115_device::reg_read() +{ + u16 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; @@ -460,33 +495,33 @@ uint16_t ics2115_device::reg_read() { ret = voice.vol.acc >> (10); break; - case 0x0A: // [osc] Wavesample address + case 0x0a: // [osc] Wavesample address ret = (voice.osc.acc >> 16) & 0xffff; break; - case 0x0B: // [osc] Wavesample address + case 0x0b: // [osc] Wavesample address ret = (voice.osc.acc >> 0) & 0xfff8; break; - case 0x0C: // [osc] Pan + case 0x0c: // [osc] Pan ret = voice.vol.pan << 8; break; /* DDP3 code (trap15's reversal) */ /* 0xA13's work: res = read() & 0xC3; - if(!(res & 2)) res |= 1; + if (!(res & 2)) res |= 1; e = d = res; */ /* 0xA4F's work: while(!(read() & 1)) */ - case 0x0D: // [osc] Volume Envelope Control + 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; + // ret = 0xff; if (!m_vmode) ret = voice.vol_ctrl.bitflags.irq ? 0x81 : 0x01; else @@ -495,24 +530,28 @@ uint16_t ics2115_device::reg_read() { ret <<= 8; break; - case 0x0E: // Active Voices + case 0x0e: // Active Voices ret = m_active_osc; break; - case 0x0F:{// [osc] Interrupt source/oscillator + case 0x0f:{// [osc] Interrupt source/oscillator ret = 0xff; - for (int i = 0; i <= m_active_osc; i++) { + for (int i = 0; i <= m_active_osc; i++) + { ics2115_voice& v = m_voice[i]; - if (v.osc_conf.bitflags.irq_pending || v.vol_ctrl.bitflags.irq_pending) { + if (v.osc_conf.bitflags.irq_pending || v.vol_ctrl.bitflags.irq_pending) + { ret = i | 0xe0; ret &= v.vol_ctrl.bitflags.irq_pending ? (~0x40) : 0xff; ret &= v.osc_conf.bitflags.irq_pending ? (~0x80) : 0xff; recalc_irq(); - if (v.osc_conf.bitflags.irq_pending) { + if (v.osc_conf.bitflags.irq_pending) + { v.osc_conf.bitflags.irq_pending = 0; ret &= ~0x80; } - if (v.vol_ctrl.bitflags.irq_pending) { + if (v.vol_ctrl.bitflags.irq_pending) + { v.vol_ctrl.bitflags.irq_pending = 0; ret &= ~0x40; } @@ -542,21 +581,21 @@ uint16_t ics2115_device::reg_read() { ret = m_irq_pending & 3; break; - case 0x4A: // IRQ Pending + case 0x4a: // IRQ Pending ret = m_irq_pending; break; - case 0x4B: // Address of Interrupting Oscillator + case 0x4b: // Address of Interrupting Oscillator ret = 0x80; break; - case 0x4C: // Chip Revision + case 0x4c: // Chip Revision ret = revision; break; default: #ifdef ICS2115_DEBUG - printf("ICS2115: Unhandled read %x\n", m_reg_select); + logerror("ICS2115: Unhandled read %x\n", m_reg_select); #endif ret = 0; break; @@ -564,140 +603,147 @@ uint16_t ics2115_device::reg_read() { return ret; } -void ics2115_device::reg_write(uint8_t data, bool msb) { +void ics2115_device::reg_write(u16 data, u16 mem_mask) +{ ics2115_voice& voice = m_voice[m_osc_select]; - switch(m_reg_select) { + switch (m_reg_select) + { case 0x00: // [osc] Oscillator Configuration - if(msb) { + if (ACCESSING_BITS_8_15) + { voice.osc_conf.value &= 0x80; - voice.osc_conf.value |= data & 0x7f; + voice.osc_conf.value |= (data >> 8) & 0x7f; } break; case 0x01: // [osc] Wavesample frequency // freq = fc*33075/1024 in 32 voices mode, fc*44100/1024 in 24 voices mode - if(msb) - voice.osc.fc = (voice.osc.fc & 0x00ff) | (data << 8); - else + if (ACCESSING_BITS_8_15) + voice.osc.fc = (voice.osc.fc & 0x00fe) | (data & 0xff00); + if (ACCESSING_BITS_0_7) //last bit not used! - voice.osc.fc = (voice.osc.fc & 0xff00) | (data & 0xfe); + voice.osc.fc = (voice.osc.fc & 0xff00) | (data & 0x00fe); break; case 0x02: // [osc] Wavesample loop start high - if(msb) - voice.osc.start = (voice.osc.start & 0x00ffffff) | (data << 24); - else - voice.osc.start = (voice.osc.start & 0xff00ffff) | (data << 16); + if (ACCESSING_BITS_8_15) + voice.osc.start = (voice.osc.start & 0x00ffffff) | ((data & 0xff00) << 16); + if (ACCESSING_BITS_0_7) + voice.osc.start = (voice.osc.start & 0xff00ffff) | ((data & 0x00ff) << 16); break; case 0x03: // [osc] Wavesample loop start low - if(msb) - voice.osc.start = (voice.osc.start & 0xffff00ff) | (data << 8); + if (ACCESSING_BITS_8_15) + voice.osc.start = (voice.osc.start & 0xffff00ff) | (data & 0xff00); // This is unused? - //else + //if (ACCESSING_BITS_0_7) //voice.osc.start = (voice.osc.start & 0xffffff00) | (data & 0); break; case 0x04: // [osc] Wavesample loop end high - if(msb) - voice.osc.end = (voice.osc.end & 0x00ffffff) | (data << 24); - else - voice.osc.end = (voice.osc.end & 0xff00ffff) | (data << 16); + if (ACCESSING_BITS_8_15) + voice.osc.end = (voice.osc.end & 0x00ffffff) | ((data & 0xff00) << 16); + if (ACCESSING_BITS_0_7) + voice.osc.end = (voice.osc.end & 0xff00ffff) | ((data & 0x00ff) << 16); break; case 0x05: // [osc] Wavesample loop end low - if(msb) - voice.osc.end = (voice.osc.end & 0xffff00ff) | (data << 8); + if (ACCESSING_BITS_8_15) + voice.osc.end = (voice.osc.end & 0xffff00ff) | (data & 0xff00); // lsb is unused? break; case 0x06: // [osc] Volume Increment - if(msb) - voice.vol.incr = data; + if (ACCESSING_BITS_8_15) + voice.vol.incr = (data >> 8) & 0xff; break; case 0x07: // [osc] Volume Start - if (!msb) - voice.vol.start = data << (10+8); + if (ACCESSING_BITS_0_7) + voice.vol.start = (data & 0xff) << (10+8); break; case 0x08: // [osc] Volume End - if (!msb) - voice.vol.end = data << (10+8); + if (ACCESSING_BITS_0_7) + voice.vol.end = (data & 0xff) << (10+8); break; case 0x09: // [osc] Volume accumulator - if(msb) - voice.vol.regacc = (voice.vol.regacc & 0x00ff) | (data << 8); - else - voice.vol.regacc = (voice.vol.regacc & 0xff00) | data; + if (ACCESSING_BITS_8_15) + voice.vol.regacc = (voice.vol.regacc & 0x00ff) | (data & 0xff00); + if (ACCESSING_BITS_0_7) + voice.vol.regacc = (voice.vol.regacc & 0xff00) | (data & 0x00ff); voice.vol.acc = voice.vol.regacc << 10; break; - case 0x0A: // [osc] Wavesample address high + 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); + logerror("<%d:oa:H=%x>", m_osc_select, data); #endif - if(msb) - voice.osc.acc = (voice.osc.acc & 0x00ffffff) | (data << 24); - else - voice.osc.acc = (voice.osc.acc & 0xff00ffff) | (data << 16); + if (ACCESSING_BITS_8_15) + voice.osc.acc = (voice.osc.acc & 0x00ffffff) | ((data & 0xff00) << 16); + if (ACCESSING_BITS_0_7) + voice.osc.acc = (voice.osc.acc & 0xff00ffff) | ((data & 0x00ff) << 16); break; - case 0x0B: // [osc] Wavesample address low + 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); + logerror("<%d:oa:L=%x>", m_osc_select, data); #endif - if(msb) - voice.osc.acc = (voice.osc.acc & 0xffff00ff) | (data << 8); - else - voice.osc.acc = (voice.osc.acc & 0xffffff00) | (data & 0xF8); + if (ACCESSING_BITS_8_15) + voice.osc.acc = (voice.osc.acc & 0xffff00ff) | (data & 0xff00); + if (ACCESSING_BITS_0_7) + voice.osc.acc = (voice.osc.acc & 0xffffff00) | (data & 0x00f8); break; - case 0x0C: // [osc] Pan - if(msb) - voice.vol.pan = data; + case 0x0c: // [osc] Pan + if (ACCESSING_BITS_8_15) + voice.vol.pan = (data >> 8) & 0xff; break; - case 0x0D: // [osc] Volume Envelope Control - if(msb) { + case 0x0d: // [osc] Volume Envelope Control + if (ACCESSING_BITS_8_15) + { voice.vol_ctrl.value &= 0x80; - voice.vol_ctrl.value |= data & 0x7F; + voice.vol_ctrl.value |= (data >> 8) & 0x7f; } break; - case 0x0E: // Active Voices + case 0x0e: // Active Voices //Does this value get added to 1? Not sure. Could trace for writes of 32. - if(msb) { - m_active_osc = data & 0x1F; // & 0x1F ? (Guessing) - } + if (ACCESSING_BITS_8_15) + m_active_osc = (data >> 8) & 0x1f; // & 0x1f ? (Guessing) 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) { + if (ACCESSING_BITS_8_15) + { + data >>= 8; voice.osc.ctl = data; if (!data) keyon(); //guessing here - else if(data == 0xf) { + else if (data == 0xf) + { #ifdef ICS2115_DEBUG #ifdef ICS2115_ISOLATE if (m_osc_select == ICS2115_ISOLATE) #endif if (!voice.osc_conf.bitflags.stop || !voice.vol_ctrl.bitflags.stop) - printf("[%02d STOP]\n", m_osc_select); + logerror("[%02d STOP]\n", m_osc_select); #endif - if (!m_vmode) { + if (!m_vmode) + { voice.osc_conf.bitflags.stop = true; voice.vol_ctrl.bitflags.stop = true; //try to key it off as well! @@ -706,71 +752,77 @@ void ics2115_device::reg_write(uint8_t data, bool msb) { } #ifdef ICS2115_DEBUG else - printf("ICS2115: Unhandled* data write %d onto 0x10.\n", data); + logerror("ICS2115: Unhandled* data write %d onto 0x10.\n", data); #endif } break; case 0x11: // [osc] Wavesample static address 27-20 - if(msb) - //v->Osc.SAddr = data; - voice.osc.saddr = data; + if (ACCESSING_BITS_8_15) + //v->Osc.SAddr = (data >> 8); + voice.osc.saddr = (data >> 8); break; case 0x12: //Could be per voice! -- investigate. - if (msb) - m_vmode = data; + if (ACCESSING_BITS_8_15) + m_vmode = (data >> 8); break; case 0x40: // Timer 1 Preset case 0x41: // Timer 2 Preset - if(!msb) { - m_timer[m_reg_select & 0x1].preset = data; + if (ACCESSING_BITS_0_7) + { + m_timer[m_reg_select & 0x1].preset = data & 0xff; recalc_timer(m_reg_select & 0x1); } break; case 0x42: // Timer 1 Prescale case 0x43: // Timer 2 Prescale - if(!msb) { - m_timer[m_reg_select & 0x1].scale = data; + if (ACCESSING_BITS_0_7) + { + m_timer[m_reg_select & 0x1].scale = data & 0xff; recalc_timer(m_reg_select & 0x1); } break; - case 0x4A: // IRQ Enable - if(!msb) { - m_irq_enabled = data; + case 0x4a: // IRQ Enable + if (ACCESSING_BITS_0_7) + { + m_irq_enabled = data & 0xff; recalc_irq(); } break; - case 0x4F: // Oscillator Address being Programmed - if(!msb) { - m_osc_select = data % (1+m_active_osc); - } + case 0x4f: // Oscillator Address being Programmed + if (ACCESSING_BITS_0_7) + m_osc_select = (data & 0xff) % (1+m_active_osc); break; default: #ifdef ICS2115_DEBUG - printf("ICS2115: Unhandled write %x onto %x(%d) [voice = %d]\n", data, m_reg_select, msb, m_osc_select); + logerror("ICS2115: Unhandled write %x onto %x [voice = %d]\n", data, m_reg_select, m_osc_select); #endif break; } } -READ8_MEMBER(ics2115_device::read) +u8 ics2115_device::read(offs_t offset) { - uint8_t ret = 0; + u8 ret = 0; - switch(offset) { + switch (offset) + { case 0: //TODO: check this suspect code - if (m_irq_on) { + if (m_irq_on) + { ret |= 0x80; if (m_irq_enabled && (m_irq_pending & 3)) ret |= 1; - for (int i = 0; i <= m_active_osc; i++) { + for (int i = 0; i <= m_active_osc; i++) + { if (//m_voice[i].vol_ctrl.bitflags.irq_pending || - m_voice[i].osc_conf.bitflags.irq_pending) { + m_voice[i].osc_conf.bitflags.irq_pending) + { ret |= 2; break; } @@ -782,35 +834,89 @@ READ8_MEMBER(ics2115_device::read) ret = m_reg_select; break; case 2: - ret = (uint8_t)(reg_read()); + ret = (u8)(reg_read()); break; case 3: ret = reg_read() >> 8; break; default: #ifdef ICS2115_DEBUG - printf("ICS2115: Unhandled memory read at %x\n", offset); + logerror("ICS2115: Unhandled memory read at %x\n", offset); #endif break; } return ret; } -WRITE8_MEMBER(ics2115_device::write) +void ics2115_device::write(offs_t offset, u8 data) { - switch(offset) { + switch (offset) + { case 1: m_reg_select = data; break; case 2: - reg_write(data,0); + reg_write(data, 0x00ff); break; case 3: - reg_write(data,1); + reg_write(data << 8, 0xff00); break; default: #ifdef ICS2115_DEBUG - printf("ICS2115: Unhandled memory write %02x to %x\n", data, offset); + logerror("ICS2115: Unhandled memory write %02x to %x\n", data, offset); +#endif + break; + } +} + +u16 ics2115_device::word_r(offs_t offset, u16 mem_mask) +{ + u16 ret = 0; + + switch (offset) + { + case 0: + case 1: + if (ACCESSING_BITS_0_7) + ret |= read(offset); + break; + case 2: + ret |= reg_read() & mem_mask; + break; + /* + case 3: + TODO : used for byte size only; + break; + */ + default: +#ifdef ICS2115_DEBUG + logerror("ICS2115: Unhandled memory read at %x\n", offset); +#endif + break; + } + return ret; +} + +void ics2115_device::word_w(offs_t offset, u16 data, u16 mem_mask) +{ + switch (offset) + { + case 0: + case 1: + if (ACCESSING_BITS_0_7) + write(offset, data & 0xff); + break; + case 2: + reg_write(data, mem_mask); + break; + /* + case 3: + TODO : used for byte size only; + break; + */ + default: +#ifdef ICS2115_DEBUG + logerror("ICS2115: Unhandled memory write %02x to %x\n", data, offset); #endif break; } @@ -828,7 +934,7 @@ void ics2115_device::keyon() m_voice[m_osc_select].state.bitflags.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, + logerror("[%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, @@ -844,17 +950,17 @@ void ics2115_device::keyon() ); #endif //testing memory corruption issue with mame stream - //printf("m_volume[0x%x]=0x%x\n", mastervolume, m_volume[mastervolume]); + //logerror("m_volume[0x%x]=0x%x\n", mastervolume, m_volume[mastervolume]); } void ics2115_device::recalc_irq() { //Suspect bool irq = (m_irq_pending & m_irq_enabled); - for(int i = 0; (!irq) && (i < 32); i++) + for (int i = 0; (!irq) && (i < 32); i++) irq |= m_voice[i].vol_ctrl.bitflags.irq_pending && m_voice[i].osc_conf.bitflags.irq_pending; m_irq_on = irq; - if(!m_irq_cb.isnull()) + if (!m_irq_cb.isnull()) m_irq_cb(irq ? ASSERT_LINE : CLEAR_LINE); } @@ -873,16 +979,17 @@ TIMER_CALLBACK_MEMBER( ics2115_device::timer_cb_1 ) void ics2115_device::recalc_timer(int timer) { //Old regression-based formula (minus constant) - //uint64_t period = m_timer[timer].preset * (m_timer[timer].scale << 16) / 60; + //u64 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_t period = ((m_timer[timer].scale & 0x1f) + 1) * (m_timer[timer].preset + 1); + u64 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) { + if (m_timer[timer].period != period) + { m_timer[timer].period = period; // Adjust the timer lengths - if(period) // Reset the length + if (period) // Reset the length m_timer[timer].timer->adjust(attotime::from_nsec(period), 0, attotime::from_nsec(period)); else // Kill the timer if length == 0 m_timer[timer].timer->adjust(attotime::never); |