diff options
author | 2016-10-08 15:18:28 -0400 | |
---|---|---|
committer | 2016-10-08 15:18:28 -0400 | |
commit | cd296194848e814f47d69f46fd9cd0bc1406599d (patch) | |
tree | b504f1bffa7b9c508c64ec2562fe74070de68af8 | |
parent | 8cf46d65c57ef2ff5f8fd3a95541761694b35be8 (diff) |
mac: rewrite audio output for original Macs to work like hardware. [R. Belmont]
-rw-r--r-- | scripts/target/mame/mess.lua | 1 | ||||
-rw-r--r-- | src/mame/audio/mac.cpp | 174 | ||||
-rw-r--r-- | src/mame/drivers/mac.cpp | 46 | ||||
-rw-r--r-- | src/mame/includes/mac.h | 52 | ||||
-rw-r--r-- | src/mame/machine/mac.cpp | 26 |
5 files changed, 59 insertions, 240 deletions
diff --git a/scripts/target/mame/mess.lua b/scripts/target/mame/mess.lua index 7658f14e15d..2493be46924 100644 --- a/scripts/target/mame/mess.lua +++ b/scripts/target/mame/mess.lua @@ -1388,7 +1388,6 @@ files { MAME_DIR .. "src/mame/machine/lisa.cpp", MAME_DIR .. "src/mame/drivers/mac.cpp", MAME_DIR .. "src/mame/includes/mac.h", - MAME_DIR .. "src/mame/audio/mac.cpp", MAME_DIR .. "src/mame/machine/egret.cpp", MAME_DIR .. "src/mame/machine/egret.h", MAME_DIR .. "src/mame/machine/mac.cpp", diff --git a/src/mame/audio/mac.cpp b/src/mame/audio/mac.cpp deleted file mode 100644 index 821c15a9afb..00000000000 --- a/src/mame/audio/mac.cpp +++ /dev/null @@ -1,174 +0,0 @@ -// license:BSD-3-Clause -// copyright-holders:Nathan Woods, Raphael Nabet, R. Belmont -/*************************************************************************** - - mac.c - - Sound handler - -****************************************************************************/ - - -#include "emu.h" -#include "sound/asc.h" -#include "includes/mac.h" -#include "machine/ram.h" - -/*************************************************************************** - MACROS / CONSTANTS -***************************************************************************/ - -#define MAC_MAIN_SND_BUF_OFFSET 0x0300 -#define MAC_ALT_SND_BUF_OFFSET 0x5F00 -#define MAC_SND_BUF_SIZE 370 /* total number of scan lines */ -#define MAC_SAMPLE_RATE ( MAC_SND_BUF_SIZE * 60 /*22255*/ ) /* scan line rate, should be 22254.5 Hz */ - - -/* intermediate buffer */ -#define SND_CACHE_SIZE 128 - - - - -const device_type MAC_SOUND = &device_creator<mac_sound_device>; - -mac_sound_device::mac_sound_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) - : device_t(mconfig, MAC_SOUND, "Mac Audio Custom", tag, owner, clock, "mac_sound", __FILE__), - device_sound_interface(mconfig, *this), - m_sample_enable(0), - m_mac_snd_buf_ptr(nullptr), - m_snd_cache_len(0), - m_snd_cache_head(0), - m_snd_cache_tail(0), - m_indexx(0) -{ -} - -//------------------------------------------------- -// device_config_complete - perform any -// operations now that the configuration is -// complete -//------------------------------------------------- - -void mac_sound_device::device_config_complete() -{ -} - -//------------------------------------------------- -// device_start - device-specific startup -//------------------------------------------------- - -void mac_sound_device::device_start() -{ - mac_state *mac = machine().driver_data<mac_state>(); - - m_snd_cache = make_unique_clear<UINT8[]>(SND_CACHE_SIZE); - m_mac_stream = machine().sound().stream_alloc(*this, 0, 1, MAC_SAMPLE_RATE); - - m_ram = machine().device<ram_device>(RAM_TAG); - m_mac_model = mac->m_model; - - save_pointer(NAME(m_snd_cache.get()), 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)); -} - -//------------------------------------------------- -// sound_stream_update - handle a stream update -//------------------------------------------------- - -void mac_sound_device::sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples) -{ - 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/mame/drivers/mac.cpp b/src/mame/drivers/mac.cpp index 2c10a769eef..321d8208dea 100644 --- a/src/mame/drivers/mac.cpp +++ b/src/mame/drivers/mac.cpp @@ -567,6 +567,41 @@ WRITE8_MEMBER(mac_state::mac_5396_w) } } +#define MAC_MAIN_SND_BUF_OFFSET 0x0300 +#define MAC_ALT_SND_BUF_OFFSET 0x5F00 + +TIMER_DEVICE_CALLBACK_MEMBER(mac_state::mac_scanline) +{ + int scanline = param; + UINT16 *mac_snd_buf_ptr; + UINT16 last_val; + + if (m_snd_enable) + { + if (m_main_buffer) + { + mac_snd_buf_ptr = (UINT16 *)(m_ram->pointer() + m_ram->size() - MAC_MAIN_SND_BUF_OFFSET); + } + else + { + mac_snd_buf_ptr = (UINT16 *)(m_ram->pointer() + m_ram->size() - MAC_ALT_SND_BUF_OFFSET); + } + + last_val = (UINT8)((mac_snd_buf_ptr[scanline] >> 8) & 0xff); + } + else + { + last_val = 0x80; + } + + // apply 0-7 volume + last_val *= m_snd_vol; + last_val <<= 5; + + m_dac->write_unsigned16(last_val); +} + + /*************************************************************************** ADDRESS MAPS ***************************************************************************/ @@ -898,11 +933,7 @@ static MACHINE_CONFIG_START( mac512ke, mac_state ) /* video hardware */ MCFG_SCREEN_ADD(MAC_SCREEN_NAME, RASTER) - MCFG_SCREEN_REFRESH_RATE(60.15) - MCFG_SCREEN_VBLANK_TIME(ATTOSECONDS_IN_USEC(1260)) - MCFG_SCREEN_VIDEO_ATTRIBUTES(VIDEO_UPDATE_BEFORE_VBLANK) - MCFG_SCREEN_SIZE(MAC_H_TOTAL, MAC_V_TOTAL) - MCFG_SCREEN_VISIBLE_AREA(0, MAC_H_VIS-1, 0, MAC_V_VIS-1) + MCFG_SCREEN_RAW_PARAMS(C7M*2, MAC_H_TOTAL, 0, MAC_H_VIS, MAC_V_TOTAL, 0, MAC_V_VIS) MCFG_SCREEN_UPDATE_DRIVER(mac_state, screen_update_mac) MCFG_SCREEN_PALETTE("palette") @@ -911,9 +942,12 @@ static MACHINE_CONFIG_START( mac512ke, mac_state ) MCFG_VIDEO_START_OVERRIDE(mac_state,mac) + MCFG_TIMER_DRIVER_ADD_SCANLINE("scantimer", mac_state, mac_scanline, "screen", 0, 1) + /* sound hardware */ MCFG_SPEAKER_STANDARD_MONO("mono") - MCFG_SOUND_ADD("custom", MAC_SOUND, 0) + //MCFG_SOUND_ADD("custom", MAC_SOUND, 0) + MCFG_SOUND_ADD(DAC_TAG, DAC, 0) MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 1.00) /* devices */ diff --git a/src/mame/includes/mac.h b/src/mame/includes/mac.h index e30e2639a3c..7426235eee1 100644 --- a/src/mame/includes/mac.h +++ b/src/mame/includes/mac.h @@ -24,12 +24,14 @@ #include "machine/macrtc.h" #include "sound/asc.h" #include "sound/awacs.h" +#include "sound/dac.h" #include "cpu/m68000/m68000.h" #define MAC_SCREEN_NAME "screen" #define MAC_539X_1_TAG "539x_1" #define MAC_539X_2_TAG "539x_2" #define MACKBD_TAG "mackbd" +#define DAC_TAG "macdac" // uncomment to run i8021 keyboard in original Mac/512(e)/Plus //#define MAC_USE_EMULATED_KBD (1) @@ -145,46 +147,6 @@ enum model_t 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: - mac_sound_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock); - ~mac_sound_device() {} - - void enable_sound(int on); - void set_sound_buffer(int buffer); - void set_volume(int volume); - void sh_updatebuffer(); - -protected: - // device-level overrides - virtual void device_config_complete() override; - virtual void device_start() override; - - // sound stream update overrides - virtual void sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples) override; -private: - // internal state - - ram_device *m_ram; - model_t m_mac_model; - - sound_stream *m_mac_stream; - int m_sample_enable; - UINT16 *m_mac_snd_buf_ptr; - std::unique_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; - - /* Mac driver data */ class mac_state : public driver_device @@ -214,7 +176,8 @@ public: m_vram16(*this,"vram16"), m_via2_ca1_hack(0), m_screen(*this, "screen"), - m_palette(*this, "palette") + m_palette(*this, "palette"), + m_dac(*this, DAC_TAG) { } @@ -252,6 +215,11 @@ public: emu_timer *m_overlay_timeout; TIMER_CALLBACK_MEMBER(overlay_timeout_func); DECLARE_READ32_MEMBER(rom_switch_r); + + TIMER_DEVICE_CALLBACK_MEMBER(mac_scanline); + bool m_snd_enable; + bool m_main_buffer; + int m_snd_vol; #ifndef MAC_USE_EMULATED_KBD /* used to store the reply to most keyboard commands */ @@ -449,6 +417,8 @@ private: int m_via2_ca1_hack; optional_device<screen_device> m_screen; optional_device<palette_device> m_palette; + optional_device<dac_device> m_dac; + public: emu_timer *m_scanline_timer; emu_timer *m_adb_timer; diff --git a/src/mame/machine/mac.cpp b/src/mame/machine/mac.cpp index 6c50b1df13b..ea4bf0d2eb4 100644 --- a/src/mame/machine/mac.cpp +++ b/src/mame/machine/mac.cpp @@ -1421,7 +1421,6 @@ READ8_MEMBER(mac_state::mac_via_in_b_pmu) WRITE8_MEMBER(mac_state::mac_via_out_a) { - mac_sound_device *sound = machine().device<mac_sound_device>("custom"); device_t *fdc = machine().device("fdc"); // printf("VIA1 OUT A: %02x (PC %x)\n", data, m_maincpu->safe_pc()); @@ -1435,12 +1434,12 @@ WRITE8_MEMBER(mac_state::mac_via_out_a) if (m_model < MODEL_MAC_SE) // SE no longer has dual buffers { - sound->set_sound_buffer((data & 0x08) >> 3); + m_main_buffer = ((data & 0x08) == 0x08) ? true : false; } if (m_model < MODEL_MAC_II) { - sound->set_volume(data & 0x07); + m_snd_vol = data & 0x07; } /* Early Mac models had VIA A4 control overlaying. In the Mac SE (and @@ -1465,12 +1464,11 @@ WRITE8_MEMBER(mac_state::mac_via_out_a_pmu) WRITE8_MEMBER(mac_state::mac_via_out_b) { - mac_sound_device *sound = machine().device<mac_sound_device>("custom"); // printf("VIA1 OUT B: %02x (PC %x)\n", data, m_maincpu->safe_pc()); if (AUDIO_IS_CLASSIC) { - sound->enable_sound((data & 0x80) == 0); + m_snd_enable = ((data & 0x80) == 0) ? true : false; } m_rtc->ce_w((data & 0x04)>>2); @@ -1955,12 +1953,7 @@ void mac_state::machine_reset() /* setup videoram */ this->m_screen_buffer = 1; - /* setup 'classic' sound */ - if (machine().device("custom") != nullptr) - { - machine().device<mac_sound_device>("custom")->set_sound_buffer(0); - } - else if (MAC_HAS_VIA2) // prime CB1 for ASC and slot interrupts + if (MAC_HAS_VIA2) // prime CB1 for ASC and slot interrupts { m_via2_ca1_hack = 1; m_via2->write_ca1(1); @@ -1974,8 +1967,6 @@ void mac_state::machine_reset() if ((m_model == MODEL_MAC_SE) || (m_model == MODEL_MAC_CLASSIC)) { - machine().device<mac_sound_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()); } @@ -1998,6 +1989,10 @@ void mac_state::machine_reset() m_pm_data_send = m_pm_data_recv = m_pm_ack = m_pm_req = m_pm_dptr = 0; m_pm_state = 0; m_last_taken_interrupt = 0; + + m_snd_enable = false; + m_main_buffer = true; + m_snd_vol = 3; } WRITE_LINE_MEMBER(mac_state::cuda_reset_w) @@ -2290,11 +2285,6 @@ TIMER_CALLBACK_MEMBER(mac_state::mac_scanline_tick) { int scanline; - if (machine().device("custom") != nullptr) - { - machine().device<mac_sound_device>("custom")->sh_updatebuffer(); - } - if (m_rbv_vbltime > 0) { m_rbv_vbltime--; |