From fd66b2953f22c87e278bb6da0614720763aa5a38 Mon Sep 17 00:00:00 2001 From: Ivan Vangelista Date: Mon, 5 Aug 2013 15:20:36 +0000 Subject: [PATCH] Modernized the Amiga sound device. (nw) --- src/mame/audio/amiga.c | 182 +++++++++++++------------------------- src/mame/includes/amiga.h | 34 ++++--- src/mame/machine/amiga.c | 11 ++- 3 files changed, 89 insertions(+), 138 deletions(-) diff --git a/src/mame/audio/amiga.c b/src/mame/audio/amiga.c index c17905252a0..5294fcc5903 100644 --- a/src/mame/audio/amiga.c +++ b/src/mame/audio/amiga.c @@ -11,7 +11,6 @@ #include "emu.h" #include "includes/amiga.h" #include "cpu/m68000/m68000.h" -#include "devlegcy.h" /************************************* @@ -34,50 +33,53 @@ #define CLOCK_DIVIDER 16 +const device_type AMIGA = &device_creator; -/************************************* - * - * Type definitions - * - *************************************/ - -struct audio_channel +amiga_sound_device::amiga_sound_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) + : device_t(mconfig, AMIGA, "Amiga Paula", tag, owner, clock, "amiga_paula", __FILE__), + device_sound_interface(mconfig, *this), + m_stream(NULL) { - emu_timer * irq_timer; - UINT32 curlocation; - UINT16 curlength; - UINT16 curticks; - UINT8 index; - UINT8 dmaenabled; - UINT8 manualmode; - INT8 latched; -}; - - -struct amiga_audio -{ - audio_channel channel[4]; - sound_stream * stream; -}; - - -INLINE amiga_audio *get_safe_token( device_t *device ) -{ - assert(device != NULL); - assert(device->type() == AMIGA); - - return (amiga_audio *)downcast(device)->token(); } +//------------------------------------------------- +// device_config_complete - perform any +// operations now that the configuration is +// complete +//------------------------------------------------- + +void amiga_sound_device::device_config_complete() +{ +} + +//------------------------------------------------- +// device_start - device-specific startup +//------------------------------------------------- + +void amiga_sound_device::device_start() +{ + int i; + + for (i = 0; i < 4; i++) + { + m_channel[i].index = i; + m_channel[i].irq_timer = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(amiga_sound_device::signal_irq), this)); + } + + /* create the stream */ + m_stream = machine().sound().stream_alloc(*this, 0, 4, clock() / CLOCK_DIVIDER, this); +} + + /************************************* * * DMA reload/IRQ signalling * *************************************/ -static TIMER_CALLBACK( signal_irq ) +TIMER_CALLBACK_MEMBER( amiga_sound_device::signal_irq ) { - amiga_state *state = machine.driver_data(); + amiga_state *state = machine().driver_data(); state->amiga_custom_w(*state->m_maincpu_program_space, REG_INTREQ, 0x8000 | (0x80 << param), 0xffff); } @@ -98,11 +100,9 @@ static void dma_reload(amiga_state *state, audio_channel *chan) * *************************************/ -void amiga_audio_data_w(device_t *device, int which, UINT16 data) +void amiga_sound_device::data_w(int which, UINT16 data) { - amiga_audio *audio_state = get_safe_token(device); - - audio_state->channel[which].manualmode = TRUE; + m_channel[which].manualmode = TRUE; } @@ -113,28 +113,28 @@ void amiga_audio_data_w(device_t *device, int which, UINT16 data) * *************************************/ -void amiga_audio_update(device_t *device) +void amiga_sound_device::update() { - amiga_audio *audio_state = get_safe_token(device); - - audio_state->stream->update(); + m_stream->update(); } +//------------------------------------------------- +// sound_stream_update - handle a stream update +//------------------------------------------------- -static STREAM_UPDATE( amiga_stream_update ) +void amiga_sound_device::sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples) { - amiga_state *state = device->machine().driver_data(); - amiga_audio *audio = (amiga_audio *)param; + amiga_state *state = machine().driver_data(); int channum, sampoffs = 0; /* if all DMA off, disable all channels */ if (!(CUSTOM_REG(REG_DMACON) & 0x0200)) { - audio->channel[0].dmaenabled = - audio->channel[1].dmaenabled = - audio->channel[2].dmaenabled = - audio->channel[3].dmaenabled = FALSE; + m_channel[0].dmaenabled = + m_channel[1].dmaenabled = + m_channel[2].dmaenabled = + m_channel[3].dmaenabled = FALSE; /* clear the sample data to 0 */ for (channum = 0; channum < 4; channum++) @@ -147,7 +147,7 @@ static STREAM_UPDATE( amiga_stream_update ) /* update the DMA states on each channel and reload if fresh */ for (channum = 0; channum < 4; channum++) { - audio_channel *chan = &audio->channel[channum]; + audio_channel *chan = &m_channel[channum]; if (!chan->dmaenabled && ((CUSTOM_REG(REG_DMACON) >> channum) & 1)) dma_reload(state, chan); chan->dmaenabled = (CUSTOM_REG(REG_DMACON) >> channum) & 1; @@ -160,14 +160,14 @@ static STREAM_UPDATE( amiga_stream_update ) int ticks = samples; /* determine the number of ticks we can do in this chunk */ - if (ticks > audio->channel[0].curticks) - ticks = audio->channel[0].curticks; - if (ticks > audio->channel[1].curticks) - ticks = audio->channel[1].curticks; - if (ticks > audio->channel[2].curticks) - ticks = audio->channel[2].curticks; - if (ticks > audio->channel[3].curticks) - ticks = audio->channel[3].curticks; + if (ticks > m_channel[0].curticks) + ticks = m_channel[0].curticks; + if (ticks > m_channel[1].curticks) + ticks = m_channel[1].curticks; + if (ticks > m_channel[2].curticks) + ticks = m_channel[2].curticks; + if (ticks > m_channel[3].curticks) + ticks = m_channel[3].curticks; /* loop over channels */ nextper = nextvol = -1; @@ -175,7 +175,7 @@ static STREAM_UPDATE( amiga_stream_update ) { int volume = (nextvol == -1) ? CUSTOM_REG(REG_AUD0VOL + channum * 8) : nextvol; int period = (nextper == -1) ? CUSTOM_REG(REG_AUD0PER + channum * 8) : nextper; - audio_channel *chan = &audio->channel[channum]; + audio_channel *chan = &m_channel[channum]; stream_sample_t sample; int i; @@ -242,7 +242,7 @@ static STREAM_UPDATE( amiga_stream_update ) /* if we're in manual mode, signal an interrupt once we latch the low byte */ if (!chan->dmaenabled && chan->manualmode && (chan->curlocation & 1)) { - signal_irq(device->machine(), NULL, channum); + signal_irq(NULL, channum); chan->manualmode = FALSE; } } @@ -253,65 +253,3 @@ static STREAM_UPDATE( amiga_stream_update ) samples -= ticks; } } - - - -/************************************* - * - * Sound system startup - * - *************************************/ - -static DEVICE_START( amiga_sound ) -{ - amiga_audio *audio_state = get_safe_token(device); - int i; - - for (i = 0; i < 4; i++) - { - audio_state->channel[i].index = i; - audio_state->channel[i].irq_timer = device->machine().scheduler().timer_alloc(FUNC(signal_irq)); - } - - /* create the stream */ - audio_state->stream = device->machine().sound().stream_alloc(*device, 0, 4, device->clock() / CLOCK_DIVIDER, audio_state, amiga_stream_update); -} - - -const device_type AMIGA = &device_creator; - -amiga_sound_device::amiga_sound_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) - : device_t(mconfig, AMIGA, "Amiga Paula", tag, owner, clock, "amiga_paula", __FILE__), - device_sound_interface(mconfig, *this) -{ - m_token = global_alloc_clear(amiga_audio); -} - -//------------------------------------------------- -// device_config_complete - perform any -// operations now that the configuration is -// complete -//------------------------------------------------- - -void amiga_sound_device::device_config_complete() -{ -} - -//------------------------------------------------- -// device_start - device-specific startup -//------------------------------------------------- - -void amiga_sound_device::device_start() -{ - DEVICE_START_NAME( amiga_sound )(this); -} - -//------------------------------------------------- -// sound_stream_update - handle a stream update -//------------------------------------------------- - -void amiga_sound_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"); -} diff --git a/src/mame/includes/amiga.h b/src/mame/includes/amiga.h index 32e8508eccc..819e3df0d1f 100644 --- a/src/mame/includes/amiga.h +++ b/src/mame/includes/amiga.h @@ -370,6 +370,8 @@ struct autoconfig_device offs_t base; }; +class amiga_sound_device; + class amiga_state : public driver_device { public: @@ -386,6 +388,7 @@ public: m_maincpu(*this, "maincpu"), /* accelerator cards may present an interesting challenge because the maincpu will be the one on the card instead */ m_cia_0(*this, "cia_0"), m_cia_1(*this, "cia_1"), + m_sound(*this, "amiga"), m_fdc(*this, "fdc"), m_chip_ram(*this, "chip_ram", 0), m_custom_regs(*this, "custom_regs", 0), @@ -403,6 +406,7 @@ public: required_device m_maincpu; required_device m_cia_0; required_device m_cia_1; + required_device m_sound; optional_device m_fdc; required_shared_ptr m_chip_ram; UINT16 (*m_chip_ram_r)(amiga_state *state, offs_t offset); @@ -425,7 +429,6 @@ public: autoconfig_device *m_cur_autoconfig; emu_timer * m_irq_timer; emu_timer * m_blitter_timer; - device_t *m_sound_device; /* sprite states */ UINT8 m_sprite_comparitor_enable_mask; @@ -528,15 +531,28 @@ const amiga_machine_interface *amiga_get_interface(running_machine &machine); /*----------- defined in audio/amiga.c -----------*/ +struct audio_channel +{ + emu_timer * irq_timer; + UINT32 curlocation; + UINT16 curlength; + UINT16 curticks; + UINT8 index; + UINT8 dmaenabled; + UINT8 manualmode; + INT8 latched; +}; + class amiga_sound_device : public device_t, public device_sound_interface { public: amiga_sound_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock); - ~amiga_sound_device() { global_free(m_token); } + ~amiga_sound_device() {} + + void update(); + void data_w(int which, UINT16 data); - // access to legacy token - void *token() const { assert(m_token != NULL); return m_token; } protected: // device-level overrides virtual void device_config_complete(); @@ -546,16 +562,14 @@ protected: virtual void sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples); private: // internal state - void *m_token; + audio_channel m_channel[4]; + sound_stream * m_stream; + + TIMER_CALLBACK_MEMBER( signal_irq ); }; extern const device_type AMIGA; - -void amiga_audio_update(device_t *device); -void amiga_audio_data_w(device_t *device, int which, UINT16 data); - - /*----------- defined in video/amiga.c -----------*/ extern const UINT16 amiga_expand_byte[256]; diff --git a/src/mame/machine/amiga.c b/src/mame/machine/amiga.c index 214f9b30026..bf6dfa335a7 100644 --- a/src/mame/machine/amiga.c +++ b/src/mame/machine/amiga.c @@ -253,7 +253,6 @@ void amiga_machine_config(running_machine &machine, const amiga_machine_interfac state->m_irq_timer = state->timer_alloc(amiga_state::TIMER_AMIGA_IRQ); state->m_blitter_timer = state->timer_alloc(amiga_state::TIMER_AMIGA_BLITTER); - state->m_sound_device = machine.device("amiga"); } @@ -367,7 +366,7 @@ TIMER_CALLBACK_MEMBER(amiga_state::scanline_callback) } /* force a sound update */ - amiga_audio_update(m_sound_device); + m_sound->update(); /* set timer for next line */ scanline = (scanline + 1) % m_screen->height(); @@ -1427,7 +1426,7 @@ WRITE16_MEMBER( amiga_state::amiga_custom_w ) break; case REG_DMACON: - amiga_audio_update(state->m_sound_device); + m_sound->update(); /* bits BBUSY (14) and BZERO (13) are read-only */ data &= 0x9fff; @@ -1470,7 +1469,7 @@ WRITE16_MEMBER( amiga_state::amiga_custom_w ) break; case REG_ADKCON: - amiga_audio_update(state->m_sound_device); + m_sound->update(); data = (data & 0x8000) ? (CUSTOM_REG(offset) | (data & 0x7fff)) : (CUSTOM_REG(offset) & ~(data & 0x7fff)); state->m_fdc->adkcon_set(data); break; @@ -1479,11 +1478,11 @@ WRITE16_MEMBER( amiga_state::amiga_custom_w ) case REG_AUD1LCL: case REG_AUD1LCH: case REG_AUD1LEN: case REG_AUD1PER: case REG_AUD1VOL: case REG_AUD2LCL: case REG_AUD2LCH: case REG_AUD2LEN: case REG_AUD2PER: case REG_AUD2VOL: case REG_AUD3LCL: case REG_AUD3LCH: case REG_AUD3LEN: case REG_AUD3PER: case REG_AUD3VOL: - amiga_audio_update(state->m_sound_device); + m_sound->update(); break; case REG_AUD0DAT: case REG_AUD1DAT: case REG_AUD2DAT: case REG_AUD3DAT: - amiga_audio_data_w(state->m_sound_device, (offset - REG_AUD0DAT) / 8, data); + m_sound->data_w((offset - REG_AUD0DAT) / 8, data); break; case REG_BPL1PTH: case REG_BPL2PTH: case REG_BPL3PTH: case REG_BPL4PTH: