upd7759: Converted to use device_rom_interface and added md input for selecting between master and slave. [smf]

Finished hooking the UPD7759 up to the following drivers:

vgmplay
Bay Route (encrypted, protected bootleg)
E-Swat - Cyber Police (bootleg, set 1)
Golden Axe (encrypted bootleg)
Passing Shot (2 Players) (bootleg)
This commit is contained in:
smf- 2018-08-12 14:01:05 +01:00
parent 82be4e22f1
commit 691f915b21
26 changed files with 242 additions and 163 deletions

View File

@ -26,7 +26,7 @@ void sega_315_5641_pcm_device::advance_state()
switch (m_state)
{
case STATE_DROP_DRQ:
if (m_rombase == nullptr)
if (!m_md)
{
// Slave Mode: get data from FIFO buffer
uint8_t fiforead = (m_fifo_read + 1) & 0x3F;
@ -43,9 +43,9 @@ void sega_315_5641_pcm_device::advance_state()
}
WRITE8_MEMBER( sega_315_5641_pcm_device::port_w )
void sega_315_5641_pcm_device::port_w(u8 data)
{
if (m_rombase != nullptr)
if (m_md)
{
// update the FIFO value
m_fifo_in = data;

View File

@ -18,7 +18,7 @@ class sega_315_5641_pcm_device : public upd7756_device
public:
sega_315_5641_pcm_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
virtual DECLARE_WRITE8_MEMBER(port_w) override;
virtual void port_w(u8 data) override;
uint8_t get_fifo_space();

View File

@ -12,7 +12,6 @@
- low-level emulation
- watchdog? - according to uPD775x datasheet, the chip goes into standy mode
if CS/ST/RESET have not been accessed for more than 3 seconds
- convert to MAME modern device
*************************************************************
@ -146,15 +145,16 @@
upd775x_device::upd775x_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock)
: device_t(mconfig, type, tag, owner, clock)
, device_sound_interface(mconfig, *this)
, device_rom_interface(mconfig, *this, 17)
, m_channel(nullptr)
, m_sample_offset_shift(0)
, m_pos(0)
, m_step(0)
, m_fifo_in(0)
, m_reset(0)
, m_start(0)
, m_reset(1)
, m_start(1)
, m_drq(0)
, m_state(0)
, m_state(STATE_IDLE)
, m_clocks_left(0)
, m_nibbles_left(0)
, m_repeat_count(0)
@ -170,10 +170,7 @@ upd775x_device::upd775x_device(const machine_config &mconfig, device_type type,
, m_adpcm_state(0)
, m_adpcm_data(0)
, m_sample(0)
, m_rombase(*this, DEVICE_SELF)
, m_rom(nullptr)
, m_romoffset(0)
, m_rommask(0)
, m_md(1)
{
}
@ -211,9 +208,6 @@ upd7756_device::upd7756_device(const machine_config &mconfig, device_type type,
void upd775x_device::device_start()
{
// chip configuration
m_sample_offset_shift = 0;
// allocate a stream channel
m_channel = machine().sound().stream_alloc(*this, 0, 1, clock()/4);
@ -223,29 +217,6 @@ void upd775x_device::device_start()
// compute the clock period
m_clock_period = clock() ? attotime::from_hz(clock()) : attotime::zero;
// set the intial state
m_state = STATE_IDLE;
// compute the ROM base or allocate a timer
m_romoffset = 0;
m_rom = m_rombase;
if (m_rombase)
{
uint32_t const romsize = m_rombase.bytes();
if (romsize >= 0x20000)
m_rommask = 0x1ffff;
else
m_rommask = romsize - 1;
}
else
{
m_rommask = 0;
}
// assume /RESET and /START are both high
m_reset = 1;
m_start = 1;
save_item(NAME(m_pos));
save_item(NAME(m_step));
@ -271,8 +242,6 @@ void upd775x_device::device_start()
save_item(NAME(m_adpcm_state));
save_item(NAME(m_adpcm_data));
save_item(NAME(m_sample));
save_item(NAME(m_romoffset));
}
void upd775x_device::device_clock_changed()
@ -282,6 +251,11 @@ void upd775x_device::device_clock_changed()
m_channel->set_sample_rate(clock() / 4);
}
void upd775x_device::rom_bank_updated()
{
m_channel->update();
}
void upd7759_device::device_start()
{
upd775x_device::device_start();
@ -289,10 +263,6 @@ void upd7759_device::device_start()
// chip configuration
m_sample_offset_shift = 1;
// alloate a timer
if (m_rombase)
m_drqcallback.reset();
else
m_timer = timer_alloc(TIMER_SLAVE_UPDATE);
m_drqcallback.resolve_safe();
@ -318,7 +288,6 @@ void upd775x_device::device_reset()
{
m_pos = 0;
m_fifo_in = 0;
m_drq = 0;
m_state = STATE_IDLE;
m_clocks_left = 0;
m_nibbles_left = 0;
@ -342,10 +311,21 @@ void upd7759_device::device_reset()
upd775x_device::device_reset();
// turn off any timer
if (m_timer)
m_timer->adjust(attotime::never);
if (m_drq)
{
m_drq = 0;
m_drqcallback(m_drq);
}
}
void upd7756_device::device_reset()
{
upd775x_device::device_reset();
m_drq = 0;
}
/************************************************************
@ -422,7 +402,7 @@ void upd775x_device::advance_state()
/* Start state: we begin here as soon as a sample is triggered */
case STATE_START:
m_req_sample = m_rom ? m_fifo_in : 0x10;
m_req_sample = m_md ? m_fifo_in : 0x10;
if (DEBUG_STATES) logerror("req_sample = %02X\n", m_req_sample);
/* 35+ cycles after we get here, the /DRQ goes low
@ -450,7 +430,7 @@ void upd775x_device::advance_state()
/* Last sample state: latch the last sample value and issue a request for the second byte */
/* The second byte read will be just a dummy */
case STATE_LAST_SAMPLE:
m_last_sample = m_rom ? m_rom[0] : m_fifo_in;
m_last_sample = m_md ? read_byte(0) : m_fifo_in;
if (DEBUG_STATES) logerror("last_sample = %02X, requesting dummy 1\n", m_last_sample);
m_drq = 1;
@ -473,7 +453,7 @@ void upd775x_device::advance_state()
/* Address MSB state: latch the MSB of the sample address and issue a request for the fourth byte */
/* The expected response will be the LSB of the sample address */
case STATE_ADDR_MSB:
m_offset = (m_rom ? m_rom[m_req_sample * 2 + 5] : m_fifo_in) << (8 + m_sample_offset_shift);
m_offset = (m_md ? read_byte(m_req_sample * 2 + 5) : m_fifo_in) << (8 + m_sample_offset_shift);
if (DEBUG_STATES) logerror("offset_hi = %02X, requesting offset_lo\n", m_offset >> (8 + m_sample_offset_shift));
m_drq = 1;
@ -485,9 +465,8 @@ void upd775x_device::advance_state()
/* Address LSB state: latch the LSB of the sample address and issue a request for the fifth byte */
/* The expected response will be just a dummy */
case STATE_ADDR_LSB:
m_offset |= (m_rom ? m_rom[m_req_sample * 2 + 6] : m_fifo_in) << m_sample_offset_shift;
m_offset |= (m_md ? read_byte(m_req_sample * 2 + 6) : m_fifo_in) << m_sample_offset_shift;
if (DEBUG_STATES) logerror("offset_lo = %02X, requesting dummy 2\n", (m_offset >> m_sample_offset_shift) & 0xff);
if (m_offset > m_rommask) logerror("uPD7759 offset %X > rommask %X\n",m_offset, m_rommask);
m_drq = 1;
/* 36 cycles later, we will latch this value and request another byte */
@ -517,7 +496,7 @@ void upd775x_device::advance_state()
m_repeat_count--;
m_offset = m_repeat_offset;
}
m_block_header = m_rom ? m_rom[m_offset++ & m_rommask] : m_fifo_in;
m_block_header = m_md ? read_byte(m_offset++) : m_fifo_in;
if (DEBUG_STATES) logerror("header (@%05X) = %02X, requesting next byte\n", m_offset, m_block_header);
m_drq = 1;
@ -560,7 +539,7 @@ void upd775x_device::advance_state()
/* Nibble count state: latch the number of nibbles to play and request another byte */
/* The expected response will be the first data byte */
case STATE_NIBBLE_COUNT:
m_nibbles_left = (m_rom ? m_rom[m_offset++ & m_rommask] : m_fifo_in) + 1;
m_nibbles_left = (m_md ? read_byte(m_offset++) : m_fifo_in) + 1;
if (DEBUG_STATES) logerror("nibble_count = %u, requesting next byte\n", (unsigned)m_nibbles_left);
m_drq = 1;
@ -572,7 +551,7 @@ void upd775x_device::advance_state()
/* MSN state: latch the data for this pair of samples and request another byte */
/* The expected response will be the next sample data or another header */
case STATE_NIBBLE_MSN:
m_adpcm_data = m_rom ? m_rom[m_offset++ & m_rommask] : m_fifo_in;
m_adpcm_data = m_md ? read_byte(m_offset++) : m_fifo_in;
update_adpcm(m_adpcm_data >> 4);
m_drq = 1;
@ -643,18 +622,6 @@ void upd7759_device::device_timer(emu_timer &timer, device_timer_id id, int para
}
}
/************************************************************
Sound startup
*************************************************************/
void upd775x_device::device_post_load()
{
if (m_rombase)
m_rom = m_rombase + m_romoffset;
}
/************************************************************
I/O handlers
@ -675,6 +642,11 @@ WRITE_LINE_MEMBER( upd775x_device::reset_w )
device_reset();
}
WRITE_LINE_MEMBER(upd7759_device::md_w)
{
m_md = state;
}
WRITE_LINE_MEMBER( upd7759_device::start_w )
{
/* update the start value */
@ -693,7 +665,7 @@ WRITE_LINE_MEMBER( upd7759_device::start_w )
m_state = STATE_START;
/* for slave mode, start the timer going */
if (m_timer)
if (!m_md)
m_timer->adjust(attotime::zero);
}
}
@ -718,7 +690,7 @@ WRITE_LINE_MEMBER( upd7756_device::start_w )
}
WRITE8_MEMBER( upd775x_device::port_w )
void upd775x_device::port_w(u8 data)
{
/* update the FIFO value */
m_fifo_in = data;
@ -732,13 +704,6 @@ READ_LINE_MEMBER( upd775x_device::busy_r )
}
void upd775x_device::set_bank_base(uint32_t base)
{
assert(m_rombase != nullptr);
m_rom = m_rombase + base;
m_romoffset = base;
}
//-------------------------------------------------
// sound_stream_update - handle a stream update
//-------------------------------------------------
@ -763,7 +728,7 @@ void upd775x_device::sound_stream_update(sound_stream &stream, stream_sample_t *
pos += step;
/* handle clocks, but only in standalone mode */
while (m_rom && pos >= FRAC_ONE)
while (m_md && pos >= FRAC_ONE)
{
int clocks_this_time = pos >> FRAC_BITS;
if (clocks_this_time > clocks_left)

View File

@ -13,16 +13,16 @@
software.
*/
class upd775x_device : public device_t, public device_sound_interface
class upd775x_device : public device_t,
public device_sound_interface,
public device_rom_interface
{
public:
enum : u32 { STANDARD_CLOCK = 640'000 };
void set_bank_base(offs_t base);
DECLARE_WRITE_LINE_MEMBER( reset_w );
DECLARE_READ_LINE_MEMBER( busy_r );
virtual DECLARE_WRITE8_MEMBER( port_w );
virtual void port_w(u8 data);
protected:
// chip states
@ -49,7 +49,8 @@ protected:
virtual void device_start() override;
virtual void device_clock_changed() override;
virtual void device_reset() override;
virtual void device_post_load() override;
virtual void rom_bank_updated() override;
// sound stream update overrides
virtual void sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples) override;
@ -95,10 +96,7 @@ protected:
int16_t m_sample; /* current sample value */
/* ROM access */
optional_region_ptr<uint8_t> m_rombase; /* pointer to ROM data or nullptr for slave mode */
uint8_t * m_rom; /* pointer to ROM data or nullptr for slave mode */
uint32_t m_romoffset; /* ROM offset to make save/restore easier */
uint32_t m_rommask; /* maximum address offset */
int m_md; /* High is stand alone, low is slave. */
};
class upd7759_device : public upd775x_device
@ -108,6 +106,7 @@ public:
upd7759_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock = STANDARD_CLOCK);
DECLARE_WRITE_LINE_MEMBER( md_w );
DECLARE_WRITE_LINE_MEMBER( start_w );
protected:
@ -131,6 +130,8 @@ class upd7756_device : public upd775x_device
public:
upd7756_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock = STANDARD_CLOCK);
virtual void device_reset() override;
DECLARE_WRITE_LINE_MEMBER( start_w );
protected:
@ -142,6 +143,9 @@ protected:
DECLARE_DEVICE_TYPE(UPD7759, upd7759_device)
DECLARE_DEVICE_TYPE(UPD7756, upd7756_device)
#define MCFG_UPD7759_MD(_md) \
downcast<upd7759_device &>(*device).md_w(_md);
#define MCFG_UPD7759_DRQ_CALLBACK(_write) \
downcast<upd7759_device &>(*device).set_drq_callback(DEVCB_##_write);

View File

@ -76,18 +76,15 @@ WRITE8_MEMBER(_88games_state::k88games_sh_irqtrigger_w)
WRITE8_MEMBER(_88games_state::speech_control_w)
{
m_speech_chip = (data & 4) ? 1 : 0;
upd7759_device *upd = m_speech_chip ? m_upd7759_2 : m_upd7759_1;
m_speech_chip = BIT(data, 2);
upd->reset_w(data & 2);
upd->start_w(data & 1);
m_upd7759[m_speech_chip]->reset_w(BIT(data, 1));
m_upd7759[m_speech_chip]->start_w(BIT(data, 0));
}
WRITE8_MEMBER(_88games_state::speech_msg_w)
{
upd7759_device *upd = m_speech_chip ? m_upd7759_2 : m_upd7759_1;
upd->port_w(space, 0, data);
m_upd7759[m_speech_chip]->port_w(data);
}
/* special handlers to combine 052109 & 051960 */

View File

@ -118,14 +118,14 @@ WRITE8_MEMBER(aerofgt_state::aerfboot_okim6295_banking_w)
WRITE8_MEMBER(aerofgt_state::karatblzbl_d7759_write_port_0_w)
{
m_upd7759->port_w(space, 0, data);
m_upd7759->port_w(data);
m_upd7759->start_w(0);
m_upd7759->start_w(1);
}
WRITE8_MEMBER(aerofgt_state::karatblzbl_d7759_reset_w)
{
m_upd7759->reset_w(data & 0x80);
m_upd7759->reset_w(BIT(data, 7));
}
template<int Layer>

View File

@ -1397,9 +1397,9 @@ READ8_MEMBER(bfcobra_state::upd_r)
WRITE8_MEMBER(bfcobra_state::upd_w)
{
m_upd7759->reset_w(data & 0x80);
m_upd7759->port_w(space, 0, data & 0x3f);
m_upd7759->start_w(data & 0x40 ? 0 : 1);
m_upd7759->reset_w(BIT(data, 7));
m_upd7759->port_w(data & 0x3f);
m_upd7759->start_w(!BIT(data, 6));
}
void bfcobra_state::m6809_prog_map(address_map &map)

View File

@ -617,13 +617,13 @@ READ8_MEMBER(bfm_sc1_state::triac_r)
WRITE8_MEMBER(bfm_sc1_state::nec_reset_w)
{
m_upd7759->start_w(0);
m_upd7759->reset_w(data);
m_upd7759->reset_w(data != 0);
}
#endif
/////////////////////////////////////////////////////////////////////////////////////
WRITE8_MEMBER(bfm_sc1_state::nec_latch_w)
{
m_upd7759->port_w (space, 0, data&0x3F); // setup sample
m_upd7759->port_w(data & 0x3f); // setup sample
m_upd7759->start_w(0);
m_upd7759->start_w(1); // start
}

View File

@ -796,7 +796,7 @@ WRITE8_MEMBER(bfm_sc2_state::volume_override_w)
WRITE8_MEMBER(bfm_sc2_state::nec_reset_w)
{
m_upd7759->start_w(0);
m_upd7759->reset_w(data);
m_upd7759->reset_w(data != 0);
}
///////////////////////////////////////////////////////////////////////////
@ -808,9 +808,9 @@ WRITE8_MEMBER(bfm_sc2_state::nec_latch_w)
if ( data & 0x80 ) bank |= 0x01;
if ( m_expansion_latch & 2 ) bank |= 0x02;
m_upd7759->set_bank_base(bank*0x20000);
m_upd7759->set_rom_bank(bank);
m_upd7759->port_w(space, 0, data&0x3F); // setup sample
m_upd7759->port_w(data & 0x3f); // setup sample
m_upd7759->start_w(0);
m_upd7759->start_w(1);
}

