mirror of
https://github.com/holub/mame
synced 2025-04-25 01:40:16 +03:00
removed SN76496 legacy device
This commit is contained in:
parent
d5b70be511
commit
e5962020d6
@ -104,6 +104,9 @@
|
||||
frequency register, while the others have 0x400 as before. Should fix a bug
|
||||
or two on sega games, particularly Vigilante on Sega Master System. Verified
|
||||
on SMS hardware.
|
||||
|
||||
27/06/2012: Michael Zapf
|
||||
Converted to modern device, legacy devices were gradually removed afterwards.
|
||||
|
||||
TODO: * Implement the TMS9919 - any difference to sn94624?
|
||||
* Implement the T6W28; has registers in a weird order, needs writes
|
||||
@ -117,668 +120,9 @@
|
||||
#include "emu.h"
|
||||
#include "sn76496.h"
|
||||
|
||||
|
||||
#define MAX_OUTPUT 0x7fff
|
||||
#define NOISEMODE (R->Register[6]&4)?1:0
|
||||
|
||||
|
||||
struct sn76496_state
|
||||
{
|
||||
sound_stream * Channel;
|
||||
INT32 VolTable[16]; /* volume table (for 4-bit to db conversion)*/
|
||||
INT32 Register[8]; /* registers */
|
||||
INT32 LastRegister; /* last register written */
|
||||
INT32 Volume[4]; /* db volume of voice 0-2 and noise */
|
||||
UINT32 RNG; /* noise generator LFSR*/
|
||||
INT32 ClockDivider; /* clock divider */
|
||||
INT32 CurrentClock;
|
||||
INT32 FeedbackMask; /* mask for feedback */
|
||||
INT32 WhitenoiseTap1; /* mask for white noise tap 1 (higher one, usually bit 14) */
|
||||
INT32 WhitenoiseTap2; /* mask for white noise tap 2 (lower one, usually bit 13)*/
|
||||
INT32 Negate; /* output negate flag */
|
||||
INT32 Stereo; /* whether we're dealing with stereo or not */
|
||||
INT32 StereoMask; /* the stereo output mask */
|
||||
INT32 Period[4]; /* Length of 1/2 of waveform */
|
||||
INT32 Count[4]; /* Position within the waveform */
|
||||
INT32 Output[4]; /* 1-bit output of each channel, pre-volume */
|
||||
INT32 CyclestoREADY;/* number of cycles until the READY line goes active */
|
||||
INT32 Freq0IsMax; /* flag for if frequency zero acts as if it is one more than max (0x3ff+1) or if it acts like 0 */
|
||||
};
|
||||
|
||||
|
||||
INLINE sn76496_state *get_safe_token(device_t *device)
|
||||
{
|
||||
assert(device != NULL);
|
||||
assert(device->type() == SN76496 ||
|
||||
device->type() == U8106 ||
|
||||
device->type() == Y2404 ||
|
||||
device->type() == SN76489 ||
|
||||
device->type() == SN76489A ||
|
||||
device->type() == SN76494 ||
|
||||
device->type() == SN94624 ||
|
||||
device->type() == NCR7496 ||
|
||||
device->type() == GAMEGEAR ||
|
||||
device->type() == SEGAPSG);
|
||||
return (sn76496_state *)downcast<sn76496_device *>(device)->token();
|
||||
}
|
||||
|
||||
READ_LINE_DEVICE_HANDLER( sn76496_ready_r )
|
||||
{
|
||||
sn76496_state *R = get_safe_token(device);
|
||||
R->Channel->update();
|
||||
return (R->CyclestoREADY? 0 : 1);
|
||||
}
|
||||
|
||||
WRITE8_DEVICE_HANDLER( sn76496_stereo_w )
|
||||
{
|
||||
sn76496_state *R = get_safe_token(device);
|
||||
R->Channel->update();
|
||||
if (R->Stereo) R->StereoMask = data;
|
||||
else fatalerror("Call to stereo write with mono chip!\n");
|
||||
}
|
||||
|
||||
WRITE8_DEVICE_HANDLER( sn76496_w )
|
||||
{
|
||||
sn76496_state *R = get_safe_token(device);
|
||||
int n, r, c;
|
||||
|
||||
|
||||
/* update the output buffer before changing the registers */
|
||||
R->Channel->update();
|
||||
|
||||
/* set number of cycles until READY is active; this is always one
|
||||
'sample', i.e. it equals the clock divider exactly; until the
|
||||
clock divider is fully supported, we delay until one sample has
|
||||
played. The fact that this below is '2' and not '1' is because
|
||||
of a ?race condition? in the mess crvision driver, where after
|
||||
any sample is played at all, no matter what, the cycles_to_ready
|
||||
ends up never being not ready, unless this value is greater than
|
||||
1. Once the full clock divider stuff is written, this should no
|
||||
longer be an issue. */
|
||||
R->CyclestoREADY = 2;
|
||||
|
||||
if (data & 0x80)
|
||||
{
|
||||
r = (data & 0x70) >> 4;
|
||||
R->LastRegister = r;
|
||||
R->Register[r] = (R->Register[r] & 0x3f0) | (data & 0x0f);
|
||||
}
|
||||
else
|
||||
{
|
||||
r = R->LastRegister;
|
||||
}
|
||||
c = r/2;
|
||||
switch (r)
|
||||
{
|
||||
case 0: /* tone 0 : frequency */
|
||||
case 2: /* tone 1 : frequency */
|
||||
case 4: /* tone 2 : frequency */
|
||||
if ((data & 0x80) == 0) R->Register[r] = (R->Register[r] & 0x0f) | ((data & 0x3f) << 4);
|
||||
if ((R->Register[r] != 0) || (R->Freq0IsMax == 0)) R->Period[c] = R->Register[r];
|
||||
else R->Period[c] = 0x400;
|
||||
|
||||
if (r == 4)
|
||||
{
|
||||
/* update noise shift frequency */
|
||||
if ((R->Register[6] & 0x03) == 0x03)
|
||||
R->Period[3] = 2 * R->Period[2];
|
||||
}
|
||||
break;
|
||||
case 1: /* tone 0 : volume */
|
||||
case 3: /* tone 1 : volume */
|
||||
case 5: /* tone 2 : volume */
|
||||
case 7: /* noise : volume */
|
||||
R->Volume[c] = R->VolTable[data & 0x0f];
|
||||
if ((data & 0x80) == 0) R->Register[r] = (R->Register[r] & 0x3f0) | (data & 0x0f);
|
||||
break;
|
||||
case 6: /* noise : frequency, mode */
|
||||
{
|
||||
if ((data & 0x80) == 0) logerror("sn76489: write to reg 6 with bit 7 clear; data was %03x, new write is %02x! report this to LN!\n", R->Register[6], data);
|
||||
if ((data & 0x80) == 0) R->Register[r] = (R->Register[r] & 0x3f0) | (data & 0x0f);
|
||||
n = R->Register[6];
|
||||
/* N/512,N/1024,N/2048,Tone #3 output */
|
||||
R->Period[3] = ((n&3) == 3) ? 2 * R->Period[2] : (1 << (5+(n&3)));
|
||||
R->RNG = R->FeedbackMask;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static STREAM_UPDATE( SN76496Update )
|
||||
{
|
||||
int i;
|
||||
sn76496_state *R = (sn76496_state *)param;
|
||||
stream_sample_t *lbuffer = outputs[0];
|
||||
stream_sample_t *rbuffer = (R->Stereo)?outputs[1]:NULL;
|
||||
INT16 out = 0;
|
||||
INT16 out2 = 0;
|
||||
|
||||
while (samples > 0)
|
||||
{
|
||||
// clock chip once
|
||||
if (R->CurrentClock > 0) // not ready for new divided clock
|
||||
{
|
||||
R->CurrentClock--;
|
||||
}
|
||||
else // ready for new divided clock, make a new sample
|
||||
{
|
||||
R->CurrentClock = R->ClockDivider-1;
|
||||
/* decrement Cycles to READY by one */
|
||||
if (R->CyclestoREADY >0) R->CyclestoREADY--;
|
||||
|
||||
// handle channels 0,1,2
|
||||
for (i = 0;i < 3;i++)
|
||||
{
|
||||
R->Count[i]--;
|
||||
if (R->Count[i] <= 0)
|
||||
{
|
||||
R->Output[i] ^= 1;
|
||||
R->Count[i] = R->Period[i];
|
||||
}
|
||||
}
|
||||
|
||||
// handle channel 3
|
||||
R->Count[3]--;
|
||||
if (R->Count[3] <= 0)
|
||||
{
|
||||
// if noisemode is 1, both taps are enabled
|
||||
// if noisemode is 0, the lower tap, whitenoisetap2, is held at 0
|
||||
if (((R->RNG & R->WhitenoiseTap1)?1:0) ^ ((((R->RNG & R->WhitenoiseTap2)?1:0))*(NOISEMODE)))
|
||||
{
|
||||
R->RNG >>= 1;
|
||||
R->RNG |= R->FeedbackMask;
|
||||
}
|
||||
else
|
||||
{
|
||||
R->RNG >>= 1;
|
||||
}
|
||||
R->Output[3] = R->RNG & 1;
|
||||
|
||||
R->Count[3] = R->Period[3];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (R->Stereo)
|
||||
{
|
||||
out = (((R->StereoMask&0x10)&&R->Output[0])?R->Volume[0]:0)
|
||||
+ (((R->StereoMask&0x20)&&R->Output[1])?R->Volume[1]:0)
|
||||
+ (((R->StereoMask&0x40)&&R->Output[2])?R->Volume[2]:0)
|
||||
+ (((R->StereoMask&0x80)&&R->Output[3])?R->Volume[3]:0);
|
||||
|
||||
out2 = (((R->StereoMask&0x1)&&R->Output[0])?R->Volume[0]:0)
|
||||
+ (((R->StereoMask&0x2)&&R->Output[1])?R->Volume[1]:0)
|
||||
+ (((R->StereoMask&0x4)&&R->Output[2])?R->Volume[2]:0)
|
||||
+ (((R->StereoMask&0x8)&&R->Output[3])?R->Volume[3]:0);
|
||||
}
|
||||
else
|
||||
{
|
||||
out = (R->Output[0]?R->Volume[0]:0)
|
||||
+(R->Output[1]?R->Volume[1]:0)
|
||||
+(R->Output[2]?R->Volume[2]:0)
|
||||
+(R->Output[3]?R->Volume[3]:0);
|
||||
}
|
||||
|
||||
if(R->Negate) { out = -out; out2 = -out2; }
|
||||
|
||||
*(lbuffer++) = out;
|
||||
if (R->Stereo) *(rbuffer++) = out2;
|
||||
samples--;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
static void SN76496_set_gain(sn76496_state *R,int gain)
|
||||
{
|
||||
int i;
|
||||
double out;
|
||||
|
||||
|
||||
gain &= 0xff;
|
||||
|
||||
/* increase max output basing on gain (0.2 dB per step) */
|
||||
out = MAX_OUTPUT / 4; // four channels, each gets 1/4 of the total range
|
||||
while (gain-- > 0)
|
||||
out *= 1.023292992; /* = (10 ^ (0.2/20)) */
|
||||
|
||||
/* build volume table (2dB per step) */
|
||||
for (i = 0;i < 15;i++)
|
||||
{
|
||||
/* limit volume to avoid clipping */
|
||||
if (out > MAX_OUTPUT / 4) R->VolTable[i] = MAX_OUTPUT / 4;
|
||||
else R->VolTable[i] = out;
|
||||
|
||||
out /= 1.258925412; /* = 10 ^ (2/20) = 2dB */
|
||||
}
|
||||
R->VolTable[15] = 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
static int SN76496_init(device_t *device, sn76496_state *R, int stereo)
|
||||
{
|
||||
int sample_rate = device->clock()/2;
|
||||
int i;
|
||||
|
||||
R->Channel = device->machine().sound().stream_alloc(*device,0,(stereo?2:1),sample_rate,R,SN76496Update);
|
||||
|
||||
for (i = 0;i < 4;i++) R->Volume[i] = 0;
|
||||
|
||||
R->LastRegister = 0;
|
||||
for (i = 0;i < 8;i+=2)
|
||||
{
|
||||
R->Register[i] = 0;
|
||||
R->Register[i + 1] = 0x0f; /* volume = 0 */
|
||||
}
|
||||
|
||||
for (i = 0;i < 4;i++)
|
||||
{
|
||||
R->Output[i] = R->Period[i] = R->Count[i] = 0;
|
||||
}
|
||||
|
||||
/* Default is SN76489A */
|
||||
R->ClockDivider = 8;
|
||||
R->FeedbackMask = 0x10000; /* mask for feedback */
|
||||
R->WhitenoiseTap1 = 0x04; /* mask for white noise tap 1*/
|
||||
R->WhitenoiseTap2 = 0x08; /* mask for white noise tap 2*/
|
||||
R->Negate = 0; /* channels are not negated */
|
||||
R->Stereo = stereo; /* depends on init */
|
||||
R->CyclestoREADY = 1; /* assume ready is not active immediately on init. is this correct?*/
|
||||
R->StereoMask = 0xFF; /* all channels enabled */
|
||||
R->Freq0IsMax = 1; /* frequency set to 0 results in freq = 0x400 rather than 0 */
|
||||
|
||||
R->RNG = R->FeedbackMask;
|
||||
R->Output[3] = R->RNG & 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static void generic_start(device_t *device, int feedbackmask, int noisetap1, int noisetap2, int negate, int stereo, int clockdivider, int freq0)
|
||||
{
|
||||
sn76496_state *chip = get_safe_token(device);
|
||||
|
||||
if (SN76496_init(device,chip,stereo) != 0)
|
||||
fatalerror("Error creating SN76496 chip\n");
|
||||
SN76496_set_gain(chip, 0);
|
||||
|
||||
chip->FeedbackMask = feedbackmask;
|
||||
chip->WhitenoiseTap1 = noisetap1;
|
||||
chip->WhitenoiseTap2 = noisetap2;
|
||||
chip->Negate = negate;
|
||||
chip->Stereo = stereo;
|
||||
chip->ClockDivider = clockdivider;
|
||||
chip->CurrentClock = clockdivider-1;
|
||||
chip->Freq0IsMax = freq0;
|
||||
|
||||
device->save_item(NAME(chip->VolTable));
|
||||
device->save_item(NAME(chip->Register));
|
||||
device->save_item(NAME(chip->LastRegister));
|
||||
device->save_item(NAME(chip->Volume));
|
||||
device->save_item(NAME(chip->RNG));
|
||||
device->save_item(NAME(chip->ClockDivider));
|
||||
device->save_item(NAME(chip->CurrentClock));
|
||||
device->save_item(NAME(chip->FeedbackMask));
|
||||
device->save_item(NAME(chip->WhitenoiseTap1));
|
||||
device->save_item(NAME(chip->WhitenoiseTap2));
|
||||
device->save_item(NAME(chip->Negate));
|
||||
device->save_item(NAME(chip->Stereo));
|
||||
device->save_item(NAME(chip->StereoMask));
|
||||
device->save_item(NAME(chip->Period));
|
||||
device->save_item(NAME(chip->Count));
|
||||
device->save_item(NAME(chip->Output));
|
||||
device->save_item(NAME(chip->CyclestoREADY));
|
||||
device->save_item(NAME(chip->Freq0IsMax));
|
||||
}
|
||||
|
||||
// function parameters: device, feedback destination tap, feedback source taps (1,2),
|
||||
// normal(false)/invert(true), mono(false)/stereo(true), clock divider factor
|
||||
|
||||
static DEVICE_START( sn76489 )
|
||||
{
|
||||
generic_start(device, 0x4000, 0x01, 0x02, TRUE, FALSE, 8, TRUE); // SN76489 not verified yet. todo: verify;
|
||||
}
|
||||
|
||||
static DEVICE_START( u8106 )
|
||||
{
|
||||
generic_start(device, 0x4000, 0x01, 0x02, TRUE, FALSE, 8, TRUE); // U8106 not verified yet. todo: verify; (a custom marked sn76489? only used on mr. do and maybe other universal games)
|
||||
}
|
||||
|
||||
static DEVICE_START( sn76489a )
|
||||
{
|
||||
generic_start(device, 0x10000, 0x04, 0x08, FALSE, FALSE, 8, TRUE); // SN76489A: whitenoise verified, phase verified, periodic verified (by plgdavid)
|
||||
}
|
||||
|
||||
static DEVICE_START( y2404 )
|
||||
{
|
||||
generic_start(device, 0x10000, 0x04, 0x08, FALSE, FALSE, 8, TRUE); // Y2404 not verified yet. todo: verify; (don't be fooled by the Y, it's a TI chip, not Yamaha)
|
||||
}
|
||||
|
||||
static DEVICE_START( sn76494 )
|
||||
{
|
||||
generic_start(device, 0x10000, 0x04, 0x08, FALSE, FALSE, 1, TRUE); // SN76494 not verified, (according to datasheet: same as sn76489a but without the /8 divider)
|
||||
}
|
||||
|
||||
static DEVICE_START( sn76496 )
|
||||
{
|
||||
generic_start(device, 0x10000, 0x04, 0x08, FALSE, FALSE, 8, TRUE); // SN76496: Whitenoise verified, phase verified, periodic verified (by Michael Zapf)
|
||||
}
|
||||
|
||||
static DEVICE_START( sn94624 )
|
||||
{
|
||||
generic_start(device, 0x4000, 0x01, 0x02, TRUE, FALSE, 1, TRUE); // SN94624 whitenoise verified, phase verified, period verified; verified by PlgDavid
|
||||
}
|
||||
|
||||
static DEVICE_START( ncr7496 )
|
||||
{
|
||||
generic_start(device, 0x8000, 0x02, 0x20, FALSE, FALSE, 8, TRUE); // NCR7496 not verified; info from smspower wiki
|
||||
}
|
||||
|
||||
static DEVICE_START( gamegear )
|
||||
{
|
||||
generic_start(device, 0x8000, 0x01, 0x08, TRUE, TRUE, 8, FALSE); // Verified by Justin Kerk
|
||||
}
|
||||
|
||||
static DEVICE_START( segapsg )
|
||||
{
|
||||
generic_start(device, 0x8000, 0x01, 0x08, TRUE, FALSE, 8, FALSE); // todo: verify; from smspower wiki, assumed to have same invert as gamegear
|
||||
}
|
||||
|
||||
const device_type SN76496 = &device_creator<sn76496_device>;
|
||||
|
||||
sn76496_device::sn76496_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
|
||||
: device_t(mconfig, SN76496, "SN76496", tag, owner, clock),
|
||||
device_sound_interface(mconfig, *this)
|
||||
{
|
||||
m_token = global_alloc_clear(sn76496_state);
|
||||
}
|
||||
sn76496_device::sn76496_device(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, UINT32 clock)
|
||||
: device_t(mconfig, type, name, tag, owner, clock),
|
||||
device_sound_interface(mconfig, *this)
|
||||
{
|
||||
m_token = global_alloc_clear(sn76496_state);
|
||||
}
|
||||
|
||||
//-------------------------------------------------
|
||||
// device_config_complete - perform any
|
||||
// operations now that the configuration is
|
||||
// complete
|
||||
//-------------------------------------------------
|
||||
|
||||
void sn76496_device::device_config_complete()
|
||||
{
|
||||
}
|
||||
|
||||
//-------------------------------------------------
|
||||
// device_start - device-specific startup
|
||||
//-------------------------------------------------
|
||||
|
||||
void sn76496_device::device_start()
|
||||
{
|
||||
DEVICE_START_NAME( sn76496 )(this);
|
||||
}
|
||||
|
||||
//-------------------------------------------------
|
||||
// sound_stream_update - handle a stream update
|
||||
//-------------------------------------------------
|
||||
|
||||
void sn76496_device::sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples)
|
||||
{
|
||||
// should never get here
|
||||
fatalerror("sound_stream_update called; not applicable to legacy sound devices\n");
|
||||
}
|
||||
|
||||
|
||||
const device_type U8106 = &device_creator<u8106_device>;
|
||||
|
||||
u8106_device::u8106_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
|
||||
: sn76496_device(mconfig, U8106, "U8106", tag, owner, clock)
|
||||
{
|
||||
}
|
||||
|
||||
//-------------------------------------------------
|
||||
// device_start - device-specific startup
|
||||
//-------------------------------------------------
|
||||
|
||||
void u8106_device::device_start()
|
||||
{
|
||||
DEVICE_START_NAME( u8106 )(this);
|
||||
}
|
||||
|
||||
//-------------------------------------------------
|
||||
// sound_stream_update - handle a stream update
|
||||
//-------------------------------------------------
|
||||
|
||||
void u8106_device::sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples)
|
||||
{
|
||||
// should never get here
|
||||
fatalerror("sound_stream_update called; not applicable to legacy sound devices\n");
|
||||
}
|
||||
|
||||
|
||||
const device_type Y2404 = &device_creator<y2404_device>;
|
||||
|
||||
y2404_device::y2404_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
|
||||
: sn76496_device(mconfig, Y2404, "Y2404", tag, owner, clock)
|
||||
{
|
||||
}
|
||||
|
||||
//-------------------------------------------------
|
||||
// device_start - device-specific startup
|
||||
//-------------------------------------------------
|
||||
|
||||
void y2404_device::device_start()
|
||||
{
|
||||
DEVICE_START_NAME( y2404 )(this);
|
||||
}
|
||||
|
||||
//-------------------------------------------------
|
||||
// sound_stream_update - handle a stream update
|
||||
//-------------------------------------------------
|
||||
|
||||
void y2404_device::sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples)
|
||||
{
|
||||
// should never get here
|
||||
fatalerror("sound_stream_update called; not applicable to legacy sound devices\n");
|
||||
}
|
||||
|
||||
|
||||
const device_type SN76489 = &device_creator<sn76489_device>;
|
||||
|
||||
sn76489_device::sn76489_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
|
||||
: sn76496_device(mconfig, SN76489, "SN76489", tag, owner, clock)
|
||||
{
|
||||
}
|
||||
|
||||
//-------------------------------------------------
|
||||
// device_start - device-specific startup
|
||||
//-------------------------------------------------
|
||||
|
||||
void sn76489_device::device_start()
|
||||
{
|
||||
DEVICE_START_NAME( sn76489 )(this);
|
||||
}
|
||||
|
||||
//-------------------------------------------------
|
||||
// sound_stream_update - handle a stream update
|
||||
//-------------------------------------------------
|
||||
|
||||
void sn76489_device::sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples)
|
||||
{
|
||||
// should never get here
|
||||
fatalerror("sound_stream_update called; not applicable to legacy sound devices\n");
|
||||
}
|
||||
|
||||
|
||||
const device_type SN76489A = &device_creator<sn76489a_device>;
|
||||
|
||||
sn76489a_device::sn76489a_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
|
||||
: sn76496_device(mconfig, SN76489A, "SN76489A", tag, owner, clock)
|
||||
{
|
||||
}
|
||||
|
||||
//-------------------------------------------------
|
||||
// device_start - device-specific startup
|
||||
//-------------------------------------------------
|
||||
|
||||
void sn76489a_device::device_start()
|
||||
{
|
||||
DEVICE_START_NAME( sn76489a )(this);
|
||||
}
|
||||
|
||||
//-------------------------------------------------
|
||||
// sound_stream_update - handle a stream update
|
||||
//-------------------------------------------------
|
||||
|
||||
void sn76489a_device::sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples)
|
||||
{
|
||||
// should never get here
|
||||
fatalerror("sound_stream_update called; not applicable to legacy sound devices\n");
|
||||
}
|
||||
|
||||
|
||||
const device_type SN76494 = &device_creator<sn76494_device>;
|
||||
|
||||
sn76494_device::sn76494_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
|
||||
: sn76496_device(mconfig, SN76494, "SN76494", tag, owner, clock)
|
||||
{
|
||||
}
|
||||
|
||||
//-------------------------------------------------
|
||||
// device_start - device-specific startup
|
||||
//-------------------------------------------------
|
||||
|
||||
void sn76494_device::device_start()
|
||||
{
|
||||
DEVICE_START_NAME( sn76494 )(this);
|
||||
}
|
||||
|
||||
//-------------------------------------------------
|
||||
// sound_stream_update - handle a stream update
|
||||
//-------------------------------------------------
|
||||
|
||||
void sn76494_device::sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples)
|
||||
{
|
||||
// should never get here
|
||||
fatalerror("sound_stream_update called; not applicable to legacy sound devices\n");
|
||||
}
|
||||
|
||||
|
||||
const device_type SN94624 = &device_creator<sn94624_device>;
|
||||
|
||||
sn94624_device::sn94624_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
|
||||
: sn76496_device(mconfig, SN94624, "SN94624", tag, owner, clock)
|
||||
{
|
||||
}
|
||||
|
||||
//-------------------------------------------------
|
||||
// device_start - device-specific startup
|
||||
//-------------------------------------------------
|
||||
|
||||
void sn94624_device::device_start()
|
||||
{
|
||||
DEVICE_START_NAME( sn94624 )(this);
|
||||
}
|
||||
|
||||
//-------------------------------------------------
|
||||
// sound_stream_update - handle a stream update
|
||||
//-------------------------------------------------
|
||||
|
||||
void sn94624_device::sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples)
|
||||
{
|
||||
// should never get here
|
||||
fatalerror("sound_stream_update called; not applicable to legacy sound devices\n");
|
||||
}
|
||||
|
||||
|
||||
const device_type NCR7496 = &device_creator<ncr7496_device>;
|
||||
|
||||
ncr7496_device::ncr7496_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
|
||||
: sn76496_device(mconfig, NCR7496, "NCR7496", tag, owner, clock)
|
||||
{
|
||||
}
|
||||
|
||||
//-------------------------------------------------
|
||||
// device_start - device-specific startup
|
||||
//-------------------------------------------------
|
||||
|
||||
void ncr7496_device::device_start()
|
||||
{
|
||||
DEVICE_START_NAME( ncr7496 )(this);
|
||||
}
|
||||
|
||||
//-------------------------------------------------
|
||||
// sound_stream_update - handle a stream update
|
||||
//-------------------------------------------------
|
||||
|
||||
void ncr7496_device::sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples)
|
||||
{
|
||||
// should never get here
|
||||
fatalerror("sound_stream_update called; not applicable to legacy sound devices\n");
|
||||
}
|
||||
|
||||
|
||||
const device_type GAMEGEAR = &device_creator<gamegear_device>;
|
||||
|
||||
gamegear_device::gamegear_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
|
||||
: sn76496_device(mconfig, GAMEGEAR, "Game Gear PSG", tag, owner, clock)
|
||||
{
|
||||
}
|
||||
|
||||
//-------------------------------------------------
|
||||
// device_start - device-specific startup
|
||||
//-------------------------------------------------
|
||||
|
||||
void gamegear_device::device_start()
|
||||
{
|
||||
DEVICE_START_NAME( gamegear )(this);
|
||||
}
|
||||
|
||||
//-------------------------------------------------
|
||||
// sound_stream_update - handle a stream update
|
||||
//-------------------------------------------------
|
||||
|
||||
void gamegear_device::sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples)
|
||||
{
|
||||
// should never get here
|
||||
fatalerror("sound_stream_update called; not applicable to legacy sound devices\n");
|
||||
}
|
||||
|
||||
|
||||
const device_type SEGAPSG = &device_creator<segapsg_device>;
|
||||
|
||||
segapsg_device::segapsg_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
|
||||
: sn76496_device(mconfig, SEGAPSG, "SEGA VDP PSG", tag, owner, clock)
|
||||
{
|
||||
}
|
||||
|
||||
//-------------------------------------------------
|
||||
// device_start - device-specific startup
|
||||
//-------------------------------------------------
|
||||
|
||||
void segapsg_device::device_start()
|
||||
{
|
||||
DEVICE_START_NAME( segapsg )(this);
|
||||
}
|
||||
|
||||
//-------------------------------------------------
|
||||
// sound_stream_update - handle a stream update
|
||||
//-------------------------------------------------
|
||||
|
||||
void segapsg_device::sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples)
|
||||
{
|
||||
// should never get here
|
||||
fatalerror("sound_stream_update called; not applicable to legacy sound devices\n");
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*****************************************************************
|
||||
New class implementation
|
||||
Michael Zapf, June 2012
|
||||
*****************************************************************/
|
||||
|
||||
sn76496_base_device::sn76496_base_device(const machine_config &mconfig, device_type type, const char *name,
|
||||
const char *tag, int feedbackmask, int noisetap1, int noisetap2, bool negate, bool stereo, int clockdivider, int freq0,
|
||||
device_t *owner, UINT32 clock)
|
||||
|
@ -3,167 +3,6 @@
|
||||
#ifndef __SN76496_H__
|
||||
#define __SN76496_H__
|
||||
|
||||
#include "devlegcy.h"
|
||||
|
||||
READ_LINE_DEVICE_HANDLER( sn76496_ready_r );
|
||||
DECLARE_WRITE8_DEVICE_HANDLER( sn76496_w );
|
||||
DECLARE_WRITE8_DEVICE_HANDLER( sn76496_stereo_w );
|
||||
|
||||
class sn76496_device : public device_t,
|
||||
public device_sound_interface
|
||||
{
|
||||
public:
|
||||
sn76496_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
|
||||
sn76496_device(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, UINT32 clock);
|
||||
~sn76496_device() { global_free(m_token); }
|
||||
|
||||
// access to legacy token
|
||||
void *token() const { assert(m_token != NULL); return m_token; }
|
||||
protected:
|
||||
// device-level overrides
|
||||
virtual void device_config_complete();
|
||||
virtual void device_start();
|
||||
|
||||
// sound stream update overrides
|
||||
virtual void sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples);
|
||||
private:
|
||||
// internal state
|
||||
void *m_token;
|
||||
};
|
||||
|
||||
extern const device_type SN76496;
|
||||
|
||||
class u8106_device : public sn76496_device
|
||||
{
|
||||
public:
|
||||
u8106_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
|
||||
protected:
|
||||
// device-level overrides
|
||||
virtual void device_start();
|
||||
|
||||
// sound stream update overrides
|
||||
virtual void sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples);
|
||||
};
|
||||
|
||||
extern const device_type U8106;
|
||||
|
||||
class y2404_device : public sn76496_device
|
||||
{
|
||||
public:
|
||||
y2404_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
|
||||
protected:
|
||||
// device-level overrides
|
||||
virtual void device_start();
|
||||
|
||||
// sound stream update overrides
|
||||
virtual void sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples);
|
||||
};
|
||||
|
||||
extern const device_type Y2404;
|
||||
|
||||
class sn76489_device : public sn76496_device
|
||||
{
|
||||
public:
|
||||
sn76489_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
|
||||
protected:
|
||||
// device-level overrides
|
||||
virtual void device_start();
|
||||
|
||||
// sound stream update overrides
|
||||
virtual void sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples);
|
||||
};
|
||||
|
||||
extern const device_type SN76489;
|
||||
|
||||
class sn76489a_device : public sn76496_device
|
||||
{
|
||||
public:
|
||||
sn76489a_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
|
||||
protected:
|
||||
// device-level overrides
|
||||
virtual void device_start();
|
||||
|
||||
// sound stream update overrides
|
||||
virtual void sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples);
|
||||
};
|
||||
|
||||
extern const device_type SN76489A;
|
||||
|
||||
class sn76494_device : public sn76496_device
|
||||
{
|
||||
public:
|
||||
sn76494_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
|
||||
protected:
|
||||
// device-level overrides
|
||||
virtual void device_start();
|
||||
|
||||
// sound stream update overrides
|
||||
virtual void sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples);
|
||||
};
|
||||
|
||||
extern const device_type SN76494;
|
||||
|
||||
class sn94624_device : public sn76496_device
|
||||
{
|
||||
public:
|
||||
sn94624_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
|
||||
protected:
|
||||
// device-level overrides
|
||||
virtual void device_start();
|
||||
|
||||
// sound stream update overrides
|
||||
virtual void sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples);
|
||||
};
|
||||
|
||||
extern const device_type SN94624;
|
||||
|
||||
class ncr7496_device : public sn76496_device
|
||||
{
|
||||
public:
|
||||
ncr7496_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
|
||||
protected:
|
||||
// device-level overrides
|
||||
virtual void device_start();
|
||||
|
||||
// sound stream update overrides
|
||||
virtual void sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples);
|
||||
};
|
||||
|
||||
extern const device_type NCR7496;
|
||||
|
||||
class gamegear_device : public sn76496_device
|
||||
{
|
||||
public:
|
||||
gamegear_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
|
||||
protected:
|
||||
// device-level overrides
|
||||
virtual void device_start();
|
||||
|
||||
// sound stream update overrides
|
||||
virtual void sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples);
|
||||
};
|
||||
|
||||
extern const device_type GAMEGEAR;
|
||||
|
||||
class segapsg_device : public sn76496_device
|
||||
{
|
||||
public:
|
||||
segapsg_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
|
||||
protected:
|
||||
// device-level overrides
|
||||
virtual void device_start();
|
||||
|
||||
// sound stream update overrides
|
||||
virtual void sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples);
|
||||
};
|
||||
|
||||
extern const device_type SEGAPSG;
|
||||
|
||||
|
||||
/*****************************************************************
|
||||
New class implementation
|
||||
Michael Zapf, June 2012
|
||||
*****************************************************************/
|
||||
|
||||
extern const device_type SN76496_NEW;
|
||||
extern const device_type U8106_NEW;
|
||||
|
Loading…
Reference in New Issue
Block a user