diff options
author | smf- <smf-@users.noreply.github.com> | 2018-09-19 10:46:56 +0100 |
---|---|---|
committer | smf- <smf-@users.noreply.github.com> | 2018-09-19 10:52:54 +0100 |
commit | 56fb60aa22dce853baa661fbce2a4187e9da0459 (patch) | |
tree | 9724c58217b5f7092035e79b75977b6df961d502 | |
parent | 01435b68b43d232b2e0180f48d320abcee358413 (diff) |
vgmplay: Support ym2608, ym2610, ym2612 & y8950 samples [smf]
-rw-r--r-- | src/devices/sound/2608intf.cpp | 24 | ||||
-rw-r--r-- | src/devices/sound/2608intf.h | 11 | ||||
-rw-r--r-- | src/devices/sound/2610intf.cpp | 47 | ||||
-rw-r--r-- | src/devices/sound/2610intf.h | 16 | ||||
-rw-r--r-- | src/devices/sound/8950intf.cpp | 13 | ||||
-rw-r--r-- | src/devices/sound/8950intf.h | 10 | ||||
-rw-r--r-- | src/devices/sound/fm.cpp | 70 | ||||
-rw-r--r-- | src/devices/sound/fm.h | 11 | ||||
-rw-r--r-- | src/devices/sound/fmopl.cpp | 8 | ||||
-rw-r--r-- | src/devices/sound/fmopl.h | 4 | ||||
-rw-r--r-- | src/devices/sound/ymdeltat.cpp | 32 | ||||
-rw-r--r-- | src/devices/sound/ymdeltat.h | 5 | ||||
-rw-r--r-- | src/mame/drivers/neogeo.cpp | 89 | ||||
-rw-r--r-- | src/mame/drivers/vgmplay.cpp | 183 |
14 files changed, 299 insertions, 224 deletions
diff --git a/src/devices/sound/2608intf.cpp b/src/devices/sound/2608intf.cpp index 4dc5bedf02f..1445de91f37 100644 --- a/src/devices/sound/2608intf.cpp +++ b/src/devices/sound/2608intf.cpp @@ -85,8 +85,6 @@ void ym2608_device::device_start() ay8910_device::device_start(); int rate = clock()/72; - void *pcmbufa; - int pcmsizea; m_irq_handler.resolve(); @@ -96,14 +94,12 @@ void ym2608_device::device_start() /* stream system initialize */ m_stream = machine().sound().stream_alloc(*this,0,2,rate, stream_update_delegate(&ym2608_device::stream_generate,this)); - /* setup adpcm buffers */ - pcmbufa = m_region->base(); - pcmsizea = m_region->bytes(); /* initialize YM2608 */ m_chip = ym2608_init(this,clock(),rate, - pcmbufa,pcmsizea, - &ym2608_device::static_timer_handler,&ym2608_device::static_irq_handler,&psgintf); + &ym2608_device::static_internal_read_byte, + &ym2608_device::static_external_read_byte, &ym2608_device::static_external_write_byte, + &ym2608_device::static_timer_handler,&ym2608_device::static_irq_handler,&psgintf); assert_always(m_chip != nullptr, "Error creating YM2608 chip"); } @@ -135,6 +131,15 @@ void ym2608_device::device_reset() ym2608_reset_chip(m_chip); } +//------------------------------------------------- +// rom_bank_updated +//------------------------------------------------- + +void ym2608_device::rom_bank_updated() +{ + m_stream->update(); +} + READ8_MEMBER( ym2608_device::read ) { @@ -150,16 +155,17 @@ DEFINE_DEVICE_TYPE(YM2608, ym2608_device, "ym2608", "YM2608 OPNA") ym2608_device::ym2608_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) : ay8910_device(mconfig, YM2608, tag, owner, clock, PSG_TYPE_YM, 1, 2) + , device_rom_interface(mconfig, *this, 21) , m_stream(nullptr) , m_timer{ nullptr, nullptr } , m_chip(nullptr) , m_irq_handler(*this) - , m_region(*this, DEVICE_SELF) + , m_internal(*this, "internal") { } ROM_START( ym2608 ) - ROM_REGION( 0x2000, "ym2608", 0 ) + ROM_REGION( 0x2000, "internal", 0 ) /* This data is derived from the chip's output - internal ROM can't be read. It was verified, using real YM2608, that this ADPCM stream produces 100% correct output signal. diff --git a/src/devices/sound/2608intf.h b/src/devices/sound/2608intf.h index d3ba76506ee..de64a23245b 100644 --- a/src/devices/sound/2608intf.h +++ b/src/devices/sound/2608intf.h @@ -14,7 +14,8 @@ struct ssg_callbacks; #define MCFG_YM2608_IRQ_HANDLER(cb) \ downcast<ym2608_device &>(*device).set_irq_handler(DEVCB_##cb); -class ym2608_device : public ay8910_device +class ym2608_device : public ay8910_device, + public device_rom_interface { public: ym2608_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); @@ -38,6 +39,8 @@ protected: virtual void device_stop() override; virtual void device_reset() override; + virtual void rom_bank_updated() override; + virtual void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr) override; void stream_generate(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples); @@ -46,6 +49,10 @@ private: void timer_handler(int c, int count, int clock); void update_request() { m_stream->update(); } + static uint8_t static_external_read_byte(device_t *param, offs_t offset) { return downcast<ym2608_device *>(param)->read_byte(offset); } + static void static_external_write_byte(device_t *param, offs_t offset, uint8_t data) { return downcast<ym2608_device *>(param)->space().write_byte(offset, data); } + static uint8_t static_internal_read_byte(device_t *param, offs_t offset) { return downcast<ym2608_device *>(param)->m_internal->as_u8(offset % downcast<ym2608_device *>(param)->m_internal->bytes()); }; + static void static_irq_handler(device_t *param, int irq) { downcast<ym2608_device *>(param)->irq_handler(irq); } static void static_timer_handler(device_t *param, int c, int count, int clock) { downcast<ym2608_device *>(param)->timer_handler(c, count, clock); } @@ -54,7 +61,7 @@ private: emu_timer * m_timer[2]; void * m_chip; devcb_write_line m_irq_handler; - required_memory_region m_region; + required_memory_region m_internal; static const ssg_callbacks psgintf; }; diff --git a/src/devices/sound/2610intf.cpp b/src/devices/sound/2610intf.cpp index 6b2e2886d8c..d6b269cf872 100644 --- a/src/devices/sound/2610intf.cpp +++ b/src/devices/sound/2610intf.cpp @@ -17,9 +17,6 @@ #include "2610intf.h" #include "fm.h" -char const *const ym2610_device::YM2610_TAG = "ymsnd"; -char const *const ym2610_device::YM2610_DELTAT_TAG = "ymsnd.deltat"; - const ssg_callbacks ym2610_device::psgintf = { &ym2610_device::psg_set_clock, @@ -107,24 +104,21 @@ void ym2610_device::device_start() /* stream system initialize */ m_stream = machine().sound().stream_alloc(*this,0,2,rate, stream_update_delegate(&ym2610_device::stream_generate,this)); - /* setup adpcm buffers */ - void *pcmbufa = m_region->base(); - int pcmsizea = m_region->bytes(); - - std::string name = tag() + std::string(".deltat"); - memory_region *deltat_region = machine().root_device().memregion(name.c_str()); - void *pcmbufb = pcmbufa; - int pcmsizeb = pcmsizea; - if (deltat_region != nullptr && deltat_region->base() != nullptr && deltat_region->bytes() != 0) + if (!has_configured_map(0) && !has_configured_map(1)) { - pcmbufb = deltat_region->base(); - pcmsizeb = deltat_region->bytes(); + if (m_adpcm_a_region) + space(0).install_rom(0, m_adpcm_a_region->bytes() - 1, m_adpcm_a_region->base()); + + if (m_adpcm_b_region) + space(1).install_rom(1, m_adpcm_b_region->bytes() - 1, m_adpcm_b_region->base()); + else if (m_adpcm_a_region) + space(1).install_rom(1, m_adpcm_a_region->bytes() - 1, m_adpcm_a_region->base()); } /**** initialize YM2610 ****/ - m_chip = ym2610_init(this,clock(),rate, - pcmbufa,pcmsizea,pcmbufb,pcmsizeb, - &ym2610_device::static_timer_handler,&ym2610_device::static_irq_handler,&psgintf); + m_chip = ym2610_init(this, clock(), rate, + &ym2610_device::static_adpcm_a_read_byte, &ym2610_device::static_adpcm_b_read_byte, + &ym2610_device::static_timer_handler, &ym2610_device::static_irq_handler, &psgintf); assert_always(m_chip != nullptr, "Error creating YM2610 chip"); } @@ -156,6 +150,19 @@ void ym2610_device::device_reset() ym2610_reset_chip(m_chip); } +//------------------------------------------------- +// memory_space_config - return a description of +// any address spaces owned by this device +//------------------------------------------------- + +device_memory_interface::space_config_vector ym2610_device::memory_space_config() const +{ + return space_config_vector{ + std::make_pair(0, &m_adpcm_a_config), + std::make_pair(1, &m_adpcm_b_config) + }; +} + READ8_MEMBER( ym2610_device::read ) { @@ -177,10 +184,14 @@ ym2610_device::ym2610_device(const machine_config &mconfig, const char *tag, dev ym2610_device::ym2610_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock) : ay8910_device(mconfig, type, tag, owner, clock, PSG_TYPE_YM, 1, 0) + , device_memory_interface(mconfig, *this) + , m_adpcm_a_config("adpcm-a", ENDIANNESS_LITTLE, 8, 24, 0) + , m_adpcm_b_config("adpcm-b", ENDIANNESS_LITTLE, 8, 24, 0) , m_stream(nullptr) , m_timer{ nullptr, nullptr } , m_irq_handler(*this) - , m_region(*this, DEVICE_SELF) + , m_adpcm_a_region(*this, DEVICE_SELF) + , m_adpcm_b_region(*this, "deltat") { } diff --git a/src/devices/sound/2610intf.h b/src/devices/sound/2610intf.h index 583091a666b..b82cbf73b22 100644 --- a/src/devices/sound/2610intf.h +++ b/src/devices/sound/2610intf.h @@ -14,7 +14,8 @@ struct ssg_callbacks; #define MCFG_YM2610_IRQ_HANDLER(cb) \ downcast<ym2610_device &>(*device).set_irq_handler((DEVCB_##cb)); -class ym2610_device : public ay8910_device +class ym2610_device : public ay8910_device, + public device_memory_interface { public: ym2610_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); @@ -23,15 +24,14 @@ 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(); } + virtual space_config_vector memory_space_config() const override; + DECLARE_READ8_MEMBER( read ); DECLARE_WRITE8_MEMBER( write ); // update request from fm.cpp static void update_request(device_t *param) { downcast<ym2610_device *>(param)->update_request(); } - static char const *const YM2610_TAG; - static char const *const YM2610_DELTAT_TAG; - protected: ym2610_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock); @@ -53,14 +53,20 @@ private: void timer_handler(int c, int count, int clock); void update_request() { m_stream->update(); } + static uint8_t static_adpcm_a_read_byte(device_t *param, offs_t offset) { return downcast<ym2610_device *>(param)->space(0).read_byte(offset); } + static uint8_t static_adpcm_b_read_byte(device_t *param, offs_t offset) { return downcast<ym2610_device *>(param)->space(1).read_byte(offset); } + static void static_irq_handler(device_t *param, int irq) { downcast<ym2610_device *>(param)->irq_handler(irq); } static void static_timer_handler(device_t *param, int c, int count, int clock) { downcast<ym2610_device *>(param)->timer_handler(c, count, clock); } // internal state + const address_space_config m_adpcm_a_config; + const address_space_config m_adpcm_b_config; sound_stream * m_stream; emu_timer * m_timer[2]; devcb_write_line m_irq_handler; - required_memory_region m_region; + optional_memory_region m_adpcm_a_region; + optional_memory_region m_adpcm_b_region; static const ssg_callbacks psgintf; }; diff --git a/src/devices/sound/8950intf.cpp b/src/devices/sound/8950intf.cpp index da0049f0a91..f56f34c88f9 100644 --- a/src/devices/sound/8950intf.cpp +++ b/src/devices/sound/8950intf.cpp @@ -84,7 +84,7 @@ void y8950_device::device_start() assert_always(m_chip != nullptr, "Error creating Y8950 chip"); /* ADPCM ROM data */ - y8950_set_delta_t_memory(m_chip, m_region->base(), m_region->bytes()); + y8950_set_delta_t_memory(m_chip, &y8950_device::static_read_byte, &y8950_device::static_write_byte); m_stream = machine().sound().stream_alloc(*this,0,1,rate); /* port and keyboard handler */ @@ -128,6 +128,15 @@ void y8950_device::device_reset() y8950_reset_chip(m_chip); } +//------------------------------------------------- +// rom_bank_updated +//------------------------------------------------- + +void y8950_device::rom_bank_updated() +{ + m_stream->update(); +} + READ8_MEMBER( y8950_device::read ) { @@ -150,6 +159,7 @@ DEFINE_DEVICE_TYPE(Y8950, y8950_device, "y8950", "Y8950 MSX-Audio") y8950_device::y8950_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) : device_t(mconfig, Y8950, tag, owner, clock) , device_sound_interface(mconfig, *this) + , device_rom_interface(mconfig, *this, 21) , m_stream(nullptr) , m_timer{ nullptr, nullptr } , m_chip(nullptr) @@ -158,6 +168,5 @@ y8950_device::y8950_device(const machine_config &mconfig, const char *tag, devic , m_keyboard_write_handler(*this) , m_io_read_handler(*this) , m_io_write_handler(*this) - , m_region(*this, DEVICE_SELF) { } diff --git a/src/devices/sound/8950intf.h b/src/devices/sound/8950intf.h index c1f3163a9ee..258e27ccdb2 100644 --- a/src/devices/sound/8950intf.h +++ b/src/devices/sound/8950intf.h @@ -21,7 +21,9 @@ #define MCFG_Y8950_IO_WRITE_HANDLER(cb) \ downcast<y8950_device &>(*device).set_io_write_handler((DEVCB_##cb)); -class y8950_device : public device_t, public device_sound_interface +class y8950_device : public device_t, + public device_sound_interface, + public device_rom_interface { public: y8950_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); @@ -48,6 +50,8 @@ protected: virtual void device_stop() override; virtual void device_reset() override; + virtual void rom_bank_updated() override; + virtual void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr) override; // sound stream update overrides @@ -63,6 +67,9 @@ private: unsigned char keyboard_handler_r() { return m_keyboard_read_handler(0); } void keyboard_handler_w(unsigned char data) { m_keyboard_write_handler(offs_t(0), data); } + static uint8_t static_read_byte(device_t *param, offs_t offset) { return downcast<y8950_device *>(param)->read_byte(offset); } + static void static_write_byte(device_t *param, offs_t offset, uint8_t data) { return downcast<y8950_device *>(param)->space().write_byte(offset, data); } + static void static_irq_handler(device_t *param, int irq) { downcast<y8950_device *>(param)->irq_handler(irq); } static void static_timer_handler(device_t *param, int c, const attotime &period) { downcast<y8950_device *>(param)->timer_handler(c, period); } static void static_update_request(device_t *param, int interval) { downcast<y8950_device *>(param)->update_request(); } @@ -81,7 +88,6 @@ private: devcb_write8 m_keyboard_write_handler; devcb_read8 m_io_read_handler; devcb_write8 m_io_write_handler; - required_memory_region m_region; }; DECLARE_DEVICE_TYPE(Y8950, y8950_device) diff --git a/src/devices/sound/fm.cpp b/src/devices/sound/fm.cpp index e93d009f65f..8f679e99357 100644 --- a/src/devices/sound/fm.cpp +++ b/src/devices/sound/fm.cpp @@ -2441,8 +2441,7 @@ struct ym2610_state uint8_t addr_A1; /* address line A1 */ /* ADPCM-A unit */ - const uint8_t *pcmbuf; /* pcm rom buffer */ - uint32_t pcm_size; /* size of pcm rom */ + FM_READBYTE read_byte; uint8_t adpcmTL; /* adpcmA total level */ ADPCM_CH adpcm[6]; /* adpcm channels */ uint32_t adpcmreg[0x30]; /* registers */ @@ -2492,7 +2491,7 @@ struct ym2610_state data = ch->now_data & 0x0f; else { - ch->now_data = *(pcmbuf+(ch->now_addr>>1)); + ch->now_data = read_byte(device, ch->now_addr>>1); data = (ch->now_data >> 4) & 0x0f; } @@ -2543,25 +2542,6 @@ struct ym2610_state adpcm[c].adpcm_step= 0; adpcm[c].adpcm_out = 0; adpcm[c].flag = 1; - - if(pcmbuf==nullptr) - { /* Check ROM Mapped */ - device->logerror("YM2608-YM2610: ADPCM-A rom not mapped\n"); - adpcm[c].flag = 0; - } - else - { - if(adpcm[c].end >= pcm_size) - { /* Check End in Range */ - device->logerror("YM2610: ADPCM-A end out of range: $%08x\n",adpcm[c].end); - /*adpcm[c].end = pcm_size-1;*/ /* JB: DO NOT uncomment this, otherwise you will break the comparison in the ADPCM_CALC_CHA() */ - } - if(adpcm[c].start >= pcm_size) /* Check Start in Range */ - { - device->logerror("YM2608-YM2610: ADPCM-A start out of range: $%08x\n",adpcm[c].start); - adpcm[c].flag = 0; - } - } } } } @@ -2959,8 +2939,10 @@ static void YM2608_deltat_status_reset(void *chip, uint8_t changebits) FM_STATUS_RESET(&(F2608->OPN.ST), changebits); } /* YM2608(OPNA) */ -void * ym2608_init(device_t *device, int clock, int rate, void *pcmrom,int pcmsize, - FM_TIMERHANDLER timer_handler,FM_IRQHANDLER IRQHandler, const ssg_callbacks *ssg) +void * ym2608_init(device_t *device, int clock, int rate, + FM_READBYTE InternalReadByte, + FM_READBYTE ExternalReadByte, FM_WRITEBYTE ExternalWriteByte, + FM_TIMERHANDLER timer_handler,FM_IRQHANDLER IRQHandler, const ssg_callbacks *ssg) { ym2608_state *F2608; @@ -2986,8 +2968,8 @@ void * ym2608_init(device_t *device, int clock, int rate, void *pcmrom,int pcmsi F2608->OPN.ST.SSG = ssg; /* DELTA-T */ - F2608->deltaT.memory = (uint8_t *)pcmrom; - F2608->deltaT.memory_size = pcmsize; + F2608->deltaT.read_byte = ExternalReadByte; + F2608->deltaT.write_byte = ExternalWriteByte; /*F2608->deltaT.write_time = 20.0 / clock;*/ /* a single byte write takes 20 cycles of main clock */ /*F2608->deltaT.read_time = 18.0 / clock;*/ /* a single byte read takes 18 cycles of main clock */ @@ -3000,8 +2982,7 @@ void * ym2608_init(device_t *device, int clock, int rate, void *pcmrom,int pcmsi F2608->deltaT.status_change_ZERO_bit = 0x10; /* status flag: set bit4 if silence continues for more than 290 milliseconds while recording the ADPCM */ /* ADPCM Rhythm */ - F2608->pcmbuf = device->memregion("ym2608")->base(); - F2608->pcm_size = 0x2000; + F2608->read_byte = InternalReadByte; Init_ADPCMATable(); @@ -3646,9 +3627,9 @@ static void YM2610_deltat_status_reset(void *chip, uint8_t changebits) F2610->adpcm_arrivedEndAddress &= (~changebits); } -void *ym2610_init(device_t *device, int clock, int rate, void *pcmroma,int pcmsizea,void *pcmromb,int pcmsizeb, - FM_TIMERHANDLER timer_handler,FM_IRQHANDLER IRQHandler, const ssg_callbacks *ssg) - +void *ym2610_init(device_t *device, int clock, int rate, + FM_READBYTE adpcm_a_read_byte, FM_READBYTE adpcm_b_read_byte, + FM_TIMERHANDLER timer_handler,FM_IRQHANDLER IRQHandler, const ssg_callbacks *ssg) { ym2610_state *F2610; @@ -3673,11 +3654,10 @@ void *ym2610_init(device_t *device, int clock, int rate, void *pcmroma,int pcmsi F2610->OPN.ST.IRQ_Handler = IRQHandler; F2610->OPN.ST.SSG = ssg; /* ADPCM */ - F2610->pcmbuf = (const uint8_t *)pcmroma; - F2610->pcm_size = pcmsizea; + F2610->read_byte = adpcm_a_read_byte; /* DELTA-T */ - F2610->deltaT.memory = (uint8_t *)pcmromb; - F2610->deltaT.memory_size = pcmsizeb; + F2610->deltaT.read_byte = adpcm_b_read_byte; + F2610->deltaT.write_byte = nullptr; F2610->deltaT.status_set_handler = YM2610_deltat_status_set; F2610->deltaT.status_reset_handler = YM2610_deltat_status_reset; @@ -3719,26 +3699,6 @@ void ym2610_reset_chip(void *chip) device_t* dev = F2610->OPN.ST.device; std::string name(dev->tag()); - /* setup PCM buffers again */ - F2610->pcmbuf = (const uint8_t *)dev->machine().root_device().memregion(name.c_str())->base(); - F2610->pcm_size = dev->machine().root_device().memregion(name.c_str())->bytes(); - name.append(".deltat"); - memory_region *deltat_region = dev->machine().root_device().memregion(name.c_str()); - F2610->deltaT.memory = nullptr; - if (deltat_region != nullptr) - { - F2610->deltaT.memory = (uint8_t *)dev->machine().root_device().memregion(name.c_str())->base(); - } - if(F2610->deltaT.memory == nullptr) - { - F2610->deltaT.memory = (uint8_t*)F2610->pcmbuf; - F2610->deltaT.memory_size = F2610->pcm_size; - } - else - { - F2610->deltaT.memory_size = dev->machine().root_device().memregion(name.c_str())->bytes(); - } - /* Reset Prescaler */ OPNSetPres( OPN, 6*24, 6*24, 4*2); /* OPN 1/6 , SSG 1/4 */ /* reset SSG section */ diff --git a/src/devices/sound/fm.h b/src/devices/sound/fm.h index 7b919ea7402..50b6b0d3d99 100644 --- a/src/devices/sound/fm.h +++ b/src/devices/sound/fm.h @@ -60,6 +60,8 @@ typedef unsigned char FMSAMPLE; #endif */ +typedef uint8_t (*FM_READBYTE)(device_t *device, offs_t offset); +typedef void(*FM_WRITEBYTE)(device_t *device, offs_t offset, uint8_t data); typedef void (*FM_TIMERHANDLER)(device_t *device,int c,int cnt,int clock); typedef void (*FM_IRQHANDLER)(device_t *device,int irq); /* FM_TIMERHANDLER : Stop or Start timer */ @@ -134,8 +136,9 @@ void ym2203_postload(void *chip); #if BUILD_YM2608 /* -------------------- YM2608(OPNA) Interface -------------------- */ void * ym2608_init(device_t *device, int baseclock, int rate, - void *pcmroma,int pcmsizea, - FM_TIMERHANDLER TimerHandler,FM_IRQHANDLER IRQHandler, const ssg_callbacks *ssg); + FM_READBYTE InternalReadByte, + FM_READBYTE ExternalReadByte, FM_WRITEBYTE ExternalWriteByte, + FM_TIMERHANDLER TimerHandler, FM_IRQHANDLER IRQHandler, const ssg_callbacks *ssg); void ym2608_clock_changed(void *chip, int clock, int rate); void ym2608_shutdown(void *chip); void ym2608_reset_chip(void *chip); @@ -150,8 +153,8 @@ void ym2608_postload(void *chip); #if (BUILD_YM2610||BUILD_YM2610B) /* -------------------- YM2610(OPNB) Interface -------------------- */ void * ym2610_init(device_t *device, int baseclock, int rate, - void *pcmroma,int pcmasize,void *pcmromb,int pcmbsize, - FM_TIMERHANDLER TimerHandler,FM_IRQHANDLER IRQHandler, const ssg_callbacks *ssg); + FM_READBYTE adpcm_a_read_byte, FM_READBYTE adpcm_b_read_byte, + FM_TIMERHANDLER TimerHandler,FM_IRQHANDLER IRQHandler, const ssg_callbacks *ssg); void ym2610_clock_changed(void *chip, int clock, int rate); void ym2610_shutdown(void *chip); void ym2610_reset_chip(void *chip); diff --git a/src/devices/sound/fmopl.cpp b/src/devices/sound/fmopl.cpp index c7390842710..99139310d69 100644 --- a/src/devices/sound/fmopl.cpp +++ b/src/devices/sound/fmopl.cpp @@ -70,8 +70,8 @@ Revision History: */ #include "emu.h" -#include "ymdeltat.h" #include "fmopl.h" +#include "ymdeltat.h" @@ -2477,11 +2477,11 @@ void y8950_set_update_handler(void *chip,OPL_UPDATEHANDLER UpdateHandler,device_ reinterpret_cast<FM_OPL *>(chip)->SetUpdateHandler(UpdateHandler, device); } -void y8950_set_delta_t_memory(void *chip, void * deltat_mem_ptr, int deltat_mem_size ) +void y8950_set_delta_t_memory(void *chip, FM_READBYTE read_byte, FM_WRITEBYTE write_byte) { FM_OPL *OPL = (FM_OPL *)chip; - OPL->deltat->memory = (uint8_t *)(deltat_mem_ptr); - OPL->deltat->memory_size = deltat_mem_size; + OPL->deltat->read_byte = read_byte; + OPL->deltat->write_byte = write_byte; } /* diff --git a/src/devices/sound/fmopl.h b/src/devices/sound/fmopl.h index 5da3f110830..add973a2369 100644 --- a/src/devices/sound/fmopl.h +++ b/src/devices/sound/fmopl.h @@ -26,6 +26,8 @@ typedef int8_t OPLSAMPLE; #endif */ +typedef uint8_t (*FM_READBYTE)(device_t *device, offs_t offset); +typedef void(*FM_WRITEBYTE)(device_t *device, offs_t offset, uint8_t data); typedef void (*OPL_TIMERHANDLER)(device_t *device,int timer,const attotime &period); typedef void (*OPL_IRQHANDLER)(device_t *device,int irq); typedef void (*OPL_UPDATEHANDLER)(device_t *device,int min_interval_us); @@ -89,7 +91,7 @@ void ym3526_set_update_handler(void *chip, OPL_UPDATEHANDLER UpdateHandler, devi /* Y8950 port handlers */ void y8950_set_port_handler(void *chip, OPL_PORTHANDLER_W PortHandler_w, OPL_PORTHANDLER_R PortHandler_r, device_t *device); void y8950_set_keyboard_handler(void *chip, OPL_PORTHANDLER_W KeyboardHandler_w, OPL_PORTHANDLER_R KeyboardHandler_r, device_t *device); -void y8950_set_delta_t_memory(void *chip, void * deltat_mem_ptr, int deltat_mem_size ); +void y8950_set_delta_t_memory(void *chip, FM_READBYTE read_byte, FM_WRITEBYTE write_byte); void * y8950_init(device_t *device, uint32_t clock, uint32_t rate); void y8950_clock_changed(void *chip, uint32_t clock, uint32_t rate); diff --git a/src/devices/sound/ymdeltat.cpp b/src/devices/sound/ymdeltat.cpp index 29e05b4ef9e..ea13da9782b 100644 --- a/src/devices/sound/ymdeltat.cpp +++ b/src/devices/sound/ymdeltat.cpp @@ -121,7 +121,7 @@ uint8_t YM_DELTAT::ADPCM_Read() if (now_addr != (end << 1)) { - v = memory[now_addr>>1]; + v = read_byte(device, now_addr>>1); /*logerror("YM Delta-T memory read $%08x, v=$%02x\n", now_addr >> 1, v);*/ @@ -200,6 +200,7 @@ value: START, REC, MEMDAT, REPEAT, SPOFF, x,x,RESET meaning: if (emulation_mode == EMULATION_MODE_YM2610) { v |= 0x20; /* YM2610 always uses external memory and doesn't even have memory flag bit. */ + v &= ~0x40; /* YM2610 has no rec bit */ } portstate = v & (0x80|0x40|0x20|0x10|0x01); /* start, rec, memory mode, repeat flag copy, reset(bit0) */ @@ -223,28 +224,6 @@ value: START, REC, MEMDAT, REPEAT, SPOFF, x,x,RESET meaning: { now_addr = start << 1; memread = 2; /* two dummy reads needed before accesing external memory via register $08*/ - - /* if yes, then let's check if ADPCM memory is mapped and big enough */ - if (!memory) - { - device->logerror("YM Delta-T ADPCM rom not mapped\n"); - portstate = 0x00; - PCM_BSY = 0; - } - else - { - if (end >= memory_size) /* Check End in Range */ - { - device->logerror("YM Delta-T ADPCM end out of range: $%08x\n", end); - end = memory_size - 1; - } - if (start >= memory_size) /* Check Start in Range */ - { - device->logerror("YM Delta-T ADPCM start out of range: $%08x\n", start); - portstate = 0x00; - PCM_BSY = 0; - } - } } else /* we access CPU memory (ADPCM data register $08) so we only reset now_addr here */ { @@ -340,7 +319,7 @@ value: START, REC, MEMDAT, REPEAT, SPOFF, x,x,RESET meaning: if (now_addr != (end << 1)) { - memory[now_addr >> 1] = v; + write_byte(device, now_addr >> 1, v); now_addr += 2; /* two nybbles at a time */ /* reset BRDY bit in status register, which means we are processing the write */ @@ -450,8 +429,7 @@ void YM_DELTAT::postload(uint8_t *regs) reg[0] = regs[0]; /* current rom data */ - if (memory) - now_data = *(memory + (now_addr >> 1)); + now_data = read_byte(device, now_addr >> 1); } void YM_DELTAT::savestate(device_t *device) @@ -515,7 +493,7 @@ static inline void YM_DELTAT_synthesis_from_external_memory(YM_DELTAT *DELTAT) if( DELTAT->now_addr&1 ) data = DELTAT->now_data & 0x0f; else { - DELTAT->now_data = *(DELTAT->memory + (DELTAT->now_addr>>1)); + DELTAT->now_data = DELTAT->read_byte(DELTAT->device, DELTAT->now_addr>>1); data = DELTAT->now_data >> 4; } diff --git a/src/devices/sound/ymdeltat.h b/src/devices/sound/ymdeltat.h index f52bd46f5cb..def88c712b9 100644 --- a/src/devices/sound/ymdeltat.h +++ b/src/devices/sound/ymdeltat.h @@ -6,6 +6,8 @@ #pragma once +typedef uint8_t (*FM_READBYTE)(device_t *device, offs_t offset); +typedef void (*FM_WRITEBYTE)(device_t *device, offs_t offset, uint8_t data); typedef void (*STATUS_CHANGE_HANDLER)(void *chip, uint8_t status_bits); @@ -14,7 +16,8 @@ struct YM_DELTAT { /* AT: rearranged and tightened structure */ static constexpr int EMULATION_MODE_NORMAL = 0; static constexpr int EMULATION_MODE_YM2610 = 1; - uint8_t *memory; + FM_READBYTE read_byte; + FM_WRITEBYTE write_byte; int32_t *output_pointer;/* pointer of output pointers */ int32_t *pan; /* pan : &output_pointer[pan] */ double freqbase; diff --git a/src/mame/drivers/neogeo.cpp b/src/mame/drivers/neogeo.cpp index bec0233cf24..d8afdcc4310 100644 --- a/src/mame/drivers/neogeo.cpp +++ b/src/mame/drivers/neogeo.cpp @@ -1351,38 +1351,22 @@ void neogeo_base_state::init_audio() void neogeo_base_state::init_ym() { - uint8_t *ROM; - uint32_t len; - // Resetting a sound device causes the core to update() it and generate samples if it's not up to date. - // Thus we preemptively reset it here while the old pointers are still valid so it's up to date and - // doesn't generate samples below when we reset it for the new pointers. m_ym->reset(); - // all these region_free / region_alloc machinery is needed because current YM emulation does not allow - // to pass a ROM pointer different from a "ymsnd" / "ymsnd.deltat" region, and therefore we need to copy - // the ROM(s) from the cart to the corresponding region(s) with appropriate names... + address_space &adpcm_a_space = m_ym->space(0); + adpcm_a_space.unmap_readwrite(0x000000, 0xffffff); + if (m_slots[m_curr_slot] && m_slots[m_curr_slot]->get_ym_size()) - { - ROM = m_slots[m_curr_slot]->get_ym_base(); - len = m_slots[m_curr_slot]->get_ym_size(); - if (memregion(":ymsnd")) - machine().memory().region_free(":ymsnd"); - machine().memory().region_alloc(":ymsnd", len, 1, ENDIANNESS_LITTLE); - memcpy(memregion(":ymsnd")->base(), ROM, len); - } + adpcm_a_space.install_rom(0, m_slots[m_curr_slot]->get_ym_size() - 1, m_slots[m_curr_slot]->get_ym_base()); - if (memregion(":ymsnd.deltat")) - machine().memory().region_free(":ymsnd.deltat"); - if (m_slots[m_curr_slot] && m_slots[m_curr_slot]->get_ymdelta_size()) - { - ROM = m_slots[m_curr_slot]->get_ymdelta_base(); - len = m_slots[m_curr_slot]->get_ymdelta_size(); - machine().memory().region_alloc(":ymsnd.deltat", len, 1, ENDIANNESS_LITTLE); - memcpy(memregion(":ymsnd.deltat")->base(), ROM, len); - } + address_space &adpcm_b_space = m_ym->space(1); + adpcm_b_space.unmap_readwrite(0x000000, 0xffffff); - m_ym->reset(); // reset it again to get the new pointers + if (m_slots[m_curr_slot] && m_slots[m_curr_slot]->get_ymdelta_size()) + adpcm_b_space.install_rom(0, m_slots[m_curr_slot]->get_ymdelta_size() - 1, m_slots[m_curr_slot]->get_ymdelta_base()); + else if (m_slots[m_curr_slot] && m_slots[m_curr_slot]->get_ym_size()) + adpcm_b_space.install_rom(0, m_slots[m_curr_slot]->get_ym_size() - 1, m_slots[m_curr_slot]->get_ym_base()); } void neogeo_base_state::init_sprites() @@ -1980,11 +1964,10 @@ MACHINE_CONFIG_START(neogeo_base_state::neogeo_stereo) SPEAKER(config, "lspeaker").front_left(); SPEAKER(config, "rspeaker").front_right(); - MCFG_DEVICE_MODIFY("ymsnd") - MCFG_SOUND_ROUTE(0, "lspeaker", 0.28) - MCFG_SOUND_ROUTE(0, "rspeaker", 0.28) - MCFG_SOUND_ROUTE(1, "lspeaker", 0.98) - MCFG_SOUND_ROUTE(2, "rspeaker", 0.98) + m_ym->add_route(0, "lspeaker", 0.28); + m_ym->add_route(0, "rspeaker", 0.28); + m_ym->add_route(1, "lspeaker", 0.98); + m_ym->add_route(2, "rspeaker", 0.98); MACHINE_CONFIG_END @@ -2008,10 +1991,9 @@ MACHINE_CONFIG_END MACHINE_CONFIG_START(ngarcade_base_state::neogeo_mono) SPEAKER(config, "speaker").front_center(); - MCFG_DEVICE_MODIFY("ymsnd") - MCFG_SOUND_ROUTE(0, "speaker", 0.28) - MCFG_SOUND_ROUTE(1, "speaker", 0.49) - MCFG_SOUND_ROUTE(2, "speaker", 0.49) + m_ym->add_route(0, "speaker", 0.28); + m_ym->add_route(1, "speaker", 0.49); + m_ym->add_route(2, "speaker", 0.49); MACHINE_CONFIG_END @@ -2314,8 +2296,7 @@ MACHINE_CONFIG_END ROM_LOAD( "sm1.sm1", 0x00000, 0x20000, CRC(94416d67) SHA1(42f9d7ddd6c0931fd64226a60dc73602b2819dcf) ) \ ROM_REGION( 0x20000, "cslot1:audiocpu", 0 ) \ ROM_LOAD( name, 0x00000, 0x10000, hash ) \ - ROM_RELOAD( 0x10000, 0x10000 ) \ - ROM_REGION( 0x10000, "ymsnd", ROMREGION_ERASEFF ) + ROM_RELOAD( 0x10000, 0x10000 ) #define NEO_BIOS_AUDIO_128K(name, hash) \ NEOGEO_BIOS \ @@ -2323,8 +2304,7 @@ MACHINE_CONFIG_END ROM_LOAD( "sm1.sm1", 0x00000, 0x20000, CRC(94416d67) SHA1(42f9d7ddd6c0931fd64226a60dc73602b2819dcf) ) \ ROM_REGION( 0x30000, "cslot1:audiocpu", 0 ) \ ROM_LOAD( name, 0x00000, 0x20000, hash ) \ - ROM_RELOAD( 0x10000, 0x20000 ) \ - ROM_REGION( 0x10000, "ymsnd", ROMREGION_ERASEFF ) + ROM_RELOAD( 0x10000, 0x20000 ) #define NEO_BIOS_AUDIO_256K(name, hash) \ NEOGEO_BIOS \ @@ -2332,8 +2312,7 @@ MACHINE_CONFIG_END ROM_LOAD( "sm1.sm1", 0x00000, 0x20000, CRC(94416d67) SHA1(42f9d7ddd6c0931fd64226a60dc73602b2819dcf) ) \ ROM_REGION( 0x50000, "cslot1:audiocpu", 0 ) \ ROM_LOAD( name, 0x00000, 0x40000, hash ) \ - ROM_RELOAD( 0x10000, 0x40000 ) \ - ROM_REGION( 0x10000, "ymsnd", ROMREGION_ERASEFF ) + ROM_RELOAD( 0x10000, 0x40000 ) #define NEO_BIOS_AUDIO_512K(name, hash) \ NEOGEO_BIOS \ @@ -2341,9 +2320,7 @@ MACHINE_CONFIG_END ROM_LOAD( "sm1.sm1", 0x00000, 0x20000, CRC(94416d67) SHA1(42f9d7ddd6c0931fd64226a60dc73602b2819dcf) ) \ ROM_REGION( 0x90000, "cslot1:audiocpu", 0 ) \ ROM_LOAD( name, 0x00000, 0x80000, hash ) \ - ROM_RELOAD( 0x10000, 0x80000 ) \ - ROM_REGION( 0x10000, "ymsnd", ROMREGION_ERASEFF ) - + ROM_RELOAD( 0x10000, 0x80000 ) #define NEO_BIOS_AUDIO_ENCRYPTED_128K(name, hash) \ NEOGEO_BIOS \ @@ -2351,24 +2328,23 @@ MACHINE_CONFIG_END ROM_LOAD( "sm1.sm1", 0x00000, 0x20000, CRC(94416d67) SHA1(42f9d7ddd6c0931fd64226a60dc73602b2819dcf) ) \ ROM_REGION( 0x90000, "cslot1:audiocpu", ROMREGION_ERASEFF ) \ ROM_REGION( 0x80000, "cslot1:audiocrypt", 0 ) \ - ROM_LOAD( name, 0x00000, 0x20000, hash ) \ - ROM_REGION( 0x10000, "ymsnd", ROMREGION_ERASEFF ) + ROM_LOAD( name, 0x00000, 0x20000, hash ) + #define NEO_BIOS_AUDIO_ENCRYPTED_256K(name, hash) \ NEOGEO_BIOS \ ROM_REGION( 0x20000, "audiobios", 0 ) \ ROM_LOAD( "sm1.sm1", 0x00000, 0x20000, CRC(94416d67) SHA1(42f9d7ddd6c0931fd64226a60dc73602b2819dcf) ) \ ROM_REGION( 0x90000, "cslot1:audiocpu", ROMREGION_ERASEFF ) \ ROM_REGION( 0x80000, "cslot1:audiocrypt", 0 ) \ - ROM_LOAD( name, 0x00000, 0x40000, hash ) \ - ROM_REGION( 0x10000, "ymsnd", ROMREGION_ERASEFF ) + ROM_LOAD( name, 0x00000, 0x40000, hash ) + #define NEO_BIOS_AUDIO_ENCRYPTED_512K(name, hash) \ NEOGEO_BIOS \ ROM_REGION( 0x20000, "audiobios", 0 ) \ ROM_LOAD( "sm1.sm1", 0x00000, 0x20000, CRC(94416d67) SHA1(42f9d7ddd6c0931fd64226a60dc73602b2819dcf) ) \ ROM_REGION( 0x90000, "cslot1:audiocpu", ROMREGION_ERASEFF ) \ ROM_REGION( 0x80000, "cslot1:audiocrypt", 0 ) \ - ROM_LOAD( name, 0x00000, 0x80000, hash ) \ - ROM_REGION( 0x10000, "ymsnd", ROMREGION_ERASEFF ) + ROM_LOAD( name, 0x00000, 0x80000, hash ) @@ -2411,8 +2387,6 @@ ROM_START( neogeo ) ROM_REGION( 0x20000, "fixedbios", 0 ) ROM_LOAD( "sfix.sfix", 0x000000, 0x20000, CRC(c2ea0cfd) SHA1(fd4a618cdcdbf849374f0a50dd8efe9dbab706c3) ) - ROM_REGION( 0x10000, "ymsnd", ROMREGION_ERASEFF ) - ROM_REGION( 0x100000, "sprites", ROMREGION_ERASEFF ) ROM_END @@ -2441,10 +2415,6 @@ ROM_START( aes ) ROM_REGION( 0x20000, "fixed", ROMREGION_ERASEFF ) - ROM_REGION( 0x1000000, "ymsnd", ROMREGION_ERASEFF ) - - ROM_REGION( 0x1000000, "ymsnd.deltat", ROMREGION_ERASEFF ) - ROM_REGION( 0x900000, "sprites", ROMREGION_ERASEFF ) ROM_END @@ -6473,7 +6443,6 @@ ROM_START( dragonsh ) ROM_REGION( 0x30000, "cslot1:audiocpu", ROMREGION_ERASEFF ) // not present - ROM_REGION( 0x10000, "ymsnd", ROMREGION_ERASEFF ) ROM_REGION( 0x200000, "cslot1:ymsnd", ROMREGION_ERASE00 ) ROM_LOAD( "sram.v1", 0x000000, 0x200000, NO_DUMP ) // was a dead AXS2000PC 2MB sram card, battery dead, data lost. @@ -7099,7 +7068,6 @@ ROM_START( kizuna4p ) /* same cartridge as kizuna - 4-player mode is enabled by ROM_LOAD16_WORD_SWAP_BIOS( 0, "sp-45.sp1",0x00000, 0x080000, CRC(03cc9f6a) SHA1(cdf1f49e3ff2bac528c21ed28449cf35b7957dc1) ) ROM_SYSTEM_BIOS( 1, "japan", "Japan MVS (J3)" ) ROM_LOAD16_WORD_SWAP_BIOS( 1, "japan-j3.bin",0x00000, 0x020000, CRC(dff6d41f) SHA1(e92910e20092577a4523a6b39d578a71d4de7085) ) - ROM_REGION( 0x10000, "ymsnd", ROMREGION_ERASEFF ) ROM_REGION( 0x30000, "cslot1:audiocpu", 0 ) ROM_LOAD( "216-m1.m1", 0x00000, 0x20000, CRC(1b096820) SHA1(72852e78c620038f8dafde5e54e02e418c31be9c) ) /* mask rom TC531001 */ @@ -7796,7 +7764,6 @@ ROM_START( irrmaze ) /* MVS ONLY RELEASE */ ROM_REGION16_BE( 0x20000, "mainbios", 0 ) /* special BIOS with trackball support, we only have one Irritating Maze bios and thats asia */ ROM_LOAD16_WORD_SWAP("236-bios.sp1", 0x00000, 0x020000, CRC(853e6b96) SHA1(de369cb4a7df147b55168fa7aaf0b98c753b735e) ) - ROM_REGION( 0x10000, "ymsnd", ROMREGION_ERASEFF ) ROM_REGION( 0x30000, "cslot1:audiocpu", 0 ) ROM_LOAD( "236-m1.m1", 0x00000, 0x20000, CRC(880a1abd) SHA1(905afa157aba700e798243b842792e50729b19a0) ) /* TC531001 */ @@ -10944,7 +10911,6 @@ ROM_START( svcboot ) ROM_REGION( 0x20000, "audiobios", 0 ) ROM_LOAD( "sm1.sm1", 0x00000, 0x20000, CRC(94416d67) SHA1(42f9d7ddd6c0931fd64226a60dc73602b2819dcf) ) - ROM_REGION( 0x10000, "ymsnd", ROMREGION_ERASEFF ) ROM_REGION( 0x50000, "cslot1:audiocpu", 0 ) ROM_LOAD( "svc-m1.bin", 0x20000, 0x10000, CRC(804328c3) SHA1(f931636c563b0789d4812033a77b47bf663db43f) ) @@ -10982,7 +10948,6 @@ ROM_START( svcplus ) ROM_REGION( 0x20000, "audiobios", 0 ) ROM_LOAD( "sm1.sm1", 0x00000, 0x20000, CRC(94416d67) SHA1(42f9d7ddd6c0931fd64226a60dc73602b2819dcf) ) - ROM_REGION( 0x10000, "ymsnd", ROMREGION_ERASEFF ) ROM_REGION( 0x50000, "cslot1:audiocpu", 0 ) ROM_LOAD( "svc-m1.bin", 0x20000, 0x10000, CRC(804328c3) SHA1(f931636c563b0789d4812033a77b47bf663db43f) ) @@ -11021,7 +10986,6 @@ ROM_START( svcplusa ) ROM_REGION( 0x20000, "audiobios", 0 ) ROM_LOAD( "sm1.sm1", 0x00000, 0x20000, CRC(94416d67) SHA1(42f9d7ddd6c0931fd64226a60dc73602b2819dcf) ) - ROM_REGION( 0x10000, "ymsnd", ROMREGION_ERASEFF ) ROM_REGION( 0x50000, "cslot1:audiocpu", 0 ) ROM_LOAD( "svc-m1.bin", 0x20000, 0x10000, CRC(804328c3) SHA1(f931636c563b0789d4812033a77b47bf663db43f) ) @@ -11058,7 +11022,6 @@ ROM_START( svcsplus ) ROM_REGION( 0x20000, "audiobios", 0 ) ROM_LOAD( "sm1.sm1", 0x00000, 0x20000, CRC(94416d67) SHA1(42f9d7ddd6c0931fd64226a60dc73602b2819dcf) ) - ROM_REGION( 0x10000, "ymsnd", ROMREGION_ERASEFF ) ROM_REGION( 0x50000, "cslot1:audiocpu", 0 ) ROM_LOAD( "svc-m1.bin", 0x20000, 0x10000, CRC(804328c3) SHA1(f931636c563b0789d4812033a77b47bf663db43f) ) diff --git a/src/mame/drivers/vgmplay.cpp b/src/mame/drivers/vgmplay.cpp index 977f50768d5..af84a06707b 100644 --- a/src/mame/drivers/vgmplay.cpp +++ b/src/mame/drivers/vgmplay.cpp @@ -191,6 +191,10 @@ public: virtual std::unique_ptr<util::disasm_interface> create_disassembler() override; template<int Chip> DECLARE_READ8_MEMBER(segapcm_rom_r); + template<int Chip> DECLARE_READ8_MEMBER(ym2608_rom_r); + template<int Chip> DECLARE_READ8_MEMBER(ym2610_adpcm_a_rom_r); + template<int Chip> DECLARE_READ8_MEMBER(ym2610_adpcm_b_rom_r); + template<int Chip> DECLARE_READ8_MEMBER(y8950_rom_r); template<int Chip> DECLARE_READ8_MEMBER(ymf278b_rom_r); template<int Chip> DECLARE_READ8_MEMBER(ymf271_rom_r); template<int Chip> DECLARE_READ8_MEMBER(ymz280b_rom_r); @@ -353,6 +357,15 @@ private: std::array<std::vector<uint8_t>, 0x40> m_data_streams; std::array<std::vector<data_block>, 0x40> m_data_stream_blocks; + struct + { + uint8_t cmp_type; + uint8_t cmp_sub_type; + uint8_t bit_dec; + uint8_t bit_cmp; + std::vector<uint8_t> entries; + } m_dec_table; + uint32_t m_ym2612_stream_offset = 0U; uint32_t m_multipcm_bank_l[2]; @@ -365,6 +378,7 @@ private: uint32_t m_okim6295_bank[2]; uint32_t m_okim6295_nmk112_bank[2][4]; + int m_sega32x_channel_hack; int m_nes_apu_channel_hack[2]; }; @@ -405,6 +419,10 @@ public: void soundchips16_map(address_map &map); template<int Chip> void segapcm_map(address_map &map); template<int Chip> void rf5c68_map(address_map &map); + template<int Chip> void ym2608_map(address_map &map); + template<int Chip> void ym2610_adpcm_a_map(address_map &map); + template<int Chip> void ym2610_adpcm_b_map(address_map &map); + template<int Chip> void y8950_map(address_map &map); template<int Chip> void ymf278b_map(address_map &map); template<int Chip> void ymf271_map(address_map &map); template<int Chip> void ymz280b_map(address_map &map); @@ -538,6 +556,7 @@ void vgmplay_device::device_reset() s.timer->enable(false); } + m_sega32x_channel_hack = 0; m_nes_apu_channel_hack[0] = 0; m_nes_apu_channel_hack[1] = 0; } @@ -624,6 +643,8 @@ void vgmplay_device::blocks_clear() m_data_streams[i].clear(); m_data_stream_blocks[i].clear(); } + + m_dec_table.entries.clear(); } uint32_t vgmplay_device::handle_data_block(uint32_t address) @@ -657,8 +678,10 @@ uint32_t vgmplay_device::handle_data_block(uint32_t address) uint8_t cmp_sub_type = m_file->read_byte(m_pc + 0x0e); uint16_t add_val = m_file->read_word(m_pc + 0x0f); - if (cmp_sub_type == 0x02) - osd_printf_error("unhandled n-bit compressed stream size %x->%x type %02x bit_dec %02x bit_cmp %02x unsupported cmp_sub_type %02x add_val %04x\n", size, out_size, type - 0x40, bit_dec, bit_cmp, cmp_sub_type, add_val); + if (cmp_sub_type == 0x02 && m_dec_table.entries.size() == 0) + osd_printf_error("invalid n-bit compressed stream, no decompression table\n"); + else if (cmp_sub_type == 0x02 && (m_dec_table.cmp_type != cmp_type || m_dec_table.cmp_sub_type != cmp_sub_type || m_dec_table.bit_dec != bit_dec || m_dec_table.bit_cmp != bit_cmp )) + osd_printf_error("invalid n-bit compressed stream, decompression table mismatch\n"); else { int in_pos = 0x11 - 0x07; @@ -705,8 +728,15 @@ uint32_t vgmplay_device::handle_data_block(uint32_t address) out_val = in_val + add_val; else if (cmp_sub_type == 1) out_val = (in_val << (bit_dec - bit_cmp)) + add_val; + else if (cmp_sub_type == 2) + { + if (bit_dec <= 8) + out_val = m_dec_table.entries[in_val]; + else if (bit_dec <= 16) + out_val = m_dec_table.entries[in_val << 1] | (m_dec_table.entries[(in_val << 1) + 1] << 8); + } else - osd_printf_error("unhandled n-bit compressed stream size %x->%x type %02x bit_dec %02x bit_cmp %02x unsupported cmp_sub_type %02x add_val %04x\n", size, out_size, type - 0x40, bit_dec, bit_cmp, cmp_sub_type, add_val); + osd_printf_error("invalid n-bit compressed stream size %x->%x type %02x bit_dec %02x bit_cmp %02x unsupported cmp_sub_type %02x add_val %04x\n", size, out_size, type - 0x40, bit_dec, bit_cmp, cmp_sub_type, add_val); for (int i = 0; i < bit_dec; i += 8) { @@ -726,9 +756,17 @@ uint32_t vgmplay_device::handle_data_block(uint32_t address) else osd_printf_error("unhandled unknown %02x compressed stream size %x->%x type %02x\n", cmp_type, size, out_size, type - 0x40); } - else if (type < 0x80) - osd_printf_error("unhandled compression table size %x\n", size); - + else if (type == 0x7f) + { + m_dec_table.cmp_type = m_file->read_byte(m_pc + 0x07); + m_dec_table.cmp_sub_type = m_file->read_byte(m_pc + 0x08); + m_dec_table.bit_dec = m_file->read_byte(m_pc + 0x09); + m_dec_table.bit_cmp = m_file->read_byte(m_pc + 0x0a); + + m_dec_table.entries.resize(m_file->read_word(m_pc + 0x0b) * ((m_dec_table.bit_dec + 7) / 8)); + for (size_t i = 0; i < m_dec_table.entries.size(); i++) + m_dec_table.entries[i] = m_file->read_byte(m_pc + 0x0d + i); + } else if (type < 0xc0) { uint32_t rom_size = m_file->read_dword(m_pc + 7); @@ -825,13 +863,33 @@ TIMER_CALLBACK_MEMBER(vgmplay_device::stream_timer_expired) else offset += s.position * s.step_size * s.byte_depth; - if (offset + s.byte_depth >= m_data_streams[s.bank].size()) + if (offset + s.byte_depth > m_data_streams[s.bank].size()) { - osd_printf_error("stream_timer_expired %02x: stream beyond end %u>=%u\n", param, offset, uint32_t(m_data_streams[s.bank].size())); + osd_printf_error("stream_timer_expired %02x: stream beyond end %d/%d %u>=%u\n", param, s.position, s.length, offset, uint32_t(m_data_streams[s.bank].size())); s.timer->enable(false); } + else if (s.chip_type == LED_YM2612) + { + m_io->write_byte(A_YM2612_0 + 0 + ((s.port & 1) << 1), s.reg); + m_io->write_byte(A_YM2612_0 + 1 + ((s.port & 1) << 1), m_data_streams[s.bank][offset]); + } + else if (s.chip_type == LED_YM2608) + { + m_io->write_byte(A_YM2608_0 + 0 + ((s.port & 1) << 1), s.reg); + m_io->write_byte(A_YM2608_0 + 1 + ((s.port & 1) << 1), m_data_streams[s.bank][offset]); + } else if (s.chip_type == LED_32X_PWM) + { + if (m_sega32x_channel_hack >= 0) + { + osd_printf_error("bad rip detected, enabling sega32x channels\n"); + m_io16->write_word(A_32X_PWM, 5); + + m_sega32x_channel_hack = -2; + } + m_io16->write_word(A_32X_PWM + (s.reg << 1), ((m_data_streams[s.bank][offset + 1] & 0xf) << 8) | m_data_streams[s.bank][offset]); + } else if (s.chip_type == LED_OKIM6258) m_io->write_byte(A_OKIM6258_0 + s.reg, m_data_streams[s.bank][offset]); else @@ -1380,10 +1438,24 @@ void vgmplay_device::execute_run() uint8_t offset = m_file->read_byte(m_pc + 1); uint8_t data = m_file->read_byte(m_pc + 2); - if ((offset & 0xf0) == 0 && data == 0) + if (m_sega32x_channel_hack >= 0) { - osd_printf_error("bad rip detected, enabling sega32x channels\n"); - data |= 5; + if ((offset & 0xf0) == 0) + { + if (data != 0) + m_sega32x_channel_hack = -1; + } + else + { + m_sega32x_channel_hack++; + if (m_sega32x_channel_hack == 32) + { + osd_printf_error("bad rip detected, enabling sega32x channels\n"); + m_io16->write_word(A_32X_PWM, 5); + + m_sega32x_channel_hack = -2; + } + } } m_io16->write_word(A_32X_PWM + ((offset & 0xf0) >> 3), ((offset & 0xf) << 8) | data); @@ -1431,11 +1503,11 @@ void vgmplay_device::execute_run() } } } - else if ((offset & 0x7f) == 0x15 && m_nes_apu_channel_hack[chip] == -2 && (m_file->read_byte(m_pc + 2) & 0x1f) != 0) - { - osd_printf_error("bad rip false positive, late enabling nesapu.%d channels\n", chip); - m_nes_apu_channel_hack[chip] = -1; - } + //else if ((offset & 0x7f) == 0x15 && m_nes_apu_channel_hack[chip] == -2 && (m_file->read_byte(m_pc + 2) & 0x1f) != 0) + //{ + // osd_printf_error("bad rip false positive, late enabling nesapu.%d channels %x/%x\n", chip, m_pc, m_io->read_dword(REG_SIZE)); + // m_nes_apu_channel_hack[chip] = -1; + //} if (offset & 0x80) m_io->write_byte(A_NESAPU_1 + (offset & 0x7f), m_file->read_byte(m_pc + 2)); @@ -1963,7 +2035,7 @@ offs_t vgmplay_disassembler::disassemble(std::ostream &stream, offs_t pc, const "ymf278b.%d rom", "ymf271.%d rom", "ymz280b.%d rom", - "ymf278b.%d rom", + "ymf278b.%d ram", "y8950.%d delta-t rom", "multipcm.%d rom", "upd7759.%d rom", @@ -2008,7 +2080,7 @@ offs_t vgmplay_disassembler::disassemble(std::ostream &stream, offs_t pc, const } else if (type < 0x7f) util::stream_format(stream, "unknown%02x.%d stream comp. data-block %x", type - 0x40, second, size); - else if (type < 0x80) + else if (type == 0x7f) util::stream_format(stream, "decomp-table %x, %02x/%02x", size, opcodes.r8(pc + 7), opcodes.r8(pc + 8)); else if (type < 0x94) { @@ -2065,27 +2137,27 @@ offs_t vgmplay_disassembler::disassemble(std::ostream &stream, offs_t pc, const return 1 | SUPPORTED; case 0x90: - util::stream_format(stream, "stream control %02x %02x %02x %02x\n", opcodes.r8(pc + 1), opcodes.r8(pc + 2), opcodes.r8(pc + 3), opcodes.r8(pc + 4)); + util::stream_format(stream, "stream control %02x %02x %02x %02x", opcodes.r8(pc + 1), opcodes.r8(pc + 2), opcodes.r8(pc + 3), opcodes.r8(pc + 4)); return 5 | SUPPORTED; case 0x91: - util::stream_format(stream, "stream data %02x %02x %02x %02x\n", opcodes.r8(pc + 1), opcodes.r8(pc + 2), opcodes.r8(pc + 3), opcodes.r8(pc + 4)); + util::stream_format(stream, "stream data %02x %02x %02x %02x", opcodes.r8(pc + 1), opcodes.r8(pc + 2), opcodes.r8(pc + 3), opcodes.r8(pc + 4)); return 5 | SUPPORTED; case 0x92: - util::stream_format(stream, "stream frequency %02x %d\n", opcodes.r8(pc + 1), opcodes.r32(pc + 2)); + util::stream_format(stream, "stream frequency %02x %d", opcodes.r8(pc + 1), opcodes.r32(pc + 2)); return 6 | SUPPORTED; case 0x93: - util::stream_format(stream, "stream start %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x\n", opcodes.r8(pc + 1), opcodes.r8(pc + 2), opcodes.r8(pc + 3), opcodes.r8(pc + 4), opcodes.r8(pc + 5), opcodes.r8(pc + 6), opcodes.r8(pc + 7), opcodes.r8(pc + 8), opcodes.r8(pc + 9), opcodes.r8(pc + 10)); + util::stream_format(stream, "stream start %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x", opcodes.r8(pc + 1), opcodes.r8(pc + 2), opcodes.r8(pc + 3), opcodes.r8(pc + 4), opcodes.r8(pc + 5), opcodes.r8(pc + 6), opcodes.r8(pc + 7), opcodes.r8(pc + 8), opcodes.r8(pc + 9), opcodes.r8(pc + 10)); return 11 | SUPPORTED; case 0x94: - util::stream_format(stream, "stream stop %02x\n", opcodes.r8(pc + 1)); + util::stream_format(stream, "stream stop %02x", opcodes.r8(pc + 1)); return 2 | SUPPORTED; case 0x95: - util::stream_format(stream, "stream start short %02x %02x %02x %02x\n", opcodes.r8(pc + 1), opcodes.r8(pc + 2), opcodes.r8(pc + 3), opcodes.r8(pc + 4)); + util::stream_format(stream, "stream start short %02x %02x %02x %02x", opcodes.r8(pc + 1), opcodes.r8(pc + 2), opcodes.r8(pc + 3), opcodes.r8(pc + 4)); return 5 | SUPPORTED; case 0xa0: @@ -2308,6 +2380,24 @@ READ8_MEMBER(vgmplay_device::segapcm_rom_r) } template<int Chip> +READ8_MEMBER(vgmplay_device::ym2608_rom_r) +{ + return rom_r(Chip, 0x81, offset); +} + +template<int Chip> +READ8_MEMBER(vgmplay_device::ym2610_adpcm_a_rom_r) +{ + return rom_r(Chip, 0x82, offset); +} + +template<int Chip> +READ8_MEMBER(vgmplay_device::ym2610_adpcm_b_rom_r) +{ + return rom_r(Chip, 0x83, offset); +} + +template<int Chip> READ8_MEMBER(vgmplay_device::ymf278b_rom_r) { return rom_r(Chip, 0x84, offset); @@ -2326,6 +2416,12 @@ READ8_MEMBER(vgmplay_device::ymz280b_rom_r) } template<int Chip> +READ8_MEMBER(vgmplay_device::y8950_rom_r) +{ + return rom_r(Chip, 0x88, offset); +} + +template<int Chip> READ8_MEMBER(vgmplay_device::multipcm_rom_r) { if (m_multipcm_banked[Chip] == 1) @@ -3176,6 +3272,30 @@ void vgmplay_state::rf5c68_map(address_map &map) } template<int Chip> +void vgmplay_state::ym2608_map(address_map &map) +{ + map(0, 0x1fffff).r("vgmplay", FUNC(vgmplay_device::ym2608_rom_r<Chip>)); +} + +template<int Chip> +void vgmplay_state::ym2610_adpcm_a_map(address_map &map) +{ + map(0, 0xffffff).r("vgmplay", FUNC(vgmplay_device::ym2610_adpcm_a_rom_r<Chip>)); +} + +template<int Chip> +void vgmplay_state::ym2610_adpcm_b_map(address_map &map) +{ + map(0, 0xffffff).r("vgmplay", FUNC(vgmplay_device::ym2610_adpcm_b_rom_r<Chip>)); +} + +template<int Chip> +void vgmplay_state::y8950_map(address_map &map) +{ + map(0, 0x1fffff).r("vgmplay", FUNC(vgmplay_device::y8950_rom_r<Chip>)); +} + +template<int Chip> void vgmplay_state::ymf278b_map(address_map &map) { map(0, 0x3fffff).r("vgmplay", FUNC(vgmplay_device::ymf278b_rom_r<Chip>)); @@ -3360,21 +3480,27 @@ MACHINE_CONFIG_START(vgmplay_state::vgmplay) // TODO: prevent error.log spew YM2608(config, m_ym2608[0], 0); + m_ym2608[0]->set_addrmap(0, &vgmplay_state::ym2608_map<0>); m_ym2608[0]->add_route(ALL_OUTPUTS, "lspeaker", 1); m_ym2608[0]->add_route(ALL_OUTPUTS, "rspeaker", 1); YM2608(config, m_ym2608[1], 0); + m_ym2608[1]->set_addrmap(0, &vgmplay_state::ym2608_map<1>); m_ym2608[1]->add_route(ALL_OUTPUTS, "lspeaker", 1); m_ym2608[1]->add_route(ALL_OUTPUTS, "rspeaker", 1); // TODO: prevent error.log spew YM2610(config, m_ym2610[0], 0); + m_ym2610[0]->set_addrmap(0, &vgmplay_state::ym2610_adpcm_a_map<0>); + m_ym2610[0]->set_addrmap(1, &vgmplay_state::ym2610_adpcm_b_map<0>); m_ym2610[0]->add_route(0, "lspeaker", 0.25); m_ym2610[0]->add_route(0, "rspeaker", 0.25); m_ym2610[0]->add_route(1, "lspeaker", 0.50); m_ym2610[0]->add_route(2, "rspeaker", 0.50); YM2610(config, m_ym2610[1], 0); + m_ym2610[1]->set_addrmap(0, &vgmplay_state::ym2610_adpcm_a_map<1>); + m_ym2610[1]->set_addrmap(1, &vgmplay_state::ym2610_adpcm_b_map<1>); m_ym2610[1]->add_route(0, "lspeaker", 0.25); m_ym2610[1]->add_route(0, "rspeaker", 0.25); m_ym2610[1]->add_route(1, "lspeaker", 0.50); @@ -3397,10 +3523,12 @@ MACHINE_CONFIG_START(vgmplay_state::vgmplay) m_ym3526[1]->add_route(ALL_OUTPUTS, "rspeaker", 0.5); Y8950(config, m_y8950[0], 0); + m_y8950[0]->set_addrmap(0, &vgmplay_state::y8950_map<0>); m_y8950[0]->add_route(ALL_OUTPUTS, "lspeaker", 0.40); m_y8950[0]->add_route(ALL_OUTPUTS, "rspeaker", 0.40); Y8950(config, m_y8950[1], 0); + m_y8950[1]->set_addrmap(0, &vgmplay_state::y8950_map<1>); m_y8950[1]->add_route(ALL_OUTPUTS, "lspeaker", 0.40); m_y8950[1]->add_route(ALL_OUTPUTS, "rspeaker", 0.40); @@ -3693,13 +3821,6 @@ MACHINE_CONFIG_START(vgmplay_state::vgmplay) MACHINE_CONFIG_END ROM_START( vgmplay ) - // TODO: change sound cores to device_rom_interface - ROM_REGION( 0x80000, "ym2608.0", ROMREGION_ERASE00 ) - ROM_REGION( 0x80000, "ym2608.1", ROMREGION_ERASE00 ) - ROM_REGION( 0x80000, "ym2610.0", ROMREGION_ERASE00 ) - ROM_REGION( 0x80000, "ym2610.1", ROMREGION_ERASE00 ) - ROM_REGION( 0x80000, "y8950.0", ROMREGION_ERASE00 ) - ROM_REGION( 0x80000, "y8950.1", ROMREGION_ERASE00 ) // TODO: split up 32x to remove dependencies ROM_REGION( 0x4000, "master", ROMREGION_ERASE00 ) ROM_REGION( 0x4000, "slave", ROMREGION_ERASE00 ) |