mirror of
https://github.com/holub/mame
synced 2025-04-23 00:39:36 +03:00
Merge branch 'master' of https://github.com/mamedev/mame
This commit is contained in:
commit
a72fad3ef4
@ -627,6 +627,8 @@ if (SOUNDS["UPD7759"]~=null) then
|
||||
files {
|
||||
MAME_DIR .. "src/emu/sound/upd7759.c",
|
||||
MAME_DIR .. "src/emu/sound/upd7759.h",
|
||||
MAME_DIR .. "src/emu/sound/315-5641.c",
|
||||
MAME_DIR .. "src/emu/sound/315-5641.h",
|
||||
}
|
||||
end
|
||||
|
||||
|
70
src/emu/sound/315-5641.c
Normal file
70
src/emu/sound/315-5641.c
Normal file
@ -0,0 +1,70 @@
|
||||
/* Sega 315-5641 / D77591 / 9442CA010 */
|
||||
|
||||
#include "emu.h"
|
||||
#include "315-5641.h"
|
||||
|
||||
const device_type SEGA_315_5641_PCM = &device_creator<sega_315_5641_pcm_device>;
|
||||
|
||||
sega_315_5641_pcm_device::sega_315_5641_pcm_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
|
||||
: upd7759_device(mconfig, SEGA_315_5641_PCM, "315-5641 PCM", tag, owner, clock, "315-5641_pcm", __FILE__)
|
||||
{
|
||||
}
|
||||
|
||||
void sega_315_5641_pcm_device::device_start()
|
||||
{
|
||||
save_item(NAME(m_fifo_data), 0x40);
|
||||
save_item(NAME(m_fifo_read));
|
||||
save_item(NAME(m_fifo_write));
|
||||
|
||||
upd7759_device::device_start();
|
||||
}
|
||||
|
||||
void sega_315_5641_pcm_device::advance_state()
|
||||
{
|
||||
switch (m_state)
|
||||
{
|
||||
case STATE_DROP_DRQ:
|
||||
if (m_rombase == NULL)
|
||||
{
|
||||
// Slave Mode: get data from FIFO buffer
|
||||
UINT8 fiforead = (m_fifo_read + 1) & 0x3F;
|
||||
if (fiforead != m_fifo_write)
|
||||
{
|
||||
m_fifo_in = m_fifo_data[fiforead];
|
||||
m_fifo_read = fiforead;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
upd775x_device::advance_state();
|
||||
}
|
||||
|
||||
|
||||
WRITE8_MEMBER( sega_315_5641_pcm_device::port_w )
|
||||
{
|
||||
if (m_rombase != NULL)
|
||||
{
|
||||
/* update the FIFO value */
|
||||
m_fifo_in = data;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_fifo_data[m_fifo_write++] = data;
|
||||
m_fifo_write &= 0x3F;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
UINT8 sega_315_5641_pcm_device::get_fifo_space()
|
||||
{
|
||||
return (m_fifo_read - m_fifo_write) & 0x3F;
|
||||
}
|
||||
|
||||
void sega_315_5641_pcm_device::device_reset()
|
||||
{
|
||||
m_fifo_read = 0x3F;
|
||||
m_fifo_write = 0x00;
|
||||
|
||||
upd775x_device::device_reset();
|
||||
}
|
30
src/emu/sound/315-5641.h
Normal file
30
src/emu/sound/315-5641.h
Normal file
@ -0,0 +1,30 @@
|
||||
/* Sega 315-5641 / D77591 / 9442CA010 */
|
||||
|
||||
// this is the PICO sound chip, we are not sure if it's the same as a 7759 or not, it requires FIFO logic
|
||||
// which the 7759 does _not_ have but it is possible that is handled somewhere else on the PICO hardawre.
|
||||
|
||||
#include "upd7759.h"
|
||||
|
||||
|
||||
class sega_315_5641_pcm_device : public upd7759_device
|
||||
{
|
||||
public:
|
||||
sega_315_5641_pcm_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
|
||||
|
||||
UINT8 get_fifo_space();
|
||||
void advance_state();
|
||||
DECLARE_WRITE8_MEMBER(port_w);
|
||||
|
||||
UINT8 m_fifo_data[0x40];
|
||||
UINT8 m_fifo_read; // last read offset (will read in m_fifo_read+1)
|
||||
UINT8 m_fifo_write; // write offset
|
||||
|
||||
protected:
|
||||
// device-level overrides
|
||||
virtual void device_start();
|
||||
virtual void device_reset();
|
||||
|
||||
|
||||
};
|
||||
|
||||
extern const device_type SEGA_315_5641_PCM;
|
@ -143,23 +143,6 @@
|
||||
#define FRAC_ONE (1 << FRAC_BITS)
|
||||
#define FRAC_MASK (FRAC_ONE - 1)
|
||||
|
||||
/* chip states */
|
||||
enum
|
||||
{
|
||||
STATE_IDLE,
|
||||
STATE_DROP_DRQ,
|
||||
STATE_START,
|
||||
STATE_FIRST_REQ,
|
||||
STATE_LAST_SAMPLE,
|
||||
STATE_DUMMY1,
|
||||
STATE_ADDR_MSB,
|
||||
STATE_ADDR_LSB,
|
||||
STATE_DUMMY2,
|
||||
STATE_BLOCK_HEADER,
|
||||
STATE_NIBBLE_COUNT,
|
||||
STATE_NIBBLE_MSN,
|
||||
STATE_NIBBLE_LSN
|
||||
};
|
||||
|
||||
upd775x_device::upd775x_device(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, UINT32 clock, const char *shortname, const char *source)
|
||||
: device_t(mconfig, type, name, tag, owner, clock, shortname, source),
|
||||
@ -204,6 +187,14 @@ upd7759_device::upd7759_device(const machine_config &mconfig, const char *tag, d
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
upd7759_device::upd7759_device(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, UINT32 clock, const char *shortname, const char *source)
|
||||
: upd775x_device(mconfig, type, name, tag, owner, clock, shortname, source),
|
||||
m_timer(NULL)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
const device_type UPD7756 = &device_creator<upd7756_device>;
|
||||
|
||||
upd7756_device::upd7756_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
|
||||
|
@ -5,6 +5,23 @@
|
||||
#ifndef __UPD7759_H__
|
||||
#define __UPD7759_H__
|
||||
|
||||
/* chip states */
|
||||
enum
|
||||
{
|
||||
STATE_IDLE,
|
||||
STATE_DROP_DRQ,
|
||||
STATE_START,
|
||||
STATE_FIRST_REQ,
|
||||
STATE_LAST_SAMPLE,
|
||||
STATE_DUMMY1,
|
||||
STATE_ADDR_MSB,
|
||||
STATE_ADDR_LSB,
|
||||
STATE_DUMMY2,
|
||||
STATE_BLOCK_HEADER,
|
||||
STATE_NIBBLE_COUNT,
|
||||
STATE_NIBBLE_MSN,
|
||||
STATE_NIBBLE_LSN
|
||||
};
|
||||
|
||||
/* NEC uPD7759/55/56/P56/57/58 ADPCM Speech Processor */
|
||||
|
||||
@ -29,7 +46,7 @@ public:
|
||||
|
||||
DECLARE_WRITE_LINE_MEMBER( reset_w );
|
||||
DECLARE_READ_LINE_MEMBER( busy_r );
|
||||
DECLARE_WRITE8_MEMBER( port_w );
|
||||
virtual DECLARE_WRITE8_MEMBER( port_w );
|
||||
void postload();
|
||||
|
||||
protected:
|
||||
@ -86,13 +103,14 @@ protected:
|
||||
devcb_write_line m_drqcallback;
|
||||
|
||||
void update_adpcm(int data);
|
||||
void advance_state();
|
||||
virtual void advance_state();
|
||||
};
|
||||
|
||||
class upd7759_device : public upd775x_device
|
||||
{
|
||||
public:
|
||||
upd7759_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
|
||||
upd7759_device(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, UINT32 clock, const char *shortname, const char *source);
|
||||
|
||||
enum
|
||||
{
|
||||
|
@ -119,7 +119,7 @@ C = MB3514 / 9325 M36
|
||||
|
||||
#include "emu.h"
|
||||
#include "includes/md_cons.h"
|
||||
#include "sound/upd7759.h"
|
||||
#include "sound/315-5641.h"
|
||||
|
||||
|
||||
#define PICO_PENX 1
|
||||
@ -130,14 +130,14 @@ class pico_base_state : public md_cons_state
|
||||
public:
|
||||
pico_base_state(const machine_config &mconfig, device_type type, const char *tag)
|
||||
: md_cons_state(mconfig, type, tag),
|
||||
m_upd7759(*this, "7759"),
|
||||
m_sega_315_5641_pcm(*this, "315_5641"),
|
||||
m_io_page(*this, "PAGE"),
|
||||
m_io_pad(*this, "PAD"),
|
||||
m_io_penx(*this, "PENX"),
|
||||
m_io_peny(*this, "PENY")
|
||||
{ }
|
||||
|
||||
optional_device<upd7759_device> m_upd7759;
|
||||
optional_device<sega_315_5641_pcm_device> m_sega_315_5641_pcm;
|
||||
|
||||
required_ioport m_io_page;
|
||||
required_ioport m_io_pad;
|
||||
@ -251,14 +251,18 @@ READ16_MEMBER(pico_base_state::pico_68k_io_read )
|
||||
|
||||
case 8: // toy story 2 checks this for 0x3f (is that 'empty'?)
|
||||
/* Returns free bytes left in the PCM FIFO buffer */
|
||||
retdata = 0x3f;
|
||||
retdata = m_sega_315_5641_pcm->get_fifo_space();
|
||||
break;
|
||||
case 9:
|
||||
/*
|
||||
For reads, if bit 15 is cleared, it means PCM is 'busy' or
|
||||
something like that, as games sometimes wait for it to become 1.
|
||||
*/
|
||||
return (m_upd7759->busy_r()^1) << 15;
|
||||
// return (m_upd7759->busy_r()^1) << 15;
|
||||
// The BUSY bit stays 1 as long as some PCM sound is playing.
|
||||
// SMPS drivers check 800012 [byte] and clear the "prevent music PCM" byte when the READY bit gets set.
|
||||
// If this is done incorrectly, the voices in Sonic Gameworld (J) are muted by the music's PCM drums.
|
||||
return m_sega_315_5641_pcm->busy_r() << 15;
|
||||
|
||||
|
||||
case 7:
|
||||
@ -279,7 +283,7 @@ READ16_MEMBER(pico_base_state::pico_68k_io_read )
|
||||
WRITE_LINE_MEMBER(pico_base_state::sound_cause_irq)
|
||||
{
|
||||
// printf("sound irq\n");
|
||||
/* upd7759 callback */
|
||||
/* sega_315_5641_pcm callback */
|
||||
m_maincpu->set_input_line(3, HOLD_LINE);
|
||||
}
|
||||
|
||||
@ -289,14 +293,44 @@ WRITE16_MEMBER(pico_base_state::pico_68k_io_write )
|
||||
|
||||
switch (offset)
|
||||
{
|
||||
case 0x12/2: // guess
|
||||
m_upd7759->reset_w(0);
|
||||
m_upd7759->start_w(0);
|
||||
m_upd7759->reset_w(1);
|
||||
m_upd7759->start_w(1);
|
||||
case 0x10/2:
|
||||
if (mem_mask & 0xFF00)
|
||||
m_sega_315_5641_pcm->port_w(space, 0, (data >> 8) & 0xFF);
|
||||
if (mem_mask & 0x00FF)
|
||||
m_sega_315_5641_pcm->port_w(space, 0, (data >> 0) & 0xFF);
|
||||
break;
|
||||
case 0x12/2: // guess
|
||||
// Note about uPD7759 lines:
|
||||
// reset line: 1 - normal, 1->0 - reset chip, 0 - playback disabled
|
||||
// start line: 0->1 - start playback
|
||||
if (mem_mask & 0xFF00)
|
||||
{
|
||||
// I assume that:
|
||||
// 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)
|
||||
{
|
||||
// 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->reset_w(0);
|
||||
m_sega_315_5641_pcm->start_w(0);
|
||||
m_sega_315_5641_pcm->reset_w(1);
|
||||
m_sega_315_5641_pcm->start_w(1);
|
||||
|
||||
if (mem_mask&0x00ff) m_upd7759->port_w(space,0,data&0xff);
|
||||
if (mem_mask&0xff00) m_upd7759->port_w(space,0,(data>>8)&0xff);
|
||||
if (mem_mask&0x00ff) m_sega_315_5641_pcm->port_w(space,0,data&0xff);
|
||||
if (mem_mask&0xff00) m_sega_315_5641_pcm->port_w(space,0,(data>>8)&0xff);*/
|
||||
|
||||
break;
|
||||
}
|
||||
@ -356,6 +390,7 @@ static MACHINE_CONFIG_START( pico, pico_state )
|
||||
MCFG_CPU_PROGRAM_MAP(pico_mem)
|
||||
|
||||
MCFG_DEVICE_REMOVE("genesis_snd_z80")
|
||||
MCFG_DEVICE_REMOVE("ymsnd")
|
||||
|
||||
MCFG_MACHINE_START_OVERRIDE( pico_state, pico )
|
||||
MCFG_MACHINE_RESET_OVERRIDE( pico_base_state, ms_megadriv )
|
||||
@ -363,10 +398,10 @@ static MACHINE_CONFIG_START( pico, pico_state )
|
||||
MCFG_PICO_CARTRIDGE_ADD("picoslot", pico_cart, NULL)
|
||||
MCFG_SOFTWARE_LIST_ADD("cart_list","pico")
|
||||
|
||||
MCFG_SOUND_ADD("7759", UPD7759, UPD7759_STANDARD_CLOCK)
|
||||
MCFG_SOUND_ADD("315_5641", SEGA_315_5641_PCM, UPD7759_STANDARD_CLOCK*2)
|
||||
MCFG_UPD7759_DRQ_CALLBACK(WRITELINE(pico_state,sound_cause_irq))
|
||||
MCFG_SOUND_ROUTE(ALL_OUTPUTS, "lspeaker", 0.48)
|
||||
MCFG_SOUND_ROUTE(ALL_OUTPUTS, "rspeaker", 0.48)
|
||||
MCFG_SOUND_ROUTE(ALL_OUTPUTS, "lspeaker", 0.16)
|
||||
MCFG_SOUND_ROUTE(ALL_OUTPUTS, "rspeaker", 0.16)
|
||||
MACHINE_CONFIG_END
|
||||
|
||||
static MACHINE_CONFIG_START( picopal, pico_state )
|
||||
@ -376,6 +411,7 @@ static MACHINE_CONFIG_START( picopal, pico_state )
|
||||
MCFG_CPU_PROGRAM_MAP(pico_mem)
|
||||
|
||||
MCFG_DEVICE_REMOVE("genesis_snd_z80")
|
||||
MCFG_DEVICE_REMOVE("ymsnd")
|
||||
|
||||
MCFG_MACHINE_START_OVERRIDE( pico_state, pico )
|
||||
MCFG_MACHINE_RESET_OVERRIDE( pico_base_state, ms_megadriv )
|
||||
@ -383,10 +419,10 @@ static MACHINE_CONFIG_START( picopal, pico_state )
|
||||
MCFG_PICO_CARTRIDGE_ADD("picoslot", pico_cart, NULL)
|
||||
MCFG_SOFTWARE_LIST_ADD("cart_list","pico")
|
||||
|
||||
MCFG_SOUND_ADD("7759", UPD7759, UPD7759_STANDARD_CLOCK)
|
||||
MCFG_SOUND_ADD("315_5641", SEGA_315_5641_PCM, UPD7759_STANDARD_CLOCK*2)
|
||||
MCFG_UPD7759_DRQ_CALLBACK(WRITELINE(pico_state,sound_cause_irq))
|
||||
MCFG_SOUND_ROUTE(ALL_OUTPUTS, "lspeaker", 0.48)
|
||||
MCFG_SOUND_ROUTE(ALL_OUTPUTS, "rspeaker", 0.48)
|
||||
MCFG_SOUND_ROUTE(ALL_OUTPUTS, "lspeaker", 0.16)
|
||||
MCFG_SOUND_ROUTE(ALL_OUTPUTS, "rspeaker", 0.16)
|
||||
MACHINE_CONFIG_END
|
||||
|
||||
|
||||
@ -552,10 +588,10 @@ MACHINE_START_MEMBER(copera_state,copera)
|
||||
m_maincpu->space(AS_PROGRAM).install_readwrite_handler(0xa15000, 0xa150ff, read16_delegate(FUNC(base_md_cart_slot_device::read_a15),(base_md_cart_slot_device*)m_picocart), write16_delegate(FUNC(base_md_cart_slot_device::write_a15),(base_md_cart_slot_device*)m_picocart));
|
||||
m_maincpu->space(AS_PROGRAM).install_write_handler(0xa14000, 0xa14003, write16_delegate(FUNC(base_md_cart_slot_device::write_tmss_bank),(base_md_cart_slot_device*)m_picocart));
|
||||
|
||||
m_upd7759->reset_w(0);
|
||||
m_upd7759->start_w(0);
|
||||
m_upd7759->reset_w(1);
|
||||
m_upd7759->start_w(1);
|
||||
m_sega_315_5641_pcm->reset_w(0);
|
||||
m_sega_315_5641_pcm->start_w(0);
|
||||
m_sega_315_5641_pcm->reset_w(1);
|
||||
m_sega_315_5641_pcm->start_w(1);
|
||||
|
||||
}
|
||||
|
||||
@ -566,6 +602,7 @@ static MACHINE_CONFIG_START( copera, copera_state )
|
||||
MCFG_CPU_PROGRAM_MAP(copera_mem)
|
||||
|
||||
MCFG_DEVICE_REMOVE("genesis_snd_z80")
|
||||
MCFG_DEVICE_REMOVE("ymsnd")
|
||||
|
||||
MCFG_MACHINE_START_OVERRIDE( copera_state, copera )
|
||||
MCFG_MACHINE_RESET_OVERRIDE( pico_base_state, ms_megadriv )
|
||||
@ -573,10 +610,10 @@ static MACHINE_CONFIG_START( copera, copera_state )
|
||||
MCFG_COPERA_CARTRIDGE_ADD("coperaslot", copera_cart, NULL)
|
||||
MCFG_SOFTWARE_LIST_ADD("cart_list","copera")
|
||||
|
||||
MCFG_SOUND_ADD("7759", UPD7759, UPD7759_STANDARD_CLOCK)
|
||||
MCFG_SOUND_ADD("315_5641", SEGA_315_5641_PCM, UPD7759_STANDARD_CLOCK)
|
||||
MCFG_UPD7759_DRQ_CALLBACK(WRITELINE(copera_state,sound_cause_irq))
|
||||
MCFG_SOUND_ROUTE(ALL_OUTPUTS, "lspeaker", 0.48)
|
||||
MCFG_SOUND_ROUTE(ALL_OUTPUTS, "rspeaker", 0.48)
|
||||
MCFG_SOUND_ROUTE(ALL_OUTPUTS, "lspeaker", 0.16)
|
||||
MCFG_SOUND_ROUTE(ALL_OUTPUTS, "rspeaker", 0.16)
|
||||
MACHINE_CONFIG_END
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user