summaryrefslogtreecommitdiffstatshomepage
path: root/src/devices/sound/l7a1045_l6028_dsp_a.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/devices/sound/l7a1045_l6028_dsp_a.cpp')
-rw-r--r--src/devices/sound/l7a1045_l6028_dsp_a.cpp138
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);