summaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
author Lord-Nightmare <Lord-Nightmare@users.noreply.github.com>2017-09-01 01:13:01 -0400
committer Lord-Nightmare <Lord-Nightmare@users.noreply.github.com>2017-09-01 01:13:01 -0400
commitec527a84682a48fc74effe66e7e155f3acdd966a (patch)
treec7cef400a034b3af29a14e9a17c40f8aa2061394
parent4f331f8e63b4da250b45e1de9b3402f517664ebc (diff)
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]
-rw-r--r--src/mame/drivers/grchamp.cpp97
-rw-r--r--src/mame/includes/grchamp.h14
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<gfxdecode_device> m_gfxdecode;
required_device<palette_device> m_palette;
required_device<screen_device> m_screen;
- required_device<generic_latch_8_device> m_soundlatch;
+ required_device<input_merger_device> m_soundnmi;
required_shared_ptr<uint8_t> m_radarram;
required_shared_ptr<uint8_t> 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);