summaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
author 0kmg <9137159+0kmg@users.noreply.github.com>2022-09-03 10:02:59 -0800
committer GitHub <noreply@github.com>2022-09-04 04:02:59 +1000
commit2468371a075875e43b24e53a3ecbfe27a879d425 (patch)
tree5e21fcd3d9cd9e8dc6294b1b77bca406514f5995
parent7a50a679c4f35d68022ff0d19d95f8865ef74848 (diff)
sound/nes_apu.cpp: Added earliest hardware variant of 2A03 APU. (#10299)
Fixes several audio bugs with the noise channel in VS. System games, including: * High-pitch sound in vsgshoe percussion track. * Jet sounds in bnglngby. * Number of tanks killed count screen in btlecity. * nvs_platoon's bullet and enemies dying sounds are subtly changed. It's estimated that these letterless CPU versions are in the first two million or so Famicoms (about 10% of Famicoms sold). There are games developed on the RP2A03 that have sound glitches on later, more common Famicoms. For instance, the very last note in the game over melody in Balloon Fight rings out with a loud buzz on later machines. The new famicomo driver plays it as the developers must have intended. New working clones ------------------ Nintendo Famicom (earlier, with RP2A03) [kmg]
-rw-r--r--src/devices/cpu/m6502/n2a03.cpp27
-rw-r--r--src/devices/cpu/m6502/n2a03.h15
-rw-r--r--src/devices/sound/nes_apu.cpp29
-rw-r--r--src/devices/sound/nes_apu.h15
-rw-r--r--src/devices/sound/nes_defs.h2
-rw-r--r--src/mame/mame.lst1
-rw-r--r--src/mame/nintendo/cham24.cpp2
-rw-r--r--src/mame/nintendo/famibox.cpp2
-rw-r--r--src/mame/nintendo/multigam.cpp2
-rw-r--r--src/mame/nintendo/nes.cpp18
-rw-r--r--src/mame/nintendo/nes.h1
-rw-r--r--src/mame/nintendo/nes_arcade_bl.cpp2
-rw-r--r--src/mame/nintendo/nes_clone.cpp4
-rw-r--r--src/mame/nintendo/playch10.cpp2
-rw-r--r--src/mame/virtual/vgmplay.cpp4
15 files changed, 102 insertions, 24 deletions
diff --git a/src/devices/cpu/m6502/n2a03.cpp b/src/devices/cpu/m6502/n2a03.cpp
index e1731b62e75..f0914298659 100644
--- a/src/devices/cpu/m6502/n2a03.cpp
+++ b/src/devices/cpu/m6502/n2a03.cpp
@@ -13,7 +13,8 @@
#include "n2a03d.h"
DEFINE_DEVICE_TYPE(N2A03_CORE, n2a03_core_device, "n2a03_core", "Ricoh N2A03 core") // needed for some VT systems with XOP instead of standard APU
-DEFINE_DEVICE_TYPE(N2A03, n2a03_device, "n2a03", "Ricoh N2A03")
+DEFINE_DEVICE_TYPE(N2A03, n2a03_device, "n2a03", "Ricoh N2A03") // earliest version, found in punchout, spnchout, dkong3, VS. systems, and some early Famicoms
+DEFINE_DEVICE_TYPE(N2A03G, n2a03g_device, "n2a03g", "Ricoh N2A03G") // later revision, found in front-loader NES
uint8_t n2a03_device::psg1_4014_r()
{
@@ -64,14 +65,24 @@ n2a03_core_device::n2a03_core_device(const machine_config &mconfig, const char *
-n2a03_device::n2a03_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
- : n2a03_core_device(mconfig, N2A03, tag, owner, clock)
+n2a03_device::n2a03_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock)
+ : n2a03_core_device(mconfig, type, tag, owner, clock)
, device_mixer_interface(mconfig, *this, 1)
, m_apu(*this, "nesapu")
{
program_config.m_internal_map = address_map_constructor(FUNC(n2a03_device::n2a03_map), this);
}
+n2a03_device::n2a03_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
+ : n2a03_device(mconfig, N2A03, tag, owner, clock)
+{
+}
+
+n2a03g_device::n2a03g_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
+ : n2a03_device(mconfig, N2A03G, tag, owner, clock)
+{
+}
+
std::unique_ptr<util::disasm_interface> n2a03_core_device::create_disassembler()
@@ -92,11 +103,19 @@ uint8_t n2a03_device::apu_read_mem(offs_t offset)
void n2a03_device::device_add_mconfig(machine_config &config)
{
- NES_APU(config, m_apu, DERIVED_CLOCK(1,1));
+ APU_2A03(config, m_apu, DERIVED_CLOCK(1,1));
m_apu->irq().set(FUNC(n2a03_device::apu_irq));
m_apu->mem_read().set(FUNC(n2a03_device::apu_read_mem));
m_apu->add_route(ALL_OUTPUTS, *this, 1.0, AUTO_ALLOC_INPUT, 0);
}
+void n2a03g_device::device_add_mconfig(machine_config &config)
+{
+ NES_APU(config, m_apu, DERIVED_CLOCK(1,1));
+ m_apu->irq().set(FUNC(n2a03g_device::apu_irq));
+ m_apu->mem_read().set(FUNC(n2a03g_device::apu_read_mem));
+ m_apu->add_route(ALL_OUTPUTS, *this, 1.0, AUTO_ALLOC_INPUT, 0);
+}
+
#include "cpu/m6502/n2a03.hxx"
diff --git a/src/devices/cpu/m6502/n2a03.h b/src/devices/cpu/m6502/n2a03.h
index 4232093c7a5..28b43233dcc 100644
--- a/src/devices/cpu/m6502/n2a03.h
+++ b/src/devices/cpu/m6502/n2a03.h
@@ -51,18 +51,26 @@ public:
void psg1_4017_w(uint8_t data);
void n2a03_map(address_map &map);
+
protected:
+ n2a03_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock);
required_device<nesapu_device> m_apu;
virtual void device_add_mconfig(machine_config &config) override;
-private:
DECLARE_WRITE_LINE_MEMBER(apu_irq);
uint8_t apu_read_mem(offs_t offset);
-
};
+class n2a03g_device : public n2a03_device
+{
+public:
+ n2a03g_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
+
+protected:
+ virtual void device_add_mconfig(machine_config &config) override;
+};
/* These are the official XTAL values and clock rates used by Nintendo for
manufacturing throughout the production of the 2A03. PALC_APU_CLOCK is
@@ -82,6 +90,7 @@ enum {
};
DECLARE_DEVICE_TYPE(N2A03_CORE, n2a03_core_device)
-DECLARE_DEVICE_TYPE(N2A03, n2a03_device)
+DECLARE_DEVICE_TYPE(N2A03, n2a03_device)
+DECLARE_DEVICE_TYPE(N2A03G, n2a03g_device)
#endif // MAME_CPU_M6502_N2A03_H
diff --git a/src/devices/sound/nes_apu.cpp b/src/devices/sound/nes_apu.cpp
index a7e8a3066f7..ee038128524 100644
--- a/src/devices/sound/nes_apu.cpp
+++ b/src/devices/sound/nes_apu.cpp
@@ -45,7 +45,8 @@
#include "emu.h"
#include "nes_apu.h"
-DEFINE_DEVICE_TYPE(NES_APU, nesapu_device, "nesapu", "N2A03 APU")
+DEFINE_DEVICE_TYPE(NES_APU, nesapu_device, "nesapu", "N2A0X APU")
+DEFINE_DEVICE_TYPE(APU_2A03, apu2a03_device, "apu2a03", "RP2A03 APU")
nesapu_device::nesapu_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 clock)
: device_t(mconfig, type, tag, owner, clock)
@@ -63,6 +64,12 @@ nesapu_device::nesapu_device(const machine_config& mconfig, const char* tag, dev
{
}
+apu2a03_device::apu2a03_device(const machine_config& mconfig, const char* tag, device_t* owner, u32 clock)
+ : nesapu_device(mconfig, APU_2A03, tag, owner, clock)
+{
+}
+
+
void nesapu_device::device_reset()
{
write(0x15, 0x00);
@@ -177,7 +184,7 @@ void nesapu_device::device_start()
save_item(NAME(m_APU.tri.output));
save_item(NAME(m_APU.noi.regs));
- save_item(NAME(m_APU.noi.seed));
+ save_item(NAME(m_APU.noi.lfsr));
save_item(NAME(m_APU.noi.vbl_length));
save_item(NAME(m_APU.noi.phaseacc));
save_item(NAME(m_APU.noi.env_phase));
@@ -385,10 +392,10 @@ void nesapu_device::apu_noise(apu_t::noise_t *chan)
while (chan->phaseacc < 0)
{
chan->phaseacc += freq;
- chan->seed = (chan->seed >> 1) | ((BIT(chan->seed, 0) ^ BIT(chan->seed, (chan->regs[2] & 0x80) ? 6 : 1)) << 14);
+ update_lfsr(*chan);
}
- if (BIT(chan->seed, 0)) /* make it silence */
+ if (BIT(chan->lfsr, 0)) /* silence channel */
{
chan->output = 0;
return;
@@ -400,6 +407,18 @@ void nesapu_device::apu_noise(apu_t::noise_t *chan)
chan->output = 0x0f - chan->env_vol;
}
+void nesapu_device::update_lfsr(apu_t::noise_t &chan)
+{
+ chan.lfsr |= (BIT(chan.lfsr, 0) ^ BIT(chan.lfsr, (chan.regs[2] & 0x80) ? 6 : 1)) << 15;
+ chan.lfsr >>= 1;
+}
+
+void apu2a03_device::update_lfsr(apu_t::noise_t &chan)
+{
+ chan.lfsr |= (BIT(chan.lfsr, 0) ^ BIT(chan.lfsr, 1)) << 15;
+ chan.lfsr >>= 1;
+}
+
/* RESET DPCM PARAMETERS */
static inline void apu_dpcmreset(apu_t::dpcm_t *chan)
{
@@ -609,7 +628,7 @@ void nesapu_device::write(offs_t offset, u8 value)
break;
case apu_t::IRQCTRL:
- if(value & 0x80)
+ if (value & 0x80)
m_APU.step_mode = 5;
else
m_APU.step_mode = 4;
diff --git a/src/devices/sound/nes_apu.h b/src/devices/sound/nes_apu.h
index bb694b79ffa..42a92be2b0e 100644
--- a/src/devices/sound/nes_apu.h
+++ b/src/devices/sound/nes_apu.h
@@ -64,6 +64,8 @@ protected:
// sound stream update overrides
virtual void sound_stream_update(sound_stream &stream, std::vector<read_stream_view> const &inputs, std::vector<write_stream_view> &outputs) override;
+ virtual void update_lfsr(apu_t::noise_t &chan);
+
private:
/* GLOBAL CONSTANTS */
static constexpr unsigned SYNCS_MAX1 = 0x20;
@@ -92,6 +94,17 @@ private:
void apu_dpcm(apu_t::dpcm_t *chan);
};
-DECLARE_DEVICE_TYPE(NES_APU, nesapu_device)
+class apu2a03_device : public nesapu_device
+{
+public:
+ apu2a03_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock);
+
+protected:
+ virtual void update_lfsr(apu_t::noise_t &chan) override;
+};
+
+
+DECLARE_DEVICE_TYPE(NES_APU, nesapu_device)
+DECLARE_DEVICE_TYPE(APU_2A03, apu2a03_device)
#endif // MAME_SOUND_NES_APU_H
diff --git a/src/devices/sound/nes_defs.h b/src/devices/sound/nes_defs.h
index 1f4544b02c2..a9ee22bef92 100644
--- a/src/devices/sound/nes_defs.h
+++ b/src/devices/sound/nes_defs.h
@@ -86,7 +86,7 @@ struct apu_t
}
u8 regs[4]; /* regs[1] unused */
- u32 seed = 1;
+ u16 lfsr = 1;
int vbl_length = 0;
float phaseacc = 0.0;
float env_phase = 0.0;
diff --git a/src/mame/mame.lst b/src/mame/mame.lst
index 0b950eda7c4..a70d9fe06c7 100644
--- a/src/mame/mame.lst
+++ b/src/mame/mame.lst
@@ -33382,6 +33382,7 @@ dendy2 // Dendy Classic 2 (Russian import of IQ-502 fam
sb486 // Subor/Xiao Ba Wang SB-486
drpcjr // Bung Doctor PC Jr
famicom // Nintendo Family Computer (a.k.a. Famicom)
+famicomo // Nintendo Family Computer (original with RP2A03)
famitvc1 // Sharp My Computer Terebi C1
famitwin // Sharp Famicom Twin System
fds // Nintendo Family Computer (a.k.a. Famicom) + Disk System add-on
diff --git a/src/mame/nintendo/cham24.cpp b/src/mame/nintendo/cham24.cpp
index ec66bfe6eba..8e197c98f59 100644
--- a/src/mame/nintendo/cham24.cpp
+++ b/src/mame/nintendo/cham24.cpp
@@ -250,7 +250,7 @@ void cham24_state::machine_reset()
void cham24_state::cham24(machine_config &config)
{
/* basic machine hardware */
- N2A03(config, m_maincpu, NTSC_APU_CLOCK);
+ N2A03G(config, m_maincpu, NTSC_APU_CLOCK);
m_maincpu->set_addrmap(AS_PROGRAM, &cham24_state::cham24_map);
/* video hardware */
diff --git a/src/mame/nintendo/famibox.cpp b/src/mame/nintendo/famibox.cpp
index c3146538d9c..22bb956ba88 100644
--- a/src/mame/nintendo/famibox.cpp
+++ b/src/mame/nintendo/famibox.cpp
@@ -523,7 +523,7 @@ void famibox_state::machine_start()
void famibox_state::famibox(machine_config &config)
{
// basic machine hardware
- N2A03(config, m_maincpu, NTSC_APU_CLOCK);
+ N2A03G(config, m_maincpu, NTSC_APU_CLOCK);
m_maincpu->set_addrmap(AS_PROGRAM, &famibox_state::famibox_map);
// video hardware
diff --git a/src/mame/nintendo/multigam.cpp b/src/mame/nintendo/multigam.cpp
index 3675da93132..5dc1d44bda6 100644
--- a/src/mame/nintendo/multigam.cpp
+++ b/src/mame/nintendo/multigam.cpp
@@ -1184,7 +1184,7 @@ MACHINE_START_MEMBER(multigam_state,supergm3)
void multigam_state::multigam(machine_config &config)
{
/* basic machine hardware */
- N2A03(config, m_maincpu, NTSC_APU_CLOCK);
+ N2A03G(config, m_maincpu, NTSC_APU_CLOCK);
m_maincpu->set_addrmap(AS_PROGRAM, &multigam_state::multigam_map);
/* video hardware */
diff --git a/src/mame/nintendo/nes.cpp b/src/mame/nintendo/nes.cpp
index 0b8d01427c1..790a740af07 100644
--- a/src/mame/nintendo/nes.cpp
+++ b/src/mame/nintendo/nes.cpp
@@ -51,7 +51,7 @@ INPUT_PORTS_END
void nes_state::nes(machine_config &config)
{
// basic machine hardware
- n2a03_device &maincpu(N2A03(config, m_maincpu, NTSC_APU_CLOCK));
+ n2a03_device &maincpu(N2A03G(config, m_maincpu, NTSC_APU_CLOCK));
maincpu.set_addrmap(AS_PROGRAM, &nes_state::nes_map);
SCREEN(config, m_screen, SCREEN_TYPE_RASTER);
@@ -121,6 +121,17 @@ void nes_state::famicom(machine_config &config)
SOFTWARE_LIST(config, "cass_list").set_original("famicom_cass");
}
+void nes_state::famicomo(machine_config &config)
+{
+ famicom(config);
+
+ // basic machine hardware
+ n2a03_device &maincpu(N2A03(config.replace(), m_maincpu, NTSC_APU_CLOCK));
+ maincpu.set_addrmap(AS_PROGRAM, &nes_state::nes_map);
+
+ maincpu.add_route(ALL_OUTPUTS, "mono", 0.90);
+}
+
void nes_state::nespalc(machine_config &config)
{
nespal(config);
@@ -314,6 +325,10 @@ ROM_START( famicom )
ROM_REGION( 0x10000, "maincpu", ROMREGION_ERASE00 ) // Main RAM
ROM_END
+ROM_START( famicomo )
+ ROM_REGION( 0x10000, "maincpu", ROMREGION_ERASE00 ) // Main RAM
+ROM_END
+
ROM_START( famitvc1 )
ROM_REGION( 0x2000, "canvas_prg", 0 )
ROM_LOAD( "ix0402ce.ic109", 0x0000, 0x2000, CRC(96456b13) SHA1(a4dcb3c4f2be5077f0d197e870a26414287ce189) ) // dump needs verified
@@ -398,6 +413,7 @@ CONS( 198?, m82p, nes, 0, nespal, nes, nes_state, empty_init,
// Famicom hardware
CONS( 1983, famicom, 0, nes, famicom, famicom, nes_state, init_famicom, "Nintendo", "Famicom", MACHINE_IMPERFECT_GRAPHICS | MACHINE_SUPPORTS_SAVE )
+CONS( 1983, famicomo, famicom, 0, famicomo, famicom, nes_state, init_famicom, "Nintendo", "Famicom (earlier, with RP2A03)", MACHINE_IMPERFECT_GRAPHICS | MACHINE_SUPPORTS_SAVE )
CONS( 1983, famitvc1, famicom, 0, famitvc1, famicom, nes_state, init_famicom, "Sharp", "My Computer Terebi C1", MACHINE_IMPERFECT_GRAPHICS | MACHINE_NOT_WORKING | MACHINE_SUPPORTS_SAVE ) // working but for unimplemented save/load in builtin cartridge, which causes system to hang
CONS( 1986, fds, famicom, 0, fds, famicom, nes_state, init_famicom, "Nintendo", "Famicom (w/ Disk System add-on)", MACHINE_IMPERFECT_GRAPHICS | MACHINE_SUPPORTS_SAVE )
CONS( 1986, famitwin, famicom, 0, famitwin, famicom, nes_state, init_famicom, "Sharp", "Famicom Twin", MACHINE_IMPERFECT_GRAPHICS | MACHINE_SUPPORTS_SAVE )
diff --git a/src/mame/nintendo/nes.h b/src/mame/nintendo/nes.h
index bf0be0b5d7d..f1c3ae6d452 100644
--- a/src/mame/nintendo/nes.h
+++ b/src/mame/nintendo/nes.h
@@ -85,6 +85,7 @@ public:
void suborkbd(machine_config &config);
void famipalc(machine_config &config);
void famicom(machine_config &config);
+ void famicomo(machine_config &config);
void famitvc1(machine_config &config);
void famitwin(machine_config &config);
void nespal(machine_config &config);
diff --git a/src/mame/nintendo/nes_arcade_bl.cpp b/src/mame/nintendo/nes_arcade_bl.cpp
index 346b64eb96d..71a4446ae28 100644
--- a/src/mame/nintendo/nes_arcade_bl.cpp
+++ b/src/mame/nintendo/nes_arcade_bl.cpp
@@ -116,7 +116,7 @@ INPUT_PORTS_END
void nes_arcade_bl_state::smb3bl(machine_config &config)
{
- N2A03(config, m_maincpu, 3.579545_MHz_XTAL / 2); // TODO: verify divider
+ N2A03G(config, m_maincpu, 3.579545_MHz_XTAL / 2); // TODO: verify divider
m_maincpu->set_addrmap(AS_PROGRAM, &nes_arcade_bl_state::nes_cpu_map);
z80_device &timercpu(Z80(config, "timercpu", 3.579545_MHz_XTAL));
diff --git a/src/mame/nintendo/nes_clone.cpp b/src/mame/nintendo/nes_clone.cpp
index 75975dc4a34..82cfb8ee90f 100644
--- a/src/mame/nintendo/nes_clone.cpp
+++ b/src/mame/nintendo/nes_clone.cpp
@@ -404,7 +404,7 @@ void nes_clone_state::machine_start()
void nes_clone_state::nes_clone(machine_config &config)
{
/* basic machine hardware */
- N2A03(config, m_maincpu, NTSC_APU_CLOCK);
+ N2A03G(config, m_maincpu, NTSC_APU_CLOCK);
m_maincpu->set_addrmap(AS_PROGRAM, &nes_clone_state::nes_clone_map);
/* video hardware */
@@ -427,7 +427,7 @@ void nes_clone_state::nes_clone(machine_config &config)
void nes_clone_state::nes_clone_pal(machine_config &config)
{
/* basic machine hardware */
- N2A03(config, m_maincpu, PALC_APU_CLOCK);
+ N2A03G(config, m_maincpu, PALC_APU_CLOCK);
m_maincpu->set_addrmap(AS_PROGRAM, &nes_clone_state::nes_clone_map);
/* video hardware */
diff --git a/src/mame/nintendo/playch10.cpp b/src/mame/nintendo/playch10.cpp
index 436c4905597..ed33534f2e7 100644
--- a/src/mame/nintendo/playch10.cpp
+++ b/src/mame/nintendo/playch10.cpp
@@ -1906,7 +1906,7 @@ void playch10_state::playch10(machine_config &config)
m_maincpu->set_addrmap(AS_PROGRAM, &playch10_state::bios_map);
m_maincpu->set_addrmap(AS_IO, &playch10_state::bios_io_map);
- N2A03(config, m_cartcpu, NTSC_APU_CLOCK);
+ N2A03G(config, m_cartcpu, NTSC_APU_CLOCK);
m_cartcpu->set_addrmap(AS_PROGRAM, &playch10_state::cart_map);
ls259_device &outlatch1(LS259(config, "outlatch1")); // 7D
diff --git a/src/mame/virtual/vgmplay.cpp b/src/mame/virtual/vgmplay.cpp
index a7402341fb4..4c4032f9076 100644
--- a/src/mame/virtual/vgmplay.cpp
+++ b/src/mame/virtual/vgmplay.cpp
@@ -3845,13 +3845,13 @@ void vgmplay_state::vgmplay(machine_config &config)
m_dmg[1]->add_route(0, m_mixer, 1, AUTO_ALLOC_INPUT, 0);
m_dmg[1]->add_route(0, m_mixer, 1, AUTO_ALLOC_INPUT, 1);
- N2A03(config, m_nescpu[0], 0);
+ N2A03G(config, m_nescpu[0], 0);
m_nescpu[0]->set_addrmap(AS_PROGRAM, &vgmplay_state::nescpu_map<0>);
m_nescpu[0]->set_disable();
m_nescpu[0]->add_route(ALL_OUTPUTS, m_mixer, 0.50, AUTO_ALLOC_INPUT, 0);
m_nescpu[0]->add_route(ALL_OUTPUTS, m_mixer, 0.50, AUTO_ALLOC_INPUT, 1);
- N2A03(config, m_nescpu[1], 0);
+ N2A03G(config, m_nescpu[1], 0);
m_nescpu[1]->set_addrmap(AS_PROGRAM, &vgmplay_state::nescpu_map<1>);
m_nescpu[1]->set_disable();
m_nescpu[1]->add_route(ALL_OUTPUTS, m_mixer, 0.50, AUTO_ALLOC_INPUT, 0);