summaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
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
commit80a48d5229eb5ff62b4f27ec6351226b672c0030 (patch)
tree4122cd513df488d8b5a68b304abbff7b82f20b8a
parent6dbd636a809ce7bda3ec476239f7b32a2d1de537 (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.lua8
-rw-r--r--scripts/target/mame/arcade.lua1
-rw-r--r--scripts/target/mame/mess.lua1
-rw-r--r--src/devices/bus/nes/namcot.cpp33
-rw-r--r--src/devices/bus/nes/namcot.h5
-rw-r--r--src/devices/sound/namco_163.cpp176
-rw-r--r--src/devices/sound/namco_163.h42
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