diff options
Diffstat (limited to 'src/devices/sound')
90 files changed, 1644 insertions, 732 deletions
diff --git a/src/devices/sound/2203intf.cpp b/src/devices/sound/2203intf.cpp index faf3072e94e..02ad8a41579 100644 --- a/src/devices/sound/2203intf.cpp +++ b/src/devices/sound/2203intf.cpp @@ -130,34 +130,34 @@ void ym2203_device::device_reset() } -READ8_MEMBER( ym2203_device::read ) +u8 ym2203_device::read(offs_t offset) { return ym2203_read(m_chip, offset & 1); } -WRITE8_MEMBER( ym2203_device::write ) +void ym2203_device::write(offs_t offset, u8 data) { ym2203_write(m_chip, offset & 1, data); } -READ8_MEMBER( ym2203_device::status_port_r ) +u8 ym2203_device::status_port_r() { - return read(space, 0); + return read(0); } -READ8_MEMBER( ym2203_device::read_port_r ) +u8 ym2203_device::read_port_r() { - return read(space, 1); + return read(1); } -WRITE8_MEMBER( ym2203_device::control_port_w ) +void ym2203_device::control_port_w(u8 data) { - write(space, 0, data); + write(0, data); } -WRITE8_MEMBER( ym2203_device::write_port_w ) +void ym2203_device::write_port_w(u8 data) { - write(space, 1, data); + write(1, data); } DEFINE_DEVICE_TYPE(YM2203, ym2203_device, "ym2203", "YM2203 OPN") diff --git a/src/devices/sound/2203intf.h b/src/devices/sound/2203intf.h index 93e09d9a9dc..8dd456f50bd 100644 --- a/src/devices/sound/2203intf.h +++ b/src/devices/sound/2203intf.h @@ -20,13 +20,13 @@ public: template <class Object> devcb_base &set_irq_handler(Object &&cb) { return m_irq_handler.set_callback(std::forward<Object>(cb)); } auto irq_handler() { return m_irq_handler.bind(); } - DECLARE_READ8_MEMBER( read ); - DECLARE_WRITE8_MEMBER( write ); + u8 read(offs_t offset); + void write(offs_t offset, u8 data); - DECLARE_READ8_MEMBER( status_port_r ); - DECLARE_READ8_MEMBER( read_port_r ); - DECLARE_WRITE8_MEMBER( control_port_w ); - DECLARE_WRITE8_MEMBER( write_port_w ); + u8 status_port_r(); + u8 read_port_r(); + void control_port_w(u8 data); + void write_port_w(u8 data); // update request from fm.cpp static void update_request(device_t *param) { downcast<ym2203_device *>(param)->update_request(); } diff --git a/src/devices/sound/2608intf.cpp b/src/devices/sound/2608intf.cpp index 1445de91f37..6c31c2aea0f 100644 --- a/src/devices/sound/2608intf.cpp +++ b/src/devices/sound/2608intf.cpp @@ -141,12 +141,12 @@ void ym2608_device::rom_bank_updated() } -READ8_MEMBER( ym2608_device::read ) +u8 ym2608_device::read(offs_t offset) { return ym2608_read(m_chip, offset & 3); } -WRITE8_MEMBER( ym2608_device::write ) +void ym2608_device::write(offs_t offset, u8 data) { ym2608_write(m_chip, offset & 3, data); } diff --git a/src/devices/sound/2608intf.h b/src/devices/sound/2608intf.h index 76c69ec3961..23506b66eea 100644 --- a/src/devices/sound/2608intf.h +++ b/src/devices/sound/2608intf.h @@ -21,8 +21,8 @@ public: template <class Object> devcb_base &set_irq_handler(Object &&cb) { return m_irq_handler.set_callback(std::forward<Object>(cb)); } auto irq_handler() { return m_irq_handler.bind(); } - DECLARE_READ8_MEMBER( read ); - DECLARE_WRITE8_MEMBER( write ); + u8 read(offs_t offset); + void write(offs_t offset, u8 data); // update request from fm.cpp static void update_request(device_t *param) { downcast<ym2608_device *>(param)->update_request(); } diff --git a/src/devices/sound/2610intf.cpp b/src/devices/sound/2610intf.cpp index 84598507274..fe4077b2d40 100644 --- a/src/devices/sound/2610intf.cpp +++ b/src/devices/sound/2610intf.cpp @@ -164,12 +164,12 @@ device_memory_interface::space_config_vector ym2610_device::memory_space_config( } -READ8_MEMBER( ym2610_device::read ) +u8 ym2610_device::read(offs_t offset) { return ym2610_read(m_chip, offset & 3); } -WRITE8_MEMBER( ym2610_device::write ) +void ym2610_device::write(offs_t offset, u8 data) { ym2610_write(m_chip, offset & 3, data); } diff --git a/src/devices/sound/2610intf.h b/src/devices/sound/2610intf.h index ff736e4890e..1a1515e081c 100644 --- a/src/devices/sound/2610intf.h +++ b/src/devices/sound/2610intf.h @@ -23,8 +23,8 @@ public: virtual space_config_vector memory_space_config() const override; - DECLARE_READ8_MEMBER( read ); - DECLARE_WRITE8_MEMBER( write ); + u8 read(offs_t offset); + void write(offs_t offset, u8 data); // update request from fm.cpp static void update_request(device_t *param) { downcast<ym2610_device *>(param)->update_request(); } diff --git a/src/devices/sound/2612intf.cpp b/src/devices/sound/2612intf.cpp index 21ca436a004..b8e440666ec 100644 --- a/src/devices/sound/2612intf.cpp +++ b/src/devices/sound/2612intf.cpp @@ -129,12 +129,12 @@ void ym2612_device::device_reset() } -READ8_MEMBER( ym2612_device::read ) +u8 ym2612_device::read(offs_t offset) { return ym2612_read(m_chip, offset & 3); } -WRITE8_MEMBER( ym2612_device::write ) +void ym2612_device::write(offs_t offset, u8 data) { ym2612_write(m_chip, offset & 3, data); } diff --git a/src/devices/sound/2612intf.h b/src/devices/sound/2612intf.h index 5dc31593685..13255b59e8f 100644 --- a/src/devices/sound/2612intf.h +++ b/src/devices/sound/2612intf.h @@ -15,8 +15,8 @@ public: template <class Object> devcb_base &set_irq_handler(Object &&cb) { return m_irq_handler.set_callback(std::forward<Object>(cb)); } auto irq_handler() { return m_irq_handler.bind(); } - DECLARE_READ8_MEMBER( read ); - DECLARE_WRITE8_MEMBER( write ); + u8 read(offs_t offset); + void write(offs_t offset, u8 data); // update request from fm.cpp static void update_request(device_t *param) { downcast<ym2612_device *>(param)->update_request(); } diff --git a/src/devices/sound/262intf.cpp b/src/devices/sound/262intf.cpp index 905d9afd8b6..0de5e274ca9 100644 --- a/src/devices/sound/262intf.cpp +++ b/src/devices/sound/262intf.cpp @@ -121,12 +121,12 @@ void ymf262_device::device_clock_changed() m_stream->set_sample_rate(rate); } -READ8_MEMBER( ymf262_device::read ) +u8 ymf262_device::read(offs_t offset) { return ymf262_read(m_chip, offset & 3); } -WRITE8_MEMBER( ymf262_device::write ) +void ymf262_device::write(offs_t offset, u8 data) { ymf262_write(m_chip, offset & 3, data); } diff --git a/src/devices/sound/262intf.h b/src/devices/sound/262intf.h index 96d819b761b..816b2903831 100644 --- a/src/devices/sound/262intf.h +++ b/src/devices/sound/262intf.h @@ -13,8 +13,8 @@ public: // configuration helpers auto irq_handler() { return m_irq_handler.bind(); } - DECLARE_READ8_MEMBER( read ); - DECLARE_WRITE8_MEMBER( write ); + u8 read(offs_t offset); + void write(offs_t offset, u8 data); protected: // device-level overrides diff --git a/src/devices/sound/3526intf.cpp b/src/devices/sound/3526intf.cpp index 86ee4a5c0b7..2418b9e65a1 100644 --- a/src/devices/sound/3526intf.cpp +++ b/src/devices/sound/3526intf.cpp @@ -130,20 +130,20 @@ void ym3526_device::device_reset() } -READ8_MEMBER( ym3526_device::read ) +u8 ym3526_device::read(offs_t offset) { return ym3526_read(m_chip, offset & 1); } -WRITE8_MEMBER( ym3526_device::write ) +void ym3526_device::write(offs_t offset, u8 data) { ym3526_write(m_chip, offset & 1, data); } -READ8_MEMBER( ym3526_device::status_port_r ) { return read(space, 0); } -READ8_MEMBER( ym3526_device::read_port_r ) { return read(space, 1); } -WRITE8_MEMBER( ym3526_device::control_port_w ) { write(space, 0, data); } -WRITE8_MEMBER( ym3526_device::write_port_w ) { write(space, 1, data); } +u8 ym3526_device::status_port_r() { return read(0); } +u8 ym3526_device::read_port_r() { return read(1); } +void ym3526_device::control_port_w(u8 data) { write(0, data); } +void ym3526_device::write_port_w(u8 data) { write(1, data); } DEFINE_DEVICE_TYPE(YM3526, ym3526_device, "ym3526", "YM3526 OPL") diff --git a/src/devices/sound/3526intf.h b/src/devices/sound/3526intf.h index 338ffb1f2b4..c880cfcfc51 100644 --- a/src/devices/sound/3526intf.h +++ b/src/devices/sound/3526intf.h @@ -15,13 +15,13 @@ public: template <class Object> devcb_base &set_irq_handler(Object &&cb) { return m_irq_handler.set_callback(std::forward<Object>(cb)); } auto irq_handler() { return m_irq_handler.bind(); } - DECLARE_READ8_MEMBER( read ); - DECLARE_WRITE8_MEMBER( write ); + u8 read(offs_t offset); + void write(offs_t offset, u8 data); - DECLARE_READ8_MEMBER( status_port_r ); - DECLARE_READ8_MEMBER( read_port_r ); - DECLARE_WRITE8_MEMBER( control_port_w ); - DECLARE_WRITE8_MEMBER( write_port_w ); + u8 status_port_r(); + u8 read_port_r(); + void control_port_w(u8 data); + void write_port_w(u8 data); protected: // device-level overrides diff --git a/src/devices/sound/3812intf.cpp b/src/devices/sound/3812intf.cpp index 6818a531371..9b29af0599d 100644 --- a/src/devices/sound/3812intf.cpp +++ b/src/devices/sound/3812intf.cpp @@ -131,20 +131,20 @@ void ym3812_device::device_reset() } -READ8_MEMBER( ym3812_device::read ) +u8 ym3812_device::read(offs_t offset) { return ym3812_read(m_chip, offset & 1); } -WRITE8_MEMBER( ym3812_device::write ) +void ym3812_device::write(offs_t offset, u8 data) { ym3812_write(m_chip, offset & 1, data); } -READ8_MEMBER( ym3812_device::status_port_r ) { return read(space, 0); } -READ8_MEMBER( ym3812_device::read_port_r ) { return read(space, 1); } -WRITE8_MEMBER( ym3812_device::control_port_w ) { write(space, 0, data); } -WRITE8_MEMBER( ym3812_device::write_port_w ) { write(space, 1, data); } +u8 ym3812_device::status_port_r() { return read(0); } +u8 ym3812_device::read_port_r() { return read(1); } +void ym3812_device::control_port_w(u8 data) { write(0, data); } +void ym3812_device::write_port_w(u8 data) { write(1, data); } DEFINE_DEVICE_TYPE(YM3812, ym3812_device, "ym3812", "YM3812 OPL2") diff --git a/src/devices/sound/3812intf.h b/src/devices/sound/3812intf.h index 5a4f4eeae2e..56a6accb30a 100644 --- a/src/devices/sound/3812intf.h +++ b/src/devices/sound/3812intf.h @@ -13,13 +13,13 @@ public: template <class Object> devcb_base &set_irq_handler(Object &&cb) { return m_irq_handler.set_callback(std::forward<Object>(cb)); } auto irq_handler() { return m_irq_handler.bind(); } - DECLARE_READ8_MEMBER( read ); - DECLARE_WRITE8_MEMBER( write ); + u8 read(offs_t offset); + void write(offs_t offset, u8 data); - DECLARE_READ8_MEMBER( status_port_r ); - DECLARE_READ8_MEMBER( read_port_r ); - DECLARE_WRITE8_MEMBER( control_port_w ); - DECLARE_WRITE8_MEMBER( write_port_w ); + u8 status_port_r(); + u8 read_port_r(); + void control_port_w(u8 data); + void write_port_w(u8 data); protected: // device-level overrides diff --git a/src/devices/sound/8950intf.cpp b/src/devices/sound/8950intf.cpp index f56f34c88f9..601c9861f33 100644 --- a/src/devices/sound/8950intf.cpp +++ b/src/devices/sound/8950intf.cpp @@ -138,20 +138,20 @@ void y8950_device::rom_bank_updated() } -READ8_MEMBER( y8950_device::read ) +u8 y8950_device::read(offs_t offset) { return y8950_read(m_chip, offset & 1); } -WRITE8_MEMBER( y8950_device::write ) +void y8950_device::write(offs_t offset, u8 data) { y8950_write(m_chip, offset & 1, data); } -READ8_MEMBER( y8950_device::status_port_r ) { return read(space, 0); } -READ8_MEMBER( y8950_device::read_port_r ) { return read(space, 1); } -WRITE8_MEMBER( y8950_device::control_port_w ) { write(space, 0, data); } -WRITE8_MEMBER( y8950_device::write_port_w ) { write(space, 1, data); } +u8 y8950_device::status_port_r() { return read(0); } +u8 y8950_device::read_port_r() { return read(1); } +void y8950_device::control_port_w(u8 data) { write(0, data); } +void y8950_device::write_port_w(u8 data) { write(1, data); } DEFINE_DEVICE_TYPE(Y8950, y8950_device, "y8950", "Y8950 MSX-Audio") diff --git a/src/devices/sound/8950intf.h b/src/devices/sound/8950intf.h index fd65a036ef8..ac4584626e4 100644 --- a/src/devices/sound/8950intf.h +++ b/src/devices/sound/8950intf.h @@ -20,13 +20,13 @@ public: auto io_read() { return m_io_read_handler.bind(); } auto io_write() { return m_io_write_handler.bind(); } - DECLARE_READ8_MEMBER( read ); - DECLARE_WRITE8_MEMBER( write ); + u8 read(offs_t offset); + void write(offs_t offset, u8 data); - DECLARE_READ8_MEMBER( status_port_r ); - DECLARE_READ8_MEMBER( read_port_r ); - DECLARE_WRITE8_MEMBER( control_port_w ); - DECLARE_WRITE8_MEMBER( write_port_w ); + u8 status_port_r(); + u8 read_port_r(); + void control_port_w(u8 data); + void write_port_w(u8 data); protected: // device-level overrides diff --git a/src/devices/sound/ad1848.cpp b/src/devices/sound/ad1848.cpp index 1049a03a177..5db5b3ded2d 100644 --- a/src/devices/sound/ad1848.cpp +++ b/src/devices/sound/ad1848.cpp @@ -29,7 +29,6 @@ void ad1848_device::device_add_mconfig(machine_config &config) DAC_16BIT_R2R(config, m_ldac, 0).add_route(ALL_OUTPUTS, "lspeaker", 0.5); // unknown DAC DAC_16BIT_R2R(config, m_rdac, 0).add_route(ALL_OUTPUTS, "rspeaker", 0.5); // unknown DAC voltage_regulator_device &vref(VOLTAGE_REGULATOR(config, "vref", 0)); - vref.set_output(5.0); vref.add_route(0, "ldac", 1.0, DAC_VREF_POS_INPUT); vref.add_route(0, "ldac", -1.0, DAC_VREF_NEG_INPUT); vref.add_route(0, "rdac", 1.0, DAC_VREF_POS_INPUT); diff --git a/src/devices/sound/astrocde.cpp b/src/devices/sound/astrocde.cpp index e3600a88286..33ae926f34c 100644 --- a/src/devices/sound/astrocde.cpp +++ b/src/devices/sound/astrocde.cpp @@ -86,7 +86,7 @@ astrocade_io_device::astrocade_io_device(const machine_config &mconfig, const ch , m_c_state(0) , m_si_callback(*this) , m_so_callback{{*this}, {*this}, {*this}, {*this}, {*this}, {*this}, {*this}, {*this}} - , m_pots(*this, {finder_base::DUMMY_TAG, finder_base::DUMMY_TAG, finder_base::DUMMY_TAG, finder_base::DUMMY_TAG}) + , m_pots{{*this}, {*this}, {*this}, {*this}} { memset(m_reg, 0, sizeof(uint8_t)*8); memset(m_bitswap, 0, sizeof(uint8_t)*256); @@ -104,6 +104,8 @@ void astrocade_io_device::device_resolve_objects() m_si_callback.resolve_safe(0); for (auto &cb : m_so_callback) cb.resolve_safe(); + for (auto &pot : m_pots) + pot.resolve_safe(0); } @@ -323,7 +325,7 @@ READ8_MEMBER(astrocade_io_device::read) return m_si_callback(space, offset & 7); } else if ((offset & 0x0f) >= 0x0c) - return m_pots[offset & 3].read_safe(0); + return m_pots[offset & 3](); else return 0xff; } diff --git a/src/devices/sound/astrocde.h b/src/devices/sound/astrocde.h index 7eaae126f4f..eddde3a12bb 100644 --- a/src/devices/sound/astrocde.h +++ b/src/devices/sound/astrocde.h @@ -49,7 +49,7 @@ public: // configuration access auto si_cb() { return m_si_callback.bind(); } template <std::size_t Bit> auto so_cb() { return m_so_callback[Bit].bind(); } - template <std::size_t Pot> void set_pot_tag(const char *tag) { m_pots[Pot].set_tag(tag); } + template <std::size_t Pot> auto pot_cb() { return m_pots[Pot].bind(); } protected: // device-level overrides @@ -90,7 +90,7 @@ private: devcb_read8 m_si_callback; devcb_write8 m_so_callback[8]; - optional_ioport_array<4> m_pots; + devcb_read8 m_pots[4]; }; DECLARE_DEVICE_TYPE(ASTROCADE_IO, astrocade_io_device) diff --git a/src/devices/sound/ay8910.cpp b/src/devices/sound/ay8910.cpp index 71dd5854725..9ee02834f67 100644 --- a/src/devices/sound/ay8910.cpp +++ b/src/devices/sound/ay8910.cpp @@ -120,7 +120,7 @@ /*************************************************************************** - ay8910.c + ay8910.cpp Emulation of the AY-3-8910 / YM2149 sound chip. @@ -511,6 +511,56 @@ Yamaha YMZ294: limited info: 0 I/O port between 4MHz (H) and 6MHz (L), while pin 10 is /TEST. OKI M5255, Winbond WF19054, JFC 95101, File KC89C72, Toshiba T7766A : differences to be listed +AY8930 Expanded mode registers : + Bank Register Bits + A 0 xxxx xxxx Channel A Tone period fine tune + A 1 xxxx xxxx Channel A Tone period coarse tune + A 2 xxxx xxxx Channel B Tone period fine tune + A 3 xxxx xxxx Channel B Tone period coarse tune + A 4 xxxx xxxx Channel C Tone period fine tune + A 5 xxxx xxxx Channel C Tone period coarse tune + A 6 xxxx xxxx Noise period + A 7 x--- ---- I/O Port B input(0) / output(1) + -x-- ---- I/O Port A input(0) / output(1) + --x- ---- Channel C Noise enable(0) / disable(1) + ---x ---- Channel B Noise enable(0) / disable(1) + ---- x--- Channel A Noise enable(0) / disable(1) + ---- -x-- Channel C Tone enable(0) / disable(1) + ---- --x- Channel B Tone enable(0) / disable(1) + ---- ---x Channel A Tone enable(0) / disable(1) + A 8 --x- ---- Channel A Envelope mode + ---x xxxx Channel A Tone volume + A 9 --x- ---- Channel B Envelope mode + ---x xxxx Channel B Tone volume + A A --x- ---- Channel C Envelope mode + ---x xxxx Channel C Tone volume + A B xxxx xxxx Channel A Envelope period fine tune + A C xxxx xxxx Channel A Envelope period coarse tune + A D 101- ---- 101 = Expanded mode enable, other AY-3-8910A Compatiblity mode + ---0 ---- 0 for Register Bank A + ---- xxxx Channel A Envelope Shape/Cycle + A E xxxx xxxx 8 bit Parallel I/O on Port A + A F xxxx xxxx 8 bit Parallel I/O on Port B + + B 0 xxxx xxxx Channel B Envelope period fine tune + B 1 xxxx xxxx Channel B Envelope period coarse tune + B 2 xxxx xxxx Channel C Envelope period fine tune + B 3 xxxx xxxx Channel C Envelope period coarse tune + B 4 ---- xxxx Channel B Envelope Shape/Cycle + B 5 ---- xxxx Channel C Envelope Shape/Cycle + B 6 ---- xxxx Channel A Duty Cycle + B 7 ---- xxxx Channel B Duty Cycle + B 8 ---- xxxx Channel C Duty Cycle + B 9 xxxx xxxx Noise "And" Mask + B A xxxx xxxx Noise "Or" Mask + B B Reserved (Read as 0) + B C Reserved (Read as 0) + B D 101- ---- 101 = Expanded mode enable, other AY-3-8910A Compatiblity mode + ---1 ---- 1 for Register Bank B + ---- xxxx Channel A Envelope Shape + B E Reserved (Read as 0) + B F Test (Function unknown) + Decaps: AY-3-8914 - http://siliconpr0n.org/map/gi/ay-3-8914/mz_mit20x/ AY-3-8910 - http://privatfrickler.de/blick-auf-den-chip-soundchip-general-instruments-ay-3-8910/ @@ -735,7 +785,7 @@ static const ay8910_device::mosfet_param ay8910_mosfet_param = * *************************************/ -static inline void build_3D_table(double rl, const ay8910_device::ay_ym_param *par, const ay8910_device::ay_ym_param *par_env, int normalize, double factor, int zero_is_off, int32_t *tab) +static inline void build_3D_table(double rl, const ay8910_device::ay_ym_param *par, const ay8910_device::ay_ym_param *par_env, int normalize, double factor, int zero_is_off, s32 *tab) { double min = 10.0, max = 0.0; @@ -794,7 +844,7 @@ static inline void build_3D_table(double rl, const ay8910_device::ay_ym_param *p /* for (e=0;e<16;e++) printf("%d %d\n",e<<10, tab[e<<10]); */ } -static inline void build_single_table(double rl, const ay8910_device::ay_ym_param *par, int normalize, int32_t *tab, int zero_is_off) +static inline void build_single_table(double rl, const ay8910_device::ay_ym_param *par, int normalize, s32 *tab, int zero_is_off) { int j; double rt; @@ -833,7 +883,7 @@ static inline void build_single_table(double rl, const ay8910_device::ay_ym_para } -static inline void build_mosfet_resistor_table(const ay8910_device::mosfet_param &par, const double rd, int32_t *tab) +static inline void build_mosfet_resistor_table(const ay8910_device::mosfet_param &par, const double rd, s32 *tab) { int j; @@ -857,7 +907,7 @@ static inline void build_mosfet_resistor_table(const ay8910_device::mosfet_param } -uint16_t ay8910_device::mix_3D() +u16 ay8910_device::mix_3D() { int indx = 0, chan; @@ -889,6 +939,7 @@ uint16_t ay8910_device::mix_3D() void ay8910_device::ay8910_write_reg(int r, int v) { //if (r >= 11 && r <= 13 ) printf("%d %x %02x\n", PSG->index, r, v); + device_type chip_type = type(); m_regs[r] = v; switch( r ) @@ -930,6 +981,14 @@ void ay8910_device::ay8910_write_reg(int r, int v) m_last_enable = m_regs[AY_ENABLE]; break; case AY_ESHAPE: + if (chip_type == AY8930) + { + m_mode = (v >> 4) & 0xf; + if ((m_mode & 0xe) == 0xa) // AY8930 expanded mode + logerror("warning: activated unemulated extended mode at %s, bank %02x\n", name(), m_mode & 1); + else if (m_mode & 0xf) + logerror("warning: activated unknown mode %02x at %s\n", m_mode & 0xf, name()); + } if ( (v & 0x0f) > 0) osd_printf_verbose("EShape\n"); m_attack = (m_regs[AY_ESHAPE] & 0x04) ? m_env_step_mask : 0x00; @@ -1175,6 +1234,7 @@ void ay8910_device::ay8910_statesave() save_item(NAME(m_attack)); save_item(NAME(m_holding)); save_item(NAME(m_rng)); + save_item(NAME(m_mode)); } //------------------------------------------------- @@ -1202,7 +1262,7 @@ void ay8910_device::device_start() m_streams = 1; } - m_vol3d_table = make_unique_clear<int32_t[]>(8*32*32*32); + m_vol3d_table = make_unique_clear<s32[]>(8*32*32*32); build_mixer_table(); @@ -1233,7 +1293,7 @@ void ay8910_device::ay8910_reset_ym() m_count_env = 0; m_prescale_noise = 0; m_last_enable = -1; /* force a write */ - for (i = 0;i < AY_PORTA;i++) + for (i = 0; i < AY_PORTA; i++) ay8910_write_reg(i,0); m_ready = 1; #if ENABLE_REGISTER_TEST @@ -1278,7 +1338,7 @@ void ay8910_device::device_clock_changed() ay_set_clock(clock()); } -void ay8910_device::ay8910_write_ym(int addr, uint8_t data) +void ay8910_device::ay8910_write_ym(int addr, u8 data) { if (addr & 1) { @@ -1309,7 +1369,7 @@ void ay8910_device::ay8910_write_ym(int addr, uint8_t data) } } -uint8_t ay8910_device::ay8910_read_ym() +u8 ay8910_device::ay8910_read_ym() { device_type chip_type = type(); int r = m_register_latch; @@ -1358,13 +1418,13 @@ uint8_t ay8910_device::ay8910_read_ym() - YM2149: no anomaly */ if (chip_type == AY8910) { - const uint8_t mask[0x10]={ + const u8 mask[0x10]={ 0xff,0x0f,0xff,0x0f,0xff,0x0f,0x1f,0xff,0x1f,0x1f,0x1f,0xff,0xff,0x0f,0xff,0xff }; return m_regs[r] & mask[r]; } else if (chip_type == AY8914) { - const uint8_t mask[0x10]={ + const u8 mask[0x10]={ 0xff,0x0f,0xff,0x0f,0xff,0x0f,0x1f,0xff,0x3f,0x3f,0x3f,0xff,0xff,0x0f,0xff,0xff }; return m_regs[r] & mask[r]; @@ -1394,74 +1454,69 @@ void ay8910_device::device_reset() * *************************************/ -READ8_MEMBER( ay8910_device::data_r ) -{ - return ay8910_read_ym(); -} - -WRITE8_MEMBER( ay8910_device::address_w ) +void ay8910_device::address_w(u8 data) { #if ENABLE_REGISTER_TEST return; #else - data_address_w(space, 1, data); + ay8910_write_ym(0, data); #endif } -WRITE8_MEMBER( ay8910_device::data_w ) +void ay8910_device::data_w(u8 data) { #if ENABLE_REGISTER_TEST return; #else - data_address_w(space, 0, data); + ay8910_write_ym(1, data); #endif } // here, BC1 is hooked up to A0 on the host and BC2 is hooked up to A1 -WRITE8_MEMBER( ay8910_device::write_bc1_bc2 ) +void ay8910_device::write_bc1_bc2(offs_t offset, u8 data) { switch (offset & 3) { case 0: // latch address - address_w(space, 0, data); + address_w(data); break; case 1: // inactive break; case 2: // write to psg - data_w(space, 0, data); + data_w(data); break; case 3: // latch address - address_w(space, 0, data); + address_w(data); break; } } -static const int mapping8914to8910[16] = { 0, 2, 4, 11, 1, 3, 5, 12, 7, 6, 13, 8, 9, 10, 14, 15 }; +static const u8 mapping8914to8910[16] = { 0, 2, 4, 11, 1, 3, 5, 12, 7, 6, 13, 8, 9, 10, 14, 15 }; -READ8_MEMBER( ay8914_device::read ) +u8 ay8914_device::read(offs_t offset) { - uint16_t rv; - address_w(space, 0, mapping8914to8910[offset & 0xf]); - rv = (uint16_t) data_r(space, 0); + u8 rv; + address_w(mapping8914to8910[offset & 0xf]); + rv = data_r(); return rv; } -WRITE8_MEMBER( ay8914_device::write ) +void ay8914_device::write(offs_t offset, u8 data) { - address_w(space, 0, mapping8914to8910[offset & 0xf]); - data_w(space, 0, data & 0xff); + address_w(mapping8914to8910[offset & 0xf]); + data_w(data & 0xff); } DEFINE_DEVICE_TYPE(AY8910, ay8910_device, "ay8910", "AY-3-8910A PSG") -ay8910_device::ay8910_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) +ay8910_device::ay8910_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) : ay8910_device(mconfig, AY8910, tag, owner, clock, PSG_TYPE_AY, 3, 2) { } -ay8910_device::ay8910_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock, +ay8910_device::ay8910_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 clock, psg_type_t psg_type, int streams, int ioports) : device_t(mconfig, type, tag, owner, clock), device_sound_interface(mconfig, *this), @@ -1483,6 +1538,7 @@ ay8910_device::ay8910_device(const machine_config &mconfig, device_type type, co m_attack(0), m_holding(0), m_rng(0), + m_mode(0), m_env_step_mask(psg_type == PSG_TYPE_AY ? 0x0f : 0x1f), m_step( psg_type == PSG_TYPE_AY ? 2 : 1), m_zero_is_off( psg_type == PSG_TYPE_AY ? 1 : 0), @@ -1528,7 +1584,7 @@ void ay8910_device::set_type(psg_type_t psg_type) DEFINE_DEVICE_TYPE(AY8912, ay8912_device, "ay8912", "AY-3-8912A PSG") -ay8912_device::ay8912_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) +ay8912_device::ay8912_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) : ay8910_device(mconfig, AY8912, tag, owner, clock, PSG_TYPE_AY, 3, 1) { } @@ -1536,7 +1592,7 @@ ay8912_device::ay8912_device(const machine_config &mconfig, const char *tag, dev DEFINE_DEVICE_TYPE(AY8913, ay8913_device, "ay8913", "AY-3-8913 PSG") -ay8913_device::ay8913_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) +ay8913_device::ay8913_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) : ay8910_device(mconfig, AY8913, tag, owner, clock, PSG_TYPE_AY, 3, 0) { } @@ -1544,7 +1600,7 @@ ay8913_device::ay8913_device(const machine_config &mconfig, const char *tag, dev DEFINE_DEVICE_TYPE(AY8914, ay8914_device, "ay8914", "AY-3-8914A PSG") -ay8914_device::ay8914_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) +ay8914_device::ay8914_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) : ay8910_device(mconfig, AY8914, tag, owner, clock, PSG_TYPE_AY, 3, 2) { } @@ -1552,7 +1608,7 @@ ay8914_device::ay8914_device(const machine_config &mconfig, const char *tag, dev DEFINE_DEVICE_TYPE(AY8930, ay8930_device, "ay8930", "AY8930 EPSG") -ay8930_device::ay8930_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) +ay8930_device::ay8930_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) : ay8910_device(mconfig, AY8930, tag, owner, clock, PSG_TYPE_AY, 3, 2) { } @@ -1560,7 +1616,7 @@ ay8930_device::ay8930_device(const machine_config &mconfig, const char *tag, dev DEFINE_DEVICE_TYPE(YM2149, ym2149_device, "ym2149", "YM2149 SSG") -ym2149_device::ym2149_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) +ym2149_device::ym2149_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) : ay8910_device(mconfig, YM2149, tag, owner, clock, PSG_TYPE_YM, 3, 2) { } @@ -1568,7 +1624,7 @@ ym2149_device::ym2149_device(const machine_config &mconfig, const char *tag, dev DEFINE_DEVICE_TYPE(YM3439, ym3439_device, "ym3439", "YM3439 SSGC") -ym3439_device::ym3439_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) +ym3439_device::ym3439_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) : ay8910_device(mconfig, YM3439, tag, owner, clock, PSG_TYPE_YM, 3, 2) { } @@ -1576,7 +1632,7 @@ ym3439_device::ym3439_device(const machine_config &mconfig, const char *tag, dev DEFINE_DEVICE_TYPE(YMZ284, ymz284_device, "ymz284", "YMZ284 SSGL") -ymz284_device::ymz284_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) +ymz284_device::ymz284_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) : ay8910_device(mconfig, YMZ284, tag, owner, clock, PSG_TYPE_YM, 1, 0) { } @@ -1584,7 +1640,7 @@ ymz284_device::ymz284_device(const machine_config &mconfig, const char *tag, dev DEFINE_DEVICE_TYPE(YMZ294, ymz294_device, "ymz294", "YMZ294 SSGLP") -ymz294_device::ymz294_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) +ymz294_device::ymz294_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) : ay8910_device(mconfig, YMZ294, tag, owner, clock, PSG_TYPE_YM, 1, 0) { } diff --git a/src/devices/sound/ay8910.h b/src/devices/sound/ay8910.h index 29a7ae674d4..c1bbf718245 100644 --- a/src/devices/sound/ay8910.h +++ b/src/devices/sound/ay8910.h @@ -62,7 +62,7 @@ public: }; // construction/destruction - ay8910_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); + ay8910_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock); // configuration helpers void set_flags(int flags) { m_flags = flags; } @@ -73,24 +73,21 @@ public: auto port_a_write_callback() { return m_port_a_write_cb.bind(); } auto port_b_write_callback() { return m_port_b_write_cb.bind(); } - DECLARE_READ8_MEMBER( data_r ); - DECLARE_WRITE8_MEMBER( address_w ); - DECLARE_WRITE8_MEMBER( data_w ); - u8 read_data() { return ay8910_read_ym(); } - void write_address(u8 data) { ay8910_write_ym(0, data); } - void write_data(u8 data) { ay8910_write_ym(1, data); } + u8 data_r() { return ay8910_read_ym(); } + void address_w(u8 data); + void data_w(u8 data); /* /RES */ - DECLARE_WRITE8_MEMBER( reset_w ) { ay8910_reset_ym(); } + void reset_w(u8 data = 0) { ay8910_reset_ym(); } // use this when BC1 == A0; here, BC1=0 selects 'data' and BC1=1 selects 'latch address' - DECLARE_WRITE8_MEMBER( data_address_w ) { ay8910_write_ym(~offset & 1, data); } // note that directly connecting BC1 to A0 puts data on 0 and address on 1 + void data_address_w(offs_t offset, u8 data) { ay8910_write_ym(~offset & 1, data); } // note that directly connecting BC1 to A0 puts data on 0 and address on 1 // use this when BC1 == !A0; here, BC1=0 selects 'latch address' and BC1=1 selects 'data' - DECLARE_WRITE8_MEMBER( address_data_w ) { ay8910_write_ym(offset & 1, data); } + void address_data_w(offs_t offset, u8 data) { ay8910_write_ym(offset & 1, data); } // bc1=a0, bc2=a1 - DECLARE_WRITE8_MEMBER(write_bc1_bc2); + void write_bc1_bc2(offs_t offset, u8 data); void set_volume(int channel,int volume); void ay_set_clock(int clock); @@ -113,13 +110,10 @@ public: // internal interface for PSG component of YM device // FIXME: these should be private, but vector06 accesses them directly - void ay8910_write_ym(int addr, uint8_t data); - uint8_t ay8910_read_ym(); - void ay8910_reset_ym(); protected: ay8910_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, - uint32_t clock, psg_type_t psg_type, int streams, int ioports); + u32 clock, psg_type_t psg_type, int streams, int ioports); // device-level overrides virtual void device_start() override; @@ -140,11 +134,15 @@ private: // internal helpers void set_type(psg_type_t psg_type); - inline uint16_t mix_3D(); + inline u16 mix_3D(); void ay8910_write_reg(int r, int v); void build_mixer_table(); void ay8910_statesave(); + void ay8910_write_ym(int addr, u8 data); + u8 ay8910_read_ym(); + void ay8910_reset_ym(); + // internal state psg_type_t m_type; int m_streams; @@ -152,28 +150,29 @@ private: int m_ready; sound_stream *m_channel; bool m_active; - int32_t m_register_latch; - uint8_t m_regs[16]; - int32_t m_last_enable; - int32_t m_count[NUM_CHANNELS]; - uint8_t m_output[NUM_CHANNELS]; - uint8_t m_prescale_noise; - int32_t m_count_noise; - int32_t m_count_env; - int8_t m_env_step; - uint32_t m_env_volume; - uint8_t m_hold,m_alternate,m_attack,m_holding; - int32_t m_rng; - uint8_t m_env_step_mask; + s32 m_register_latch; + u8 m_regs[16]; + s32 m_last_enable; + s32 m_count[NUM_CHANNELS]; + u8 m_output[NUM_CHANNELS]; + u8 m_prescale_noise; + s32 m_count_noise; + s32 m_count_env; + s8 m_env_step; + u32 m_env_volume; + u8 m_hold,m_alternate,m_attack,m_holding; + s32 m_rng; + u8 m_mode; + u8 m_env_step_mask; /* init parameters ... */ int m_step; int m_zero_is_off; - uint8_t m_vol_enabled[NUM_CHANNELS]; + u8 m_vol_enabled[NUM_CHANNELS]; const ay_ym_param *m_par; const ay_ym_param *m_par_env; - int32_t m_vol_table[NUM_CHANNELS][16]; - int32_t m_env_table[NUM_CHANNELS][32]; - std::unique_ptr<int32_t[]> m_vol3d_table; + s32 m_vol_table[NUM_CHANNELS][16]; + s32 m_env_table[NUM_CHANNELS][32]; + std::unique_ptr<s32[]> m_vol3d_table; int m_flags; /* Flags */ int m_res_load[3]; /* Load on channel in ohms */ devcb_read8 m_port_a_read_cb; @@ -187,7 +186,7 @@ DECLARE_DEVICE_TYPE(AY8910, ay8910_device) class ay8912_device : public ay8910_device { public: - ay8912_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); + ay8912_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock); }; DECLARE_DEVICE_TYPE(AY8912, ay8912_device) @@ -195,7 +194,7 @@ DECLARE_DEVICE_TYPE(AY8912, ay8912_device) class ay8913_device : public ay8910_device { public: - ay8913_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); + ay8913_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock); }; DECLARE_DEVICE_TYPE(AY8913, ay8913_device) @@ -203,11 +202,11 @@ DECLARE_DEVICE_TYPE(AY8913, ay8913_device) class ay8914_device : public ay8910_device { public: - ay8914_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); + ay8914_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock); /* AY8914 handlers needed due to different register map */ - DECLARE_READ8_MEMBER( read ); - DECLARE_WRITE8_MEMBER( write ); + u8 read(offs_t offset); + void write(offs_t offset, u8 data); }; DECLARE_DEVICE_TYPE(AY8914, ay8914_device) @@ -215,7 +214,7 @@ DECLARE_DEVICE_TYPE(AY8914, ay8914_device) class ay8930_device : public ay8910_device { public: - ay8930_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); + ay8930_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock); }; DECLARE_DEVICE_TYPE(AY8930, ay8930_device) @@ -223,7 +222,7 @@ DECLARE_DEVICE_TYPE(AY8930, ay8930_device) class ym2149_device : public ay8910_device { public: - ym2149_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); + ym2149_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock); }; DECLARE_DEVICE_TYPE(YM2149, ym2149_device) @@ -231,7 +230,7 @@ DECLARE_DEVICE_TYPE(YM2149, ym2149_device) class ym3439_device : public ay8910_device { public: - ym3439_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); + ym3439_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock); }; DECLARE_DEVICE_TYPE(YM3439, ym3439_device) @@ -239,7 +238,7 @@ DECLARE_DEVICE_TYPE(YM3439, ym3439_device) class ymz284_device : public ay8910_device { public: - ymz284_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); + ymz284_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock); }; DECLARE_DEVICE_TYPE(YMZ284, ymz284_device) @@ -247,7 +246,7 @@ DECLARE_DEVICE_TYPE(YMZ284, ymz284_device) class ymz294_device : public ay8910_device { public: - ymz294_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); + ymz294_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock); }; DECLARE_DEVICE_TYPE(YMZ294, ymz294_device) diff --git a/src/devices/sound/bsmt2000.cpp b/src/devices/sound/bsmt2000.cpp index 4104b83a619..f29e429390a 100644 --- a/src/devices/sound/bsmt2000.cpp +++ b/src/devices/sound/bsmt2000.cpp @@ -180,8 +180,8 @@ void bsmt2000_device::sound_stream_update(sound_stream &stream, stream_sample_t // just fill with current left/right values for (int samp = 0; samp < samples; samp++) { - outputs[0][samp] = m_left_data * 16; - outputs[1][samp] = m_right_data * 16; + outputs[0][samp] = m_left_data; + outputs[1][samp] = m_right_data; } } @@ -264,8 +264,8 @@ READ16_MEMBER( bsmt2000_device::tms_data_r ) READ16_MEMBER( bsmt2000_device::tms_rom_r ) { - // underlying logic assumes this is a sign-extended value - return (int8_t)read_byte((m_rom_bank << 16) + m_rom_address); + // DSP code expects a 16-bit value with the data in the high byte + return (int16_t)(read_byte((m_rom_bank << 16) + m_rom_address) << 8); } diff --git a/src/devices/sound/c140.cpp b/src/devices/sound/c140.cpp index 0d72ac8be24..b5534959230 100644 --- a/src/devices/sound/c140.cpp +++ b/src/devices/sound/c140.cpp @@ -374,14 +374,14 @@ void c140_device::sound_stream_update(sound_stream &stream, stream_sample_t **in } -READ8_MEMBER( c140_device::c140_r ) +u8 c140_device::c140_r(offs_t offset) { offset&=0x1ff; return m_REG[offset]; } -WRITE8_MEMBER( c140_device::c140_w ) +void c140_device::c140_w(offs_t offset, u8 data) { m_stream->update(); diff --git a/src/devices/sound/c140.h b/src/devices/sound/c140.h index cdc84a38fd1..dba89c78089 100644 --- a/src/devices/sound/c140.h +++ b/src/devices/sound/c140.h @@ -32,8 +32,8 @@ public: // configuration void set_bank_type(C140_TYPE bank) { m_banking_type = bank; } - DECLARE_READ8_MEMBER( c140_r ); - DECLARE_WRITE8_MEMBER( c140_w ); + u8 c140_r(offs_t offset); + void c140_w(offs_t offset, u8 data); protected: // device-level overrides diff --git a/src/devices/sound/cdp1864.cpp b/src/devices/sound/cdp1864.cpp index 58697352b8d..de39b3390c8 100644 --- a/src/devices/sound/cdp1864.cpp +++ b/src/devices/sound/cdp1864.cpp @@ -470,18 +470,18 @@ void cdp1864_device::initialize_palette() // foreground colors uint8_t r = 0, g = 0, b = 0; - if (m_chr_r != RES_INF) r = combine_1_weights(color_weights_r, BIT(i, 0)); - if (m_chr_b != RES_INF) b = combine_1_weights(color_weights_b, BIT(i, 1)); - if (m_chr_g != RES_INF) g = combine_1_weights(color_weights_g, BIT(i, 2)); + if (m_chr_r != RES_INF) r = combine_weights(color_weights_r, BIT(i, 0)); + if (m_chr_b != RES_INF) b = combine_weights(color_weights_b, BIT(i, 1)); + if (m_chr_g != RES_INF) g = combine_weights(color_weights_g, BIT(i, 2)); m_palette[i] = rgb_t(r, g, b); // background colors r = 0, g = 0, b = 0; - if (m_chr_r != RES_INF) r = combine_1_weights(color_weights_bkg_r, BIT(i, 0)); - if (m_chr_b != RES_INF) b = combine_1_weights(color_weights_bkg_b, BIT(i, 1)); - if (m_chr_g != RES_INF) g = combine_1_weights(color_weights_bkg_g, BIT(i, 2)); + if (m_chr_r != RES_INF) r = combine_weights(color_weights_bkg_r, BIT(i, 0)); + if (m_chr_b != RES_INF) b = combine_weights(color_weights_bkg_b, BIT(i, 1)); + if (m_chr_g != RES_INF) g = combine_weights(color_weights_bkg_g, BIT(i, 2)); m_palette[i + 8] = rgb_t(r, g, b); } diff --git a/src/devices/sound/cdp1869.cpp b/src/devices/sound/cdp1869.cpp index 1347081549a..661611531d8 100644 --- a/src/devices/sound/cdp1869.cpp +++ b/src/devices/sound/cdp1869.cpp @@ -88,7 +88,8 @@ void cdp1869_device::page_map(address_map &map) // default address map void cdp1869_device::cdp1869(address_map &map) { - map(0x000, 0x7ff).ram(); + if (!has_configured_map(0)) + map(0x000, 0x7ff).ram(); } @@ -359,7 +360,7 @@ cdp1869_device::cdp1869_device(const machine_config &mconfig, const char *tag, d m_color_clock(0), m_stream(nullptr), m_palette(*this, "palette"), - m_space_config("pageram", ENDIANNESS_LITTLE, 8, 11, 0, address_map_constructor(), address_map_constructor(FUNC(cdp1869_device::cdp1869), this)) + m_space_config("pageram", ENDIANNESS_LITTLE, 8, 11, 0, address_map_constructor(FUNC(cdp1869_device::cdp1869), this)) { } diff --git a/src/devices/sound/dac.h b/src/devices/sound/dac.h index 96ebb2757d7..434f82ba4f9 100644 --- a/src/devices/sound/dac.h +++ b/src/devices/sound/dac.h @@ -258,7 +258,7 @@ DECLARE_DEVICE_TYPE(_dac_type, _dac_class) \ class _dac_class : public dac_generator<_dac_interface, _dac_coding> \ {\ public: \ - _dac_class(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) : \ + _dac_class(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock = 0) : \ dac_generator(mconfig, _dac_type, tag, owner, clock, _dac_gain) {} \ }; \ DAC_GENERATOR_EPILOG(_dac_type, _dac_class, _dac_description, _dac_shortname) diff --git a/src/devices/sound/es1373.cpp b/src/devices/sound/es1373.cpp index 9279e3558cd..dbc0c6a96d8 100644 --- a/src/devices/sound/es1373.cpp +++ b/src/devices/sound/es1373.cpp @@ -71,10 +71,11 @@ #define ES_PCI_READ 0 #define ES_PCI_WRITE 1 -MACHINE_CONFIG_START(es1373_device::device_add_mconfig) +void es1373_device::device_add_mconfig(machine_config &config) +{ SPEAKER(config, "lspeaker").front_left(); SPEAKER(config, "rspeaker").front_right(); -MACHINE_CONFIG_END +} DEFINE_DEVICE_TYPE(ES1373, es1373_device, "es1373", "Creative Labs Ensoniq AudioPCI97 ES1373") diff --git a/src/devices/sound/es5506.cpp b/src/devices/sound/es5506.cpp index f243f0c06e7..2702d58fa25 100644 --- a/src/devices/sound/es5506.cpp +++ b/src/devices/sound/es5506.cpp @@ -156,7 +156,8 @@ es550x_device::es550x_device(const machine_config &mconfig, device_type type, co m_region3(nullptr), m_channels(0), m_irq_cb(*this), - m_read_port_cb(*this) + m_read_port_cb(*this), + m_sample_rate_changed_cb(*this) { for (auto & elem : m_region_base) { @@ -230,6 +231,7 @@ void es5506_device::device_start() m_master_clock = clock(); m_irq_cb.resolve(); m_read_port_cb.resolve(); + m_sample_rate_changed_cb.resolve(); m_irqv = 0x80; m_channels = channels; @@ -309,6 +311,8 @@ void es550x_device::device_clock_changed() m_master_clock = clock(); m_sample_rate = m_master_clock / (16 * (m_active_voices + 1)); m_stream->set_sample_rate(m_sample_rate); + if (!m_sample_rate_changed_cb.isnull()) + m_sample_rate_changed_cb(m_sample_rate); } //------------------------------------------------- @@ -378,6 +382,7 @@ void es5505_device::device_start() m_master_clock = clock(); m_irq_cb.resolve(); m_read_port_cb.resolve(); + m_sample_rate_changed_cb.resolve(); m_irqv = 0x80; m_channels = channels; @@ -1215,6 +1220,8 @@ inline void es5506_device::reg_write_low(es550x_voice *voice, offs_t offset, uin m_active_voices = data & 0x1f; m_sample_rate = m_master_clock / (16 * (m_active_voices + 1)); m_stream->set_sample_rate(m_sample_rate); + if (!m_sample_rate_changed_cb.isnull()) + m_sample_rate_changed_cb(m_sample_rate); LOG("active voices=%d, sample_rate=%d\n", m_active_voices, m_sample_rate); break; @@ -1749,6 +1756,8 @@ inline void es5505_device::reg_write_low(es550x_voice *voice, offs_t offset, uin m_active_voices = data & 0x1f; m_sample_rate = m_master_clock / (16 * (m_active_voices + 1)); m_stream->set_sample_rate(m_sample_rate); + if (!m_sample_rate_changed_cb.isnull()) + m_sample_rate_changed_cb(m_sample_rate); LOG("active voices=%d, sample_rate=%d\n", m_active_voices, m_sample_rate); } @@ -1847,6 +1856,8 @@ inline void es5505_device::reg_write_high(es550x_voice *voice, offs_t offset, ui m_active_voices = data & 0x1f; m_sample_rate = m_master_clock / (16 * (m_active_voices + 1)); m_stream->set_sample_rate(m_sample_rate); + if (!m_sample_rate_changed_cb.isnull()) + m_sample_rate_changed_cb(m_sample_rate); LOG("active voices=%d, sample_rate=%d\n", m_active_voices, m_sample_rate); } @@ -1890,6 +1901,8 @@ inline void es5505_device::reg_write_test(es550x_voice *voice, offs_t offset, ui m_active_voices = data & 0x1f; m_sample_rate = m_master_clock / (16 * (m_active_voices + 1)); m_stream->set_sample_rate(m_sample_rate); + if (!m_sample_rate_changed_cb.isnull()) + m_sample_rate_changed_cb(m_sample_rate); LOG("active voices=%d, sample_rate=%d\n", m_active_voices, m_sample_rate); } diff --git a/src/devices/sound/es5506.h b/src/devices/sound/es5506.h index 38a006ea967..ddf38d19fb9 100644 --- a/src/devices/sound/es5506.h +++ b/src/devices/sound/es5506.h @@ -25,6 +25,7 @@ public: auto irq_cb() { return m_irq_cb.bind(); } auto read_port_cb() { return m_read_port_cb.bind(); } + auto sample_rate_changed() { return m_sample_rate_changed_cb.bind(); } protected: // struct describing a single playing voice @@ -114,6 +115,7 @@ protected: int m_channels; /* number of output channels: 1 .. 6 */ devcb_write_line m_irq_cb; /* irq callback */ devcb_read16 m_read_port_cb; /* input port read */ + devcb_write32 m_sample_rate_changed_cb; /* callback for when sample rate is changed */ }; diff --git a/src/devices/sound/es8712.cpp b/src/devices/sound/es8712.cpp index e0b2699edd0..00ec7fe90d3 100644 --- a/src/devices/sound/es8712.cpp +++ b/src/devices/sound/es8712.cpp @@ -228,7 +228,7 @@ WRITE_LINE_MEMBER(es8712_device::msm_int) } else { - m_adpcm_select->write_ab(read_byte(m_base_offset)); + m_adpcm_select->ab_w(read_byte(m_base_offset)); m_adpcm_select->select_w(m_adpcm_trigger); m_adpcm_trigger ^= 1; if (m_adpcm_trigger == 0) diff --git a/src/devices/sound/es8712.h b/src/devices/sound/es8712.h index d355bd10633..b1cfafc1424 100644 --- a/src/devices/sound/es8712.h +++ b/src/devices/sound/es8712.h @@ -23,7 +23,7 @@ public: es8712_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); // configuration - void set_msm_tag(const char *tag) { m_msm.set_tag(tag); } + template <typename T> void set_msm_tag(T &&tag) { m_msm.set_tag(std::forward<T>(tag)); } auto reset_handler() { return m_reset_handler.bind(); } auto msm_write_handler() { return m_msm_write_cb.bind(); } diff --git a/src/devices/sound/esqpump.cpp b/src/devices/sound/esqpump.cpp index f817b0d7274..5ed977b9f81 100644 --- a/src/devices/sound/esqpump.cpp +++ b/src/devices/sound/esqpump.cpp @@ -16,8 +16,12 @@ DEFINE_DEVICE_TYPE(ESQ_5505_5510_PUMP, esq_5505_5510_pump_device, "esq_5505_5510 esq_5505_5510_pump_device::esq_5505_5510_pump_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) : device_t(mconfig, ESQ_5505_5510_PUMP, tag, owner, clock) , device_sound_interface(mconfig, *this) - , m_stream(nullptr), m_timer(nullptr), m_esp(nullptr) - , m_esp_halted(true), ticks_spent_processing(0), samples_processed(0) + , m_stream(nullptr) + , m_timer(nullptr) + , m_esp(*this, finder_base::DUMMY_TAG) + , m_esp_halted(true) + , ticks_spent_processing(0) + , samples_processed(0) { #if !PUMP_FAKE_ESP_PROCESSING && PUMP_REPLACE_ESP_PROGRAM e = nullptr; @@ -59,14 +63,16 @@ void esq_5505_5510_pump_device::device_stop() void esq_5505_5510_pump_device::device_reset() { - int64_t nsec_per_sample = 100 * 16 * 21; - attotime sample_time(0, 1000000000 * nsec_per_sample); - attotime initial_delay(0, 0); - - m_timer->adjust(initial_delay, 0, sample_time); + m_timer->adjust(attotime::zero, 0, attotime::from_hz(clock())); m_timer->enable(true); } +void esq_5505_5510_pump_device::device_clock_changed() +{ + m_stream->set_sample_rate(clock()); + m_timer->adjust(attotime::zero, 0, attotime::from_hz(clock())); +} + void esq_5505_5510_pump_device::sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples) { if (samples != 1) { diff --git a/src/devices/sound/esqpump.h b/src/devices/sound/esqpump.h index a95ee84c292..8ebd12bccb0 100644 --- a/src/devices/sound/esqpump.h +++ b/src/devices/sound/esqpump.h @@ -20,7 +20,7 @@ public: esq_5505_5510_pump_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); - void set_esp(es5510_device *esp) { m_esp = esp; } + template <typename T> void set_esp(T &&tag) { m_esp.set_tag(std::forward<T>(tag)); } void set_esp_halted(bool esp_halted) { m_esp_halted = esp_halted; logerror("ESP-halted -> %d\n", m_esp_halted); @@ -72,6 +72,7 @@ protected: virtual void device_start() override; virtual void device_stop() override; virtual void device_reset() override; + virtual void device_clock_changed() override; // sound stream update overrides virtual void sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples) override; @@ -88,7 +89,7 @@ private: emu_timer *m_timer; // ESP signal processor - es5510_device *m_esp; + required_device<es5510_device> m_esp; // Is the ESP halted by the CPU? bool m_esp_halted; diff --git a/src/devices/sound/gaelco.cpp b/src/devices/sound/gaelco.cpp index 57167945cae..c8109ce5acd 100644 --- a/src/devices/sound/gaelco.cpp +++ b/src/devices/sound/gaelco.cpp @@ -131,7 +131,9 @@ void gaelco_gae1_device::sound_stream_update(sound_stream &stream, stream_sample } } else { LOG_SOUND(("(GAE1) Playing unknown sample format in channel: %02d, type: %02x, bank: %02x, end: %08x, Length: %04x\n", ch, type, bank, end_pos, m_sndregs[base_offset + 3])); - channel->active = 0; + //channel->active = 0; + // play2000 expects these to expire, are they valid? this is unrelated to the missing sounds in touchgo which never hits here + m_sndregs[base_offset + 3]--; } /* check if the current sample has finished playing */ diff --git a/src/devices/sound/ics2115.cpp b/src/devices/sound/ics2115.cpp index 12062e9a509..9ce19fe649f 100644 --- a/src/devices/sound/ics2115.cpp +++ b/src/devices/sound/ics2115.cpp @@ -15,9 +15,9 @@ //#define ICS2115_ISOLATE 6 // device type definition -DEFINE_DEVICE_TYPE(ICS2115, ics2115_device, "ics2115", "ICS2115") +DEFINE_DEVICE_TYPE(ICS2115, ics2115_device, "ics2115", "ICS2115 WaveFront Synthesizer") -ics2115_device::ics2115_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) +ics2115_device::ics2115_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) : device_t(mconfig, ICS2115, tag, owner, clock), device_sound_interface(mconfig, *this), m_stream(nullptr), m_rom(*this, DEVICE_SELF), @@ -36,26 +36,26 @@ void ics2115_device::device_start() //Exact formula as per patent 5809466 //This seems to give the ok fit but it is not good enough. /*double maxvol = ((1 << volume_bits) - 1) * pow(2., (double)1/0x100); - for (int i = 0; i < 0x1000; i++) { + for (int i = 0; i < 0x1000; i++) m_volume[i] = floor(maxvol * pow(2.,(double)i/256 - 16) + 0.5); - }*/ + */ //austere's table, derived from patent 5809466: //See section V starting from page 195 //Subsection F (column 124, page 198) onwards - for (int i = 0; i<4096; i++) { + for (int i = 0; i<4096; i++) m_volume[i] = ((0x100 | (i & 0xff)) << (volume_bits-9)) >> (15 - (i>>8)); - } //u-Law table as per MIL-STD-188-113 - uint16_t lut[8]; - uint16_t lut_initial = 33 << 2; //shift up 2-bits for 16-bit range. - for(int i = 0; i < 8; i++) + u16 lut[8]; + u16 lut_initial = 33 << 2; //shift up 2-bits for 16-bit range. + for (int i = 0; i < 8; i++) lut[i] = (lut_initial << i) - lut_initial; - for(int i = 0; i < 256; i++) { - uint8_t exponent = (~i >> 4) & 0x07; - uint8_t mantissa = ~i & 0x0f; - int16_t value = lut[exponent] + (mantissa << (exponent + 3)); + for (int i = 0; i < 256; i++) + { + u8 exponent = (~i >> 4) & 0x07; + u8 mantissa = ~i & 0x0f; + s16 value = lut[exponent] + (mantissa << (exponent + 3)); m_ulaw[i] = (i & 0x80) ? -value : value; } @@ -73,7 +73,8 @@ void ics2115_device::device_start() save_item(NAME(m_active_osc)); save_item(NAME(m_vmode)); - for(int i = 0; i < 32; i++) { + for (int i = 0; i < 32; i++) + { save_item(NAME(m_voice[i].osc_conf.value), i); save_item(NAME(m_voice[i].state.value), i); save_item(NAME(m_voice[i].vol_ctrl.value), i); @@ -108,14 +109,15 @@ void ics2115_device::device_reset() m_vmode = 0; m_irq_on = false; memset(m_voice, 0, sizeof(m_voice)); - for(auto & elem : m_timer) + for (auto & elem : m_timer) { elem.timer->adjust(attotime::never); elem.period = 0; elem.scale = 0; elem.preset = 0; } - for(auto & elem : m_voice) { + for (auto & elem : m_voice) + { elem.osc_conf.value = 2; elem.osc.fc = 0; elem.osc.acc = 0; @@ -127,7 +129,7 @@ void ics2115_device::device_reset() elem.vol.incr = 0; elem.vol.start = 0; elem.vol.end = 0; - elem.vol.pan = 0x7F; + elem.vol.pan = 0x7f; elem.vol_ctrl.value = 1; elem.vol.mode = 0; elem.state.value = 0; @@ -138,40 +140,47 @@ void ics2115_device::device_reset() int ics2115_device::ics2115_voice::update_volume_envelope() { int ret = 0; - if(vol_ctrl.bitflags.done || vol_ctrl.bitflags.stop) + if (vol_ctrl.bitflags.done || vol_ctrl.bitflags.stop) return ret; - if(vol_ctrl.bitflags.invert) { + if (vol_ctrl.bitflags.invert) + { vol.acc -= vol.add; vol.left = vol.acc - vol.start; - } else { + } + else + { vol.acc += vol.add; vol.left = vol.end - vol.acc; } - if(vol.left > 0) + if (vol.left > 0) return ret; - if(vol_ctrl.bitflags.irq) { + if (vol_ctrl.bitflags.irq) + { vol_ctrl.bitflags.irq_pending = true; ret = 1; } - if(osc_conf.bitflags.eightbit) + if (osc_conf.bitflags.eightbit) return ret; - if(vol_ctrl.bitflags.loop) { - if(vol_ctrl.bitflags.loop_bidir) + if (vol_ctrl.bitflags.loop) + { + if (vol_ctrl.bitflags.loop_bidir) vol_ctrl.bitflags.invert = !vol_ctrl.bitflags.invert; - if(vol_ctrl.bitflags.invert) + if (vol_ctrl.bitflags.invert) vol.acc = vol.end + vol.left; else vol.acc = vol.start - vol.left; - } else { + } + else + { state.bitflags.on = false; vol_ctrl.bitflags.done = true; - if(vol_ctrl.bitflags.invert) + if (vol_ctrl.bitflags.invert) vol.acc = vol.end; else vol.acc = vol.start; @@ -180,7 +189,7 @@ int ics2115_device::ics2115_voice::update_volume_envelope() return ret; } -/*uint32_t ics2115_device::ics2115_voice::next_address() +/*u32 ics2115_device::ics2115_voice::next_address() { //Patent 6,246,774 B1, Column 111, Row 25 //LEN BLEN DIR BC NextAddress @@ -198,40 +207,49 @@ int ics2115_device::ics2115_voice::update_volume_envelope() int ics2115_device::ics2115_voice::update_oscillator() { int ret = 0; - if(osc_conf.bitflags.stop) + if (osc_conf.bitflags.stop) return ret; - if(osc_conf.bitflags.invert) { + if (osc_conf.bitflags.invert) + { osc.acc -= osc.fc << 2; osc.left = osc.acc - osc.start; - } else { + } + else + { osc.acc += osc.fc << 2; osc.left = osc.end - osc.acc; } // > instead of >= to stop crackling? - if(osc.left > 0) + if (osc.left > 0) return ret; - if(osc_conf.bitflags.irq) { + if (osc_conf.bitflags.irq) + { osc_conf.bitflags.irq_pending = true; ret = 1; } - if(osc_conf.bitflags.loop) { - if(osc_conf.bitflags.loop_bidir) + if (osc_conf.bitflags.loop) + { + if (osc_conf.bitflags.loop_bidir) osc_conf.bitflags.invert = !osc_conf.bitflags.invert; //else - // printf("click!\n"); + // logerror("click!\n"); - if(osc_conf.bitflags.invert) { + if (osc_conf.bitflags.invert) + { osc.acc = osc.end + osc.left; osc.left = osc.acc - osc.start; } - else { + else + { osc.acc = osc.start - osc.left; osc.left = osc.end - osc.acc; } - } else { + } + else + { state.bitflags.on = false; osc_conf.bitflags.stop = true; - if(!osc_conf.bitflags.invert) + if (!osc_conf.bitflags.invert) osc.acc = osc.end; else osc.acc = osc.start; @@ -242,41 +260,44 @@ int ics2115_device::ics2115_voice::update_oscillator() //TODO: proper interpolation for uLaw (fill_output doesn't use this) and 8-bit samples (looping) stream_sample_t ics2115_device::get_sample(ics2115_voice& voice) { - uint32_t curaddr = ((voice.osc.saddr << 20) & 0xffffff) | (voice.osc.acc >> 12); - uint32_t nextaddr; + u32 curaddr = ((voice.osc.saddr << 20) & 0xffffff) | (voice.osc.acc >> 12); + u32 nextaddr; if (voice.state.bitflags.on && voice.osc_conf.bitflags.loop && !voice.osc_conf.bitflags.loop_bidir && - (voice.osc.left < (voice.osc.fc <<2))) { - //printf("C?[%x:%x]", voice.osc.left, voice.osc.acc); + (voice.osc.left < (voice.osc.fc <<2))) + { + //logerror("C?[%x:%x]", voice.osc.left, voice.osc.acc); nextaddr = ((voice.osc.saddr << 20) & 0xffffff) | (voice.osc.start >> 12); } else nextaddr = curaddr + 2; - int16_t sample1, sample2; - if (voice.osc_conf.bitflags.eightbit) { - sample1 = ((int8_t)m_rom[curaddr]) << 8; - sample2 = ((int8_t)m_rom[curaddr + 1]) << 8; + s16 sample1, sample2; + if (voice.osc_conf.bitflags.eightbit) + { + sample1 = ((s8)m_rom[curaddr]) << 8; + sample2 = ((s8)m_rom[curaddr + 1]) << 8; } - else { - sample1 = m_rom[curaddr + 0] | (((int8_t)m_rom[curaddr + 1]) << 8); - sample2 = m_rom[nextaddr+ 0] | (((int8_t)m_rom[nextaddr+ 1]) << 8); - //sample2 = m_rom[curaddr + 2] | (((int8_t)m_rom[curaddr + 3]) << 8); + else + { + sample1 = m_rom[curaddr + 0] | (((s8)m_rom[curaddr + 1]) << 8); + sample2 = m_rom[nextaddr+ 0] | (((s8)m_rom[nextaddr+ 1]) << 8); + //sample2 = m_rom[curaddr + 2] | (((s8)m_rom[curaddr + 3]) << 8); } //no need for interpolation since it's around 1 note a cycle? - //if(voice.osc.fc >> 10) + //if (voice.osc.fc >> 10) // return sample1; //linear interpolation as in US patent 6,246,774 B1, column 2 row 59 //LEN=1, BLEN=0, DIR=0, start+end interpolation - int32_t sample, diff; - uint16_t fract; + s32 sample, diff; + u16 fract; diff = sample2 - sample1; fract = (voice.osc.acc >> 3) & 0x1ff; - sample = (((int32_t)sample1 << 9) + diff * fract) >> 9; + sample = (((s32)sample1 << 9) + diff * fract) >> 9; //sample = sample1; return sample; } @@ -286,16 +307,19 @@ bool ics2115_device::ics2115_voice::playing() return state.bitflags.on && !((vol_ctrl.bitflags.done || vol_ctrl.bitflags.stop) && osc_conf.bitflags.stop); } -void ics2115_device::ics2115_voice::update_ramp() { +void ics2115_device::ics2115_voice::update_ramp() +{ //slow attack - if (state.bitflags.on && !osc_conf.bitflags.stop) { + if (state.bitflags.on && !osc_conf.bitflags.stop) + { if (state.bitflags.ramp < 0x40) state.bitflags.ramp += 0x1; else state.bitflags.ramp = 0x40; } //slow release - else { + else + { if (state.bitflags.ramp) state.bitflags.ramp -= 0x1; } @@ -304,14 +328,15 @@ void ics2115_device::ics2115_voice::update_ramp() { int ics2115_device::fill_output(ics2115_voice& voice, stream_sample_t *outputs[2], int samples) { bool irq_invalid = false; - uint16_t fine = 1 << (3*(voice.vol.incr >> 6)); - voice.vol.add = (voice.vol.incr & 0x3F)<< (10 - fine); + u16 fine = 1 << (3*(voice.vol.incr >> 6)); + voice.vol.add = (voice.vol.incr & 0x3f)<< (10 - fine); - for (int i = 0; i < samples; i++) { - uint32_t volacc = (voice.vol.acc >> 10) & 0xffff; - uint32_t volume = (m_volume[volacc >> 4] * voice.state.bitflags.ramp) >> 6; - uint16_t vleft = volume; //* (255 - voice.vol.pan) / 0x80]; - uint16_t vright = volume; //* (voice.vol.pan + 1) / 0x80]; + for (int i = 0; i < samples; i++) + { + u32 volacc = (voice.vol.acc >> 10) & 0xffff; + u32 volume = (m_volume[volacc >> 4] * voice.state.bitflags.ramp) >> 6; + u16 vleft = volume; //* (255 - voice.vol.pan) / 0x80]; + u16 vright = volume; //* (voice.vol.pan + 1) / 0x80]; //From GUS doc: //In general, it is necessary to remember that all voices are being summed in to the @@ -319,22 +344,26 @@ int ics2115_device::fill_output(ics2115_voice& voice, stream_sample_t *outputs[2 //that the voice is pointing at is contributing to the summation. //(austere note: this will of course fix some of the glitches due to multiple transition) stream_sample_t sample; - if(voice.osc_conf.bitflags.ulaw) { - uint32_t curaddr = ((voice.osc.saddr << 20) & 0xffffff) | (voice.osc.acc >> 12); + if (voice.osc_conf.bitflags.ulaw) + { + u32 curaddr = ((voice.osc.saddr << 20) & 0xffffff) | (voice.osc.acc >> 12); sample = m_ulaw[m_rom[curaddr]]; } else sample = get_sample(voice); //15-bit volume + (5-bit worth of 32 channel sum) + 16-bit samples = 4-bit extra - if (!m_vmode || voice.playing()) { - //if (voice.playing()) { + if (!m_vmode || voice.playing()) + { + /*if (voice.playing()) + {*/ outputs[0][i] += (sample * vleft) >> (5 + volume_bits - 16); outputs[1][i] += (sample * vright) >> (5 + volume_bits - 16); } voice.update_ramp(); - if (voice.playing()) { + if (voice.playing()) + { if (voice.update_oscillator()) irq_invalid = true; if (voice.update_volume_envelope()) @@ -350,71 +379,77 @@ void ics2115_device::sound_stream_update(sound_stream &stream, stream_sample_t * memset(outputs[1], 0, samples * sizeof(stream_sample_t)); bool irq_invalid = false; - for(int osc = 0; osc <= m_active_osc; osc++) { + for (int osc = 0; osc <= m_active_osc; osc++) + { ics2115_voice& voice = m_voice[osc]; #ifdef ICS2115_ISOLATE - if(osc != ICS2115_ISOLATE) + if (osc != ICS2115_ISOLATE) continue; #endif /* #ifdef ICS2115_DEBUG - uint32_t curaddr = ((voice.osc.saddr << 20) & 0xffffff) | (voice.osc.acc >> 12); + u32 curaddr = ((voice.osc.saddr << 20) & 0xffffff) | (voice.osc.acc >> 12); stream_sample_t sample; - if(voice.osc_conf.bitflags.ulaw) + if (voice.osc_conf.bitflags.ulaw) sample = m_ulaw[m_rom[curaddr]]; else sample = get_sample(voice); - printf("[%06x=%04x]", curaddr, (int16_t)sample); + logerror("[%06x=%04x]", curaddr, (s16)sample); #endif */ - if(fill_output(voice, outputs, samples)) + if (fill_output(voice, outputs, samples)) irq_invalid = true; #ifdef ICS2115_DEBUG - if(voice.playing()) { - printf("%d", osc); + if (voice.playing()) + { + logerror("%d", osc); if (voice.osc_conf.bitflags.invert) - printf("+"); + logerror("+"); else if ((voice.osc.fc >> 1) > 0x1ff) - printf("*"); - printf(" "); + logerror("*"); + logerror(" "); /*int min = 0x7fffffff, max = 0x80000000; double average = 0; - for (int i = 0; i < samples; i++) { + for (int i = 0; i < samples; i++) + { if (outputs[0][i] > max) max = outputs[0][i]; if (outputs[0][i] < min) min = outputs[0][i]; average += fabs(outputs[0][i]); } average /= samples; average /= 1 << 16; - printf("<Mi:%d Mx:%d Av:%g>", min >> 16, max >> 16, average);*/ + logerror("<Mi:%d Mx:%d Av:%g>", min >> 16, max >> 16, average);*/ } #endif } #ifdef ICS2115_DEBUG - printf("|"); + logerror("|"); #endif //rescale - for (int i = 0; i < samples; i++) { + for (int i = 0; i < samples; i++) + { outputs[0][i] >>= 16; outputs[1][i] >>= 16; } - if(irq_invalid) + if (irq_invalid) recalc_irq(); } //Helper Function (Reads off current register) -uint16_t ics2115_device::reg_read() { - uint16_t ret; +u16 ics2115_device::reg_read() +{ + u16 ret; ics2115_voice& voice = m_voice[m_osc_select]; - switch(m_reg_select) { + switch (m_reg_select) + { case 0x00: // [osc] Oscillator Configuration ret = voice.osc_conf.value; ret <<= 8; @@ -460,33 +495,33 @@ uint16_t ics2115_device::reg_read() { ret = voice.vol.acc >> (10); break; - case 0x0A: // [osc] Wavesample address + case 0x0a: // [osc] Wavesample address ret = (voice.osc.acc >> 16) & 0xffff; break; - case 0x0B: // [osc] Wavesample address + case 0x0b: // [osc] Wavesample address ret = (voice.osc.acc >> 0) & 0xfff8; break; - case 0x0C: // [osc] Pan + case 0x0c: // [osc] Pan ret = voice.vol.pan << 8; break; /* DDP3 code (trap15's reversal) */ /* 0xA13's work: res = read() & 0xC3; - if(!(res & 2)) res |= 1; + if (!(res & 2)) res |= 1; e = d = res; */ /* 0xA4F's work: while(!(read() & 1)) */ - case 0x0D: // [osc] Volume Envelope Control + case 0x0d: // [osc] Volume Envelope Control //ret = v->Vol.Ctl | ((v->state & FLAG_STATE_VOLIRQ) ? 0x81 : 1); // may expect |8 on voice irq with &40 == 0 // may expect |8 on reg 0 on voice irq with &80 == 0 - // ret = 0xFF; + // ret = 0xff; if (!m_vmode) ret = voice.vol_ctrl.bitflags.irq ? 0x81 : 0x01; else @@ -495,24 +530,28 @@ uint16_t ics2115_device::reg_read() { ret <<= 8; break; - case 0x0E: // Active Voices + case 0x0e: // Active Voices ret = m_active_osc; break; - case 0x0F:{// [osc] Interrupt source/oscillator + case 0x0f:{// [osc] Interrupt source/oscillator ret = 0xff; - for (int i = 0; i <= m_active_osc; i++) { + for (int i = 0; i <= m_active_osc; i++) + { ics2115_voice& v = m_voice[i]; - if (v.osc_conf.bitflags.irq_pending || v.vol_ctrl.bitflags.irq_pending) { + if (v.osc_conf.bitflags.irq_pending || v.vol_ctrl.bitflags.irq_pending) + { ret = i | 0xe0; ret &= v.vol_ctrl.bitflags.irq_pending ? (~0x40) : 0xff; ret &= v.osc_conf.bitflags.irq_pending ? (~0x80) : 0xff; recalc_irq(); - if (v.osc_conf.bitflags.irq_pending) { + if (v.osc_conf.bitflags.irq_pending) + { v.osc_conf.bitflags.irq_pending = 0; ret &= ~0x80; } - if (v.vol_ctrl.bitflags.irq_pending) { + if (v.vol_ctrl.bitflags.irq_pending) + { v.vol_ctrl.bitflags.irq_pending = 0; ret &= ~0x40; } @@ -542,21 +581,21 @@ uint16_t ics2115_device::reg_read() { ret = m_irq_pending & 3; break; - case 0x4A: // IRQ Pending + case 0x4a: // IRQ Pending ret = m_irq_pending; break; - case 0x4B: // Address of Interrupting Oscillator + case 0x4b: // Address of Interrupting Oscillator ret = 0x80; break; - case 0x4C: // Chip Revision + case 0x4c: // Chip Revision ret = revision; break; default: #ifdef ICS2115_DEBUG - printf("ICS2115: Unhandled read %x\n", m_reg_select); + logerror("ICS2115: Unhandled read %x\n", m_reg_select); #endif ret = 0; break; @@ -564,140 +603,147 @@ uint16_t ics2115_device::reg_read() { return ret; } -void ics2115_device::reg_write(uint8_t data, bool msb) { +void ics2115_device::reg_write(u16 data, u16 mem_mask) +{ ics2115_voice& voice = m_voice[m_osc_select]; - switch(m_reg_select) { + switch (m_reg_select) + { case 0x00: // [osc] Oscillator Configuration - if(msb) { + if (ACCESSING_BITS_8_15) + { voice.osc_conf.value &= 0x80; - voice.osc_conf.value |= data & 0x7f; + voice.osc_conf.value |= (data >> 8) & 0x7f; } break; case 0x01: // [osc] Wavesample frequency // freq = fc*33075/1024 in 32 voices mode, fc*44100/1024 in 24 voices mode - if(msb) - voice.osc.fc = (voice.osc.fc & 0x00ff) | (data << 8); - else + if (ACCESSING_BITS_8_15) + voice.osc.fc = (voice.osc.fc & 0x00fe) | (data & 0xff00); + if (ACCESSING_BITS_0_7) //last bit not used! - voice.osc.fc = (voice.osc.fc & 0xff00) | (data & 0xfe); + voice.osc.fc = (voice.osc.fc & 0xff00) | (data & 0x00fe); break; case 0x02: // [osc] Wavesample loop start high - if(msb) - voice.osc.start = (voice.osc.start & 0x00ffffff) | (data << 24); - else - voice.osc.start = (voice.osc.start & 0xff00ffff) | (data << 16); + if (ACCESSING_BITS_8_15) + voice.osc.start = (voice.osc.start & 0x00ffffff) | ((data & 0xff00) << 16); + if (ACCESSING_BITS_0_7) + voice.osc.start = (voice.osc.start & 0xff00ffff) | ((data & 0x00ff) << 16); break; case 0x03: // [osc] Wavesample loop start low - if(msb) - voice.osc.start = (voice.osc.start & 0xffff00ff) | (data << 8); + if (ACCESSING_BITS_8_15) + voice.osc.start = (voice.osc.start & 0xffff00ff) | (data & 0xff00); // This is unused? - //else + //if (ACCESSING_BITS_0_7) //voice.osc.start = (voice.osc.start & 0xffffff00) | (data & 0); break; case 0x04: // [osc] Wavesample loop end high - if(msb) - voice.osc.end = (voice.osc.end & 0x00ffffff) | (data << 24); - else - voice.osc.end = (voice.osc.end & 0xff00ffff) | (data << 16); + if (ACCESSING_BITS_8_15) + voice.osc.end = (voice.osc.end & 0x00ffffff) | ((data & 0xff00) << 16); + if (ACCESSING_BITS_0_7) + voice.osc.end = (voice.osc.end & 0xff00ffff) | ((data & 0x00ff) << 16); break; case 0x05: // [osc] Wavesample loop end low - if(msb) - voice.osc.end = (voice.osc.end & 0xffff00ff) | (data << 8); + if (ACCESSING_BITS_8_15) + voice.osc.end = (voice.osc.end & 0xffff00ff) | (data & 0xff00); // lsb is unused? break; case 0x06: // [osc] Volume Increment - if(msb) - voice.vol.incr = data; + if (ACCESSING_BITS_8_15) + voice.vol.incr = (data >> 8) & 0xff; break; case 0x07: // [osc] Volume Start - if (!msb) - voice.vol.start = data << (10+8); + if (ACCESSING_BITS_0_7) + voice.vol.start = (data & 0xff) << (10+8); break; case 0x08: // [osc] Volume End - if (!msb) - voice.vol.end = data << (10+8); + if (ACCESSING_BITS_0_7) + voice.vol.end = (data & 0xff) << (10+8); break; case 0x09: // [osc] Volume accumulator - if(msb) - voice.vol.regacc = (voice.vol.regacc & 0x00ff) | (data << 8); - else - voice.vol.regacc = (voice.vol.regacc & 0xff00) | data; + if (ACCESSING_BITS_8_15) + voice.vol.regacc = (voice.vol.regacc & 0x00ff) | (data & 0xff00); + if (ACCESSING_BITS_0_7) + voice.vol.regacc = (voice.vol.regacc & 0xff00) | (data & 0x00ff); voice.vol.acc = voice.vol.regacc << 10; break; - case 0x0A: // [osc] Wavesample address high + case 0x0a: // [osc] Wavesample address high #ifdef ICS2115_DEBUG #ifdef ICS2115_ISOLATE - if(m_osc_select == ICS2115_ISOLATE) + if (m_osc_select == ICS2115_ISOLATE) #endif - printf("<%d:oa:H[%d]=%x>", m_osc_select, msb, data); + logerror("<%d:oa:H=%x>", m_osc_select, data); #endif - if(msb) - voice.osc.acc = (voice.osc.acc & 0x00ffffff) | (data << 24); - else - voice.osc.acc = (voice.osc.acc & 0xff00ffff) | (data << 16); + if (ACCESSING_BITS_8_15) + voice.osc.acc = (voice.osc.acc & 0x00ffffff) | ((data & 0xff00) << 16); + if (ACCESSING_BITS_0_7) + voice.osc.acc = (voice.osc.acc & 0xff00ffff) | ((data & 0x00ff) << 16); break; - case 0x0B: // [osc] Wavesample address low + case 0x0b: // [osc] Wavesample address low #ifdef ICS2115_DEBUG #ifdef ICS2115_ISOLATE - if(m_osc_select == ICS2115_ISOLATE) + if (m_osc_select == ICS2115_ISOLATE) #endif - printf("<%d:oa:L[%d]=%x>", m_osc_select, msb, data); + logerror("<%d:oa:L=%x>", m_osc_select, data); #endif - if(msb) - voice.osc.acc = (voice.osc.acc & 0xffff00ff) | (data << 8); - else - voice.osc.acc = (voice.osc.acc & 0xffffff00) | (data & 0xF8); + if (ACCESSING_BITS_8_15) + voice.osc.acc = (voice.osc.acc & 0xffff00ff) | (data & 0xff00); + if (ACCESSING_BITS_0_7) + voice.osc.acc = (voice.osc.acc & 0xffffff00) | (data & 0x00f8); break; - case 0x0C: // [osc] Pan - if(msb) - voice.vol.pan = data; + case 0x0c: // [osc] Pan + if (ACCESSING_BITS_8_15) + voice.vol.pan = (data >> 8) & 0xff; break; - case 0x0D: // [osc] Volume Envelope Control - if(msb) { + case 0x0d: // [osc] Volume Envelope Control + if (ACCESSING_BITS_8_15) + { voice.vol_ctrl.value &= 0x80; - voice.vol_ctrl.value |= data & 0x7F; + voice.vol_ctrl.value |= (data >> 8) & 0x7f; } break; - case 0x0E: // Active Voices + case 0x0e: // Active Voices //Does this value get added to 1? Not sure. Could trace for writes of 32. - if(msb) { - m_active_osc = data & 0x1F; // & 0x1F ? (Guessing) - } + if (ACCESSING_BITS_8_15) + m_active_osc = (data >> 8) & 0x1f; // & 0x1f ? (Guessing) break; //2X8 ? case 0x10: // [osc] Oscillator Control //Could this be 2X9? //[7 R | 6 M2 | 5 M1 | 4-2 Reserve | 1 - Timer 2 Strt | 0 - Timer 1 Strt] - if (msb) { + if (ACCESSING_BITS_8_15) + { + data >>= 8; voice.osc.ctl = data; if (!data) keyon(); //guessing here - else if(data == 0xf) { + else if (data == 0xf) + { #ifdef ICS2115_DEBUG #ifdef ICS2115_ISOLATE if (m_osc_select == ICS2115_ISOLATE) #endif if (!voice.osc_conf.bitflags.stop || !voice.vol_ctrl.bitflags.stop) - printf("[%02d STOP]\n", m_osc_select); + logerror("[%02d STOP]\n", m_osc_select); #endif - if (!m_vmode) { + if (!m_vmode) + { voice.osc_conf.bitflags.stop = true; voice.vol_ctrl.bitflags.stop = true; //try to key it off as well! @@ -706,71 +752,77 @@ void ics2115_device::reg_write(uint8_t data, bool msb) { } #ifdef ICS2115_DEBUG else - printf("ICS2115: Unhandled* data write %d onto 0x10.\n", data); + logerror("ICS2115: Unhandled* data write %d onto 0x10.\n", data); #endif } break; case 0x11: // [osc] Wavesample static address 27-20 - if(msb) - //v->Osc.SAddr = data; - voice.osc.saddr = data; + if (ACCESSING_BITS_8_15) + //v->Osc.SAddr = (data >> 8); + voice.osc.saddr = (data >> 8); break; case 0x12: //Could be per voice! -- investigate. - if (msb) - m_vmode = data; + if (ACCESSING_BITS_8_15) + m_vmode = (data >> 8); break; case 0x40: // Timer 1 Preset case 0x41: // Timer 2 Preset - if(!msb) { - m_timer[m_reg_select & 0x1].preset = data; + if (ACCESSING_BITS_0_7) + { + m_timer[m_reg_select & 0x1].preset = data & 0xff; recalc_timer(m_reg_select & 0x1); } break; case 0x42: // Timer 1 Prescale case 0x43: // Timer 2 Prescale - if(!msb) { - m_timer[m_reg_select & 0x1].scale = data; + if (ACCESSING_BITS_0_7) + { + m_timer[m_reg_select & 0x1].scale = data & 0xff; recalc_timer(m_reg_select & 0x1); } break; - case 0x4A: // IRQ Enable - if(!msb) { - m_irq_enabled = data; + case 0x4a: // IRQ Enable + if (ACCESSING_BITS_0_7) + { + m_irq_enabled = data & 0xff; recalc_irq(); } break; - case 0x4F: // Oscillator Address being Programmed - if(!msb) { - m_osc_select = data % (1+m_active_osc); - } + case 0x4f: // Oscillator Address being Programmed + if (ACCESSING_BITS_0_7) + m_osc_select = (data & 0xff) % (1+m_active_osc); break; default: #ifdef ICS2115_DEBUG - printf("ICS2115: Unhandled write %x onto %x(%d) [voice = %d]\n", data, m_reg_select, msb, m_osc_select); + logerror("ICS2115: Unhandled write %x onto %x [voice = %d]\n", data, m_reg_select, m_osc_select); #endif break; } } -READ8_MEMBER(ics2115_device::read) +u8 ics2115_device::read(offs_t offset) { - uint8_t ret = 0; + u8 ret = 0; - switch(offset) { + switch (offset) + { case 0: //TODO: check this suspect code - if (m_irq_on) { + if (m_irq_on) + { ret |= 0x80; if (m_irq_enabled && (m_irq_pending & 3)) ret |= 1; - for (int i = 0; i <= m_active_osc; i++) { + for (int i = 0; i <= m_active_osc; i++) + { if (//m_voice[i].vol_ctrl.bitflags.irq_pending || - m_voice[i].osc_conf.bitflags.irq_pending) { + m_voice[i].osc_conf.bitflags.irq_pending) + { ret |= 2; break; } @@ -782,35 +834,89 @@ READ8_MEMBER(ics2115_device::read) ret = m_reg_select; break; case 2: - ret = (uint8_t)(reg_read()); + ret = (u8)(reg_read()); break; case 3: ret = reg_read() >> 8; break; default: #ifdef ICS2115_DEBUG - printf("ICS2115: Unhandled memory read at %x\n", offset); + logerror("ICS2115: Unhandled memory read at %x\n", offset); #endif break; } return ret; } -WRITE8_MEMBER(ics2115_device::write) +void ics2115_device::write(offs_t offset, u8 data) { - switch(offset) { + switch (offset) + { case 1: m_reg_select = data; break; case 2: - reg_write(data,0); + reg_write(data, 0x00ff); break; case 3: - reg_write(data,1); + reg_write(data << 8, 0xff00); break; default: #ifdef ICS2115_DEBUG - printf("ICS2115: Unhandled memory write %02x to %x\n", data, offset); + logerror("ICS2115: Unhandled memory write %02x to %x\n", data, offset); +#endif + break; + } +} + +u16 ics2115_device::word_r(offs_t offset, u16 mem_mask) +{ + u16 ret = 0; + + switch (offset) + { + case 0: + case 1: + if (ACCESSING_BITS_0_7) + ret |= read(offset); + break; + case 2: + ret |= reg_read() & mem_mask; + break; + /* + case 3: + TODO : used for byte size only; + break; + */ + default: +#ifdef ICS2115_DEBUG + logerror("ICS2115: Unhandled memory read at %x\n", offset); +#endif + break; + } + return ret; +} + +void ics2115_device::word_w(offs_t offset, u16 data, u16 mem_mask) +{ + switch (offset) + { + case 0: + case 1: + if (ACCESSING_BITS_0_7) + write(offset, data & 0xff); + break; + case 2: + reg_write(data, mem_mask); + break; + /* + case 3: + TODO : used for byte size only; + break; + */ + default: +#ifdef ICS2115_DEBUG + logerror("ICS2115: Unhandled memory write %02x to %x\n", data, offset); #endif break; } @@ -828,7 +934,7 @@ void ics2115_device::keyon() m_voice[m_osc_select].state.bitflags.ramp = 0x40; #ifdef ICS2115_DEBUG - printf("[%02d vs:%04x ve:%04x va:%04x vi:%02x vc:%02x os:%06x oe:%06x oa:%06x of:%04x SA:%02x oc:%02x][%04x]\n", m_osc_select, + logerror("[%02d vs:%04x ve:%04x va:%04x vi:%02x vc:%02x os:%06x oe:%06x oa:%06x of:%04x SA:%02x oc:%02x][%04x]\n", m_osc_select, m_voice[m_osc_select].vol.start >> 10, m_voice[m_osc_select].vol.end >> 10, m_voice[m_osc_select].vol.acc >> 10, @@ -844,17 +950,17 @@ void ics2115_device::keyon() ); #endif //testing memory corruption issue with mame stream - //printf("m_volume[0x%x]=0x%x\n", mastervolume, m_volume[mastervolume]); + //logerror("m_volume[0x%x]=0x%x\n", mastervolume, m_volume[mastervolume]); } void ics2115_device::recalc_irq() { //Suspect bool irq = (m_irq_pending & m_irq_enabled); - for(int i = 0; (!irq) && (i < 32); i++) + for (int i = 0; (!irq) && (i < 32); i++) irq |= m_voice[i].vol_ctrl.bitflags.irq_pending && m_voice[i].osc_conf.bitflags.irq_pending; m_irq_on = irq; - if(!m_irq_cb.isnull()) + if (!m_irq_cb.isnull()) m_irq_cb(irq ? ASSERT_LINE : CLEAR_LINE); } @@ -873,16 +979,17 @@ TIMER_CALLBACK_MEMBER( ics2115_device::timer_cb_1 ) void ics2115_device::recalc_timer(int timer) { //Old regression-based formula (minus constant) - //uint64_t period = m_timer[timer].preset * (m_timer[timer].scale << 16) / 60; + //u64 period = m_timer[timer].preset * (m_timer[timer].scale << 16) / 60; //New formula based on O.Galibert's reverse engineering of ICS2115 card firmware - uint64_t period = ((m_timer[timer].scale & 0x1f) + 1) * (m_timer[timer].preset + 1); + u64 period = ((m_timer[timer].scale & 0x1f) + 1) * (m_timer[timer].preset + 1); period = (period << (4 + (m_timer[timer].scale >> 5)))*78125/2646; - if(m_timer[timer].period != period) { + if (m_timer[timer].period != period) + { m_timer[timer].period = period; // Adjust the timer lengths - if(period) // Reset the length + if (period) // Reset the length m_timer[timer].timer->adjust(attotime::from_nsec(period), 0, attotime::from_nsec(period)); else // Kill the timer if length == 0 m_timer[timer].timer->adjust(attotime::never); diff --git a/src/devices/sound/ics2115.h b/src/devices/sound/ics2115.h index 57afef9f0c1..e9dc99a368f 100644 --- a/src/devices/sound/ics2115.h +++ b/src/devices/sound/ics2115.h @@ -16,77 +16,79 @@ class ics2115_device : public device_t, public device_sound_interface { public: // construction/destruction - ics2115_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); + ics2115_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock); template <class Object> devcb_base &set_irq_callback(Object &&cb) { return m_irq_cb.set_callback(std::forward<Object>(cb)); } auto irq() { return m_irq_cb.bind(); } - DECLARE_READ8_MEMBER(read); - DECLARE_WRITE8_MEMBER(write); - //uint8_t read(offs_t offset); - //void write(offs_t offset, uint8_t data); + u8 read(offs_t offset); + void write(offs_t offset, u8 data); + + // 16-bit read / write handlers (when /IOCS16 is low) + u16 word_r(offs_t offset, u16 mem_mask); + void word_w(offs_t offset, u16 data, u16 mem_mask); TIMER_CALLBACK_MEMBER(timer_cb_0); TIMER_CALLBACK_MEMBER(timer_cb_1); protected: - static constexpr uint16_t revision = 0x1; + static constexpr u16 revision = 0x1; struct ics2115_voice { struct { - int32_t left; - uint32_t acc, start, end; - uint16_t fc; - uint8_t ctl, saddr; + s32 left; + u32 acc, start, end; + u16 fc; + u8 ctl, saddr; } osc; struct { - int32_t left; - uint32_t add; - uint32_t start, end; - uint32_t acc; - uint16_t regacc; - uint8_t incr; - uint8_t pan, mode; + s32 left; + u32 add; + u32 start, end; + u32 acc; + u16 regacc; + u8 incr; + u8 pan, mode; } vol; union { struct { - uint8_t ulaw : 1; - uint8_t stop : 1; //stops wave + vol envelope - uint8_t eightbit : 1; - uint8_t loop : 1; - uint8_t loop_bidir : 1; - uint8_t irq : 1; - uint8_t invert : 1; - uint8_t irq_pending: 1; + u8 ulaw : 1; + u8 stop : 1; //stops wave + vol envelope + u8 eightbit : 1; + u8 loop : 1; + u8 loop_bidir : 1; + u8 irq : 1; + u8 invert : 1; + u8 irq_pending: 1; //IRQ on variable? } bitflags; - uint8_t value; + u8 value; } osc_conf; union { struct { - uint8_t done : 1; //indicates ramp has stopped - uint8_t stop : 1; //stops the ramp - uint8_t rollover : 1; //rollover (TODO) - uint8_t loop : 1; - uint8_t loop_bidir : 1; - uint8_t irq : 1; //enable IRQ generation - uint8_t invert : 1; //invert direction - uint8_t irq_pending: 1; //(read only) IRQ pending + u8 done : 1; //indicates ramp has stopped + u8 stop : 1; //stops the ramp + u8 rollover : 1; //rollover (TODO) + u8 loop : 1; + u8 loop_bidir : 1; + u8 irq : 1; //enable IRQ generation + u8 invert : 1; //invert direction + u8 irq_pending: 1; //(read only) IRQ pending //noenvelope == (done | disable) } bitflags; - uint8_t value; + u8 value; } vol_ctrl; //Possibly redundant state. => improvements of wavetable logic //may lead to its elimination. union { struct { - uint8_t on : 1; - uint8_t ramp : 7; // 100 0000 = 0x40 maximum + u8 on : 1; + u8 ramp : 7; // 100 0000 = 0x40 maximum } bitflags; - uint8_t value; + u8 value; } state; bool playing(); @@ -103,8 +105,8 @@ protected: virtual void sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples) override; //internal register helper functions - uint16_t reg_read(); - void reg_write(uint8_t data, bool msb); + u16 reg_read(); + void reg_write(u16 data, u16 mem_mask); void recalc_timer(int timer); void keyon(); void recalc_irq(); @@ -116,29 +118,29 @@ protected: sound_stream *m_stream; // internal state - required_region_ptr<uint8_t> m_rom; + required_region_ptr<u8> m_rom; devcb_write_line m_irq_cb; - int16_t m_ulaw[256]; - uint16_t m_volume[4096]; + s16 m_ulaw[256]; + u16 m_volume[4096]; static const int volume_bits = 15; ics2115_voice m_voice[32]; struct { - uint8_t scale, preset; + u8 scale, preset; emu_timer *timer; - uint64_t period; /* in nsec */ + u64 period; /* in nsec */ } m_timer[2]; - uint8_t m_active_osc; - uint8_t m_osc_select; - uint8_t m_reg_select; - uint8_t m_irq_enabled, m_irq_pending; + u8 m_active_osc; + u8 m_osc_select; + u8 m_reg_select; + u8 m_irq_enabled, m_irq_pending; bool m_irq_on; //Unknown variable, seems to be effected by 0x12. Further investigation //Required. - uint8_t m_vmode; + u8 m_vmode; }; diff --git a/src/devices/sound/k051649.cpp b/src/devices/sound/k051649.cpp index 815abb26739..995593aa6b2 100644 --- a/src/devices/sound/k051649.cpp +++ b/src/devices/sound/k051649.cpp @@ -37,7 +37,7 @@ void k051649_device::scc_map(address_map &map) map(0x80, 0x89).w(FUNC(k051649_device::k051649_frequency_w)); map(0x8a, 0x8e).w(FUNC(k051649_device::k051649_volume_w)); map(0x8f, 0x8f).w(FUNC(k051649_device::k051649_keyonoff_w)); - map(0xe0, 0xff).rw(FUNC(k051649_device::k051649_test_r), FUNC(k051649_device::k051649_test_w)); + map(0xe0, 0xe0).mirror(0x1f).rw(FUNC(k051649_device::k051649_test_r), FUNC(k051649_device::k051649_test_w)); } // device type definition @@ -177,7 +177,7 @@ void k051649_device::sound_stream_update(sound_stream &stream, stream_sample_t * /********************************************************************************/ -WRITE8_MEMBER( k051649_device::k051649_waveform_w ) +void k051649_device::k051649_waveform_w(offs_t offset, uint8_t data) { // waveram is read-only? if (m_test & 0x40 || (m_test & 0x80 && offset >= 0x60)) @@ -196,7 +196,7 @@ WRITE8_MEMBER( k051649_device::k051649_waveform_w ) } -READ8_MEMBER ( k051649_device::k051649_waveform_r ) +uint8_t k051649_device::k051649_waveform_r(offs_t offset) { // test-register bits 6/7 expose the internal counter if (m_test & 0xc0) @@ -212,7 +212,7 @@ READ8_MEMBER ( k051649_device::k051649_waveform_r ) } -WRITE8_MEMBER( k051649_device::k052539_waveform_w ) +void k051649_device::k052539_waveform_w(offs_t offset, uint8_t data) { // waveram is read-only? if (m_test & 0x40) @@ -223,7 +223,7 @@ WRITE8_MEMBER( k051649_device::k052539_waveform_w ) } -READ8_MEMBER ( k051649_device::k052539_waveform_r ) +uint8_t k051649_device::k052539_waveform_r(offs_t offset) { // test-register bit 6 exposes the internal counter if (m_test & 0x40) @@ -235,14 +235,14 @@ READ8_MEMBER ( k051649_device::k052539_waveform_r ) } -WRITE8_MEMBER( k051649_device::k051649_volume_w ) +void k051649_device::k051649_volume_w(offs_t offset, uint8_t data) { m_stream->update(); m_channel_list[offset&0x7].volume=data&0xf; } -WRITE8_MEMBER( k051649_device::k051649_frequency_w ) +void k051649_device::k051649_frequency_w(offs_t offset, uint8_t data) { int freq_hi = offset & 1; offset >>= 1; @@ -263,7 +263,7 @@ WRITE8_MEMBER( k051649_device::k051649_frequency_w ) } -WRITE8_MEMBER( k051649_device::k051649_keyonoff_w ) +void k051649_device::k051649_keyonoff_w(uint8_t data) { int i; m_stream->update(); @@ -276,16 +276,17 @@ WRITE8_MEMBER( k051649_device::k051649_keyonoff_w ) } -WRITE8_MEMBER( k051649_device::k051649_test_w ) +void k051649_device::k051649_test_w(uint8_t data) { m_test = data; } -READ8_MEMBER ( k051649_device::k051649_test_r ) +uint8_t k051649_device::k051649_test_r() { // reading the test register sets it to $ff! - k051649_test_w(space, offset, 0xff); + if (!machine().side_effects_disabled()) + k051649_test_w(0xff); return 0xff; } diff --git a/src/devices/sound/k051649.h b/src/devices/sound/k051649.h index 6ede7a295ee..bbd671fe9ab 100644 --- a/src/devices/sound/k051649.h +++ b/src/devices/sound/k051649.h @@ -18,16 +18,16 @@ class k051649_device : public device_t, public: k051649_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); - DECLARE_WRITE8_MEMBER( k051649_waveform_w ); - DECLARE_READ8_MEMBER ( k051649_waveform_r ); - DECLARE_WRITE8_MEMBER( k051649_volume_w ); - DECLARE_WRITE8_MEMBER( k051649_frequency_w ); - DECLARE_WRITE8_MEMBER( k051649_keyonoff_w ); - DECLARE_WRITE8_MEMBER( k051649_test_w ); - DECLARE_READ8_MEMBER ( k051649_test_r ); - - DECLARE_WRITE8_MEMBER( k052539_waveform_w ); - DECLARE_READ8_MEMBER ( k052539_waveform_r ); + void k051649_waveform_w(offs_t offset, uint8_t data); + uint8_t k051649_waveform_r(offs_t offset); + void k051649_volume_w(offs_t offset, uint8_t data); + void k051649_frequency_w(offs_t offset, uint8_t data); + void k051649_keyonoff_w(uint8_t data); + void k051649_test_w(uint8_t data); + uint8_t k051649_test_r(); + + void k052539_waveform_w(offs_t offset, uint8_t data); + uint8_t k052539_waveform_r(offs_t offset); void scc_map(address_map &map); protected: diff --git a/src/devices/sound/k054539.cpp b/src/devices/sound/k054539.cpp index 35f45bf4fa6..17dd9c97501 100644 --- a/src/devices/sound/k054539.cpp +++ b/src/devices/sound/k054539.cpp @@ -338,7 +338,7 @@ void k054539_device::init_chip() save_item(NAME(m_timer_state)); } -WRITE8_MEMBER(k054539_device::write) +void k054539_device::write(offs_t offset, u8 data) { if(0) { int voice, reg; @@ -476,7 +476,7 @@ void k054539_device::device_post_load() cur_limit = rom_addr == 0x80 ? 0x4000 : 0x20000; } -READ8_MEMBER(k054539_device::read) +u8 k054539_device::read(offs_t offset) { switch(offset) { case 0x22d: diff --git a/src/devices/sound/k054539.h b/src/devices/sound/k054539.h index ebc117d494c..9e7bafdb0fc 100644 --- a/src/devices/sound/k054539.h +++ b/src/devices/sound/k054539.h @@ -44,8 +44,8 @@ public: set_analog_callback(cb_delegate(callback, name, nullptr, static_cast<FunctionClass *>(nullptr))); } - DECLARE_WRITE8_MEMBER(write); - DECLARE_READ8_MEMBER(read); + void write(offs_t offset, u8 data); + u8 read(offs_t offset); void init_flags(int flags); diff --git a/src/devices/sound/meg.cpp b/src/devices/sound/meg.cpp new file mode 100644 index 00000000000..a1f9d67b293 --- /dev/null +++ b/src/devices/sound/meg.cpp @@ -0,0 +1,384 @@ +// license:BSD-3-Clause +// copyright-holders:Olivier Galibert + +// Yamaha MEG - Multiple effects generator +// +// Audio dsp dedicated to effects generation + +#include "emu.h" +#include "debugger.h" +#include "meg.h" + +DEFINE_DEVICE_TYPE(MEG, meg_device, "meg", "Multiple Effects Generator (HD62098 / XM309A00)") +DEFINE_DEVICE_TYPE(MEGEMB, meg_embedded_device, "megemb", "Multiple Effects Generator (embedded)") + +void meg_base_device::prg_map(address_map &map) +{ + map(0, m_prg_size - 1).ram(); +} + +void meg_base_device::fp_map(address_map &map) +{ + map(0, m_prg_size - 1).ram(); +} + +void meg_base_device::offsets_map(address_map &map) +{ + map(0, 0x7f).ram(); +} + +meg_base_device::meg_base_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock, u32 prg_size) : + cpu_device(mconfig, type, tag, owner, clock), + m_program_config("program", ENDIANNESS_BIG, 64, prg_size > 256 ? 9 : 8, -3, address_map_constructor(FUNC(meg_base_device::prg_map), this)), + m_fp_config("fp", ENDIANNESS_BIG, 16, prg_size > 256 ? 9 : 8, -1, address_map_constructor(FUNC(meg_base_device::fp_map), this)), + m_offsets_config("offsets", ENDIANNESS_BIG, 16, prg_size > 256 ? 7 : 7, -1, address_map_constructor(FUNC(meg_base_device::offsets_map), this)), + m_prg_size(prg_size) +{ +} + + +void meg_base_device::prg_w(u16 address, u64 opcode) +{ + m_program->write_qword(address, opcode); +} + +void meg_base_device::fp_w(u16 address, u16 value) +{ + m_fp->write_word(address, value); +} + +void meg_base_device::offset_w(u16 address, u16 value) +{ + m_offsets->write_word(address, value); +} + +void meg_base_device::lfo_w(u8 reg, u16 value) +{ + m_lfo[reg] = value; + + static const int dt[8] = { 0, 32, 64, 128, 256, 512, 1024, 2048 }; + static const int sh[8] = { 0, 0, 1, 2, 3, 4, 5, 6 }; + + int scale = (value >> 5) & 7; + int step = ((value & 31) << sh[scale]) + dt[scale]; + logerror("lfo_w %02x freq=%5.2f phase=%6.4f\n", reg, step * 44100.0/4194304, (value >> 8)/256.0); +} + +void meg_base_device::map_w(u8 reg, u16 value) +{ + m_map[reg] = value; +} + +u64 meg_base_device::prg_r(u16 address) const +{ + return m_program->read_qword(address); +} + +u16 meg_base_device::fp_r(u16 address) const +{ + return m_fp->read_word(address); +} + +u16 meg_base_device::offset_r(u16 address) const +{ + return m_offsets->read_word(address); +} + +u16 meg_base_device::lfo_r(u8 reg) const +{ + return m_lfo[reg]; +} + +u16 meg_base_device::map_r(u8 reg) const +{ + return m_map[reg]; +} + + +void meg_base_device::device_start() +{ + m_program = &space(AS_PROGRAM); + m_fp = &space(AS_FP); + m_offsets = &space(AS_OFFSETS); + + state_add(STATE_GENPC, "GENPC", m_pc).noshow(); + state_add(STATE_GENPCBASE, "CURPC", m_pc).noshow(); + state_add(0, "PC", m_pc); + + set_icountptr(m_icount); + + save_item(NAME(m_lfo)); + save_item(NAME(m_map)); + save_item(NAME(m_pc)); +} + +void meg_base_device::device_reset() +{ + memset(m_lfo, 0, sizeof(m_lfo)); + memset(m_map, 0, sizeof(m_map)); + m_pc = 0; +} + +uint32_t meg_base_device::execute_min_cycles() const +{ + return 1; +} + +uint32_t meg_base_device::execute_max_cycles() const +{ + return 1; +} + +uint32_t meg_base_device::execute_input_lines() const +{ + return 0; +} + +void meg_base_device::execute_run() +{ + if(machine().debug_flags & DEBUG_FLAG_ENABLED) + debugger_instruction_hook(m_pc); + m_icount = 0; +} + +device_memory_interface::space_config_vector meg_base_device::memory_space_config() const +{ + return space_config_vector { + std::make_pair(AS_PROGRAM, &m_program_config), + std::make_pair(AS_FP, &m_fp_config), + std::make_pair(AS_OFFSETS, &m_offsets_config) + }; +} + +void meg_base_device::state_import(const device_state_entry &entry) +{ +} + +void meg_base_device::state_export(const device_state_entry &entry) +{ +} + +void meg_base_device::state_string_export(const device_state_entry &entry, std::string &str) const +{ +} + +std::unique_ptr<util::disasm_interface> meg_base_device::create_disassembler() +{ + return std::make_unique<meg_disassembler>(this); +} + +meg_embedded_device::meg_embedded_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) : + meg_base_device(mconfig, MEGEMB, tag, owner, clock, 384) +{ +} + +meg_device::meg_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) : + meg_base_device(mconfig, MEG, tag, owner, clock, 256) +{ +} + + +// vl70: +// 6d1e: write 1, r0l +// 6d26: write 2, r0l +// 6d2e: read 2 +// 6d36: write 3, r0l +// 6d3e: write reg 4:r0h, r0l +// 6d52: write reg 5:r0h, r0l-1 +// 6d68: write 7, r0l +// 6d70: write reg 8:r0h, r0l +// 6d84: write reg 9:r0h, r0l +// 6dac: write a, r0l +// 6db4: write reg cd:r1l, r0 +// 6dd4: write reg e:r0h, r0l +// 6dee: write reg f:r0h, r0l +// 6e08: read 10,11 +// 6e1c: write reg 1213:r1l, r0 +// 6e3c: write reg 14:r0h, r0l +// 6e50: write 15, r0l +// 6e58: write reg 16:r0h, r0l +// 6e6c: write reg 17:r0h, r0l +// 6e80: write reg 18:e0h, e0l + +void meg_device::map(address_map &map) +{ + map(0x00, 0x00).w(FUNC(meg_device::select_w)); + map(0x01, 0x01).w(FUNC(meg_device::s1_w)); + map(0x02, 0x02).rw(FUNC(meg_device::s2_r), FUNC(meg_device::s2_w)); + map(0x03, 0x03).w(FUNC(meg_device::s3_w)); + map(0x04, 0x04).w(FUNC(meg_device::s4_w)); + map(0x05, 0x05).w(FUNC(meg_device::s5_w)); + map(0x07, 0x07).w(FUNC(meg_device::s7_w)); + map(0x08, 0x08).w(FUNC(meg_device::s8_w)); + map(0x09, 0x09).w(FUNC(meg_device::s9_w)); + map(0x0a, 0x0a).w(FUNC(meg_device::sa_w)); + map(0x0c, 0x0c).w(FUNC(meg_device::fph_w)); + map(0x0d, 0x0d).w(FUNC(meg_device::fpl_w)); + map(0x0e, 0x0e).w(FUNC(meg_device::se_w)); + map(0x0f, 0x0f).w(FUNC(meg_device::sf_w)); + map(0x10, 0x10).r(FUNC(meg_device::s10_r)); + map(0x11, 0x11).r(FUNC(meg_device::s11_r)); + map(0x12, 0x12).w(FUNC(meg_device::offseth_w)); + map(0x13, 0x13).w(FUNC(meg_device::offsetl_w)); + map(0x14, 0x14).w(FUNC(meg_device::s14_w)); + map(0x15, 0x15).w(FUNC(meg_device::s15_w)); + map(0x16, 0x16).w(FUNC(meg_device::s16_w)); + map(0x17, 0x17).w(FUNC(meg_device::s17_w)); + map(0x18, 0x18).w(FUNC(meg_device::s18_w)); +} + +u8 meg_device::s2_r() +{ + logerror("read r2 %s\n", machine().describe_context()); + return 0x00; +} + +void meg_device::select_w(u8 data) +{ + m_reg = data; +} + +void meg_device::s1_w(u8 data) +{ + logerror("r1 %02x %s\n", data, machine().describe_context()); +} + +void meg_device::s2_w(u8 data) +{ + logerror("r2 %02x %s\n", data, machine().describe_context()); +} + +void meg_device::s3_w(u8 data) +{ + logerror("r3 %02x %s\n", data, machine().describe_context()); +} + +void meg_device::s4_w(u8 data) +{ + if(m_r4[m_reg] != data) { + m_r4[m_reg] = data; + logerror("r4[%02x] = %02x %s\n", m_reg, data, machine().describe_context()); + } +} + +void meg_device::s5_w(u8 data) +{ + if(m_r5[m_reg] != data) { + m_r5[m_reg] = data; + logerror("r5[%02x] = %02x %s\n", m_reg, data, machine().describe_context()); + } +} + +void meg_device::s7_w(u8 data) +{ + logerror("r7 %02x %s\n", data, machine().describe_context()); +} + +void meg_device::s8_w(u8 data) +{ + if(m_r8[m_reg] != data) { + m_r8[m_reg] = data; + logerror("r8[%02x] = %02x %s\n", m_reg, data, machine().describe_context()); + } +} + + +void meg_device::s9_w(u8 data) +{ + if(m_r9[m_reg] != data) { + m_r9[m_reg] = data; + logerror("r9[%02x] = %02x %s\n", m_reg, data, machine().describe_context()); + } +} + +void meg_device::sa_w(u8 data) +{ + logerror("ra %02x %s\n", data, machine().describe_context()); +} + +void meg_device::fph_w(u8 data) +{ + fp_w(m_reg, (fp_r(m_reg) & 0x00ff) | (data << 8)); +} + + +void meg_device::fpl_w(u8 data) +{ + fp_w(m_reg, (fp_r(m_reg) & 0xff00) | data); +} + +void meg_device::se_w(u8 data) +{ + if(m_re[m_reg] != data) { + m_re[m_reg] = data; + logerror("re[%02x] = %02x %s\n", m_reg, data, machine().describe_context()); + } +} + + +void meg_device::sf_w(u8 data) +{ + if(m_rf[m_reg] != data) { + m_rf[m_reg] = data; + logerror("rf[%02x] = %02x %s\n", m_reg, data, machine().describe_context()); + } +} + +u8 meg_device::s10_r() +{ + logerror("read r10 %s\n", machine().describe_context()); + return 0x00; +} + +u8 meg_device::s11_r() +{ + logerror("read r11 %s\n", machine().describe_context()); + return 0x00; +} + +void meg_device::offseth_w(u8 data) +{ + offset_w(m_reg, (offset_r(m_reg) & 0x00ff) | (data << 8)); +} + +void meg_device::offsetl_w(u8 data) +{ + offset_w(m_reg, (offset_r(m_reg) & 0xff00) | data); +} + +void meg_device::s14_w(u8 data) +{ + if(m_r14[m_reg] != data) { + m_r14[m_reg] = data; + logerror("r14[%02x] = %02x %s\n", m_reg, data, machine().describe_context()); + } +} + +void meg_device::s15_w(u8 data) +{ + logerror("r15 %02x %s\n", data, machine().describe_context()); +} + +void meg_device::s16_w(u8 data) +{ + if(m_r16[m_reg] != data) { + m_r16[m_reg] = data; + logerror("r16[%02x] = %02x %s\n", m_reg, data, machine().describe_context()); + } +} + +void meg_device::s17_w(u8 data) +{ + if(m_r17[m_reg] != data) { + m_r17[m_reg] = data; + logerror("r17[%02x] = %02x %s\n", m_reg, data, machine().describe_context()); + } +} + +void meg_device::s18_w(u8 data) +{ + if(m_r18[m_reg] != data) { + m_r18[m_reg] = data; + logerror("r18[%02x] = %02x %s\n", m_reg, data, machine().describe_context()); + } +} diff --git a/src/devices/sound/meg.h b/src/devices/sound/meg.h new file mode 100644 index 00000000000..e9ff44f990a --- /dev/null +++ b/src/devices/sound/meg.h @@ -0,0 +1,122 @@ +// license:BSD-3-Clause +// copyright-holders:Olivier Galibert + +// Yamaha MEG - Multiple effects generator +// +// Audio dsp dedicated to effects generation + +#ifndef DEVICES_SOUND_MEG_H +#define DEVICES_SOUND_MEG_H + +#pragma once + +#include "megd.h" + + +class meg_base_device : public cpu_device, public meg_disassembler::info +{ +public: + enum { + AS_FP = 1, + AS_OFFSETS = 2 + }; + + meg_base_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock, u32 prg_size); + + void prg_w(u16 address, u64 opcode); + void fp_w(u16 address, u16 value); + void offset_w(u16 address, u16 value); + void lfo_w(u8 reg, u16 value); + void map_w(u8 reg, u16 value); + u64 prg_r(u16 address) const; + virtual u16 fp_r(u16 address) const override; + virtual u16 offset_r(u16 address) const override; + u16 lfo_r(u8 reg) const; + u16 map_r(u8 reg) const; + +protected: + virtual void device_start() override; + virtual void device_reset() override; + virtual uint32_t execute_min_cycles() const override; + virtual uint32_t execute_max_cycles() const override; + virtual uint32_t execute_input_lines() const override; + virtual void execute_run() override; + virtual space_config_vector memory_space_config() const override; + virtual void state_import(const device_state_entry &entry) override; + virtual void state_export(const device_state_entry &entry) override; + virtual void state_string_export(const device_state_entry &entry, std::string &str) const override; + virtual std::unique_ptr<util::disasm_interface> create_disassembler() override; + +private: + address_space_config m_program_config, m_fp_config, m_offsets_config; + address_space *m_program, *m_fp, *m_offsets; + + u32 m_prg_size, m_pc; + int m_icount; + + u16 m_lfo[0x18], m_map[8]; + + void prg_map(address_map &map); + void fp_map(address_map &map); + void offsets_map(address_map &map); +}; + +class meg_embedded_device : public meg_base_device +{ +public: + meg_embedded_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock = 44100*384); +}; + +class meg_device : public meg_base_device +{ +public: + meg_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock = 44100*256); + void map(address_map &map); + +private: + u8 m_r4[256]; + u8 m_r5[256]; + u8 m_r8[256]; + u8 m_r9[256]; + u8 m_re[256]; + u8 m_rf[256]; + u8 m_r12[256]; + u8 m_r13[256]; + u8 m_r14[256]; + u8 m_r16[256]; + u8 m_r17[256]; + u8 m_r18[256]; + u8 m_reg; + u8 s2_r(); + u8 s10_r(); + u8 s11_r(); + void select_w(u8 reg); + void s1_w(u8 data); + void s2_w(u8 data); + void s3_w(u8 data); + void s4_w(u8 data); + void s5_w(u8 data); + void s7_w(u8 data); + void s8_w(u8 data); + void s9_w(u8 data); + void sa_w(u8 data); + void fph_w(u8 data); + void fpl_w(u8 data); + void se_w(u8 data); + void sf_w(u8 data); + void s10_w(u8 data); + void s11_w(u8 data); + void offseth_w(u8 data); + void offsetl_w(u8 data); + void s14_w(u8 data); + void s15_w(u8 data); + void s16_w(u8 data); + void s17_w(u8 data); + void s18_w(u8 data); +}; + + +DECLARE_DEVICE_TYPE(MEG, meg_device) +DECLARE_DEVICE_TYPE(MEGEMB, meg_embedded_device) + +#endif diff --git a/src/devices/sound/megd.cpp b/src/devices/sound/megd.cpp new file mode 100644 index 00000000000..2790a7ca69c --- /dev/null +++ b/src/devices/sound/megd.cpp @@ -0,0 +1,118 @@ +// license:BSD-3-Clause +// copyright-holders:Olivier Galibert + +// Yamaha MEG - Multiple effects generator +// +// Audio dsp dedicated to effects generation +// +// Disassembler + +#include "emu.h" +#include "megd.h" + +meg_disassembler::meg_disassembler(info *inf) : m_info(inf) +{ +} + +u32 meg_disassembler::opcode_alignment() const +{ + return 1; +} + +std::string meg_disassembler::gfp(offs_t address) const +{ + if(!m_info) + return util::string_format("fp%03x", address); + s16 fp = m_info->fp_r(address); + return util::string_format("%g", fp / 16384.0); +} + +std::string meg_disassembler::goffset(offs_t address) const +{ + return m_info ? util::string_format("%x", m_info->offset_r(address)) : util::string_format("of%02x", address); +} + +u32 meg_disassembler::b(u64 opc, u32 start, u32 count) +{ + return (opc >> start) & ((1 << count) - 1); +} + +void meg_disassembler::append(std::string &r, std::string e) +{ + if(r != "") + r += " ; "; + r += e; +} + +// 33333333 33333333 22222222 22222222 11111111 11111111 00000000 00000000 +// fedcba98 76543210 fedcba98 76543210 fedcba98 76543210 fedcba98 76543210 + +// 66665555 55555544 44444444 33333333 33222222 22221111 11111100 00000000 +// 32109876 54321098 76543210 98765432 10987654 32109876 54321098 76543210 +// XLB----- -rrrrrrr r--mmmmm m-MM---- -P-----* -----Arr rrrrrrmm mmmm---- + +// m = low is read port, high is write port, memory register +// r = low is read port, high is high port, rotating register + +// X = used for lo-fi variation only +// L = lfo read +// * = compute mul +// A = mul input = m or r +// P = P sent for register write +// B = register write to mbuf +// M = memory mode, none/read/write/read+1 + +offs_t meg_disassembler::disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) +{ + u64 opc = opcodes.r64(pc); + + std::string r; + + r = util::string_format("[m%02x]", b(opc, 39, 6)); + + if(b(opc, 62, 1)) + append(r, "lfo"); + + if(b(opc, 23, 1)) + switch(b(opc, 24, 2)) { + case 0: + if(b(opc, 18, 1)) + append(r, util::string_format("p += %s*m%02x", gfp(pc), b(opc, 4, 6))); + else + append(r, util::string_format("p += %s*r%02x", gfp(pc), b(opc, 10, 8))); + break; + case 1: + append(r, util::string_format("p = %s*(r%02x+m%02x)", gfp(pc), b(opc, 10, 8), b(opc, 4, 6))); + break; + case 2: + append(r, util::string_format("p ?= %s*(r%02x+m%02x)", gfp(pc), b(opc, 10, 8), b(opc, 4, 6))); + break; + case 3: + if(b(opc, 18, 1)) + append(r, util::string_format("p = %s*m%02x", gfp(pc), b(opc, 4, 6))); + else + append(r, util::string_format("p = %s*r%02x", gfp(pc), b(opc, 10, 8))); + break; + } + + if(b(opc, 30, 1)) { + if(b(opc, 61, 1)) + append(r, "mb = p"); + else if(b(opc, 46, 1) == 1) + append(r, util::string_format("m%02x = p", b(opc, 39, 6))); + else + append(r, util::string_format("r%02x = p", b(opc, 47, 8))); + } + + u32 memmode = b(opc, 36, 2); + if(memmode) { + static const char *modes[4] = { nullptr, "w", "r", "rw" }; + + append(r, util::string_format("mem_%s %x +%s", modes[memmode], b(opc, 33, 3), goffset(pc/3))); + r += util::string_format("-> m%02x", b(opcodes.r64(pc+2), 39, 6)); + } + + stream << r; + + return 1 | SUPPORTED; +} diff --git a/src/devices/sound/megd.h b/src/devices/sound/megd.h new file mode 100644 index 00000000000..59a13aa0ea4 --- /dev/null +++ b/src/devices/sound/megd.h @@ -0,0 +1,39 @@ +// license:BSD-3-Clause +// copyright-holders:Olivier Galibert + +// Yamaha MEG - Multiple effects generator +// +// Audio dsp dedicated to effects generation +// +// Disassembler + +#ifndef DEVICES_SOUND_MEGD_H +#define DEVICES_SOUND_MEGD_H + +#pragma once + +class meg_disassembler : public util::disasm_interface +{ +public: + class info { + public: + virtual u16 fp_r(u16 address) const = 0; + virtual u16 offset_r(u16 address) const = 0; + }; + + meg_disassembler(info *inf = nullptr); + + virtual u32 opcode_alignment() const override; + virtual offs_t disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) override; + +private: + info *m_info; + + std::string gfp(offs_t address) const; + std::string goffset(offs_t address) const; + + static inline u32 b(u64 opc, u32 start, u32 count); + static inline void append(std::string &r, std::string e); +}; + +#endif diff --git a/src/devices/sound/mos6560.cpp b/src/devices/sound/mos6560.cpp index 45b944c5179..d332791ec7c 100644 --- a/src/devices/sound/mos6560.cpp +++ b/src/devices/sound/mos6560.cpp @@ -682,12 +682,14 @@ DEFINE_DEVICE_TYPE(MOS656X_ATTACK_UFO, mos656x_attack_ufo_device, "mos656x_attac // default address maps void mos6560_device::mos6560_videoram_map(address_map &map) { - map(0x0000, 0x3fff).ram(); + if (!has_configured_map(0)) + map(0x0000, 0x3fff).ram(); } void mos6560_device::mos6560_colorram_map(address_map &map) { - map(0x000, 0x3ff).ram(); + if (!has_configured_map(1)) + map(0x000, 0x3ff).ram(); } mos6560_device::mos6560_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock, uint32_t variant) @@ -696,8 +698,8 @@ mos6560_device::mos6560_device(const machine_config &mconfig, device_type type, device_sound_interface(mconfig, *this), device_video_interface(mconfig, *this), m_variant(variant), - m_videoram_space_config("videoram", ENDIANNESS_LITTLE, 8, 14, 0, address_map_constructor(), address_map_constructor(FUNC(mos6560_device::mos6560_videoram_map), this)), - m_colorram_space_config("colorram", ENDIANNESS_LITTLE, 8, 10, 0, address_map_constructor(), address_map_constructor(FUNC(mos6560_device::mos6560_colorram_map), this)), + m_videoram_space_config("videoram", ENDIANNESS_LITTLE, 8, 14, 0, address_map_constructor(FUNC(mos6560_device::mos6560_videoram_map), this)), + m_colorram_space_config("colorram", ENDIANNESS_LITTLE, 8, 10, 0, address_map_constructor(FUNC(mos6560_device::mos6560_colorram_map), this)), m_read_potx(*this), m_read_poty(*this) { diff --git a/src/devices/sound/mos6581.cpp b/src/devices/sound/mos6581.cpp index 8648e86bbc9..2e4cb1f3cfd 100644 --- a/src/devices/sound/mos6581.cpp +++ b/src/devices/sound/mos6581.cpp @@ -119,7 +119,7 @@ void mos6581_device::sound_stream_update(sound_stream &stream, stream_sample_t * // read - //------------------------------------------------- -READ8_MEMBER( mos6581_device::read ) +uint8_t mos6581_device::read(offs_t offset) { uint8_t data; @@ -146,7 +146,7 @@ READ8_MEMBER( mos6581_device::read ) // write - //------------------------------------------------- -WRITE8_MEMBER( mos6581_device::write ) +void mos6581_device::write(offs_t offset, uint8_t data) { m_token->port_w(offset, data); } diff --git a/src/devices/sound/mos6581.h b/src/devices/sound/mos6581.h index 95af2cbd687..68d319a45df 100644 --- a/src/devices/sound/mos6581.h +++ b/src/devices/sound/mos6581.h @@ -53,8 +53,8 @@ public: auto potx() { return m_read_potx.bind(); } auto poty() { return m_read_poty.bind(); } - DECLARE_READ8_MEMBER( read ); - DECLARE_WRITE8_MEMBER( write ); + uint8_t read(offs_t offset); + void write(offs_t offset, uint8_t data); protected: mos6581_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock, uint32_t variant); diff --git a/src/devices/sound/mos7360.cpp b/src/devices/sound/mos7360.cpp index f1ced2e6a9e..2c3f6cbd26d 100644 --- a/src/devices/sound/mos7360.cpp +++ b/src/devices/sound/mos7360.cpp @@ -172,7 +172,8 @@ DEFINE_DEVICE_TYPE(MOS7360, mos7360_device, "mos7360", "MOS 7360 TED") // default address maps void mos7360_device::mos7360_videoram_map(address_map &map) { - map(0x0000, 0xffff).ram(); + if (!has_configured_map(0)) + map(0x0000, 0xffff).ram(); } @@ -265,7 +266,7 @@ mos7360_device::mos7360_device(const machine_config &mconfig, const char *tag, d device_memory_interface(mconfig, *this), device_sound_interface(mconfig, *this), device_video_interface(mconfig, *this), - m_videoram_space_config("videoram", ENDIANNESS_LITTLE, 8, 16, 0, address_map_constructor(), address_map_constructor(FUNC(mos7360_device::mos7360_videoram_map), this)), + m_videoram_space_config("videoram", ENDIANNESS_LITTLE, 8, 16, 0, address_map_constructor(FUNC(mos7360_device::mos7360_videoram_map), this)), m_write_irq(*this), m_read_k(*this), m_stream(nullptr) diff --git a/src/devices/sound/msm5205.h b/src/devices/sound/msm5205.h index 7bdb0544af1..2f36d0347e9 100644 --- a/src/devices/sound/msm5205.h +++ b/src/devices/sound/msm5205.h @@ -7,16 +7,6 @@ /* an interface for the MSM5205 and similar chips */ -#define MCFG_MSM5205_PRESCALER_SELECTOR(select) \ - downcast<msm5205_device &>(*device).set_prescaler_selector((msm5205_device::select)); - -#define MCFG_MSM5205_VCK_CALLBACK(cb) \ - downcast<msm5205_device &>(*device).set_vck_callback((DEVCB_##cb)); - -#define MCFG_MSM5205_VCLK_CB(cb) \ - downcast<msm5205_device &>(*device).set_vck_legacy_callback((DEVCB_##cb)); - - class msm5205_device : public device_t, public device_sound_interface { public: diff --git a/src/devices/sound/nile.cpp b/src/devices/sound/nile.cpp index 4e78b754db5..fcd9e4b592d 100644 --- a/src/devices/sound/nile.cpp +++ b/src/devices/sound/nile.cpp @@ -69,6 +69,11 @@ nile_device::nile_device(const machine_config &mconfig, const char *tag, device_ void nile_device::device_start() { m_stream = stream_alloc(0, 2, 44100); + save_item(NAME(m_sound_regs)); + save_item(NAME(m_vpos)); + save_item(NAME(m_frac)); + save_item(NAME(m_lponce)); + save_item(NAME(m_ctrl)); } diff --git a/src/devices/sound/okim6258.cpp b/src/devices/sound/okim6258.cpp index 491229a4e81..a9477a5d7bc 100644 --- a/src/devices/sound/okim6258.cpp +++ b/src/devices/sound/okim6258.cpp @@ -262,7 +262,7 @@ int okim6258_device::get_vclk() ***********************************************************************************************/ -READ8_MEMBER( okim6258_device::status_r ) +uint8_t okim6258_device::status_r() { m_stream->update(); @@ -275,7 +275,7 @@ READ8_MEMBER( okim6258_device::status_r ) okim6258_data_w -- write to the control port of an OKIM6258-compatible chip ***********************************************************************************************/ -WRITE8_MEMBER( okim6258_device::data_w ) +void okim6258_device::data_w(uint8_t data) { /* update the stream */ m_stream->update(); @@ -291,7 +291,7 @@ WRITE8_MEMBER( okim6258_device::data_w ) ***********************************************************************************************/ -WRITE8_MEMBER( okim6258_device::ctrl_w ) +void okim6258_device::ctrl_w(uint8_t data) { m_stream->update(); diff --git a/src/devices/sound/okim6258.h b/src/devices/sound/okim6258.h index 6ca2c67532b..57f764d4eb7 100644 --- a/src/devices/sound/okim6258.h +++ b/src/devices/sound/okim6258.h @@ -33,9 +33,9 @@ public: void set_type(int type) { m_adpcm_type = type; } void set_outbits(int outbit) { m_output_bits = outbit; } - DECLARE_READ8_MEMBER( status_r ); - DECLARE_WRITE8_MEMBER( data_w ); - DECLARE_WRITE8_MEMBER( ctrl_w ); + uint8_t status_r(); + void data_w(uint8_t data); + void ctrl_w(uint8_t data); void set_divider(int val); int get_vclk(); diff --git a/src/devices/sound/okim6295.cpp b/src/devices/sound/okim6295.cpp index faf078e5f7c..10375f7736a 100644 --- a/src/devices/sound/okim6295.cpp +++ b/src/devices/sound/okim6295.cpp @@ -210,10 +210,10 @@ void okim6295_device::set_pin7(int pin7) //------------------------------------------------- -// read_status - read the status register +// read - read the status register //------------------------------------------------- -uint8_t okim6295_device::read_status() +uint8_t okim6295_device::read() { uint8_t result = 0xf0; // naname expects bits 4-7 to be 1 @@ -228,20 +228,10 @@ uint8_t okim6295_device::read_status() //------------------------------------------------- -// read - memory interface for read +// write - write to the command register //------------------------------------------------- -READ8_MEMBER( okim6295_device::read ) -{ - return read_status(); -} - - -//------------------------------------------------- -// write_command - write to the command register -//------------------------------------------------- - -void okim6295_device::write_command(uint8_t command) +void okim6295_device::write(uint8_t command) { // if a command is pending, process the second half if (m_command != -1) @@ -323,16 +313,6 @@ void okim6295_device::write_command(uint8_t command) } -//------------------------------------------------- -// write - memory interface for write -//------------------------------------------------- - -WRITE8_MEMBER( okim6295_device::write ) -{ - write_command(data); -} - - //************************************************************************** // OKIM VOICE diff --git a/src/devices/sound/okim6295.h b/src/devices/sound/okim6295.h index 536c76b3b10..0e836c29ad9 100644 --- a/src/devices/sound/okim6295.h +++ b/src/devices/sound/okim6295.h @@ -47,11 +47,8 @@ public: // runtime configuration void set_pin7(int pin7); - uint8_t read_status(); - void write_command(uint8_t command); - - DECLARE_READ8_MEMBER( read ); - DECLARE_WRITE8_MEMBER( write ); + uint8_t read(); + void write(uint8_t command); protected: // device-level overrides diff --git a/src/devices/sound/okim6376.cpp b/src/devices/sound/okim6376.cpp index 0e33c83d7a8..e04f051b0f5 100644 --- a/src/devices/sound/okim6376.cpp +++ b/src/devices/sound/okim6376.cpp @@ -513,7 +513,7 @@ WRITE_LINE_MEMBER( okim6376_device::st_w ) ***********************************************************************************************/ -WRITE8_MEMBER( okim6376_device::write ) +void okim6376_device::write(uint8_t data) { // The data port is purely used to set the latch, everything else is started by an ST pulse diff --git a/src/devices/sound/okim6376.h b/src/devices/sound/okim6376.h index 7efaa337d49..91cb3acf7e6 100644 --- a/src/devices/sound/okim6376.h +++ b/src/devices/sound/okim6376.h @@ -13,7 +13,7 @@ class okim6376_device : public device_t, public: okim6376_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); - DECLARE_WRITE8_MEMBER( write ); + void write(uint8_t data); DECLARE_WRITE_LINE_MEMBER( st_w ); DECLARE_WRITE_LINE_MEMBER( ch2_w ); diff --git a/src/devices/sound/pokey.cpp b/src/devices/sound/pokey.cpp index 487a1b4e83b..3372ac70a81 100644 --- a/src/devices/sound/pokey.cpp +++ b/src/devices/sound/pokey.cpp @@ -99,11 +99,6 @@ #define TIMER2 1 #define TIMER4 2 -/* values to add to the divisors for the different modes */ -#define DIVADD_LOCLK 1 -#define DIVADD_HICLK 4 -#define DIVADD_HICLK_JOINED 7 - /* AUDCx */ #define NOTPOLY5 0x80 /* selects POLY5 or direct CLOCK */ #define POLY4 0x40 /* selects POLY4 or POLY17 */ @@ -152,17 +147,10 @@ #define DIV_64 28 /* divisor for 1.78979 MHz clock to 63.9211 kHz */ #define DIV_15 114 /* divisor for 1.78979 MHz clock to 15.6999 kHz */ -#define P4(chip) chip->poly4[chip->p4] -#define P5(chip) chip->poly5[chip->p5] -#define P9(chip) chip->poly9[chip->p9] -#define P17(chip) chip->poly17[chip->p17] - #define CLK_1 0 #define CLK_28 1 #define CLK_114 2 -static const int clock_divisors[3] = {1, DIV_64, DIV_15}; - constexpr unsigned pokey_device::FREQ_17_EXACT; @@ -253,7 +241,8 @@ void pokey_device::device_start() m_pot_counter = 0; m_kbd_cnt = 0; m_out_filter = 0; - m_output = 0; + m_out_raw = 0; + m_old_raw_inval = true; m_kbd_state = 0; /* reset more internal state */ @@ -435,14 +424,7 @@ void pokey_device::execute_run() { do { - uint32_t new_out = step_one_clock(); - if (m_output != new_out) - { - //printf("forced update %08d %08x\n", m_icount, m_output); - m_stream->update(); - m_output = new_out; - } - + step_one_clock(); m_icount--; } while (m_icount > 0); @@ -546,11 +528,8 @@ void pokey_device::step_keyboard() void pokey_device::step_pot() { - if ((m_SKCTL & SK_RESET) == 0) - return; - - uint8_t upd = 0; m_pot_counter++; + uint8_t upd = 0; for (int pot = 0; pot < 8; pot++) { if ((m_POTx[pot]<m_pot_counter) || (m_pot_counter == 228)) @@ -559,7 +538,9 @@ void pokey_device::step_pot() /* latching is emulated in read */ } } - synchronize(SYNC_POT, upd); + // some pots latched? + if (upd != 0) + synchronize(SYNC_POT, upd); } /* @@ -570,31 +551,38 @@ void pokey_device::step_pot() * */ -uint32_t pokey_device::step_one_clock(void) +void pokey_device::step_one_clock(void) { - int const base_clock = (m_AUDCTL & CLK_15KHZ) ? CLK_114 : CLK_28; - + /* Clocks only count if we are not in a reset */ if (m_SKCTL & SK_RESET) { - /* Clocks only count if we are not in a reset */ - int clock_triggered[3] = {0,0,0}; - int clk; - for (clk = 0; clk < 3; clk++) + /* polynom pointers */ + if (++m_p4 == 0x0000f) + m_p4 = 0; + if (++m_p5 == 0x0001f) + m_p5 = 0; + if (++m_p9 == 0x001ff) + m_p9 = 0; + if (++m_p17 == 0x1ffff) + m_p17 = 0; + + /* CLK_1: no presacler */ + int clock_triggered[3] = {1,0,0}; + /* CLK_28: prescaler 63.9211 kHz */ + if (++m_clock_cnt[CLK_28] >= DIV_64) { - m_clock_cnt[clk]++; - if (m_clock_cnt[clk] >= clock_divisors[clk]) - { - m_clock_cnt[clk] = 0; - clock_triggered[clk] = 1; - } + m_clock_cnt[CLK_28] = 0; + clock_triggered[CLK_28] = 1; + } + /* CLK_114 prescaler 15.6999 kHz */ + if (++m_clock_cnt[CLK_114] >= DIV_15) + { + m_clock_cnt[CLK_114] = 0; + clock_triggered[CLK_114] = 1; } - m_p4 = (m_p4 + 1) % 0x0000f; - m_p5 = (m_p5 + 1) % 0x0001f; - m_p9 = (m_p9 + 1) % 0x001ff; - m_p17 = (m_p17 + 1 ) % 0x1ffff; - - clk = (m_AUDCTL & CH1_HICLK) ? CLK_1 : base_clock; + int const base_clock = (m_AUDCTL & CLK_15KHZ) ? CLK_114 : CLK_28; + int clk = (m_AUDCTL & CH1_HICLK) ? CLK_1 : base_clock; if (clock_triggered[clk]) m_channel[CHAN1].inc_chan(); @@ -678,12 +666,23 @@ uint32_t pokey_device::step_one_clock(void) m_channel[CHAN1].m_filter_sample = 1; } - uint32_t sum = 0; - for (int ch = 0; ch < 4; ch++) + if (m_old_raw_inval) { - sum |= (((((m_channel[ch].m_output ^ m_channel[ch].m_filter_sample) || (m_channel[ch].m_AUDC & VOLUME_ONLY)) ? (m_channel[ch].m_AUDC & VOLUME_MASK) : 0 )) << (ch * 4)); + uint32_t sum = 0; + for (int ch = 0; ch < 4; ch++) + { + sum |= (((m_channel[ch].m_output ^ m_channel[ch].m_filter_sample) || (m_channel[ch].m_AUDC & VOLUME_ONLY)) ? + ((m_channel[ch].m_AUDC & VOLUME_MASK) << (ch * 4)) : 0); + } + + if (m_out_raw != sum) + { + //printf("forced update %08d %08x\n", m_icount, m_out_raw); + m_stream->update(); + } + m_old_raw_inval = false; + m_out_raw = sum; } - return sum; } //------------------------------------------------- @@ -700,7 +699,7 @@ void pokey_device::sound_stream_update(sound_stream &stream, stream_sample_t **i { int32_t out = 0; for (int i = 0; i < 4; i++) - out += ((m_output >> (4*i)) & 0x0f); + out += ((m_out_raw >> (4*i)) & 0x0f); out *= POKEY_DEFAULT_GAIN; out = (out > 0x7fff) ? 0x7fff : out; while( samples > 0 ) @@ -711,7 +710,7 @@ void pokey_device::sound_stream_update(sound_stream &stream, stream_sample_t **i } else if (m_output_type == RC_LOWPASS) { - double rTot = m_voltab[m_output]; + double rTot = m_voltab[m_out_raw]; double V0 = rTot / (rTot+m_r_pullup) * m_v_ref / 5.0 * 32767.0; double mult = (m_cap == 0.0) ? 1.0 : 1.0 - exp(-(rTot + m_r_pullup) / (m_cap * m_r_pullup * rTot) * m_clock_period.as_double()); @@ -727,7 +726,7 @@ void pokey_device::sound_stream_update(sound_stream &stream, stream_sample_t **i } else if (m_output_type == OPAMP_C_TO_GROUND) { - double rTot = m_voltab[m_output]; + double rTot = m_voltab[m_out_raw]; /* In this configuration there is a capacitor in parallel to the pokey output to ground. * With a LM324 in LTSpice this causes the opamp circuit to oscillate at around 100 kHz. * We are ignoring the capacitor here, since this oscillation would not be audible. @@ -749,7 +748,7 @@ void pokey_device::sound_stream_update(sound_stream &stream, stream_sample_t **i } else if (m_output_type == OPAMP_LOW_PASS) { - double rTot = m_voltab[m_output]; + double rTot = m_voltab[m_out_raw]; /* This post-pokey stage usually has a low-pass filter behind it * It is approximated by not adding in VRef below. */ @@ -767,7 +766,7 @@ void pokey_device::sound_stream_update(sound_stream &stream, stream_sample_t **i } else if (m_output_type == DISCRETE_VAR_R) { - int32_t out = m_voltab[m_output]; + int32_t out = m_voltab[m_out_raw]; while( samples > 0 ) { *buffer++ = out; @@ -780,7 +779,7 @@ void pokey_device::sound_stream_update(sound_stream &stream, stream_sample_t **i // read - memory interface for reading the active status //------------------------------------------------- -READ8_MEMBER( pokey_device::read ) +uint8_t pokey_device::read(offs_t offset) { int data, pot; @@ -876,7 +875,7 @@ READ8_MEMBER( pokey_device::read ) // write - memory interface for write //------------------------------------------------- -WRITE8_MEMBER( pokey_device::write ) +void pokey_device::write(offs_t offset, uint8_t data) { synchronize(SYNC_WRITE, (offset << 8) | data); } @@ -894,6 +893,7 @@ void pokey_device::write_internal(offs_t offset, uint8_t data) case AUDC1_C: LOG_SOUND(("POKEY '%s' AUDC1 $%02x (%s)\n", tag(), data, audc2str(data))); m_channel[CHAN1].m_AUDC = data; + m_old_raw_inval = true; break; case AUDF2_C: @@ -904,6 +904,7 @@ void pokey_device::write_internal(offs_t offset, uint8_t data) case AUDC2_C: LOG_SOUND(("POKEY '%s' AUDC2 $%02x (%s)\n", tag(), data, audc2str(data))); m_channel[CHAN2].m_AUDC = data; + m_old_raw_inval = true; break; case AUDF3_C: @@ -914,6 +915,7 @@ void pokey_device::write_internal(offs_t offset, uint8_t data) case AUDC3_C: LOG_SOUND(("POKEY '%s' AUDC3 $%02x (%s)\n", tag(), data, audc2str(data))); m_channel[CHAN3].m_AUDC = data; + m_old_raw_inval = true; break; case AUDF4_C: @@ -924,6 +926,7 @@ void pokey_device::write_internal(offs_t offset, uint8_t data) case AUDC4_C: LOG_SOUND(("POKEY '%s' AUDC4 $%02x (%s)\n", tag(), data, audc2str(data))); m_channel[CHAN4].m_AUDC = data; + m_old_raw_inval = true; break; case AUDCTL_C: @@ -948,7 +951,7 @@ void pokey_device::write_internal(offs_t offset, uint8_t data) m_channel[i].m_output = 0; m_channel[i].m_filter_sample = (i<2 ? 1 : 0); } - + m_old_raw_inval = true; break; case SKREST_C: @@ -1018,6 +1021,7 @@ void pokey_device::write_internal(offs_t offset, uint8_t data) m_clock_cnt[0] = 0; m_clock_cnt[1] = 0; m_clock_cnt[2] = 0; + m_old_raw_inval = true; /* FIXME: Serial port reset ! */ } break; @@ -1066,6 +1070,7 @@ inline void pokey_device::process_channel(int ch) m_channel[ch].m_output = (m_poly9[m_p9] & 1); else m_channel[ch].m_output = (m_poly17[m_p17] & 1); + m_old_raw_inval = true; } } diff --git a/src/devices/sound/pokey.h b/src/devices/sound/pokey.h index ec1a21b3541..7e63e89e54d 100644 --- a/src/devices/sound/pokey.h +++ b/src/devices/sound/pokey.h @@ -165,8 +165,8 @@ public: set_interrupt_callback(int_cb_delegate(callback, name, nullptr, static_cast<FunctionClass *>(nullptr))); } - DECLARE_READ8_MEMBER( read ); - DECLARE_WRITE8_MEMBER( write ); + uint8_t read(offs_t offset); + void write(offs_t offset, uint8_t data); DECLARE_WRITE_LINE_MEMBER( sid_w ); // pin 24 void serin_ready(int after); @@ -264,7 +264,7 @@ private: static constexpr int POKEY_CHANNELS = 4; - uint32_t step_one_clock(); + void step_one_clock(); void step_keyboard(); void step_pot(); @@ -284,10 +284,11 @@ private: pokey_channel m_channel[POKEY_CHANNELS]; - uint32_t m_output; /* raw output */ - double m_out_filter; /* filtered output */ + uint32_t m_out_raw; /* raw output */ + bool m_old_raw_inval; /* true: recalc m_out_raw required */ + double m_out_filter; /* filtered output */ - int32_t m_clock_cnt[3]; /* clock counters */ + int32_t m_clock_cnt[3]; /* clock counters */ uint32_t m_p4; /* poly4 index */ uint32_t m_p5; /* poly5 index */ uint32_t m_p9; /* poly9 index */ diff --git a/src/devices/sound/qs1000.h b/src/devices/sound/qs1000.h index 237ef21b8e5..f57b2e41d91 100644 --- a/src/devices/sound/qs1000.h +++ b/src/devices/sound/qs1000.h @@ -40,6 +40,7 @@ public: //auto serial_w() { return m_serial_w_cb.bind(); } // external + i8052_device &cpu() const { return *m_cpu; } void serial_in(uint8_t data); DECLARE_WRITE_LINE_MEMBER( set_irq ); diff --git a/src/devices/sound/rf5c68.cpp b/src/devices/sound/rf5c68.cpp index 2af393c884b..9ec522b7d92 100644 --- a/src/devices/sound/rf5c68.cpp +++ b/src/devices/sound/rf5c68.cpp @@ -189,7 +189,7 @@ void rf5c68_device::sound_stream_update(sound_stream &stream, stream_sample_t ** // RF5C68 write register //------------------------------------------------- -READ8_MEMBER( rf5c68_device::rf5c68_r ) +u8 rf5c68_device::rf5c68_r(offs_t offset) { uint8_t shift; @@ -201,7 +201,7 @@ READ8_MEMBER( rf5c68_device::rf5c68_r ) return (m_chan[(offset & 0x0e) >> 1].addr) >> (shift); } -WRITE8_MEMBER( rf5c68_device::rf5c68_w ) +void rf5c68_device::rf5c68_w(offs_t offset, u8 data) { pcm_channel &chan = m_chan[m_cbank]; int i; @@ -266,7 +266,7 @@ WRITE8_MEMBER( rf5c68_device::rf5c68_w ) // RF5C68 read memory //------------------------------------------------- -READ8_MEMBER( rf5c68_device::rf5c68_mem_r ) +u8 rf5c68_device::rf5c68_mem_r(offs_t offset) { return m_cache->read_byte(m_wbank | offset); } @@ -276,7 +276,7 @@ READ8_MEMBER( rf5c68_device::rf5c68_mem_r ) // RF5C68 write memory //------------------------------------------------- -WRITE8_MEMBER( rf5c68_device::rf5c68_mem_w ) +void rf5c68_device::rf5c68_mem_w(offs_t offset, u8 data) { m_data->write_byte(m_wbank | offset, data); } diff --git a/src/devices/sound/rf5c68.h b/src/devices/sound/rf5c68.h index 056d2c9c99c..262efb54286 100644 --- a/src/devices/sound/rf5c68.h +++ b/src/devices/sound/rf5c68.h @@ -38,11 +38,11 @@ public: set_end_callback(sample_end_cb_delegate(callback, name, nullptr, static_cast<FunctionClass *>(nullptr))); } - DECLARE_READ8_MEMBER( rf5c68_r ); - DECLARE_WRITE8_MEMBER( rf5c68_w ); + u8 rf5c68_r(offs_t offset); + void rf5c68_w(offs_t offset, u8 data); - DECLARE_READ8_MEMBER( rf5c68_mem_r ); - DECLARE_WRITE8_MEMBER( rf5c68_mem_w ); + u8 rf5c68_mem_r(offs_t offset); + void rf5c68_mem_w(offs_t offset, u8 data); protected: rf5c68_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 clock); diff --git a/src/devices/sound/sn76496.cpp b/src/devices/sound/sn76496.cpp index 23b29c208e3..6765fb3393f 100644 --- a/src/devices/sound/sn76496.cpp +++ b/src/devices/sound/sn76496.cpp @@ -290,14 +290,14 @@ void sn76496_base_device::device_clock_changed() m_sound->set_sample_rate(clock()/2); } -WRITE8_MEMBER( sn76496_base_device::stereo_w ) +void sn76496_base_device::stereo_w(u8 data) { m_sound->update(); if (m_stereo) m_stereo_mask = data; else fatalerror("sn76496_base_device: Call to stereo write with mono chip!\n"); } -void sn76496_base_device::write(uint8_t data) +void sn76496_base_device::write(u8 data) { int n, r, c; diff --git a/src/devices/sound/sn76496.h b/src/devices/sound/sn76496.h index b518fa25398..cd7b4a6c509 100644 --- a/src/devices/sound/sn76496.h +++ b/src/devices/sound/sn76496.h @@ -24,9 +24,8 @@ class sn76496_base_device : public device_t, public device_sound_interface public: auto ready_cb() { return m_ready_handler.bind(); } - DECLARE_WRITE8_MEMBER( stereo_w ); - void write(uint8_t data); - DECLARE_WRITE8_MEMBER( command_w ) { write(data); } + void stereo_w(u8 data); + void write(u8 data); DECLARE_READ_LINE_MEMBER( ready_r ) { return m_ready_state ? 1 : 0; } protected: diff --git a/src/devices/sound/spkrdev.h b/src/devices/sound/spkrdev.h index 7542d943793..49e953b5d40 100644 --- a/src/devices/sound/spkrdev.h +++ b/src/devices/sound/spkrdev.h @@ -21,9 +21,9 @@ public: ~speaker_sound_device() {} // configuration - void set_levels(int num_levels, const int16_t *levels) { m_num_levels = num_levels; m_levels = levels;} + void set_levels(int num_levels, const int16_t *levels) { m_num_levels = num_levels; m_levels = levels; } - void level_w(int new_level); + void level_w(int new_level); // can use as writeline protected: // device-level overrides diff --git a/src/devices/sound/swp30.cpp b/src/devices/sound/swp30.cpp index 56870df5ec7..f43df8084f9 100644 --- a/src/devices/sound/swp30.cpp +++ b/src/devices/sound/swp30.cpp @@ -150,8 +150,15 @@ DEFINE_DEVICE_TYPE(SWP30, swp30_device, "swp30", "Yamaha SWP30 sound chip") swp30_device::swp30_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) : device_t(mconfig, SWP30, tag, owner, clock), device_sound_interface(mconfig, *this), - device_rom_interface(mconfig, *this, 25+2, ENDIANNESS_LITTLE, 32) + device_rom_interface(mconfig, *this, 25+2, ENDIANNESS_LITTLE, 32), + m_meg(*this, "meg") { + (void)m_map; +} + +void swp30_device::device_add_mconfig(machine_config &config) +{ + MEGEMB(config, m_meg); } void swp30_device::device_start() @@ -160,7 +167,7 @@ void swp30_device::device_start() // Attenuantion for panning is 4.4 floating point. That means 0 // to -96.3dB. Since it's a nice range, we assume it's the same - // for other attenuation values. Computed value is is 1.16 + // for other attenuation values. Computed value is 1.16 // format, to avoid overflow for(int i=0; i<256; i++) @@ -328,8 +335,8 @@ void swp30_device::map(address_map &map) rchan(map, 0x27).rw(FUNC(swp30_device::prg_fp_r<3>), FUNC(swp30_device::prg_fp_w<3>)); rchan(map, 0x29).rw(FUNC(swp30_device::prg_fp_r<4>), FUNC(swp30_device::prg_fp_w<4>)); rchan(map, 0x2b).rw(FUNC(swp30_device::prg_fp_r<5>), FUNC(swp30_device::prg_fp_w<5>)); - rchan(map, 0x30).rw(FUNC(swp30_device::prg_int_r<0>), FUNC(swp30_device::prg_int_w<0>)); - rchan(map, 0x31).rw(FUNC(swp30_device::prg_int_r<1>), FUNC(swp30_device::prg_int_w<1>)); + rchan(map, 0x30).rw(FUNC(swp30_device::prg_off_r<0>), FUNC(swp30_device::prg_off_w<0>)); + rchan(map, 0x31).rw(FUNC(swp30_device::prg_off_r<1>), FUNC(swp30_device::prg_off_w<1>)); rchan(map, 0x3e).rw(FUNC(swp30_device::prg_lfo_r<0>), FUNC(swp30_device::prg_lfo_w<0>)); rchan(map, 0x3f).rw(FUNC(swp30_device::prg_lfo_r<1>), FUNC(swp30_device::prg_lfo_w<1>)); } @@ -381,14 +388,14 @@ void swp30_device::prg_address_w(u16 data) template<int sel> u16 swp30_device::prg_r() { constexpr offs_t shift = 48-16*sel; - return m_program[m_program_address] >> shift; + return m_meg->prg_r(m_program_address) >> shift; } template<int sel> void swp30_device::prg_w(u16 data) { constexpr offs_t shift = 48-16*sel; constexpr u64 mask = ~(u64(0xffff) << shift); - m_program[m_program_address] = (m_program[m_program_address] & mask) | (u64(data) << shift); + m_meg->prg_w(m_program_address, (m_meg->prg_r(m_program_address) & mask) | (u64(data) << shift)); if(sel == 3) { if(0) @@ -402,14 +409,12 @@ template<int sel> void swp30_device::prg_w(u16 data) template<int sel> u16 swp30_device::map_r() { - return m_map[sel]; + return m_meg->map_r(sel); } template<int sel> void swp30_device::map_w(u16 data) { - m_map[sel] = data; - if(0) - logerror("map %d: type=%02x offset=%05x size=%05x\n", sel, data >> 11, (data & 0xff) << 10, 0x400 << ((data >> 8) & 7)); + m_meg->map_w(sel, data); } @@ -656,54 +661,36 @@ void swp30_device::address_l_w(offs_t offset, u16 data) } -// MEG registers (Multiple Effects Generator) +// MEG registers forwarding template<int sel> u16 swp30_device::prg_fp_r(offs_t offset) { - offs_t adr = (offset >> 6)*6 + sel; - return m_program_pfp[adr]; + return m_meg->fp_r((offset >> 6)*6 + sel); } template<int sel> void swp30_device::prg_fp_w(offs_t offset, u16 data) { - offs_t adr = (offset >> 6)*6 + sel; - m_program_pfp[adr] = data; - if(0) - logerror("prg_fp_w %03x, %04x\n", adr, data); + m_meg->fp_w((offset >> 6)*6 + sel, data); } -template<int sel> u16 swp30_device::prg_int_r(offs_t offset) +template<int sel> u16 swp30_device::prg_off_r(offs_t offset) { - offs_t adr = (offset >> 6)*2 + sel; - return m_program_pint[adr]; + return m_meg->offset_r((offset >> 6)*2 + sel); } -template<int sel> void swp30_device::prg_int_w(offs_t offset, u16 data) +template<int sel> void swp30_device::prg_off_w(offs_t offset, u16 data) { - offs_t adr = (offset >> 6)*2 + sel; - m_program_pint[adr] = data; - if(0) - logerror("prg_int_w %02x, %04x\n", adr, data); + m_meg->offset_w((offset >> 6)*2 + sel, data); } template<int sel> u16 swp30_device::prg_lfo_r(offs_t offset) { - offs_t adr = (offset >> 6)*2 + sel; - return m_program_plfo[adr]; + return m_meg->lfo_r((offset >> 6)*2 + sel); } template<int sel> void swp30_device::prg_lfo_w(offs_t offset, u16 data) { - offs_t adr = (offset >> 6)*2 + sel; - m_program_plfo[adr] = data; - - static const int dt[8] = { 0, 32, 64, 128, 256, 512, 1024, 2048 }; - static const int sh[8] = { 0, 0, 1, 2, 3, 4, 5, 6 }; - - int scale = (data >> 5) & 7; - int step = ((data & 31) << sh[scale]) + dt[scale]; - if(0) - logerror("prg_lfo_w %02x freq=%5.2f phase=%6.4f\n", adr, step * 44100.0/4194304, (data >> 8)/256.0); + m_meg->lfo_w((offset >> 6)*2 + sel, data); } diff --git a/src/devices/sound/swp30.h b/src/devices/sound/swp30.h index 56e24b453f0..dd95a8dd85f 100644 --- a/src/devices/sound/swp30.h +++ b/src/devices/sound/swp30.h @@ -8,6 +8,8 @@ #pragma once +#include "meg.h" + class swp30_device : public device_t, public device_sound_interface, public device_rom_interface { public: @@ -20,8 +22,11 @@ protected: virtual void device_reset() override; virtual void sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples) override; virtual void rom_bank_updated() override; + virtual void device_add_mconfig(machine_config &config) override; private: + required_device<meg_embedded_device> m_meg; + sound_stream *m_stream; s32 m_sample_increment[0x4000]; @@ -99,8 +104,8 @@ private: // MEG registers template<int sel> u16 prg_fp_r(offs_t offset); template<int sel> void prg_fp_w(offs_t offset, u16 data); - template<int sel> u16 prg_int_r(offs_t offset); - template<int sel> void prg_int_w(offs_t offset, u16 data); + template<int sel> u16 prg_off_r(offs_t offset); + template<int sel> void prg_off_w(offs_t offset, u16 data); template<int sel> u16 prg_lfo_r(offs_t offset); template<int sel> void prg_lfo_w(offs_t offset, u16 data); diff --git a/src/devices/sound/t6721a.cpp b/src/devices/sound/t6721a.cpp index f4ea65a92b5..423cd3edc19 100644 --- a/src/devices/sound/t6721a.cpp +++ b/src/devices/sound/t6721a.cpp @@ -74,7 +74,7 @@ void t6721a_device::sound_stream_update(sound_stream &stream, stream_sample_t ** // read - //------------------------------------------------- -READ8_MEMBER( t6721a_device::read ) +uint8_t t6721a_device::read() { return 0; } @@ -84,7 +84,7 @@ READ8_MEMBER( t6721a_device::read ) // write - //------------------------------------------------- -WRITE8_MEMBER( t6721a_device::write ) +void t6721a_device::write(uint8_t data) { } diff --git a/src/devices/sound/t6721a.h b/src/devices/sound/t6721a.h index 0342cbaad84..ebc7ea6924e 100644 --- a/src/devices/sound/t6721a.h +++ b/src/devices/sound/t6721a.h @@ -53,8 +53,8 @@ public: auto dtrd_handler() { return m_write_dtrd.bind(); } auto apd_handler() { return m_write_apd.bind(); } - DECLARE_READ8_MEMBER( read ); - DECLARE_WRITE8_MEMBER( write ); + uint8_t read(); + void write(uint8_t data); DECLARE_WRITE_LINE_MEMBER( di_w ); diff --git a/src/devices/sound/t6w28.cpp b/src/devices/sound/t6w28.cpp index 2f155644c5c..cc7324d41f1 100644 --- a/src/devices/sound/t6w28.cpp +++ b/src/devices/sound/t6w28.cpp @@ -39,7 +39,7 @@ Offset 0: #define STEP 0x10000 -WRITE8_MEMBER( t6w28_device::write ) +void t6w28_device::write(offs_t offset, uint8_t data) { int n, r, c; diff --git a/src/devices/sound/t6w28.h b/src/devices/sound/t6w28.h index e62852e77b6..e6cc2d9319d 100644 --- a/src/devices/sound/t6w28.h +++ b/src/devices/sound/t6w28.h @@ -10,8 +10,8 @@ class t6w28_device : public device_t, public device_sound_interface public: t6w28_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); - DECLARE_WRITE8_MEMBER( write ); - void set_enable( bool enable ); + void write(offs_t offset, uint8_t data); + void set_enable(bool enable); protected: // device-level overrides diff --git a/src/devices/sound/upd7752.cpp b/src/devices/sound/upd7752.cpp index f49171588e7..e2e28317d4c 100644 --- a/src/devices/sound/upd7752.cpp +++ b/src/devices/sound/upd7752.cpp @@ -31,8 +31,8 @@ DEFINE_DEVICE_TYPE(UPD7752, upd7752_device, "upd7752", "NEC uPD7752") /* TODO: unknown exact size */ void upd7752_device::upd7752_ram(address_map &map) { -// AM_RANGE(0x0000, 0x7fff) AM_ROM - map(0x0000, 0xffff).ram(); + if (!has_configured_map(0)) + map(0x0000, 0xffff).ram(); } //************************************************************************** @@ -47,7 +47,7 @@ upd7752_device::upd7752_device(const machine_config &mconfig, const char *tag, d : device_t(mconfig, UPD7752, tag, owner, clock), device_sound_interface(mconfig, *this), device_memory_interface(mconfig, *this), m_stream(nullptr), - m_space_config("ram", ENDIANNESS_LITTLE, 8, 16, 0, address_map_constructor(), address_map_constructor(FUNC(upd7752_device::upd7752_ram), this)), m_status(0), m_ram_addr(0), m_mode(0) + m_space_config("ram", ENDIANNESS_LITTLE, 8, 16, 0, address_map_constructor(FUNC(upd7752_device::upd7752_ram), this)), m_status(0), m_ram_addr(0), m_mode(0) { } diff --git a/src/devices/sound/vlm5030.cpp b/src/devices/sound/vlm5030.cpp index 9bdbd807876..f58540558d4 100644 --- a/src/devices/sound/vlm5030.cpp +++ b/src/devices/sound/vlm5030.cpp @@ -397,9 +397,9 @@ READ_LINE_MEMBER( vlm5030_device::bsy ) } /* latch contoll data */ -WRITE8_MEMBER( vlm5030_device::data_w ) +void vlm5030_device::data_w(uint8_t data) { - m_latch_data = (uint8_t)data; + m_latch_data = data; } /* set RST pin level : reset / set table address A8-A15 */ diff --git a/src/devices/sound/vlm5030.h b/src/devices/sound/vlm5030.h index af5f6dbc75b..adbd9173c2b 100644 --- a/src/devices/sound/vlm5030.h +++ b/src/devices/sound/vlm5030.h @@ -14,7 +14,7 @@ public: DECLARE_READ_LINE_MEMBER( bsy ); /* latch contoll data */ - DECLARE_WRITE8_MEMBER( data_w ); + void data_w(uint8_t data); /* set RST pin level : reset / set table address A8-A15 */ DECLARE_WRITE_LINE_MEMBER( rst ); diff --git a/src/devices/sound/volt_reg.cpp b/src/devices/sound/volt_reg.cpp index 12f3ed31130..aade7ddff01 100644 --- a/src/devices/sound/volt_reg.cpp +++ b/src/devices/sound/volt_reg.cpp @@ -23,7 +23,7 @@ voltage_regulator_device::voltage_regulator_device(const machine_config &mconfig device_t(mconfig, VOLTAGE_REGULATOR, tag, owner, clock), device_sound_interface(mconfig, *this), m_stream(nullptr), - m_output(0) + m_output(0x7fff) { } diff --git a/src/devices/sound/volt_reg.h b/src/devices/sound/volt_reg.h index f2e5d88298e..516039aac17 100644 --- a/src/devices/sound/volt_reg.h +++ b/src/devices/sound/volt_reg.h @@ -14,13 +14,10 @@ #pragma once -#define MCFG_VOLTAGE_REGULATOR_OUTPUT(_output) \ - downcast<voltage_regulator_device &>(*device).set_output(_output); - class voltage_regulator_device : public device_t, public device_sound_interface { public: - voltage_regulator_device &set_output(double analogue_dc) { m_output = (analogue_dc * 32768) / 5.0f; return *this; } + voltage_regulator_device &set_output(double analogue_dc) { m_output = (analogue_dc * 0x7fff) / 5.0f; return *this; } voltage_regulator_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock = 0); diff --git a/src/devices/sound/votrax.cpp b/src/devices/sound/votrax.cpp index d2741b0a7dc..720df7d2ca9 100644 --- a/src/devices/sound/votrax.cpp +++ b/src/devices/sound/votrax.cpp @@ -84,7 +84,7 @@ votrax_sc01_device::votrax_sc01_device(const machine_config &mconfig, const char { } -WRITE8_MEMBER( votrax_sc01_device::write ) +void votrax_sc01_device::write(uint8_t data) { // flush out anything currently processing m_stream->update(); @@ -114,7 +114,7 @@ WRITE8_MEMBER( votrax_sc01_device::write ) // inflection bits //------------------------------------------------- -WRITE8_MEMBER( votrax_sc01_device::inflection_w ) +void votrax_sc01_device::inflection_w(uint8_t data) { // only 2 bits matter data &= 3; diff --git a/src/devices/sound/votrax.h b/src/devices/sound/votrax.h index a7122c561af..aa3b88cc7e3 100644 --- a/src/devices/sound/votrax.h +++ b/src/devices/sound/votrax.h @@ -24,8 +24,8 @@ public: auto ar_callback() { return m_ar_cb.bind(); } - DECLARE_WRITE8_MEMBER(write); - DECLARE_WRITE8_MEMBER(inflection_w); + void write(uint8_t data); + void inflection_w(uint8_t data); DECLARE_READ_LINE_MEMBER(request) { m_stream->update(); return m_ar_state; } protected: diff --git a/src/devices/sound/vrc6.cpp b/src/devices/sound/vrc6.cpp index e632cce1cdb..e990a0edd69 100644 --- a/src/devices/sound/vrc6.cpp +++ b/src/devices/sound/vrc6.cpp @@ -2,7 +2,7 @@ // copyright-holders:R. Belmont /*************************************************************************** - vrc6.c + vrc6.cpp Konami VRC6 additional sound channels Emulation by R. Belmont @@ -218,7 +218,7 @@ void vrc6snd_device::sound_stream_update(sound_stream &stream, stream_sample_t * // write - write to the chip's registers //--------------------------------------- -WRITE8_MEMBER( vrc6snd_device::write ) +void vrc6snd_device::write(offs_t offset, uint8_t data) { switch (offset >> 8) { diff --git a/src/devices/sound/vrc6.h b/src/devices/sound/vrc6.h index dbcd5152c3b..a24d34a90c4 100644 --- a/src/devices/sound/vrc6.h +++ b/src/devices/sound/vrc6.h @@ -24,7 +24,7 @@ public: // construction/destruction vrc6snd_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); - DECLARE_WRITE8_MEMBER(write); + void write(offs_t offset, uint8_t data); protected: // device-level overrides diff --git a/src/devices/sound/ym2151.cpp b/src/devices/sound/ym2151.cpp index 4f3a95acdb8..42c105c64a0 100644 --- a/src/devices/sound/ym2151.cpp +++ b/src/devices/sound/ym2151.cpp @@ -1676,7 +1676,7 @@ ym2151_device::ym2151_device(const machine_config &mconfig, const char *tag, dev // read - read from the device //------------------------------------------------- -READ8_MEMBER( ym2151_device::read ) +u8 ym2151_device::read(offs_t offset) { if (offset & 1) { @@ -1692,7 +1692,7 @@ READ8_MEMBER( ym2151_device::read ) // write - write from the device //------------------------------------------------- -WRITE8_MEMBER( ym2151_device::write ) +void ym2151_device::write(offs_t offset, u8 data) { if (offset & 1) { @@ -1707,19 +1707,19 @@ WRITE8_MEMBER( ym2151_device::write ) } -READ8_MEMBER( ym2151_device::status_r ) +u8 ym2151_device::status_r() { - return read(space, 1); + return read(1); } -WRITE8_MEMBER( ym2151_device::register_w ) +void ym2151_device::register_w(u8 data) { - write(space, 0, data); + write(0, data); } -WRITE8_MEMBER( ym2151_device::data_w ) +void ym2151_device::data_w(u8 data) { - write(space, 1, data); + write(1, data); } diff --git a/src/devices/sound/ym2151.h b/src/devices/sound/ym2151.h index e797a88724b..562c6bb10a2 100644 --- a/src/devices/sound/ym2151.h +++ b/src/devices/sound/ym2151.h @@ -55,12 +55,12 @@ public: auto port_write_handler() { return m_portwritehandler.bind(); } // read/write - DECLARE_READ8_MEMBER(read); - DECLARE_WRITE8_MEMBER(write); + u8 read(offs_t offset); + void write(offs_t offset, u8 data); - DECLARE_READ8_MEMBER(status_r); - DECLARE_WRITE8_MEMBER(register_w); - DECLARE_WRITE8_MEMBER(data_w); + u8 status_r(); + void register_w(u8 data); + void data_w(u8 data); DECLARE_WRITE_LINE_MEMBER(reset_w); diff --git a/src/devices/sound/ym2413.cpp b/src/devices/sound/ym2413.cpp index 69ad6b31e33..755e66ea629 100644 --- a/src/devices/sound/ym2413.cpp +++ b/src/devices/sound/ym2413.cpp @@ -42,6 +42,8 @@ to do: #include "emu.h" #include "ym2413.h" +#include <algorithm> + #define FREQ_SH 16 /* 16.16 fixed point (frequency calculations) */ #define EG_SH 16 /* 16.16 fixed point (EG timing) */ #define LFO_SH 24 /* 8.24 fixed point (LFO calculations) */ @@ -131,7 +133,7 @@ const uint32_t ym2413_device::sl_tab[16] = { }; #undef SC -const unsigned char ym2413_device::eg_inc[15*RATE_STEPS] = { +const uint8_t ym2413_device::eg_inc[15*RATE_STEPS] = { /*cycle:0 1 2 3 4 5 6 7*/ /* 0 */ 0,1, 0,1, 0,1, 0,1, /* rates 00..12 0 (increment by 0 or 1) */ @@ -158,7 +160,7 @@ const unsigned char ym2413_device::eg_inc[15*RATE_STEPS] = { #define O(a) (a*RATE_STEPS) /*note that there is no O(13) in this table - it's directly in the code */ -const unsigned char ym2413_device::eg_rate_select[16+64+16] = { /* Envelope Generator rates (16 + 64 rates + 16 RKS) */ +const uint8_t ym2413_device::eg_rate_select[16+64+16] = { /* Envelope Generator rates (16 + 64 rates + 16 RKS) */ /* 16 infinite time rates */ O(14),O(14),O(14),O(14),O(14),O(14),O(14),O(14), O(14),O(14),O(14),O(14),O(14),O(14),O(14),O(14), @@ -199,7 +201,7 @@ const unsigned char ym2413_device::eg_rate_select[16+64+16] = { /* Envelope Ge /*mask 8191, 4095, 2047, 1023, 511, 255, 127, 63, 31, 15, 7, 3, 1, 0, 0, 0 */ #define O(a) (a*1) -const unsigned char ym2413_device::eg_rate_shift[16+64+16] = { /* Envelope Generator counter shifts (16 + 64 rates + 16 RKS) */ +const uint8_t ym2413_device::eg_rate_shift[16+64+16] = { /* Envelope Generator counter shifts (16 + 64 rates + 16 RKS) */ /* 16 infinite time rates */ O(0),O(0),O(0),O(0),O(0),O(0),O(0),O(0), O(0),O(0),O(0),O(0),O(0),O(0),O(0),O(0), @@ -350,9 +352,10 @@ const int8_t ym2413_device::lfo_pm_table[8*8] = { - waveform DC and DM select are 100% correct */ -const unsigned char ym2413_device::table[19][8] = { +const uint8_t ym2413_device::table[19][8] = { /* MULT MULT modTL DcDmFb AR/DR AR/DR SL/RR SL/RR */ /* 0 1 2 3 4 5 6 7 */ +/* These YM2413(OPLL) patch dumps are done via audio analysis (and a/b testing?) from Jarek and are known to be inaccurate */ {0x49, 0x4c, 0x4c, 0x12, 0x00, 0x00, 0x00, 0x00 }, //0 {0x61, 0x61, 0x1e, 0x17, 0xf0, 0x78, 0x00, 0x17 }, //1 @@ -385,9 +388,45 @@ const unsigned char ym2413_device::table[19][8] = { /* drum instruments definitions */ /* MULTI MULTI modTL xxx AR/DR AR/DR SL/RR SL/RR */ /* 0 1 2 3 4 5 6 7 */ - {0x01, 0x01, 0x16, 0x00, 0xfd, 0xf8, 0x2f, 0x6d },/* BD(multi verified, modTL verified, mod env - verified(close), carr. env verifed) */ - {0x01, 0x01, 0x00, 0x00, 0xd8, 0xd8, 0xf9, 0xf8 },/* HH(multi verified), SD(multi not used) */ - {0x05, 0x01, 0x00, 0x00, 0xf8, 0xba, 0x49, 0x55 },/* TOM(multi,env verified), TOP CYM(multi verified, env verified) */ +/* old dumps via audio analysis (and a/b testing?) from Jarek */ +//{0x01, 0x01, 0x16, 0x00, 0xfd, 0xf8, 0x2f, 0x6d },/* BD(multi verified, modTL verified, mod env - verified(close), carr. env verifed) */ +//{0x01, 0x01, 0x00, 0x00, 0xd8, 0xd8, 0xf9, 0xf8 },/* HH(multi verified), SD(multi not used) */ +//{0x05, 0x01, 0x00, 0x00, 0xf8, 0xba, 0x49, 0x55 },/* TOM(multi,env verified), TOP CYM(multi verified, env verified) */ +/* Drums dumped from the VRC7 using debug mode, these are likely also correct for ym2413(OPLL) but need verification */ + {0x01, 0x01, 0x18, 0x0f, 0xdf, 0xf8, 0x6a, 0x6d },/* BD */ + {0x01, 0x01, 0x00, 0x00, 0xc8, 0xd8, 0xa7, 0x68 },/* HH, SD */ + {0x05, 0x01, 0x00, 0x00, 0xf8, 0xaa, 0x59, 0x55 },/* TOM, TOP CYM */ +}; + +// VRC7 Instruments : Dumped from internal ROM +// reference : https://siliconpr0n.org/archive/doku.php?id=vendor:yamaha:opl2 +const uint8_t vrc7snd_device::vrc7_table[19][8] = { +/* MULT MULT modTL DcDmFb AR/DR AR/DR SL/RR SL/RR */ +/* 0 1 2 3 4 5 6 7 */ + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, //0 (This is the user-defined instrument, should this default to anything?) + + {0x03, 0x21, 0x05, 0x06, 0xe8, 0x81, 0x42, 0x27 }, //1 + {0x13, 0x41, 0x14, 0x0d, 0xd8, 0xf6, 0x23, 0x12 }, //2 + {0x11, 0x11, 0x08, 0x08, 0xfa, 0xb2, 0x20, 0x12 }, //3 + {0x31, 0x61, 0x0c, 0x07, 0xa8, 0x64, 0x61, 0x27 }, //4 + {0x32, 0x21, 0x1e, 0x06, 0xe1, 0x76, 0x01, 0x28 }, //5 + {0x02, 0x01, 0x06, 0x00, 0xa3, 0xe2, 0xf4, 0xf4 }, //6 + {0x21, 0x61, 0x1d, 0x07, 0x82, 0x81, 0x11, 0x07 }, //7 + {0x23, 0x21, 0x22, 0x17, 0xa2, 0x72, 0x01, 0x17 }, //8 + {0x35, 0x11, 0x25, 0x00, 0x40, 0x73, 0x72, 0x01 }, //9 + {0xb5, 0x01, 0x0f, 0x0f, 0xa8, 0xa5, 0x51, 0x02 }, //A + {0x17, 0xc1, 0x24, 0x07, 0xf8, 0xf8, 0x22, 0x12 }, //B + {0x71, 0x23, 0x11, 0x06, 0x65, 0x74, 0x18, 0x16 }, //C + {0x01, 0x02, 0xd3, 0x05, 0xc9, 0x95, 0x03, 0x02 }, //D + {0x61, 0x63, 0x0c, 0x00, 0x94, 0xc0, 0x33, 0xf6 }, //E + {0x21, 0x72, 0x0d, 0x00, 0xc1, 0xd5, 0x56, 0x06 }, //F + +/* Drums (silent due to no RO output pin(?) on VRC7, but present internally; these are probably shared with YM2413) */ +/* MULTI MULTI modTL xxx AR/DR AR/DR SL/RR SL/RR */ +/* 0 1 2 3 4 5 6 7 */ + {0x01, 0x01, 0x18, 0x0f, 0xdf, 0xf8, 0x6a, 0x6d },/* BD */ + {0x01, 0x01, 0x00, 0x00, 0xc8, 0xd8, 0xa7, 0x68 },/* HH, SD */ + {0x05, 0x01, 0x00, 0x00, 0xf8, 0xaa, 0x59, 0x55 },/* TOM, TOP CYM */ }; /* work table */ @@ -823,21 +862,21 @@ void ym2413_device::rhythm_calc( OPLL_CH *CH, unsigned int noise ) */ /* base frequency derived from operator 1 in channel 7 */ - unsigned char bit7 = ((SLOT7_1->phase>>FREQ_SH)>>7)&1; - unsigned char bit3 = ((SLOT7_1->phase>>FREQ_SH)>>3)&1; - unsigned char bit2 = ((SLOT7_1->phase>>FREQ_SH)>>2)&1; + uint8_t bit7 = ((SLOT7_1->phase>>FREQ_SH)>>7)&1; + uint8_t bit3 = ((SLOT7_1->phase>>FREQ_SH)>>3)&1; + uint8_t bit2 = ((SLOT7_1->phase>>FREQ_SH)>>2)&1; - unsigned char res1 = (bit2 ^ bit7) | bit3; + uint8_t res1 = (bit2 ^ bit7) | bit3; /* when res1 = 0 phase = 0x000 | 0xd0; */ /* when res1 = 1 phase = 0x200 | (0xd0>>2); */ uint32_t phase = res1 ? (0x200|(0xd0>>2)) : 0xd0; /* enable gate based on frequency of operator 2 in channel 8 */ - unsigned char bit5e= ((SLOT8_2->phase>>FREQ_SH)>>5)&1; - unsigned char bit3e= ((SLOT8_2->phase>>FREQ_SH)>>3)&1; + uint8_t bit5e= ((SLOT8_2->phase>>FREQ_SH)>>5)&1; + uint8_t bit3e= ((SLOT8_2->phase>>FREQ_SH)>>3)&1; - unsigned char res2 = (bit3e | bit5e); + uint8_t res2 = (bit3e | bit5e); /* when res2 = 0 pass the phase from calculation above (res1); */ /* when res2 = 1 phase = 0x200 | (0xd0>>2); */ @@ -868,7 +907,7 @@ void ym2413_device::rhythm_calc( OPLL_CH *CH, unsigned int noise ) if( env < ENV_QUIET ) { /* base frequency derived from operator 1 in channel 7 */ - unsigned char bit8 = ((SLOT7_1->phase>>FREQ_SH)>>8)&1; + uint8_t bit8 = ((SLOT7_1->phase>>FREQ_SH)>>8)&1; /* when bit8 = 0 phase = 0x100; */ /* when bit8 = 1 phase = 0x200; */ @@ -894,21 +933,21 @@ void ym2413_device::rhythm_calc( OPLL_CH *CH, unsigned int noise ) if( env < ENV_QUIET ) { /* base frequency derived from operator 1 in channel 7 */ - unsigned char bit7 = ((SLOT7_1->phase>>FREQ_SH)>>7)&1; - unsigned char bit3 = ((SLOT7_1->phase>>FREQ_SH)>>3)&1; - unsigned char bit2 = ((SLOT7_1->phase>>FREQ_SH)>>2)&1; + uint8_t bit7 = ((SLOT7_1->phase>>FREQ_SH)>>7)&1; + uint8_t bit3 = ((SLOT7_1->phase>>FREQ_SH)>>3)&1; + uint8_t bit2 = ((SLOT7_1->phase>>FREQ_SH)>>2)&1; - unsigned char res1 = (bit2 ^ bit7) | bit3; + uint8_t res1 = (bit2 ^ bit7) | bit3; /* when res1 = 0 phase = 0x000 | 0x100; */ /* when res1 = 1 phase = 0x200 | 0x100; */ uint32_t phase = res1 ? 0x300 : 0x100; /* enable gate based on frequency of operator 2 in channel 8 */ - unsigned char bit5e= ((SLOT8_2->phase>>FREQ_SH)>>5)&1; - unsigned char bit3e= ((SLOT8_2->phase>>FREQ_SH)>>3)&1; + uint8_t bit5e= ((SLOT8_2->phase>>FREQ_SH)>>5)&1; + uint8_t bit3e= ((SLOT8_2->phase>>FREQ_SH)>>3)&1; - unsigned char res2 = (bit3e | bit5e); + uint8_t res2 = (bit3e | bit5e); /* when res2 = 0 pass the phase from calculation above (res1); */ /* when res2 = 1 phase = 0x200 | 0x100; */ if (res2) @@ -1635,11 +1674,14 @@ void ym2413_device::device_reset() noise_rng = 1; /* noise shift register */ /* setup instruments table */ - for (int i=0; i<19; i++) + if (m_inst_table != nullptr) { - for (int c=0; c<8; c++) + for (int i=0; i<19; i++) { - inst_tab[i][c] = table[i][c]; + for (int c=0; c<8; c++) + { + inst_tab[i][c] = m_inst_table[i][c]; + } } } @@ -1664,20 +1706,20 @@ void ym2413_device::device_reset() } -WRITE8_MEMBER( ym2413_device::write ) +void ym2413_device::write(offs_t offset, u8 data) { if (offset) - data_port_w(space, offset, data); + data_port_w(data); else - register_port_w(space, offset, data); + register_port_w(data); } -WRITE8_MEMBER( ym2413_device::register_port_w ) +void ym2413_device::register_port_w(u8 data) { address = data; } -WRITE8_MEMBER( ym2413_device::data_port_w ) +void ym2413_device::data_port_w(u8 data) { m_stream->update(); write_reg(address, data); @@ -1686,7 +1728,37 @@ WRITE8_MEMBER( ym2413_device::data_port_w ) DEFINE_DEVICE_TYPE(YM2413, ym2413_device, "ym2413", "Yamaha YM2413 OPLL") ym2413_device::ym2413_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) - : device_t(mconfig, YM2413, tag, owner, clock) + : ym2413_device(mconfig, YM2413, tag, owner, clock) +{ + for (int i = 0; i < 19; i++) + { + for (int c = 0; c < 8; c++) + { + m_inst_table[i][c] = table[i][c]; + } + } +} + +ym2413_device::ym2413_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock) + : device_t(mconfig, type, tag, owner, clock) , device_sound_interface(mconfig, *this) { + for (int i = 0; i < 19; i++) + { + std::fill_n(&m_inst_table[i][0], 8, 0); + } +} + +DEFINE_DEVICE_TYPE(VRC7, vrc7snd_device, "vrc7snd", "Konami VRC7 (Sound)") + +vrc7snd_device::vrc7snd_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) + : ym2413_device(mconfig, VRC7, tag, owner, clock) +{ + for (int i = 0; i < 19; i++) + { + for (int c = 0; c < 8; c++) + { + m_inst_table[i][c] = vrc7_table[i][c]; + } + } } diff --git a/src/devices/sound/ym2413.h b/src/devices/sound/ym2413.h index 8f496645ee9..1b0d9869770 100644 --- a/src/devices/sound/ym2413.h +++ b/src/devices/sound/ym2413.h @@ -11,12 +11,14 @@ class ym2413_device : public device_t, public device_sound_interface public: ym2413_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); - DECLARE_WRITE8_MEMBER( write ); + void write(offs_t offset, u8 data); - DECLARE_WRITE8_MEMBER( register_port_w ); - DECLARE_WRITE8_MEMBER( data_port_w ); + void register_port_w(u8 data); + void data_port_w(u8 data); protected: + ym2413_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock); + // device-level overrides virtual void device_start() override; virtual void device_clock_changed() override; @@ -25,6 +27,8 @@ protected: // sound stream update overrides virtual void sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples) override; + uint8_t m_inst_table[19][8]; + private: struct OPLL_SLOT { @@ -106,13 +110,13 @@ private: static const double ksl_tab[8*16]; static const uint32_t ksl_shift[4]; static const uint32_t sl_tab[16]; - static const unsigned char eg_inc[15*RATE_STEPS]; - static const unsigned char eg_rate_select[16+64+16]; - static const unsigned char eg_rate_shift[16+64+16]; + static const uint8_t eg_inc[15*RATE_STEPS]; + static const uint8_t eg_rate_select[16+64+16]; + static const uint8_t eg_rate_shift[16+64+16]; static const uint8_t mul_tab[16]; static const uint8_t lfo_am_table[LFO_AM_TAB_ELEMENTS]; static const int8_t lfo_pm_table[8*8]; - static const unsigned char table[19][8]; + static const uint8_t table[19][8]; int tl_tab[TL_TAB_LEN]; @@ -185,4 +189,15 @@ private: DECLARE_DEVICE_TYPE(YM2413, ym2413_device) +class vrc7snd_device : public ym2413_device +{ +public: + vrc7snd_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); + +private: + static const uint8_t vrc7_table[19][8]; +}; + +DECLARE_DEVICE_TYPE(VRC7, vrc7snd_device) + #endif // MAME_SOUND_YM2413_H diff --git a/src/devices/sound/ymf271.cpp b/src/devices/sound/ymf271.cpp index 70f466b0667..c979ea7426e 100644 --- a/src/devices/sound/ymf271.cpp +++ b/src/devices/sound/ymf271.cpp @@ -1457,7 +1457,7 @@ void ymf271_device::ymf271_write_timer(uint8_t address, uint8_t data) } } -WRITE8_MEMBER( ymf271_device::write ) +void ymf271_device::write(offs_t offset, u8 data) { m_stream->update(); @@ -1503,7 +1503,7 @@ WRITE8_MEMBER( ymf271_device::write ) } } -READ8_MEMBER( ymf271_device::read ) +u8 ymf271_device::read(offs_t offset) { switch (offset & 0xf) { diff --git a/src/devices/sound/ymf271.h b/src/devices/sound/ymf271.h index 2022096bce3..efee18db0ad 100644 --- a/src/devices/sound/ymf271.h +++ b/src/devices/sound/ymf271.h @@ -16,8 +16,8 @@ public: // configuration helpers auto irq_handler() { return m_irq_handler.bind(); } - DECLARE_READ8_MEMBER( read ); - DECLARE_WRITE8_MEMBER( write ); + u8 read(offs_t offset); + void write(offs_t offset, u8 data); protected: // device-level overrides diff --git a/src/devices/sound/ymf278b.cpp b/src/devices/sound/ymf278b.cpp index 18451d71732..c25b519ae4e 100644 --- a/src/devices/sound/ymf278b.cpp +++ b/src/devices/sound/ymf278b.cpp @@ -673,7 +673,7 @@ void ymf278b_device::timer_busy_start(int is_pcm) m_timer_busy->adjust(attotime::from_hz(m_clock / (is_pcm ? 88 : 56))); } -WRITE8_MEMBER( ymf278b_device::write ) +void ymf278b_device::write(offs_t offset, u8 data) { switch (offset) { @@ -717,7 +717,7 @@ WRITE8_MEMBER( ymf278b_device::write ) } -READ8_MEMBER( ymf278b_device::read ) +u8 ymf278b_device::read(offs_t offset) { uint8_t ret = 0; diff --git a/src/devices/sound/ymf278b.h b/src/devices/sound/ymf278b.h index 6db01f9b096..480397c1d0c 100644 --- a/src/devices/sound/ymf278b.h +++ b/src/devices/sound/ymf278b.h @@ -16,8 +16,8 @@ public: // configuration helpers auto irq_handler() { return m_irq_handler.bind(); } - DECLARE_READ8_MEMBER( read ); - DECLARE_WRITE8_MEMBER( write ); + u8 read(offs_t offset); + void write(offs_t offset, u8 data); protected: // device-level overrides diff --git a/src/devices/sound/ymz280b.cpp b/src/devices/sound/ymz280b.cpp index ce2754e97fa..1ab3cd9b6a9 100644 --- a/src/devices/sound/ymz280b.cpp +++ b/src/devices/sound/ymz280b.cpp @@ -890,7 +890,7 @@ int ymz280b_device::compute_status() ***********************************************************************************************/ -READ8_MEMBER( ymz280b_device::read ) +u8 ymz280b_device::read(offs_t offset) { if ((offset & 1) == 0) { @@ -908,7 +908,7 @@ READ8_MEMBER( ymz280b_device::read ) } -WRITE8_MEMBER( ymz280b_device::write ) +void ymz280b_device::write(offs_t offset, u8 data) { if ((offset & 1) == 0) m_current_register = data; diff --git a/src/devices/sound/ymz280b.h b/src/devices/sound/ymz280b.h index 62c80b23ec9..0a8ada2ae5b 100644 --- a/src/devices/sound/ymz280b.h +++ b/src/devices/sound/ymz280b.h @@ -23,8 +23,8 @@ public: // configuration helpers auto irq_handler() { return m_irq_handler.bind(); } - DECLARE_READ8_MEMBER( read ); - DECLARE_WRITE8_MEMBER( write ); + u8 read(offs_t offset); + void write(offs_t offset, u8 data); protected: // device-level overrides |