summaryrefslogtreecommitdiffstatshomepage
path: root/src/devices/sound
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 /src/devices/sound
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]
Diffstat (limited to 'src/devices/sound')
-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
3 files changed, 39 insertions, 7 deletions
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;