View File

@ -89,7 +89,7 @@ WRITE8_MEMBER(bladestl_state::bladestl_bankswitch_w)
WRITE8_MEMBER(bladestl_state::bladestl_port_B_w)
{
// bits 3-5 = ROM bank select
m_upd7759->set_bank_base(((data & 0x38) >> 3) * 0x20000);
m_upd7759->set_rom_bank((data & 0x38) >> 3);
// bit 2 = SSG-C rc filter enable
m_filter3->filter_rc_set_RC(filter_rc_device::LOWPASS, 1000, 2200, 1000, data & 0x04 ? CAP_N(150) : 0); /* YM2203-SSG-C */

View File

@ -74,8 +74,8 @@ WRITE8_MEMBER(homerun_state::homerun_control_w)
// d5: d7756 reset pin(?)
if (m_d7756 != nullptr)
{
m_d7756->reset_w(~data & 0x20);
m_d7756->start_w(~data & 0x10);
m_d7756->reset_w(!BIT(data, 5));
m_d7756->start_w(!BIT(data, 4));
}
if (m_samples != nullptr)
{
@ -100,7 +100,7 @@ WRITE8_MEMBER(homerun_state::homerun_d7756_sample_w)
m_sample = data;
if (m_d7756 != nullptr)
m_d7756->port_w(space, 0, data);
m_d7756->port_w(data);
}
void homerun_state::homerun_memmap(address_map &map)

View File

@ -469,8 +469,8 @@ WRITE16_MEMBER(jpmimpct_state::volume_w)
{
if (ACCESSING_BITS_0_7)
{
m_upd7759->set_bank_base(0x20000 * ((data >> 1) & 3));
m_upd7759->reset_w(data & 0x01);
m_upd7759->set_rom_bank((data >> 1) & 3);
m_upd7759->reset_w(BIT(data, 0));
}
}
@ -478,7 +478,7 @@ WRITE16_MEMBER(jpmimpct_state::upd7759_w)
{
if (ACCESSING_BITS_0_7)
{
m_upd7759->port_w(space, 0, data);
m_upd7759->port_w(data);
m_upd7759->start_w(0);
m_upd7759->start_w(1);
}

View File

@ -236,7 +236,7 @@ WRITE16_MEMBER(jpmsys5_state::jpm_upd7759_w)
{
case 0:
{
m_upd7759->port_w(space, 0, data & 0xff);
m_upd7759->port_w(data & 0xff);
m_upd7759->start_w(0);
m_upd7759->start_w(1);
break;
@ -251,8 +251,8 @@ WRITE16_MEMBER(jpmsys5_state::jpm_upd7759_w)
}
case 2:
{
m_upd7759->reset_w(~data & 0x04);
m_upd7759->set_bank_base((data & 2) ? 0x20000 : 0);
m_upd7759->reset_w(!BIT(data, 2));
m_upd7759->set_rom_bank(BIT(data, 1));
break;
}
default:

View File

@ -121,7 +121,7 @@ WRITE8_MEMBER(mainevt_state::mainevt_sh_bankswitch_w)
m_k007232->set_bank(bank_A, bank_B);
/* bits 4-5 select the UPD7759 bank */
m_upd7759->set_bank_base(((data >> 4) & 0x03) * 0x20000);
m_upd7759->set_rom_bank((data >> 4) & 0x03);
}
WRITE8_MEMBER(mainevt_state::dv_sh_bankswitch_w)

View File

@ -548,16 +548,16 @@ READ8_MEMBER(maygay1b_state::nec_reset_r)
WRITE8_MEMBER(maygay1b_state::nec_bank0_w)
{
m_upd7759->set_bank_base(0x00000);
m_upd7759->port_w(space, 0, data);
m_upd7759->set_rom_bank(0);
m_upd7759->port_w(data);
m_upd7759->start_w(0);
m_upd7759->start_w(1);
}
WRITE8_MEMBER(maygay1b_state::nec_bank1_w)
{
m_upd7759->set_bank_base(0x20000);
m_upd7759->port_w(space, 0, data);
m_upd7759->set_rom_bank(1);
m_upd7759->port_w(data);
m_upd7759->start_w(0);
m_upd7759->start_w(1);
}

View File

@ -47,14 +47,14 @@ void prehisle_state::prehisle_map(address_map &map)
WRITE8_MEMBER(prehisle_state::D7759_write_port_0_w)
{
m_upd7759->port_w(space, 0, data);
m_upd7759->port_w(data);
m_upd7759->start_w(0);
m_upd7759->start_w(1);
}
WRITE8_MEMBER(prehisle_state::D7759_upd_reset_w)
{
m_upd7759->reset_w(data & 0x80);
m_upd7759->reset_w(BIT(data, 7));
}
void prehisle_state::prehisle_sound_map(address_map &map)

View File

@ -183,13 +183,13 @@ WRITE8_MEMBER(rpunch_state::upd_control_w)
m_upd_rom_bank = data & 1;
memcpy(snd, snd + 0x20000 * (m_upd_rom_bank + 1), 0x20000);
}
m_upd7759->reset_w(data >> 7);
m_upd7759->reset_w(BIT(data, 7));
}
WRITE8_MEMBER(rpunch_state::upd_data_w)
{
m_upd7759->port_w(space, 0, data);
m_upd7759->port_w(data);
m_upd7759->start_w(0);
m_upd7759->start_w(1);
}

View File

@ -309,7 +309,7 @@ WRITE16_MEMBER(segac2_state::segac2_upd7759_w)
/* only works if we're accessing the low byte */
if (ACCESSING_BITS_0_7)
{
m_upd7759->port_w(space, 0, data & 0xff);
m_upd7759->port_w(data & 0xff);
m_upd7759->start_w(0);
m_upd7759->start_w(1);
}
@ -485,7 +485,7 @@ WRITE8_MEMBER(segac2_state::io_porth_w)
if (m_sound_banks > 1)
{
newbank = (data >> 2) & (m_sound_banks - 1);
m_upd7759->set_bank_base(newbank * 0x20000);
m_upd7759->set_rom_bank(newbank);
}
}

View File

@ -304,9 +304,9 @@ WRITE16_MEMBER(pico_base_state::pico_68k_io_write )
{
case 0x10/2:
if (mem_mask & 0xFF00)
m_sega_315_5641_pcm->port_w(space, 0, (data >> 8) & 0xFF);
m_sega_315_5641_pcm->port_w((data >> 8) & 0xFF);
if (mem_mask & 0x00FF)
m_sega_315_5641_pcm->port_w(space, 0, (data >> 0) & 0xFF);
m_sega_315_5641_pcm->port_w((data >> 0) & 0xFF);
break;
case 0x12/2: // guess
// Note about uPD7759 lines:
@ -318,17 +318,17 @@ WRITE16_MEMBER(pico_base_state::pico_68k_io_write )
// value 8000 resets the FIFO? (always used with low reset line)
// value 0800 maps to the uPD7759's reset line (0 = reset, 1 = normal)
// value 4000 maps to the uPD7759's start line (0->1 = start)
m_sega_315_5641_pcm->reset_w((data >> 8) & 0x08);
m_sega_315_5641_pcm->start_w((data >> 8) & 0x40);
if (data & 0x4000)
m_sega_315_5641_pcm->reset_w(BIT(data, 11));
m_sega_315_5641_pcm->start_w(BIT(data, 14));
if (BIT(data, 14))
{
// Somewhere between "Reset Off" and the first sample data,
// we need to send a few commands to make the sample stream work.
// Doing that when rising the "start" line seems to work fine.
m_sega_315_5641_pcm->port_w(space, 0, 0xFF); // "Last Sample" value (must be >= 0x10)
m_sega_315_5641_pcm->port_w(space, 0, 0x00); // Dummy 1
m_sega_315_5641_pcm->port_w(space, 0, 0x00); // Addr MSB
m_sega_315_5641_pcm->port_w(space, 0, 0x00); // Addr LSB
m_sega_315_5641_pcm->port_w(0xFF); // "Last Sample" value (must be >= 0x10)
m_sega_315_5641_pcm->port_w(0x00); // Dummy 1
m_sega_315_5641_pcm->port_w(0x00); // Addr MSB
m_sega_315_5641_pcm->port_w(0x00); // Addr LSB
}
}

View File

@ -1151,8 +1151,8 @@ WRITE8_MEMBER( segas16b_state::upd7759_control_w )
{
// it is important to write in this order: if the /START line goes low
// at the same time /RESET goes low, no sample should be started
m_upd7759->start_w(data & 0x80);
m_upd7759->reset_w(data & 0x40);
m_upd7759->start_w(BIT(data, 7));
m_upd7759->reset_w(BIT(data, 6));
// banking depends on the ROM board
int bankoffs = 0;
@ -3752,6 +3752,7 @@ MACHINE_CONFIG_START(segas16b_state::system16b)
MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 0.43)
MCFG_DEVICE_ADD("upd", UPD7759)
MCFG_UPD7759_MD(0)
MCFG_UPD7759_DRQ_CALLBACK(WRITELINE(*this, segas16b_state,upd7759_generate_nmi))
MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 0.48)
MACHINE_CONFIG_END

View File

@ -157,14 +157,14 @@ void snk68_state::sound_map(address_map &map)
WRITE8_MEMBER(snk68_state::D7759_write_port_0_w)
{
m_upd7759->port_w(space, 0, data);
m_upd7759->port_w(data);
m_upd7759->start_w(0);
m_upd7759->start_w(1);
}
WRITE8_MEMBER(snk68_state::D7759_upd_reset_w)
{
m_upd7759->reset_w(data & 0x80);
m_upd7759->reset_w(BIT(data, 7));
}
void snk68_state::sound_io_map(address_map &map)

