Split S-SMP and S-DSP implement in snes_snd.cpp (#6417)

* Split S-SMP and S-DSP implement in snes_snd.cpp
both convert memory handler into device_memory_interface, Internalize ROM region of S-SMP
s_smp.cpp : Use callback for S-DSP interface, Split internal and external memory space
snes.cpp : Convert WRAM into shared_ptr

* s_dsp.cpp : Reduce #define macros
This commit is contained in:
cam900 2020-04-04 21:59:50 +09:00 committed by GitHub
parent 7b060ff044
commit 6aef7adadd
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
16 changed files with 651 additions and 489 deletions

View File

@ -4269,6 +4269,18 @@ if (MACHINES["I3002"]~=null) then
}
end
---------------------------------------------------
--
--@src/devices/machine/s_smp.h,MACHINES["S_SMP"] = true
---------------------------------------------------
if (MACHINES["S_SMP"]~=null) then
files {
MAME_DIR .. "src/devices/machine/s_smp.cpp",
MAME_DIR .. "src/devices/machine/s_smp.h",
}
end
---------------------------------------------------
--
--@src/devices/machine/cxd1185.h,MACHINES["CXD1185"] = true

View File

@ -1566,6 +1566,18 @@ if (SOUNDS["VGMVIZ"]~=null) then
}
end
---------------------------------------------------
--
--@src/devices/sound/s_dsp.h,SOUNDS["S_DSP"] = true
---------------------------------------------------
if (SOUNDS["S_DSP"]~=null) then
files {
MAME_DIR .. "src/devices/sound/s_dsp.cpp",
MAME_DIR .. "src/devices/sound/s_dsp.h",
}
end
---------------------------------------------------
--
--@src/devices/sound/ks0164.h,SOUNDS["KS0164"] = true

View File

@ -279,6 +279,7 @@ SOUNDS["MM5837"] = true
--SOUNDS["DAVE"] = true
SOUNDS["LC7535"] = true
--SOUNDS["UPD934G"] = true
SOUNDS["S_DSP"] = true
SOUNDS["KS0164"] = true
--------------------------------------------------
@ -595,6 +596,7 @@ MACHINES["RSTBUF"] = true
MACHINES["RTC4543"] = true
MACHINES["RTC65271"] = true
MACHINES["RTC9701"] = true
MACHINES["S_SMP"] = true
MACHINES["S2636"] = true
MACHINES["S3520CF"] = true
MACHINES["S3C24XX"] = true
@ -3099,8 +3101,6 @@ files {
MAME_DIR .. "src/mame/video/n8080.cpp",
MAME_DIR .. "src/mame/drivers/nss.cpp",
MAME_DIR .. "src/mame/machine/snes.cpp",
MAME_DIR .. "src/mame/audio/snes_snd.cpp",
MAME_DIR .. "src/mame/audio/snes_snd.h",
MAME_DIR .. "src/mame/drivers/playch10.cpp",
MAME_DIR .. "src/mame/includes/playch10.h",
MAME_DIR .. "src/mame/machine/playch10.cpp",

View File

@ -302,6 +302,7 @@ SOUNDS["IOPSPU"] = true
SOUNDS["SWP00"] = true
SOUNDS["SWP20"] = true
SOUNDS["SWP30"] = true
SOUNDS["S_DSP"] = true
SOUNDS["ROLANDPCM"] = true
--------------------------------------------------
@ -617,6 +618,7 @@ MACHINES["RSTBUF"] = true
MACHINES["RTC4543"] = true
MACHINES["RTC65271"] = true
MACHINES["RTC9701"] = true
MACHINES["S_SMP"] = true
--MACHINES["S2636"] = true
MACHINES["S3520CF"] = true
MACHINES["S3C24XX"] = true
@ -1419,8 +1421,6 @@ files {
MAME_DIR .. "src/mame/machine/kabuki.h",
MAME_DIR .. "src/mame/video/pk8000.cpp",
MAME_DIR .. "src/mame/machine/snes.cpp",
MAME_DIR .. "src/mame/audio/snes_snd.cpp",
MAME_DIR .. "src/mame/audio/snes_snd.h",
MAME_DIR .. "src/mame/machine/n64.cpp",
MAME_DIR .. "src/mame/video/n64.cpp",
MAME_DIR .. "src/mame/video/n64types.h",

View File

@ -222,8 +222,13 @@ DEFINE_DEVICE_TYPE(SPC700, spc700_device, "spc700", "Sony SPC700")
spc700_device::spc700_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
: cpu_device(mconfig, SPC700, tag, owner, clock)
, m_program_config("program", ENDIANNESS_LITTLE, 8, 16, 0)
: spc700_device(mconfig, SPC700, tag, owner, clock)
{
}
spc700_device::spc700_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock, address_map_constructor internal_map)
: cpu_device(mconfig, type, tag, owner, clock)
, m_program_config("program", ENDIANNESS_LITTLE, 8, 16, 0, internal_map)
, m_a(0)
, m_x(0)
, m_y(0)

View File

@ -13,6 +13,9 @@ public:
spc700_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
protected:
// construction/destruction
spc700_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock, address_map_constructor internal_map = address_map_constructor());
// device-level overrides
virtual void device_start() override;
virtual void device_reset() override;
@ -36,9 +39,8 @@ protected:
// device_disasm_interface overrides
virtual std::unique_ptr<util::disasm_interface> create_disassembler() override;
private:
address_space_config m_program_config;
private:
uint32_t m_a; /* Accumulator */
uint32_t m_x; /* Index Register X */
uint32_t m_y; /* Index Register Y */

View File

