diff options
author | cam900 <dbtlrchl@naver.com> | 2019-03-30 06:57:27 +0900 |
---|---|---|
committer | R. Belmont <rb6502@users.noreply.github.com> | 2019-03-29 17:57:27 -0400 |
commit | 80a48d5229eb5ff62b4f27ec6351226b672c0030 (patch) | |
tree | 4122cd513df488d8b5a68b304abbff7b82f20b8a | |
parent | 6dbd636a809ce7bda3ec476239f7b32a2d1de537 (diff) |
Add Namco 163 sound emulation (#4814)
* Add Namco 163 sound emulation
* namco_163.cpp : Typo
* namco_163.cpp : Fix spacing
* namco_163.h : Fix comment (nw)
* namco_163.cpp : Correct update behavior
device/bus/nes/namcot.* : Remove / Fix outdated comments
* namco_163.cpp : Remove unnecessary value (nw)
* namco_163.cpp : Add notes (nw)
* namco_163.cpp : inline'd sample function, Minor fix
* namco_163.cpp : Fix notes
-rw-r--r-- | scripts/src/sound.lua | 8 | ||||
-rw-r--r-- | scripts/target/mame/arcade.lua | 1 | ||||
-rw-r--r-- | scripts/target/mame/mess.lua | 1 | ||||
-rw-r--r-- | src/devices/bus/nes/namcot.cpp | 33 | ||||
-rw-r--r-- | src/devices/bus/nes/namcot.h | 5 | ||||
-rw-r--r-- | src/devices/sound/namco_163.cpp | 176 | ||||
-rw-r--r-- | src/devices/sound/namco_163.h | 42 |
7 files changed, 254 insertions, 12 deletions
diff --git a/scripts/src/sound.lua b/scripts/src/sound.lua index f2d6c9b979d..73c6a852e44 100644 --- a/scripts/src/sound.lua +++ b/scripts/src/sound.lua @@ -590,6 +590,7 @@ end --------------------------------------------------- -- Namco custom sound chips --@src/devices/sound/namco.h,SOUNDS["NAMCO"] = true +--@src/devices/sound/namco_163.h,SOUNDS["NAMCO_163"] = true --@src/devices/sound/n63701x.h,SOUNDS["NAMCO_63701X"] = true --@src/devices/sound/c140.h,SOUNDS["C140"] = true --@src/devices/sound/c352.h,SOUNDS["C352"] = true @@ -602,6 +603,13 @@ if (SOUNDS["NAMCO"]~=null or SOUNDS["NAMCO_15XX"]~=null or SOUNDS["NAMCO_CUS30"] } end +if (SOUNDS["NAMCO_163"]~=null) then + files { + MAME_DIR .. "src/devices/sound/namco_163.cpp", + MAME_DIR .. "src/devices/sound/namco_163.h", + } +end + if (SOUNDS["NAMCO_63701X"]~=null) then files { MAME_DIR .. "src/devices/sound/n63701x.cpp", diff --git a/scripts/target/mame/arcade.lua b/scripts/target/mame/arcade.lua index 40ef9fc3e16..b80506d399c 100644 --- a/scripts/target/mame/arcade.lua +++ b/scripts/target/mame/arcade.lua @@ -173,6 +173,7 @@ SOUNDS["NAMCO_15XX"] = true SOUNDS["NAMCO_CUS30"] = true SOUNDS["NAMCO_52XX"] = true SOUNDS["NAMCO_63701X"] = true +--SOUNDS["NAMCO_163"] = true SOUNDS["T6W28"] = true SOUNDS["SNKWAVE"] = true SOUNDS["C140"] = true diff --git a/scripts/target/mame/mess.lua b/scripts/target/mame/mess.lua index 9d42bd1aa43..036b63c330b 100644 --- a/scripts/target/mame/mess.lua +++ b/scripts/target/mame/mess.lua @@ -181,6 +181,7 @@ SOUNDS["ASTROCADE"] = true --SOUNDS["NAMCO_CUS30"] = true --SOUNDS["NAMCO_52XX"] = true --SOUNDS["NAMCO_63701X"] = true +SOUNDS["NAMCO_163"] = true SOUNDS["T6W28"] = true --SOUNDS["SNKWAVE"] = true --SOUNDS["C140"] = true diff --git a/src/devices/bus/nes/namcot.cpp b/src/devices/bus/nes/namcot.cpp index e2898d6b9ba..256e5d65f3b 100644 --- a/src/devices/bus/nes/namcot.cpp +++ b/src/devices/bus/nes/namcot.cpp @@ -16,7 +16,6 @@ * Namcot 340 [mapper 210] TODO: - - add sound feature of Namcot-163 - Quinty is not working (same issue of Mendel Palace on TxROM boards, of course) ***********************************************************************************************************/ @@ -26,6 +25,8 @@ #include "namcot.h" #include "ui/uimain.h" +#include "speaker.h" + #ifdef NES_PCB_DEBUG #define VERBOSE 1 #else @@ -83,7 +84,7 @@ nes_namcot175_device::nes_namcot175_device(const machine_config &mconfig, const } nes_namcot163_device::nes_namcot163_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) - : nes_namcot340_device(mconfig, NES_NAMCOT163, tag, owner, clock), m_wram_protect(0), m_latch(0), m_chr_bank(0) + : nes_namcot340_device(mconfig, NES_NAMCOT163, tag, owner, clock), m_wram_protect(0), m_latch(0), m_chr_bank(0), m_namco163snd(*this, "n163") { } @@ -550,13 +551,11 @@ void nes_namcot175_device::write_h(offs_t offset, uint8_t data) Compared to Namcot-175 here we have mapper controlled mirroring, NTRAM mapping to VRAM and additional - sound hw inside the chip (currently unemulated) and - some internal RAM. + sound hw inside the chip and some internal RAM. iNES: mapper 19 - In MESS: Supported (with no emulation of the - sound component) + In MESS: Supported -------------------------------------------------*/ @@ -614,7 +613,7 @@ void nes_namcot163_device::write_l(offs_t offset, uint8_t data) switch (offset & 0x1800) { case 0x0800: - LOG_MMC(("Namcot-163 sound reg write, data: %02x\n", data)); + m_namco163snd->data_w(data); break; default: n340_lowrite(offset, data); @@ -630,8 +629,7 @@ uint8_t nes_namcot163_device::read_l(offs_t offset) switch (offset & 0x1800) { case 0x0800: - LOG_MMC(("Namcot-163 sound reg read\n")); - return 0; + return m_namco163snd->data_r(); default: return n340_loread(offset); } @@ -667,7 +665,7 @@ void nes_namcot163_device::write_h(offs_t offset, uint8_t data) set_mirror(page, data); break; case 0x6000: - // TODO: data & 40 (or data & c0) disable sound if set + m_namco163snd->disable_w((data & 0x40) ? ASSERT_LINE : CLEAR_LINE); prg8_89(data & 0x3f); break; case 0x6800: @@ -677,10 +675,23 @@ void nes_namcot163_device::write_h(offs_t offset, uint8_t data) case 0x7800: // the lower 4 bits work *BOTH* as WRAM write protect *AND* as sound address! m_wram_protect = data & 0x0f; - LOG_MMC(("Namcot-163 sound address write, data: %02x\n", data)); + m_namco163snd->addr_w(data); break; default: n340_hiwrite(offset, data); break; } } + +//------------------------------------------------- +// device_add_mconfig - add device configuration +//------------------------------------------------- + +void nes_namcot163_device::device_add_mconfig(machine_config &config) +{ + // additional sound hardware + SPEAKER(config, "addon").front_center(); + + // TODO: Correct clock input / divider? + NAMCO_163(config, m_namco163snd, XTAL(21'477'272)/12).add_route(ALL_OUTPUTS, "addon", 0.5); +} diff --git a/src/devices/bus/nes/namcot.h b/src/devices/bus/nes/namcot.h index bcf72f5bad4..1dcf237fa90 100644 --- a/src/devices/bus/nes/namcot.h +++ b/src/devices/bus/nes/namcot.h @@ -6,6 +6,7 @@ #pragma once #include "nxrom.h" +#include "sound/namco_163.h" // ======================> nes_namcot3433_device @@ -157,11 +158,13 @@ protected: // device-level overrides virtual void device_start() override; + virtual void device_add_mconfig(machine_config &config) override; + private: void set_mirror(uint8_t page, uint8_t data); uint8_t m_wram_protect, m_latch, m_chr_bank; - // TODO: add emulation of the sound part of the chip + required_device<namco_163_sound_device> m_namco163snd; }; diff --git a/src/devices/sound/namco_163.cpp b/src/devices/sound/namco_163.cpp new file mode 100644 index 00000000000..6fdde572537 --- /dev/null +++ b/src/devices/sound/namco_163.cpp @@ -0,0 +1,176 @@ +// license:BSD-3-Clause +// copyright-holders:cam900 +/*************************************************************************** + + Namco 163 internal sound emulation by cam900 + 4 bit wavetable (variable length), 1 ~ 8 channel + Reference : https://wiki.nesdev.com/w/index.php/Namco_163_audio + +***************************************************************************/ + +#include "emu.h" +#include "namco_163.h" + + +DEFINE_DEVICE_TYPE(NAMCO_163, namco_163_sound_device, "namco_163_sound", "Namco 163 (Sound)") + +namco_163_sound_device::namco_163_sound_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) + : device_t(mconfig, NAMCO_163, tag, owner, clock) + , device_sound_interface(mconfig, *this) + , m_ram(nullptr) + , m_reg_addr(0x78) + , m_addr(0) + , m_inc(false) + , m_disable(false) + , m_stream(nullptr) +{ +} + + +//------------------------------------------------- +// device_start - device-specific startup +//------------------------------------------------- + +void namco_163_sound_device::device_start() +{ + m_ram = make_unique_clear<u8[]>(0x80); + m_stream = machine().sound().stream_alloc(*this, 0, 1, clock() / 15); + + save_pointer(NAME(m_ram), 0x80); + save_item(NAME(m_reg_addr)); + save_item(NAME(m_addr)); + save_item(NAME(m_inc)); + save_item(NAME(m_disable)); +} + + +//------------------------------------------------- +// device_clock_changed - called if the clock +// changes +//------------------------------------------------- + +void namco_163_sound_device::device_clock_changed() +{ + m_stream->set_sample_rate(clock() / 15); +} + + +inline s8 namco_163_sound_device::get_sample(u16 addr) +{ + return ((m_ram[(addr >> 1) & 0x7f] >> ((addr & 1) << 2)) & 0xf) - 8; +} + + +WRITE_LINE_MEMBER(namco_163_sound_device::disable_w) +{ + m_disable = state; +} + + +/********************************************************************************/ + +/* + Register Map (in RAM) + + 40 ffff ffff Channel 0 Frequency bits 0 - 7 + 41 pppp pppp Channel 0 Phase bits 0 - 7 + 42 ffff ffff Channel 0 Frequency bits 8 - 15 + 43 pppp pppp Channel 0 Phase bits 8 - 15 + 44 ---- --ff Channel 0 Frequency bits 16 - 17 + llll ll-- Channel 0 Waveform Length (256 - (l * 4)) 4 bit samples + 45 pppp pppp Channel 0 Phase bits 16 - 23 + 46 oooo oooo Channel 0 Waveform Offset at 4 bit samples + 47 ---- cccc Channel 0 Volume + + 48 ffff ffff Channel 1 Frequency bits 0 - 7 + 49 pppp pppp Channel 1 Phase bits 0 - 7 + 4a ffff ffff Channel 1 Frequency bits 8 - 15 + 4b pppp pppp Channel 1 Phase bits 8 - 15 + 4c ---- --ff Channel 1 Frequency bits 16 - 17 + llll ll-- Channel 1 Waveform Length (256 - (l * 4)) 4 bit samples + 4d pppp pppp Channel 1 Phase bits 16 - 23 + 4e oooo oooo Channel 1 Waveform Offset at 4 bit samples + 4f ---- cccc Channel 1 Volume + + . + . + . + + 78 ffff ffff Channel 7 Frequency bits 0 - 7 + 79 pppp pppp Channel 7 Phase bits 0 - 7 + 7a ffff ffff Channel 7 Frequency bits 8 - 15 + 7b pppp pppp Channel 7 Phase bits 8 - 15 + 7c ---- --ff Channel 7 Frequency bits 16 - 17 + llll ll-- Channel 7 Waveform Length (256 - (l * 4)) 4 bit samples + 7d pppp pppp Channel 7 Phase bits 16 - 23 + 7e oooo oooo Channel 7 Waveform Offset at 4 bit samples + 7f ---- cccc Channel 7 Volume + -ccc ---- Enable channels + -000 ---- Enable channel 7 only + -001 ---- Enable channel 7, 6 + -010 ---- Enable channel 7, 6, 5 + + . + . + . + + -111 ---- Enable all channels +*/ + +void namco_163_sound_device::addr_w(u8 data) +{ + m_inc = data & 0x80; + m_addr = data & 0x7f; +} + + +void namco_163_sound_device::data_w(u8 data) +{ + m_stream->update(); + m_ram[m_addr] = data; + if (m_inc) + m_addr = (m_addr + 1) & 0x7f; +} + + +u8 namco_163_sound_device::data_r() +{ + u8 val = m_ram[m_addr]; + if (m_inc) + m_addr = (m_addr + 1) & 0x7f; + + return val; +} + + +void namco_163_sound_device::sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples) +{ + std::fill_n(&outputs[0][0], samples, 0); + + if (m_disable) + return; + + // Slightly noisy but closer to real hardware behavior + for (int s = 0; s < samples; s++) + { + u32 phase = (m_ram[m_reg_addr + 5] << 16) | (m_ram[m_reg_addr + 3] << 8) | m_ram[m_reg_addr + 1]; + const u32 freq = ((m_ram[m_reg_addr + 4] & 0x3) << 16) | (m_ram[m_reg_addr + 2] << 8) | m_ram[m_reg_addr + 0]; + const u16 length = 256 - (m_ram[m_reg_addr + 4] & 0xfc); + const u16 offset = m_ram[m_reg_addr + 6]; + const u8 vol = m_ram[m_reg_addr + 7] & 0xf; + + phase = (phase + freq) % (length << 16); + s32 output = get_sample((phase >> 16) + offset) * vol; + + m_ram[m_reg_addr + 1] = phase & 0xff; + m_ram[m_reg_addr + 3] = phase >> 8; + m_ram[m_reg_addr + 5] = phase >> 16; + + m_reg_addr += 8; + if (m_reg_addr >= 0x80) + { + m_reg_addr = 0x78 - ((m_ram[0x7f] & 0x70) >> 1); + } + outputs[0][s] = (output << 8); + } +} diff --git a/src/devices/sound/namco_163.h b/src/devices/sound/namco_163.h new file mode 100644 index 00000000000..1256884242b --- /dev/null +++ b/src/devices/sound/namco_163.h @@ -0,0 +1,42 @@ +// license:BSD-3-Clause +// copyright-holders:cam900 +#ifndef MAME_SOUND_NAMCO_163_H +#define MAME_SOUND_NAMCO_163_H + +#pragma once + + +class namco_163_sound_device : public device_t, + public device_sound_interface +{ +public: + namco_163_sound_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock); + + DECLARE_WRITE_LINE_MEMBER(disable_w); + + void addr_w(u8 data); + void data_w(u8 data); + u8 data_r(); + +protected: + // device-level overrides + virtual void device_start() override; + virtual void device_clock_changed() override; + + // global sound parameters + std::unique_ptr<u8[]> m_ram; + u8 m_reg_addr; + u8 m_addr; + bool m_inc; + bool m_disable; + sound_stream *m_stream; + + // internals + inline s8 get_sample(u16 addr); + + virtual void sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples) override; +}; + +DECLARE_DEVICE_TYPE(NAMCO_163, namco_163_sound_device) + +#endif // MAME_SOUND_NAMCO_163_H |