View File

@ -487,7 +487,8 @@ WRITE8_MEMBER(segas1x_bootleg_state::upd7759_bank_w)//*
{
int offs, size = m_soundcpu_region->bytes() - 0x10000;
m_upd7759->reset_w(data & 0x40);
m_upd7759->start_w(BIT(data, 7));
m_upd7759->reset_w(BIT(data, 6));
offs = 0x10000 + (data * 0x4000) % size;
membank("bank1")->set_base(m_soundcpu_region->base() + offs);
}
@ -2076,7 +2077,7 @@ MACHINE_CONFIG_END
WRITE_LINE_MEMBER(segas1x_bootleg_state::sound_cause_nmi)
{
/* upd7759 callback */
if (state)
m_soundcpu->pulse_input_line(INPUT_LINE_NMI, attotime::zero);
}
@ -2095,6 +2096,7 @@ MACHINE_CONFIG_START(segas1x_bootleg_state::z80_ym2151_upd7759)
MCFG_SOUND_ROUTE(1, "rspeaker", 0.32)
MCFG_DEVICE_ADD("7759", UPD7759)
MCFG_UPD7759_MD(0)
MCFG_UPD7759_DRQ_CALLBACK(WRITELINE(*this, segas1x_bootleg_state,sound_cause_nmi))
MCFG_SOUND_ROUTE(ALL_OUTPUTS, "lspeaker", 0.48)
MCFG_SOUND_ROUTE(ALL_OUTPUTS, "rspeaker", 0.48)

View File