@ -0,0 +1,321 @@
// license:LGPL-2.1+
// copyright-holders:R. Belmont, Brad Martin
/***************************************************************************
s_smp.cpp
File to handle the S-SMP emulation used in Nintendo Super NES.
By R. Belmont, adapted from OpenSPC 0.3.99 by Brad Martin with permission.
Thanks to Brad and also to Charles Bilyu? of SNeESe.
OpenSPC's license terms (the LGPL) follow:
---------------------------------------------------------------------------
Copyright Brad Martin.
OpenSPC is free software; you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
OpenSPC is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
***************************************************************************/
#include "emu.h"
#include "s_smp.h"
/***************************************************************************
CONSTANTS AND MACROS
***************************************************************************/
// Nintendo/Sony S-SMP internal ROM region
ROM_START( s_smp )
ROM_REGION( 0x40, "sound_ipl", 0 ) /* IPL ROM */
ROM_LOAD( "spc700.rom", 0, 0x40, CRC(44bb3a40) SHA1(97e352553e94242ae823547cd853eecda55c20f0) ) /* boot rom */
ROM_END
void s_smp_device::internal_map(address_map &map)
{
map(0x0000, 0x00ef).lrw8(
[this](offs_t offset) -> u8 { return data_read_byte(offset); }, "data_r",
[this](offs_t offset, u8 data) { data_write_byte(offset, data); }, "data_w");
map(0x00f0, 0x00ff).rw(FUNC(s_smp_device::io_r), FUNC(s_smp_device::io_w));
map(0x0100, 0xffff).lrw8(
[this](offs_t offset) -> u8 { return data_read_byte(offset + 0x100); }, "data_100_r",
[this](offs_t offset, u8 data) { data_write_byte(offset + 0x100, data); }, "data_100_w");
}
DEFINE_DEVICE_TYPE(S_SMP, s_smp_device, "s_smp", "Nintendo/Sony S-SMP")
s_smp_device::s_smp_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock)
: spc700_device(mconfig, S_SMP, tag, owner, clock, address_map_constructor(FUNC(s_smp_device::internal_map), this))
, m_data_config("data", ENDIANNESS_LITTLE, 8, 16)
, m_ipl_region(*this, "sound_ipl")
, m_dsp_io_r_cb(*this)
, m_dsp_io_w_cb(*this)
{
}
//-------------------------------------------------
// rom_region - return a pointer to the device's
// internal ROM region
//-------------------------------------------------
const tiny_rom_entry *s_smp_device::device_rom_region() const
{
return ROM_NAME( s_smp );
}
//-------------------------------------------------
// device_start - device-specific startup
//-------------------------------------------------
void s_smp_device::device_start()
{
m_dsp_io_r_cb.resolve_safe(0);
m_dsp_io_w_cb.resolve_safe();
m_data = &space(AS_DATA);
// Find our direct access
m_dcache = m_data->cache<0, 0, ENDIANNESS_LITTLE>();
m_tick_timer = timer_alloc(TIMER_TICK_ID);
save_item(NAME(m_timer_enabled));
save_item(NAME(m_subcounter));
save_item(NAME(m_counter));
save_item(NAME(m_port_in));
save_item(NAME(m_port_out));
save_item(NAME(m_test));
save_item(NAME(m_ctrl));
save_item(NAME(m_counter_reg));
save_item(NAME(m_TnDIV));
spc700_device::device_start();
}
//-------------------------------------------------
// device_reset - device-specific reset
//-------------------------------------------------
void s_smp_device::device_reset()
{
int i;
/* default to ROM visible */
m_ctrl = 0x80;
/* Sort out the ports */
for (i = 0; i < 4; i++)
{
m_port_in[i] = 0;
m_port_out[i] = 0;
}
for (i = 0; i < 3; i++)
{
m_timer_enabled[i] = false;
m_TnDIV[i] = 256;
m_counter[i] = 0;
m_subcounter[i] = 0;
}
attotime period = attotime::from_ticks(32, clock());
m_tick_timer->adjust(period, 0, period);
spc700_device::device_reset();
}
//-------------------------------------------------
// device_clock_changed - called if the clock
// changes
//-------------------------------------------------
void s_smp_device::device_clock_changed()
{
attotime period = attotime::from_ticks(32, clock());
m_tick_timer->adjust(period, 0, period);
}
//-------------------------------------------------
// memory_space_config - return a description of
// any address spaces owned by this device
//-------------------------------------------------
device_memory_interface::space_config_vector s_smp_device::memory_space_config() const
{
return space_config_vector{
std::make_pair(AS_PROGRAM, &m_program_config),
std::make_pair(AS_DATA, &m_data_config)
};
}
inline void s_smp_device::update_timer_tick(u8 which)
{
if (m_timer_enabled[which] == false)
return;
m_subcounter[which]++;
// if timer channel is 0 or 1 we update at 64000/8
if (m_subcounter[which] >= 8 || which == 2)
{
m_subcounter[which] = 0;
m_counter[which]++;
if (m_counter[which] >= m_TnDIV[which] ) // minus =
{
m_counter[which] = 0;
m_counter_reg[which]++;
m_counter_reg[which] &= 0x0f;
}
}
}
void s_smp_device::device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr)
{
if (id != TIMER_TICK_ID)
throw emu_fatalerror("Unknown id in s_smp_device::device_timer");
for (int ch = 0; ch < 3; ch++)
update_timer_tick(ch);
}
/*****************************************************************************
IMPLEMENTATION
*****************************************************************************/
/***************************
I/O for S-SMP
***************************/
u8 s_smp_device::io_r(offs_t offset)
{
switch (offset) /* Offset is from 0x00f0 */
{
case 0x0: //FIXME: Super Bomberman PBW reads from there, is it really write-only?
return 0;
case 0x1:
return 0; //Super Kick Boxing reads port 1 and wants it to be zero.
case 0x2: /* Register address */
case 0x3: /* Register data */
return m_dsp_io_r_cb(offset - 0x2);
case 0x4: /* Port 0 */
case 0x5: /* Port 1 */
case 0x6: /* Port 2 */
case 0x7: /* Port 3 */
// osd_printf_debug("%s SPC: rd %02x @ %d\n", machine().describe_context(), m_port_in[offset - 4], offset - 4);
return m_port_in[offset - 4];
case 0x8: //normal RAM, can be read even if the ram disabled flag ($f0 bit 1) is active
case 0x9:
return data_read_byte(0xf0 + offset);
case 0xa: /* Timer 0 */
case 0xb: /* Timer 1 */
case 0xc: /* Timer 2 */
break;
case 0xd: /* Counter 0 */
case 0xe: /* Counter 1 */
case 0xf: /* Counter 2 */
{
u8 value = m_counter_reg[offset - 0xd] & 0x0f;
if (!machine().side_effects_disabled())
m_counter_reg[offset - 0xd] = 0;
return value;
}
}
return 0;
}
void s_smp_device::io_w(offs_t offset, u8 data)
{
switch (offset) /* Offset is from 0x00f0 */
{
case 0x0:
m_test = data;
logerror("Warning: write to SOUND TEST register with data %02x!\n", data);
break;
case 0x1: /* Control */
m_ctrl = data;
for (int i = 0; i < 3; i++)
{
if (BIT(data, i) && m_timer_enabled[i] == false)
{
m_subcounter[i] = 0;
m_counter[i] = 0;
m_counter_reg[i] = 0;
}
m_timer_enabled[i] = BIT(data, i);
//m_timer[i]->enable(m_timer_enabled[i]);
}
if (BIT(data, 4))
{
m_port_in[0] = 0;
m_port_in[1] = 0;
}
if (BIT(data, 5))
{
m_port_in[2] = 0;
m_port_in[3] = 0;
}
/* bit 7 = IPL ROM enable */
break;
case 0x2: /* Register address */
case 0x3: /* Register data - 0x80-0xff is a read-only mirror of 0x00-0x7f */
m_dsp_io_w_cb(offset - 0x2, data);
break;
case 0x4: /* Port 0 */
case 0x5: /* Port 1 */
case 0x6: /* Port 2 */
case 0x7: /* Port 3 */
// osd_printf_debug("%s SPC: %02x to APU @ %d\n", machine().describe_context(), data, offset & 3);
m_port_out[offset - 4] = data;
// Unneeded, we already run at perfect_interleave
// machine().scheduler().boost_interleave(attotime::zero, attotime::from_usec(20));
break;
case 0xa: /* Timer 0 */
case 0xb: /* Timer 1 */
case 0xc: /* Timer 2 */
// if 0 then TnDiv is divided by 256, otherwise it's divided by 1 to 255
if (data == 0)
m_TnDIV[offset - 0xa] = 256;
else
m_TnDIV[offset - 0xa] = data;
break;
case 0xd: /* Counter 0 */
case 0xe: /* Counter 1 */
case 0xf: /* Counter 2 */
return;
}
data_write_byte(0xf0 + offset, data);
}
u8 s_smp_device::spc_port_out_r(offs_t offset)
{
assert(offset < 4);
return m_port_out[offset];
}
void s_smp_device::spc_port_in_w(offs_t offset, u8 data)
{
assert(offset < 4);
m_port_in[offset] = data;
}

View File

@ -0,0 +1,90 @@
// license:LGPL-2.1+
// copyright-holders:R. Belmont, Brad Martin
/*****************************************************************************
*
* Nintendo/Sony S-SMP emulation
*
****************************************************************************/
#ifndef MAME_MACHINE_S_SMP_H
#define MAME_MACHINE_S_SMP_H
#include "cpu/spc700/spc700.h"
/***************************************************************************
TYPE DEFINITIONS
***************************************************************************/
class s_smp_device : public spc700_device
{
public:
s_smp_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock);
auto dsp_io_read_callback() { return m_dsp_io_r_cb.bind(); }
auto dsp_io_write_callback() { return m_dsp_io_w_cb.bind(); }
u8 spc_port_out_r(offs_t offset);
void spc_port_in_w(offs_t offset, u8 data);
protected:
tiny_rom_entry const *device_rom_region() const override;
virtual void device_start() override;
virtual void device_reset() override;
virtual void device_clock_changed() override;
virtual void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr) override;
// device_memory_interface configuration
virtual space_config_vector memory_space_config() const override;
address_space_config m_data_config;
private:
address_space *m_data;
memory_access_cache<0, 0, ENDIANNESS_LITTLE> *m_dcache;
inline u8 data_read_byte(offs_t a)
{
/* IPL ROM enabled */
if (a >= 0xffc0 && m_ctrl & 0x80)
return m_ipl_region[a & 0x3f];
return m_dcache->read_byte(a);
}
inline void data_write_byte(offs_t a, u8 d) { m_data->write_byte(a, d); }
required_region_ptr<u8> m_ipl_region; /* SPC top 64 bytes */
u8 io_r(offs_t offset);
void io_w(offs_t offset, u8 data);
enum
{
TIMER_TICK_ID = 1
};
/* timers */
emu_timer *m_tick_timer;
bool m_timer_enabled[3];
u16 m_counter[3];
u8 m_subcounter[3];
inline void update_timer_tick(u8 which);
/* IO ports */
u8 m_port_in[4]; /* SPC input ports */
u8 m_port_out[4]; /* SPC output ports */
u16 m_TnDIV[3]; /**< Timer N Divider */
// registers
u8 m_test;
u8 m_ctrl;
u8 m_counter_reg[3];
devcb_read8 m_dsp_io_r_cb;
devcb_write8 m_dsp_io_w_cb;
void internal_map(address_map &map);
};
DECLARE_DEVICE_TYPE(S_SMP, s_smp_device)
#endif // MAME_MACHINE_S_SMP_H

View File

@ -2,9 +2,9 @@
// copyright-holders:R. Belmont, Brad Martin
/***************************************************************************
snes_snd.cpp
s_dsp.cpp
File to handle the sound emulation of the Nintendo Super NES.
File to handle the S-DSP emulation used in Nintendo Super NES.
By R. Belmont, adapted from OpenSPC 0.3.99 by Brad Martin with permission.
Thanks to Brad and also to Charles Bilyu? of SNeESe.
@ -28,7 +28,7 @@
***************************************************************************/
#include "emu.h"
#include "audio/snes_snd.h"
#include "s_dsp.h"
/***************************************************************************
CONSTANTS AND MACROS
@ -135,72 +135,42 @@ static const int ENVCNT[0x20]
};
/* Make reading the ADSR code easier */
#define SL( v ) (m_dsp_regs[((v) << 4) + 6] >> 5) /* Returns SUSTAIN level */
#define SR( v ) (m_dsp_regs[((v) << 4) + 6] & 0x1f) /* Returns SUSTAIN rate */
/* Handle endianness */
#define LEtoME16( x ) little_endianize_int16(x)
#define MEtoLE16( x ) little_endianize_int16(x)
ALLOW_SAVE_TYPE(snes_sound_device::env_state_t32);
ALLOW_SAVE_TYPE(s_dsp_device::env_state_t32);
DEFINE_DEVICE_TYPE(SNES_SOUND, snes_sound_device, "snes_sound", "SNES Custom DSP (SPC700)")
DEFINE_DEVICE_TYPE(S_DSP, s_dsp_device, "s_dsp", "Nintendo/Sony S-DSP")
snes_sound_device::snes_sound_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock)
: device_t(mconfig, SNES_SOUND, tag, owner, clock)
s_dsp_device::s_dsp_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock)
: device_t(mconfig, S_DSP, tag, owner, clock)
, device_sound_interface(mconfig, *this)
, device_memory_interface(mconfig, *this)
, m_data_config("data", ENDIANNESS_LITTLE, 8, 16)
{
}
//-------------------------------------------------
// device_start - device-specific startup
//-------------------------------------------------
void snes_sound_device::device_start()
void s_dsp_device::device_start()
{
m_data = &space(0);
// Find our direct access
m_cache = m_data->cache<0, 0, ENDIANNESS_LITTLE>();
m_channel = machine().sound().stream_alloc(*this, 0, 2, clock() / 64);
m_ram = make_unique_clear<u8[]>(SNES_SPCRAM_SIZE);
/* put IPL image at the top of RAM */
memcpy(m_ipl_region, machine().root_device().memregion("sound_ipl")->base(), 64);
m_tick_timer = timer_alloc(TIMER_TICK_ID);
state_register();
save_pointer(NAME(m_ram), SNES_SPCRAM_SIZE);
}
//-------------------------------------------------
// device_reset - device-specific reset
//-------------------------------------------------
void snes_sound_device::device_reset()
void s_dsp_device::device_reset()
{
int i;
/* default to ROM visible */
m_ram[0xf1] = 0x80;
/* Sort out the ports */
for (i = 0; i < 4; i++)
{
m_port_in[i] = 0;
m_port_out[i] = 0;
}
for (i = 0; i < 3; i++)
{
m_timer_enabled[i] = false;
m_TnDIV[i] = 256;
m_counter[i] = 0;
m_subcounter[i] = 0;
}
attotime period = attotime::from_ticks(32, clock());
m_tick_timer->adjust(period, 0, period);
dsp_reset();
}
@ -209,41 +179,19 @@ void snes_sound_device::device_reset()
// changes
//-------------------------------------------------
void snes_sound_device::device_clock_changed()
void s_dsp_device::device_clock_changed()
{
m_channel->set_sample_rate(clock() / 64);
attotime period = attotime::from_ticks(32, clock());
m_tick_timer->adjust(period, 0, period);
}
inline void snes_sound_device::update_timer_tick(u8 which)
//-------------------------------------------------
// memory_space_config - return a description of
// any address spaces owned by this device
//-------------------------------------------------
device_memory_interface::space_config_vector s_dsp_device::memory_space_config() const
{
if (m_timer_enabled[which] == false)
return;
m_subcounter[which]++;
// if timer channel is 0 or 1 we update at 64000/8
if (m_subcounter[which] >= 8 || which == 2)
{
m_subcounter[which] = 0;
m_counter[which]++;
if (m_counter[which] >= m_TnDIV[which] ) // minus =
{
m_counter[which] = 0;
m_ram[0xfd + which]++;
m_ram[0xfd + which] &= 0x0f;
}
}
}
void snes_sound_device::device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr)
{
if (id != TIMER_TICK_ID)
throw emu_fatalerror("Unknown id in snes_sound_device::device_timer");
for (int ch = 0; ch < 3; ch++)
update_timer_tick(ch);
return space_config_vector{ std::make_pair(0, &m_data_config) };
}
@ -258,7 +206,7 @@ void snes_sound_device::device_timer(emu_timer &timer, device_timer_id id, int p
Reset emulated DSP
-------------------------------------------------*/
void snes_sound_device::dsp_reset()
void s_dsp_device::dsp_reset()
{
#ifdef MAME_DEBUG
logerror("dsp_reset\n");
@ -295,19 +243,18 @@ void snes_sound_device::dsp_reset()
to mix audio into
-------------------------------------------------*/
void snes_sound_device::dsp_update( s16 *sound_ptr )
void s_dsp_device::dsp_update( s16 *sound_ptr )
{
int V;
int envx;
int m;
src_dir_type * sd;
int v;
int vl;
voice_state_type * vp;
int vr;
sd = (src_dir_type *) &m_ram[(int) m_dsp_regs[0x5d] << 8];
const u16 sd = m_dsp_regs[0x5d];
/* Check for reset */
if (m_dsp_regs[0x6c] & 0x80)
@ -355,9 +302,11 @@ void snes_sound_device::dsp_update( s16 *sound_ptr )
/* Voice was keyed on */
m_keys |= m;
m_keyed_on |= m;
#ifdef DBG_KEY
vl = m_dsp_regs[(v << 4) + 4];
vp->samp_id = *( u32 * )&sd[vl];
vp->mem_ptr = LEtoME16(sd[vl].vptr);
#endif
vp->samp_id = (vptr(sd, V) << 16) | lptr(sd, V);
vp->mem_ptr = vptr(sd, V);
#ifdef DBG_KEY
logerror("Keying on voice %d, samp=0x%04X (0x%02X)\n", v, vp->mem_ptr, vl);
@ -409,7 +358,7 @@ void snes_sound_device::dsp_update( s16 *sound_ptr )
continue;
}
vp->pitch = LEtoME16(*((u16 *)&m_dsp_regs[V + 2])) & 0x3fff;
vp->pitch = pitch(V);
#ifndef NO_PMOD
/* Pitch mod uses OUTX from last voice for this one. Luckily we haven't
@ -445,7 +394,7 @@ void snes_sound_device::dsp_update( s16 *sound_ptr )
m_dsp_regs[0x7c] |= m;
if (vp->end & 2)
{
vp->mem_ptr = LEtoME16(sd[m_dsp_regs[V + 4]].lptr);
vp->mem_ptr = lptr(sd, V);
#ifdef DBG_BRR
logerror("BRR looping to 0x%04X\n", vp->mem_ptr);
@ -472,7 +421,7 @@ void snes_sound_device::dsp_update( s16 *sound_ptr )
}
vp->header_cnt = 8;
vl = (u8)m_ram[vp->mem_ptr++];
vl = (u8)read_byte(vp->mem_ptr++);
vp->range = vl >> 4;
vp->end = vl & 3;
vp->filter = (vl & 12) >> 2;
@ -485,13 +434,13 @@ void snes_sound_device::dsp_update( s16 *sound_ptr )
if (vp->half == 0)
{
vp->half = 1;
outx = ((s8)m_ram[vp->mem_ptr]) >> 4;
outx = ((s8)read_byte(vp->mem_ptr)) >> 4;
}
else
{
vp->half = 0;
/* Funkiness to get 4-bit signed to carry through */
outx = (s8)(m_ram[vp->mem_ptr++] << 4);
outx = (s8)(read_byte(vp->mem_ptr++) << 4);
outx >>= 4;
vp->header_cnt--;
}
@ -644,8 +593,8 @@ void snes_sound_device::dsp_update( s16 *sound_ptr )
#endif
int echo_base = ((m_dsp_regs[0x6d] << 8) + m_echo_ptr) & 0xffff;
m_fir_lbuf[m_fir_ptr] = (s16)LEtoME16(*(u16 *)&m_ram[echo_base]);
m_fir_rbuf[m_fir_ptr] = (s16)LEtoME16(*(u16 *)&m_ram[echo_base + sizeof(s16)]);
m_fir_lbuf[m_fir_ptr] = (s16)read_word(echo_base);
m_fir_rbuf[m_fir_ptr] = (s16)read_word(echo_base + sizeof(s16));
/* Now, evaluate the FIR filter, and add the results into the final output. */
vl = m_fir_lbuf[m_fir_ptr] * (s8)m_dsp_regs[0x7f];
@ -709,8 +658,8 @@ void snes_sound_device::dsp_update( s16 *sound_ptr )
logerror("Echo: Writing %04X,%04X at location %04X\n", (u16)echol, (u16)echor, echo_base);
#endif
*(u16 *)&m_ram[echo_base] = MEtoLE16((u16)echol);
*(u16 *)&m_ram[echo_base + sizeof(s16)] = MEtoLE16((u16)echor);
write_word(echo_base, (u16)echol);
write_word(echo_base + sizeof(s16), (u16)echor);
}
m_echo_ptr += 2 * sizeof(s16);
@ -766,7 +715,7 @@ void snes_sound_device::dsp_update( s16 *sound_ptr )
to process envelope for.
-------------------------------------------------*/
int snes_sound_device::advance_envelope( int v )
int s_dsp_device::advance_envelope( int v )
{
int t;
@ -1010,11 +959,11 @@ int snes_sound_device::advance_envelope( int v )
}
/*-------------------------------------------------
spc700_set_volume - sets SPC700 volume level
set_volume - sets S-DSP volume level
for both speakers, used for fade in/out effects
-------------------------------------------------*/
void snes_sound_device::set_volume(int volume)
void s_dsp_device::set_volume(int volume)
{
m_channel->set_output_gain(0, volume / 100.0);
m_channel->set_output_gain(1, volume / 100.0);
@ -1025,183 +974,56 @@ void snes_sound_device::set_volume(int volume)
I/O for DSP
***************************/
u8 snes_sound_device::dsp_io_r(offs_t offset)
u8 s_dsp_device::dsp_io_r(offs_t offset)
{
m_channel->update();
#ifdef NO_ENVX
if (8 == (m_ram[0xf2] & 0x0f))
m_dsp_regs[m_ram[0xf2]] = 0;
if (!machine().side_effects_disabled())
if (8 == (m_dsp_addr & 0x0f))
m_dsp_regs[m_dsp_addr] = 0;
#endif
/* All reads simply return the contents of the addressed register. */
return m_dsp_regs[offset & 0x7f];
if (offset & 1)
return m_dsp_regs[m_dsp_addr & 0x7f];
return m_dsp_addr;
}
void snes_sound_device::dsp_io_w(offs_t offset, u8 data)
void s_dsp_device::dsp_io_w(offs_t offset, u8 data)
{
m_channel->update();
if (offset == 0x7c)
if (offset & 1)
{
/* Writes to register 0x7c (ENDX) clear ALL bits no matter which value is written */
m_dsp_regs[offset] = 0;
}
else
{
/* All other writes store the value in the addressed register as expected. */
m_dsp_regs[offset] = data;
}
}
/***************************
I/O for SPC700
***************************/
u8 snes_sound_device::spc_io_r(offs_t offset)
{
switch (offset) /* Offset is from 0x00f0 */
{
case 0x0: //FIXME: Super Bomberman PBW reads from there, is it really write-only?
return 0;
case 0x1:
return 0; //Super Kick Boxing reads port 1 and wants it to be zero.
case 0x2: /* Register address */
return m_ram[0xf2];
case 0x3: /* Register data */
return dsp_io_r(m_ram[0xf2]);
case 0x4: /* Port 0 */
case 0x5: /* Port 1 */
case 0x6: /* Port 2 */
case 0x7: /* Port 3 */
// osd_printf_debug("%s SPC: rd %02x @ %d\n", machine().describe_context(), m_port_in[offset - 4], offset - 4);
return m_port_in[offset - 4];
case 0x8: //normal RAM, can be read even if the ram disabled flag ($f0 bit 1) is active
case 0x9:
return m_ram[0xf0 + offset];
case 0xa: /* Timer 0 */
case 0xb: /* Timer 1 */
case 0xc: /* Timer 2 */
break;
case 0xd: /* Counter 0 */
case 0xe: /* Counter 1 */
case 0xf: /* Counter 2 */
if (!(m_dsp_addr & 0x80))
{
u8 value = m_ram[0xf0 + offset] & 0x0f;
m_ram[0xf0 + offset] = 0;
return value;
offset = m_dsp_addr & 0x7f;
if (offset == 0x7c)
{
/* Writes to register 0x7c (ENDX) clear ALL bits no matter which value is written */
m_dsp_regs[offset & 0x7f] = 0;
}
else
{
/* All other writes store the value in the addressed register as expected. */
m_dsp_regs[offset & 0x7f] = data;
}
}
}
return 0;
else
m_dsp_addr = data;
}
void snes_sound_device::spc_io_w(offs_t offset, u8 data)
{
switch (offset) /* Offset is from 0x00f0 */
{
case 0x0:
logerror("Warning: write to SOUND TEST register with data %02x!\n", data);
break;
case 0x1: /* Control */
for (int i = 0; i < 3; i++)
{
if (BIT(data, i) && m_timer_enabled[i] == false)
{
m_subcounter[i] = 0;
m_counter[i] = 0;
m_ram[0xfd + i] = 0;
}
m_timer_enabled[i] = BIT(data, i);
//m_timer[i]->enable(m_timer_enabled[i]);
}
if (BIT(data, 4))
{
m_port_in[0] = 0;
m_port_in[1] = 0;
}
if (BIT(data, 5))
{
m_port_in[2] = 0;
m_port_in[3] = 0;
}
/* bit 7 = IPL ROM enable */
break;
case 0x2: /* Register address */
break;
case 0x3: /* Register data - 0x80-0xff is a read-only mirror of 0x00-0x7f */
if (!(m_ram[0xf2] & 0x80))
dsp_io_w(m_ram[0xf2] & 0x7f, data);
break;
case 0x4: /* Port 0 */
case 0x5: /* Port 1 */
case 0x6: /* Port 2 */
case 0x7: /* Port 3 */
// osd_printf_debug("%s SPC: %02x to APU @ %d\n", machine().describe_context(), data, offset & 3);
m_port_out[offset - 4] = data;
// Unneeded, we already run at perfect_interleave
// machine().scheduler().boost_interleave(attotime::zero, attotime::from_usec(20));
break;
case 0xa: /* Timer 0 */
case 0xb: /* Timer 1 */
case 0xc: /* Timer 2 */
// if 0 then TnDiv is divided by 256, otherwise it's divided by 1 to 255
if (data == 0)
m_TnDIV[offset - 0xa] = 256;
else
m_TnDIV[offset - 0xa] = data;
break;
case 0xd: /* Counter 0 */
case 0xe: /* Counter 1 */
case 0xf: /* Counter 2 */
return;
}
m_ram[0xf0 + offset] = data;
}
u8 snes_sound_device::spc_ram_r(offs_t offset)
{
/* IPL ROM enabled */
if (offset >= 0xffc0 && m_ram[0xf1] & 0x80)
return m_ipl_region[offset & 0x3f];
return m_ram[offset];
}
void snes_sound_device::spc_ram_w(offs_t offset, u8 data)
{
m_ram[offset] = data;
}
u8 snes_sound_device::spc_port_out(offs_t offset)
{
assert(offset < 4);
return m_port_out[offset];
}
void snes_sound_device::spc_port_in(offs_t offset, u8 data)
{
assert(offset < 4);
m_port_in[offset] = data;
}
/*****************************************************************************
DEVICE INTERFACE
*****************************************************************************/
void snes_sound_device::state_register()
void s_dsp_device::state_register()
{
save_item(NAME(m_dsp_addr));
save_item(NAME(m_dsp_regs));
save_item(NAME(m_ipl_region));
save_item(NAME(m_keyed_on));
save_item(NAME(m_keys));
@ -1216,14 +1038,6 @@ void snes_sound_device::state_register()
save_item(NAME(m_echo_ptr));
#endif
save_item(NAME(m_timer_enabled));
save_item(NAME(m_subcounter));
save_item(NAME(m_counter));
save_item(NAME(m_port_in));
save_item(NAME(m_port_out));
save_item(NAME(m_TnDIV));
for (int v = 0; v < 8; v++)
{
save_item(NAME(m_voice_state[v].mem_ptr), v);
@ -1250,7 +1064,7 @@ void snes_sound_device::state_register()
// sound_stream_update - handle a stream update
//-------------------------------------------------
void snes_sound_device::sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples)
void s_dsp_device::sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples)
{
s16 mix[2];

View File

@ -2,33 +2,26 @@
// copyright-holders:R. Belmont, Brad Martin
/*****************************************************************************
*
* audio/snes_snd.h
* Nintendo/Sony S-DSP emulation
*
****************************************************************************/
#ifndef MAME_AUDIO_SNES_SND_H
#define MAME_AUDIO_SNES_SND_H
#ifndef MAME_SOUND_S_DSP_H
#define MAME_SOUND_S_DSP_H
/***************************************************************************
TYPE DEFINITIONS
***************************************************************************/
class snes_sound_device : public device_t, public device_sound_interface
class s_dsp_device : public device_t, public device_sound_interface, public device_memory_interface
{
public:
snes_sound_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock);
s_dsp_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock);
void set_volume(int volume);
u8 spc_io_r(offs_t offset);
u8 spc_ram_r(offs_t offset);
u8 spc_port_out(offs_t offset);
void spc_io_w(offs_t offset, u8 data);
void spc_ram_w(offs_t offset, u8 data);
void spc_port_in(offs_t offset, u8 data);
// u8 *spc_get_ram() { return m_ram; }
u8 dsp_io_r(offs_t offset);
void dsp_io_w(offs_t offset, u8 data);
protected:
// device-level overrides
@ -38,9 +31,20 @@ protected:
// sound stream update overrides
virtual void sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples) override;
virtual void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr) override;
// device_memory_interface configuration
virtual space_config_vector memory_space_config() const override;
address_space_config m_data_config;
private:
address_space *m_data;
memory_access_cache<0, 0, ENDIANNESS_LITTLE> *m_cache;
inline u8 read_byte(offs_t a) { return m_cache->read_byte(a); }
inline u16 read_word(offs_t a) { return read_byte(a) | (read_byte(a + 1) << 8); }
inline void write_byte(offs_t a, u8 d) { m_data->write_byte(a, d); }
inline void write_word(offs_t a, u16 d) { write_byte(a, d & 0xff); write_byte(a + 1, (d >> 8) & 0xff); }
enum class env_state_t32 : u8
{
ATTACK,
@ -49,8 +53,6 @@ private:
RELEASE
};
static constexpr unsigned SNES_SPCRAM_SIZE = 0x10000;
struct voice_state_type /* Voice state type */
{
u16 mem_ptr; /* Sample data memory pointer */
@ -72,25 +74,23 @@ private:
s16 sampbuf[4]; /* Buffer for Gaussian interp */
};
struct src_dir_type /* Source directory entry */
{
u16 vptr; /* Ptr to start of sample data */
u16 lptr; /* Loop pointer in sample data */
};
inline u16 vptr(u8 sd, u8 v) { return read_word((sd << 8) + (m_dsp_regs[v + 4] << 2)); } /* Ptr to start of sample data */
inline u16 lptr(u8 sd, u8 v) { return read_word((sd << 8) + (m_dsp_regs[v + 4] << 2) + 2); } /* Loop pointer in sample data */
inline u16 pitch(u8 v) { (m_dsp_regs[v + 2] | (m_dsp_regs[v + 3] << 8)) & 0x3fff; }
/* Make reading the ADSR code easier */
inline u8 SL(u8 v) { return m_dsp_regs[(v << 4) + 6] >> 5; } /* Returns SUSTAIN level */
inline u8 SR(u8 v) { return m_dsp_regs[(v << 4) + 6] & 0x1f; } /* Returns SUSTAIN rate */
u8 dsp_io_r(offs_t offset);
void dsp_io_w(offs_t offset, u8 data);
// TIMER_CALLBACK_MEMBER(spc_timer);
void dsp_reset();
void dsp_update(s16 *sound_ptr);
int advance_envelope(int v);
void state_register();
// internal state
std::unique_ptr<u8[]> m_ram;
sound_stream *m_channel;
u8 m_dsp_addr;
u8 m_dsp_regs[256]; /* DSP registers */
u8 m_ipl_region[64]; /* SPC top 64 bytes */
int m_keyed_on;
int m_keys; /* 8-bits for 8 voices */
@ -108,25 +108,9 @@ private:
int m_echo_ptr;
#endif
enum
{
TIMER_TICK_ID = 1
};
/* timers */
emu_timer *m_tick_timer;
bool m_timer_enabled[3];
u16 m_counter[3];
u8 m_subcounter[3];
inline void update_timer_tick(u8 which);
/* IO ports */
u8 m_port_in[4]; /* SPC input ports */
u8 m_port_out[4]; /* SPC output ports */
u16 m_TnDIV[3]; /**< Timer N Divider */
};
DECLARE_DEVICE_TYPE(SNES_SOUND, snes_sound_device)
DECLARE_DEVICE_TYPE(S_DSP, s_dsp_device)
#endif // MAME_AUDIO_SNES_SND_H
#endif // MAME_SOUND_S_DSP_H

View File

@ -353,12 +353,10 @@ private:
virtual void machine_start() override;
virtual void machine_reset() override;
DECLARE_WRITE_LINE_MEMBER(nss_vblank_irq);
DECLARE_READ8_MEMBER(spc_ram_100_r);
DECLARE_WRITE8_MEMBER(spc_ram_100_w);
void bios_io_map(address_map &map);
void bios_map(address_map &map);
void snes_map(address_map &map);
void spc_mem(address_map &map);
void spc_map(address_map &map);
};
@ -374,25 +372,13 @@ uint32_t nss_state::screen_update( screen_device &screen, bitmap_rgb32 &bitmap,
void nss_state::snes_map(address_map &map)
{
map(0x000000, 0x7dffff).rw(FUNC(nss_state::snes_r_bank1), FUNC(nss_state::snes_w_bank1));
map(0x7e0000, 0x7fffff).ram(); /* 8KB Low RAM, 24KB High RAM, 96KB Expanded RAM */
map(0x7e0000, 0x7fffff).ram().share("wram"); /* 8KB Low RAM, 24KB High RAM, 96KB Expanded RAM */
map(0x800000, 0xffffff).rw(FUNC(nss_state::snes_r_bank2), FUNC(nss_state::snes_w_bank2)); /* Mirror and ROM */
}
READ8_MEMBER(nss_state::spc_ram_100_r)
void nss_state::spc_map(address_map &map)
{
return m_spc700->spc_ram_r(offset + 0x100);
}
WRITE8_MEMBER(nss_state::spc_ram_100_w)
{
m_spc700->spc_ram_w(offset + 0x100, data);
}
void nss_state::spc_mem(address_map &map)
{
map(0x0000, 0x00ef).rw(m_spc700, FUNC(snes_sound_device::spc_ram_r), FUNC(snes_sound_device::spc_ram_w)); /* lower 32k ram */
map(0x00f0, 0x00ff).rw(m_spc700, FUNC(snes_sound_device::spc_io_r), FUNC(snes_sound_device::spc_io_w)); /* spc io */
map(0x0100, 0xffff).rw(FUNC(nss_state::spc_ram_100_r), FUNC(nss_state::spc_ram_100_w));
map(0x0000, 0xffff).ram().share("aram");
}
/* NSS specific */
@ -577,7 +563,7 @@ WRITE8_MEMBER(nss_state::port_01_w)
---- ---x Maybe SNES CPU/PPU reset? (0=Reset, 1=Run)
*/
m_input_disabled = BIT(data, 7) ^ 1;
m_spc700->set_volume((data & 0x20) ? 0.0 : 100.0);
m_s_dsp->set_volume((data & 0x20) ? 0.0 : 100.0);
m_cart_sel = (data & 0xc) >> 2;
@ -587,7 +573,7 @@ WRITE8_MEMBER(nss_state::port_01_w)
m_soundcpu->set_input_line(INPUT_LINE_RESET, (data & 1) ? CLEAR_LINE : ASSERT_LINE);
/* also reset the device */
if (!(data & 1))
m_spc700->reset();
m_s_dsp->reset();
}
WRITE8_MEMBER(nss_state::port_02_w)
@ -839,8 +825,10 @@ void nss_state::nss(machine_config &config)
m_maincpu->set_addrmap(AS_PROGRAM, &nss_state::snes_map);
// runs at 24.576 MHz / 12 = 2.048 MHz
SPC700(config, m_soundcpu, XTAL(24'576'000) / 12);
m_soundcpu->set_addrmap(AS_PROGRAM, &nss_state::spc_mem);
S_SMP(config, m_soundcpu, XTAL(24'576'000) / 12);
m_soundcpu->set_addrmap(AS_DATA, &nss_state::spc_map);
m_soundcpu->dsp_io_read_callback().set(m_s_dsp, FUNC(s_dsp_device::dsp_io_r));
m_soundcpu->dsp_io_write_callback().set(m_s_dsp, FUNC(s_dsp_device::dsp_io_w));
config.set_perfect_quantum(m_maincpu);
@ -857,9 +845,11 @@ void nss_state::nss(machine_config &config)
/* sound hardware */
SPEAKER(config, "lspeaker").front_left();
SPEAKER(config, "rspeaker").front_right();
SNES_SOUND(config, m_spc700, XTAL(24'576'000) / 12);
m_spc700->add_route(0, "lspeaker", 1.00);
m_spc700->add_route(1, "rspeaker", 1.00);
S_DSP(config, m_s_dsp, XTAL(24'576'000) / 12);
m_s_dsp->set_addrmap(0, &nss_state::spc_map);
m_s_dsp->add_route(0, "lspeaker", 1.00);
m_s_dsp->add_route(1, "rspeaker", 1.00);
/* video hardware */
/* TODO: the screen should actually superimpose, but for the time being let's just separate outputs */
@ -892,8 +882,6 @@ void nss_state::nss(machine_config &config)
***************************************************************************/
#define NSS_BIOS \
ROM_REGION(0x100, "sound_ipl", 0) /* IPL ROM */ \
ROM_LOAD("spc700.rom", 0, 0x40, CRC(44bb3a40) SHA1(97e352553e94242ae823547cd853eecda55c20f0) ) \
ROM_REGION(0x8000, "bios", 0) /* Bios CPU */ \
ROM_SYSTEM_BIOS( 0, "single", "Nintendo Super System (Single Cart BIOS)" ) \
ROMX_LOAD("nss-ic14.02.ic14", 0x00000, 0x8000, CRC(e06cb58f) SHA1(62f507e91a2797919a78d627af53f029c7d81477), ROM_BIOS(0) ) /* bios */ \

View File

@ -155,12 +155,10 @@ private:
DECLARE_WRITE8_MEMBER( snes_map_1_w );
virtual void machine_start() override;
virtual void machine_reset() override;
DECLARE_READ8_MEMBER(spc_ram_100_r);
DECLARE_WRITE8_MEMBER(spc_ram_100_w);
void sfcbox_io(address_map &map);
void sfcbox_map(address_map &map);
void snes_map(address_map &map);
void spc_mem(address_map &map);
void spc_map(address_map &map);
};
uint32_t sfcbox_state::screen_update( screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect )
@ -172,25 +170,13 @@ uint32_t sfcbox_state::screen_update( screen_device &screen, bitmap_rgb32 &bitma
void sfcbox_state::snes_map(address_map &map)
{
map(0x000000, 0x7dffff).rw(FUNC(sfcbox_state::snes_r_bank1), FUNC(sfcbox_state::snes_w_bank1));
map(0x7e0000, 0x7fffff).ram(); /* 8KB Low RAM, 24KB High RAM, 96KB Expanded RAM */
map(0x7e0000, 0x7fffff).ram().share("wram"); /* 8KB Low RAM, 24KB High RAM, 96KB Expanded RAM */
map(0x800000, 0xffffff).rw(FUNC(sfcbox_state::snes_r_bank2), FUNC(sfcbox_state::snes_w_bank2)); /* Mirror and ROM */
}
READ8_MEMBER(sfcbox_state::spc_ram_100_r)
void sfcbox_state::spc_map(address_map &map)
{
return m_spc700->spc_ram_r(offset + 0x100);
}
WRITE8_MEMBER(sfcbox_state::spc_ram_100_w)
{
m_spc700->spc_ram_w(offset + 0x100, data);
}
void sfcbox_state::spc_mem(address_map &map)
{
map(0x0000, 0x00ef).rw(m_spc700, FUNC(snes_sound_device::spc_ram_r), FUNC(snes_sound_device::spc_ram_w)); /* lower 32k ram */
map(0x00f0, 0x00ff).rw(m_spc700, FUNC(snes_sound_device::spc_io_r), FUNC(snes_sound_device::spc_io_w)); /* spc io */
map(0x0100, 0xffff).rw(FUNC(sfcbox_state::spc_ram_100_r), FUNC(sfcbox_state::spc_ram_100_w));
map(0x0000, 0xffff).ram().share("aram");
}
void sfcbox_state::sfcbox_map(address_map &map)
@ -463,8 +449,10 @@ void sfcbox_state::sfcbox(machine_config &config)
m_maincpu->set_addrmap(AS_PROGRAM, &sfcbox_state::snes_map);
// runs at 24.576 MHz / 12 = 2.048 MHz
SPC700(config, m_soundcpu, XTAL(24'576'000) / 12);
m_soundcpu->set_addrmap(AS_PROGRAM, &sfcbox_state::spc_mem);
S_SMP(config, m_soundcpu, XTAL(24'576'000) / 12);
m_soundcpu->set_addrmap(AS_DATA, &sfcbox_state::spc_map);
m_soundcpu->dsp_io_read_callback().set(m_s_dsp, FUNC(s_dsp_device::dsp_io_r));
m_soundcpu->dsp_io_write_callback().set(m_s_dsp, FUNC(s_dsp_device::dsp_io_w));
config.set_perfect_quantum(m_maincpu);
@ -479,9 +467,11 @@ void sfcbox_state::sfcbox(machine_config &config)
/* sound hardware */
SPEAKER(config, "lspeaker").front_left();
SPEAKER(config, "rspeaker").front_right();
SNES_SOUND(config, m_spc700, XTAL(24'576'000) / 12);
m_spc700->add_route(0, "lspeaker", 1.00);
m_spc700->add_route(1, "rspeaker", 1.00);
S_DSP(config, m_s_dsp, XTAL(24'576'000) / 12);
m_s_dsp->set_addrmap(0, &sfcbox_state::spc_map);
m_s_dsp->add_route(0, "lspeaker", 1.00);
m_s_dsp->add_route(1, "rspeaker", 1.00);
/* video hardware */
/* TODO: the screen should actually superimpose, but for the time being let's just separate outputs */
@ -516,8 +506,6 @@ void sfcbox_state::sfcbox(machine_config &config)
#define SFCBOX_BIOS \
ROM_REGION( 0x1000000, "maincpu", ROMREGION_ERASE00 ) \
ROM_REGION( 0x100, "sound_ipl", 0 ) \
ROM_LOAD( "spc700.rom", 0x00, 0x40, CRC(44bb3a40) SHA1(97e352553e94242ae823547cd853eecda55c20f0) ) \
ROM_REGION( 0x10000, "krom", 0 ) \
ROM_LOAD( "krom1.ic1", 0x00000, 0x10000, CRC(c9010002) SHA1(f4c74086a83b728b1c1af3a021a60efa80eff5a4) ) \
ROM_REGION( 0x100000, "user3", 0 ) \

View File

@ -28,9 +28,7 @@
#include "emu.h"
#include "includes/snes.h"
#include "audio/snes_snd.h"
#include "cpu/spc700/spc700.h"
#include "machine/snescx4.h"
#include "bus/snes/snes_slot.h"
@ -92,9 +90,6 @@ private:
DECLARE_READ8_MEMBER( pfest94_lo_r );
DECLARE_WRITE8_MEMBER( pfest94_lo_w );
DECLARE_READ8_MEMBER( spc_ram_100_r );
DECLARE_WRITE8_MEMBER( spc_ram_100_w );
// input related
SNESCTRL_ONSCREEN_CB(onscreen_cb);
SNESCTRL_GUNLATCH_CB(gun_latch_cb);
@ -122,18 +117,6 @@ private:
*
*************************************/
// SPC access
READ8_MEMBER(snes_console_state::spc_ram_100_r )
{
return m_spc700->spc_ram_r(offset + 0x100);
}
WRITE8_MEMBER(snes_console_state::spc_ram_100_w )
{
m_spc700->spc_ram_w(offset + 0x100, data);
}
// Memory access for the various types of carts
//---------------------------------------------------------------------------------
@ -165,7 +148,7 @@ READ8_MEMBER( snes_console_state::snes20_hi_r )
if (offset < 0x400000)
{
if (address < 0x2000)
return space.read_byte(0x7e0000 + address);
return m_wram[address];
else if (address < 0x6000)
return snes_r_io(space, address);
else if (address < 0x8000)
@ -225,7 +208,7 @@ WRITE8_MEMBER( snes_console_state::snes20_hi_w )
if (offset < 0x400000)
{
if (address < 0x2000)
space.write_byte(0x7e0000 + address, data);
m_wram[address] = data;
else if (address < 0x6000)
snes_w_io(space, address, data);
}
@ -260,7 +243,7 @@ READ8_MEMBER( snes_console_state::snes20_lo_r )
if (offset < 0x400000)
{
if (address < 0x2000)
return space.read_byte(0x7e0000 + address);
return m_wram[address];
else if (address < 0x6000)
return snes_r_io(space, address);
else if (address < 0x8000)
@ -321,7 +304,7 @@ READ8_MEMBER( snes_console_state::snes21_lo_r )
if (offset < 0x400000 && address < 0x8000)
{
if (address < 0x2000)
return space.read_byte(0x7e0000 + address);
return m_wram[address];
else if (address < 0x6000)
return snes_r_io(space, address);
else
@ -354,7 +337,7 @@ WRITE8_MEMBER( snes_console_state::snes21_lo_w )
if (offset < 0x400000 && address < 0x8000)
{
if (address < 0x2000)
space.write_byte(0x7e0000 + address, data);
m_wram[address] = data;
else if (address < 0x6000)
snes_w_io(space, address, data);
else
@ -383,7 +366,7 @@ READ8_MEMBER( snes_console_state::snes21_hi_r )
if (offset < 0x400000 && address < 0x8000)
{
if (address < 0x2000)
return space.read_byte(0x7e0000 + address);
return m_wram[address];
else if (address < 0x6000)
return snes_r_io(space, address);
else
@ -416,7 +399,7 @@ WRITE8_MEMBER( snes_console_state::snes21_hi_w )
if (offset < 0x400000 && address < 0x8000)
{
if (address < 0x2000)
space.write_byte(0x7e0000 + address, data);
m_wram[address] = data;
else if (address < 0x6000)
snes_w_io(space, address, data);
else
@ -449,7 +432,7 @@ READ8_MEMBER( snes_console_state::snessfx_hi_r )
if (offset < 0x400000)
{
if (address < 0x2000)
return space.read_byte(0x7e0000 + address);
return m_wram[address];
else if (address < 0x6000)
{
if (address >= 0x3000 && address < 0x3300)
@ -475,7 +458,7 @@ READ8_MEMBER( snes_console_state::snessfx_lo_r )
if (offset < 0x400000)
{
if (address < 0x2000)
return space.read_byte(0x7e0000 + address);
return m_wram[address];
else if (address < 0x6000)
{
if (address >= 0x3000 && address < 0x3300)
@ -500,7 +483,7 @@ WRITE8_MEMBER( snes_console_state::snessfx_hi_w )
if (offset < 0x400000)
{
if (address < 0x2000)
space.write_byte(0x7e0000 + address, data);
m_wram[address] = data;
else if (address < 0x6000)
{
if (address >= 0x3000 && address < 0x3300)
@ -531,7 +514,7 @@ READ8_MEMBER( snes_console_state::snessa1_hi_r )
if (offset < 0x400000)
{
if (address < 0x2000)
return space.read_byte(0x7e0000 + address);
return m_wram[address];
else if (address < 0x6000)
{
if (address >= 0x2200 && address < 0x2400)
@ -557,7 +540,7 @@ READ8_MEMBER( snes_console_state::snessa1_lo_r )
if (offset < 0x400000)
{
if (address < 0x2000)
return space.read_byte(0x7e0000 + address);
return m_wram[address];
else if (address < 0x6000)
{
if (address >= 0x2200 && address < 0x2400)
@ -584,7 +567,7 @@ WRITE8_MEMBER( snes_console_state::snessa1_hi_w )
if (offset < 0x400000)
{
if (address < 0x2000)
space.write_byte(0x7e0000 + address, data);
m_wram[address] = data;
else if (address < 0x6000)
{
if (address >= 0x2200 && address < 0x2400)
@ -618,7 +601,7 @@ READ8_MEMBER( snes_console_state::snes7110_hi_r )
if (offset < 0x400000)
{
if (address < 0x2000)
return space.read_byte(0x7e0000 + address);
return m_wram[address];
else if (address < 0x6000)
{
uint16_t limit = (m_cartslot->get_type() == SNES_SPC7110_RTC) ? 0x4843 : 0x4840;
@ -647,7 +630,7 @@ READ8_MEMBER( snes_console_state::snes7110_lo_r )
if (offset < 0x400000)
{
if (address < 0x2000)
return space.read_byte(0x7e0000 + address);
return m_wram[address];
else if (address < 0x6000)
{
uint16_t limit = (m_cartslot->get_type() == SNES_SPC7110_RTC) ? 0x4843 : 0x4840;
@ -683,7 +666,7 @@ WRITE8_MEMBER( snes_console_state::snes7110_lo_w )
if (offset < 0x400000)
{
if (address < 0x2000)
space.write_byte(0x7e0000 + address, data);
m_wram[address] = data;
else if (address < 0x6000)
{
uint16_t limit = (m_cartslot->get_type() == SNES_SPC7110_RTC) ? 0x4843 : 0x4840;
@ -716,7 +699,7 @@ READ8_MEMBER( snes_console_state::snessdd1_lo_r )
if (offset < 0x400000)
{
if (address < 0x2000)
return space.read_byte(0x7e0000 + address);
return m_wram[address];
else if (address < 0x6000)
{
if (address >= 0x4800 && address < 0x4808)
@ -754,7 +737,7 @@ WRITE8_MEMBER( snes_console_state::snessdd1_hi_w )
if (offset < 0x400000)
{
if (address < 0x2000)
space.write_byte(0x7e0000 + address, data);
m_wram[address] = data;
else if (address < 0x6000)
{
if (address >= 0x4300 && address < 0x4380)
@ -786,7 +769,7 @@ READ8_MEMBER( snes_console_state::snesbsx_hi_r )
if (offset < 0x400000)
{
if (address < 0x2000)
return space.read_byte(0x7e0000 + address);
return m_wram[address];
else if (address < 0x6000)
{
if (address >= 0x2188 && address < 0x21a0)
@ -814,7 +797,7 @@ WRITE8_MEMBER( snes_console_state::snesbsx_hi_w )
if (offset < 0x400000)
{
if (address < 0x2000)
space.write_byte(0x7e0000 + address, data);
m_wram[address] = data;
else if (address < 0x6000)
{
if (address >= 0x2188 && address < 0x21a0)
@ -847,7 +830,7 @@ READ8_MEMBER( snes_console_state::snesbsx_lo_r )
if (offset < 0x400000)
{
if (address < 0x2000)
return space.read_byte(0x7e0000 + address);
return m_wram[address];
else if (address < 0x6000)
{
if (address >= 0x2188 && address < 0x21a0)
@ -886,7 +869,7 @@ READ8_MEMBER( snes_console_state::snessgb_hi_r )
if (offset < 0x400000)
{
if (address < 0x2000)
return space.read_byte(0x7e0000 + address);
return m_wram[address];
else if (address < 0x6000)
return snes_r_io(space, address);
else if (address < 0x8000)
@ -911,7 +894,7 @@ WRITE8_MEMBER( snes_console_state::snessgb_hi_w )
if (offset < 0x400000)
{
if (address < 0x2000)
space.write_byte(0x7e0000 + address, data);
m_wram[address] = data;
else if (address < 0x6000)
snes_w_io(space, address, data);
else if (address < 0x8000)
@ -935,7 +918,7 @@ READ8_MEMBER( snes_console_state::pfest94_hi_r )
if (offset < 0x400000)
{
if (address < 0x2000)
return space.read_byte(0x7e0000 + address);
return m_wram[address];
else if (address < 0x6000)
return snes_r_io(space, address);
else if (address < 0x8000)
@ -961,7 +944,7 @@ WRITE8_MEMBER( snes_console_state::pfest94_hi_w )
if (offset < 0x400000)
{
if (address < 0x2000)
space.write_byte(0x7e0000 + address, data);
m_wram[address] = data;
else if (address < 0x6000)
snes_w_io(space, address, data);
else if (address < 0x8000)
@ -983,7 +966,7 @@ READ8_MEMBER( snes_console_state::pfest94_lo_r )
if (offset < 0x400000)
{
if (address < 0x2000)
return space.read_byte(0x7e0000 + address);
return m_wram[address];
else if (address < 0x6000)
return snes_r_io(space, address);
else if (address < 0x8000)
@ -1018,15 +1001,13 @@ WRITE8_MEMBER( snes_console_state::pfest94_lo_w )
void snes_console_state::snes_map(address_map &map)
{
// map(0x000000, 0x7dffff).rw(FUNC(snes_console_state::snes20_lo_r), FUNC(snes_console_state::snes20_lo_w));
map(0x7e0000, 0x7fffff).ram(); /* 8KB Low RAM, 24KB High RAM, 96KB Expanded RAM */
map(0x7e0000, 0x7fffff).ram().share("wram"); /* 8KB Low RAM, 24KB High RAM, 96KB Expanded RAM */
// map(0x800000, 0xffffff).rw(FUNC(snes_console_state::snes20_hi_r), FUNC(snes_console_state::snes20_hi_w));
}
void snes_console_state::spc_map(address_map &map)
{
map(0x0000, 0x00ef).rw(m_spc700, FUNC(snes_sound_device::spc_ram_r), FUNC(snes_sound_device::spc_ram_w)); /* lower 32k ram */
map(0x00f0, 0x00ff).rw(m_spc700, FUNC(snes_sound_device::spc_io_r), FUNC(snes_sound_device::spc_io_w)); /* spc io */
map(0x0100, 0xffff).rw(FUNC(snes_console_state::spc_ram_100_r), FUNC(snes_console_state::spc_ram_100_w));
map(0x0000, 0xffff).ram().share("aram");
}
@ -1340,8 +1321,10 @@ void snes_console_state::snes(machine_config &config)
m_maincpu->set_addrmap(AS_PROGRAM, &snes_console_state::snes_map);
// runs at 24.576 MHz / 12 = 2.048 MHz
SPC700(config, m_soundcpu, XTAL(24'576'000) / 12);
m_soundcpu->set_addrmap(AS_PROGRAM, &snes_console_state::spc_map);
S_SMP(config, m_soundcpu, XTAL(24'576'000) / 12);
m_soundcpu->set_addrmap(AS_DATA, &snes_console_state::spc_map);
m_soundcpu->dsp_io_read_callback().set(m_s_dsp, FUNC(s_dsp_device::dsp_io_r));
m_soundcpu->dsp_io_write_callback().set(m_s_dsp, FUNC(s_dsp_device::dsp_io_w));
//config.set_maximum_quantum(attotime::from_hz(48000));
config.set_perfect_quantum(m_maincpu);
@ -1365,9 +1348,11 @@ void snes_console_state::snes(machine_config &config)
/* sound hardware */
SPEAKER(config, "lspeaker").front_left();
SPEAKER(config, "rspeaker").front_right();
SNES_SOUND(config, m_spc700, XTAL(24'576'000) / 12);
m_spc700->add_route(0, "lspeaker", 1.00);
m_spc700->add_route(1, "rspeaker", 1.00);
S_DSP(config, m_s_dsp, XTAL(24'576'000) / 12);
m_s_dsp->set_addrmap(0, &snes_console_state::spc_map);
m_s_dsp->add_route(0, "lspeaker", 1.00);
m_s_dsp->add_route(1, "rspeaker", 1.00);
SNS_CART_SLOT(config, m_cartslot, MCLK_NTSC, snes_cart, nullptr);
m_cartslot->irq_callback().set_inputline(m_maincpu, G65816_LINE_IRQ);
@ -1399,9 +1384,6 @@ void snes_console_state::snespal(machine_config &config)
ROM_START( snes )
ROM_REGION( 0x1000000, "maincpu", ROMREGION_ERASE00 )
ROM_REGION( 0x100, "sound_ipl", 0 ) /* IPL ROM */
ROM_LOAD( "spc700.rom", 0, 0x40, CRC(44bb3a40) SHA1(97e352553e94242ae823547cd853eecda55c20f0) ) /* boot rom */
ROM_END
#define rom_snespal rom_snes

View File

@ -192,12 +192,10 @@ private:
DECLARE_READ8_MEMBER(snesb_dsw1_r);
DECLARE_READ8_MEMBER(snesb_dsw2_r);
DECLARE_READ8_MEMBER(snesb_coin_r);
DECLARE_READ8_MEMBER(spc_ram_100_r);
DECLARE_WRITE8_MEMBER(spc_ram_100_w);
DECLARE_MACHINE_RESET(ffight2b);
void mcu_io_map(address_map &map);
void snesb_map(address_map &map);
void spc_mem(address_map &map);
void spc_map(address_map &map);
};
@ -332,25 +330,13 @@ READ8_MEMBER(snesb_state::snesb_coin_r)
void snesb_state::snesb_map(address_map &map)
{
map(0x000000, 0x7dffff).rw(FUNC(snesb_state::snes_r_bank1), FUNC(snesb_state::snes_w_bank1));
map(0x7e0000, 0x7fffff).ram(); /* 8KB Low RAM, 24KB High RAM, 96KB Expanded RAM */
map(0x7e0000, 0x7fffff).ram().share("wram"); /* 8KB Low RAM, 24KB High RAM, 96KB Expanded RAM */
map(0x800000, 0xffffff).rw(FUNC(snesb_state::snes_r_bank2), FUNC(snesb_state::snes_w_bank2)); /* Mirror and ROM */
}
READ8_MEMBER(snesb_state::spc_ram_100_r)
void snesb_state::spc_map(address_map &map)
{
return m_spc700->spc_ram_r(offset + 0x100);
}
WRITE8_MEMBER(snesb_state::spc_ram_100_w)
{
m_spc700->spc_ram_w(offset + 0x100, data);
}
void snesb_state::spc_mem(address_map &map)
{
map(0x0000, 0x00ef).rw(m_spc700, FUNC(snes_sound_device::spc_ram_r), FUNC(snes_sound_device::spc_ram_w)); /* lower 32k ram */
map(0x00f0, 0x00ff).rw(m_spc700, FUNC(snes_sound_device::spc_io_r), FUNC(snes_sound_device::spc_io_w)); /* spc io */
map(0x0100, 0xffff).rw(FUNC(snesb_state::spc_ram_100_r), FUNC(snesb_state::spc_ram_100_w));
map(0x0000, 0xffff).ram().share("aram");
}
static INPUT_PORTS_START( snes_common )
@ -821,8 +807,10 @@ void snesb_state::kinstb(machine_config &config)
/* audio CPU */
// runs at 24.576 MHz / 12 = 2.048 MHz
SPC700(config, m_soundcpu, XTAL(24'576'000) / 12);
m_soundcpu->set_addrmap(AS_PROGRAM, &snesb_state::spc_mem);
S_SMP(config, m_soundcpu, XTAL(24'576'000) / 12);
m_soundcpu->set_addrmap(AS_DATA, &snesb_state::spc_map);
m_soundcpu->dsp_io_read_callback().set(m_s_dsp, FUNC(s_dsp_device::dsp_io_r));
m_soundcpu->dsp_io_write_callback().set(m_s_dsp, FUNC(s_dsp_device::dsp_io_w));
config.set_perfect_quantum(m_maincpu);
@ -839,9 +827,11 @@ void snesb_state::kinstb(machine_config &config)
/* sound hardware */
SPEAKER(config, "lspeaker").front_left();
SPEAKER(config, "rspeaker").front_right();
SNES_SOUND(config, m_spc700, XTAL(24'576'000) / 12);
m_spc700->add_route(0, "lspeaker", 1.00);
m_spc700->add_route(1, "rspeaker", 1.00);
S_DSP(config, m_s_dsp, XTAL(24'576'000) / 12);
m_s_dsp->set_addrmap(0, &snesb_state::spc_map);
m_s_dsp->add_route(0, "lspeaker", 1.00);
m_s_dsp->add_route(1, "rspeaker", 1.00);
}
MACHINE_RESET_MEMBER( snesb_state, ffight2b )
@ -1371,9 +1361,6 @@ ROM_START( kinstb )
ROM_LOAD( "3.u16", 0x200000, 0x100000, CRC(7a40f7dd) SHA1(cebe632e8d2d68d0619077cc1e931af73c9a723b) )
ROM_LOAD( "4.u17", 0x300000, 0x100000, CRC(3d7564c1) SHA1(392b513991897668d5dd469ac84a34f785895774) )
ROM_REGION(0x100, "sound_ipl", 0)
ROM_LOAD("spc700.rom", 0, 0x40, CRC(44bb3a40) SHA1(97e352553e94242ae823547cd853eecda55c20f0) )
ROM_REGION(0x800, "user6", ROMREGION_ERASEFF)
ROM_END
@ -1413,9 +1400,6 @@ ROM_START( ffight2b )
ROM_CONTINUE( 0x078000, 0x008000 )
ROM_LOAD( "ff2_1.u8", 0x100000, 0x040000, CRC(ea315ac1) SHA1(a85de091882d35bc77dc99677511828ff7c20350) )
ROM_REGION(0x100, "sound_ipl", 0)
ROM_LOAD("spc700.rom", 0, 0x40, CRC(44bb3a40) SHA1(97e352553e94242ae823547cd853eecda55c20f0) )
ROM_REGION(0x800, "user6", ROMREGION_ERASEFF)
ROM_END
@ -1425,9 +1409,6 @@ ROM_START( iron )
ROM_LOAD( "5.c10.bin", 0x080000, 0x080000, CRC(0c3a0b5b) SHA1(1e8ab860689137e0e94731f1af2cfc561492b5bd) )
ROM_LOAD( "4.c11.bin", 0x100000, 0x040000, CRC(2aa417c7) SHA1(24b375e5bbd4be5dcd31b63ea98fbbadd53d543e) )
ROM_REGION(0x100, "sound_ipl", 0)
ROM_LOAD("spc700.rom", 0, 0x40, CRC(44bb3a40) SHA1(97e352553e94242ae823547cd853eecda55c20f0) )
ROM_REGION(0x800, "user6", ROMREGION_ERASEFF)
ROM_END
@ -1438,18 +1419,12 @@ ROM_START( denseib )
ROM_LOAD( "dj.u16", 0x100000, 0x0080000, CRC(7cb71fd7) SHA1(7673e9dcaabe804e2d637e67eabca1683dad4245) )
ROM_LOAD( "dj.u17", 0x180000, 0x0080000, CRC(de29dd89) SHA1(441aefbc7ee64515ee66431ef504e76dc8dc5ca3) )
ROM_REGION(0x100, "sound_ipl", 0)
ROM_LOAD("spc700.rom", 0, 0x40, CRC(44bb3a40) SHA1(97e352553e94242ae823547cd853eecda55c20f0) )
ROM_REGION(0x800, "user6", ROMREGION_ERASEFF)
ROM_END
ROM_START( denseib2 )
ROM_REGION( 0x200000, "user3", ROMREGION_ERASEFF )
ROM_REGION(0x100, "sound_ipl", 0)
ROM_LOAD("spc700.rom", 0, 0x40, CRC(44bb3a40) SHA1(97e352553e94242ae823547cd853eecda55c20f0) )
ROM_REGION(0x800, "user6", ROMREGION_ERASEFF)
ROM_REGION( 0x200000, "user7", 0 )
@ -1462,9 +1437,6 @@ ROM_END
ROM_START( sblast2b )
ROM_REGION( 0x180000, "user3", ROMREGION_ERASEFF )
ROM_REGION(0x100, "sound_ipl", 0)
ROM_LOAD("spc700.rom", 0, 0x40, CRC(44bb3a40) SHA1(97e352553e94242ae823547cd853eecda55c20f0) )
ROM_REGION(0x800, "user6", ROMREGION_ERASEFF)
ROM_REGION( 0x180000, "user7", 0 )
@ -1511,18 +1483,12 @@ ROM_START( legendsb )
ROM_CONTINUE( 0x0f0000, 0x008000 )
ROM_CONTINUE( 0x078000, 0x008000 )
ROM_REGION(0x100, "sound_ipl", 0)
ROM_LOAD("spc700.rom", 0, 0x40, CRC(44bb3a40) SHA1(97e352553e94242ae823547cd853eecda55c20f0) )
ROM_REGION(0x800, "user6", ROMREGION_ERASEFF)
ROM_END
ROM_START( endless )
ROM_REGION( 0x200000, "user3", ROMREGION_ERASEFF )
ROM_REGION(0x100, "sound_ipl", 0)
ROM_LOAD("spc700.rom", 0, 0x40, CRC(44bb3a40) SHA1(97e352553e94242ae823547cd853eecda55c20f0) )
ROM_REGION(0x800, "user6", ROMREGION_ERASEFF)
ROM_REGION( 0x200000, "user7", 0 )
@ -1535,9 +1501,6 @@ ROM_END
ROM_START( rushbets )
ROM_REGION( 0x200000, "user3", ROMREGION_ERASEFF )
ROM_REGION(0x100, "sound_ipl", 0)
ROM_LOAD("spc700.rom", 0, 0x40, CRC(44bb3a40) SHA1(97e352553e94242ae823547cd853eecda55c20f0) )
ROM_REGION(0x800, "user6", ROMREGION_ERASEFF)
ROM_REGION( 0x200000, "user7", 0 )
@ -1550,9 +1513,6 @@ ROM_END
ROM_START( venom )
ROM_REGION( 0x300000, "user3", ROMREGION_ERASEFF )
ROM_REGION(0x100, "sound_ipl", 0)
ROM_LOAD("spc700.rom", 0, 0x40, CRC(44bb3a40) SHA1(97e352553e94242ae823547cd853eecda55c20f0) )
ROM_REGION(0x800, "user6", ROMREGION_ERASEFF)
ROM_REGION( 0x300000, "user7", 0 )

View File

@ -4,9 +4,9 @@
#ifndef MAME_INCLUDES_SNES_H
#define MAME_INCLUDES_SNES_H
#include "cpu/spc700/spc700.h"
#include "cpu/g65816/g65816.h"
#include "audio/snes_snd.h"
#include "machine/s_smp.h"
#include "sound/s_dsp.h"
#include "video/snes_ppu.h"
#include "screen.h"
@ -303,9 +303,10 @@ public:
driver_device(mconfig, type, tag),
m_maincpu(*this, "maincpu"),
m_soundcpu(*this, "soundcpu"),
m_spc700(*this, "spc700"),
m_s_dsp(*this, "s_dsp"),
m_ppu(*this, "ppu"),
m_screen(*this, "screen")
m_screen(*this, "screen"),
m_wram(*this, "wram")
{ }
void init_snes();
@ -316,6 +317,11 @@ public:
uint32_t screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect);
protected:
virtual void machine_start() override;
virtual void machine_reset() override;
virtual void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr) override;
enum
{
TIMER_NMI_TICK,
@ -385,11 +391,13 @@ protected:
/* devices */
required_device<_5a22_device> m_maincpu;
required_device<spc700_device> m_soundcpu;
required_device<snes_sound_device> m_spc700;
required_device<s_smp_device> m_soundcpu;
required_device<s_dsp_device> m_s_dsp;
required_device<snes_ppu_device> m_ppu;
required_device<screen_device> m_screen;
required_shared_ptr<u8> m_wram;
inline int dma_abus_valid(uint32_t address);
inline uint8_t abus_read(address_space &space, uint32_t abus);
inline void dma_transfer(address_space &space, uint8_t dma, uint32_t abus, uint16_t bbus);
@ -432,10 +440,6 @@ protected:
DECLARE_DEVICE_IMAGE_LOAD_MEMBER(load_snes_cart);
DECLARE_DEVICE_IMAGE_LOAD_MEMBER(load_sufami_cart);
void snes_init_timers();
virtual void machine_start() override;
virtual void machine_reset() override;
virtual void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr) override;
};
/* Special chips, checked at init and used in memory handlers */

View File

@ -390,7 +390,7 @@ READ8_MEMBER( snes_state::snes_r_io )
// APU is mirrored from 2140 to 217f
if (offset >= APU00 && offset < WMDATA)
{
return m_spc700->spc_port_out(offset & 0x3);
return m_soundcpu->spc_port_out_r(offset & 0x3);
}
// DMA accesses are from 4300 to 437f
@ -404,7 +404,7 @@ READ8_MEMBER( snes_state::snes_r_io )
switch (offset) // offset is from 0x000000
{
case WMDATA: /* Data to read from WRAM */
value = m_maincpu->space(AS_PROGRAM).read_byte(0x7e0000 + m_wram_address++);
value = m_wram[m_wram_address++];
m_wram_address &= 0x1ffff;
return value;
@ -480,7 +480,7 @@ WRITE8_MEMBER( snes_state::snes_w_io )
if (offset >= APU00 && offset < WMDATA)
{
// printf("816: %02x to APU @ %d (PC=%06x)\n", data, offset & 3,m_maincpu->pc());
m_spc700->spc_port_in(offset & 0x3, data);
m_soundcpu->spc_port_in_w(offset & 0x3, data);
machine().scheduler().boost_interleave(attotime::zero, attotime::from_usec(20));
return;
}
@ -496,7 +496,7 @@ WRITE8_MEMBER( snes_state::snes_w_io )
switch (offset)
{
case WMDATA: /* Data to write to WRAM */
m_maincpu->space(AS_PROGRAM).write_byte(0x7e0000 + m_wram_address++, data );
m_wram[m_wram_address++] = data;
m_wram_address &= 0x1ffff;
return;
case WMADDL: /* Address to read/write to wram (low) */
@ -720,7 +720,7 @@ READ8_MEMBER(snes_state::snes_r_bank1)
if (offset < 0x400000)
{
if (address < 0x2000) /* Mirror of Low RAM */
value = m_maincpu->space(AS_PROGRAM).read_byte(0x7e0000 + address);
value = m_wram[address];
else if (address < 0x6000) /* I/O */
value = snes_r_io(space, address);
else if (address < 0x8000)
@ -831,7 +831,7 @@ WRITE8_MEMBER(snes_state::snes_w_bank1)
if (offset < 0x400000)
{
if (address < 0x2000) /* Mirror of Low RAM */
m_maincpu->space(AS_PROGRAM).write_byte(0x7e0000 + address, data);
m_wram[address] = data;
else if (address < 0x6000) /* I/O */
snes_w_io(space, address, data);
else if (address < 0x8000)
@ -1034,14 +1034,14 @@ void snes_state::snes_init_timers()
void snes_state::snes_init_ram()
{
address_space &cpu0space = m_maincpu->space(AS_PROGRAM);
int i;
/* Init work RAM - 0x55 isn't exactly right but it's close */
/* make sure it happens to the 65816 (CPU 0) */
for (i = 0; i < (128*1024); i++)
const size_t size = m_wram.bytes();
for (i = 0; i < size; i++)
{
cpu0space.write_byte(0x7e0000 + i, 0x55);
m_wram[i] = 0x55;
}
/* Inititialize registers/variables */