From 3d8a42a6d661fe66c2ad0b3a01b5dec8ca0400ef Mon Sep 17 00:00:00 2001 From: cam900 Date: Tue, 20 Feb 2018 01:04:29 +0900 Subject: [PATCH] ymz280b : Add device_rom_interface instead external memory handlers (#3242) * ymz280b : Add device_rom_interface instead external memory handlers firebeat.cpp : Minor cleanups, Split main CPU memory maps related for number of allocated gcu chips in PCB * ymz280b : Fix compile --- src/devices/sound/ymz280b.cpp | 62 ++++-------- src/devices/sound/ymz280b.h | 18 +--- src/mame/drivers/firebeat.cpp | 172 +++++----------------------------- src/mame/drivers/vgmplay.cpp | 7 +- 4 files changed, 52 insertions(+), 207 deletions(-) diff --git a/src/devices/sound/ymz280b.cpp b/src/devices/sound/ymz280b.cpp index c9523dcf2b2..83ae7a2fa18 100644 --- a/src/devices/sound/ymz280b.cpp +++ b/src/devices/sound/ymz280b.cpp @@ -56,25 +56,6 @@ static constexpr int index_scale[8] = { 0x0e6, 0x0e6, 0x0e6, 0x0e6, 0x133, 0x199 static int diff_lookup[16]; -uint8_t ymz280b_device::ymz280b_read_memory(uint32_t offset) -{ - if (m_ext_read_handler.isnull()) - { - if (offset < m_mem_size) - return m_mem_base[offset]; - - /* 16MB chip limit (shouldn't happen) */ - else if (offset > 0xffffff) - return m_mem_base[offset & 0xffffff]; - - else - return 0; - } - else - return m_ext_read_handler(offset); -} - - void ymz280b_device::update_irq_state() { int irq_bits = m_status_register & m_irq_mask; @@ -198,7 +179,7 @@ int ymz280b_device::generate_adpcm(struct YMZ280BVoice *voice, int16_t *buffer, while (samples) { /* compute the new amplitude and update the current step */ - val = ymz280b_read_memory(position / 2) >> ((~position & 1) << 2); + val = read_byte(position / 2) >> ((~position & 1) << 2); signal += (step * diff_lookup[val & 15]) / 8; /* clamp to the maximum */ @@ -235,7 +216,7 @@ int ymz280b_device::generate_adpcm(struct YMZ280BVoice *voice, int16_t *buffer, while (samples) { /* compute the new amplitude and update the current step */ - val = ymz280b_read_memory(position / 2) >> ((~position & 1) << 2); + val = read_byte(position / 2) >> ((~position & 1) << 2); signal += (step * diff_lookup[val & 15]) / 8; /* clamp to the maximum */ @@ -308,7 +289,7 @@ int ymz280b_device::generate_pcm8(struct YMZ280BVoice *voice, int16_t *buffer, i while (samples) { /* fetch the current value */ - val = ymz280b_read_memory(position / 2); + val = read_byte(position / 2); /* output to the buffer, scaling by the volume */ *buffer++ = (int8_t)val * 256; @@ -331,7 +312,7 @@ int ymz280b_device::generate_pcm8(struct YMZ280BVoice *voice, int16_t *buffer, i while (samples) { /* fetch the current value */ - val = ymz280b_read_memory(position / 2); + val = read_byte(position / 2); /* output to the buffer, scaling by the volume */ *buffer++ = (int8_t)val * 256; @@ -378,7 +359,7 @@ int ymz280b_device::generate_pcm16(struct YMZ280BVoice *voice, int16_t *buffer, while (samples) { /* fetch the current value */ - val = (int16_t)((ymz280b_read_memory(position / 2 + 1) << 8) + ymz280b_read_memory(position / 2 + 0)); + val = (int16_t)((read_byte(position / 2 + 1) << 8) + read_byte(position / 2 + 0)); /* output to the buffer, scaling by the volume */ *buffer++ = val; @@ -401,7 +382,7 @@ int ymz280b_device::generate_pcm16(struct YMZ280BVoice *voice, int16_t *buffer, while (samples) { /* fetch the current value */ - val = (int16_t)((ymz280b_read_memory(position / 2 + 1) << 8) + ymz280b_read_memory(position / 2 + 0)); + val = (int16_t)((read_byte(position / 2 + 1) << 8) + read_byte(position / 2 + 0)); /* output to the buffer, scaling by the volume */ *buffer++ = val; @@ -573,9 +554,6 @@ void ymz280b_device::sound_stream_update(sound_stream &stream, stream_sample_t * void ymz280b_device::device_start() { - m_ext_read_handler.resolve(); - m_ext_write_handler.resolve(); - /* compute ADPCM tables */ compute_tables(); @@ -583,14 +561,6 @@ void ymz280b_device::device_start() m_master_clock = (double)clock() / 384.0; m_irq_handler.resolve(); - memory_region *region = memregion(DEVICE_SELF); - if (region != nullptr) - { - /* Some systems (e.g. Konami Firebeat) have a YMZ280B on-board that isn't hooked up to ROM, so be safe. */ - m_mem_base = region->base(); - m_mem_size = region->bytes(); - } - for (int i = 0; i < 8; i++) { m_voice[i].timer = timer_alloc(i); @@ -694,6 +664,12 @@ void ymz280b_device::device_clock_changed() } +void ymz280b_device::rom_bank_updated() +{ + m_stream->update(); +} + + /********************************************************************************************** write_to_register -- handle a write to the current register @@ -831,16 +807,13 @@ void ymz280b_device::write_to_register(int data) case 0x86: /* ROM readback / RAM write (low) -> update latch */ m_ext_mem_address = m_ext_mem_address_hi | m_ext_mem_address_mid | data; if (m_ext_mem_enable) - m_ext_readlatch = ymz280b_read_memory(m_ext_mem_address); + m_ext_readlatch = read_byte(m_ext_mem_address); break; case 0x87: /* RAM write */ if (m_ext_mem_enable) { - if (!m_ext_write_handler.isnull()) - m_ext_write_handler(m_ext_mem_address, data); - else - logerror("YMZ280B attempted RAM write to %X\n", m_ext_mem_address); + space(0).write_byte(m_ext_mem_address, data); m_ext_mem_address = (m_ext_mem_address + 1) & 0xffffff; } break; @@ -911,7 +884,7 @@ int ymz280b_device::compute_status() /********************************************************************************************** - ymz280b_r/ymz280b_w -- handle external accesses + read/write -- handle external accesses ***********************************************************************************************/ @@ -924,7 +897,7 @@ READ8_MEMBER( ymz280b_device::read ) /* read from external memory */ uint8_t ret = m_ext_readlatch; - m_ext_readlatch = ymz280b_read_memory(m_ext_mem_address); + m_ext_readlatch = read_byte(m_ext_mem_address); m_ext_mem_address = (m_ext_mem_address + 1) & 0xffffff; return ret; } @@ -952,6 +925,7 @@ DEFINE_DEVICE_TYPE(YMZ280B, ymz280b_device, "ymz280b", "Yamaha YMZ280B PCMD8") ymz280b_device::ymz280b_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) : device_t(mconfig, YMZ280B, tag, owner, clock) , device_sound_interface(mconfig, *this) + , device_rom_interface(mconfig, *this, 24) , m_current_register(0) , m_status_register(0) , m_irq_state(0) @@ -964,8 +938,6 @@ ymz280b_device::ymz280b_device(const machine_config &mconfig, const char *tag, d , m_ext_mem_address_mid(0) , m_ext_mem_address(0) , m_irq_handler(*this) - , m_ext_read_handler(*this) - , m_ext_write_handler(*this) { memset(m_voice, 0, sizeof(m_voice)); } diff --git a/src/devices/sound/ymz280b.h b/src/devices/sound/ymz280b.h index 0cba025384f..2c2dc7b1f48 100644 --- a/src/devices/sound/ymz280b.h +++ b/src/devices/sound/ymz280b.h @@ -18,21 +18,13 @@ #define MCFG_YMZ280B_IRQ_HANDLER(_devcb) \ devcb = &ymz280b_device::set_irq_handler(*device, DEVCB_##_devcb); -#define MCFG_YMZ280B_EXT_READ_HANDLER(_devcb) \ - devcb = &ymz280b_device::set_ext_read_handler(*device, DEVCB_##_devcb); - -#define MCFG_YMZ280B_EXT_WRITE_HANDLER(_devcb) \ - devcb = &ymz280b_device::set_ext_write_handler(*device, DEVCB_##_devcb); - -class ymz280b_device : public device_t, public device_sound_interface +class ymz280b_device : public device_t, public device_sound_interface, public device_rom_interface { public: ymz280b_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); // static configuration helpers template static devcb_base &set_irq_handler(device_t &device, Object &&cb) { return downcast(device).m_irq_handler.set_callback(std::forward(cb)); } - template static devcb_base &set_ext_read_handler(device_t &device, Object &&cb) { return downcast(device).m_ext_read_handler.set_callback(std::forward(cb)); } - template static devcb_base &set_ext_write_handler(device_t &device, Object &&cb) { return downcast(device).m_ext_write_handler.set_callback(std::forward(cb)); } DECLARE_READ8_MEMBER( read ); DECLARE_WRITE8_MEMBER( write ); @@ -48,6 +40,9 @@ protected: // sound stream update overrides virtual void sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples) override; + // device_rom_interface overrides + virtual void rom_bank_updated() override; + private: /* struct describing a single playing ADPCM voice */ struct YMZ280BVoice @@ -86,7 +81,6 @@ private: emu_timer *timer; }; - uint8_t ymz280b_read_memory(uint32_t offset); void update_irq_state(); void update_step(struct YMZ280BVoice *voice); void update_volumes(struct YMZ280BVoice *voice); @@ -112,12 +106,8 @@ private: uint32_t m_ext_mem_address; /* where the CPU can read the ROM */ devcb_write_line m_irq_handler; /* IRQ callback */ - devcb_read8 m_ext_read_handler; /* external RAM read handler */ - devcb_write8 m_ext_write_handler;/* external RAM write handler */ double m_master_clock; /* master clock frequency */ - uint8_t *m_mem_base; /* pointer to the base of external memory */ - uint32_t m_mem_size; sound_stream *m_stream; /* which stream are we using */ std::unique_ptr m_scratch; #if YMZ280B_MAKE_WAVS diff --git a/src/mame/drivers/firebeat.cpp b/src/mame/drivers/firebeat.cpp index 47d80763f18..95a421d715a 100644 --- a/src/mame/drivers/firebeat.cpp +++ b/src/mame/drivers/firebeat.cpp @@ -181,32 +181,22 @@ public: m_maincpu(*this, "maincpu"), m_audiocpu(*this, "audiocpu"), m_work_ram(*this, "work_ram"), - m_flash_main(*this, "flash_main"), - m_flash_snd1(*this, "flash_snd1"), - m_flash_snd2(*this, "flash_snd2"), m_duart_midi(*this, "duart_midi"), m_duart_com(*this, "duart_com"), - m_kbd0(*this, "kbd0"), - m_kbd1(*this, "kbd1"), + m_kbd(*this, "kbd%u", 0), m_ata(*this, "ata"), - m_gcu0(*this, "gcu0"), - m_gcu1(*this, "gcu1"), + m_gcu(*this, "gcu%u", 0), m_spuata(*this, "spu_ata") { } required_device m_maincpu; optional_device m_audiocpu; required_shared_ptr m_work_ram; - required_device m_flash_main; - required_device m_flash_snd1; - required_device m_flash_snd2; optional_device m_duart_midi; required_device m_duart_com; - optional_device m_kbd0; - optional_device m_kbd1; + optional_device_array m_kbd; required_device m_ata; - required_device m_gcu0; - required_device m_gcu1; + optional_device_array m_gcu; optional_device m_spuata; uint8_t m_extend_board_irq_enable; @@ -223,7 +213,6 @@ public: int m_ibutton_read_subkey_ptr; uint8_t m_ibutton_subkey_data[0x40]; - DECLARE_READ8_MEMBER(soundram_r); DECLARE_DRIVER_INIT(ppd); DECLARE_DRIVER_INIT(kbm); DECLARE_DRIVER_INIT(ppp); @@ -235,10 +224,6 @@ public: INTERRUPT_GEN_MEMBER(firebeat_interrupt); DECLARE_READ32_MEMBER(input_r); DECLARE_READ32_MEMBER(sensor_r ); - DECLARE_READ32_MEMBER(flashram_r); - DECLARE_WRITE32_MEMBER(flashram_w); - DECLARE_READ32_MEMBER(soundflash_r); - DECLARE_WRITE32_MEMBER(soundflash_w); DECLARE_WRITE_LINE_MEMBER(ata_interrupt); DECLARE_READ32_MEMBER(ata_command_r); DECLARE_WRITE32_MEMBER(ata_command_w); @@ -286,7 +271,9 @@ public: void firebeat(machine_config &config); void firebeat_spu(machine_config &config); void firebeat_map(address_map &map); + void firebeat2_map(address_map &map); void spu_map(address_map &map); + void ymz280b_map(address_map &map); }; @@ -298,8 +285,8 @@ VIDEO_START_MEMBER(firebeat_state,firebeat) { } -uint32_t firebeat_state::screen_update_firebeat_0(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect){ return m_gcu0->draw(screen, bitmap, cliprect); } -uint32_t firebeat_state::screen_update_firebeat_1(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect){ return m_gcu1->draw(screen, bitmap, cliprect); } +uint32_t firebeat_state::screen_update_firebeat_0(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect){ return m_gcu[0]->draw(screen, bitmap, cliprect); } +uint32_t firebeat_state::screen_update_firebeat_1(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect){ return m_gcu[1]->draw(screen, bitmap, cliprect); } /*****************************************************************************/ @@ -335,114 +322,6 @@ READ32_MEMBER(firebeat_state::sensor_r ) } } -READ32_MEMBER(firebeat_state::flashram_r) -{ - uint32_t r = 0; - if (ACCESSING_BITS_24_31) - { - r |= (m_flash_main->read((offset*4)+0) & 0xff) << 24; - } - if (ACCESSING_BITS_16_23) - { - r |= (m_flash_main->read((offset*4)+1) & 0xff) << 16; - } - if (ACCESSING_BITS_8_15) - { - r |= (m_flash_main->read((offset*4)+2) & 0xff) << 8; - } - if (ACCESSING_BITS_0_7) - { - r |= (m_flash_main->read((offset*4)+3) & 0xff) << 0; - } - return r; -} - -WRITE32_MEMBER(firebeat_state::flashram_w) -{ - if (ACCESSING_BITS_24_31) - { - m_flash_main->write((offset*4)+0, (data >> 24) & 0xff); - } - if (ACCESSING_BITS_16_23) - { - m_flash_main->write((offset*4)+1, (data >> 16) & 0xff); - } - if (ACCESSING_BITS_8_15) - { - m_flash_main->write((offset*4)+2, (data >> 8) & 0xff); - } - if (ACCESSING_BITS_0_7) - { - m_flash_main->write((offset*4)+3, (data >> 0) & 0xff); - } -} - -READ32_MEMBER(firebeat_state::soundflash_r) -{ - uint32_t r = 0; - fujitsu_29f016a_device *chip; - if (offset < 0x200000/4) - { - chip = m_flash_snd1; - } - else - { - chip = m_flash_snd2; - } - - offset &= 0x7ffff; - - if (ACCESSING_BITS_24_31) - { - r |= (chip->read((offset*4)+0) & 0xff) << 24; - } - if (ACCESSING_BITS_16_23) - { - r |= (chip->read((offset*4)+1) & 0xff) << 16; - } - if (ACCESSING_BITS_8_15) - { - r |= (chip->read((offset*4)+2) & 0xff) << 8; - } - if (ACCESSING_BITS_0_7) - { - r |= (chip->read((offset*4)+3) & 0xff) << 0; - } - return r; -} - -WRITE32_MEMBER(firebeat_state::soundflash_w) -{ - fujitsu_29f016a_device *chip; - if (offset < 0x200000/4) - { - chip = m_flash_snd1; - } - else - { - chip = m_flash_snd2; - } - - offset &= 0x7ffff; - - if (ACCESSING_BITS_24_31) - { - chip->write((offset*4)+0, (data >> 24) & 0xff); - } - if (ACCESSING_BITS_16_23) - { - chip->write((offset*4)+1, (data >> 16) & 0xff); - } - if (ACCESSING_BITS_8_15) - { - chip->write((offset*4)+2, (data >> 8) & 0xff); - } - if (ACCESSING_BITS_0_7) - { - chip->write((offset*4)+3, (data >> 0) & 0xff); - } -} - /*****************************************************************************/ /* ATA Interface */ @@ -1065,18 +944,23 @@ ADDRESS_MAP_START(firebeat_state::firebeat_map) AM_RANGE(0x7d000340, 0x7d000347) AM_READ(sensor_r) AM_RANGE(0x7d000400, 0x7d000403) AM_DEVREADWRITE8("ymz", ymz280b_device, read, write, 0xffff0000) AM_RANGE(0x7d000800, 0x7d000803) AM_READ(input_r) - AM_RANGE(0x7d400000, 0x7d5fffff) AM_READWRITE(flashram_r, flashram_w) - AM_RANGE(0x7d800000, 0x7dbfffff) AM_READWRITE(soundflash_r, soundflash_w) + AM_RANGE(0x7d400000, 0x7d5fffff) AM_DEVREADWRITE8("flash_main", fujitsu_29f016a_device, read, write, 0xffffffff) + AM_RANGE(0x7d800000, 0x7d9fffff) AM_DEVREADWRITE8("flash_snd1", fujitsu_29f016a_device, read, write, 0xffffffff) + AM_RANGE(0x7da00000, 0x7dbfffff) AM_DEVREADWRITE8("flash_snd2", fujitsu_29f016a_device, read, write, 0xffffffff) AM_RANGE(0x7dc00000, 0x7dc0000f) AM_DEVREADWRITE8("duart_com", pc16552_device, read, write, 0xffffffff) AM_RANGE(0x7e000000, 0x7e00003f) AM_DEVREADWRITE8("rtc", rtc65271_device, rtc_r, rtc_w, 0xffffffff) AM_RANGE(0x7e000100, 0x7e00013f) AM_DEVREADWRITE8("rtc", rtc65271_device, xram_r, xram_w, 0xffffffff) AM_RANGE(0x7e800000, 0x7e8000ff) AM_DEVREADWRITE("gcu0", k057714_device, read, write) - AM_RANGE(0x7e800100, 0x7e8001ff) AM_DEVREADWRITE("gcu1", k057714_device, read, write) AM_RANGE(0x7fe00000, 0x7fe0000f) AM_READWRITE(ata_command_r, ata_command_w) AM_RANGE(0x7fe80000, 0x7fe8000f) AM_READWRITE(ata_control_r, ata_control_w) AM_RANGE(0x7ff80000, 0x7fffffff) AM_ROM AM_REGION("user1", 0) /* System BIOS */ ADDRESS_MAP_END +ADDRESS_MAP_START(firebeat_state::firebeat2_map) + AM_IMPORT_FROM(firebeat_map) + AM_RANGE(0x7e800100, 0x7e8001ff) AM_DEVREADWRITE("gcu1", k057714_device, read, write) +ADDRESS_MAP_END + ADDRESS_MAP_START(firebeat_state::spu_map) AM_RANGE(0x000000, 0x07ffff) AM_ROM AM_RANGE(0x100000, 0x13ffff) AM_RAM @@ -1092,16 +976,13 @@ ADDRESS_MAP_START(firebeat_state::spu_map) AM_RANGE(0xfc0000, 0xffffff) AM_RAM // SDRAM ADDRESS_MAP_END -/*****************************************************************************/ +ADDRESS_MAP_START(firebeat_state::ymz280b_map) + ADDRESS_MAP_GLOBAL_MASK(0x3fffff) + AM_RANGE(0x000000, 0x1fffff) AM_DEVREAD("flash_snd1", fujitsu_29f016a_device, read) + AM_RANGE(0x200000, 0x3fffff) AM_DEVREAD("flash_snd2", fujitsu_29f016a_device, read) +ADDRESS_MAP_END -READ8_MEMBER(firebeat_state::soundram_r) -{ - offset &= 0x3fffff; - if (offset < 0x200000) - return m_flash_snd1->read(offset); - else - return m_flash_snd2->read(offset & 0x1fffff); -} +/*****************************************************************************/ WRITE_LINE_MEMBER(firebeat_state::sound_irq_callback) { @@ -1314,9 +1195,6 @@ MACHINE_CONFIG_START(firebeat_state::firebeat) MCFG_DEVICE_ADD("gcu0", K057714, 0) MCFG_K057714_IRQ_CALLBACK(WRITELINE(firebeat_state, gcu0_interrupt)) - MCFG_DEVICE_ADD("gcu1", K057714, 0) - MCFG_K057714_IRQ_CALLBACK(WRITELINE(firebeat_state, gcu1_interrupt)) - MCFG_SCREEN_ADD("screen", RASTER) MCFG_SCREEN_REFRESH_RATE(60) MCFG_SCREEN_VBLANK_TIME(ATTOSECONDS_IN_USEC(2500) /* not accurate */) @@ -1332,7 +1210,7 @@ MACHINE_CONFIG_START(firebeat_state::firebeat) MCFG_SOUND_ADD("ymz", YMZ280B, 16934400) MCFG_YMZ280B_IRQ_HANDLER(WRITELINE(firebeat_state, sound_irq_callback)) - MCFG_YMZ280B_EXT_READ_HANDLER(READ8(firebeat_state, soundram_r)) + MCFG_DEVICE_ADDRESS_MAP(0, ymz280b_map) MCFG_SOUND_ROUTE(0, "lspeaker", 1.0) MCFG_SOUND_ROUTE(1, "rspeaker", 1.0) @@ -1350,7 +1228,7 @@ MACHINE_CONFIG_START(firebeat_state::firebeat2) /* basic machine hardware */ MCFG_CPU_ADD("maincpu", PPC403GCX, XTAL(64'000'000)) - MCFG_CPU_PROGRAM_MAP(firebeat_map) + MCFG_CPU_PROGRAM_MAP(firebeat2_map) MCFG_CPU_VBLANK_INT_DRIVER("lscreen", firebeat_state, firebeat_interrupt) MCFG_MACHINE_START_OVERRIDE(firebeat_state,firebeat) @@ -1400,7 +1278,7 @@ MACHINE_CONFIG_START(firebeat_state::firebeat2) MCFG_SOUND_ADD("ymz", YMZ280B, 16934400) MCFG_YMZ280B_IRQ_HANDLER(WRITELINE(firebeat_state, sound_irq_callback)) - MCFG_YMZ280B_EXT_READ_HANDLER(READ8(firebeat_state, soundram_r)) + MCFG_DEVICE_ADDRESS_MAP(0, ymz280b_map) MCFG_SOUND_ROUTE(0, "lspeaker", 1.0) MCFG_SOUND_ROUTE(1, "rspeaker", 1.0) diff --git a/src/mame/drivers/vgmplay.cpp b/src/mame/drivers/vgmplay.cpp index a662cc6a1a3..2d3991b0563 100644 --- a/src/mame/drivers/vgmplay.cpp +++ b/src/mame/drivers/vgmplay.cpp @@ -201,6 +201,7 @@ public: void segapcm_map(address_map &map); void soundchips16_map(address_map &map); void soundchips_map(address_map &map); + void ymz280b_map(address_map &map); private: std::vector m_file_data; required_device m_file; @@ -1569,6 +1570,10 @@ ADDRESS_MAP_START(vgmplay_state::qsound_map) AM_RANGE(0, 0xffffff) AM_DEVREAD("vgmplay", vgmplay_device, qsound_rom_r) ADDRESS_MAP_END +ADDRESS_MAP_START(vgmplay_state::ymz280b_map) + AM_RANGE(0, 0xffffff) AM_DEVREAD("vgmplay", vgmplay_device, ymz280b_rom_r) +ADDRESS_MAP_END + ADDRESS_MAP_START(vgmplay_state::nescpu_map) AM_RANGE(0, 0xffff) AM_RAM AM_SHARE("nesapu_ram") ADDRESS_MAP_END @@ -1705,7 +1710,7 @@ MACHINE_CONFIG_START(vgmplay_state::vgmplay) MCFG_SOUND_ROUTE(1, "rspeaker", 1) MCFG_SOUND_ADD("ymz280b", YMZ280B, 16934400) - MCFG_YMZ280B_EXT_READ_HANDLER(DEVREAD8("vgmplay", vgmplay_device, ymz280b_rom_r)) + MCFG_DEVICE_ADDRESS_MAP(0, ymz280b_map) MCFG_SOUND_ROUTE(0, "lspeaker", 1) MCFG_SOUND_ROUTE(1, "rspeaker", 1)