@ -64,6 +64,7 @@
#include <memory>
#include <utility>
#include <vector>
#include <queue>
#define AS_IO16 1
@ -192,19 +193,22 @@ public:
template<int Chip> DECLARE_READ8_MEMBER(ymf271_rom_r);
template<int Chip> DECLARE_READ8_MEMBER(ymz280b_rom_r);
template<int Chip> DECLARE_READ8_MEMBER(multipcm_rom_r);
template<int Chip> DECLARE_READ8_MEMBER(c140_rom_r);
template<int Chip> DECLARE_READ8_MEMBER(k053260_rom_r);
template<int Chip> DECLARE_READ8_MEMBER(upd7759_rom_r);
template<int Chip> DECLARE_READ8_MEMBER(okim6295_rom_r);
template<int Chip> DECLARE_READ8_MEMBER(k054539_rom_r);
template<int Chip> DECLARE_READ8_MEMBER(c352_rom_r);
template<int Chip> DECLARE_READ8_MEMBER(c140_rom_r);
template<int Chip> DECLARE_READ8_MEMBER(k053260_rom_r);
template<int Chip> DECLARE_READ8_MEMBER(qsound_rom_r);
template<int Chip> DECLARE_READ8_MEMBER(es5505_rom_r);
template<int Chip> DECLARE_READ8_MEMBER(ga20_rom_r);
template<int Chip> DECLARE_READ8_MEMBER(x1_010_rom_r);
template<int Chip> DECLARE_READ8_MEMBER(c352_rom_r);
template<int Chip> DECLARE_READ8_MEMBER(ga20_rom_r);
template<int Chip> DECLARE_WRITE8_MEMBER(multipcm_bank_hi_w);
template<int Chip> DECLARE_WRITE8_MEMBER(multipcm_bank_lo_w);
template<int Chip> DECLARE_WRITE8_MEMBER(upd7759_bank_w);
template<int Chip> DECLARE_WRITE8_MEMBER(okim6295_nmk112_enable_w);
template<int Chip> DECLARE_WRITE8_MEMBER(okim6295_bank_w);
template<int Chip> DECLARE_WRITE8_MEMBER(okim6295_nmk112_bank_w);
@ -345,6 +349,8 @@ private:
uint32_t m_multipcm_bank_r[2];
uint32_t m_multipcm_banked[2];
uint32_t m_upd7759_bank[2];
uint32_t m_okim6295_nmk112_enable[2];
uint32_t m_okim6295_bank[2];
uint32_t m_okim6295_nmk112_bank[2][4];
@ -372,6 +378,9 @@ public:
DECLARE_READ8_MEMBER(file_size_r);
DECLARE_INPUT_CHANGED_MEMBER(key_pressed);
template<int Chip> DECLARE_WRITE8_MEMBER(upd7759_reset_w);
template<int Chip> DECLARE_WRITE8_MEMBER(upd7759_data_w);
template<int Chip> DECLARE_WRITE_LINE_MEMBER(upd7759_drq_w);
template<int Chip> DECLARE_WRITE8_MEMBER(okim6295_clock_w);
template<int Chip> DECLARE_WRITE8_MEMBER(okim6295_pin7_w);
template<int Chip> DECLARE_WRITE8_MEMBER(scc_w);
@ -388,6 +397,7 @@ public:
template<int Chip> void rf5c164_map(address_map &map);
template<int Chip> void nescpu_map(address_map &map);
template<int Chip> void multipcm_map(address_map &map);
template<int Chip> void upd7759_map(address_map &map);
template<int Chip> void okim6295_map(address_map &map);
template<int Chip> void k054539_map(address_map &map);
template<int Chip> void c140_map(address_map &map);
@ -451,6 +461,11 @@ private:
uint32_t m_okim6295_pin7[2];
uint8_t m_scc_reg[2];
int m_upd7759_md[2];
int m_upd7759_reset[2];
int m_upd7759_drq[2];
std::queue<uint8_t> m_upd7759_slave_data[2];
uint32_t r32(int offset) const;
uint8_t r8(int offset) const;
};
@ -494,6 +509,7 @@ void vgmplay_device::device_reset()
m_paused = false;
m_ym2612_stream_offset = 0;
std::fill(std::begin(m_upd7759_bank), std::end(m_upd7759_bank), 0);
blocks_clear();
for (int i = 0; i < 0xff; i++)
@ -1147,7 +1163,12 @@ void vgmplay_device::execute_run()
case 0xb6:
{
pulse_act_led(LED_UPD7759);
// TODO: upd7759
uint8_t offset = m_file->read_byte(m_pc + 1);
if (offset & 0x80)
m_io->write_byte(A_UPD7759_1 + (offset & 0x7f), m_file->read_byte(m_pc + 2));
else
m_io->write_byte(A_UPD7759_0 + (offset & 0x7f), m_file->read_byte(m_pc + 2));
m_pc += 3;
break;
}
@ -2000,6 +2021,12 @@ READ8_MEMBER(vgmplay_device::multipcm_rom_r)
return rom_r(Chip, 0x89, offset);
}
template<int Chip>
READ8_MEMBER(vgmplay_device::upd7759_rom_r)
{
return rom_r(Chip, 0x8a, m_upd7759_bank[Chip] | offset);
}
template<int Chip>
READ8_MEMBER(vgmplay_device::okim6295_rom_r)
{
@ -2116,6 +2143,9 @@ vgmplay_state::vgmplay_state(const machine_config &mconfig, device_type type, co
, m_c352(*this, "c352.%d", 0)
, m_ga20(*this, "ga20.%d", 0)
{
std::fill(std::begin(m_upd7759_md), std::end(m_upd7759_md), 0);
std::fill(std::begin(m_upd7759_reset), std::end(m_upd7759_drq), 0);
std::fill(std::begin(m_upd7759_drq), std::end(m_upd7759_drq), 0);
}
uint32_t vgmplay_state::r32(int off) const
@ -2305,8 +2335,14 @@ QUICKLOAD_LOAD_MEMBER(vgmplay_state, load_file)
m_multipcm[0]->set_unscaled_clock(version >= 0x161 && header_size >= 0x8c ? r32(0x88) & ~0x40000000 : 0);
m_multipcm[1]->set_unscaled_clock(version >= 0x161 && header_size >= 0x8c && (r32(0x88) & 0x40000000) ? r32(0x88) & ~0x40000000 : 0);
m_upd7759[0]->set_unscaled_clock(version >= 0x161 && header_size >= 0x90 ? r32(0x8c) & ~0x40000000 : 0);
m_upd7759[1]->set_unscaled_clock(version >= 0x161 && header_size >= 0x90 && (r32(0x8c) & 0x40000000) ? r32(0x8c) & ~0x40000000 : 0);
m_upd7759[0]->set_unscaled_clock(version >= 0x161 && header_size >= 0x90 ? r32(0x8c) & ~0xc0000000 : 0);
m_upd7759[1]->set_unscaled_clock(version >= 0x161 && header_size >= 0x90 && (r32(0x8c) & 0x40000000) ? r32(0x8c) & ~0xc0000000 : 0);
m_upd7759_md[0] = r32(0x8c) & 0x80000000 ? 0 : 1;
m_upd7759_md[1] = r32(0x8c) & 0x80000000 ? 0 : 1;
m_upd7759[0]->md_w(m_upd7759_md[0]);
m_upd7759[1]->md_w(m_upd7759_md[1]);
m_okim6258[0]->set_unscaled_clock(version >= 0x161 && header_size >= 0x94 ? r32(0x90) & ~0x40000000 : 0);
m_okim6258[1]->set_unscaled_clock(version >= 0x161 && header_size >= 0x94 && (r32(0x90) & 0x40000000) ? r32(0x90) & ~0x40000000 : 0);
@ -2458,6 +2494,61 @@ WRITE8_MEMBER(vgmplay_device::multipcm_bank_lo_w)
m_multipcm_banked[Chip] = 1;
}
template<int Chip>
WRITE8_MEMBER(vgmplay_state::upd7759_reset_w)
{
int reset = data != 0;
m_upd7759[Chip]->reset_w(reset);
if (m_upd7759_reset[Chip] != reset)
{
m_upd7759_reset[Chip] = reset;
if (!reset)
std::queue<uint8_t>().swap(m_upd7759_slave_data[Chip]);
}
}
template<int Chip>
WRITE8_MEMBER(vgmplay_state::upd7759_data_w)
{
if (!m_upd7759_md[Chip] && !m_upd7759_drq[Chip])
{
m_upd7759_slave_data[Chip].push(data);
}
else
{
m_upd7759[Chip]->port_w(data);
m_upd7759_drq[Chip] = 0;
}
}
template<int Chip>
WRITE_LINE_MEMBER(vgmplay_state::upd7759_drq_w)
{
if (m_upd7759_drq[Chip] && !state)
logerror("upd7759.%d underflow\n", Chip);
m_upd7759_drq[Chip] = state;
if (!m_upd7759_md[Chip] && m_upd7759_drq[Chip] && !m_upd7759_slave_data[Chip].empty())
{
const uint8_t data(m_upd7759_slave_data[Chip].front());
m_upd7759_slave_data[Chip].pop();
m_upd7759[Chip]->port_w(data);
m_upd7759_drq[Chip] = 0;
}
}
template<int Chip>
WRITE8_MEMBER(vgmplay_device::upd7759_bank_w)
{
// TODO: upd7759 update stream
m_upd7759_bank[Chip] = data * 0x20000;
}
template<int Chip>
WRITE8_MEMBER(vgmplay_state::okim6295_clock_w)
{
@ -2635,11 +2726,24 @@ void vgmplay_state::soundchips_map(address_map &map)
map(vgmplay_device::A_MULTIPCM_1, vgmplay_device::A_MULTIPCM_1 + 3).w(m_multipcm[1], FUNC(multipcm_device::write));
map(vgmplay_device::A_MULTIPCM_1 + 4, vgmplay_device::A_MULTIPCM_1 + 7).w("vgmplay", FUNC(vgmplay_device::multipcm_bank_hi_w<1>));
map(vgmplay_device::A_MULTIPCM_1 + 8, vgmplay_device::A_MULTIPCM_1 + 11).w("vgmplay", FUNC(vgmplay_device::multipcm_bank_lo_w<1>));
// TODO: upd7759
map(vgmplay_device::A_OKIM6258_0 + 0, vgmplay_device::A_OKIM6295_0 + 0).w(m_okim6258[0], FUNC(okim6258_device::ctrl_w));
map(vgmplay_device::A_OKIM6258_0 + 1, vgmplay_device::A_OKIM6295_0 + 1).w(m_okim6258[0], FUNC(okim6258_device::data_w));
map(vgmplay_device::A_OKIM6258_1 + 0, vgmplay_device::A_OKIM6295_1 + 0).w(m_okim6258[1], FUNC(okim6258_device::ctrl_w));
map(vgmplay_device::A_OKIM6258_1 + 1, vgmplay_device::A_OKIM6295_1 + 1).w(m_okim6258[1], FUNC(okim6258_device::data_w));
map(vgmplay_device::A_UPD7759_0 + 0, vgmplay_device::A_UPD7759_0 + 0).w(FUNC(vgmplay_state::upd7759_reset_w<0>));
map(vgmplay_device::A_UPD7759_0 + 1, vgmplay_device::A_UPD7759_0 + 1).lw8("upd7759.0.start", [this](uint8_t data) {m_upd7759[0]->start_w(data != 0); });
map(vgmplay_device::A_UPD7759_0 + 2, vgmplay_device::A_UPD7759_0 + 2).w(FUNC(vgmplay_state::upd7759_data_w<0>));
map(vgmplay_device::A_UPD7759_0 + 3, vgmplay_device::A_UPD7759_0 + 3).w("vgmplay", FUNC(vgmplay_device::upd7759_bank_w<0>));
map(vgmplay_device::A_UPD7759_1 + 0, vgmplay_device::A_UPD7759_1 + 0).w(FUNC(vgmplay_state::upd7759_reset_w<1>));
map(vgmplay_device::A_UPD7759_1 + 1, vgmplay_device::A_UPD7759_1 + 1).lw8("upd7759.1.start", [this](uint8_t data) {m_upd7759[1]->start_w(data != 0); });
map(vgmplay_device::A_UPD7759_1 + 2, vgmplay_device::A_UPD7759_1 + 2).w(FUNC(vgmplay_state::upd7759_data_w<1>));
map(vgmplay_device::A_UPD7759_1 + 3, vgmplay_device::A_UPD7759_1 + 3).w("vgmplay", FUNC(vgmplay_device::upd7759_bank_w<1>));
map(vgmplay_device::A_OKIM6258_0 + 0x0, vgmplay_device::A_OKIM6258_0 + 0x0).w(m_okim6258[0], FUNC(okim6258_device::ctrl_w));
map(vgmplay_device::A_OKIM6258_0 + 0x1, vgmplay_device::A_OKIM6258_0 + 0x1).w(m_okim6258[0], FUNC(okim6258_device::data_w));
map(vgmplay_device::A_OKIM6258_0 + 0x2, vgmplay_device::A_OKIM6258_0 + 0x2).nopw(); // TODO: okim6258 pan
map(vgmplay_device::A_OKIM6258_0 + 0x8, vgmplay_device::A_OKIM6258_0 + 0xb).nopw(); // TODO: okim6258 clock
map(vgmplay_device::A_OKIM6258_0 + 0xc, vgmplay_device::A_OKIM6258_0 + 0xc).nopw(); // TODO: okim6258 divider
map(vgmplay_device::A_OKIM6258_1 + 0x0, vgmplay_device::A_OKIM6258_1 + 0x0).w(m_okim6258[1], FUNC(okim6258_device::ctrl_w));
map(vgmplay_device::A_OKIM6258_1 + 0x1, vgmplay_device::A_OKIM6258_1 + 0x1).w(m_okim6258[1], FUNC(okim6258_device::data_w));
map(vgmplay_device::A_OKIM6258_1 + 0x2, vgmplay_device::A_OKIM6258_1 + 0x2).nopw(); // TODO: okim6258 pan
map(vgmplay_device::A_OKIM6258_1 + 0x8, vgmplay_device::A_OKIM6258_1 + 0xb).nopw(); // TODO: okim6258 clock
map(vgmplay_device::A_OKIM6258_1 + 0xc, vgmplay_device::A_OKIM6258_1 + 0xc).nopw(); // TODO: okim6258 divider
map(vgmplay_device::A_OKIM6295_0, vgmplay_device::A_OKIM6295_0).w(m_okim6295[0], FUNC(okim6295_device::write));
map(vgmplay_device::A_OKIM6295_0 + 0x8, vgmplay_device::A_OKIM6295_0 + 0xb).w(FUNC(vgmplay_state::okim6295_clock_w<0>));
map(vgmplay_device::A_OKIM6295_0 + 0xc, vgmplay_device::A_OKIM6295_0 + 0xc).w(FUNC(vgmplay_state::okim6295_pin7_w<0>));
@ -2734,6 +2838,12 @@ void vgmplay_state::multipcm_map(address_map &map)
map(0, 0x3fffff).r("vgmplay", FUNC(vgmplay_device::multipcm_rom_r<Chip>));
}
template<int Chip>
void vgmplay_state::upd7759_map(address_map &map)
{
map(0, 0x1ffff).r("vgmplay", FUNC(vgmplay_device::upd7759_rom_r<Chip>));
}
template<int Chip>
void vgmplay_state::okim6295_map(address_map &map)
{
@ -3029,10 +3139,14 @@ MACHINE_CONFIG_START(vgmplay_state::vgmplay)
m_multipcm[1]->add_route(1, "rspeaker", 1);
UPD7759(config, m_upd7759[0], 0);
m_upd7759[0]->set_drq_callback(DEVCB_WRITELINE(*this, vgmplay_state, upd7759_drq_w<0>));
m_upd7759[0]->set_addrmap(0, &vgmplay_state::upd7759_map<0>);
m_upd7759[0]->add_route(ALL_OUTPUTS, "lspeaker", 1.0);
m_upd7759[0]->add_route(ALL_OUTPUTS, "rspeaker", 1.0);
UPD7759(config, m_upd7759[1], 0);
m_upd7759[1]->set_drq_callback(DEVCB_WRITELINE(*this, vgmplay_state, upd7759_drq_w<1>));
m_upd7759[1]->set_addrmap(0, &vgmplay_state::upd7759_map<1>);
m_upd7759[1]->add_route(ALL_OUTPUTS, "lspeaker", 1.0);
m_upd7759[1]->add_route(ALL_OUTPUTS, "rspeaker", 1.0);
@ -3211,8 +3325,6 @@ ROM_START( vgmplay )
ROM_REGION( 0x80000, "ym2610.1", ROMREGION_ERASE00 )
ROM_REGION( 0x80000, "y8950.0", ROMREGION_ERASE00 )
ROM_REGION( 0x80000, "y8950.1", ROMREGION_ERASE00 )
ROM_REGION( 0x80000, "upd7759.0", ROMREGION_ERASE00 )
ROM_REGION( 0x80000, "upd7759.1", ROMREGION_ERASE00 )
ROM_REGION( 0x80000, "scsp", ROMREGION_ERASE00 )
// TODO: split up 32x to remove dependencies
ROM_REGION( 0x4000, "master", ROMREGION_ERASE00 )

View File

@ -21,8 +21,7 @@ public:
m_k052109(*this, "k052109"),
m_k051960(*this, "k051960"),
m_k051316(*this, "k051316"),
m_upd7759_1(*this, "upd1"),
m_upd7759_2(*this, "upd2"),
m_upd7759(*this, "upd%d", 1),
m_bank0000(*this, "bank0000"),
m_bank1000(*this, "bank1000"),
m_ram(*this, "ram") { }
@ -42,8 +41,7 @@ private:
required_device<k052109_device> m_k052109;
required_device<k051960_device> m_k051960;
required_device<k051316_device> m_k051316;
required_device<upd7759_device> m_upd7759_1;
required_device<upd7759_device> m_upd7759_2;
required_device_array<upd7759_device, 2> m_upd7759;
/* memory banks */
required_memory_bank m_bank0000;

View File

@ -74,7 +74,7 @@
<element name="act_label_gameboy"><text string="Game Boy™" align="1"><color red="1.0" green="1.0" blue="1.0" /></text></element>
<element name="act_label_nesapu"><text string="NES™ APU" align="1"><color red="1.0" green="1.0" blue="1.0" /></text></element>
<element name="act_label_multipcm"><text string="YMW-258-F" align="1"><color red="1.0" green="1.0" blue="1.0" /></text></element>
<element name="act_label_upd7759"><text string="uPD7759" align="1"><color red="0.5" green="0.5" blue="0.5" /></text></element>
<element name="act_label_upd7759"><text string="uPD7759" align="1"><color red="1.0" green="1.0" blue="1.0" /></text></element>
<element name="act_label_okim6258"><text string="M6258" align="1"><color red="0.5" green="0.5" blue="0.5" /></text></element>
<element name="act_label_okim6295"><text string="M6295" align="1"><color red="1.0" green="1.0" blue="1.0" /></text></element>
<element name="act_label_k051649"><text string="K051649" align="1"><color red="1.0" green="1.0" blue="1.0" /></text></element>

View File

@ -485,8 +485,8 @@ WRITE8_MEMBER(micro3d_state::micro3d_sound_p3_w)
{
m_sound_port_latch[3] = data;
m_upd7759->set_bank_base((data & 0x4) ? 0x20000 : 0);
m_upd7759->reset_w((data & 0x10) ? 0 : 1);
m_upd7759->set_rom_bank(BIT(data, 2));
m_upd7759->reset_w(!BIT(data, 4));
}
READ8_MEMBER(micro3d_state::micro3d_sound_p1_r)
@ -501,7 +501,7 @@ READ8_MEMBER(micro3d_state::micro3d_sound_p3_r)
WRITE8_MEMBER(micro3d_state::micro3d_upd7759_w)
{
m_upd7759->port_w(space, 0, data);
m_upd7759->port_w(data);
m_upd7759->start_w(0);
m_upd7759->start_w(1);
}