diff options
author | 2019-10-09 02:19:32 +1100 | |
---|---|---|
committer | 2019-10-09 02:26:45 +1100 | |
commit | f43b28ed4a053e5531cfcd57e7031b8c9c6fc9d7 (patch) | |
tree | a4881b08a209a4acc7a20f0d025dacda8a5a3ddc | |
parent | a110c8923cfdc448d5c1659bfa19855dd335cc46 (diff) |
(nw) misc stuff:
* screen: validate crystal values used for set_raw
* driver: get rid of sound start/reset overrides in machine configuration
* vrender0.cpp, nexus3d.cpp: corrected pixel clock crystal value
* mw8080bw.cpp: turned several audio subsystems into devices
* bus/sat_ctrl: don't start subdevices in device_start - the machine does it for you
* mb14241.cpp: simplify handlers
* fgoal.cpp: updated for simplified handlers
* devfind, screen: repair some doxy comments that had rotted with refactoring
* doxygen: disable warnings for undocumented things - it's most of our codebase
* snowbros.cpp: restore an output level setting lost in MCFG removal
There's an outstanding validation error from the HP98543 DIO video card
not using a valid crystal value. Someone needs to find a picture of the
card and confirm or deny the existence of the 39.504MHz crystal.
The various start/reset overrides are bugs waiting to happen. It's not
immediately obvious that the ones run earlier can end up being called
multiple times if subsequent ones throw missing dependencies exceptions.
They're a relic of when everything from the old C-style drivers was
thrown into classes all jumbled together.
-rw-r--r-- | doxygen/doxygen.config | 2 | ||||
-rw-r--r-- | scripts/target/mame/arcade.lua | 1 | ||||
-rw-r--r-- | src/devices/bus/sat_ctrl/multitap.cpp | 36 | ||||
-rw-r--r-- | src/devices/bus/sat_ctrl/multitap.h | 9 | ||||
-rw-r--r-- | src/devices/bus/sat_ctrl/segatap.cpp | 35 | ||||
-rw-r--r-- | src/devices/bus/sat_ctrl/segatap.h | 8 | ||||
-rw-r--r-- | src/devices/machine/mb14241.cpp | 12 | ||||
-rw-r--r-- | src/devices/machine/mb14241.h | 13 | ||||
-rw-r--r-- | src/devices/machine/vrender0.cpp | 2 | ||||
-rw-r--r-- | src/emu/devfind.h | 16 | ||||
-rw-r--r-- | src/emu/driver.cpp | 10 | ||||
-rw-r--r-- | src/emu/driver.h | 18 | ||||
-rw-r--r-- | src/emu/screen.h | 185 | ||||
-rw-r--r-- | src/mame/audio/mw8080bw.cpp | 2334 | ||||
-rw-r--r-- | src/mame/audio/mw8080bw.h | 169 | ||||
-rw-r--r-- | src/mame/drivers/fgoal.cpp | 8 | ||||
-rw-r--r-- | src/mame/drivers/mw8080bw.cpp | 194 | ||||
-rw-r--r-- | src/mame/drivers/nexus3d.cpp | 2 | ||||
-rw-r--r-- | src/mame/drivers/snowbros.cpp | 1 | ||||
-rw-r--r-- | src/mame/includes/mw8080bw.h | 108 | ||||
-rw-r--r-- | src/mame/video/mw8080bw.cpp | 90 |
21 files changed, 1678 insertions, 1575 deletions
diff --git a/doxygen/doxygen.config b/doxygen/doxygen.config index 0b2c5e3be73..787b8738463 100644 --- a/doxygen/doxygen.config +++ b/doxygen/doxygen.config @@ -689,7 +689,7 @@ WARNINGS = YES # will automatically be disabled. # The default value is: YES. -WARN_IF_UNDOCUMENTED = YES +WARN_IF_UNDOCUMENTED = NO # If the WARN_IF_DOC_ERROR tag is set to YES, doxygen will generate warnings for # potential errors in the documentation, such as not documenting some parameters diff --git a/scripts/target/mame/arcade.lua b/scripts/target/mame/arcade.lua index f9e53e3ff99..5a0a5f01793 100644 --- a/scripts/target/mame/arcade.lua +++ b/scripts/target/mame/arcade.lua @@ -2688,6 +2688,7 @@ files { MAME_DIR .. "src/mame/includes/mw8080bw.h", MAME_DIR .. "src/mame/machine/mw8080bw.cpp", MAME_DIR .. "src/mame/audio/mw8080bw.cpp", + MAME_DIR .. "src/mame/audio/mw8080bw.h", MAME_DIR .. "src/mame/video/mw8080bw.cpp", MAME_DIR .. "src/mame/drivers/rotaryf.cpp", } diff --git a/src/devices/bus/sat_ctrl/multitap.cpp b/src/devices/bus/sat_ctrl/multitap.cpp index 76fd4c3094a..71eacdf0053 100644 --- a/src/devices/bus/sat_ctrl/multitap.cpp +++ b/src/devices/bus/sat_ctrl/multitap.cpp @@ -22,10 +22,6 @@ DEFINE_DEVICE_TYPE(SATURN_MULTITAP, saturn_multitap_device, "saturn_multitap", " // LIVE DEVICE //************************************************************************** -//------------------------------------------------- -// saturn_multitap_device - constructor -//------------------------------------------------- - saturn_multitap_device::saturn_multitap_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) : device_t(mconfig, SATURN_MULTITAP, tag, owner, clock) , device_saturn_control_port_interface(mconfig, *this) @@ -34,49 +30,23 @@ saturn_multitap_device::saturn_multitap_device(const machine_config &mconfig, co } -//------------------------------------------------- -// device_start - device-specific startup -//------------------------------------------------- - void saturn_multitap_device::device_start() { - for (int i = 0; i < 6; i++) - m_subctrl_port[i]->device_start(); } -//------------------------------------------------- -// device_reset - device-specific reset -//------------------------------------------------- - -void saturn_multitap_device::device_reset() +void saturn_multitap_device::device_add_mconfig(machine_config &config) { + for (auto &port : m_subctrl_port) + SATURN_CONTROL_PORT(config, port, saturn_joys, "joypad"); } -//------------------------------------------------- -// read_ctrl -//------------------------------------------------- uint8_t saturn_multitap_device::read_ctrl(uint8_t offset) { return m_subctrl_port[offset < 12 ? (offset >> 1) : 0]->read_ctrl(offset & 1); } -//------------------------------------------------- -// read_id -//------------------------------------------------- - uint8_t saturn_multitap_device::read_id(int idx) { return m_subctrl_port[idx < 6 ? idx : 0]->read_id(0); } - - -void saturn_multitap_device::device_add_mconfig(machine_config &config) -{ - SATURN_CONTROL_PORT(config, m_subctrl_port[0], saturn_joys, "joypad"); - SATURN_CONTROL_PORT(config, m_subctrl_port[1], saturn_joys, "joypad"); - SATURN_CONTROL_PORT(config, m_subctrl_port[2], saturn_joys, "joypad"); - SATURN_CONTROL_PORT(config, m_subctrl_port[3], saturn_joys, "joypad"); - SATURN_CONTROL_PORT(config, m_subctrl_port[4], saturn_joys, "joypad"); - SATURN_CONTROL_PORT(config, m_subctrl_port[5], saturn_joys, "joypad"); -} diff --git a/src/devices/bus/sat_ctrl/multitap.h b/src/devices/bus/sat_ctrl/multitap.h index c90b559d96c..5aa98dacf3b 100644 --- a/src/devices/bus/sat_ctrl/multitap.h +++ b/src/devices/bus/sat_ctrl/multitap.h @@ -15,15 +15,11 @@ #include "ctrl.h" - //************************************************************************** // TYPE DEFINITIONS //************************************************************************** -// ======================> saturn_multitap_device - -class saturn_multitap_device : public device_t, - public device_saturn_control_port_interface +class saturn_multitap_device : public device_t, public device_saturn_control_port_interface { public: // construction/destruction @@ -32,9 +28,6 @@ public: protected: // device-level overrides virtual void device_start() override; - virtual void device_reset() override; - - // optional information overrides virtual void device_add_mconfig(machine_config &config) override; // device_saturn_control_port_interface overrides diff --git a/src/devices/bus/sat_ctrl/segatap.cpp b/src/devices/bus/sat_ctrl/segatap.cpp index e36400125fe..baaa52071ed 100644 --- a/src/devices/bus/sat_ctrl/segatap.cpp +++ b/src/devices/bus/sat_ctrl/segatap.cpp @@ -10,7 +10,6 @@ #include "segatap.h" - //************************************************************************** // DEVICE DEFINITIONS //************************************************************************** @@ -22,10 +21,6 @@ DEFINE_DEVICE_TYPE(SATURN_SEGATAP, saturn_segatap_device, "saturn_segatap", "sat // LIVE DEVICE //************************************************************************** -//------------------------------------------------- -// saturn_segatap_device - constructor -//------------------------------------------------- - saturn_segatap_device::saturn_segatap_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) : device_t(mconfig, SATURN_SEGATAP, tag, owner, clock) , device_saturn_control_port_interface(mconfig, *this) @@ -34,47 +29,23 @@ saturn_segatap_device::saturn_segatap_device(const machine_config &mconfig, cons } -//------------------------------------------------- -// device_start - device-specific startup -//------------------------------------------------- - void saturn_segatap_device::device_start() { - for (int i = 0; i < 4; i++) - m_subctrl_port[i]->device_start(); } -//------------------------------------------------- -// device_reset - device-specific reset -//------------------------------------------------- - -void saturn_segatap_device::device_reset() +void saturn_segatap_device::device_add_mconfig(machine_config &config) { + for (auto &port : m_subctrl_port) + SATURN_CONTROL_PORT(config, port, saturn_joys, "joypad"); } -//------------------------------------------------- -// read_ctrl -//------------------------------------------------- uint8_t saturn_segatap_device::read_ctrl(uint8_t offset) { return m_subctrl_port[offset < 8 ? (offset >> 1) : 0]->read_ctrl(offset & 1); } -//------------------------------------------------- -// read_id -//------------------------------------------------- - uint8_t saturn_segatap_device::read_id(int idx) { return m_subctrl_port[idx < 4 ? idx : 0]->read_id(0); } - - -void saturn_segatap_device::device_add_mconfig(machine_config &config) -{ - SATURN_CONTROL_PORT(config, m_subctrl_port[0], saturn_joys, "joypad"); - SATURN_CONTROL_PORT(config, m_subctrl_port[1], saturn_joys, "joypad"); - SATURN_CONTROL_PORT(config, m_subctrl_port[2], saturn_joys, "joypad"); - SATURN_CONTROL_PORT(config, m_subctrl_port[3], saturn_joys, "joypad"); -} diff --git a/src/devices/bus/sat_ctrl/segatap.h b/src/devices/bus/sat_ctrl/segatap.h index 987699e0a5a..799d4d8356a 100644 --- a/src/devices/bus/sat_ctrl/segatap.h +++ b/src/devices/bus/sat_ctrl/segatap.h @@ -20,10 +20,7 @@ // TYPE DEFINITIONS //************************************************************************** -// ======================> saturn_segatap_device - -class saturn_segatap_device : public device_t, - public device_saturn_control_port_interface +class saturn_segatap_device : public device_t, public device_saturn_control_port_interface { public: // construction/destruction @@ -32,9 +29,6 @@ public: protected: // device-level overrides virtual void device_start() override; - virtual void device_reset() override; - - // optional information overrides virtual void device_add_mconfig(machine_config &config) override; // device_saturn_control_port_interface overrides diff --git a/src/devices/machine/mb14241.cpp b/src/devices/machine/mb14241.cpp index 31a209e44cd..c9d08eb503e 100644 --- a/src/devices/machine/mb14241.cpp +++ b/src/devices/machine/mb14241.cpp @@ -17,7 +17,7 @@ DEFINE_DEVICE_TYPE(MB14241, mb14241_device, "mb14241", "MB14241 Data Shifter") -mb14241_device::mb14241_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) +mb14241_device::mb14241_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) : device_t(mconfig, MB14241, tag, owner, clock), m_shift_data(0), m_shift_count(0) { } @@ -47,17 +47,17 @@ void mb14241_device::device_reset() IMPLEMENTATION *****************************************************************************/ -WRITE8_MEMBER( mb14241_device::shift_count_w ) +void mb14241_device::shift_count_w(u8 data) { m_shift_count = ~data & 0x07; } -WRITE8_MEMBER( mb14241_device::shift_data_w ) +void mb14241_device::shift_data_w(u8 data) { - m_shift_data = (m_shift_data >> 8) | ((uint16_t)data << 7); + m_shift_data = (m_shift_data >> 8) | (u16(data) << 7); } -READ8_MEMBER( mb14241_device::shift_result_r ) +u8 mb14241_device::shift_result_r() { - return m_shift_data >> m_shift_count; + return u8((m_shift_data >> m_shift_count) & 0x00ff); } diff --git a/src/devices/machine/mb14241.h b/src/devices/machine/mb14241.h index 378c3c75b7d..00bc2a55949 100644 --- a/src/devices/machine/mb14241.h +++ b/src/devices/machine/mb14241.h @@ -14,11 +14,11 @@ class mb14241_device : public device_t { public: - mb14241_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock = 0); + mb14241_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock = 0); - DECLARE_WRITE8_MEMBER( shift_count_w ); - DECLARE_WRITE8_MEMBER( shift_data_w ); - DECLARE_READ8_MEMBER( shift_result_r ); + void shift_count_w(u8 data); + void shift_data_w(u8 data); + u8 shift_result_r(); protected: // device-level overrides @@ -27,9 +27,8 @@ protected: private: // internal state - - uint16_t m_shift_data; /* 15 bits only */ - uint8_t m_shift_count; /* 3 bits */ + u16 m_shift_data; // 15 bits only + u8 m_shift_count; // 3 bits }; DECLARE_DEVICE_TYPE(MB14241, mb14241_device) diff --git a/src/devices/machine/vrender0.cpp b/src/devices/machine/vrender0.cpp index c60a8908207..76442866a6d 100644 --- a/src/devices/machine/vrender0.cpp +++ b/src/devices/machine/vrender0.cpp @@ -115,7 +115,7 @@ void vrender0soc_device::device_add_mconfig(machine_config &config) SCREEN(config, m_screen, SCREEN_TYPE_RASTER); // evolution soccer defaults - m_screen->set_raw((XTAL(14'318'180)*2)/4, 455, 0, 320, 262, 0, 240); + m_screen->set_raw((XTAL(14'318'181)*2)/4, 455, 0, 320, 262, 0, 240); m_screen->set_screen_update(FUNC(vrender0soc_device::screen_update)); m_screen->screen_vblank().set(FUNC(vrender0soc_device::screen_vblank)); m_screen->set_palette(m_palette); diff --git a/src/emu/devfind.h b/src/emu/devfind.h index 2428e1a7325..2f90c48f370 100644 --- a/src/emu/devfind.h +++ b/src/emu/devfind.h @@ -100,8 +100,8 @@ public: /// int argument. /// \param [in] start Number to add to element index when /// calculating values for string format argument. - /// \arg [in] Optional additional constructor argument(s) passed to - /// all elements. + /// \param [in] arg Optional additional constructor argument(s) passed + /// to all elements. /// \sa util::string_format template <typename F, typename... Param> object_array_finder(device_t &base, F const &fmt, unsigned start, Param const &... arg) @@ -117,8 +117,8 @@ public: /// \param [in] tags Tags to search for, e.g. { "player", "dips" }. /// The tags are not copied, it is the caller's responsibility to /// ensure the pointers remain valid until resolution time. - /// \arg [in] Optional additional constructor argument(s) passed to - /// all elements. + /// \param [in] arg Optional additional constructor argument(s) passed + /// to all elements. template <typename... Param> object_array_finder(device_t &base, std::array<char const *, Count> const &tags, Param const &... arg) : object_array_finder(base, tags, std::make_integer_sequence<unsigned, Count>(), arg...) @@ -368,9 +368,9 @@ protected: /// with the requested tag is found, but it doesn't match the /// desired width. /// \param [in] width Desired memory share width in bits. - /// \param [out] bytes Set to memoyr share length in bytes if a + /// \param [out] bytes Set to memory share length in bytes if a /// matching memory share is found, otherwise left unchanged. - /// \param [in] required. Whether warning message should be printed + /// \param [in] required Whether warning message should be printed /// if a memory share with matching tag of incorrect width is /// found. /// \return Pointer to base of memory share if a matching memory @@ -387,7 +387,7 @@ protected: /// or a space with the designated number. /// \param [in] spacenum Address space number. /// \param [in] width Specific data width, or 0. - /// \param [in] required. Whether warning message should be printed + /// \param [in] required Whether warning message should be printed /// if a device with no memory interface or space of that number /// is found. /// \return Pointer to address space if a matching address space @@ -400,7 +400,7 @@ protected: /// found, or false otherwise. /// \param [in] spacenum Address space number. /// \param [in] width Specific data width, or 0. - /// \param [in] required. Whether warning message should be printed + /// \param [in] required Whether warning message should be printed /// if a device with no memory interface or space of that number /// is found. /// \return True if the space is optional, or if the space is diff --git a/src/emu/driver.cpp b/src/emu/driver.cpp index 8dde7622da6..d13a4899136 100644 --- a/src/emu/driver.cpp +++ b/src/emu/driver.cpp @@ -236,10 +236,7 @@ void driver_device::device_start() else machine_start(); - if (!m_callbacks[CB_SOUND_START].isnull()) - m_callbacks[CB_SOUND_START](); - else - sound_start(); + sound_start(); if (!m_callbacks[CB_VIDEO_START].isnull()) m_callbacks[CB_VIDEO_START](); @@ -268,10 +265,7 @@ void driver_device::device_reset_after_children() else machine_reset(); - if (!m_callbacks[CB_SOUND_RESET].isnull()) - m_callbacks[CB_SOUND_RESET](); - else - sound_reset(); + sound_reset(); if (!m_callbacks[CB_VIDEO_RESET].isnull()) m_callbacks[CB_VIDEO_RESET](); diff --git a/src/emu/driver.h b/src/emu/driver.h index 4f6576aa737..0a92151d07c 100644 --- a/src/emu/driver.h +++ b/src/emu/driver.h @@ -32,13 +32,6 @@ #define MCFG_MACHINE_RESET_REMOVE() \ driver_device::static_set_callback(config.root_device(), driver_device::CB_MACHINE_RESET, driver_callback_delegate()); -// core sound callbacks -#define MCFG_SOUND_START_OVERRIDE(_class, _func) \ - driver_device::static_set_callback(config.root_device(), driver_device::CB_SOUND_START, driver_callback_delegate(&_class::SOUND_START_NAME(_func), this)); - -#define MCFG_SOUND_RESET_OVERRIDE(_class, _func) \ - driver_device::static_set_callback(config.root_device(), driver_device::CB_SOUND_RESET, driver_callback_delegate(&_class::SOUND_RESET_NAME(_func), this)); - // core video callbacks #define MCFG_VIDEO_START_OVERRIDE(_class, _func) \ @@ -63,15 +56,6 @@ #define DECLARE_MACHINE_RESET(name) void MACHINE_RESET_NAME(name)() #define MACHINE_RESET_MEMBER(cls,name) void cls::MACHINE_RESET_NAME(name)() -#define SOUND_START_NAME(name) sound_start_##name -#define DECLARE_SOUND_START(name) void SOUND_START_NAME(name)() ATTR_COLD -#define SOUND_START_MEMBER(cls,name) void cls::SOUND_START_NAME(name)() - -#define SOUND_RESET_NAME(name) sound_reset_##name -#define SOUND_RESET_CALL_MEMBER(name) SOUND_RESET_NAME(name)() -#define DECLARE_SOUND_RESET(name) void SOUND_RESET_NAME(name)() -#define SOUND_RESET_MEMBER(cls,name) void cls::SOUND_RESET_NAME(name)() - #define VIDEO_START_NAME(name) video_start_##name #define VIDEO_START_CALL_MEMBER(name) VIDEO_START_NAME(name)() #define DECLARE_VIDEO_START(name) void VIDEO_START_NAME(name)() ATTR_COLD @@ -110,8 +94,6 @@ public: { CB_MACHINE_START, CB_MACHINE_RESET, - CB_SOUND_START, - CB_SOUND_RESET, CB_VIDEO_START, CB_VIDEO_RESET, CB_COUNT diff --git a/src/emu/screen.h b/src/emu/screen.h index 0ae11f85b9b..87eed6a2738 100644 --- a/src/emu/screen.h +++ b/src/emu/screen.h @@ -207,7 +207,24 @@ public: void set_orientation(int orientation) { assert(!configured()); m_orientation = orientation; } void set_physical_aspect(unsigned x, unsigned y) { assert(!configured()); m_phys_aspect = std::make_pair(x, y); } void set_native_aspect() { assert(!configured()); m_phys_aspect = std::make_pair(~0U, ~0U); } - void set_raw(u32 pixclock, u16 htotal, u16 hbend, u16 hbstart, u16 vtotal, u16 vbend, u16 vbstart) + + /// \brief Configure screen parameters + /// + /// \param [in] pixclock Pixel clock frequency in Hertz. + /// \param [in] htotal Total pixel clocks per line, including + /// horizontal blanking period. + /// \param [in] hbend Index of first visible pixel after horizontal + /// blanking period ends. + /// \param [in] hbstart Index of first pixel in horzontal blanking + /// period after visible pixels. + /// \param [in] vtotal Total lines per frame, including vertical + /// blanking period. + /// \param [in] vbend Index of first visible line after vertical + /// blanking period ends. + /// \param [in] vbstart Index of first line in vertical blanking + /// period after visible lines. + /// \return Reference to device for method chaining. + screen_device &set_raw(u32 pixclock, u16 htotal, u16 hbend, u16 hbstart, u16 vtotal, u16 vbend, u16 vbstart) { assert(pixclock != 0); m_clock = pixclock; @@ -216,15 +233,101 @@ public: m_width = htotal; m_height = vtotal; m_visarea.set(hbend, hbstart - 1, vbend, vbstart - 1); + return *this; + } + screen_device &set_raw(const XTAL &xtal, u16 htotal, u16 hbend, u16 hbstart, u16 vtotal, u16 vbend, u16 vbstart) + { + xtal.validate(std::string("Configuring screen ") + tag()); + return set_raw(xtal.value(), htotal, hbend, hbstart, vtotal, vbend, vbstart); } - void set_raw(const XTAL &xtal, u16 htotal, u16 hbend, u16 hbstart, u16 vtotal, u16 vbend, u16 vbstart) { set_raw(xtal.value(), htotal, hbend, hbstart, vtotal, vbend, vbstart); } void set_refresh(attoseconds_t rate) { m_refresh = rate; } - template <typename T> void set_refresh_hz(T &&hz) { set_refresh(HZ_TO_ATTOSECONDS(std::forward<T>(hz))); } - void set_vblank_time(attoseconds_t time) { m_vblank = time; m_oldstyle_vblank_supplied = true; } - void set_size(u16 width, u16 height) { m_width = width; m_height = height; } - void set_visarea(s16 minx, s16 maxx, s16 miny, s16 maxy) { m_visarea.set(minx, maxx, miny, maxy); } - void set_visarea_full() { m_visarea.set(0, m_width - 1, 0, m_height - 1); } // call after set_size - void set_default_position(double xscale, double xoffs, double yscale, double yoffs) { + + /// \brief Set refresh rate in Hertz + /// + /// Sets refresh rate in Hertz (frames per second). Used in + /// conjunction with #set_vblank_time, #set_size and #set_visarea. + /// For raster displays, please use #set_raw to configure screen + /// parameters in terms of pixel clock. + /// \param [in] hz Desired refresh rate. + /// \return Reference to device for method chaining. + template <typename T> screen_device &set_refresh_hz(T &&hz) + { + set_refresh(HZ_TO_ATTOSECONDS(std::forward<T>(hz))); + return *this; + } + + /// \brief Set vertical blanking interval time + /// + /// Sets vertical blanking interval period. Used in conjunction + /// with #set_refresh_hz, #set_size and #set_visarea. For raster + /// displays, please use #set_raw to configure screen parameters in + /// terms of pixel clock. + /// \param [in] time Length of vertical blanking interval. + /// \return Reference to device for method chaining. + screen_device &set_vblank_time(attoseconds_t time) + { + m_vblank = time; + m_oldstyle_vblank_supplied = true; + return *this; + } + + /// \brief Set total screen size + /// + /// Set the total screen size in pixels, including blanking areas if + /// applicable. This sets the size of the screen bitmap. Used in + /// conjunction with #set_refresh_hz, #set_vblank_time and + /// #set_visarea. For raster displays, please use #set_raw to + /// configure screen parameters in terms of pixel clock. + /// \param [in] width Total width in pixels, including horizontal + /// blanking period if applicable. + /// \param [in] height Total height in lines, including vertical + /// blanking period if applicable. + /// \return Reference to device for method chaining. + screen_device &set_size(u16 width, u16 height) + { + m_width = width; + m_height = height; + return *this; + } + + /// \brief Set visible screen area + /// + /// Set visible screen area. This should fit within the total + /// screen area. Used in conjunction with #set_refresh_hz, + /// #set_vblank_time and #set_size. For raster displays, please + /// use #set_raw to configure screen parameters in terms of pixel + /// clock. + /// \param [in] minx First visible pixel index after horizontal + /// blanking period ends. + /// \param [in] maxx Last visible pixel index before horizontal + /// blanking period starts. + /// \param [in] miny First visible line index after vertical + /// blanking period ends. + /// \param [in] maxy Last visible line index before vertical + /// blanking period starts. + /// \return Reference to device for method chaining. + screen_device &set_visarea(s16 minx, s16 maxx, s16 miny, s16 maxy) + { + m_visarea.set(minx, maxx, miny, maxy); + return *this; + } + + /// \brief Set visible area to full area + /// + /// Set visible screen area to the full screen area (i.e. noi + /// horizontal or vertical blanking period). This is generally not + /// possible for raster displays, but is useful for other display + /// simulations. Must be called after calling #set_size. + /// \return Reference to device for method chaining. + /// \sa set_visarea + screen_device &set_visarea_full() + { + m_visarea.set(0, m_width - 1, 0, m_height - 1); + return *this; + } + + void set_default_position(double xscale, double xoffs, double yscale, double yoffs) + { m_xscale = xscale; m_xoffset = xoffs; m_yscale = yscale; @@ -445,72 +548,6 @@ typedef device_type_iterator<screen_device> screen_device_iterator; @def set_type Modify the screen device type @see screen_type_enum - - @def set_raw - Configures screen parameters for the given screen. - @remark It's better than using @see set_refresh_hz and @see set_vblank_time but still not enough. - - @param _pixclock - Pixel Clock frequency value - - @param _htotal - Total number of horizontal pixels, including hblank period. - - @param _hbend - Horizontal pixel position for HBlank end event, also first pixel where screen rectangle is visible. - - @param _hbstart - Horizontal pixel position for HBlank start event, also last pixel where screen rectangle is visible. - - @param _vtotal - Total number of vertical pixels, including vblank period. - - @param _vbend - Vertical pixel position for VBlank end event, also first pixel where screen rectangle is visible. - - @param _vbstart - Vertical pixel position for VBlank start event, also last pixel where screen rectangle is visible. - - @def set_refresh_hz - Sets the number of Frames Per Second for this screen - @remarks Please use @see set_raw instead. Gives imprecise timings. - - @param _rate - FPS number - - @def set_vblank_time - Sets the vblank time of the given screen - @remarks Please use @see MCFG_SCREEN_RAW_PARAMS instead. Gives imprecise timings. - - @param _time - Time parameter, in attotime value - - @def set_size - Sets total screen size, including H/V-Blanks - @remarks Please use @see set_raw instead. Gives imprecise timings. - - @param _width - Screen horizontal size - - @param _height - Screen vertical size - - @def set_visarea - Sets screen visible area - @remarks Please use @see set_raw instead. Gives imprecise timings. - - @param _minx - Screen left border - - @param _maxx - Screen right border, must be in N-1 format - - @param _miny - Screen top border - - @param _maxx - Screen bottom border, must be in N-1 format - @} */ diff --git a/src/mame/audio/mw8080bw.cpp b/src/mame/audio/mw8080bw.cpp index 0c54e4b70d6..70e0b59e2ff 100644 --- a/src/mame/audio/mw8080bw.cpp +++ b/src/mame/audio/mw8080bw.cpp @@ -8,26 +8,14 @@ ****************************************************************************/ #include "emu.h" +#include "audio/mw8080bw.h" + #include "includes/mw8080bw.h" #include "speaker.h" /************************************* * - * Audio setup - * - *************************************/ - -SOUND_START_MEMBER( mw8080bw_state, samples ) -{ - /* setup for save states */ - save_item(NAME(m_port_1_last)); - save_item(NAME(m_port_2_last)); -} - - -/************************************* - * * Implementation of tone generator used * by a few of these games * @@ -53,26 +41,26 @@ SOUND_START_MEMBER( mw8080bw_state, samples ) /* most common values based on clowns schematic */ -static const discrete_op_amp_tvca_info midway_music_tvca_info = +static discrete_op_amp_tvca_info const midway_music_tvca_info = { - RES_M(3.3), /* r502 */ - RES_K(10) + RES_K(680), /* r505 + r506 */ + RES_M(3.3), // r502 + RES_K(10) + RES_K(680), // r505 + r506 0, - RES_K(680), /* r503 */ - RES_K(10), /* r500 */ + RES_K(680), // r503 + RES_K(10), // r500 0, - RES_K(680), /* r501 */ + RES_K(680), // r501 0, 0, 0, 0, - CAP_U(.001), /* c500 */ + CAP_U(.001), // c500 0, 0, 0, - 12, /* v1 */ - 0, /* v2 */ - 0, /* v3 */ - 12, /* vP */ + 12, // v1 + 0, // v2 + 0, // v3 + 12, // vP DISC_OP_AMP_TRIGGER_FUNCTION_TRG0, DISC_OP_AMP_TRIGGER_FUNCTION_NONE, DISC_OP_AMP_TRIGGER_FUNCTION_TRG1, @@ -82,180 +70,1247 @@ static const discrete_op_amp_tvca_info midway_music_tvca_info = }; -WRITE8_MEMBER(mw8080bw_state::midway_tone_generator_lo_w) +/************************************* + * + * Implementation of the common + * noise circuits + * + *************************************/ + +static discrete_lfsr_desc const midway_lfsr = { - m_discrete->write(MIDWAY_TONE_EN, (data >> 0) & 0x01); + DISC_CLK_IS_FREQ, + 17, // bit length + // the RC network fed into pin 4 has the effect of presetting all bits high at power up + 0x1ffff, // reset value + 4, // use bit 4 as XOR input 0 + 16, // use bit 16 as XOR input 1 + DISC_LFSR_XOR, // feedback stage1 is XOR + DISC_LFSR_OR, // feedback stage2 is just stage 1 output OR with external feed + DISC_LFSR_REPLACE, // feedback stage3 replaces the shifted register contents + 0x000001, // everything is shifted into the first bit only + 0, // output is not inverted + 12 // output bit +}; - m_discrete->write(MIDWAY_TONE_DATA_L, (data >> 1) & 0x1f); - /* D6 and D7 are not connected */ +/************************************* + * + * Device type globals + * + *************************************/ + +DEFINE_DEVICE_TYPE(SEAWOLF_AUDIO, seawolf_audio_device, "seawolf_audio", "Nutting Sea Wolf Audio") +DEFINE_DEVICE_TYPE(GUNFIGHT_AUDIO, gunfight_audio_device, "gunfight_audio", "Nutting Gun Fight Audio") +DEFINE_DEVICE_TYPE(GMISSILE_AUDIO, gmissile_audio_device, "gmissile_audio", "Midway Guided Missile Audio") +DEFINE_DEVICE_TYPE(CLOWNS_AUDIO, clowns_audio_device, "clowns_audio", "Midway Clowns Audio") +DEFINE_DEVICE_TYPE(SPCENCTR_AUDIO, spcenctr_audio_device, "spcenctr_audio", "Midway Space Encounters Audio") +DEFINE_DEVICE_TYPE(M4_AUDIO, m4_audio_device, "m4_audio", "Midway M-4 Audio") +DEFINE_DEVICE_TYPE(PHANTOM2_AUDIO, phantom2_audio_device, "pantom2_audio", "Midway Phantom 2 Audio") + + +/************************************* + * + * Sea Wolf + * + *************************************/ + +seawolf_audio_device::seawolf_audio_device(machine_config const &mconfig, char const *tag, device_t *owner, u32 clock) : + device_t(mconfig, SEAWOLF_AUDIO, tag, owner, clock), + m_samples(*this, "samples"), + m_prev(0U) +{ } +void seawolf_audio_device::write(u8 data) +{ + u8 const rising(data & ~m_prev); + m_prev = data; -WRITE8_MEMBER(mw8080bw_state::midway_tone_generator_hi_w) + if (BIT(rising, 0)) m_samples->start(0, 0); // SHIP HIT sound + if (BIT(rising, 1)) m_samples->start(1, 1); // TORPEDO sound + if (BIT(rising, 2)) m_samples->start(2, 2); // DIVE sound + if (BIT(rising, 3)) m_samples->start(3, 3); // SONAR sound + if (BIT(rising, 4)) m_samples->start(4, 4); // MINE HIT sound + + machine().bookkeeping().coin_counter_w(0, BIT(data, 5)); + + // D6 and D7 are not connected +} + +void seawolf_audio_device::device_add_mconfig(machine_config &config) { - m_discrete->write(MIDWAY_TONE_DATA_H, data & 0x3f); + static char const *const sample_names[] = { + "*seawolf", + "shiphit", + "torpedo", + "dive", + "sonar", + "minehit", + nullptr }; - /* D6 and D7 are not connected */ + SPEAKER(config, "mono").front_center(); + + SAMPLES(config, m_samples); + m_samples->set_channels(5); + m_samples->set_samples_names(sample_names); + m_samples->add_route(ALL_OUTPUTS, "mono", 0.6); } +void seawolf_audio_device::device_start() +{ + m_prev = 0U; + + save_item(NAME(m_prev)); +} /************************************* * - * Implementation of the common - * noise circuits + * Gun Fight * *************************************/ -static const discrete_lfsr_desc midway_lfsr = +gunfight_audio_device::gunfight_audio_device(machine_config const &mconfig, char const *tag, device_t *owner, u32 clock) : + device_t(mconfig, GUNFIGHT_AUDIO, tag, owner, clock), + m_samples(*this, "samples%u", 1U) { - DISC_CLK_IS_FREQ, - 17, /* bit length */ - /* the RC network fed into pin 4, has the effect - of presetting all bits high at power up */ - 0x1ffff, /* reset value */ - 4, /* use bit 4 as XOR input 0 */ - 16, /* use bit 16 as XOR input 1 */ - DISC_LFSR_XOR, /* feedback stage1 is XOR */ - DISC_LFSR_OR, /* feedback stage2 is just stage 1 output OR with external feed */ - DISC_LFSR_REPLACE, /* feedback stage3 replaces the shifted register contents */ - 0x000001, /* everything is shifted into the first bit only */ - 0, /* output is not inverted */ - 12 /* output bit */ -}; +} + +void gunfight_audio_device::write(u8 data) +{ + // D0 and D1 are just tied to 1k resistors + + machine().bookkeeping().coin_counter_w(0, BIT(data, 2)); + // the 74175 latches and inverts the top 4 bits + switch ((~data >> 4) & 0x0f) + { + case 0x00: + break; + case 0x01: // LEFT SHOOT sound (left speaker) + m_samples[0]->start(0, 0); + break; + case 0x02: // RIGHT SHOOT sound (right speaker) + m_samples[1]->start(0, 0); + break; + case 0x03: // LEFT HIT sound (left speaker) + m_samples[0]->start(0, 1); + break; + case 0x04: // enable RIGHT HIT sound (right speaker) + m_samples[1]->start(0, 1); + break; + default: + logerror("%s: Unknown sh port write %02x\n", machine().describe_context(), data); + break; + } +} + +void gunfight_audio_device::device_add_mconfig(machine_config &config) +{ + static char const *const sample_names[] = { + "*gunfight", + "gunshot", + "killed", + nullptr }; + + SPEAKER(config, "lspeaker").front_left(); + SPEAKER(config, "rspeaker").front_right(); + + SAMPLES(config, m_samples[0]); + m_samples[0]->set_channels(1); + m_samples[0]->set_samples_names(sample_names); + m_samples[0]->add_route(ALL_OUTPUTS, "lspeaker", 0.5); + + SAMPLES(config, m_samples[1]); + m_samples[1]->set_channels(1); + m_samples[1]->set_samples_names(sample_names); + m_samples[1]->add_route(ALL_OUTPUTS, "rspeaker", 0.5); +} + +void gunfight_audio_device::device_start() +{ +} /************************************* * - * Sea Wolf + * Guided Missile * *************************************/ -static const char *const seawolf_sample_names[] = +gmissile_audio_device::gmissile_audio_device(machine_config const &mconfig, char const *tag, device_t *owner, u32 clock) : + device_t(mconfig, GMISSILE_AUDIO, tag, owner, clock), + m_samples(*this, "samples%u", 1U), + m_l_exp(*this, "L_EXP_LIGHT"), + m_r_exp(*this, "R_EXP_LIGHT"), + m_p1(0U) { - "*seawolf", - "shiphit", - "torpedo", - "dive", - "sonar", - "minehit", - nullptr +} + +void gmissile_audio_device::p1_w(u8 data) +{ + /* note that the schematics shows the left and right explosions + reversed (D5=R, D7=L), but the software confirms that + ours is right */ + + u8 const rising(data & ~m_p1); + m_p1 = data; + + // D0 and D1 are not connected + + machine().bookkeeping().coin_counter_w(0, BIT(data, 2)); + + machine().sound().system_enable(BIT(data, 3)); + + if (BIT(rising, 4)) m_samples[1]->start(0, 0); // RIGHT MISSILE sound (goes to right speaker) + + m_l_exp = BIT(data, 5); + if (BIT(rising, 5)) m_samples[0]->start(0, 1); // LEFT EXPLOSION sound (goes to left speaker) + + if (BIT(rising, 6)) m_samples[0]->start(0, 0); // LEFT MISSILE sound (goes to left speaker) + + m_r_exp = BIT(data, 7); + if (BIT(rising, 7)) m_samples[1]->start(0, 1); // RIGHT EXPLOSION sound (goes to right speaker) +} + +void gmissile_audio_device::p2_w(u8 data) +{ + // set AIRPLANE/COPTER/JET PAN(data & 0x07) + + // set TANK PAN((data >> 3) & 0x07) + + // D6 and D7 are not connected +} + +void gmissile_audio_device::p3_w(u8 data) +{ + // if (data & 0x01) enable AIRPLANE (bi-plane) sound (goes to AIRPLANE/COPTER/JET panning circuit) + + // if (data & 0x02) enable TANK sound (goes to TANK panning circuit) + + // if (data & 0x04) enable COPTER sound (goes to AIRPLANE/COPTER/JET panning circuit) + + // D3 and D4 are not connected + + // if (data & 0x20) enable JET (3 fighter jets) sound (goes to AIRPLANE/COPTER/JET panning circuit) + + // D6 and D7 are not connected +} + +void gmissile_audio_device::device_add_mconfig(machine_config &config) +{ + static char const *const sample_names[] = { + "*gmissile", + "1", // missle + "2", // explosion + nullptr }; + + SPEAKER(config, "lspeaker").front_left(); + SPEAKER(config, "rspeaker").front_right(); + + SAMPLES(config, m_samples[0]); + m_samples[0]->set_channels(1); + m_samples[0]->set_samples_names(sample_names); + m_samples[0]->add_route(ALL_OUTPUTS, "lspeaker", 1.0); + + SAMPLES(config, m_samples[1]); + m_samples[1]->set_channels(1); + m_samples[1]->set_samples_names(sample_names); + m_samples[1]->add_route(ALL_OUTPUTS, "rspeaker", 1.0); +} + +void gmissile_audio_device::device_start() +{ + m_l_exp.resolve(); + m_r_exp.resolve(); + + m_p1 = 0U; + + save_item(NAME(m_p1)); +} + + +/************************************* + * + * Clowns + * + * Discrete sound emulation: Mar 2005, D.R. + * + *************************************/ + +// nodes - inputs +#define CLOWNS_POP_BOTTOM_EN NODE_01 +#define CLOWNS_POP_MIDDLE_EN NODE_02 +#define CLOWNS_POP_TOP_EN NODE_03 +#define CLOWNS_SPRINGBOARD_HIT_EN NODE_04 +#define CLOWNS_SPRINGBOARD_MISS_EN NODE_05 + +// nodes - sounds +#define CLOWNS_NOISE NODE_06 +#define CLOWNS_POP_SND NODE_07 +#define CLOWNS_SB_HIT_SND NODE_08 +#define CLOWNS_SB_MISS_SND NODE_09 + +// nodes - adjusters +#define CLOWNS_R507_POT NODE_11 + +static discrete_op_amp_tvca_info const clowns_pop_tvca_info = +{ + RES_M(2.7), // r304 + RES_K(680), // r303 + 0, + RES_K(680), // r305 + RES_K(1), // j3 + 0, + RES_K(470), // r300 + RES_K(1), // j3 + RES_K(510), // r301 + RES_K(1), // j3 + RES_K(680), // r302 + CAP_U(.015), // c300 + CAP_U(.1), // c301 + CAP_U(.082), // c302 + 0, // no c4 + 5, // v1 + 5, // v2 + 5, // v3 + 12, // vP + DISC_OP_AMP_TRIGGER_FUNCTION_NONE, + DISC_OP_AMP_TRIGGER_FUNCTION_NONE, + DISC_OP_AMP_TRIGGER_FUNCTION_TRG0, + DISC_OP_AMP_TRIGGER_FUNCTION_NONE, + DISC_OP_AMP_TRIGGER_FUNCTION_TRG1, + DISC_OP_AMP_TRIGGER_FUNCTION_TRG2 }; -void mw8080bw_state::seawolf_audio(machine_config &config) +static discrete_op_amp_osc_info const clowns_sb_hit_osc_info = { - MCFG_SOUND_START_OVERRIDE(mw8080bw_state, samples) + DISC_OP_AMP_OSCILLATOR_1 | DISC_OP_AMP_IS_NORTON | DISC_OP_AMP_OSCILLATOR_OUT_SQW, + RES_K(820), // r200 + RES_K(33), // r203 + RES_K(150), // r201 + RES_K(240), // r204 + RES_M(1), // r202 + 0, + 0, + 0, + CAP_U(0.01), // c200 + 12 +}; + +static discrete_op_amp_tvca_info const clowns_sb_hit_tvca_info = +{ + RES_M(2.7), // r207 + RES_K(680), // r205 + 0, + RES_K(680), // r208 + RES_K(1), // j3 + 0, + RES_K(680), // r206 + 0,0,0,0, + CAP_U(1), // c201 + 0, + 0, 0, + 5, // v1 + 0, // v2 + 0, // v3 + 12, // vP + DISC_OP_AMP_TRIGGER_FUNCTION_NONE, + DISC_OP_AMP_TRIGGER_FUNCTION_NONE, + DISC_OP_AMP_TRIGGER_FUNCTION_TRG0, + DISC_OP_AMP_TRIGGER_FUNCTION_NONE, + DISC_OP_AMP_TRIGGER_FUNCTION_NONE, + DISC_OP_AMP_TRIGGER_FUNCTION_NONE +}; + +static discrete_mixer_desc const clowns_mixer = +{ + DISC_MIXER_IS_OP_AMP, + { RES_K(10), + RES_K(10), + RES_K(10) + 1.0 / (1.0 / RES_K(15) + 1.0 / RES_K(39)), + RES_K(1) }, + { 0, + 0, + 0, + CLOWNS_R507_POT }, + { 0, + CAP_U(0.022), + 0, + 0 }, + 0, + RES_K(100), + 0, + CAP_U(1), + 0, + 1 +}; + +static DISCRETE_SOUND_START(clowns_discrete) + + /************************************************ + * Input register mapping + ************************************************/ + DISCRETE_INPUT_LOGIC(CLOWNS_POP_BOTTOM_EN) + DISCRETE_INPUT_LOGIC(CLOWNS_POP_MIDDLE_EN) + DISCRETE_INPUT_LOGIC(CLOWNS_POP_TOP_EN) + DISCRETE_INPUT_LOGIC(CLOWNS_SPRINGBOARD_HIT_EN) + DISCRETE_INPUT_LOGIC(CLOWNS_SPRINGBOARD_MISS_EN) + + // The low value of the pot is set to 7000. A real 1M pot will never go to 0 anyways. + // This will give the control more apparent volume range. + // The music way overpowers the rest of the sounds anyways. + DISCRETE_ADJUSTMENT(CLOWNS_R507_POT, RES_M(1), 7000, DISC_LOGADJ, "R507") + + /************************************************ + * Tone generator + ************************************************/ + MIDWAY_TONE_GENERATOR(midway_music_tvca_info) + + /************************************************ + * Balloon hit sounds + * The LFSR is the same as boothill + ************************************************/ + // Noise clock was breadboarded and measured at 7700Hz + DISCRETE_LFSR_NOISE(CLOWNS_NOISE, 1, 1, 7700, 12.0, 0, 12.0/2, &midway_lfsr) + + DISCRETE_OP_AMP_TRIG_VCA(NODE_30, CLOWNS_POP_TOP_EN, CLOWNS_POP_MIDDLE_EN, CLOWNS_POP_BOTTOM_EN, CLOWNS_NOISE, 0, &clowns_pop_tvca_info) + DISCRETE_RCFILTER(NODE_31, NODE_30, RES_K(15), CAP_U(.01)) + DISCRETE_CRFILTER(NODE_32, NODE_31, RES_K(15) + RES_K(39), CAP_U(.01)) + DISCRETE_GAIN(CLOWNS_POP_SND, NODE_32, RES_K(39)/(RES_K(15) + RES_K(39))) + + /************************************************ + * Springboard hit + ************************************************/ + DISCRETE_OP_AMP_OSCILLATOR(NODE_40, 1, &clowns_sb_hit_osc_info) + DISCRETE_OP_AMP_TRIG_VCA(NODE_41, CLOWNS_SPRINGBOARD_HIT_EN, 0, 0, NODE_40, 0, &clowns_sb_hit_tvca_info) + // The rest of the circuit is a filter. The frequency response was calculated with SPICE. + DISCRETE_FILTER2(NODE_42, 1, NODE_41, 500, 1.0/.8, DISC_FILTER_LOWPASS) + // The filter has a gain of 0.5 + DISCRETE_GAIN(CLOWNS_SB_HIT_SND, NODE_42, 0.5) + + /************************************************ + * Springboard miss - INCOMPLETE + ************************************************/ + DISCRETE_CONSTANT(CLOWNS_SB_MISS_SND, 0) // Placeholder for incomplete sound + + /************************************************ + * Combine all sound sources. + ************************************************/ + DISCRETE_MIXER4(NODE_91, 1, CLOWNS_SB_HIT_SND, CLOWNS_SB_MISS_SND, CLOWNS_POP_SND, MIDWAY_TONE_SND, &clowns_mixer) + + DISCRETE_OUTPUT(NODE_91, 11000) +DISCRETE_SOUND_END + +clowns_audio_device::clowns_audio_device(machine_config const &mconfig, char const *tag, device_t *owner, u32 clock) : + device_t(mconfig, CLOWNS_AUDIO, tag, owner, clock), + m_samples(*this, "samples"), + m_discrete(*this, "discrete"), + m_ctrl_sel_out(*this), + m_p1(0U), + m_p2(0U) +{ +} + +void clowns_audio_device::p1_w(u8 data) +{ + u8 const changed(data ^ m_p1); + m_p1 = data; + + machine().bookkeeping().coin_counter_w(0, BIT(data, 0)); + + if (BIT(changed, 1)) m_ctrl_sel_out(BIT(data, 1)); + + // D2-D7 are not connected +} + +void clowns_audio_device::p2_w(u8 data) +{ + u8 const rising(data & ~m_p2); + m_p2 = data; + + m_discrete->write(CLOWNS_POP_BOTTOM_EN, BIT(data, 0)); + m_discrete->write(CLOWNS_POP_MIDDLE_EN, BIT(data, 1)); + m_discrete->write(CLOWNS_POP_TOP_EN, BIT(data, 2)); + + machine().sound().system_enable(BIT(data, 3)); + + m_discrete->write(CLOWNS_SPRINGBOARD_HIT_EN, BIT(data, 4)); + + if (BIT(rising, 5)) m_samples->start(0, 0); // springboard miss + + // D6 and D7 are not connected +} + +void clowns_audio_device::device_add_mconfig(machine_config &config) +{ + static char const *const sample_names[] = { + "*clowns", + "miss", + nullptr }; SPEAKER(config, "mono").front_center(); + SAMPLES(config, m_samples); - m_samples->set_channels(5); - m_samples->set_samples_names(seawolf_sample_names); - m_samples->add_route(ALL_OUTPUTS, "mono", 0.6); + m_samples->set_channels(1); + m_samples->set_samples_names(sample_names); + m_samples->add_route(ALL_OUTPUTS, "mono", 0.70); + + DISCRETE(config, m_discrete, clowns_discrete); + m_discrete->add_route(ALL_OUTPUTS, "mono", 0.25); +} + +void clowns_audio_device::device_start() +{ + m_ctrl_sel_out.resolve_safe(); + + m_p1 = 0U; + m_p2 = 0U; + + save_item(NAME(m_p2)); + save_item(NAME(m_p2)); } -WRITE8_MEMBER(mw8080bw_state::seawolf_audio_w) +/************************************* + * + * Space Encounters + * + * Discrete sound emulation: + * Apr 2007, D.R. + *************************************/ + +// nodes - inputs +#define SPCENCTR_ENEMY_SHIP_SHOT_EN NODE_01 +#define SPCENCTR_PLAYER_SHOT_EN NODE_02 +#define SPCENCTR_SCREECH_EN NODE_03 +#define SPCENCTR_CRASH_EN NODE_04 +#define SPCENCTR_EXPLOSION_EN NODE_05 +#define SPCENCTR_BONUS_EN NODE_06 +#define SPCENCTR_WIND_DATA NODE_07 + +// nodes - sounds +#define SPCENCTR_NOISE NODE_10 +#define SPCENCTR_ENEMY_SHIP_SHOT_SND NODE_11 +#define SPCENCTR_PLAYER_SHOT_SND NODE_12 +#define SPCENCTR_SCREECH_SND NODE_13 +#define SPCENCTR_CRASH_SND NODE_14 +#define SPCENCTR_EXPLOSION_SND NODE_15 +#define SPCENCTR_BONUS_SND NODE_16 +#define SPCENCTR_WIND_SND NODE_17 + +static discrete_op_amp_info const spcenctr_enemy_ship_shot_op_amp_E1 = +{ + DISC_OP_AMP_IS_NORTON, + 0, // no r1 + RES_K(510), // R100 + RES_M(2.2), // R101 + RES_M(2.2), // R102 + CAP_U(0.1), // C100 + 0, // vN + 12 // vP +}; + +static discrete_op_amp_osc_info const spcenctr_enemy_ship_shot_op_amp_osc = +{ + DISC_OP_AMP_OSCILLATOR_VCO_3 | DISC_OP_AMP_IS_NORTON | DISC_OP_AMP_OSCILLATOR_OUT_SQW, + RES_K(560), // R103 + RES_K(7.5), // R118 + RES_K(22), // R104 + RES_K(47), // R106 + RES_K(100), // R105 + 0, // no r6 + 0, // no r7 + 0, // no r8 + CAP_U(0.0022), // C101 + 12, // vP +}; + + +static discrete_op_amp_info const spcenctr_enemy_ship_shot_op_amp_D1 = { - uint8_t rising_bits = data & ~m_port_1_last; + DISC_OP_AMP_IS_NORTON, + RES_K(100), // R107 + RES_K(100), // R109 + RES_M(2.7), // R108 + RES_K(100), // R110 + 0, // no c + 0, // vN + 12 // vP +}; - /* if (data & 0x01) enable SHIP HIT sound */ - if (rising_bits & 0x01) m_samples->start(0, 0); +static discrete_op_amp_filt_info const spcenctr_enemy_ship_shot_filt = +{ + RES_K(100), // R112 + RES_K(10), // R113 + RES_M(4.3), // r3 + 0, // no r4 + RES_M(2.2), // R114 + CAP_U(0.001), // c1 + CAP_U(0.001), // c2 + 0, // no c3 + 0, // vRef + 12, // vP + 0 // vN +}; + +static discrete_op_amp_1sht_info const spcenctr_player_shot_1sht = +{ + DISC_OP_AMP_1SHT_1 | DISC_OP_AMP_IS_NORTON, + RES_M(4.7), // R500 + RES_K(100), // R502 + RES_M(1), // R501 + RES_M(1), // R503 + RES_M(2.2), // R504 + CAP_U(1), // C500 + CAP_P(470), // C501 + 0, // vN + 12 // vP +}; - /* if (data & 0x02) enable TORPEDO sound */ - if (rising_bits & 0x02) m_samples->start(1, 1); +static discrete_op_amp_info const spcenctr_player_shot_op_amp_E1 = +{ + DISC_OP_AMP_IS_NORTON, + 0, // no r1 + RES_K(10), // R505 + RES_M(1.5), // R506 + 0, // no r4 + CAP_U(0.22), // C502 + 0, // vN + 12 // vP +}; - /* if (data & 0x04) enable DIVE sound */ - if (rising_bits & 0x04) m_samples->start(2, 2); +static discrete_op_amp_osc_info const spcenctr_player_shot_op_amp_osc = +{ + DISC_OP_AMP_OSCILLATOR_VCO_3 | DISC_OP_AMP_IS_NORTON | DISC_OP_AMP_OSCILLATOR_OUT_SQW, + 1.0 / (1.0 / RES_M(1) + 1.0 / RES_K(330)) + RES_M(1.5), // R507||R509 + R508 + RES_M(1), // R513 + RES_K(560), // R512 + RES_M(2.7), // R516 + RES_M(1), // R515 + RES_M(4.7), // R510 + RES_M(3.3), // R511 + 0, // no r8 + CAP_P(330), // C504 + 12, // vP +}; - /* if (data & 0x08) enable SONAR sound */ - if (rising_bits & 0x08) m_samples->start(3, 3); +static discrete_op_amp_info const spcenctr_player_shot_op_amp_C1 = +{ + DISC_OP_AMP_IS_NORTON, + RES_K(560), // R517 + RES_K(470), // R514 + RES_M(2.7), // R518 + RES_K(560), // R524 + 0, // no c + 0, // vN + 12 // vP +}; - /* if (data & 0x10) enable MINE HIT sound */ - if (rising_bits & 0x10) m_samples->start(4, 4); +static discrete_op_amp_tvca_info const spcenctr_player_shot_tvca = +{ + RES_M(2.7), // R522 + RES_K(560), // R521 + 0, // no r3 + RES_K(560), // R560 + RES_K(1), // R42 + 0, // no r6 + RES_K(560), // R523 + 0, // no r8 + 0, // no r9 + 0, // no r10 + 0, // no r11 + CAP_U(1), // C506 + 0, // no c2 + 0, 0, // no c3, c4 + 12, // v1 + 0, // no v2 + 0, // no v3 + 12, // vP + DISC_OP_AMP_TRIGGER_FUNCTION_NONE, // no f0 + DISC_OP_AMP_TRIGGER_FUNCTION_NONE, // no f1 + DISC_OP_AMP_TRIGGER_FUNCTION_TRG0, // f2 + DISC_OP_AMP_TRIGGER_FUNCTION_NONE, // no f3 + DISC_OP_AMP_TRIGGER_FUNCTION_NONE, // no f4 + DISC_OP_AMP_TRIGGER_FUNCTION_NONE // no f5 +}; - machine().bookkeeping().coin_counter_w(0, (data >> 5) & 0x01); +static discrete_op_amp_tvca_info const spcenctr_crash_tvca = +{ + RES_M(2.7), // R302 + RES_K(470), // R300 + 0, // no r3 + RES_K(470), // R303 + RES_K(1), // R56 + 0, // no r6 + RES_K(470), // R301 + 0, // no r8 + 0, // no r9 + 0, // no r10 + 0, // no r11 + CAP_U(2.2), // C304 + 0, // no c2 + 0, 0, // no c3, c4 + 5, // v1 + 0, // no v2 + 0, // no v3 + 12, // vP + DISC_OP_AMP_TRIGGER_FUNCTION_NONE, // no f0 + DISC_OP_AMP_TRIGGER_FUNCTION_NONE, // no f1 + DISC_OP_AMP_TRIGGER_FUNCTION_TRG0, // f2 + DISC_OP_AMP_TRIGGER_FUNCTION_NONE, // no f3 + DISC_OP_AMP_TRIGGER_FUNCTION_NONE, // no f4 + DISC_OP_AMP_TRIGGER_FUNCTION_NONE // no f5 +}; - /* D6 and D7 are not connected */ +static discrete_op_amp_tvca_info const spcenctr_explosion_tvca = +{ + RES_M(2.7), // R402 + RES_K(680), // R400 + 0, // no r3 + RES_K(680), // R403 + RES_K(1), // R41 + 0, // no r6 + RES_K(680), // R401 + 0, // no r8 + 0, // no r9 + 0, // no r10 + 0, // no r11 + CAP_U(2.2), // C400 + 0, // no c2 + 0, 0, // no c3, c4 + 12, // v1 + 0, // no v2 + 0, // no v3 + 12, // vP + DISC_OP_AMP_TRIGGER_FUNCTION_NONE, // no f0 + DISC_OP_AMP_TRIGGER_FUNCTION_NONE, // no f1 + DISC_OP_AMP_TRIGGER_FUNCTION_TRG0, // f2 + DISC_OP_AMP_TRIGGER_FUNCTION_NONE, // no f3 + DISC_OP_AMP_TRIGGER_FUNCTION_NONE, // no f4 + DISC_OP_AMP_TRIGGER_FUNCTION_NONE // no f5 +}; + +static const discrete_555_desc spcenctr_555_bonus = +{ + DISC_555_OUT_SQW | DISC_555_OUT_DC, + 5, // B+ voltage of 555 + DEFAULT_555_VALUES +}; + +static const discrete_mixer_desc spcenctr_mixer = +{ + DISC_MIXER_IS_RESISTOR, // type + { RES_K(15), // R117 + RES_K(15), // R526 + RES_K(22), // R211 + RES_K(3.6), // R309 + RES_K(1.8) + RES_K(3.6) + RES_K(4.7), // R405 + R406 + R407 + RES_K(27), // R715 + RES_K(27)}, // R51 + {0}, // no rNode{} + { 0, + CAP_U(0.001), // C505 + CAP_U(0.1), // C202 + CAP_U(1), // C303 + 0, + 0, + CAP_U(10)}, // C16 + 0, // no rI + 0, // no rF + 0, // no cF + CAP_U(1), // C900 + 0, // vRef = ground + 1 // gain +}; + +static DISCRETE_SOUND_START(spcenctr_discrete) + + /************************************************ + * Input register mapping + ************************************************/ + DISCRETE_INPUTX_LOGIC(SPCENCTR_ENEMY_SHIP_SHOT_EN, 12, 0, 0) + DISCRETE_INPUTX_LOGIC(SPCENCTR_PLAYER_SHOT_EN, 12, 0, 0) + DISCRETE_INPUT_LOGIC (SPCENCTR_SCREECH_EN) + DISCRETE_INPUT_LOGIC (SPCENCTR_CRASH_EN) + DISCRETE_INPUT_LOGIC (SPCENCTR_EXPLOSION_EN) + DISCRETE_INPUT_LOGIC (SPCENCTR_BONUS_EN) + DISCRETE_INPUT_DATA (SPCENCTR_WIND_DATA) + + /************************************************ + * Noise Generator + ************************************************/ + // Noise clock was breadboarded and measured at 7515 + DISCRETE_LFSR_NOISE(SPCENCTR_NOISE, // IC A0, pin 10 + 1, // ENAB + 1, // no RESET + 7515, // CLK in Hz + 12, // p-p AMPL + 0, // no FEED input + 12.0/2, // dc BIAS + &midway_lfsr) + + /************************************************ + * Enemy Ship Shot + ************************************************/ + DISCRETE_OP_AMP(NODE_20, // IC E1, pin 10 + 1, // ENAB + 0, // no IN0 + SPCENCTR_ENEMY_SHIP_SHOT_EN, // IN1 + &spcenctr_enemy_ship_shot_op_amp_E1) + DISCRETE_OP_AMP_VCO1(NODE_21, // IC D1, pin 5 + 1, // ENAB + NODE_20, // VMOD1 + &spcenctr_enemy_ship_shot_op_amp_osc) + DISCRETE_OP_AMP(NODE_22, // IC D1, pin 9 + 1, // ENAB + NODE_21, // IN0 + NODE_20, // IN1 + &spcenctr_enemy_ship_shot_op_amp_D1) + DISCRETE_OP_AMP_FILTER(NODE_23, // IC D1, pin 10 + 1, // ENAB + NODE_22, // INP0 + 0, // no INP1 + DISC_OP_AMP_FILTER_IS_BAND_PASS_1M | DISC_OP_AMP_IS_NORTON, + &spcenctr_enemy_ship_shot_filt) + DISCRETE_CRFILTER(SPCENCTR_ENEMY_SHIP_SHOT_SND, + NODE_23, // IN0 + RES_K(1.8), // R116 + CAP_U(0.1) ) // C104 + + /************************************************ + * Player Shot + ************************************************/ + DISCRETE_OP_AMP_ONESHOT(NODE_30, // IC E1, pin 4 + SPCENCTR_PLAYER_SHOT_EN, // TRIG + &spcenctr_player_shot_1sht) // breadboarded and scoped at 325mS + DISCRETE_OP_AMP(NODE_31, // IC E1, pin 5 + 1, // ENAB + 0, // no IN0 + NODE_30, // IN1 + &spcenctr_player_shot_op_amp_E1) + // next 2 modules simulate the D502 voltage drop + DISCRETE_ADDER2(NODE_32, + 1, // ENAB + NODE_31, // IN0 + -0.5) // IN1 + DISCRETE_CLAMP(NODE_33, + NODE_32, // IN0 + 0, // MIN + 12) // MAX + DISCRETE_CRFILTER(NODE_34, + SPCENCTR_NOISE, // IN0 + RES_M(1) + RES_K(330), // R507, R509 + CAP_U(0.1) ) // C503 + DISCRETE_GAIN(NODE_35, + NODE_34, // IN0 + RES_K(330)/(RES_M(1) + RES_K(330))) // GAIN - R507 : R509 + DISCRETE_OP_AMP_VCO2(NODE_36, // IC C1, pin 4 + 1, // ENAB + NODE_35, // VMOD1 + NODE_33, // VMOD2 + &spcenctr_player_shot_op_amp_osc) + DISCRETE_OP_AMP(NODE_37, // IC C1, pin 9 + 1, // ENAB + NODE_36, // IN0 + NODE_33, // IN1 + &spcenctr_player_shot_op_amp_C1) + DISCRETE_OP_AMP_TRIG_VCA(SPCENCTR_PLAYER_SHOT_SND, // IC C1, pin 10 + SPCENCTR_PLAYER_SHOT_EN, // TRG0 + 0, // no TRG1 + 0, // no TRG2 + NODE_37, // IN0 + 0, // no IN1 + &spcenctr_player_shot_tvca) + + /************************************************ + *Screech - unemulated + ************************************************/ + DISCRETE_CONSTANT(SPCENCTR_SCREECH_SND, 0) + + /************************************************ + * Crash + ************************************************/ + DISCRETE_OP_AMP_TRIG_VCA(NODE_60, // IC C2, pin 4 + SPCENCTR_CRASH_EN, // TRG0 + 0, // no TRG1 + 0, // no TRG2 + SPCENCTR_NOISE, // IN0 + 0, // no IN1 + &spcenctr_crash_tvca) + // The next 5 modules emulate the filter. + // The DC level was breadboarded and the frequency response was SPICEd + DISCRETE_ADDER2(NODE_61, // center on filter DC level + 1, // ENAB + NODE_60, // IN0 + -6.8) // IN1 + DISCRETE_FILTER2(NODE_62, + 1, // ENAB + NODE_61, // INP0 + 130, // FREQ + 1.0 / 8, // DAMP + DISC_FILTER_BANDPASS) + DISCRETE_GAIN(NODE_63, + NODE_62, // IN0 + 6) // GAIN + DISCRETE_ADDER2(NODE_64, // center on filter DC level + 1, // ENAB + NODE_63, // IN0 + 6.8) // IN1 + DISCRETE_CLAMP(SPCENCTR_CRASH_SND, // IC C2, pin 5 + NODE_64, // IN0 + 0, // MIN + 12.0 - OP_AMP_NORTON_VBE) // MAX + + /************************************************ + * Explosion + ************************************************/ + DISCRETE_OP_AMP_TRIG_VCA(NODE_70, // IC D2, pin 10 + SPCENCTR_EXPLOSION_EN, // TRG0 + 0, // no TRG1 + 0, // no TRG2 + SPCENCTR_NOISE, // IN0 + 0, // no IN1 + &spcenctr_explosion_tvca) + DISCRETE_RCFILTER(NODE_71, + NODE_70, // IN0 + RES_K(1.8), // R405 + CAP_U(0.22) ) // C401 + DISCRETE_RCFILTER(SPCENCTR_EXPLOSION_SND, + NODE_71, // IN0 + RES_K(1.8) + RES_K(3.6), // R405 + R406 + CAP_U(0.22) ) // C402 + + /************************************************ + *Bonus + ************************************************/ + DISCRETE_555_ASTABLE(NODE_80, // pin 5 + // the pin 4 reset is not connected in schematic, but should be + SPCENCTR_BONUS_EN, // RESET + RES_K(1), // R710 + RES_K(27), // R711 + CAP_U(0.047), // C710 + &spcenctr_555_bonus) + DISCRETE_555_ASTABLE(NODE_81, // pin 9 + SPCENCTR_BONUS_EN, // RESET pin 10 + RES_K(100), // R713 + RES_K(47), // R714 + CAP_U(1), // C713 + &spcenctr_555_bonus) + DISCRETE_LOGIC_AND3(NODE_82, // IC C-D, pin 6 + NODE_80, // INP0 + NODE_81, // INP1 + SPCENCTR_BONUS_EN) // INP2 + DISCRETE_GAIN(SPCENCTR_BONUS_SND, // adjust from logic to TTL voltage level + NODE_82, // IN0 + DEFAULT_TTL_V_LOGIC_1) // GAIN + + /************************************************ + *Wind - unemulated + ************************************************/ + DISCRETE_CONSTANT(SPCENCTR_WIND_SND, 0) + + /************************************************ + * Final mix + ************************************************/ + DISCRETE_MIXER7(NODE_91, + 1, // ENAB + SPCENCTR_ENEMY_SHIP_SHOT_SND, // IN0 + SPCENCTR_PLAYER_SHOT_SND, // IN1 + SPCENCTR_SCREECH_SND, // IN2 + SPCENCTR_CRASH_SND, // IN3 + SPCENCTR_EXPLOSION_SND, // IN4 + SPCENCTR_BONUS_SND, // IN5 + SPCENCTR_WIND_SND, // IN6 + &spcenctr_mixer) + + DISCRETE_OUTPUT(NODE_91, 20000) +DISCRETE_SOUND_END + +spcenctr_audio_device::spcenctr_audio_device(machine_config const &mconfig, char const *tag, device_t *owner, u32 clock) : + device_t(mconfig, SPCENCTR_AUDIO, tag, owner, clock), + m_sn(*this, "snsnd"), + m_discrete(*this, "discrete"), + m_lamp(*this, "LAMP"), + m_strobe(*this, "STROBE"), + m_strobe_timer(nullptr), + m_strobe_enable(0U) +{ +} + +void spcenctr_audio_device::p1_w(u8 data) +{ + machine().sound().system_enable(BIT(data, 0)); + + // D1 is marked as 'OPTIONAL SWITCH VIDEO FOR COCKTAIL', but it is never set by the software + + m_discrete->write(SPCENCTR_CRASH_EN, BIT(data, 2)); + + // D3-D7 are not connected +} + +void spcenctr_audio_device::p2_w(u8 data) +{ + // set WIND SOUND FREQ(data & 0x0f) 0, if no wind + + m_discrete->write(SPCENCTR_EXPLOSION_EN, BIT(data, 4)); + m_discrete->write(SPCENCTR_PLAYER_SHOT_EN, BIT(data, 5)); + + // D6 and D7 are not connected +} + + +void spcenctr_audio_device::p3_w(u8 data) +{ + // if (data & 0x01) enable SCREECH (hit the sides) sound + + m_discrete->write(SPCENCTR_ENEMY_SHIP_SHOT_EN, BIT(data, 1)); + + m_strobe_enable = BIT(data, 2); + + m_lamp = BIT(data, 3); + + m_discrete->write(SPCENCTR_BONUS_EN, BIT(data, 4)); + + m_sn->enable_w(BIT(data, 5)); + + // D6 and D7 are not connected +} + +void spcenctr_audio_device::device_add_mconfig(machine_config &config) +{ + SPEAKER(config, "mono").front_center(); + + SN76477(config, m_sn); + m_sn->set_noise_params(0, 0, 0); + m_sn->set_decay_res(0); + m_sn->set_attack_params(0, RES_K(100)); + m_sn->set_amp_res(RES_K(56)); + m_sn->set_feedback_res(RES_K(10)); + m_sn->set_vco_params(0, CAP_U(0.047), RES_K(56)); + m_sn->set_pitch_voltage(5.0); + m_sn->set_slf_params(CAP_U(1.0), RES_K(150)); + m_sn->set_oneshot_params(0, 0); + m_sn->set_vco_mode(1); + m_sn->set_mixer_params(0, 0, 0); + m_sn->set_envelope_params(1, 0); + m_sn->set_enable(1); + m_sn->add_route(ALL_OUTPUTS, "mono", 0.20); - m_port_1_last = data; + DISCRETE(config, m_discrete, spcenctr_discrete); + m_discrete->add_route(ALL_OUTPUTS, "mono", 0.45); +} + +void spcenctr_audio_device::device_start() +{ + m_lamp.resolve(); + m_strobe.resolve(); + + m_strobe_timer = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(spcenctr_audio_device::strobe_callback), this)); + + m_strobe_enable = 0U; + + save_item(NAME(m_strobe_enable)); + + strobe_callback(nullptr, 0U); } +TIMER_CALLBACK_MEMBER(spcenctr_audio_device::strobe_callback) +{ + constexpr double STROBE_FREQ = 9.00; // Hz - calculated from the 555 timer + constexpr u32 STROBE_DUTY_CYCLE = 95; // % + + m_strobe = (param && m_strobe_enable) ? 1 : 0; + m_strobe_timer->adjust( + attotime::from_hz(STROBE_FREQ) * (param ? (100 - STROBE_DUTY_CYCLE) : STROBE_DUTY_CYCLE) / 100, + param ? 0 : 1); +} /************************************* * - * Gun Fight + * M-4 * *************************************/ -static const char *const gunfight_sample_names[] = +// Noise clock was breadboarded and measured at 3760Hz + +m4_audio_device::m4_audio_device(machine_config const &mconfig, char const *tag, device_t *owner, u32 clock) : + device_t(mconfig, M4_AUDIO, tag, owner, clock), + m_samples(*this, "samples%u", 1U), + m_p1(0U), + m_p2(0U) { - "*gunfight", - "gunshot", - "killed", - nullptr -}; +} + +void m4_audio_device::p1_w(u8 data) +{ + u8 const rising(data & ~m_p1); + m_p1 = data; + // D0 and D1 are not connected -void mw8080bw_state::gunfight_audio(machine_config &config) + machine().bookkeeping().coin_counter_w(0, BIT(data, 2)); + + machine().sound().system_enable(BIT(data, 3)); + + if (BIT(rising, 4)) m_samples[0]->start(0, 0); // LEFT PLAYER SHOT sound (goes to left speaker) + if (BIT(rising, 5)) m_samples[1]->start(0, 0); // RIGHT PLAYER SHOT sound (goes to right speaker) + if (BIT(rising, 6)) m_samples[0]->start(1, 1); // LEFT PLAYER EXPLOSION sound via 300K res (goes to left speaker) + if (BIT(rising, 7)) m_samples[1]->start(1, 1); // RIGHT PLAYER EXPLOSION sound via 300K res (goes to right speaker) +} + + +void m4_audio_device::p2_w(u8 data) +{ + u8 const rising(data & ~m_p2); + m_p2 = data; + + if (BIT(rising, 0)) m_samples[0]->start(1, 1); // LEFT PLAYER EXPLOSION sound via 510K res (goes to left speaker) + if (BIT(rising, 1)) m_samples[1]->start(1, 1); // RIGHT PLAYER EXPLOSION sound via 510K res (goes to right speaker) + + // if (data & 0x04) enable LEFT TANK MOTOR sound (goes to left speaker) + + // if (data & 0x08) enable RIGHT TANK MOTOR sound (goes to right speaker) + + // if (data & 0x10) enable sound that is playing while the right plane is flying. Circuit not named on schematics (goes to left speaker) + + // if (data & 0x20) enable sound that is playing while the left plane is flying. Circuit not named on schematics (goes to right speaker) + + // D6 and D7 are not connected +} + +void m4_audio_device::device_add_mconfig(machine_config &config) { - MCFG_SOUND_START_OVERRIDE(mw8080bw_state, samples) + static char const *const sample_names[] = { + "*m4", + "1", // missle + "2", // explosion + nullptr }; SPEAKER(config, "lspeaker").front_left(); SPEAKER(config, "rspeaker").front_right(); - SAMPLES(config, m_samples1); - m_samples1->set_channels(1); - m_samples1->set_samples_names(gunfight_sample_names); - m_samples1->add_route(ALL_OUTPUTS, "lspeaker", 0.50); + SAMPLES(config, m_samples[0]); + m_samples[0]->set_channels(2); + m_samples[0]->set_samples_names(sample_names); + m_samples[0]->add_route(ALL_OUTPUTS, "lspeaker", 1.0); + + SAMPLES(config, m_samples[1]); + m_samples[1]->set_channels(2); + m_samples[1]->set_samples_names(sample_names); + m_samples[1]->add_route(ALL_OUTPUTS, "rspeaker", 1.0); +} + +void m4_audio_device::device_start() +{ + m_p1 = 0U; + m_p2 = 0U; - SAMPLES(config, m_samples2); - m_samples2->set_channels(1); - m_samples2->set_samples_names(gunfight_sample_names); - m_samples2->add_route(ALL_OUTPUTS, "rspeaker", 0.50); + save_item(NAME(m_p1)); + save_item(NAME(m_p2)); } -WRITE8_MEMBER(mw8080bw_state::gunfight_audio_w) +/************************************* + * + * Phantom II + * + *************************************/ + +phantom2_audio_device::phantom2_audio_device(machine_config const &mconfig, char const *tag, device_t *owner, u32 clock) : + device_t(mconfig, PHANTOM2_AUDIO, tag, owner, clock), + m_samples(*this, "samples"), + m_exp(*this, "EXPLAMP"), + m_p1(0U), + m_p2(0U) { - /* D0 and D1 are just tied to 1k resistors */ +} - machine().bookkeeping().coin_counter_w(0, (data >> 2) & 0x01); +void phantom2_audio_device::p1_w(u8 data) +{ + u8 const rising(data & ~m_p1); + m_p1 = data; - /* the 74175 latches and inverts the top 4 bits */ - switch ((~data >> 4) & 0x0f) - { - case 0x00: - break; + if (BIT(rising, 0)) m_samples->start(0, 0); // PLAYER SHOT sound - case 0x01: - /* enable LEFT SHOOT sound (left speaker) */ - m_samples1->start(0, 0); - break; + // if (data & 0x02) enable ENEMY SHOT sound - case 0x02: - /* enable RIGHT SHOOT sound (right speaker) */ - m_samples2->start(0, 0); - break; + machine().sound().system_mute(!BIT(data, 5)); + machine().sound().system_enable(BIT(data, 2)); - case 0x03: - /* enable LEFT HIT sound (left speaker) */ - m_samples1->start(0, 1); - break; + machine().bookkeeping().coin_counter_w(0, BIT(data, 3)); - case 0x04: - /* enable RIGHT HIT sound (right speaker) */ - m_samples2->start(0, 1); - break; + // if (data & 0x10) enable RADAR sound - default: - logerror("%04x: Unknown sh port write %02x\n", m_maincpu->pc(), data); - break; - } + // D5-D7 are not connected } +void phantom2_audio_device::p2_w(u8 data) +{ + u8 const rising(data & ~m_p2); + m_p2 = data; + + // D0-D2 are not connected + + if (BIT(rising, 3)) m_samples->start(1, 1); // enable EXPLOSION sound + + m_exp = BIT(data, 4); + + // set JET SOUND FREQ((data >> 5) & 0x07) 0, if no jet sound +} + +void phantom2_audio_device::device_add_mconfig(machine_config &config) +{ + static char const *const sample_names[] = { + "*phantom2", + "1", // shot + "2", // explosion + nullptr }; + + SPEAKER(config, "mono").front_center(); + + SAMPLES(config, m_samples); + m_samples->set_channels(2); + m_samples->set_samples_names(sample_names); + m_samples->add_route(ALL_OUTPUTS, "mono", 1.0); +} + +void phantom2_audio_device::device_start() +{ + m_exp.resolve(); + + m_p1 = 0U; + m_p2 = 0U; + + save_item(NAME(m_p1)); + save_item(NAME(m_p2)); +} + + +/************************************* + * + * Audio setup + * + *************************************/ + +WRITE8_MEMBER(mw8080bw_state::midway_tone_generator_lo_w) +{ + m_discrete->write(MIDWAY_TONE_EN, (data >> 0) & 0x01); + + m_discrete->write(MIDWAY_TONE_DATA_L, (data >> 1) & 0x1f); + + /* D6 and D7 are not connected */ +} + + +WRITE8_MEMBER(mw8080bw_state::midway_tone_generator_hi_w) +{ + m_discrete->write(MIDWAY_TONE_DATA_H, data & 0x3f); + + /* D6 and D7 are not connected */ +} /************************************* @@ -1539,421 +2594,6 @@ WRITE8_MEMBER(mw8080bw_state::dplay_audio_w) /************************************* * - * Guided Missile - * - *************************************/ - -static const char *const gmissile_sample_names[] = -{ - "*gmissile", - "1", /* missle */ - "2", /* explosion */ - nullptr -}; - -void mw8080bw_state::gmissile_audio(machine_config &config) -{ - MCFG_SOUND_START_OVERRIDE(mw8080bw_state, samples) - - SPEAKER(config, "lspeaker").front_left(); - SPEAKER(config, "rspeaker").front_right(); - - SAMPLES(config, m_samples1); - m_samples1->set_channels(1); - m_samples1->set_samples_names(gmissile_sample_names); - m_samples1->add_route(ALL_OUTPUTS, "lspeaker", 1.0); - - SAMPLES(config, m_samples2); - m_samples2->set_channels(1); - m_samples2->set_samples_names(gmissile_sample_names); - m_samples2->add_route(ALL_OUTPUTS, "rspeaker", 1.0); -} - - -WRITE8_MEMBER(mw8080bw_state::gmissile_audio_1_w) -{ - /* note that the schematics shows the left and right explosions - reversed (D5=R, D7=L), but the software confirms that - ours is right */ - - uint8_t rising_bits = data & ~m_port_1_last; - - /* D0 and D1 are not connected */ - - machine().bookkeeping().coin_counter_w(0, (data >> 2) & 0x01); - - machine().sound().system_enable((data >> 3) & 0x01); - - /* if (data & 0x10) enable RIGHT MISSILE sound (goes to right speaker) */ - if (rising_bits & 0x10) m_samples2->start(0, 0); - - /* if (data & 0x20) enable LEFT EXPLOSION sound (goes to left speaker) */ - output().set_value("L_EXP_LIGHT", (data >> 5) & 0x01); - if (rising_bits & 0x20) m_samples1->start(0, 1); - - /* if (data & 0x40) enable LEFT MISSILE sound (goes to left speaker) */ - if (rising_bits & 0x40) m_samples1->start(0, 0); - - /* if (data & 0x80) enable RIGHT EXPLOSION sound (goes to right speaker) */ - output().set_value("R_EXP_LIGHT", (data >> 7) & 0x01); - if (rising_bits & 0x80) m_samples2->start(0, 1); - - m_port_1_last = data; -} - - -WRITE8_MEMBER(mw8080bw_state::gmissile_audio_2_w) -{ - /* set AIRPLANE/COPTER/JET PAN(data & 0x07) */ - - /* set TANK PAN((data >> 3) & 0x07) */ - - /* D6 and D7 are not connected */ -} - - -WRITE8_MEMBER(mw8080bw_state::gmissile_audio_3_w) -{ - /* if (data & 0x01) enable AIRPLANE (bi-plane) sound (goes to AIRPLANE/COPTER/JET panning circuit) */ - - /* if (data & 0x02) enable TANK sound (goes to TANK panning circuit) */ - - /* if (data & 0x04) enable COPTER sound (goes to AIRPLANE/COPTER/JET panning circuit) */ - - /* D3 and D4 are not connected */ - - /* if (data & 0x20) enable JET (3 fighter jets) sound (goes to AIRPLANE/COPTER/JET panning circuit) */ - - /* D6 and D7 are not connected */ -} - - - -/************************************* - * - * M-4 - * - *************************************/ - -/* Noise clock was breadboarded and measured at 3760Hz */ - -static const char *const m4_sample_names[] = -{ - "*m4", - "1", /* missle */ - "2", /* explosion */ - nullptr -}; - - -void mw8080bw_state::m4_audio(machine_config &config) -{ - MCFG_SOUND_START_OVERRIDE(mw8080bw_state, samples) - - SPEAKER(config, "lspeaker").front_left(); - SPEAKER(config, "rspeaker").front_right(); - - SAMPLES(config, m_samples1); - m_samples1->set_channels(2); - m_samples1->set_samples_names(m4_sample_names); - m_samples1->add_route(ALL_OUTPUTS, "lspeaker", 1); - - SAMPLES(config, m_samples2); - m_samples2->set_channels(2); - m_samples2->set_samples_names(m4_sample_names); - m_samples2->add_route(ALL_OUTPUTS, "rspeaker", 1); -} - - -WRITE8_MEMBER(mw8080bw_state::m4_audio_1_w) -{ - uint8_t rising_bits = data & ~m_port_1_last; - - /* D0 and D1 are not connected */ - - machine().bookkeeping().coin_counter_w(0, (data >> 2) & 0x01); - - machine().sound().system_enable((data >> 3) & 0x01); - - /* if (data & 0x10) enable LEFT PLAYER SHOT sound (goes to left speaker) */ - if (rising_bits & 0x10) m_samples1->start(0, 0); - - /* if (data & 0x20) enable RIGHT PLAYER SHOT sound (goes to right speaker) */ - if (rising_bits & 0x20) m_samples2->start(0, 0); - - /* if (data & 0x40) enable LEFT PLAYER EXPLOSION sound via 300K res (goes to left speaker) */ - if (rising_bits & 0x40) m_samples1->start(1, 1); - - /* if (data & 0x80) enable RIGHT PLAYER EXPLOSION sound via 300K res (goes to right speaker) */ - if (rising_bits & 0x80) m_samples2->start(1, 1); - - m_port_1_last = data; -} - - -WRITE8_MEMBER(mw8080bw_state::m4_audio_2_w) -{ - uint8_t rising_bits = data & ~m_port_2_last; - - /* if (data & 0x01) enable LEFT PLAYER EXPLOSION sound via 510K res (goes to left speaker) */ - if (rising_bits & 0x01) m_samples1->start(1, 1); - - /* if (data & 0x02) enable RIGHT PLAYER EXPLOSION sound via 510K res (goes to right speaker) */ - if (rising_bits & 0x02) m_samples2->start(1, 1); - - /* if (data & 0x04) enable LEFT TANK MOTOR sound (goes to left speaker) */ - - /* if (data & 0x08) enable RIGHT TANK MOTOR sound (goes to right speaker) */ - - /* if (data & 0x10) enable sound that is playing while the right plane is - flying. Circuit not named on schematics (goes to left speaker) */ - - /* if (data & 0x20) enable sound that is playing while the left plane is - flying. Circuit not named on schematics (goes to right speaker) */ - - /* D6 and D7 are not connected */ - - m_port_2_last = data; -} - - - -/************************************* - * - * Clowns - * - * Discrete sound emulation: Mar 2005, D.R. - * - *************************************/ - -/* nodes - inputs */ -#define CLOWNS_POP_BOTTOM_EN NODE_01 -#define CLOWNS_POP_MIDDLE_EN NODE_02 -#define CLOWNS_POP_TOP_EN NODE_03 -#define CLOWNS_SPRINGBOARD_HIT_EN NODE_04 -#define CLOWNS_SPRINGBOARD_MISS_EN NODE_05 - -/* nodes - sounds */ -#define CLOWNS_NOISE NODE_06 -#define CLOWNS_POP_SND NODE_07 -#define CLOWNS_SB_HIT_SND NODE_08 -#define CLOWNS_SB_MISS_SND NODE_09 - -/* nodes - adjusters */ -#define CLOWNS_R507_POT NODE_11 - - -static const discrete_op_amp_tvca_info clowns_pop_tvca_info = -{ - RES_M(2.7), /* r304 */ - RES_K(680), /* r303 */ - 0, - RES_K(680), /* r305 */ - RES_K(1), /* j3 */ - 0, - RES_K(470), /* r300 */ - RES_K(1), /* j3 */ - RES_K(510), /* r301 */ - RES_K(1), /* j3 */ - RES_K(680), /* r302 */ - CAP_U(.015), /* c300 */ - CAP_U(.1), /* c301 */ - CAP_U(.082), /* c302 */ - 0, /* no c4 */ - 5, /* v1 */ - 5, /* v2 */ - 5, /* v3 */ - 12, /* vP */ - DISC_OP_AMP_TRIGGER_FUNCTION_NONE, - DISC_OP_AMP_TRIGGER_FUNCTION_NONE, - DISC_OP_AMP_TRIGGER_FUNCTION_TRG0, - DISC_OP_AMP_TRIGGER_FUNCTION_NONE, - DISC_OP_AMP_TRIGGER_FUNCTION_TRG1, - DISC_OP_AMP_TRIGGER_FUNCTION_TRG2 -}; - - -static const discrete_op_amp_osc_info clowns_sb_hit_osc_info = -{ - DISC_OP_AMP_OSCILLATOR_1 | DISC_OP_AMP_IS_NORTON | DISC_OP_AMP_OSCILLATOR_OUT_SQW, - RES_K(820), /* r200 */ - RES_K(33), /* r203 */ - RES_K(150), /* r201 */ - RES_K(240), /* r204 */ - RES_M(1), /* r202 */ - 0, - 0, - 0, - CAP_U(0.01), /* c200 */ - 12 -}; - - -static const discrete_op_amp_tvca_info clowns_sb_hit_tvca_info = -{ - RES_M(2.7), /* r207 */ - RES_K(680), /* r205 */ - 0, - RES_K(680), /* r208 */ - RES_K(1), /* j3 */ - 0, - RES_K(680), /* r206 */ - 0,0,0,0, - CAP_U(1), /* c201 */ - 0, - 0, 0, - 5, /* v1 */ - 0, /* v2 */ - 0, /* v3 */ - 12, /* vP */ - DISC_OP_AMP_TRIGGER_FUNCTION_NONE, - DISC_OP_AMP_TRIGGER_FUNCTION_NONE, - DISC_OP_AMP_TRIGGER_FUNCTION_TRG0, - DISC_OP_AMP_TRIGGER_FUNCTION_NONE, - DISC_OP_AMP_TRIGGER_FUNCTION_NONE, - DISC_OP_AMP_TRIGGER_FUNCTION_NONE -}; - - -static const discrete_mixer_desc clowns_mixer = -{ - DISC_MIXER_IS_OP_AMP, - { RES_K(10), - RES_K(10), - RES_K(10) + 1.0 / (1.0 / RES_K(15) + 1.0 / RES_K(39)), - RES_K(1) }, - { 0, - 0, - 0, - CLOWNS_R507_POT }, - { 0, - CAP_U(0.022), - 0, - 0 }, - 0, - RES_K(100), - 0, - CAP_U(1), - 0, - 1 -}; - - -static DISCRETE_SOUND_START(clowns_discrete) - - /************************************************ - * Input register mapping - ************************************************/ - DISCRETE_INPUT_LOGIC(CLOWNS_POP_BOTTOM_EN) - DISCRETE_INPUT_LOGIC(CLOWNS_POP_MIDDLE_EN) - DISCRETE_INPUT_LOGIC(CLOWNS_POP_TOP_EN) - DISCRETE_INPUT_LOGIC(CLOWNS_SPRINGBOARD_HIT_EN) - DISCRETE_INPUT_LOGIC(CLOWNS_SPRINGBOARD_MISS_EN) - - /* The low value of the pot is set to 7000. A real 1M pot will never go to 0 anyways. */ - /* This will give the control more apparent volume range. */ - /* The music way overpowers the rest of the sounds anyways. */ - DISCRETE_ADJUSTMENT(CLOWNS_R507_POT, RES_M(1), 7000, DISC_LOGADJ, "R507") - - /************************************************ - * Tone generator - ************************************************/ - MIDWAY_TONE_GENERATOR(midway_music_tvca_info) - - /************************************************ - * Balloon hit sounds - * The LFSR is the same as boothill - ************************************************/ - /* Noise clock was breadboarded and measured at 7700Hz */ - DISCRETE_LFSR_NOISE(CLOWNS_NOISE, 1, 1, 7700, 12.0, 0, 12.0/2, &midway_lfsr) - - DISCRETE_OP_AMP_TRIG_VCA(NODE_30, CLOWNS_POP_TOP_EN, CLOWNS_POP_MIDDLE_EN, CLOWNS_POP_BOTTOM_EN, CLOWNS_NOISE, 0, &clowns_pop_tvca_info) - DISCRETE_RCFILTER(NODE_31, NODE_30, RES_K(15), CAP_U(.01)) - DISCRETE_CRFILTER(NODE_32, NODE_31, RES_K(15) + RES_K(39), CAP_U(.01)) - DISCRETE_GAIN(CLOWNS_POP_SND, NODE_32, RES_K(39)/(RES_K(15) + RES_K(39))) - - /************************************************ - * Springboard hit - ************************************************/ - DISCRETE_OP_AMP_OSCILLATOR(NODE_40, 1, &clowns_sb_hit_osc_info) - DISCRETE_OP_AMP_TRIG_VCA(NODE_41, CLOWNS_SPRINGBOARD_HIT_EN, 0, 0, NODE_40, 0, &clowns_sb_hit_tvca_info) - /* The rest of the circuit is a filter. The frequency response was calculated with SPICE. */ - DISCRETE_FILTER2(NODE_42, 1, NODE_41, 500, 1.0/.8, DISC_FILTER_LOWPASS) - /* The filter has a gain of 0.5 */ - DISCRETE_GAIN(CLOWNS_SB_HIT_SND, NODE_42, 0.5) - - /************************************************ - * Springboard miss - INCOMPLETE - ************************************************/ - DISCRETE_CONSTANT(CLOWNS_SB_MISS_SND, 0) /* Placeholder for incomplete sound */ - - /************************************************ - * Combine all sound sources. - ************************************************/ - DISCRETE_MIXER4(NODE_91, 1, CLOWNS_SB_HIT_SND, CLOWNS_SB_MISS_SND, CLOWNS_POP_SND, MIDWAY_TONE_SND, &clowns_mixer) - - DISCRETE_OUTPUT(NODE_91, 11000) -DISCRETE_SOUND_END - - -static const char *const clowns_sample_names[] = -{ - "*clowns", - "miss", - nullptr -}; - -void mw8080bw_state::clowns_audio(machine_config &config) -{ - MCFG_SOUND_START_OVERRIDE(mw8080bw_state, samples) - - SPEAKER(config, "mono").front_center(); - - SAMPLES(config, m_samples); - m_samples->set_channels(1); - m_samples->set_samples_names(clowns_sample_names); - m_samples->add_route(ALL_OUTPUTS, "mono", 0.70); - - DISCRETE(config, m_discrete, clowns_discrete); - m_discrete->add_route(ALL_OUTPUTS, "mono", 0.25); -} - - -WRITE8_MEMBER(mw8080bw_state::clowns_audio_1_w) -{ - machine().bookkeeping().coin_counter_w(0, (data >> 0) & 0x01); - - m_clowns_controller_select = (data >> 1) & 0x01; - - /* D2-D7 are not connected */ -} - - -WRITE8_MEMBER(mw8080bw_state::clowns_audio_2_w) -{ - uint8_t rising_bits = data & ~m_port_2_last; - - m_discrete->write(CLOWNS_POP_BOTTOM_EN, (data >> 0) & 0x01); - - m_discrete->write(CLOWNS_POP_MIDDLE_EN, (data >> 1) & 0x01); - - m_discrete->write(CLOWNS_POP_TOP_EN, (data >> 2) & 0x01); - - machine().sound().system_enable((data >> 3) & 0x01); - - m_discrete->write(CLOWNS_SPRINGBOARD_HIT_EN, (data >> 4) & 0x01); - - if (rising_bits & 0x20) m_samples->start(0, 0); /* springboard miss */ - - /* D6 and D7 are not connected */ - - m_port_2_last = data; -} - - - -/************************************* - * * Space Walk * * Discrete sound emulation: Oct 2009, D.R. @@ -2715,622 +3355,6 @@ WRITE8_MEMBER(mw8080bw_state::dogpatch_audio_w) /************************************* * - * Space Encounters - * - * Discrete sound emulation: - * Apr 2007, D.R. - *************************************/ - -/* nodes - inputs */ -#define SPCENCTR_ENEMY_SHIP_SHOT_EN NODE_01 -#define SPCENCTR_PLAYER_SHOT_EN NODE_02 -#define SPCENCTR_SCREECH_EN NODE_03 -#define SPCENCTR_CRASH_EN NODE_04 -#define SPCENCTR_EXPLOSION_EN NODE_05 -#define SPCENCTR_BONUS_EN NODE_06 -#define SPCENCTR_WIND_DATA NODE_07 - -/* nodes - sounds */ -#define SPCENCTR_NOISE NODE_10 -#define SPCENCTR_ENEMY_SHIP_SHOT_SND NODE_11 -#define SPCENCTR_PLAYER_SHOT_SND NODE_12 -#define SPCENCTR_SCREECH_SND NODE_13 -#define SPCENCTR_CRASH_SND NODE_14 -#define SPCENCTR_EXPLOSION_SND NODE_15 -#define SPCENCTR_BONUS_SND NODE_16 -#define SPCENCTR_WIND_SND NODE_17 - - -static const discrete_op_amp_info spcenctr_enemy_ship_shot_op_amp_E1 = -{ - DISC_OP_AMP_IS_NORTON, - 0, /* no r1 */ - RES_K(510), /* R100 */ - RES_M(2.2), /* R101 */ - RES_M(2.2), /* R102 */ - CAP_U(0.1), /* C100 */ - 0, /* vN */ - 12 /* vP */ -}; - - -static const discrete_op_amp_osc_info spcenctr_enemy_ship_shot_op_amp_osc = -{ - DISC_OP_AMP_OSCILLATOR_VCO_3 | DISC_OP_AMP_IS_NORTON | DISC_OP_AMP_OSCILLATOR_OUT_SQW, - RES_K(560), /* R103 */ - RES_K(7.5), /* R118 */ - RES_K(22), /* R104 */ - RES_K(47), /* R106 */ - RES_K(100), /* R105 */ - 0, /* no r6 */ - 0, /* no r7 */ - 0, /* no r8 */ - CAP_U(0.0022), /* C101 */ - 12, /* vP */ -}; - - -static const discrete_op_amp_info spcenctr_enemy_ship_shot_op_amp_D1 = -{ - DISC_OP_AMP_IS_NORTON, - RES_K(100), /* R107 */ - RES_K(100), /* R109 */ - RES_M(2.7), /* R108 */ - RES_K(100), /* R110 */ - 0, /* no c */ - 0, /* vN */ - 12 /* vP */ -}; - - -static const discrete_op_amp_filt_info spcenctr_enemy_ship_shot_filt = -{ - RES_K(100), /* R112 */ - RES_K(10), /* R113 */ - RES_M(4.3), /* r3 */ - 0, /* no r4 */ - RES_M(2.2), /* R114 */ - CAP_U(0.001), /* c1 */ - CAP_U(0.001), /* c2 */ - 0, /* no c3 */ - 0, /* vRef */ - 12, /* vP */ - 0 /* vN */ -}; - - -static const discrete_op_amp_1sht_info spcenctr_player_shot_1sht = -{ - DISC_OP_AMP_1SHT_1 | DISC_OP_AMP_IS_NORTON, - RES_M(4.7), /* R500 */ - RES_K(100), /* R502 */ - RES_M(1), /* R501 */ - RES_M(1), /* R503 */ - RES_M(2.2), /* R504 */ - CAP_U(1), /* C500 */ - CAP_P(470), /* C501 */ - 0, /* vN */ - 12 /* vP */ -}; - - -static const discrete_op_amp_info spcenctr_player_shot_op_amp_E1 = -{ - DISC_OP_AMP_IS_NORTON, - 0, /* no r1 */ - RES_K(10), /* R505 */ - RES_M(1.5), /* R506 */ - 0, /* no r4 */ - CAP_U(0.22), /* C502 */ - 0, /* vN */ - 12 /* vP */ -}; - - -static const discrete_op_amp_osc_info spcenctr_player_shot_op_amp_osc = -{ - DISC_OP_AMP_OSCILLATOR_VCO_3 | DISC_OP_AMP_IS_NORTON | DISC_OP_AMP_OSCILLATOR_OUT_SQW, - 1.0 / (1.0 / RES_M(1) + 1.0 / RES_K(330)) + RES_M(1.5), /* R507||R509 + R508 */ - RES_M(1), /* R513 */ - RES_K(560), /* R512 */ - RES_M(2.7), /* R516 */ - RES_M(1), /* R515 */ - RES_M(4.7), /* R510 */ - RES_M(3.3), /* R511 */ - 0, /* no r8 */ - CAP_P(330), /* C504 */ - 12, /* vP */ -}; - - -static const discrete_op_amp_info spcenctr_player_shot_op_amp_C1 = -{ - DISC_OP_AMP_IS_NORTON, - RES_K(560), /* R517 */ - RES_K(470), /* R514 */ - RES_M(2.7), /* R518 */ - RES_K(560), /* R524 */ - 0, /* no c */ - 0, /* vN */ - 12 /* vP */ -}; - - -static const discrete_op_amp_tvca_info spcenctr_player_shot_tvca = -{ - RES_M(2.7), /* R522 */ - RES_K(560), /* R521 */ - 0, /* no r3 */ - RES_K(560), /* R560 */ - RES_K(1), /* R42 */ - 0, /* no r6 */ - RES_K(560), /* R523 */ - 0, /* no r8 */ - 0, /* no r9 */ - 0, /* no r10 */ - 0, /* no r11 */ - CAP_U(1), /* C506 */ - 0, /* no c2 */ - 0, 0, /* no c3, c4 */ - 12, /* v1 */ - 0, /* no v2 */ - 0, /* no v3 */ - 12, /* vP */ - DISC_OP_AMP_TRIGGER_FUNCTION_NONE, /* no f0 */ - DISC_OP_AMP_TRIGGER_FUNCTION_NONE, /* no f1 */ - DISC_OP_AMP_TRIGGER_FUNCTION_TRG0, /* f2 */ - DISC_OP_AMP_TRIGGER_FUNCTION_NONE, /* no f3 */ - DISC_OP_AMP_TRIGGER_FUNCTION_NONE, /* no f4 */ - DISC_OP_AMP_TRIGGER_FUNCTION_NONE /* no f5 */ -}; - - -static const discrete_op_amp_tvca_info spcenctr_crash_tvca = -{ - RES_M(2.7), /* R302 */ - RES_K(470), /* R300 */ - 0, /* no r3 */ - RES_K(470), /* R303 */ - RES_K(1), /* R56 */ - 0, /* no r6 */ - RES_K(470), /* R301 */ - 0, /* no r8 */ - 0, /* no r9 */ - 0, /* no r10 */ - 0, /* no r11 */ - CAP_U(2.2), /* C304 */ - 0, /* no c2 */ - 0, 0, /* no c3, c4 */ - 5, /* v1 */ - 0, /* no v2 */ - 0, /* no v3 */ - 12, /* vP */ - DISC_OP_AMP_TRIGGER_FUNCTION_NONE, /* no f0 */ - DISC_OP_AMP_TRIGGER_FUNCTION_NONE, /* no f1 */ - DISC_OP_AMP_TRIGGER_FUNCTION_TRG0, /* f2 */ - DISC_OP_AMP_TRIGGER_FUNCTION_NONE, /* no f3 */ - DISC_OP_AMP_TRIGGER_FUNCTION_NONE, /* no f4 */ - DISC_OP_AMP_TRIGGER_FUNCTION_NONE /* no f5 */ -}; - - -static const discrete_op_amp_tvca_info spcenctr_explosion_tvca = -{ - RES_M(2.7), /* R402 */ - RES_K(680), /* R400 */ - 0, /* no r3 */ - RES_K(680), /* R403 */ - RES_K(1), /* R41 */ - 0, /* no r6 */ - RES_K(680), /* R401 */ - 0, /* no r8 */ - 0, /* no r9 */ - 0, /* no r10 */ - 0, /* no r11 */ - CAP_U(2.2), /* C400 */ - 0, /* no c2 */ - 0, 0, /* no c3, c4 */ - 12, /* v1 */ - 0, /* no v2 */ - 0, /* no v3 */ - 12, /* vP */ - DISC_OP_AMP_TRIGGER_FUNCTION_NONE, /* no f0 */ - DISC_OP_AMP_TRIGGER_FUNCTION_NONE, /* no f1 */ - DISC_OP_AMP_TRIGGER_FUNCTION_TRG0, /* f2 */ - DISC_OP_AMP_TRIGGER_FUNCTION_NONE, /* no f3 */ - DISC_OP_AMP_TRIGGER_FUNCTION_NONE, /* no f4 */ - DISC_OP_AMP_TRIGGER_FUNCTION_NONE /* no f5 */ -}; - - -static const discrete_555_desc spcenctr_555_bonus = -{ - DISC_555_OUT_SQW | DISC_555_OUT_DC, - 5, /* B+ voltage of 555 */ - DEFAULT_555_VALUES -}; - - -static const discrete_mixer_desc spcenctr_mixer = -{ - DISC_MIXER_IS_RESISTOR, /* type */ - { RES_K(15), /* R117 */ - RES_K(15), /* R526 */ - RES_K(22), /* R211 */ - RES_K(3.6), /* R309 */ - RES_K(1.8) + RES_K(3.6) + RES_K(4.7), /* R405 + R406 + R407 */ - RES_K(27), /* R715 */ - RES_K(27)}, /* R51 */ - {0}, /* no rNode{} */ - { 0, - CAP_U(0.001), /* C505 */ - CAP_U(0.1), /* C202 */ - CAP_U(1), /* C303 */ - 0, - 0, - CAP_U(10)}, /* C16 */ - 0, /* no rI */ - 0, /* no rF */ - 0, /* no cF */ - CAP_U(1), /* C900 */ - 0, /* vRef = ground */ - 1 /* gain */ -}; - - -static DISCRETE_SOUND_START(spcenctr_discrete) - - /************************************************ - * Input register mapping - ************************************************/ - DISCRETE_INPUTX_LOGIC(SPCENCTR_ENEMY_SHIP_SHOT_EN, 12, 0, 0) - DISCRETE_INPUTX_LOGIC(SPCENCTR_PLAYER_SHOT_EN, 12, 0, 0) - DISCRETE_INPUT_LOGIC (SPCENCTR_SCREECH_EN) - DISCRETE_INPUT_LOGIC (SPCENCTR_CRASH_EN) - DISCRETE_INPUT_LOGIC (SPCENCTR_EXPLOSION_EN) - DISCRETE_INPUT_LOGIC (SPCENCTR_BONUS_EN) - DISCRETE_INPUT_DATA (SPCENCTR_WIND_DATA) - - - /************************************************ - * Noise Generator - ************************************************/ - /* Noise clock was breadboarded and measured at 7515 */ - DISCRETE_LFSR_NOISE(SPCENCTR_NOISE, /* IC A0, pin 10 */ - 1, /* ENAB */ - 1, /* no RESET */ - 7515, /* CLK in Hz */ - 12, /* p-p AMPL */ - 0, /* no FEED input */ - 12.0/2, /* dc BIAS */ - &midway_lfsr) - - - /************************************************ - * Enemy Ship Shot - ************************************************/ - DISCRETE_OP_AMP(NODE_20, /* IC E1, pin 10 */ - 1, /* ENAB */ - 0, /* no IN0 */ - SPCENCTR_ENEMY_SHIP_SHOT_EN, /* IN1 */ - &spcenctr_enemy_ship_shot_op_amp_E1) - DISCRETE_OP_AMP_VCO1(NODE_21, /* IC D1, pin 5 */ - 1, /* ENAB */ - NODE_20, /* VMOD1 */ - &spcenctr_enemy_ship_shot_op_amp_osc) - DISCRETE_OP_AMP(NODE_22, /* IC D1, pin 9 */ - 1, /* ENAB */ - NODE_21, /* IN0 */ - NODE_20, /* IN1 */ - &spcenctr_enemy_ship_shot_op_amp_D1) - DISCRETE_OP_AMP_FILTER(NODE_23, /* IC D1, pin 10 */ - 1, /* ENAB */ - NODE_22, /* INP0 */ - 0, /* no INP1 */ - DISC_OP_AMP_FILTER_IS_BAND_PASS_1M | DISC_OP_AMP_IS_NORTON, - &spcenctr_enemy_ship_shot_filt) - DISCRETE_CRFILTER(SPCENCTR_ENEMY_SHIP_SHOT_SND, - NODE_23, /* IN0 */ - RES_K(1.8), /* R116 */ - CAP_U(0.1) ) /* C104 */ - - - /************************************************ - * Player Shot - ************************************************/ - DISCRETE_OP_AMP_ONESHOT(NODE_30, /* IC E1, pin 4 */ - SPCENCTR_PLAYER_SHOT_EN, /* TRIG */ - &spcenctr_player_shot_1sht) /* breadboarded and scoped at 325mS */ - DISCRETE_OP_AMP(NODE_31, /* IC E1, pin 5 */ - 1, /* ENAB */ - 0, /* no IN0 */ - NODE_30, /* IN1 */ - &spcenctr_player_shot_op_amp_E1) - /* next 2 modules simulate the D502 voltage drop */ - DISCRETE_ADDER2(NODE_32, - 1, /* ENAB */ - NODE_31, /* IN0 */ - -0.5) /* IN1 */ - DISCRETE_CLAMP(NODE_33, - NODE_32, /* IN0 */ - 0, /* MIN */ - 12) /* MAX */ - DISCRETE_CRFILTER(NODE_34, - SPCENCTR_NOISE, /* IN0 */ - RES_M(1) + RES_K(330), /* R507, R509 */ - CAP_U(0.1) ) /* C503 */ - DISCRETE_GAIN(NODE_35, - NODE_34, /* IN0 */ - RES_K(330)/(RES_M(1) + RES_K(330))) /* GAIN - R507 : R509 */ - DISCRETE_OP_AMP_VCO2(NODE_36, /* IC C1, pin 4 */ - 1, /* ENAB */ - NODE_35, /* VMOD1 */ - NODE_33, /* VMOD2 */ - &spcenctr_player_shot_op_amp_osc) - DISCRETE_OP_AMP(NODE_37, /* IC C1, pin 9 */ - 1, /* ENAB */ - NODE_36, /* IN0 */ - NODE_33, /* IN1 */ - &spcenctr_player_shot_op_amp_C1) - DISCRETE_OP_AMP_TRIG_VCA(SPCENCTR_PLAYER_SHOT_SND, /* IC C1, pin 10 */ - SPCENCTR_PLAYER_SHOT_EN, /* TRG0 */ - 0, /* no TRG1 */ - 0, /* no TRG2 */ - NODE_37, /* IN0 */ - 0, /* no IN1 */ - &spcenctr_player_shot_tvca) - - - /************************************************ - *Screech - unemulated - ************************************************/ - DISCRETE_CONSTANT(SPCENCTR_SCREECH_SND, 0) - - - /************************************************ - * Crash - ************************************************/ - DISCRETE_OP_AMP_TRIG_VCA(NODE_60, /* IC C2, pin 4 */ - SPCENCTR_CRASH_EN, /* TRG0 */ - 0, /* no TRG1 */ - 0, /* no TRG2 */ - SPCENCTR_NOISE, /* IN0 */ - 0, /* no IN1 */ - &spcenctr_crash_tvca) - /* The next 5 modules emulate the filter. */ - /* The DC level was breadboarded and the frequency response was SPICEd */ - DISCRETE_ADDER2(NODE_61, /* center on filter DC level */ - 1, /* ENAB */ - NODE_60, /* IN0 */ - -6.8) /* IN1 */ - DISCRETE_FILTER2(NODE_62, - 1, /* ENAB */ - NODE_61, /* INP0 */ - 130, /* FREQ */ - 1.0 / 8, /* DAMP */ - DISC_FILTER_BANDPASS) - DISCRETE_GAIN(NODE_63, - NODE_62, /* IN0 */ - 6) /* GAIN */ - DISCRETE_ADDER2(NODE_64, /* center on filter DC level */ - 1, /* ENAB */ - NODE_63, /* IN0 */ - 6.8) /* IN1 */ - DISCRETE_CLAMP(SPCENCTR_CRASH_SND, /* IC C2, pin 5 */ - NODE_64, /* IN0 */ - 0, /* MIN */ - 12.0 - OP_AMP_NORTON_VBE) /* MAX */ - - - /************************************************ - * Explosion - ************************************************/ - DISCRETE_OP_AMP_TRIG_VCA(NODE_70, /* IC D2, pin 10 */ - SPCENCTR_EXPLOSION_EN, /* TRG0 */ - 0, /* no TRG1 */ - 0, /* no TRG2 */ - SPCENCTR_NOISE, /* IN0 */ - 0, /* no IN1 */ - &spcenctr_explosion_tvca) - DISCRETE_RCFILTER(NODE_71, - NODE_70, /* IN0 */ - RES_K(1.8), /* R405 */ - CAP_U(0.22) ) /* C401 */ - DISCRETE_RCFILTER(SPCENCTR_EXPLOSION_SND, - NODE_71, /* IN0 */ - RES_K(1.8) + RES_K(3.6), /* R405 + R406 */ - CAP_U(0.22) ) /* C402 */ - - - /************************************************ - *Bonus - ************************************************/ - DISCRETE_555_ASTABLE(NODE_80, /* pin 5 */ - /* the pin 4 reset is not connected in schematic, but should be */ - SPCENCTR_BONUS_EN, /* RESET */ - RES_K(1), /* R710 */ - RES_K(27), /* R711 */ - CAP_U(0.047), /* C710 */ - &spcenctr_555_bonus) - DISCRETE_555_ASTABLE(NODE_81, /* pin 9 */ - SPCENCTR_BONUS_EN, /* RESET pin 10 */ - RES_K(100), /* R713 */ - RES_K(47), /* R714 */ - CAP_U(1), /* C713 */ - &spcenctr_555_bonus) - DISCRETE_LOGIC_AND3(NODE_82, /* IC C-D, pin 6 */ - NODE_80, /* INP0 */ - NODE_81, /* INP1 */ - SPCENCTR_BONUS_EN) /* INP2 */ - DISCRETE_GAIN(SPCENCTR_BONUS_SND, /* adjust from logic to TTL voltage level */ - NODE_82, /* IN0 */ - DEFAULT_TTL_V_LOGIC_1) /* GAIN */ - - - /************************************************ - *Wind - unemulated - ************************************************/ - DISCRETE_CONSTANT(SPCENCTR_WIND_SND, 0) - - - /************************************************ - * Final mix - ************************************************/ - DISCRETE_MIXER7(NODE_91, - 1, /* ENAB */ - SPCENCTR_ENEMY_SHIP_SHOT_SND, /* IN0 */ - SPCENCTR_PLAYER_SHOT_SND, /* IN1 */ - SPCENCTR_SCREECH_SND, /* IN2 */ - SPCENCTR_CRASH_SND, /* IN3 */ - SPCENCTR_EXPLOSION_SND, /* IN4 */ - SPCENCTR_BONUS_SND, /* IN5 */ - SPCENCTR_WIND_SND, /* IN6 */ - &spcenctr_mixer) - - DISCRETE_OUTPUT(NODE_91, 20000) -DISCRETE_SOUND_END - - -void mw8080bw_state::spcenctr_audio(machine_config &config) -{ - SPEAKER(config, "mono").front_center(); - - SN76477(config, m_sn); - m_sn->set_noise_params(0, 0, 0); - m_sn->set_decay_res(0); - m_sn->set_attack_params(0, RES_K(100)); - m_sn->set_amp_res(RES_K(56)); - m_sn->set_feedback_res(RES_K(10)); - m_sn->set_vco_params(0, CAP_U(0.047), RES_K(56)); - m_sn->set_pitch_voltage(5.0); - m_sn->set_slf_params(CAP_U(1.0), RES_K(150)); - m_sn->set_oneshot_params(0, 0); - m_sn->set_vco_mode(1); - m_sn->set_mixer_params(0, 0, 0); - m_sn->set_envelope_params(1, 0); - m_sn->set_enable(1); - m_sn->add_route(ALL_OUTPUTS, "mono", 0.20); - - DISCRETE(config, m_discrete, spcenctr_discrete); - m_discrete->add_route(ALL_OUTPUTS, "mono", 0.45); -} - - - -WRITE8_MEMBER(mw8080bw_state::spcenctr_audio_1_w) -{ - machine().sound().system_enable((data >> 0) & 0x01); - - /* D1 is marked as 'OPTIONAL SWITCH VIDEO FOR COCKTAIL', - but it is never set by the software */ - - m_discrete->write(SPCENCTR_CRASH_EN, (data >> 2) & 0x01); - - /* D3-D7 are not connected */ -} - - -WRITE8_MEMBER(mw8080bw_state::spcenctr_audio_2_w) -{ - /* set WIND SOUND FREQ(data & 0x0f) 0, if no wind */ - - m_discrete->write(SPCENCTR_EXPLOSION_EN, (data >> 4) & 0x01); - - m_discrete->write(SPCENCTR_PLAYER_SHOT_EN, (data >> 5) & 0x01); - - /* D6 and D7 are not connected */ - - m_port_2_last = data; -} - - -WRITE8_MEMBER(mw8080bw_state::spcenctr_audio_3_w) -{ - /* if (data & 0x01) enable SCREECH (hit the sides) sound */ - - m_discrete->write(SPCENCTR_ENEMY_SHIP_SHOT_EN, (data >> 1) & 0x01); - - m_spcenctr_strobe_state = (data >> 2) & 0x01; - - output().set_value("LAMP", (data >> 3) & 0x01); - - m_discrete->write(SPCENCTR_BONUS_EN, (data >> 4) & 0x01); - - m_sn->enable_w((data >> 5) & 0x01); /* saucer sound */ - - /* D6 and D7 are not connected */ -} - - - -/************************************* - * - * Phantom II - * - *************************************/ - -static const char *const phantom2_sample_names[] = -{ - "*phantom2", - "1", /* shot */ - "2", /* explosion */ - nullptr -}; - -void mw8080bw_state::phantom2_audio(machine_config &config) -{ - MCFG_SOUND_START_OVERRIDE(mw8080bw_state, samples) - - SPEAKER(config, "mono").front_center(); - SAMPLES(config, m_samples); - m_samples->set_channels(2); - m_samples->set_samples_names(phantom2_sample_names); - m_samples->add_route(ALL_OUTPUTS, "mono", 1); -} - - -WRITE8_MEMBER(mw8080bw_state::phantom2_audio_1_w) -{ - uint8_t rising_bits = data & ~m_port_1_last; - - /* if (data & 0x01) enable PLAYER SHOT sound */ - if (rising_bits & 0x01) m_samples->start(0, 0); - - /* if (data & 0x02) enable ENEMY SHOT sound */ - - machine().sound().system_mute(!(data & 0x20)); - machine().sound().system_enable((data >> 2) & 0x01); - - machine().bookkeeping().coin_counter_w(0, (data >> 3) & 0x01); - - /* if (data & 0x10) enable RADAR sound */ - - /* D5-D7 are not connected */ - - m_port_1_last = data; -} - - -WRITE8_MEMBER(mw8080bw_state::phantom2_audio_2_w) -{ - uint8_t rising_bits = data & ~m_port_2_last; - - /* D0-D2 are not connected */ - - /* if (data & 0x08) enable EXPLOSION sound */ - if (rising_bits & 0x08) m_samples->start(1, 1); - - output().set_value("EXPLAMP", (data >> 4) & 0x01); - - /* set JET SOUND FREQ((data >> 5) & 0x07) 0, if no jet sound */ - - m_port_2_last = data; -} - - - -/************************************* - * * Bowling Alley * * Discrete sound emulation: @@ -3525,8 +3549,6 @@ static const char *const invaders_sample_names[] = /* left in for all games that hack into invaders samples for audio */ void mw8080bw_state::invaders_samples_audio(machine_config &config) { - MCFG_SOUND_START_OVERRIDE(mw8080bw_state, samples) - SPEAKER(config, "mono").front_center(); SN76477(config, m_sn); diff --git a/src/mame/audio/mw8080bw.h b/src/mame/audio/mw8080bw.h new file mode 100644 index 00000000000..c65ee8b2a9d --- /dev/null +++ b/src/mame/audio/mw8080bw.h @@ -0,0 +1,169 @@ +// license:BSD-3-Clause +// copyright-holders:Nicola Salmoria, Tormod Tjaberg, Mirko Buffoni,Lee Taylor, Valerio Verrando, Zsolt Vasvari,Derrick Renaud +// thanks-to:Michael Strutts, Marco Cassili +/*************************************************************************** + + Midway 8080-based black and white hardware + +****************************************************************************/ +#ifndef MAME_AUDIO_MW8080BW_H +#define MAME_AUDIO_MW8080BW_H + +#pragma once + +#include "sound/discrete.h" +#include "sound/samples.h" +#include "sound/sn76477.h" + + +class seawolf_audio_device : public device_t +{ +public: + seawolf_audio_device(machine_config const &mconfig, char const *tag, device_t *owner, u32 clock = 0); + + void write(u8 data); + +protected: + virtual void device_add_mconfig(machine_config &config) override; + virtual void device_start() override; + +private: + required_device<samples_device> m_samples; + u8 m_prev; +}; + + +class gunfight_audio_device : public device_t +{ +public: + gunfight_audio_device(machine_config const &mconfig, char const *tag, device_t *owner, u32 clock = 0); + + void write(u8 data); + +protected: + virtual void device_add_mconfig(machine_config &config) override; + virtual void device_start() override; + +private: + required_device_array<samples_device, 2> m_samples; +}; + + + +class gmissile_audio_device : public device_t +{ +public: + gmissile_audio_device(machine_config const &mconfig, char const *tag, device_t *owner, u32 clock = 0); + + void p1_w(u8 data); + void p2_w(u8 data); + void p3_w(u8 data); + +protected: + virtual void device_add_mconfig(machine_config &config) override; + virtual void device_start() override; + +private: + required_device_array<samples_device, 2> m_samples; + output_finder<> m_l_exp; + output_finder<> m_r_exp; + u8 m_p1; +}; + + +class clowns_audio_device : public device_t +{ +public: + auto ctrl_sel_out() { return m_ctrl_sel_out.bind(); } + + clowns_audio_device(machine_config const &mconfig, char const *tag, device_t *owner, u32 clock = 0); + + void p1_w(u8 data); + void p2_w(u8 data); + +protected: + virtual void device_add_mconfig(machine_config &config) override; + virtual void device_start() override; + +private: + required_device<samples_device> m_samples; + required_device<discrete_sound_device> m_discrete; + devcb_write_line m_ctrl_sel_out; + u8 m_p1; + u8 m_p2; +}; + + +class spcenctr_audio_device : public device_t +{ +public: + spcenctr_audio_device(machine_config const &mconfig, char const *tag, device_t *owner, u32 clock = 0); + + void p1_w(u8 data); + void p2_w(u8 data); + void p3_w(u8 data); + +protected: + virtual void device_add_mconfig(machine_config &config) override; + virtual void device_start() override; + +private: + TIMER_CALLBACK_MEMBER(strobe_callback); + + required_device<sn76477_device> m_sn; + required_device<discrete_sound_device> m_discrete; + output_finder<> m_lamp; + output_finder<> m_strobe; + emu_timer *m_strobe_timer; + u8 m_strobe_enable; +}; + + +class m4_audio_device : public device_t +{ +public: + m4_audio_device(machine_config const &mconfig, char const *tag, device_t *owner, u32 clock = 0); + + void p1_w(u8 data); + void p2_w(u8 data); + +protected: + virtual void device_add_mconfig(machine_config &config) override; + virtual void device_start() override; + +private: + required_device_array<samples_device, 2> m_samples; + u8 m_p1; + u8 m_p2; +}; + + +class phantom2_audio_device : public device_t +{ +public: + phantom2_audio_device(machine_config const &mconfig, char const *tag, device_t *owner, u32 clock = 0); + + void p1_w(u8 data); + void p2_w(u8 data); + +protected: + virtual void device_add_mconfig(machine_config &config) override; + virtual void device_start() override; + +private: + required_device<samples_device> m_samples; + output_finder<> m_exp; + u8 m_p1; + u8 m_p2; +}; + + +DECLARE_DEVICE_TYPE(SEAWOLF_AUDIO, seawolf_audio_device) +DECLARE_DEVICE_TYPE(GUNFIGHT_AUDIO, gunfight_audio_device) +DECLARE_DEVICE_TYPE(GMISSILE_AUDIO, gmissile_audio_device) +DECLARE_DEVICE_TYPE(CLOWNS_AUDIO, clowns_audio_device) +DECLARE_DEVICE_TYPE(SPCENCTR_AUDIO, spcenctr_audio_device) +DECLARE_DEVICE_TYPE(M4_AUDIO, m4_audio_device) +DECLARE_DEVICE_TYPE(PHANTOM2_AUDIO, phantom2_audio_device) + +#endif // MAME_AUDIO_MW8080BW_H diff --git a/src/mame/drivers/fgoal.cpp b/src/mame/drivers/fgoal.cpp index c8031505a03..9ac20acc22c 100644 --- a/src/mame/drivers/fgoal.cpp +++ b/src/mame/drivers/fgoal.cpp @@ -142,13 +142,13 @@ READ8_MEMBER(fgoal_state::row_r) WRITE8_MEMBER(fgoal_state::row_w) { m_row = data; - m_mb14241->shift_data_w(space, 0, 0); + m_mb14241->shift_data_w(0); } WRITE8_MEMBER(fgoal_state::col_w) { m_col = data; - m_mb14241->shift_count_w(space, 0, data); + m_mb14241->shift_count_w(data); } READ8_MEMBER(fgoal_state::address_hi_r) @@ -163,14 +163,14 @@ READ8_MEMBER(fgoal_state::address_lo_r) READ8_MEMBER(fgoal_state::shifter_r) { - uint8_t v = m_mb14241->shift_result_r(space, 0); + uint8_t v = m_mb14241->shift_result_r(); return bitswap<8>(v, 7, 6, 5, 4, 3, 2, 1, 0); } READ8_MEMBER(fgoal_state::shifter_reverse_r) { - uint8_t v = m_mb14241->shift_result_r(space, 0); + uint8_t v = m_mb14241->shift_result_r(); return bitswap<8>(v, 0, 1, 2, 3, 4, 5, 6, 7); } diff --git a/src/mame/drivers/mw8080bw.cpp b/src/mame/drivers/mw8080bw.cpp index d00d06e6695..4b96f9c55e5 100644 --- a/src/mame/drivers/mw8080bw.cpp +++ b/src/mame/drivers/mw8080bw.cpp @@ -151,9 +151,12 @@ ****************************************************************************/ #include "emu.h" +#include "includes/mw8080bw.h" + #include "cpu/i8085/i8085.h" #include "machine/rescap.h" -#include "includes/mw8080bw.h" + +#include <algorithm> #include "280zzzap.lh" #include "clowns.lh" @@ -177,7 +180,7 @@ READ8_MEMBER(mw8080bw_state::mw8080bw_shift_result_rev_r) { - uint8_t ret = m_mb14241->shift_result_r(space, 0); + uint8_t ret = m_mb14241->shift_result_r(); return bitswap<8>(ret,0,1,2,3,4,5,6,7); } @@ -188,20 +191,16 @@ READ8_MEMBER(mw8080bw_state::mw8080bw_reversable_shift_result_r) uint8_t ret; if (m_rev_shift_res) - { ret = mw8080bw_shift_result_rev_r(space, 0); - } else - { - ret = m_mb14241->shift_result_r(space, 0); - } + ret = m_mb14241->shift_result_r(); return ret; } WRITE8_MEMBER(mw8080bw_state::mw8080bw_reversable_shift_count_w) { - m_mb14241->shift_count_w(space, offset, data); + m_mb14241->shift_count_w(data); m_rev_shift_res = data & 0x08; } @@ -345,7 +344,7 @@ void mw8080bw_state::seawolf_io_map(address_map &map) map(0x02, 0x02).w(FUNC(mw8080bw_state::seawolf_periscope_lamp_w)); map(0x03, 0x03).w(m_mb14241, FUNC(mb14241_device::shift_data_w)); map(0x04, 0x04).w(m_mb14241, FUNC(mb14241_device::shift_count_w)); - map(0x05, 0x05).w(FUNC(mw8080bw_state::seawolf_audio_w)); + map(0x05, 0x05).w("soundboard", FUNC(seawolf_audio_device::write)); } @@ -421,7 +420,7 @@ void mw8080bw_state::seawolf(machine_config &config) MB14241(config, m_mb14241); /* audio hardware */ - seawolf_audio(config); + SEAWOLF_AUDIO(config, "soundboard"); } @@ -432,21 +431,20 @@ void mw8080bw_state::seawolf(machine_config &config) * *************************************/ -WRITE8_MEMBER(mw8080bw_state::gunfight_io_w) +void gunfight_state::io_w(offs_t offset, u8 data) { if (offset & 0x01) - gunfight_audio_w(space, 0, data); + m_soundboard->write(data); if (offset & 0x02) - m_mb14241->shift_count_w(space, 0, data); + m_mb14241->shift_count_w(data); if (offset & 0x04) - m_mb14241->shift_data_w(space, 0, data); - + m_mb14241->shift_data_w(data); } -void mw8080bw_state::gunfight_io_map(address_map &map) +void gunfight_state::io_map(address_map &map) { map.global_mask(0x7); map(0x00, 0x00).mirror(0x04).portr("IN0"); @@ -454,8 +452,7 @@ void mw8080bw_state::gunfight_io_map(address_map &map) map(0x02, 0x02).mirror(0x04).portr("IN2"); map(0x03, 0x03).mirror(0x04).r(m_mb14241, FUNC(mb14241_device::shift_result_r)); - /* no decoder, just 3 AND gates */ - map(0x00, 0x07).w(FUNC(mw8080bw_state::gunfight_io_w)); + map(0x00, 0x07).w(FUNC(gunfight_state::io_w)); // no decoder, just 3 AND gates } @@ -510,19 +507,20 @@ static INPUT_PORTS_START( gunfight ) INPUT_PORTS_END -void mw8080bw_state::gunfight(machine_config &config) +void gunfight_state::gunfight(machine_config &config) { mw8080bw_root(config); - /* basic machine hardware */ - m_maincpu->set_addrmap(AS_IO, &mw8080bw_state::gunfight_io_map); - /* there is no watchdog */ + // basic machine hardware + m_maincpu->set_addrmap(AS_IO, &gunfight_state::io_map); - /* add shifter */ + // there is no watchdog + + // add shifter MB14241(config, m_mb14241); - /* audio hardware */ - gunfight_audio(config); + // audio hardware + GUNFIGHT_AUDIO(config, m_soundboard); } @@ -634,10 +632,10 @@ WRITE8_MEMBER(mw8080bw_state::tornbase_io_w) tornbase_audio_w(space, 0, data); if (offset & 0x02) - m_mb14241->shift_count_w(space, 0, data); + m_mb14241->shift_count_w(data); if (offset & 0x04) - m_mb14241->shift_data_w(space, 0, data); + m_mb14241->shift_data_w(data); } @@ -1533,11 +1531,11 @@ void mw8080bw_state::gmissile_io_map(address_map &map) map(0x01, 0x01).w(FUNC(mw8080bw_state::mw8080bw_reversable_shift_count_w)); map(0x02, 0x02).w(m_mb14241, FUNC(mb14241_device::shift_data_w)); - map(0x03, 0x03).w(FUNC(mw8080bw_state::gmissile_audio_1_w)); + map(0x03, 0x03).w("soundboard", FUNC(gmissile_audio_device::p1_w)); map(0x04, 0x04).w(m_watchdog, FUNC(watchdog_timer_device::reset_w)); - map(0x05, 0x05).w(FUNC(mw8080bw_state::gmissile_audio_2_w)); + map(0x05, 0x05).w("soundboard", FUNC(gmissile_audio_device::p2_w)); /* also writes 0x00 to 0x06, but it is not connected */ - map(0x07, 0x07).w(FUNC(mw8080bw_state::gmissile_audio_3_w)); + map(0x07, 0x07).w("soundboard", FUNC(gmissile_audio_device::p3_w)); } @@ -1600,7 +1598,7 @@ void mw8080bw_state::gmissile(machine_config &config) MB14241(config, m_mb14241); /* audio hardware */ - gmissile_audio(config); + GMISSILE_AUDIO(config, "soundboard"); } @@ -1630,9 +1628,9 @@ void mw8080bw_state::m4_io_map(address_map &map) map(0x01, 0x01).w(FUNC(mw8080bw_state::mw8080bw_reversable_shift_count_w)); map(0x02, 0x02).w(m_mb14241, FUNC(mb14241_device::shift_data_w)); - map(0x03, 0x03).w(FUNC(mw8080bw_state::m4_audio_1_w)); + map(0x03, 0x03).w("soundboard", FUNC(m4_audio_device::p1_w)); map(0x04, 0x04).w(m_watchdog, FUNC(watchdog_timer_device::reset_w)); - map(0x05, 0x05).w(FUNC(mw8080bw_state::m4_audio_2_w)); + map(0x05, 0x05).w("soundboard", FUNC(m4_audio_device::p2_w)); } @@ -1695,7 +1693,7 @@ void mw8080bw_state::m4(machine_config &config) MB14241(config, m_mb14241); /* audio hardware */ - m4_audio(config); + M4_AUDIO(config, "soundboard"); } @@ -1746,11 +1744,11 @@ void mw8080bw_state::clowns_io_map(address_map &map) map(0x01, 0x01).w(m_mb14241, FUNC(mb14241_device::shift_count_w)); map(0x02, 0x02).w(m_mb14241, FUNC(mb14241_device::shift_data_w)); - map(0x03, 0x03).w(FUNC(mw8080bw_state::clowns_audio_1_w)); + map(0x03, 0x03).w("soundboard", FUNC(clowns_audio_device::p1_w)); map(0x04, 0x04).w(m_watchdog, FUNC(watchdog_timer_device::reset_w)); map(0x05, 0x05).w(FUNC(mw8080bw_state::midway_tone_generator_lo_w)); map(0x06, 0x06).w(FUNC(mw8080bw_state::midway_tone_generator_hi_w)); - map(0x07, 0x07).w(FUNC(mw8080bw_state::clowns_audio_2_w)); + map(0x07, 0x07).w("soundboard", FUNC(clowns_audio_device::p2_w)); } @@ -1865,7 +1863,7 @@ void mw8080bw_state::clowns(machine_config &config) MB14241(config, m_mb14241); /* audio hardware */ - clowns_audio(config); + CLOWNS_AUDIO(config, "soundboard").ctrl_sel_out().set([this] (int state) { m_clowns_controller_select = state ? 1 : 0; }); } @@ -2142,70 +2140,55 @@ void mw8080bw_state::dogpatch(machine_config &config) * *************************************/ -#define SPCENCTR_STROBE_FREQ (9.00) /* Hz - calculated from the 555 timer */ -#define SPCENCTR_STROBE_DUTY_CYCLE (95.0) /* % */ - - -TIMER_DEVICE_CALLBACK_MEMBER(mw8080bw_state::spcenctr_strobe_timer_callback) +MACHINE_START_MEMBER(spcenctr_state, spcenctr) { - output().set_value("STROBE", param && m_spcenctr_strobe_state); -} + m_trench_width = 0U; + m_trench_center = 0U; + std::fill(std::begin(m_trench_slope), std::end(m_trench_slope), 0U); + m_bright_control = 0U; + m_brightness = 0U; - -MACHINE_START_MEMBER(mw8080bw_state,spcenctr) -{ - /* setup for save states */ - save_item(NAME(m_spcenctr_strobe_state)); - save_item(NAME(m_spcenctr_trench_width)); - save_item(NAME(m_spcenctr_trench_center)); - save_item(NAME(m_spcenctr_trench_slope)); - save_item(NAME(m_spcenctr_bright_control)); - save_item(NAME(m_spcenctr_brightness)); + save_item(NAME(m_trench_width)); + save_item(NAME(m_trench_center)); + save_item(NAME(m_trench_slope)); + save_item(NAME(m_bright_control)); + save_item(NAME(m_brightness)); MACHINE_START_CALL_MEMBER(mw8080bw); } -WRITE8_MEMBER(mw8080bw_state::spcenctr_io_w) -{ /* A7 A6 A5 A4 A3 A2 A1 A0 */ - - if ((offset & 0x07) == 0x02) - m_watchdog->watchdog_reset(); /* - - - - - 0 1 0 */ - +void spcenctr_state::io_w(offs_t offset, u8 data) +{ // A7 A6 A5 A4 A3 A2 A1 A0 + if ((offset & 0x07) == 0x00) + // hex flip-flop B5 + // bit 3: /BRITE + // bit 2: /NO_PLANET + // bit 1: /SET_WSL + // bit 0: COIN_COUNTER + m_bright_control = BIT(~data, 3); // - - - - - 0 0 0 else if ((offset & 0x5f) == 0x01) - spcenctr_audio_1_w(space, 0, data); /* - 0 - 0 0 0 0 1 */ - + m_soundboard->p1_w(data); // - 0 - 0 0 0 0 1 else if ((offset & 0x5f) == 0x09) - spcenctr_audio_2_w(space, 0, data); /* - 0 - 0 1 0 0 1 */ - + m_soundboard->p2_w(data); // - 0 - 0 1 0 0 1 else if ((offset & 0x5f) == 0x11) - spcenctr_audio_3_w(space, 0, data); /* - 0 - 1 0 0 0 1 */ - + m_soundboard->p3_w(data); // - 0 - 1 0 0 0 1 + else if ((offset & 0x07) == 0x02) + m_watchdog->watchdog_reset(); // - - - - - 0 1 0 else if ((offset & 0x07) == 0x03) - { /* - - - - - 0 1 1 */ - uint8_t addr = ((offset & 0xc0) >> 4) | ((offset & 0x18) >> 3); - m_spcenctr_trench_slope[addr] = data; + { // - - - - - 0 1 1 + m_trench_slope[bitswap<4>(offset, 7, 6, 4, 3)] = data; } else if ((offset & 0x07) == 0x04) - m_spcenctr_trench_center = data; /* - - - - - 1 0 0 */ - + m_trench_center = data; // - - - - - 1 0 0 else if ((offset & 0x07) == 0x07) - m_spcenctr_trench_width = data; /* - - - - - 1 1 1 */ - - else if ((offset & 0x07) == 0x00) - // hex flip-flop B5 - // bit 3: /BRITE - // bit 2: /NO_PLANET - // bit 1: /SET_WSL - // bit 0: COIN_COUNTER - m_spcenctr_bright_control = ~data & 0x08; /* - - - - - 0 0 0 */ - + m_trench_width = data; // - - - - - 1 1 1 else - logerror("%04x: Unmapped I/O port write to %02x = %02x\n", m_maincpu->pc(), offset, data); + logerror("%s: Unmapped I/O port write to %02x = %02x\n", machine().describe_context(), offset, data); } -void mw8080bw_state::spcenctr_io_map(address_map &map) +void spcenctr_state::io_map(address_map &map) { map.global_mask(0xff); map(0x00, 0x00).mirror(0xfc).portr("IN0"); @@ -2213,8 +2196,7 @@ void mw8080bw_state::spcenctr_io_map(address_map &map) map(0x02, 0x02).mirror(0xfc).portr("IN2"); map(0x03, 0x03).mirror(0xfc).nopr(); - /* complicated addressing logic */ - map(0x00, 0xff).w(FUNC(mw8080bw_state::spcenctr_io_w)); + map(0x00, 0xff).w(FUNC(spcenctr_state::io_w)); // complicated addressing logic } @@ -2268,32 +2250,22 @@ static INPUT_PORTS_START( spcenctr ) INPUT_PORTS_END -void mw8080bw_state::spcenctr(machine_config &config) +void spcenctr_state::spcenctr(machine_config &config) { mw8080bw_root(config); - /* basic machine hardware */ - m_maincpu->set_addrmap(AS_IO, &mw8080bw_state::spcenctr_io_map); + // basic machine hardware + m_maincpu->set_addrmap(AS_IO, &spcenctr_state::io_map); - MCFG_MACHINE_START_OVERRIDE(mw8080bw_state,spcenctr) + MCFG_MACHINE_START_OVERRIDE(spcenctr_state, spcenctr) WATCHDOG_TIMER(config, m_watchdog).set_time(255 * attotime::from_hz(MW8080BW_60HZ)); - /* timers */ - timer_device &strobeon(TIMER(config, "strobeon")); - strobeon.configure_periodic(FUNC(mw8080bw_state::spcenctr_strobe_timer_callback), attotime::from_hz(SPCENCTR_STROBE_FREQ)); - strobeon.config_param(true); /* indicates strobe ON */ - - timer_device &strobeoff(TIMER(config, "strobeoff")); - strobeoff.configure_periodic(FUNC(mw8080bw_state::spcenctr_strobe_timer_callback), attotime::from_hz(SPCENCTR_STROBE_FREQ)); - strobeoff.set_start_delay(attotime::from_hz(SPCENCTR_STROBE_FREQ) * (100 - SPCENCTR_STROBE_DUTY_CYCLE) / 100); - strobeoff.config_param(false); /* indicates strobe OFF */ + // video hardware + m_screen->set_screen_update(FUNC(spcenctr_state::screen_update)); - /* video hardware */ - m_screen->set_screen_update(FUNC(mw8080bw_state::screen_update_spcenctr)); - - /* audio hardware */ - spcenctr_audio(config); + // audio hardware + SPCENCTR_AUDIO(config, m_soundboard); } @@ -2325,8 +2297,8 @@ void mw8080bw_state::phantom2_io_map(address_map &map) map(0x01, 0x01).w(m_mb14241, FUNC(mb14241_device::shift_count_w)); map(0x02, 0x02).w(m_mb14241, FUNC(mb14241_device::shift_data_w)); map(0x04, 0x04).w(m_watchdog, FUNC(watchdog_timer_device::reset_w)); - map(0x05, 0x05).w(FUNC(mw8080bw_state::phantom2_audio_1_w)); - map(0x06, 0x06).w(FUNC(mw8080bw_state::phantom2_audio_2_w)); + map(0x05, 0x05).w("soundboard", FUNC(phantom2_audio_device::p1_w)); + map(0x06, 0x06).w("soundboard", FUNC(phantom2_audio_device::p2_w)); } @@ -2385,7 +2357,7 @@ void mw8080bw_state::phantom2(machine_config &config) MB14241(config, m_mb14241); /* audio hardware */ - phantom2_audio(config); + PHANTOM2_AUDIO(config, "soundboard"); } @@ -2402,7 +2374,7 @@ READ8_MEMBER(mw8080bw_state::bowler_shift_result_r) anything unusual on the schematics that would cause the bits to flip */ - return ~m_mb14241->shift_result_r(space, 0); + return ~m_mb14241->shift_result_r(); } WRITE8_MEMBER(mw8080bw_state::bowler_lights_1_w) @@ -3244,12 +3216,12 @@ ROM_END * *************************************/ -/* PCB # year rom parent machine inp init monitor,company,fullname,flags */ +// PCB # year rom parent machine inp state init monitor company,fullname,flags /* 596 */ GAMEL( 1976, seawolf, 0, seawolf, seawolf, mw8080bw_state, empty_init, ROT0, "Dave Nutting Associates / Midway", "Sea Wolf (set 1)", MACHINE_IMPERFECT_SOUND | MACHINE_SUPPORTS_SAVE, layout_seawolf ) /* 596 */ GAMEL( 1976, seawolfo, seawolf, seawolf, seawolf, mw8080bw_state, empty_init, ROT0, "Dave Nutting Associates / Midway", "Sea Wolf (set 2)", MACHINE_IMPERFECT_SOUND | MACHINE_SUPPORTS_SAVE, layout_seawolf ) -/* 597 */ GAMEL( 1975, gunfight, 0, gunfight, gunfight, mw8080bw_state, empty_init, ROT0, "Dave Nutting Associates / Midway", "Gun Fight (set 1)", MACHINE_IMPERFECT_SOUND | MACHINE_SUPPORTS_SAVE, layout_gunfight ) -/* 597 */ GAMEL( 1975, gunfighto, gunfight, gunfight, gunfight, mw8080bw_state, empty_init, ROT0, "Dave Nutting Associates / Midway", "Gun Fight (set 2)", MACHINE_IMPERFECT_SOUND | MACHINE_SUPPORTS_SAVE, layout_gunfight ) +/* 597 */ GAMEL( 1975, gunfight, 0, gunfight, gunfight, gunfight_state, empty_init, ROT0, "Dave Nutting Associates / Midway", "Gun Fight (set 1)", MACHINE_IMPERFECT_SOUND | MACHINE_SUPPORTS_SAVE, layout_gunfight ) +/* 597 */ GAMEL( 1975, gunfighto, gunfight, gunfight, gunfight, gunfight_state, empty_init, ROT0, "Dave Nutting Associates / Midway", "Gun Fight (set 2)", MACHINE_IMPERFECT_SOUND | MACHINE_SUPPORTS_SAVE, layout_gunfight ) /* 604 Gun Fight (cocktail, dump does not exist) */ /* 605 */ GAME( 1976, tornbase, 0, tornbase, tornbase, mw8080bw_state, empty_init, ROT0, "Dave Nutting Associates / Midway / Taito", "Tornado Baseball / Ball Park", MACHINE_IMPERFECT_SOUND | MACHINE_SUPPORTS_SAVE ) /* 610 */ GAMEL( 1976, 280zzzap, 0, zzzap, zzzap, mw8080bw_state, empty_init, ROT0, "Dave Nutting Associates / Midway", "280-ZZZAP", MACHINE_NO_SOUND | MACHINE_SUPPORTS_SAVE, layout_280zzzap ) @@ -3268,7 +3240,7 @@ ROM_END /* 642 */ GAME( 1978, einning, 0, dplay, einning, mw8080bw_state, empty_init, ROT0, "Midway / Taito", "Extra Inning / Ball Park II", MACHINE_SUPPORTS_SAVE ) /* 643 */ GAME( 1978, shuffle, 0, shuffle, shuffle, mw8080bw_state, empty_init, ROT90, "Midway", "Shuffleboard", MACHINE_IMPERFECT_SOUND | MACHINE_SUPPORTS_SAVE ) /* 644 */ GAME( 1977, dogpatch, 0, dogpatch, dogpatch, mw8080bw_state, empty_init, ROT0, "Midway", "Dog Patch", MACHINE_IMPERFECT_SOUND | MACHINE_SUPPORTS_SAVE ) -/* 645 */ GAMEL( 1980, spcenctr, 0, spcenctr, spcenctr, mw8080bw_state, empty_init, ROT0, "Midway", "Space Encounters", MACHINE_IMPERFECT_SOUND | MACHINE_SUPPORTS_SAVE, layout_spcenctr ) +/* 645 */ GAMEL( 1980, spcenctr, 0, spcenctr, spcenctr, spcenctr_state, empty_init, ROT0, "Midway", "Space Encounters", MACHINE_IMPERFECT_SOUND | MACHINE_SUPPORTS_SAVE, layout_spcenctr ) /* 652 */ GAMEL( 1979, phantom2, 0, phantom2, phantom2, mw8080bw_state, empty_init, ROT0, "Midway", "Phantom II", MACHINE_IMPERFECT_SOUND | MACHINE_SUPPORTS_SAVE, layout_phantom2 ) /* 730 */ GAME( 1978, bowler, 0, bowler, bowler, mw8080bw_state, empty_init, ROT90, "Midway", "Bowling Alley", MACHINE_IMPERFECT_SOUND | MACHINE_SUPPORTS_SAVE ) /* 739 */ GAMEL( 1978, invaders, 0, invaders, invaders, mw8080bw_state, empty_init, ROT270, "Taito / Midway", "Space Invaders / Space Invaders M", MACHINE_SUPPORTS_SAVE, layout_invaders ) diff --git a/src/mame/drivers/nexus3d.cpp b/src/mame/drivers/nexus3d.cpp index 3b7486d28aa..695c99a9a3e 100644 --- a/src/mame/drivers/nexus3d.cpp +++ b/src/mame/drivers/nexus3d.cpp @@ -318,7 +318,7 @@ void nexus3d_state::nexus3d(machine_config &config) m_maincpu->set_addrmap(AS_PROGRAM, &nexus3d_state::nexus3d_map); SCREEN(config, m_screen, SCREEN_TYPE_RASTER); - m_screen->set_raw((XTAL(14'318'180)*2), 454*2, 0, 640, 262*2, 0, 480); // not accurate, needs CRTC understanding + m_screen->set_raw((XTAL(14'318'181)*2), 454*2, 0, 640, 262*2, 0, 480); // not accurate, needs CRTC understanding m_screen->set_screen_update(FUNC(nexus3d_state::screen_update)); m_screen->screen_vblank().set(FUNC(nexus3d_state::screen_vblank)); m_screen->set_palette("palette"); diff --git a/src/mame/drivers/snowbros.cpp b/src/mame/drivers/snowbros.cpp index 107e1ad767d..b8875ed594c 100644 --- a/src/mame/drivers/snowbros.cpp +++ b/src/mame/drivers/snowbros.cpp @@ -1952,6 +1952,7 @@ void snowbros_state::finalttr(machine_config &config) ymsnd.add_route(1, "mono", 0.08); m_oki->set_clock(999900); + m_oki->reset_routes().add_route(ALL_OUTPUTS, "mono", 0.4); } diff --git a/src/mame/includes/mw8080bw.h b/src/mame/includes/mw8080bw.h index 0aa65d4d0f6..6148e8b917e 100644 --- a/src/mame/includes/mw8080bw.h +++ b/src/mame/includes/mw8080bw.h @@ -6,6 +6,12 @@ Midway 8080-based black and white hardware ****************************************************************************/ +#ifndef MAME_INCLUDES_MW8080BW_H +#define MAME_INCLUDES_MW8080BW_H + +#pragma once + +#include "audio/mw8080bw.h" #include "machine/mb14241.h" #include "machine/timer.h" @@ -33,16 +39,15 @@ #define MW8080BW_INT_TRIGGER_VBLANK_2 (1) #define MW8080BW_60HZ (MW8080BW_PIXEL_CLOCK / MW8080BW_HTOTAL / MW8080BW_VTOTAL) -/* +4 is added to HBSTART because the hardware displays that many pixels after - setting HBLANK */ +// +4 is added to HBSTART because the hardware displays that many pixels after setting HBLANK #define MW8080BW_HPIXCOUNT (MW8080BW_HBSTART + 4) class mw8080bw_state : public driver_device { public: - mw8080bw_state(const machine_config &mconfig, device_type type, const char *tag) - : driver_device(mconfig, type, tag), + mw8080bw_state(const machine_config &mconfig, device_type type, const char *tag) : + driver_device(mconfig, type, tag), m_maincpu(*this,"maincpu"), m_mb14241(*this,"mb14241"), m_watchdog(*this, "watchdog"), @@ -51,8 +56,6 @@ public: m_colorram2(*this, "colorram2"), m_discrete(*this, "discrete"), m_samples(*this, "samples"), - m_samples1(*this, "samples1"), - m_samples2(*this, "samples2"), m_sn1(*this, "sn1"), m_sn2(*this, "sn2"), m_sn(*this, "snsnd"), @@ -68,7 +71,6 @@ public: void checkmat(machine_config &config); void checkmat_audio(machine_config &config); void clowns(machine_config &config); - void clowns_audio(machine_config &config); void desertgu(machine_config &config); void desertgu_audio(machine_config &config); void dogpatch(machine_config &config); @@ -76,29 +78,21 @@ public: void dplay(machine_config &config); void dplay_audio(machine_config &config); void gmissile(machine_config &config); - void gmissile_audio(machine_config &config); - void gunfight(machine_config &config); - void gunfight_audio(machine_config &config); void invad2ct(machine_config &config); void invad2ct_audio(machine_config &config); void invaders(machine_config &config); void invaders_audio(machine_config &config); void invaders_samples_audio(machine_config &config); void m4(machine_config &config); - void m4_audio(machine_config &config); void maze(machine_config &config); void maze_audio(machine_config &config); void mw8080bw_root(machine_config &config); void phantom2(machine_config &config); - void phantom2_audio(machine_config &config); void seawolf(machine_config &config); - void seawolf_audio(machine_config &config); void shuffle(machine_config &config); void shuffle_audio(machine_config &config); void spacwalk(machine_config &config); void spacwalk_audio(machine_config &config); - void spcenctr(machine_config &config); - void spcenctr_audio(machine_config &config); void tornbase(machine_config &config); void tornbase_audio(machine_config &config); void zzzap(machine_config &config); @@ -142,16 +136,12 @@ protected: /* other devices */ optional_device<samples_device> m_samples; - optional_device<samples_device> m_samples1; - optional_device<samples_device> m_samples2; optional_device<sn76477_device> m_sn1; optional_device<sn76477_device> m_sn2; optional_device<sn76477_device> m_sn; required_device<screen_device> m_screen; /* sound-related */ - uint8_t m_port_1_last; - uint8_t m_port_2_last; uint8_t m_port_1_last_extra; uint8_t m_port_2_last_extra; uint8_t m_port_3_last_extra; @@ -176,13 +166,6 @@ private: uint8_t m_desertgun_controller_select; uint8_t m_clowns_controller_select; - uint8_t m_spcenctr_strobe_state; - uint8_t m_spcenctr_trench_width; - uint8_t m_spcenctr_trench_center; - uint8_t m_spcenctr_trench_slope[16]; /* 16x4 bit RAM */ - uint8_t m_spcenctr_bright_control; - uint8_t m_spcenctr_brightness; - /* timers */ emu_timer *m_interrupt_timer; emu_timer *m_maze_tone_timer; @@ -194,27 +177,15 @@ private: DECLARE_WRITE8_MEMBER(mw8080bw_reversable_shift_count_w); DECLARE_WRITE8_MEMBER(seawolf_explosion_lamp_w); DECLARE_WRITE8_MEMBER(seawolf_periscope_lamp_w); - DECLARE_WRITE8_MEMBER(gunfight_io_w); DECLARE_WRITE8_MEMBER(tornbase_io_w); DECLARE_WRITE8_MEMBER(maze_coin_counter_w); DECLARE_WRITE8_MEMBER(maze_io_w); DECLARE_WRITE8_MEMBER(checkmat_io_w); - DECLARE_WRITE8_MEMBER(spcenctr_io_w); DECLARE_READ8_MEMBER(bowler_shift_result_r); DECLARE_WRITE8_MEMBER(bowler_lights_1_w); DECLARE_WRITE8_MEMBER(bowler_lights_2_w); - DECLARE_WRITE8_MEMBER(seawolf_audio_w); - DECLARE_WRITE8_MEMBER(gunfight_audio_w); DECLARE_WRITE8_MEMBER(zzzap_audio_1_w); DECLARE_WRITE8_MEMBER(zzzap_audio_2_w); - DECLARE_WRITE8_MEMBER(gmissile_audio_1_w); - DECLARE_WRITE8_MEMBER(gmissile_audio_2_w); - DECLARE_WRITE8_MEMBER(gmissile_audio_3_w); - DECLARE_WRITE8_MEMBER(m4_audio_1_w); - DECLARE_WRITE8_MEMBER(m4_audio_2_w); - DECLARE_WRITE8_MEMBER(clowns_audio_1_w); - DECLARE_WRITE8_MEMBER(phantom2_audio_1_w); - DECLARE_WRITE8_MEMBER(phantom2_audio_2_w); DECLARE_WRITE8_MEMBER(bowler_audio_2_w); DECLARE_WRITE8_MEMBER(bowler_audio_3_w); DECLARE_WRITE8_MEMBER(bowler_audio_4_w); @@ -226,16 +197,12 @@ private: DECLARE_MACHINE_START(gmissile); DECLARE_MACHINE_START(m4); DECLARE_MACHINE_START(clowns); - DECLARE_MACHINE_START(spcenctr); DECLARE_MACHINE_START(phantom2); DECLARE_MACHINE_START(invaders); - DECLARE_SOUND_START(samples); - uint32_t screen_update_spcenctr(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect); uint32_t screen_update_phantom2(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect); DECLARE_WRITE_LINE_MEMBER(screen_vblank_phantom2); TIMER_CALLBACK_MEMBER(maze_tone_timing_timer_callback); TIMER_CALLBACK_MEMBER(interrupt_trigger); - TIMER_DEVICE_CALLBACK_MEMBER(spcenctr_strobe_timer_callback); DECLARE_WRITE8_MEMBER(midway_tone_generator_lo_w); DECLARE_WRITE8_MEMBER(midway_tone_generator_hi_w); DECLARE_WRITE8_MEMBER(tornbase_audio_w); @@ -244,15 +211,11 @@ private: DECLARE_WRITE8_MEMBER(desertgu_audio_1_w); DECLARE_WRITE8_MEMBER(desertgu_audio_2_w); DECLARE_WRITE8_MEMBER(dplay_audio_w); - DECLARE_WRITE8_MEMBER(clowns_audio_2_w); DECLARE_WRITE8_MEMBER(spacwalk_audio_1_w); DECLARE_WRITE8_MEMBER(spacwalk_audio_2_w); DECLARE_WRITE8_MEMBER(shuffle_audio_1_w); DECLARE_WRITE8_MEMBER(shuffle_audio_2_w); DECLARE_WRITE8_MEMBER(dogpatch_audio_w); - DECLARE_WRITE8_MEMBER(spcenctr_audio_1_w); - DECLARE_WRITE8_MEMBER(spcenctr_audio_2_w); - DECLARE_WRITE8_MEMBER(spcenctr_audio_3_w); DECLARE_WRITE8_MEMBER(bowler_audio_1_w); DECLARE_WRITE8_MEMBER(blueshrk_audio_w); DECLARE_WRITE8_MEMBER(invad2ct_audio_1_w); @@ -276,7 +239,6 @@ private: void dogpatch_io_map(address_map &map); void dplay_io_map(address_map &map); void gmissile_io_map(address_map &map); - void gunfight_io_map(address_map &map); void invad2ct_io_map(address_map &map); void invaders_io_map(address_map &map); void m4_io_map(address_map &map); @@ -286,12 +248,61 @@ private: void seawolf_io_map(address_map &map); void shuffle_io_map(address_map &map); void spacwalk_io_map(address_map &map); - void spcenctr_io_map(address_map &map); void tornbase_io_map(address_map &map); void zzzap_io_map(address_map &map); }; +class gunfight_state : public mw8080bw_state +{ +public: + gunfight_state(machine_config const &mconfig, device_type type, char const *tag) : + mw8080bw_state(mconfig, type, tag), + m_soundboard(*this, "soundboard") + { + } + + void gunfight(machine_config &config); + +private: + void io_w(offs_t offset, u8 data); + + void io_map(address_map &map); + + required_device<gunfight_audio_device> m_soundboard; +}; + + +class spcenctr_state : public mw8080bw_state +{ +public: + spcenctr_state(machine_config const &mconfig, device_type type, char const *tag) : + mw8080bw_state(mconfig, type, tag), + m_soundboard(*this, "soundboard") + { + } + + void spcenctr(machine_config &config); + +protected: + DECLARE_MACHINE_START(spcenctr); + +private: + void io_w(offs_t offset, u8 data); + + u32 screen_update(screen_device &screen, bitmap_rgb32 &bitmap, rectangle const &cliprect); + + void io_map(address_map &map); + + required_device<spcenctr_audio_device> m_soundboard; + u8 m_trench_width; + u8 m_trench_center; + u8 m_trench_slope[16]; // 16x4 bit RAM + u8 m_bright_control; + u8 m_brightness; +}; + + #define SEAWOLF_GUN_PORT_TAG ("GUN") #define TORNBASE_CAB_TYPE_UPRIGHT_OLD (0) @@ -334,3 +345,4 @@ private: extern const internal_layout layout_invaders; +#endif // MAME_INCLUDES_MW8080BW_H diff --git a/src/mame/video/mw8080bw.cpp b/src/mame/video/mw8080bw.cpp index 2faa2adb3a4..83e6756a1fb 100644 --- a/src/mame/video/mw8080bw.cpp +++ b/src/mame/video/mw8080bw.cpp @@ -19,21 +19,19 @@ uint32_t mw8080bw_state::screen_update_mw8080bw(screen_device &screen, bitmap_rg while (1) { - /* plot the current pixel */ + // plot the current pixel pen_t pen = (video_data & 0x01) ? rgb_t::white() : rgb_t::black(); bitmap.pix32(y - MW8080BW_VCOUNTER_START_NO_VBLANK, x) = pen; - /* next pixel */ + // next pixel video_data = video_data >> 1; x = x + 1; /* end of line? */ if (x == 0) { - /* yes, flush out the shift register */ - int i; - - for (i = 0; i < 4; i++) + // yes, flush out the shift register + for (int i = 0; i < 4; i++) { pen = (video_data & 0x01) ? rgb_t::white() : rgb_t::black(); bitmap.pix32(y - MW8080BW_VCOUNTER_START_NO_VBLANK, 256 + i) = pen; @@ -41,18 +39,17 @@ uint32_t mw8080bw_state::screen_update_mw8080bw(screen_device &screen, bitmap_rg video_data = video_data >> 1; } - /* next row, video_data is now 0, so the next line will start - with 4 blank pixels */ + // next row, video_data is now 0, so the next line will start with 4 blank pixels y = y + 1; - /* end of screen? */ + // end of screen? if (y == 0) break; } /* the video RAM is read at every 8 pixels starting with pixel 4 */ else if ((x & 0x07) == 0x04) { - offs_t offs = ((offs_t)y << 5) | (x >> 3); + offs_t const offs = ((offs_t)y << 5) | (x >> 3); video_data = m_main_ram[offs]; } } @@ -95,7 +92,7 @@ uint32_t mw8080bw_state::screen_update_mw8080bw(screen_device &screen, bitmap_rg #define SPCENCTR_BRIGHTNESS_DECAY 10 -uint32_t mw8080bw_state::screen_update_spcenctr(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect) +uint32_t spcenctr_state::screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect) { uint8_t line_buf[256]; /* 256x1 bit RAM */ @@ -105,41 +102,38 @@ uint32_t mw8080bw_state::screen_update_spcenctr(screen_device &screen, bitmap_rg uint8_t draw_line = 0; uint8_t draw_trench = 0; uint8_t draw_floor = 0; - uint8_t width = m_spcenctr_trench_width; + uint8_t width = m_trench_width; uint8_t floor_width = width; - uint8_t center = m_spcenctr_trench_center; + uint8_t center = m_trench_center; memset(line_buf, 0, 256); - if(m_spcenctr_bright_control) - m_spcenctr_brightness = 255; - else if(m_spcenctr_brightness > SPCENCTR_BRIGHTNESS_DECAY) - m_spcenctr_brightness -= SPCENCTR_BRIGHTNESS_DECAY; + if (m_bright_control) + m_brightness = 255; + else if (m_brightness > SPCENCTR_BRIGHTNESS_DECAY) + m_brightness -= SPCENCTR_BRIGHTNESS_DECAY; else - m_spcenctr_brightness = 0; + m_brightness = 0; while (1) { - /* plot the current pixel */ + // plot the current pixel uint8_t bit = video_data & 0x01; pen_t pen = bit ? rgb_t::white() : rgb_t::black(); - /* possibly draw trench in the background, top of trench first */ - if (!(width & 0x80) && draw_trench) + if (!(width & 0x80) && draw_trench) // possibly draw trench in the background, top of trench first { line_buf[x] = draw_line; if (!bit) pen = draw_line ? SPCENCTR_TOP_TRENCH_LIGHT_RGB32_PEN : SPCENCTR_TOP_TRENCH_DARK_RGB32_PEN; } - /* sides of trench? */ - else if (!(floor_width & 0x80) && (draw_trench || draw_floor)) + else if (!(floor_width & 0x80) && (draw_trench || draw_floor)) // sides of trench? { if (!bit) pen = line_buf[x] ? SPCENCTR_SIDE_TRENCH_LIGHT_RGB32_PEN : SPCENCTR_SIDE_TRENCH_DARK_RGB32_PEN; } - /* bottom of trench? */ - else if (draw_floor) + else if (draw_floor) // bottom of trench? { line_buf[x] = line_buf[x - 1]; @@ -147,8 +141,8 @@ uint32_t mw8080bw_state::screen_update_spcenctr(screen_device &screen, bitmap_rg pen = line_buf[x] ? SPCENCTR_BOTTOM_TRENCH_LIGHT_RGB32_PEN : SPCENCTR_BOTTOM_TRENCH_DARK_RGB32_PEN; } - if(m_spcenctr_brightness > (pen & 0xff)) - pen = rgb_t(m_spcenctr_brightness, m_spcenctr_brightness, m_spcenctr_brightness); + if (m_brightness > (pen & 0xff)) + pen = rgb_t(m_brightness, m_brightness, m_brightness); bitmap.pix32(y - MW8080BW_VCOUNTER_START_NO_VBLANK, x) = pen; @@ -156,25 +150,19 @@ uint32_t mw8080bw_state::screen_update_spcenctr(screen_device &screen, bitmap_rg width = width + ((center & 0x80) ? -1 : 1); floor_width = floor_width + ((center & 0x80) ? -1 : 1); - /* next pixel */ + // next pixel video_data = video_data >> 1; x = x + 1; - /* end of line? */ - if (x == 0) + if (x == 0) // end of line? { - offs_t offs; - uint8_t trench_control; - - /* yes, flush out the shift register */ - int i; - - for (i = 0; i < 4; i++) + // yes, flush out the shift register + for (int i = 0; i < 4; i++) { - if(video_data & 0x01) + if (video_data & 0x01) pen = rgb_t::white(); - else if(m_spcenctr_brightness) - pen = rgb_t(m_spcenctr_brightness, m_spcenctr_brightness, m_spcenctr_brightness); + else if(m_brightness) + pen = rgb_t(m_brightness, m_brightness, m_brightness); else pen = rgb_t::black(); @@ -184,8 +172,8 @@ uint32_t mw8080bw_state::screen_update_spcenctr(screen_device &screen, bitmap_rg } /* update the trench control for the next line */ - offs = ((offs_t)y << 5) | 0x1f; - trench_control = m_main_ram[offs]; + offs_t const offs = ((offs_t)y << 5) | 0x1f; + uint8_t const trench_control = m_main_ram[offs]; if (trench_control & 0x40) draw_trench = 1; @@ -201,26 +189,24 @@ uint32_t mw8080bw_state::screen_update_spcenctr(screen_device &screen, bitmap_rg draw_line = (trench_control & 0x80) >> 7; - /* add the lower 2 bits stored in the slope array to width */ + // add the lower 2 bits stored in the slope array to width if (draw_trench) - width = width + (m_spcenctr_trench_slope[y & 0x0f] & 0x03); + width = width + (m_trench_slope[y & 0x0f] & 0x03); - /* add the higher 2 bits stored in the slope array to floor width */ + // add the higher 2 bits stored in the slope array to floor width if (draw_floor) - floor_width = floor_width + ((m_spcenctr_trench_slope[y & 0x0f] & 0x0c) >> 2); + floor_width = floor_width + ((m_trench_slope[y & 0x0f] & 0x0c) >> 2); - /* next row, video_data is now 0, so the next line will start - with 4 blank pixels */ + // next row, video_data is now 0, so the next line will start with 4 blank pixels y = y + 1; - /* end of screen? */ + // end of screen? if (y == 0) break; } - /* the video RAM is read at every 8 pixels starting with pixel 4 */ - else if ((x & 0x07) == 0x04) + else if ((x & 0x07) == 0x04) // the video RAM is read at every 8 pixels starting with pixel 4 { - offs_t offs = ((offs_t)y << 5) | (x >> 3); + offs_t const offs = ((offs_t)y << 5) | (x >> 3); video_data = m_main_ram[offs]; } } |