From 80621acaf1329fb9dafe8742b2f696278c665752 Mon Sep 17 00:00:00 2001 From: AJR Date: Thu, 11 Feb 2021 18:24:55 -0500 Subject: grobda: Eliminate DAC and allow the 15XX custom to play the speech sample * sound/namco.cpp: Allow channels to still play with a frequency of 0; allow writes to manipulate the counter directly for namco15xx --- src/devices/sound/namco.cpp | 63 +++++++++++++++++++++++++-------------------- src/mame/drivers/mappy.cpp | 29 +++------------------ src/mame/includes/mappy.h | 4 --- 3 files changed, 39 insertions(+), 57 deletions(-) diff --git a/src/devices/sound/namco.cpp b/src/devices/sound/namco.cpp index 27a540872c2..6d112d4dc1f 100644 --- a/src/devices/sound/namco.cpp +++ b/src/devices/sound/namco.cpp @@ -492,6 +492,11 @@ void namco_device::polepos_sound_w(offs_t offset, uint8_t data) 0x3b ch 7 volume 0x3c-0x3d ch 7 frequency 0x3e ch 7 waveform select & frequency + +Grobda also stuffs values into register offset 0x02 with a frequency of zero +to make 15XX channels act like a 4-bit DAC instead of waveform voices. This +has been emulated by allowing writes to set the upper counter bits directly. +Possibly offsets 0x00 and 0x01 can be used to set the fractional bits. */ void namco_15xx_device::namco_15xx_w(offs_t offset, uint8_t data) @@ -516,6 +521,11 @@ void namco_15xx_device::namco_15xx_w(offs_t offset, uint8_t data) voice = m_channel_list + ch; switch (offset - ch * 8) { + case 0x02: + voice->counter &= util::make_bitmask(m_f_fracbits); + voice->counter |= uint32_t(data & 0x1f) << m_f_fracbits; + break; + case 0x03: voice->volume[0] = data & 0x0f; break; @@ -688,8 +698,8 @@ void namco_audio_device::sound_stream_update(sound_stream &stream, std::vectorfrequency & 0xff; - /* only update if we have non-zero volume and frequency */ - if ((lv || rv) && f) + /* only update if we have non-zero volume */ + if (lv || rv) { int hold_time = 1 << (m_f_fracbits - 16); int hold = voice->noise_hold; @@ -741,33 +751,29 @@ void namco_audio_device::sound_stream_update(sound_stream &stream, std::vectorfrequency) - { - /* save the counter for this voice */ - uint32_t c = voice->counter; - - /* only update if we have non-zero left volume */ - if (lv) - { - const int16_t *lw = &m_waveform[lv][voice->waveform_select * 32]; + /* save the counter for this voice */ + uint32_t c = voice->counter; - /* generate sound into the buffer */ - c = namco_update_one(lmix, lw, voice->counter, voice->frequency); - } + /* only update if we have non-zero left volume */ + if (lv) + { + const int16_t *lw = &m_waveform[lv][voice->waveform_select * 32]; - /* only update if we have non-zero right volume */ - if (rv) - { - const int16_t *rw = &m_waveform[rv][voice->waveform_select * 32]; + /* generate sound into the buffer */ + c = namco_update_one(lmix, lw, voice->counter, voice->frequency); + } - /* generate sound into the buffer */ - c = namco_update_one(rmix, rw, voice->counter, voice->frequency); - } + /* only update if we have non-zero right volume */ + if (rv) + { + const int16_t *rw = &m_waveform[rv][voice->waveform_select * 32]; - /* update the counter for this voice */ - voice->counter = c; + /* generate sound into the buffer */ + c = namco_update_one(rmix, rw, voice->counter, voice->frequency); } + + /* update the counter for this voice */ + voice->counter = c; } } } @@ -790,8 +796,9 @@ void namco_audio_device::sound_stream_update(sound_stream &stream, std::vectornoise_sw) { int f = voice->frequency & 0xff; - /* only update if we have non-zero volume and frequency */ - if (v && f) + + /* only update if we have non-zero volume */ + if (v) { int hold_time = 1 << (m_f_fracbits - 16); int hold = voice->noise_hold; @@ -836,8 +843,8 @@ void namco_audio_device::sound_stream_update(sound_stream &stream, std::vectorfrequency) + /* only update if we have non-zero volume */ + if (v) { const int16_t *w = &m_waveform[v][voice->waveform_select * 32]; diff --git a/src/mame/drivers/mappy.cpp b/src/mame/drivers/mappy.cpp index aa9b3d35015..bd4a0b76f8c 100644 --- a/src/mame/drivers/mappy.cpp +++ b/src/mame/drivers/mappy.cpp @@ -14,8 +14,9 @@ They can be divided in three "families": The hardware consists of two 6809, and several Namco custom ICs that provide a static tilemap and 2bpp sprites. Grobda is the only Namco game of this era that has speech (just a short - sample). At this time, it is still unknown how speech samples are transmitted - to the DAC (almost certainly the same resistor network used by the 15XX). + sample). It appears to do this by manipulating 15XX channels to deliver + non-waveform outputs (removing the 15XX from the board causes sound to + disappear completely). 2) Phozon. This game runs on an unique board: the large number of sprites on screen at the same time required a 3rd 6809 to help with the calculations. The sprite hardware is also different from Super Pacman, featuring 8x8 sprites. @@ -63,7 +64,7 @@ The I/O interface chips vary from game to game (see machine/namcoio.c) Super Pac-Man memory map ------------------------ -Pac & Pal is the same. Grobda appears to have a DAC hacked in. +Pac & Pal and Grobda are the same. Note: Part of the address decoding is done by PALs (SPC-5 and SPC-6) so the tables are inferred by program behaviour. @@ -680,23 +681,6 @@ void mappy_state::superpac_cpu2_map(address_map &map) map(0xe000, 0xffff).rom(); } -/* - The speech in Grobda might not be a standard Namco sound feature, but rather a hack. - The hardware automatically cycles the bottom 6 address lines of sound RAM, so they - probably added a latch loaded when the bottom 4 lines are 0010 (which corresponds - to locations not used by the sound hardware). - The program writes the same value to 0x02, 0x12, 0x22 and 0x32. - However, removing the 15XX from the board causes sound to disappear completely, so - the 15XX may still play some part in conveying speech to the DAC. -*/ - -void mappy_state::grobda_cpu2_map(address_map &map) -{ - superpac_cpu2_map(map); - - map(0x0002, 0x0002).w("dac", FUNC(dac_byte_interface::data_w)); -} - void mappy_state::phozon_cpu2_map(address_map &map) { map(0x0000, 0x03ff).rw(m_namco_15xx, FUNC(namco_15xx_device::sharedram_r), FUNC(namco_15xx_device::sharedram_w)); /* shared RAM with the main CPU + sound registers */ @@ -1417,8 +1401,6 @@ void mappy_state::grobda(machine_config &config) { superpac_common(config); - m_subcpu->set_addrmap(AS_PROGRAM, &mappy_state::grobda_cpu2_map); - NAMCO_58XX(config, m_namcoio[0], 0); m_namcoio[0]->in_callback<0>().set_ioport("COINS"); m_namcoio[0]->in_callback<1>().set_ioport("P1"); @@ -1431,9 +1413,6 @@ void mappy_state::grobda(machine_config &config) m_namcoio[1]->in_callback<2>().set_ioport("DSW1").rshift(4); m_namcoio[1]->in_callback<3>().set_ioport("DSW0"); m_namcoio[1]->out_callback<0>().set("dipmux", FUNC(ls157_device::select_w)).bit(0); - - /* sound hardware */ - DAC_4BIT_BINARY_WEIGHTED(config, "dac", 0).add_route(ALL_OUTPUTS, "speaker", 0.275); // alternate route to 15XX-related DAC? } void mappy_state::phozon(machine_config &config) diff --git a/src/mame/includes/mappy.h b/src/mame/includes/mappy.h index 455cebad247..4484011c8e7 100644 --- a/src/mame/includes/mappy.h +++ b/src/mame/includes/mappy.h @@ -6,7 +6,6 @@ #pragma once #include "machine/namcoio.h" -#include "sound/dac.h" #include "sound/namco.h" #include "emupal.h" #include "screen.h" @@ -24,7 +23,6 @@ public: m_subcpu2(*this, "sub2"), m_namcoio(*this, "namcoio_%u", 1), m_namco_15xx(*this, "namco"), - m_dac(*this, "dac"), m_gfxdecode(*this, "gfxdecode"), m_screen(*this, "screen"), m_palette(*this, "palette"), @@ -56,7 +54,6 @@ private: optional_device m_subcpu2; required_device_array m_namcoio; required_device m_namco_15xx; - optional_device m_dac; required_device m_gfxdecode; required_device m_screen; required_device m_palette; @@ -103,7 +100,6 @@ private: void mappy_draw_sprites(bitmap_ind16 &bitmap, const rectangle &cliprect, uint8_t *spriteram_base); void phozon_draw_sprites(bitmap_ind16 &bitmap, const rectangle &cliprect, uint8_t *spriteram_base); - void grobda_cpu2_map(address_map &map); void mappy_cpu1_map(address_map &map); void mappy_cpu2_map(address_map &map); void phozon_cpu1_map(address_map &map); -- cgit v1.2.3