mirror of
https://github.com/holub/mame
synced 2025-06-27 06:39:03 +03:00
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]
This commit is contained in:
parent
4f331f8e63
commit
ec527a8468
@ -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))
|
||||
|
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user