summaryrefslogtreecommitdiffstatshomepage
path: root/src/mess/audio/gamate.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/mess/audio/gamate.c')
-rw-r--r--src/mess/audio/gamate.c159
1 files changed, 131 insertions, 28 deletions
diff --git a/src/mess/audio/gamate.c b/src/mess/audio/gamate.c
index 5c682841076..4abb8a5f14b 100644
--- a/src/mess/audio/gamate.c
+++ b/src/mess/audio/gamate.c
@@ -1,17 +1,22 @@
/***************************************************************************
gamate sound hardware
- PeT mess@utanet.at
+ PeT mess@utanet.at 2015
***************************************************************************/
#include "emu.h"
#include "includes/gamate.h"
+#include "ui/ui.h"
+enum { ClockDelay=32 };
+
// device type definition
const device_type GAMATE_SND = &device_creator<gamate_sound_device>;
-
+const int gamate_sound_device::DAConverter[]={ 0, 3, 7, 13, 23, 41, 75, 137, 249, 453, 825, 1499, 2726, 4956, 9011, 16383 }; // (*.55) on the real below index 8 bareless measureable
+const UINT8 Mask[]={ 0xff, 0x0f, 0xff, 0x0f, 0xff, 0x0f, 0x1f, 0x3f, 0x1f, 0x1f, 0x1f, 0xff, 0xff, 0xf };
+const int EnvelopeVolumes[]={ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0 };
//**************************************************************************
// LIVE DEVICE
//**************************************************************************
@@ -27,7 +32,6 @@ gamate_sound_device::gamate_sound_device(const machine_config &mconfig, const ch
{
}
-
//-------------------------------------------------
// device_start - device-specific startup
//-------------------------------------------------
@@ -35,7 +39,7 @@ gamate_sound_device::gamate_sound_device(const machine_config &mconfig, const ch
void gamate_sound_device::device_start()
{
// bind callbacks
-// m_irq_cb.bind_relative_to(*owner());
+// m_irq_cb.bind_relative_to(*owner());
memset(m_channels, 0, sizeof(m_channels));
memset(reg, 0, sizeof(reg));
@@ -52,31 +56,94 @@ void gamate_sound_device::sound_stream_update(sound_stream &stream, stream_sampl
{
stream_sample_t *left=outputs[0], *right=outputs[1];
int i, j;
- GAMATE_CHANNEL *channel;
-
+ Tone *channel;
+
for (i = 0; i < samples; i++, left++, right++)
{
+ noise.pos += noise.step;
+ while (noise.pos >= 1.0) {
+ // guess (white noise register taken from supervision)
+ noise.level = noise.state & 0x40 ? 1 : 0;
+ bool b1 = (noise.state & 0x40) != 0, b2 = (noise.state & 0x20) != 0;
+ noise.state=(noise.state<<1)+(b1!=b2?1:0);
+ noise.pos -= 1;
+ }
+
+ envelope.pos += envelope.step;
+ while (envelope.pos >= 1.0) {
+ envelope.pos -= 1;
+ envelope.index++;
+ switch (envelope.control) {
+ case 0: case 1: case 2: case 3:
+ case 4: case 5: case 6: case 7:
+ case 8: case 9: case 0xb:
+ case 0xd: case 0xf:
+ if (envelope.index>=ARRAY_LENGTH(EnvelopeVolumes)/2) {
+ envelope.index=0;
+ envelope.first=false;
+ }
+ break;
+ default:
+ if (envelope.index>=ARRAY_LENGTH(EnvelopeVolumes)) {
+ envelope.index=0;
+ envelope.first=false;
+ }
+ break;
+ }
+
+ }
+
*left = 0;
*right = 0;
for (channel=m_channels, j=0; j<ARRAY_LENGTH(m_channels); j++, channel++)
{
if (channel->size != 0)
{
- if (channel->on)//||channel->count)
- {
- int on = FALSE;
- on = channel->pos <= channel->size / 2;
- {
- INT16 s = on ? channel->volume << 8 : 0;
- if (j == 0)
- *right += s;
- else if (j==1)
- *left += s;
- else {
- *right += s;
- *left += s;
- }
- }
+ channel->level= channel->pos <= channel->size / 2;
+ bool l= channel->full_cycle? true: channel->level;
+ if (!channel->tone) l= l && noise.level;
+ int volume=0;
+ if (l) {
+ if (channel->envelope_on) {
+ switch (envelope.control) {
+ case 0: case 1: case 2: case 3:
+ case 0x9: // one time falling, low
+ if (envelope.first && channel->level) volume=0xf-EnvelopeVolumes[envelope.index];
+ break;
+ case 4: case 5: case 6: case 7:
+ case 0xf: // one time rising, low
+ if (envelope.first && channel->level) volume=EnvelopeVolumes[envelope.index];
+ break;
+ case 8: // falling
+ if (channel->level) volume=0xf-EnvelopeVolumes[envelope.index];
+ break;
+ case 0xa: // rising, falling
+ if (channel->level) volume=EnvelopeVolumes[envelope.index];
+ break;
+ case 0xb: // one time falling, high
+ if (channel->level) volume=envelope.first? 0xf-EnvelopeVolumes[envelope.index]: 0xf;
+ break;
+ case 0xc: // rising, low
+ if (channel->level) volume=envelope.index<ARRAY_LENGTH(EnvelopeVolumes)/2? EnvelopeVolumes[envelope.index]: 0;
+ break;
+ case 0xd: // one time rising, high
+ if (channel->level) volume=envelope.first? EnvelopeVolumes[envelope.index]: 0xf;
+ break;
+ case 0xe: // falling, rising
+ if (channel->level) volume=0xf-EnvelopeVolumes[envelope.index];
+ break;
+ }
+ } else {
+ volume=channel->volume;
+ }
+ }
+ if (j == Right)
+ *right += Value2Volume(volume);
+ else if (j==Left)
+ *left += Value2Volume(volume);
+ else {
+ *right += Value2Volume(volume);
+ *left += Value2Volume(volume);
}
channel->pos++;
if (channel->pos >= channel->size)
@@ -94,7 +161,7 @@ WRITE8_MEMBER( gamate_sound_device::device_w )
reg[offset] = data;
int chan=-1;
- switch (offset)
+ switch (offset&0xf)
{
case 0:
case 1:
@@ -102,11 +169,11 @@ WRITE8_MEMBER( gamate_sound_device::device_w )
case 3:
case 4:
case 5:
- chan=offset/2;
+ chan=offset/2;
size = reg[chan*2] | ((reg[chan*2+1] & 0xf) << 8);
if (size)
{
- m_channels[chan].size= (int) (machine().sample_rate() * (size << 5) / machine().device("maincpu")->unscaled_clock());
+ m_channels[chan].size= (int) (machine().sample_rate() * size*ClockDelay / machine().device("maincpu")->unscaled_clock());
}
else
{
@@ -115,13 +182,49 @@ WRITE8_MEMBER( gamate_sound_device::device_w )
m_channels[chan].pos = 0;
break;
case 6:
+ size=data&0x1f;
+ if (size==0) size=1;
+ noise.step= machine().device("maincpu")->unscaled_clock() / (1.0*ClockDelay*machine().sample_rate()*size);
+ break;
case 7:
+ m_channels[Right].full_cycle=data&1;
+ m_channels[Right].tone=data&8;
+ m_channels[Left].full_cycle=data&2;
+ m_channels[Left].tone=data&0x10;
+ m_channels[Both].full_cycle=data&4;
+ m_channels[Both].tone=data&0x20;
+ noise.state=1;
+ noise.pos=0.0;
+ noise.level=false;
+ break;
case 8:
- chan=offset-6;
-// m_channels[chan]->on = data & 0x40;
-// channel->waveform = (data & 0x30) >> 4;
+ case 9:
+ case 0xa:
+ chan=offset-8;
+ m_channels[chan].envelope_on = data & 0x10; // buggy aussetzer cube up
m_channels[chan].volume = data & 0xf;
break;
+ case 0xb: case 0xc:
+ size = reg[0xb] | ((reg[0xc]) << 8);
+ if (size==0) size=1;
+ envelope.step= machine().device("maincpu")->unscaled_clock() / (1.0*ClockDelay*machine().sample_rate()*size);
+ break;
+ case 0xd:
+ envelope.control=data&0xf;
+ envelope.pos=0;
+ envelope.index=0;
+ envelope.first=true;
+ break;
+
}
- if (chan!=-1) m_channels[chan].on=m_channels[chan].volume!=0 && m_channels[chan].size>3/* avoid speed loss for unhearable >=23khz*/;
+ envelope.pos=0; // guess
+ envelope.index=0;
+ envelope.first=true;
+}
+
+READ8_MEMBER( gamate_sound_device::device_r )
+{
+ UINT8 data=0;
+ if ((offset&0xf)<ARRAY_LENGTH(Mask)) data=reg[offset&0xf]&Mask[offset&0xf]; // unused bits set to last write value? in this area
+ return data;
}