diff options
Diffstat (limited to 'src/devices/sound/l7a1045_l6028_dsp_a.cpp')
-rw-r--r-- | src/devices/sound/l7a1045_l6028_dsp_a.cpp | 138 |
1 files changed, 77 insertions, 61 deletions
diff --git a/src/devices/sound/l7a1045_l6028_dsp_a.cpp b/src/devices/sound/l7a1045_l6028_dsp_a.cpp index ae6e7b49a3d..aeb87e47968 100644 --- a/src/devices/sound/l7a1045_l6028_dsp_a.cpp +++ b/src/devices/sound/l7a1045_l6028_dsp_a.cpp @@ -1,6 +1,6 @@ // license:LGPL-2.1+ // copyright-holders:David Haywood, Angelo Salese, ElSemi -/*************************************************************************** +/************************************************************************************************** L7A1045 L6028 DSP-A (QFP120 package) @@ -77,11 +77,16 @@ TODO: - Sample format needs to be double checked; - - Octave Control/BPM/Pitch, right now XRally Network BGM wants 66150 Hz which is definitely too fast for Terry Bogard speech; - - Key Off; + - Octave Control/BPM/Pitch, xrally Network BGM wants 66150 Hz which is definitely too fast for + most fatfurwa samples; + - Key Off for looping samples (fatfurwa should stop all samples when user insert a credit, + cfr. reg[0] readback); + - Most non-looping samples are setup to repeat twice on different channels (cfr. fatfurwa); + - Fix relative sample end positions (non-loop); - ADSR (registers 2 & 4?); + - How DMA really works? -***************************************************************************/ +**************************************************************************************************/ #include "emu.h" #include "l7a1045_l6028_dsp_a.h" @@ -116,41 +121,41 @@ l7a1045_sound_device::l7a1045_sound_device(const machine_config &mconfig, const void l7a1045_sound_device::device_start() { - /* Allocate the stream */ - m_stream = stream_alloc(0, 2, 66150); //clock() / 384); - - for (int voice = 0; voice < 32; voice++) - { - save_item(NAME(m_voice[voice].start), voice); - save_item(NAME(m_voice[voice].end), voice); - save_item(NAME(m_voice[voice].mode), voice); - save_item(NAME(m_voice[voice].pos), voice); - save_item(NAME(m_voice[voice].frac), voice); - save_item(NAME(m_voice[voice].l_volume), voice); - save_item(NAME(m_voice[voice].r_volume), voice); - } + // assumes it can make an address mask with m_rom.length() - 1 + assert(!(m_rom.length() & (m_rom.length() - 1))); + + // Allocate the stream +// m_stream = stream_alloc(0, 2, 66150); //clock() / 384); + // TODO: confirm frequency + m_stream = stream_alloc(0, 2, 44100); + + save_item(STRUCT_MEMBER(m_voice, start)); + save_item(STRUCT_MEMBER(m_voice, end)); + save_item(STRUCT_MEMBER(m_voice, mode)); + save_item(STRUCT_MEMBER(m_voice, pos)); + save_item(STRUCT_MEMBER(m_voice, frac)); + save_item(STRUCT_MEMBER(m_voice, l_volume)); + save_item(STRUCT_MEMBER(m_voice, r_volume)); save_item(NAME(m_key)); save_item(NAME(m_audiochannel)); save_item(NAME(m_audioregister)); - for (int reg = 0; reg < 0x10; reg++) - { - for (int voice = 0; voice < 0x20; voice++) - { - save_item(NAME(m_audiodat[reg][voice].dat), (reg << 8) | voice); - } - } + save_item(STRUCT_MEMBER(m_audiodat, dat)); } +void l7a1045_sound_device::device_reset() +{ + m_key = 0; +} //------------------------------------------------- // sound_stream_update - handle a stream update //------------------------------------------------- -void l7a1045_sound_device::sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples) +void l7a1045_sound_device::sound_stream_update(sound_stream &stream, std::vector<read_stream_view> const &inputs, std::vector<write_stream_view> &outputs) { /* Clear the buffers */ - memset(outputs[0], 0, samples*sizeof(*outputs[0])); - memset(outputs[1], 0, samples*sizeof(*outputs[1])); + outputs[0].fill(0); + outputs[1].fill(0); for (int i = 0; i < 32; i++) { @@ -165,7 +170,7 @@ void l7a1045_sound_device::sound_stream_update(sound_stream &stream, stream_samp uint32_t pos = vptr->pos; uint32_t frac = vptr->frac; - for (int j = 0; j < samples; j++) + for (int j = 0; j < outputs[0].samples(); j++) { int32_t sample; uint8_t data; @@ -188,12 +193,12 @@ void l7a1045_sound_device::sound_stream_update(sound_stream &stream, stream_samp } - data = m_rom[(start + pos) & m_rom.mask()]; - sample = ((int8_t)(data & 0xfc)) << (3 - (data & 3)); + data = m_rom[(start + pos) & (m_rom.length() - 1)]; + sample = int8_t(data & 0xfc) << (3 - (data & 3)); frac += step; - outputs[0][j] += ((sample * vptr->l_volume) >> 9); - outputs[1][j] += ((sample * vptr->r_volume) >> 9); + outputs[0].add_int(j, sample * vptr->l_volume, 32768 * 512); + outputs[1].add_int(j, sample * vptr->r_volume, 32768 * 512); } vptr->pos = pos; @@ -203,37 +208,39 @@ void l7a1045_sound_device::sound_stream_update(sound_stream &stream, stream_samp } // TODO: needs proper memory map -WRITE16_MEMBER( l7a1045_sound_device::l7a1045_sound_w ) +void l7a1045_sound_device::l7a1045_sound_w(offs_t offset, uint16_t data, uint16_t mem_mask) { m_stream->update(); // TODO //logerror("%s: %x to %x (mask %04x)\n", tag(), data, offset, mem_mask); if(offset == 0) - sound_select_w(space, offset, data, mem_mask); + sound_select_w(offset, data, mem_mask); else if(offset == 8/2) - sound_status_w(space, offset, data, mem_mask); + sound_status_w(data); else - sound_data_w(space,offset - 1,data,mem_mask); + sound_data_w(offset - 1,data); } -READ16_MEMBER( l7a1045_sound_device::l7a1045_sound_r ) +uint16_t l7a1045_sound_device::l7a1045_sound_r(offs_t offset, uint16_t mem_mask) { m_stream->update(); //logerror("%s: read at %x (mask %04x)\n", tag(), offset, mem_mask); - if(offset == 0) - printf("sound_select_r?\n"); + if (offset == 0) + { + //logerror("sound_select_r?\n"); + } else - return sound_data_r(space,offset -1,mem_mask); + return sound_data_r(offset -1); return 0xffff; } -WRITE16_MEMBER(l7a1045_sound_device::sound_select_w) +void l7a1045_sound_device::sound_select_w(offs_t offset, uint16_t data, uint16_t mem_mask) { // I'm guessing these addresses are the sound chip / DSP? @@ -256,12 +263,12 @@ WRITE16_MEMBER(l7a1045_sound_device::sound_select_w) } -WRITE16_MEMBER(l7a1045_sound_device::sound_data_w) +void l7a1045_sound_device::sound_data_w(offs_t offset, uint16_t data) { l7a1045_voice *vptr = &m_voice[m_audiochannel]; //if(m_audioregister != 0 && m_audioregister != 1 && m_audioregister != 7) - // printf("%04x %04x (%04x %04x)\n",offset,data,m_audioregister,m_audiochannel); + // logerror("%04x %04x (%04x %04x)\n",offset,data,m_audioregister,m_audiochannel); m_audiodat[m_audioregister][m_audiochannel].dat[offset] = data; @@ -277,7 +284,7 @@ WRITE16_MEMBER(l7a1045_sound_device::sound_data_w) //logerror("%s: channel %d start = %08x\n", tag(), m_audiochannel, vptr->start); - vptr->start &= m_rom.mask(); + vptr->start &= m_rom.length() - 1; // if voice isn't active, clear the pos on start writes (required for DMA tests on MPC3000) if (!(m_key & (1 << m_audiochannel))) @@ -287,18 +294,20 @@ WRITE16_MEMBER(l7a1045_sound_device::sound_data_w) break; case 0x01: // relative to start - //printf("%04x\n",m_audiodat[m_audioregister][m_audiochannel].dat[0]); - //printf("%04x\n",m_audiodat[m_audioregister][m_audiochannel].dat[1]); - //printf("%04x\n",m_audiodat[m_audioregister][m_audiochannel].dat[2]); + //logerror("%04x\n",m_audiodat[m_audioregister][m_audiochannel].dat[0]); + //logerror("%04x\n",m_audiodat[m_audioregister][m_audiochannel].dat[1]); + //logerror("%04x\n",m_audiodat[m_audioregister][m_audiochannel].dat[2]); if(m_audiodat[m_audioregister][m_audiochannel].dat[2] & 0x100) { + // TODO: definitely wrong + // fatfurwa title screen sample 0x45a (0x8000?) + // fatfurwa coin 0x3a0 (0x2000?) vptr->end = (m_audiodat[m_audioregister][m_audiochannel].dat[0] & 0xffff) << 2; vptr->end += vptr->start; vptr->mode = false; // hopefully it'll never happen? Maybe assert here? - vptr->end &= m_rom.mask(); - + vptr->end &= m_rom.length() - 1; } else // absolute { @@ -307,7 +316,7 @@ WRITE16_MEMBER(l7a1045_sound_device::sound_data_w) vptr->end |= (m_audiodat[m_audioregister][m_audiochannel].dat[0] & 0xf000) >> (12); vptr->mode = true; - vptr->end &= m_rom.mask(); + vptr->end &= m_rom.length() - 1; } //logerror("%s: channel %d end = %08x\n", tag(), m_audiochannel, vptr->start); break; @@ -319,16 +328,16 @@ WRITE16_MEMBER(l7a1045_sound_device::sound_data_w) vptr->r_volume = (vptr->r_volume) | (vptr->r_volume << 8); vptr->l_volume = (m_audiodat[m_audioregister][m_audiochannel].dat[0] >> 8) & 0xff; vptr->l_volume = (vptr->l_volume) | (vptr->l_volume << 8); - //printf("%04x %02x %02x\n",m_audiodat[m_audioregister][m_audiochannel].dat[0],vptr->l_volume,vptr->r_volume); + //logerror("%04x %02x %02x\n",m_audiodat[m_audioregister][m_audiochannel].dat[0],vptr->l_volume,vptr->r_volume); break; } } -READ16_MEMBER(l7a1045_sound_device::sound_data_r) +uint16_t l7a1045_sound_device::sound_data_r(offs_t offset) { - //printf("%04x (%04x %04x)\n",offset,m_audioregister,m_audiochannel); + //logerror("%04x (%04x %04x)\n",offset,m_audioregister,m_audiochannel); //machine().debug_break(); l7a1045_voice *vptr = &m_voice[m_audiochannel]; @@ -339,6 +348,9 @@ READ16_MEMBER(l7a1045_sound_device::sound_data_r) uint32_t current_addr; uint16_t res; + // TODO: fatfurwa reads offset == 2, ANDs with 0xf and compares against a sample buffer value if it's bigger, smaller or equal + // Returning 0xffff here for looping samples and they will silence out when user insert a coin ... + current_addr = vptr->start + vptr->pos; if(offset == 0) res = (current_addr & 0xf) << 12; // TODO: frac @@ -351,10 +363,13 @@ READ16_MEMBER(l7a1045_sound_device::sound_data_r) } } + // TODO: at least regs [3] and [5], relative position read-back? + // TODO: reg [6] + return 0; } -WRITE16_MEMBER(l7a1045_sound_device::sound_status_w) +void l7a1045_sound_device::sound_status_w(uint16_t data) { if(data & 0x100) // keyin { @@ -363,11 +378,11 @@ WRITE16_MEMBER(l7a1045_sound_device::sound_status_w) #if 0 if(vptr->start != 0) { - printf("%08x START\n",vptr->start); - printf("%08x END\n",vptr->end); + logerror("%08x START\n",vptr->start); + logerror("%08x END\n",vptr->end); - for(int i=0;i<0x10;i++) - printf("%02x (%02x) = %04x%04x%04x\n",m_audiochannel,i,m_audiodat[i][m_audiochannel].dat[2],m_audiodat[i][m_audiochannel].dat[1],m_audiodat[i][m_audiochannel].dat[0]); + for(int i=0;i<0x10;i++) + logerror("%02x (%02x) = %04x%04x%04x\n",m_audiochannel,i,m_audiodat[i][m_audiochannel].dat[2],m_audiodat[i][m_audiochannel].dat[1],m_audiodat[i][m_audiochannel].dat[0]); } #endif @@ -377,12 +392,13 @@ WRITE16_MEMBER(l7a1045_sound_device::sound_status_w) } } -WRITE_LINE_MEMBER(l7a1045_sound_device::dma_hreq_cb) +// TODO: stub functions not really used +void l7a1045_sound_device::dma_hreq_cb(int state) { // m_maincpu->hack_w(1); } -READ8_MEMBER(l7a1045_sound_device::dma_r_cb) +uint8_t l7a1045_sound_device::dma_r_cb(offs_t offset) { // logerror("dma_ior3_cb: offset %x\n", offset); @@ -390,7 +406,7 @@ READ8_MEMBER(l7a1045_sound_device::dma_r_cb) return 0; } -WRITE8_MEMBER(l7a1045_sound_device::dma_w_cb) +void l7a1045_sound_device::dma_w_cb(offs_t offset, uint8_t data) { m_voice[0].pos++; // logerror("dma_iow3_cb: offset %x\n", offset); |