mirror of
https://github.com/holub/mame
synced 2025-10-04 16:34:53 +03:00
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
This commit is contained in:
parent
6dbd636a80
commit
80a48d5229
@ -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",
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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;
|
||||
};
|
||||
|
||||
|
||||
|
176
src/devices/sound/namco_163.cpp
Normal file
176
src/devices/sound/namco_163.cpp
Normal file
@ -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);
|
||||
}
|
||||
}
|
42
src/devices/sound/namco_163.h
Normal file
42
src/devices/sound/namco_163.h
Normal file
@ -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
|
Loading…
Reference in New Issue
Block a user