diff options
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 |
commit | 2468371a075875e43b24e53a3ecbfe27a879d425 (patch) | |
tree | 5e21fcd3d9cd9e8dc6294b1b77bca406514f5995 /src/devices/sound | |
parent | 7a50a679c4f35d68022ff0d19d95f8865ef74848 (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.cpp | 29 | ||||
-rw-r--r-- | src/devices/sound/nes_apu.h | 15 | ||||
-rw-r--r-- | src/devices/sound/nes_defs.h | 2 |
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; |