diff options
author | Andrew Gardner <andrew-gardner@users.noreply.github.com> | 2012-12-28 17:40:55 +0000 |
---|---|---|
committer | Andrew Gardner <andrew-gardner@users.noreply.github.com> | 2012-12-28 17:40:55 +0000 |
commit | bb354e69103585ced86623a8a849f698a630af07 (patch) | |
tree | 95c3b032cbc95e97f662d3bf92dec18dbfdd6152 /src/emu/sound | |
parent | aa2a143e96bd953613b2a88ab209ddc9af2066bf (diff) |
Modernize the SegaPCM sound device. [Andrew Gardner]
Out of whatsnew:
Modernizing the QSound device has proven tricky, so I did this one just to make
sure my approach isn't wrong. SegaPCM modernized fine, so I'm guessing the
modernized QSound device has some state that isn't getting cleared or something.
Diffstat (limited to 'src/emu/sound')
-rw-r--r-- | src/emu/sound/segapcm.c | 171 | ||||
-rw-r--r-- | src/emu/sound/segapcm.h | 42 |
2 files changed, 100 insertions, 113 deletions
diff --git a/src/emu/sound/segapcm.c b/src/emu/sound/segapcm.c index ee9a1595307..163d43d9a3e 100644 --- a/src/emu/sound/segapcm.c +++ b/src/emu/sound/segapcm.c @@ -5,30 +5,69 @@ #include "emu.h" #include "segapcm.h" -struct segapcm_state -{ - UINT8 *ram; - UINT8 low[16]; - const UINT8 *rom; - int bankshift; - int bankmask; - int rgnmask; - sound_stream * stream; -}; - -INLINE segapcm_state *get_safe_token(device_t *device) + +// device type definition +const device_type SEGAPCM = &device_creator<segapcm_device>; + + +//------------------------------------------------- +// segapcm_device - constructor +//------------------------------------------------- + +segapcm_device::segapcm_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) + : device_t(mconfig, SEGAPCM, "Sega PCM", "segapcm", tag, owner, clock), + device_sound_interface(mconfig, *this), + m_ram(NULL), + m_rom(NULL), + m_bankshift(0), + m_bankmask(0), + m_rgnmask(0), + m_stream(NULL) { - assert(device != NULL); - assert(device->type() == SEGAPCM); - return (segapcm_state *)downcast<segapcm_device *>(device)->token(); } -static STREAM_UPDATE( SEGAPCM_update ) + +//------------------------------------------------- +// device_start - device-specific startup +//------------------------------------------------- + +void segapcm_device::device_start() { - segapcm_state *spcm = (segapcm_state *)param; - int rgnmask = spcm->rgnmask; - int ch; + int mask, rom_mask, len; + const sega_pcm_interface *intf = (const sega_pcm_interface *)static_config(); + + m_rom = *region(); + m_ram = auto_alloc_array(machine(), UINT8, 0x800); + + memset(m_ram, 0xff, 0x800); + + m_bankshift = (UINT8)(intf->bank); + mask = intf->bank >> 16; + if(!mask) + mask = BANK_MASK7>>16; + + len = region()->bytes(); + m_rgnmask = len - 1; + + for(rom_mask = 1; rom_mask < len; rom_mask *= 2); + + rom_mask--; + + m_bankmask = mask & (rom_mask >> m_bankshift); + + m_stream = stream_alloc(0, 2, clock() / 128); + + save_item(NAME(m_low)); + save_pointer(NAME(m_ram), 0x800); +} + +//------------------------------------------------- +// sound_stream_update - handle a stream update +//------------------------------------------------- + +void segapcm_device::sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples) +{ /* clear the buffers */ memset(outputs[0], 0, samples*sizeof(*outputs[0])); memset(outputs[1], 0, samples*sizeof(*outputs[1])); @@ -55,15 +94,15 @@ static STREAM_UPDATE( SEGAPCM_update ) // 0x87 ? /* loop over channels */ - for (ch = 0; ch < 16; ch++) + for (int ch = 0; ch < 16; ch++) { - UINT8 *regs = spcm->ram+8*ch; + UINT8 *regs = m_ram+8*ch; /* only process active channels */ if (!(regs[0x86]&1)) { - const UINT8 *rom = spcm->rom + ((regs[0x86] & spcm->bankmask) << spcm->bankshift); - UINT32 addr = (regs[0x85] << 16) | (regs[0x84] << 8) | spcm->low[ch]; + const UINT8 *rom = m_rom + ((regs[0x86] & m_bankmask) << m_bankshift); + UINT32 addr = (regs[0x85] << 16) | (regs[0x84] << 8) | m_low[ch]; UINT32 loop = (regs[0x05] << 16) | (regs[0x04] << 8); UINT8 end = regs[6] + 1; int i; @@ -85,7 +124,7 @@ static STREAM_UPDATE( SEGAPCM_update ) } /* fetch the sample */ - v = rom[(addr >> 8) & rgnmask] - 0x80; + v = rom[(addr >> 8) & m_rgnmask] - 0x80; /* apply panning and advance */ outputs[0][i] += v * regs[2]; @@ -96,93 +135,23 @@ static STREAM_UPDATE( SEGAPCM_update ) /* store back the updated address */ regs[0x84] = addr >> 8; regs[0x85] = addr >> 16; - spcm->low[ch] = regs[0x86] & 1 ? 0 : addr; + m_low[ch] = regs[0x86] & 1 ? 0 : addr; } } } -static DEVICE_START( segapcm ) -{ - const sega_pcm_interface *intf = (const sega_pcm_interface *)device->static_config(); - int mask, rom_mask, len; - segapcm_state *spcm = get_safe_token(device); - - spcm->rom = *device->region(); - spcm->ram = auto_alloc_array(device->machine(), UINT8, 0x800); - - memset(spcm->ram, 0xff, 0x800); - spcm->bankshift = (UINT8)(intf->bank); - mask = intf->bank >> 16; - if(!mask) - mask = BANK_MASK7>>16; - - len = device->region()->bytes(); - spcm->rgnmask = len - 1; - - for(rom_mask = 1; rom_mask < len; rom_mask *= 2); - - rom_mask--; - - spcm->bankmask = mask & (rom_mask >> spcm->bankshift); - - spcm->stream = device->machine().sound().stream_alloc(*device, 0, 2, device->clock() / 128, spcm, SEGAPCM_update); - - device->save_item(NAME(spcm->low)); - device->save_pointer(NAME(spcm->ram), 0x800); -} - - -WRITE8_DEVICE_HANDLER( sega_pcm_w ) -{ - segapcm_state *spcm = get_safe_token(device); - spcm->stream->update(); - spcm->ram[offset & 0x07ff] = data; -} - -READ8_DEVICE_HANDLER( sega_pcm_r ) +WRITE8_MEMBER( segapcm_device::sega_pcm_w ) { - segapcm_state *spcm = get_safe_token(device); - spcm->stream->update(); - return spcm->ram[offset & 0x07ff]; + m_stream->update(); + m_ram[offset & 0x07ff] = data; } -const device_type SEGAPCM = &device_creator<segapcm_device>; -segapcm_device::segapcm_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) - : device_t(mconfig, SEGAPCM, "Sega PCM", tag, owner, clock), - device_sound_interface(mconfig, *this) -{ - m_token = global_alloc_clear(segapcm_state); -} - -//------------------------------------------------- -// device_config_complete - perform any -// operations now that the configuration is -// complete -//------------------------------------------------- - -void segapcm_device::device_config_complete() -{ -} - -//------------------------------------------------- -// device_start - device-specific startup -//------------------------------------------------- - -void segapcm_device::device_start() -{ - DEVICE_START_NAME( segapcm )(this); -} - -//------------------------------------------------- -// sound_stream_update - handle a stream update -//------------------------------------------------- - -void segapcm_device::sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples) +READ8_MEMBER( segapcm_device::sega_pcm_r ) { - // should never get here - fatalerror("sound_stream_update called; not applicable to legacy sound devices\n"); + m_stream->update(); + return m_ram[offset & 0x07ff]; } diff --git a/src/emu/sound/segapcm.h b/src/emu/sound/segapcm.h index 6a051e4064e..fdb991e2108 100644 --- a/src/emu/sound/segapcm.h +++ b/src/emu/sound/segapcm.h @@ -7,8 +7,6 @@ #ifndef __SEGAPCM_H__ #define __SEGAPCM_H__ -#include "devlegcy.h" - #define BANK_256 (11) #define BANK_512 (12) #define BANK_12M (13) @@ -16,33 +14,53 @@ #define BANK_MASKF (0xf0<<16) #define BANK_MASKF8 (0xf8<<16) + +//************************************************************************** +// INTERFACE CONFIGURATION MACROS +//************************************************************************** + +#define MCFG_SEGAPCM_ADD(_tag, _clock) \ + MCFG_DEVICE_ADD(_tag, SEGAPCM, _clock) \ + +#define MCFG_SEGAPCM_REPLACE(_tag, _clock) \ + MCFG_DEVICE_REPLACE(_tag, SEGAPCM, _clock) \ + + +//************************************************************************** +// TYPE DEFINITIONS +//************************************************************************** + struct sega_pcm_interface { int bank; }; -DECLARE_WRITE8_DEVICE_HANDLER( sega_pcm_w ); -DECLARE_READ8_DEVICE_HANDLER( sega_pcm_r ); - class segapcm_device : public device_t, - public device_sound_interface + public device_sound_interface { public: segapcm_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock); - ~segapcm_device() { global_free(m_token); } + ~segapcm_device() { } - // 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); + +public: + DECLARE_WRITE8_MEMBER( sega_pcm_w ); + DECLARE_READ8_MEMBER( sega_pcm_r ); + private: - // internal state - void *m_token; + UINT8* m_ram; + UINT8 m_low[16]; + const UINT8* m_rom; + int m_bankshift; + int m_bankmask; + int m_rgnmask; + sound_stream* m_stream; }; extern const device_type SEGAPCM; |