From 0e35391d2066647ebba8a4d678cbfd10def72db5 Mon Sep 17 00:00:00 2001 From: Fabio Priuli Date: Sun, 2 Jun 2013 21:40:08 +0000 Subject: [PATCH] (MESS) modernized the Mac Sound device. [Fabio Priuli] --- src/mess/audio/mac.c | 276 ++++++++++++++++------------------------ src/mess/includes/mac.h | 30 +++-- src/mess/machine/mac.c | 16 +-- 3 files changed, 138 insertions(+), 184 deletions(-) diff --git a/src/mess/audio/mac.c b/src/mess/audio/mac.c index 2c8f3d6a4bb..be71718116d 100644 --- a/src/mess/audio/mac.c +++ b/src/mess/audio/mac.c @@ -26,174 +26,20 @@ #define SND_CACHE_SIZE 128 -/*************************************************************************** - TYPE DEFINITIONS -***************************************************************************/ - -struct mac_sound -{ - sound_stream *mac_stream; - int sample_enable; - UINT16 *mac_snd_buf_ptr; - UINT8 *snd_cache; - int snd_cache_len; - int snd_cache_head; - int snd_cache_tail; - int indexx; -}; - - -/*************************************************************************** - INLINE FUNCTIONS -***************************************************************************/ - -INLINE mac_sound *get_token(device_t *device) -{ - assert(device != NULL); - assert(device->type() == MAC_SOUND); - return (mac_sound *) downcast(device)->token(); -} - - -/*************************************************************************** - IMPLEMENTATION -***************************************************************************/ - -/************************************/ -/* Stream updater */ -/************************************/ - -static STREAM_UPDATE( mac_sound_update ) -{ - INT16 last_val = 0; - stream_sample_t *buffer = outputs[0]; - mac_sound *token = get_token(device); - mac_state *mac = device->machine().driver_data(); - - if ((mac->m_model == MODEL_MAC_PORTABLE) || (mac->m_model == MODEL_MAC_PB100)) - { - memset(buffer, 0, samples * sizeof(*buffer)); - return; - } - - /* if we're not enabled, just fill with 0 */ - if (device->machine().sample_rate() == 0) - { - memset(buffer, 0, samples * sizeof(*buffer)); - return; - } - - /* fill in the sample */ - while (samples && token->snd_cache_len) - { - *buffer++ = last_val = ((token->snd_cache[token->snd_cache_head] << 8) ^ 0x8000) & 0xff00; - token->snd_cache_head++; - token->snd_cache_head %= SND_CACHE_SIZE; - token->snd_cache_len--; - samples--; - } - - while (samples--) - { - /* should never happen */ - *buffer++ = last_val; - } -} - - - -/************************************/ -/* Sound handler start */ -/************************************/ - -static DEVICE_START(mac_sound) -{ - mac_sound *token = get_token(device); - - memset(token, 0, sizeof(*token)); - - token->snd_cache = auto_alloc_array(device->machine(), UINT8, SND_CACHE_SIZE); - token->mac_stream = device->machine().sound().stream_alloc(*device, 0, 1, MAC_SAMPLE_RATE, 0, mac_sound_update); -} - - - -/* - Set the sound enable flag (VIA port line) -*/ -void mac_enable_sound(device_t *device, int on) -{ - mac_sound *token = get_token(device); - token->sample_enable = on; -} - - - -/* - Set the current sound buffer (one VIA port line) -*/ -void mac_set_sound_buffer(device_t *device, int buffer) -{ - mac_sound *token = get_token(device); - ram_device *ram = device->machine().device(RAM_TAG); - - if (buffer) - token->mac_snd_buf_ptr = (UINT16 *) (ram->pointer() + ram->size() - MAC_MAIN_SND_BUF_OFFSET); - else - token->mac_snd_buf_ptr = (UINT16 *) (ram->pointer() + ram->size() - MAC_ALT_SND_BUF_OFFSET); -} - - - -/* - Set the current sound volume (3 VIA port line) -*/ -void mac_set_volume(device_t *device, int volume) -{ - mac_sound *token = get_token(device); - - token->mac_stream->update(); - volume = (100 / 7) * volume; - token->mac_stream->set_output_gain(0, volume / 100.0); -} - - - -/* - Fetch one byte from sound buffer and put it to sound output (called every scanline) -*/ -void mac_sh_updatebuffer(device_t *device) -{ - mac_sound *token = get_token(device); - UINT16 *base = token->mac_snd_buf_ptr; - - token->indexx++; - token->indexx %= 370; - - if (token->snd_cache_len >= SND_CACHE_SIZE) - { - /* clear buffer */ - token->mac_stream->update(); - } - - if (token->snd_cache_len >= SND_CACHE_SIZE) - /* should never happen */ - return; - - token->snd_cache[token->snd_cache_tail] = token->sample_enable ? (base[token->indexx] >> 8) & 0xff : 0; - token->snd_cache_tail++; - token->snd_cache_tail %= SND_CACHE_SIZE; - token->snd_cache_len++; -} const device_type MAC_SOUND = &device_creator; mac_sound_device::mac_sound_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) - : device_t(mconfig, MAC_SOUND, "Mac Custom", tag, owner, clock), - device_sound_interface(mconfig, *this) + : device_t(mconfig, MAC_SOUND, "Mac Custom", tag, owner, clock), + device_sound_interface(mconfig, *this), + m_sample_enable(0), + m_mac_snd_buf_ptr(NULL), + m_snd_cache_len(0), + m_snd_cache_head(0), + m_snd_cache_tail(0), + m_indexx(0) { - m_token = global_alloc_clear(mac_sound); } //------------------------------------------------- @@ -212,7 +58,20 @@ void mac_sound_device::device_config_complete() void mac_sound_device::device_start() { - DEVICE_START_NAME( mac_sound )(this); + mac_state *mac = machine().driver_data(); + + m_snd_cache = auto_alloc_array_clear(machine(), UINT8, SND_CACHE_SIZE); + m_mac_stream = machine().sound().stream_alloc(*this, 0, 1, MAC_SAMPLE_RATE, this); + + m_ram = machine().device(RAM_TAG); + m_mac_model = mac->m_model; + + save_pointer(NAME(m_snd_cache), SND_CACHE_SIZE); + save_item(NAME(m_sample_enable)); + save_item(NAME(m_snd_cache_len)); + save_item(NAME(m_snd_cache_head)); + save_item(NAME(m_snd_cache_tail)); + save_item(NAME(m_indexx)); } //------------------------------------------------- @@ -221,6 +80,93 @@ void mac_sound_device::device_start() void mac_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"); + INT16 last_val = 0; + stream_sample_t *buffer = outputs[0]; + + if ((m_mac_model == MODEL_MAC_PORTABLE) || (m_mac_model == MODEL_MAC_PB100)) + { + memset(buffer, 0, samples * sizeof(*buffer)); + return; + } + + /* if we're not enabled, just fill with 0 */ + if (machine().sample_rate() == 0) + { + memset(buffer, 0, samples * sizeof(*buffer)); + return; + } + + /* fill in the sample */ + while (samples && m_snd_cache_len) + { + *buffer++ = last_val = ((m_snd_cache[m_snd_cache_head] << 8) ^ 0x8000) & 0xff00; + m_snd_cache_head++; + m_snd_cache_head %= SND_CACHE_SIZE; + m_snd_cache_len--; + samples--; + } + + while (samples--) + { + /* should never happen */ + *buffer++ = last_val; + } +} + + +/*************************************************************************** + IMPLEMENTATION +***************************************************************************/ + + +// Set the sound enable flag (VIA port line) +void mac_sound_device::enable_sound(int on) +{ + m_sample_enable = on; +} + + +// Set the current sound buffer (one VIA port line) +void mac_sound_device::set_sound_buffer(int buffer) +{ + if (buffer) + m_mac_snd_buf_ptr = (UINT16 *) (m_ram->pointer() + m_ram->size() - MAC_MAIN_SND_BUF_OFFSET); + else + m_mac_snd_buf_ptr = (UINT16 *) (m_ram->pointer() + m_ram->size() - MAC_ALT_SND_BUF_OFFSET); +} + + + +// Set the current sound volume (3 VIA port line) +void mac_sound_device::set_volume(int volume) +{ + m_mac_stream->update(); + volume = (100 / 7) * volume; + m_mac_stream->set_output_gain(0, volume / 100.0); +} + + + +// Fetch one byte from sound buffer and put it to sound output (called every scanline) +void mac_sound_device::sh_updatebuffer() +{ + UINT16 *base = m_mac_snd_buf_ptr; + + m_indexx++; + m_indexx %= 370; + + if (m_snd_cache_len >= SND_CACHE_SIZE) + { + /* clear buffer */ + m_mac_stream->update(); + } + + if (m_snd_cache_len >= SND_CACHE_SIZE) + /* should never happen */ + return; + + m_snd_cache[m_snd_cache_tail] = m_sample_enable ? (base[m_indexx] >> 8) & 0xff : 0; + m_snd_cache_tail++; + m_snd_cache_tail %= SND_CACHE_SIZE; + m_snd_cache_len++; } diff --git a/src/mess/includes/mac.h b/src/mess/includes/mac.h index aad7792af8f..3b73637c322 100644 --- a/src/mess/includes/mac.h +++ b/src/mess/includes/mac.h @@ -147,14 +147,17 @@ void mac_fdc_set_enable_lines(device_t *device, int enable_mask); /*----------- defined in audio/mac.c -----------*/ class mac_sound_device : public device_t, - public device_sound_interface + public device_sound_interface { public: mac_sound_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock); - ~mac_sound_device() { global_free(m_token); } + ~mac_sound_device() {} + + void enable_sound(int on); + void set_sound_buffer(int buffer); + void set_volume(int volume); + void sh_updatebuffer(); - // access to legacy token - void *token() const { assert(m_token != NULL); return m_token; } protected: // device-level overrides virtual void device_config_complete(); @@ -164,18 +167,23 @@ 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; + + ram_device *m_ram; + model_t m_mac_model; + + sound_stream *m_mac_stream; + int m_sample_enable; + UINT16 *m_mac_snd_buf_ptr; + UINT8 *m_snd_cache; + int m_snd_cache_len; + int m_snd_cache_head; + int m_snd_cache_tail; + int m_indexx; }; extern const device_type MAC_SOUND; -void mac_enable_sound( device_t *device, int on ); -void mac_set_sound_buffer( device_t *device, int buffer ); -void mac_set_volume( device_t *device, int volume ); - -void mac_sh_updatebuffer(device_t *device); - /* Mac driver data */ class mac_state : public driver_device diff --git a/src/mess/machine/mac.c b/src/mess/machine/mac.c index 09a0ee71199..6659f54be2a 100644 --- a/src/mess/machine/mac.c +++ b/src/mess/machine/mac.c @@ -1356,7 +1356,7 @@ READ8_MEMBER(mac_state::mac_via_in_b) WRITE8_MEMBER(mac_state::mac_via_out_a) { - device_t *sound = machine().device("custom"); + mac_sound_device *sound = machine().device("custom"); device_t *fdc = machine().device("fdc"); // printf("VIA1 OUT A: %02x (PC %x)\n", data, m_maincpu->safe_pc()); @@ -1379,12 +1379,12 @@ WRITE8_MEMBER(mac_state::mac_via_out_a) if (m_model < MODEL_MAC_SE) // SE no longer has dual buffers { - mac_set_sound_buffer(sound, (data & 0x08) >> 3); + sound->set_sound_buffer((data & 0x08) >> 3); } if (m_model < MODEL_MAC_II) { - mac_set_volume(sound, data & 0x07); + sound->set_volume(data & 0x07); } /* Early Mac models had VIA A4 control overlaying. In the Mac SE (and @@ -1398,7 +1398,7 @@ WRITE8_MEMBER(mac_state::mac_via_out_a) WRITE8_MEMBER(mac_state::mac_via_out_b) { - device_t *sound = machine().device("custom"); + mac_sound_device *sound = machine().device("custom"); // printf("VIA1 OUT B: %02x (PC %x)\n", data, m_maincpu->safe_pc()); if (ADB_IS_PM_VIA1) @@ -1467,7 +1467,7 @@ WRITE8_MEMBER(mac_state::mac_via_out_b) if (AUDIO_IS_CLASSIC) { - mac_enable_sound(sound, (data & 0x80) == 0); + sound->enable_sound((data & 0x80) == 0); } // SE and Classic have SCSI enable/disable here @@ -1859,7 +1859,7 @@ void mac_state::machine_reset() /* setup 'classic' sound */ if (machine().device("custom") != NULL) { - mac_set_sound_buffer(machine().device("custom"), 0); + machine().device("custom")->set_sound_buffer(0); } else if (MAC_HAS_VIA2) // prime CB1 for ASC and slot interrupts { @@ -1874,7 +1874,7 @@ void mac_state::machine_reset() if ((m_model == MODEL_MAC_SE) || (m_model == MODEL_MAC_CLASSIC)) { - mac_set_sound_buffer(machine().device("custom"), 1); + machine().device("custom")->set_sound_buffer(1); // classic will fail RAM test and try to boot appletalk if RAM is not all zero memset(m_ram->pointer(), 0, m_ram->size()); @@ -2205,7 +2205,7 @@ TIMER_CALLBACK_MEMBER(mac_state::mac_scanline_tick) if (machine().device("custom") != NULL) { - mac_sh_updatebuffer(machine().device("custom")); + machine().device("custom")->sh_updatebuffer(); } if (m_rbv_vbltime > 0)