From ec527a84682a48fc74effe66e7e155f3acdd966a Mon Sep 17 00:00:00 2001 From: Lord-Nightmare Date: Fri, 1 Sep 2017 01:13:01 -0400 Subject: grchamp.cpp: Fixed the sound latch system such that the bit 7 clearing actually works, and properly synchronized the sound latch writes and bit 7 clears. Added memory map comment for sound cpu. Added missing sound nmi enable, and hooked sound nmi to the sound semaphore. Added sound semaphore readback. [Lord Nightmare] --- src/mame/drivers/grchamp.cpp | 97 ++++++++++++++++++++++++++++++++++++++++---- src/mame/includes/grchamp.h | 14 +++++-- 2 files changed, 100 insertions(+), 11 deletions(-) diff --git a/src/mame/drivers/grchamp.cpp b/src/mame/drivers/grchamp.cpp index 70b2416ac8b..3b356724bfa 100644 --- a/src/mame/drivers/grchamp.cpp +++ b/src/mame/drivers/grchamp.cpp @@ -24,6 +24,17 @@ Note that a dipswitch setting allows score to be displayed onscreen, but there's no equivalent for tachometer. + - TODO: the two sound callbacks could, under unusual circumstances, + conflict with one another, causing the newly written value to have + its bit 7 cleared before the sound cpu reads it. + The proper way to handle this is to use a single callback which + processes a timestamped event queue. + + - TODO: merge the sound system with taitosj.cpp, as the sound system + is almost completely identical. Also import the taitosj.cpp dac/volume + system, as the system used in audio/grchamp.cpp for dac output is + incorrect. + Notes: - The object of the game is to avoid the opposing cars. @@ -82,6 +93,8 @@ void grchamp_state::machine_start() { + m_soundlatch_data = 0x00; + m_soundlatch_flag = false; save_item(NAME(m_cpu0_out)); save_item(NAME(m_cpu1_out)); save_item(NAME(m_comm_latch)); @@ -95,6 +108,7 @@ void grchamp_state::machine_start() void grchamp_state::machine_reset() { + m_soundnmi->in_w<0>(1); // disable sound nmi /* if the coin system is 1 way, lock Coin B (Page 40) */ machine().bookkeeping().coin_lockout_w(1, (ioport("DSWB")->read() & 0x10) ? 1 : 0); } @@ -202,8 +216,7 @@ WRITE8_MEMBER(grchamp_state::cpu0_outputs_w) case 0x0e: /* OUT14 */ /* O-21 connector */ - m_soundlatch->write(space, 0, data); - m_audiocpu->set_input_line(INPUT_LINE_NMI, PULSE_LINE); + machine().scheduler().synchronize(timer_expired_delegate(FUNC(grchamp_state::soundlatch_w_cb), this), data); // soundlatch write, needs to synchronize break; } } @@ -423,6 +436,41 @@ READ8_MEMBER(grchamp_state::main_to_sub_comm_r) * Sound port handlers * *************************************/ +TIMER_CALLBACK_MEMBER(grchamp_state::soundlatch_w_cb) +{ + if ((m_soundlatch_flag != false) && (m_soundlatch_data != param)) + logerror("Warning: soundlatch written before being read. Previous: %02x, new: %02x\n", m_soundlatch_data, param); + m_soundlatch_data = param; + m_soundlatch_flag = true; + m_soundnmi->in_w<1>(1); +} + +TIMER_CALLBACK_MEMBER(grchamp_state::soundlatch_clear7_w_cb) +{ + if (m_soundlatch_flag != false) + logerror("Warning: soundlatch bit 7 cleared before being read. Previous: %02x, new: %02x\n", m_soundlatch_data, m_soundlatch_data&0x7f); + m_soundlatch_data &= 0x7F; +} + +READ8_MEMBER(grchamp_state::soundlatch_r) +{ + if (!machine().side_effect_disabled()) + { + m_soundlatch_flag = false; + m_soundnmi->in_w<1>(0); + } + return m_soundlatch_data; +} + +WRITE8_MEMBER(grchamp_state::soundlatch_clear7_w) +{ + machine().scheduler().synchronize(timer_expired_delegate(FUNC(grchamp_state::soundlatch_clear7_w_cb), this), data); +} + +READ8_MEMBER(grchamp_state::soundlatch_flags_r) +{ + return 0x03 | (m_soundlatch_flag?0x8:0); +} WRITE8_MEMBER(grchamp_state::portA_0_w) { @@ -436,12 +484,13 @@ WRITE8_MEMBER(grchamp_state::portB_0_w) WRITE8_MEMBER(grchamp_state::portA_2_w) { - /* A0/A1 modify the output of AY8910 #2 */ - /* A7 contributes to the discrete logic hanging off of AY8910 #0 */ + /* A0/A1 modify the output of AY8910 #2 with filter capacitors */ + /* A7 contributes to the volume control for the discrete logic dac hanging off of AY8910 #0's i/o ports */ } WRITE8_MEMBER(grchamp_state::portB_2_w) { - /* B0 connects elsewhere */ + /* B0 is the sound nmi enable, active low */ + m_soundnmi->in_w<0>((~data)&1); } @@ -535,9 +584,39 @@ static ADDRESS_MAP_START( sub_portmap, AS_IO, 8, grchamp_state ) ADDRESS_MAP_END -/* complete memory map derived from schematics */ +/* complete memory map derived from schematics; + the grchamp sound system is almost identical to taitosj.cpp sound system +*/ +/* Sound cpu address map ( * = used within this section; x = don't care ) + | | | +15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 + 0 * * * R 74LS138 @ 10B + 0 0 0 0 * * * * * * * * * * * * R ROM (7B) + 0 0 0 1 * * * * * * * * * * * * R ROM (6B) +(0 0 1 0 * * * * * * * * * * * * R ROM (5B), not populated, OPEN BUS) +(0 0 1 1 * * * * * * * * * * * * R ROM (4B), not populated, OPEN BUS) +(0 1 * * x x x x x x x x x x x x R is also decoded by the 74LS138 @ 10B, but those four outputs are not connected anywhere and that region is occupied below) + 0 1 * * * RW 74LS138 @ 9C + 0 1 0 0 0 0 * * * * * * * * * * RW SRAMs (2x 2114 @ 5C, 4C) + 0 1 0 0 0 1 x x x x x x x x x x OPEN BUS + 0 1 0 0 1 RW /CS5 (AY chips, this area has a 2 clock waitstate penalty on any access) + 0 1 0 0 1 x x x x x x x x 0 0 0 W Address AY @ 3B (with dac/volume connected to ioa/iob) + 0 1 0 0 1 x x x x x x x x 0 0 1 RW Data AY @ 3B (with dac/volume connected to ioa/iob) + 0 1 0 0 1 x x x x x x x x 0 1 0 W Address AY @ 2B + 0 1 0 0 1 x x x x x x x x 0 1 1 RW Data AY @ 2B + 0 1 0 0 1 x x x x x x x x 1 x 0 W Address AY @ 1B (with filter caps on ioa1,ioa0, nmi enable on iob0, dac attenuate on ioa7) + 0 1 0 0 1 x x x x x x x x 1 x 1 RW Data AY @ 1B (with filter caps on ioa1,ioa0, nmi enable on iob0, dac attenuate on ioa7) + 0 1 0 1 0 RW /CS6 (soundlatch/semaphores/nmi state) + 0 1 0 1 0 x x x x x x x x x * * RW 74155 @ 6D + 0 1 0 1 0 x x x x x x x x x 0 0 R Read soundlatch, and clear main->sound semaphore + 0 1 0 1 0 x x x x x x x x x 0 0 W Clear bit 7 in soundlatch + 0 1 0 1 0 x x x x x x x x x 0 1 R Read main->sound semaphore state in bit 3, bit 2 is 0, bits 1 and 0 are both 1, remaining bits are open bus + 0 1 0 1 0 x x x x x x x x x 0 1 W OPEN BUS + 0 1 0 1 0 x x x x x x x x x 1 x RW OPEN BUS +*/ static ADDRESS_MAP_START( sound_map, AS_PROGRAM, 8, grchamp_state ) AM_RANGE(0x0000, 0x1fff) AM_ROM + // 2000-3fff are empty rom sockets AM_RANGE(0x4000, 0x43ff) AM_RAM AM_RANGE(0x4800, 0x4801) AM_MIRROR(0x07f8) AM_DEVWRITE("ay1", ay8910_device, address_data_w) AM_RANGE(0x4801, 0x4801) AM_MIRROR(0x07f8) AM_DEVREAD("ay1", ay8910_device, data_r) @@ -545,7 +624,8 @@ static ADDRESS_MAP_START( sound_map, AS_PROGRAM, 8, grchamp_state ) AM_RANGE(0x4803, 0x4803) AM_MIRROR(0x07f8) AM_DEVREAD("ay2", ay8910_device, data_r) AM_RANGE(0x4804, 0x4805) AM_MIRROR(0x07fa) AM_DEVWRITE("ay3", ay8910_device, address_data_w) AM_RANGE(0x4805, 0x4805) AM_MIRROR(0x07fa) AM_DEVREAD("ay3", ay8910_device, data_r) - AM_RANGE(0x5000, 0x5000) AM_DEVREAD("soundlatch", generic_latch_8_device, read) + AM_RANGE(0x5000, 0x5000) AM_MIRROR(0x07fc) AM_READ(soundlatch_r) AM_WRITE(soundlatch_clear7_w) + AM_RANGE(0x5001, 0x5001) AM_MIRROR(0x07fc) AM_READ(soundlatch_flags_r) AM_WRITENOP // writes here on taitosj reset the secondary semaphore, which doesn't exist on grchamp, but the code tries to reset it anyway! ADDRESS_MAP_END @@ -682,7 +762,8 @@ static MACHINE_CONFIG_START( grchamp ) /* sound hardware */ MCFG_SPEAKER_STANDARD_MONO("mono") - MCFG_GENERIC_LATCH_8_ADD("soundlatch") + MCFG_INPUT_MERGER_ALL_HIGH("soundnmi") + MCFG_INPUT_MERGER_OUTPUT_HANDLER(INPUTLINE("audiocpu", INPUT_LINE_NMI)) MCFG_SOUND_ADD("ay1", AY8910, SOUND_CLOCK/4) /* 3B */ MCFG_AY8910_PORT_A_WRITE_CB(WRITE8(grchamp_state, portA_0_w)) diff --git a/src/mame/includes/grchamp.h b/src/mame/includes/grchamp.h index 32790312286..c721b302e6d 100644 --- a/src/mame/includes/grchamp.h +++ b/src/mame/includes/grchamp.h @@ -6,7 +6,7 @@ *************************************************************************/ -#include "machine/gen_latch.h" +#include "machine/input_merger.h" #include "machine/watchdog.h" #include "sound/discrete.h" #include "screen.h" @@ -24,7 +24,7 @@ public: m_gfxdecode(*this, "gfxdecode"), m_palette(*this, "palette"), m_screen(*this, "screen"), - m_soundlatch(*this, "soundlatch"), + m_soundnmi(*this, "soundnmi"), m_radarram(*this, "radarram"), m_videoram(*this, "videoram"), m_spriteram(*this, "spriteram"), @@ -40,7 +40,7 @@ public: required_device m_gfxdecode; required_device m_palette; required_device m_screen; - required_device m_soundlatch; + required_device m_soundnmi; required_shared_ptr m_radarram; required_shared_ptr m_videoram; @@ -59,6 +59,9 @@ public: uint8_t m_ledaddr; uint16_t m_ledram[8]; + uint8_t m_soundlatch_data; + bool m_soundlatch_flag; + uint16_t m_collide; uint8_t m_collmode; @@ -82,6 +85,11 @@ public: DECLARE_WRITE8_MEMBER(left_w); DECLARE_WRITE8_MEMBER(center_w); DECLARE_WRITE8_MEMBER(right_w); + TIMER_CALLBACK_MEMBER(soundlatch_w_cb); + TIMER_CALLBACK_MEMBER(soundlatch_clear7_w_cb); + DECLARE_READ8_MEMBER(soundlatch_r); + DECLARE_WRITE8_MEMBER(soundlatch_clear7_w); + DECLARE_READ8_MEMBER(soundlatch_flags_r); DECLARE_WRITE8_MEMBER(portA_0_w); DECLARE_WRITE8_MEMBER(portB_0_w); DECLARE_WRITE8_MEMBER(portA_2_w); -- cgit v1.2.3