summaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
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
commit56fb60aa22dce853baa661fbce2a4187e9da0459 (patch)
tree9724c58217b5f7092035e79b75977b6df961d502
parent01435b68b43d232b2e0180f48d320abcee358413 (diff)
vgmplay: Support ym2608, ym2610, ym2612 & y8950 samples [smf]
-rw-r--r--src/devices/sound/2608intf.cpp24
-rw-r--r--src/devices/sound/2608intf.h11
-rw-r--r--src/devices/sound/2610intf.cpp47
-rw-r--r--src/devices/sound/2610intf.h16
-rw-r--r--src/devices/sound/8950intf.cpp13
-rw-r--r--src/devices/sound/8950intf.h10
-rw-r--r--src/devices/sound/fm.cpp70
-rw-r--r--src/devices/sound/fm.h11
-rw-r--r--src/devices/sound/fmopl.cpp8
-rw-r--r--src/devices/sound/fmopl.h4
-rw-r--r--src/devices/sound/ymdeltat.cpp32
-rw-r--r--src/devices/sound/ymdeltat.h5
-rw-r--r--src/mame/drivers/neogeo.cpp89
-rw-r--r--src/mame/drivers/vgmplay.cpp183
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 )