summaryrefslogtreecommitdiffstatshomepage
path: root/src
diff options
context:
space:
mode:
author AJR <ajrhacker@users.noreply.github.com>2017-01-04 15:10:23 -0500
committer AJR <ajrhacker@users.noreply.github.com>2017-01-04 17:43:31 -0500
commit6f8c39e442abbad88cb124266f503036facb00e2 (patch)
tree40ff85dd46aad66937a016b6645f98bd6a4264df /src
parent47c4f47bd40def91566dda49cc378d4ae0d63e37 (diff)
Cedar Magnet/EFO ZSU
- Conversion of the Cedar Magnet board from a base device class to a mix-in interface - Emulate EFO ZSU as main variant of the Cedar Magnet sound board - Hook up ZSU1 to Skill Flight and Phantom Ship - Modernize ZSU soundlatch/IRQ mechanism - More hardware notes (nw) - Various associated code cleanups (nw)
Diffstat (limited to 'src')
-rw-r--r--src/mame/audio/efo_zsu.cpp275
-rw-r--r--src/mame/audio/efo_zsu.h (renamed from src/mame/machine/cedar_magnet_sound.h)45
-rw-r--r--src/mame/drivers/cedar_magnet.cpp38
-rw-r--r--src/mame/drivers/play_3.cpp126
-rw-r--r--src/mame/machine/cedar_magnet_board.cpp65
-rw-r--r--src/mame/machine/cedar_magnet_board.h45
-rw-r--r--src/mame/machine/cedar_magnet_plane.cpp6
-rw-r--r--src/mame/machine/cedar_magnet_plane.h5
-rw-r--r--src/mame/machine/cedar_magnet_sound.cpp208
-rw-r--r--src/mame/machine/cedar_magnet_sprite.cpp8
-rw-r--r--src/mame/machine/cedar_magnet_sprite.h2
11 files changed, 473 insertions, 350 deletions
diff --git a/src/mame/audio/efo_zsu.cpp b/src/mame/audio/efo_zsu.cpp
new file mode 100644
index 00000000000..7fe7744e69b
--- /dev/null
+++ b/src/mame/audio/efo_zsu.cpp
@@ -0,0 +1,275 @@
+// license:BSD-3-Clause
+// copyright-holders:David Haywood,AJR
+
+/***************************************************************************
+
+ ZSU Sound Control Unit (Proyectado 21/4/86 J. Gamell)
+ ZSU1 Sound Control Unit (Proyectado 12/6/86 J. Gamell)
+ Cedar Magnet Sound Board
+
+ The ZSU board is a component of the Z-Pinball hardware developed by
+ E.F.O. (Electrónica Funcional Operativa) S.A. of Barcelona, Spain. Its
+ sound generators are 2 AY-3-8910As and 1 OKI MSM5205, and 2 MF10s and
+ 1 HC4066 are used to mix their outputs. The timing circuits are rather
+ intricate, using Z80-CTCs, HC74s and HC393s and various other gates to
+ drive both the 5205 and the SGS HCF40105BE through which its samples
+ are funneled.
+
+ There are no available schematics for the Cedar Magnet video game
+ system (also designed by E.F.O.), but its sound board is believed to be
+ a close analogue of ZSU, since it includes all of the aforementioned
+ devices. The main known difference is that the Cedar Magnet sound
+ code and data are externally loaded into 64K of RAM (2xTMM41464P-15),
+ whereas ZSU's memory map consists primarily of a bank of up to 5 27256
+ EPROMs switched from two output lines of the first 8910, overlaid with
+ a mere 2K of RAM.
+
+ irq vectors
+
+ 0xe6 - from ctc0 channel 3 (vector = E0) used to drive MSM5205 through FIFO
+ 0xee - from ctc0 channel 3 (vector = E8) ^^
+ 0xf6 - drive AY (once per frame?) triggered by ctc1 channel 3 (vector = F0)
+ 0xff - read sound latch (triggered by write from master board; default vector set by 5K/+5 pullups on D0-D7)
+
+***************************************************************************/
+
+#include "emu.h"
+#include "audio/efo_zsu.h"
+
+#include "machine/clock.h"
+#include "machine/input_merger.h"
+
+
+extern const device_type EFO_ZSU = &device_creator<efo_zsu_device>;
+extern const device_type EFO_ZSU1 = &device_creator<efo_zsu1_device>;
+extern const device_type CEDAR_MAGNET_SOUND = &device_creator<cedar_magnet_sound_device>;
+
+
+efo_zsu_device::efo_zsu_device(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, u32 clock, const char *shortname, const char *source)
+ : device_t(mconfig, type, name, tag, owner, clock, shortname, source),
+ m_ctc0(*this, "ctc0"),
+ m_ctc1(*this, "ctc1"),
+ m_soundlatch(*this, "soundlatch"),
+ m_fifo(*this, "fifo"),
+ m_adpcm(*this, "adpcm")
+{
+}
+
+
+efo_zsu_device::efo_zsu_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock)
+ : efo_zsu_device(mconfig, EFO_ZSU, "ZSU Sound Control Unit", tag, owner, clock, "efo_zsu", __FILE__)
+{
+}
+
+
+efo_zsu1_device::efo_zsu1_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock)
+ : efo_zsu_device(mconfig, EFO_ZSU1, "ZSU1 Sound Control Unit", tag, owner, clock, "efo_zsu1", __FILE__)
+{
+}
+
+
+cedar_magnet_sound_device::cedar_magnet_sound_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock)
+ : efo_zsu_device(mconfig, CEDAR_MAGNET_SOUND, "Cedar Sound", tag, owner, clock, "cedmag_sound", __FILE__),
+ cedar_magnet_board_interface(mconfig, *this, "soundcpu", "ram")
+{
+}
+
+
+WRITE8_MEMBER(efo_zsu_device::sound_command_w)
+{
+ m_soundlatch->write(space, 0, data);
+}
+
+
+
+static ADDRESS_MAP_START( zsu_map, AS_PROGRAM, 8, efo_zsu_device )
+ AM_RANGE(0x0000, 0x6fff) AM_ROM
+ AM_RANGE(0x7000, 0x77ff) AM_MIRROR(0x0800) AM_RAM
+ AM_RANGE(0x8000, 0xffff) AM_ROMBANK("rombank")
+ADDRESS_MAP_END
+
+static ADDRESS_MAP_START( cedar_magnet_sound_map, AS_PROGRAM, 8, cedar_magnet_sound_device )
+ AM_RANGE(0x0000, 0xffff) AM_RAM AM_SHARE("ram")
+ADDRESS_MAP_END
+
+static ADDRESS_MAP_START( zsu_io, AS_IO, 8, efo_zsu_device )
+ ADDRESS_MAP_GLOBAL_MASK(0xff)
+ ADDRESS_MAP_UNMAP_HIGH
+
+ AM_RANGE(0x00, 0x03) AM_DEVREADWRITE("ctc0", z80ctc_device, read, write)
+ AM_RANGE(0x04, 0x07) AM_DEVREADWRITE("ctc1", z80ctc_device, read, write)
+
+ AM_RANGE(0x08, 0x08) AM_WRITE(adpcm_fifo_w)
+
+ AM_RANGE(0x0c, 0x0c) AM_DEVWRITE("aysnd0", ay8910_device, address_w)
+ AM_RANGE(0x0d, 0x0d) AM_DEVWRITE("aysnd0", ay8910_device, data_w)
+
+ AM_RANGE(0x10, 0x10) AM_DEVWRITE("aysnd1", ay8910_device, address_w)
+ AM_RANGE(0x11, 0x11) AM_DEVWRITE("aysnd1", ay8910_device, data_w)
+
+ AM_RANGE(0x14, 0x14) AM_DEVREAD("soundlatch", generic_latch_8_device, read)
+
+ADDRESS_MAP_END
+
+WRITE8_MEMBER(efo_zsu_device::adpcm_fifo_w)
+{
+ // Z80 code first unpacks 8 bytes of ADPCM sample data into nibbles
+ // and, upon receiving interrupt vector E6, fills FIFO at once using OTIR
+ // 4-bit data is shifted out of the FIFO to the MSM5205 by another timer
+ m_fifo->write(data & 0x0f); // only low nibble is used here
+ m_fifo->si_w(1);
+ m_fifo->si_w(0);
+}
+
+WRITE8_MEMBER(cedar_magnet_sound_device::ay0_porta_w)
+{
+ // unknown (not in ZSU schematic); 0x80 written on reset
+}
+
+WRITE8_MEMBER(efo_zsu_device::ay1_porta_w)
+{
+ m_adpcm->reset_w(data & 1);
+ if (data & 1)
+ m_fifo->reset();
+ // D4-D6 likely used to select clock for ctc0 channel 2
+ // other bits probably used to modulate analog sound output
+}
+
+WRITE_LINE_MEMBER(efo_zsu_device::ctc0_z0_w)
+{
+// printf("USED ctc0_z0_w %d\n", state);
+}
+
+WRITE_LINE_MEMBER(efo_zsu_device::ctc0_z1_w)
+{
+// printf("USED ctc0_z1_w %d\n", state);
+}
+
+WRITE_LINE_MEMBER(efo_zsu_device::ctc1_z0_w)
+{
+ printf("ctc1_z0_w %d\n", state);
+}
+
+WRITE_LINE_MEMBER(efo_zsu_device::ctc1_z1_w)
+{
+ printf("ctc1_z1_w %d\n", state);
+}
+
+WRITE_LINE_MEMBER(efo_zsu_device::ctc1_z2_w)
+{
+ printf("ctc1_z2_w %d\n", state);
+}
+
+WRITE_LINE_MEMBER(efo_zsu_device::ctc0_z2_w)
+{
+ printf("ctc0_z2_w %d\n", state);
+}
+
+WRITE_LINE_MEMBER(efo_zsu_device::fifo_dor_w)
+{
+ // combined with a clock signal and used to drive ctc0 channel 3
+}
+
+static const z80_daisy_config daisy_chain[] =
+{
+ { "ctc1" },
+ { "ctc0" },
+ { nullptr }
+};
+
+TIMER_CALLBACK_MEMBER(cedar_magnet_sound_device::reset_assert_callback)
+{
+ cedar_magnet_board_interface::reset_assert_callback(ptr,param);
+ // reset lines go to the ctc as well?
+ m_ctc0->reset();
+ m_ctc1->reset();
+}
+
+
+
+static MACHINE_CONFIG_FRAGMENT( efo_zsu )
+ MCFG_CPU_ADD("soundcpu", Z80, 4000000)
+ MCFG_CPU_PROGRAM_MAP(zsu_map)
+ MCFG_CPU_IO_MAP(zsu_io)
+ MCFG_Z80_DAISY_CHAIN(daisy_chain)
+
+ MCFG_DEVICE_ADD("ctc0", Z80CTC, 4000000)
+ MCFG_Z80CTC_INTR_CB(DEVWRITELINE("soundirq", input_merger_device, in0_w))
+ MCFG_Z80CTC_ZC0_CB(WRITELINE(efo_zsu_device, ctc0_z0_w))
+ MCFG_Z80CTC_ZC1_CB(WRITELINE(efo_zsu_device, ctc0_z1_w))
+ MCFG_Z80CTC_ZC2_CB(WRITELINE(efo_zsu_device, ctc0_z2_w))
+
+ MCFG_DEVICE_ADD("ctc1", Z80CTC, 4000000)
+ MCFG_Z80CTC_INTR_CB(DEVWRITELINE("soundirq", input_merger_device, in0_w))
+ MCFG_Z80CTC_ZC0_CB(WRITELINE(efo_zsu_device, ctc1_z0_w))
+ MCFG_Z80CTC_ZC1_CB(WRITELINE(efo_zsu_device, ctc1_z1_w))
+ MCFG_Z80CTC_ZC2_CB(WRITELINE(efo_zsu_device, ctc1_z2_w))
+
+#if 0 // does nothing useful now
+ MCFG_DEVICE_ADD("ck1mhz", CLOCK, 4000000/4)
+ MCFG_CLOCK_SIGNAL_HANDLER(DEVWRITELINE("ctc1", z80ctc_device, trg0))
+ MCFG_DEVCB_CHAIN_OUTPUT(DEVWRITELINE("ctc1", z80ctc_device, trg1))
+ MCFG_DEVCB_CHAIN_OUTPUT(DEVWRITELINE("ctc1", z80ctc_device, trg2))
+#endif
+
+ MCFG_GENERIC_LATCH_8_ADD("soundlatch")
+ MCFG_GENERIC_LATCH_DATA_PENDING_CB(DEVWRITELINE("soundirq", input_merger_device, in1_w))
+
+ MCFG_INPUT_MERGER_ACTIVE_HIGH("soundirq") // 74HC03 NAND gate
+ MCFG_INPUT_MERGER_OUTPUT_HANDLER(INPUTLINE("soundcpu", INPUT_LINE_IRQ0))
+
+ MCFG_SPEAKER_STANDARD_MONO("mono")
+
+ MCFG_SOUND_ADD("aysnd0", AY8910, 4000000/2)
+ MCFG_AY8910_PORT_A_WRITE_CB(MEMBANK("rombank")) MCFG_DEVCB_MASK(0x03)
+ MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 0.5)
+
+ MCFG_SOUND_ADD("aysnd1", AY8910, 4000000/2)
+ MCFG_AY8910_PORT_A_WRITE_CB(WRITE8(efo_zsu_device, ay1_porta_w))
+ MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 0.5)
+
+ MCFG_DEVICE_ADD("fifo", HC40105, 0)
+ MCFG_40105_DATA_OUT_READY_CB(WRITELINE(efo_zsu_device, fifo_dor_w))
+ MCFG_40105_DATA_OUT_CB(DEVWRITELINE("adpcm", msm5205_device, data_w))
+
+ MCFG_SOUND_ADD("adpcm", MSM5205, 4000000/8)
+ MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 0.50)
+MACHINE_CONFIG_END
+
+static MACHINE_CONFIG_FRAGMENT( cedar_magnet_sound )
+ MCFG_FRAGMENT_ADD(efo_zsu)
+
+ MCFG_CPU_MODIFY("soundcpu")
+ MCFG_CPU_PROGRAM_MAP(cedar_magnet_sound_map)
+
+ MCFG_SOUND_MODIFY("aysnd0")
+ MCFG_AY8910_PORT_A_WRITE_CB(WRITE8(cedar_magnet_sound_device, ay0_porta_w))
+MACHINE_CONFIG_END
+
+machine_config_constructor efo_zsu_device::device_mconfig_additions() const
+{
+ return MACHINE_CONFIG_NAME( efo_zsu );
+}
+
+machine_config_constructor cedar_magnet_sound_device::device_mconfig_additions() const
+{
+ return MACHINE_CONFIG_NAME( cedar_magnet_sound );
+}
+
+void efo_zsu_device::device_start()
+{
+ memory_bank *rombank = membank("rombank");
+ rombank->configure_entries(0, 4, &static_cast<u8 *>(memregion("soundcpu")->base())[0x8000], 0x8000);
+ rombank->set_entry(0); // 10K/GND pulldowns on banking lines
+}
+
+void efo_zsu1_device::device_start()
+{
+ memory_bank *rombank = membank("rombank");
+ rombank->configure_entries(0, 4, &static_cast<u8 *>(memregion("soundcpu")->base())[0x8000], 0x8000);
+ rombank->set_entry(3); // 10K/+5 pullups on banking lines
+}
+
+void cedar_magnet_sound_device::device_start()
+{
+}
diff --git a/src/mame/machine/cedar_magnet_sound.h b/src/mame/audio/efo_zsu.h
index 0d1a5d0226b..928f7800a8e 100644
--- a/src/mame/machine/cedar_magnet_sound.h
+++ b/src/mame/audio/efo_zsu.h
@@ -1,5 +1,5 @@
// license:BSD-3-Clause
-// copyright-holders:David Haywood
+// copyright-holders:David Haywood,AJR
#pragma once
@@ -9,36 +9,37 @@
#include "cpu/z80/z80.h"
#include "cpu/z80/z80daisy.h"
#include "machine/z80ctc.h"
+#include "machine/gen_latch.h"
#include "machine/40105.h"
#include "sound/ay8910.h"
#include "sound/msm5205.h"
#include "machine/cedar_magnet_board.h"
+extern const device_type EFO_ZSU;
+extern const device_type EFO_ZSU1;
extern const device_type CEDAR_MAGNET_SOUND;
#define MCFG_CEDAR_MAGNET_SOUND_ADD(_tag) \
MCFG_DEVICE_ADD(_tag, CEDAR_MAGNET_SOUND, 0)
-class cedar_magnet_sound_device : public cedar_magnet_board_device
+class efo_zsu_device : public device_t
{
public:
// construction/destruction
- cedar_magnet_sound_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
+ efo_zsu_device(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, u32 clock, const char *shortname, const char *source);
+ efo_zsu_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock);
required_device<z80ctc_device> m_ctc0;
required_device<z80ctc_device> m_ctc1;
+ required_device<generic_latch_8_device> m_soundlatch;
required_device<cmos_40105_device> m_fifo;
required_device<msm5205_device> m_adpcm;
- DECLARE_READ8_MEMBER(soundlatch_r);
+ DECLARE_WRITE8_MEMBER(sound_command_w);
DECLARE_WRITE8_MEMBER(adpcm_fifo_w);
- DECLARE_WRITE8_MEMBER(ay0_porta_w);
DECLARE_WRITE8_MEMBER(ay1_porta_w);
- void write_command(uint8_t data);
- uint8_t m_command;
-
DECLARE_WRITE_LINE_MEMBER(ctc1_z0_w);
DECLARE_WRITE_LINE_MEMBER(ctc1_z1_w);
DECLARE_WRITE_LINE_MEMBER(ctc1_z2_w);
@@ -47,12 +48,38 @@ public:
DECLARE_WRITE_LINE_MEMBER(ctc0_z2_w);
DECLARE_WRITE_LINE_MEMBER(fifo_dor_w);
+protected:
+ virtual machine_config_constructor device_mconfig_additions() const override;
+ virtual void device_start() override;
+
+private:
+};
+
+
+class efo_zsu1_device : public efo_zsu_device
+{
+public:
+ // construction/destruction
+ efo_zsu1_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock);
+
+protected:
+ virtual void device_start() override;
+};
+
+
+class cedar_magnet_sound_device : public efo_zsu_device, public cedar_magnet_board_interface
+{
+public:
+ // construction/destruction
+ cedar_magnet_sound_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock);
+
+ DECLARE_WRITE8_MEMBER(ay0_porta_w);
+
TIMER_CALLBACK_MEMBER(reset_assert_callback) override;
protected:
virtual machine_config_constructor device_mconfig_additions() const override;
virtual void device_start() override;
- virtual void device_reset() override;
private:
};
diff --git a/src/mame/drivers/cedar_magnet.cpp b/src/mame/drivers/cedar_magnet.cpp
index 1b972602df0..09d91496f82 100644
--- a/src/mame/drivers/cedar_magnet.cpp
+++ b/src/mame/drivers/cedar_magnet.cpp
@@ -110,7 +110,7 @@ I suspect the additional memory was an afterthought.
#include "machine/z80ctc.h"
#include "sound/ay8910.h"
-#include "machine/cedar_magnet_sound.h"
+#include "audio/efo_zsu.h"
#include "machine/cedar_magnet_plane.h"
#include "machine/cedar_magnet_sprite.h"
#include "machine/cedar_magnet_flop.h"
@@ -185,8 +185,6 @@ public:
DECLARE_READ8_MEMBER(port7c_r);
// other ports
- DECLARE_WRITE8_MEMBER(soundlatch_w);
- uint8_t portff_data;
DECLARE_READ8_MEMBER(other_cpu_r);
DECLARE_WRITE8_MEMBER(other_cpu_w);
@@ -203,7 +201,7 @@ public:
DECLARE_WRITE8_MEMBER(palette_g_w);
DECLARE_WRITE8_MEMBER(palette_b_w);
- void handle_sub_board_cpu_lines(cedar_magnet_board_device* dev, int old_data, int data);
+ void handle_sub_board_cpu_lines(cedar_magnet_board_interface &dev, int old_data, int data);
INTERRUPT_GEN_MEMBER(irq);
void(*m_prothack)(cedar_magnet_state*);
@@ -271,7 +269,7 @@ static ADDRESS_MAP_START( cedar_magnet_io, AS_IO, 8, cedar_magnet_state )
AM_RANGE(0x78, 0x78) AM_READWRITE(watchdog_r, paladdr_w)
AM_RANGE(0x7c, 0x7c) AM_READ(port7c_r) // protection??
- AM_RANGE(0xff, 0xff) AM_WRITE(soundlatch_w)
+ AM_RANGE(0xff, 0xff) AM_DEVWRITE("cedtop", cedar_magnet_sound_device, sound_command_w)
ADDRESS_MAP_END
static ADDRESS_MAP_START( cedar_bank0, AS_PROGRAM, 8, cedar_magnet_state )
@@ -441,13 +439,6 @@ void cedar_magnet_state::video_start()
***********************/
-WRITE8_MEMBER(cedar_magnet_state::soundlatch_w)
-{
-// printf("%s: writing soundlatch_w! %02x\n", machine().describe_context(), data);
- portff_data = data;
- m_cedsound->write_command(data);
-}
-
READ8_MEMBER(cedar_magnet_state::other_cpu_r)
{
int bankbit0 = (m_ic48_pio_pa_val & 0x60) >> 5;
@@ -544,19 +535,19 @@ WRITE8_MEMBER(cedar_magnet_state::other_cpu_w)
}
-void cedar_magnet_state::handle_sub_board_cpu_lines(cedar_magnet_board_device* dev, int old_data, int data)
+void cedar_magnet_state::handle_sub_board_cpu_lines(cedar_magnet_board_interface &dev, int old_data, int data)
{
if (old_data != data)
{
if (data & 0x04)
- dev->reset_assert();
+ dev.reset_assert();
else
- dev->reset_clear();
+ dev.reset_clear();
if (data & 0x02)
- dev->halt_clear();
+ dev.halt_clear();
else
- dev->halt_assert();
+ dev.halt_assert();
}
}
@@ -605,7 +596,7 @@ WRITE8_MEMBER( cedar_magnet_state::ic48_pio_pa_w ) // 0x20
int plane0select = (m_ic48_pio_pa_val & 0x07) >> 0;
- handle_sub_board_cpu_lines(m_cedplane0, oldplane0select, plane0select);
+ handle_sub_board_cpu_lines(*m_cedplane0, oldplane0select, plane0select);
}
@@ -644,8 +635,8 @@ WRITE8_MEMBER(cedar_magnet_state::ic48_pio_pb_w) // 0x22
int plane1select = (m_ic48_pio_pb_val & 0x07) >> 0;
int spriteselect = (m_ic48_pio_pb_val & 0x70) >> 4;
- handle_sub_board_cpu_lines(m_cedplane1, oldplane1select, plane1select);
- handle_sub_board_cpu_lines(m_cedsprite, oldspriteselect, spriteselect);
+ handle_sub_board_cpu_lines(*m_cedplane1, oldplane1select, plane1select);
+ handle_sub_board_cpu_lines(*m_cedsprite, oldspriteselect, spriteselect);
}
/***********************
@@ -688,7 +679,7 @@ WRITE8_MEMBER( cedar_magnet_state::ic49_pio_pb_w ) // 0x42
int soundselect = (m_ic49_pio_pb_val & 0x70) >> 4;
- handle_sub_board_cpu_lines(m_cedsound, oldsoundselect, soundselect);
+ handle_sub_board_cpu_lines(*m_cedsound, oldsoundselect, soundselect);
}
/***********************
@@ -705,7 +696,6 @@ void cedar_magnet_state::machine_start()
void cedar_magnet_state::machine_reset()
{
m_ic48_pio_pa_val = 0xff;
- portff_data = 0x00;
int bankbit0 = (m_ic48_pio_pa_val & 0x60) >> 5;
m_bank0->set_bank(bankbit0);
@@ -752,7 +742,9 @@ INTERRUPT_GEN_MEMBER(cedar_magnet_state::irq)
m_prothack(this);
m_maincpu->set_input_line(0, HOLD_LINE);
- // maybe generate the irqs for the other PCBs here?
+ m_cedplane0->irq_hold();
+ m_cedplane1->irq_hold();
+ m_cedsprite->irq_hold();
}
static MACHINE_CONFIG_START( cedar_magnet, cedar_magnet_state )
diff --git a/src/mame/drivers/play_3.cpp b/src/mame/drivers/play_3.cpp
index fc2a3e7329e..1a6457dabf6 100644
--- a/src/mame/drivers/play_3.cpp
+++ b/src/mame/drivers/play_3.cpp
@@ -11,16 +11,13 @@ Status:
- Lots of loud siren-like noises when there should be silence
- Mechanical sounds to add
- Most games work
--- Spain82: not working (no manual available)
+-- Spain82: not working (no manual available; uses same sound board as Cerberus)
-- Nautilus: sound is broken (runs into the weeds)
--- Skill Flight: not working
+-- Skill Flight, Phantom Ship: not working
+-- Eight Ball Champ, Cobra: not working (different hardware)
-- Miss Disco: not working (no manual available)
--- Phantom Ship: no sound (no manual available)
-- Meg Aaton: Ball number doesn't show
-It looks like Skill Flight and Phantom Ship use a new sound card that contains
-Z80A, 5205, 2x AY-3-8910, 2x Z80CTC, 2x MF10.
-
Note: The input lines INT, EF1-4 are inverted (not true voltage).
First time:
@@ -51,6 +48,7 @@ The manual is not that clear, there's a lot we don't know, this *seems* to work.
#include "machine/clock.h"
#include "machine/7474.h"
#include "sound/ay8910.h"
+#include "audio/efo_zsu.h"
#include "play_3.lh"
@@ -65,6 +63,7 @@ public:
, m_4013b(*this, "4013b")
, m_aysnd1(*this, "aysnd1")
, m_aysnd2(*this, "aysnd2")
+ , m_zsu(*this, "zsu")
, m_keyboard(*this, "X.%u", 0)
{ }
@@ -72,6 +71,7 @@ public:
DECLARE_WRITE8_MEMBER(megaaton_port01_w);
DECLARE_WRITE8_MEMBER(port02_w);
DECLARE_WRITE8_MEMBER(port03_w);
+ DECLARE_WRITE8_MEMBER(sklflite_port03_w);
DECLARE_READ8_MEMBER(port04_r);
DECLARE_READ8_MEMBER(port05_r);
DECLARE_WRITE8_MEMBER(port06_w);
@@ -87,22 +87,24 @@ public:
DECLARE_READ_LINE_MEMBER(clear_a_r);
private:
- uint16_t m_clockcnt;
- uint16_t m_resetcnt;
- uint16_t m_resetcnt_a;
- uint8_t m_soundlatch;
- uint8_t m_a_irqset;
- uint16_t m_a_irqcnt;
- uint8_t m_kbdrow;
- uint8_t m_segment[5];
+ u16 m_clockcnt;
+ u16 m_resetcnt;
+ u16 m_resetcnt_a;
+ u8 m_soundlatch;
+ u8 m_port03_old;
+ u8 m_a_irqset;
+ u16 m_a_irqcnt;
+ u8 m_kbdrow;
+ u8 m_segment[5];
bool m_disp_sw;
virtual void machine_reset() override;
required_device<cosmac_device> m_maincpu;
- required_device<cosmac_device> m_audiocpu;
+ optional_device<cosmac_device> m_audiocpu;
required_device<ttl7474_device> m_4013a;
required_device<ttl7474_device> m_4013b;
- required_device<ay8910_device> m_aysnd1;
- required_device<ay8910_device> m_aysnd2;
+ optional_device<ay8910_device> m_aysnd1;
+ optional_device<ay8910_device> m_aysnd2;
+ optional_device<efo_zsu_device> m_zsu;
required_ioport_array<10> m_keyboard;
};
@@ -124,12 +126,12 @@ ADDRESS_MAP_END
static ADDRESS_MAP_START( megaaton_io, AS_IO, 8, play_3_state )
AM_RANGE(0x01, 0x01) AM_WRITE(megaaton_port01_w) // digits, scan-lines
- AM_RANGE(0x02, 0x02) AM_WRITE(port02_w) // sound code
- AM_RANGE(0x03, 0x03) AM_WRITE(port03_w) //
- AM_RANGE(0x04, 0x04) AM_READ(port04_r) // switches
- AM_RANGE(0x05, 0x05) AM_READ(port05_r) // more switches
- AM_RANGE(0x06, 0x06) AM_WRITE(port06_w) // segments
- AM_RANGE(0x07, 0x07) AM_WRITE(port07_w) // flipflop clear
+ AM_IMPORT_FROM(play_3_io)
+ADDRESS_MAP_END
+
+static ADDRESS_MAP_START( sklflite_io, AS_IO, 8, play_3_state )
+ AM_RANGE(0x03, 0x03) AM_WRITE(sklflite_port03_w) //
+ AM_IMPORT_FROM(play_3_io)
ADDRESS_MAP_END
static ADDRESS_MAP_START( play_3_audio_map, AS_PROGRAM, 8, play_3_state )
@@ -258,6 +260,7 @@ void play_3_state::machine_reset()
m_disp_sw = 0;
for (uint8_t i = 0; i < 5; i++)
m_segment[i] = 0;
+ m_port03_old = 0;
}
WRITE8_MEMBER( play_3_state::port01_w )
@@ -320,6 +323,21 @@ WRITE8_MEMBER( play_3_state::port03_w )
}
+WRITE8_MEMBER( play_3_state::sklflite_port03_w )
+{
+ if (BIT(data, 6) && !BIT(m_port03_old, 6))
+ m_zsu->sound_command_w(space, 0, m_soundlatch);
+ if (BIT(data, 5))
+ {
+ if (m_soundlatch == 11)
+ m_samples->start(0, 5); // outhole
+ //if (m_soundlatch == 13)
+ //m_samples->start(0, 6); // no knocker?
+ }
+
+ m_port03_old = data;
+}
+
READ8_MEMBER( play_3_state::port04_r )
{
if (m_kbdrow & 0x3f)
@@ -405,15 +423,18 @@ WRITE_LINE_MEMBER( play_3_state::clock_w )
if ((m_clockcnt & 0x3ff) == 0)
m_4013b->preset_w(BIT(m_clockcnt, 10)); // Q10 output
- // sound irq
- m_a_irqcnt--;
- if (m_a_irqcnt == 1)
- m_audiocpu->int_w(1); // inverted
- else
- if (m_a_irqcnt == 0)
+ if (m_audiocpu.found())
{
- m_a_irqcnt = (m_a_irqset << 3) | 7;
- m_audiocpu->int_w(0); // inverted
+ // sound irq
+ m_a_irqcnt--;
+ if (m_a_irqcnt == 1)
+ m_audiocpu->int_w(1); // inverted
+ else
+ if (m_a_irqcnt == 0)
+ {
+ m_a_irqcnt = (m_a_irqset << 3) | 7;
+ m_audiocpu->int_w(0); // inverted
+ }
}
}
}
@@ -482,6 +503,19 @@ static MACHINE_CONFIG_DERIVED( megaaton, play_3 )
MCFG_CPU_IO_MAP(megaaton_io)
MACHINE_CONFIG_END
+static MACHINE_CONFIG_DERIVED( sklflite, play_3 )
+ MCFG_CPU_MODIFY("maincpu")
+ MCFG_CPU_IO_MAP(sklflite_io)
+
+ MCFG_DEVICE_REMOVE("audiocpu")
+ MCFG_DEVICE_REMOVE("aysnd1")
+ MCFG_DEVICE_REMOVE("aysnd2")
+ MCFG_DEVICE_REMOVE("lspeaker")
+ MCFG_DEVICE_REMOVE("rspeaker")
+
+ MCFG_DEVICE_ADD("zsu", EFO_ZSU1, 0)
+MACHINE_CONFIG_END
+
/*-------------------------------------------------------------------
/ Spain 82 (10/82)
@@ -642,7 +676,7 @@ ROM_START(sklflite)
ROM_LOAD("skflcpu1.rom", 0x0000, 0x2000, CRC(8f833b55) SHA1(1729203582c22b51d1cc401aa8f270aa5cdadabe))
ROM_LOAD("skflaudiocpu.rom", 0x2000, 0x2000, CRC(ffc497aa) SHA1(3e88539ae1688322b9268f502d8ca41cffb28df3))
- ROM_REGION(0x20000, "audiocpu", 0) // Z80A soundcard
+ ROM_REGION(0x28000, "zsu:soundcpu", 0) // Z80A soundcard
ROM_LOAD("skflsnd.rom", 0x0000, 0x8000, CRC(926a1da9) SHA1(16c762fbfe6a55597f26ff55d380192bb8647ee0))
ROM_END
@@ -654,7 +688,7 @@ ROM_START(phntmshp)
ROM_LOAD("video1.bin", 0x0000, 0x2000, CRC(2b61a8d2) SHA1(1b5cabbab252b2ffb6ed12fb7e4181de7695ed9a))
ROM_LOAD("video2.bin", 0x2000, 0x2000, CRC(50126db1) SHA1(58d89e44131554cb087c4cad62869f90366704ad))
- ROM_REGION(0x20000, "audiocpu", 0) // Z80A soundcard
+ ROM_REGION(0x28000, "zsu:soundcpu", 0) // Z80A soundcard
ROM_LOAD("sonido1.bin", 0x00000, 0x8000, CRC(3294611d) SHA1(5f790b41bcb6d87418c80e61ac8ae69c57864b1d))
ROM_LOAD("sonido2.bin", 0x08000, 0x8000, CRC(c2efc826) SHA1(44ee144b902627745853011968e0d654b35b3b08))
ROM_LOAD("sonido3.bin", 0x10000, 0x8000, CRC(13d50f39) SHA1(70624de2dd8412c83866183a83f16cc5b8bdccb8))
@@ -699,7 +733,7 @@ ROM_START(eballchps)
ROM_REGION(0x8000, "maincpu", 0) // Z80-based
ROM_LOAD("U18-JEB 5A0 - CPU.BIN", 0x0000, 0x8000, CRC(87615a7d) SHA1(b27ca2d863040a2641f88f9bd3143467a83f181b))
- ROM_REGION(0x20000, "audiocpu", 0) // Z80-based
+ ROM_REGION(0x28000, "zsu:soundcpu", 0) // Z80-based
ROM_LOAD("U3-EBE A02 - Sonido.BIN", 0x00000, 0x8000, CRC(34be32ee) SHA1(ce0271540164639f28d617753760ecc479b6b0d0))
ROM_LOAD("U4-EBE B01 - Sonido.BIN", 0x08000, 0x8000, CRC(d696c4e8) SHA1(501e18c258e6d42819d25d72e1907984a6cfeecb))
ROM_LOAD("U5-EBE C01 - Sonido.BIN", 0x10000, 0x8000, CRC(fe78d7ef) SHA1(ed91c51dd230854a007f88446011f786759687ca))
@@ -711,12 +745,25 @@ ROM_START(cobrapb)
ROM_REGION(0x8000, "maincpu", 0) // Z80-based
ROM_LOAD("U18 - JCB 4 A0 - CPU.BIN", 0x0000, 0x8000, CRC(c663910e) SHA1(c38692343f114388259c4e7b7943e5be934189ca))
- ROM_REGION(0x20000, "audiocpu", 0) // Z80-based
+ ROM_REGION(0x28000, "zsu:soundcpu", 0) // Z80-based
ROM_LOAD("U3 - SCB 1 A0 - Sonido.BIN", 0x00000, 0x8000, CRC(d3675770) SHA1(882ce748308f2d78cccd28fc8cd64fe69bd223e3))
ROM_LOAD("U4 - SCB 1 B0 - Sonido.BIN", 0x08000, 0x8000, CRC(e8e1bdbb) SHA1(215bdfab751cb0ea47aa529df0ac30976de4f772))
ROM_LOAD("U5 - SCB 1 C0 - Sonido.BIN", 0x10000, 0x8000, CRC(c36340ab) SHA1(cd662457959de3a929ba02779e2046ed18b797e2))
ROM_END
+#ifdef UNUSED_DEFINITION
+// Come Back (Nondum)
+ROM_START(comeback)
+ ROM_REGION(0x8000, "maincpu", 0)
+ ROM_LOAD("JCO_6a0.u18", 0x0000, 0x8000, NO_DUMP)
+
+ ROM_REGION(0x28000, "zsu:soundcpu", 0)
+ ROM_LOAD("CBS_3a0.u3", 0x00000, 0x8000, NO_DUMP)
+ ROM_LOAD("CBS_3b0.u4", 0x08000, 0x8000, NO_DUMP)
+ ROM_LOAD("CBS_1c0.u5", 0x10000, 0x8000, NO_DUMP)
+ROM_END
+#endif
+
GAME(1982, spain82, 0, play_3, play_3, driver_device, 0, ROT0, "Playmatic", "Spain '82", MACHINE_MECHANICAL | MACHINE_NOT_WORKING | MACHINE_NO_SOUND)
GAME(1983, megaaton, 0, megaaton, megaaton, driver_device, 0, ROT0, "Playmatic", "Meg-Aaton", MACHINE_MECHANICAL | MACHINE_NOT_WORKING | MACHINE_IMPERFECT_SOUND)
GAME(1983, megaatona, megaaton, megaaton, megaaton, driver_device, 0, ROT0, "Playmatic", "Meg-Aaton (alternate set)", MACHINE_MECHANICAL | MACHINE_NOT_WORKING | MACHINE_IMPERFECT_SOUND)
@@ -730,13 +777,14 @@ GAME(1985, starfirpa, starfirp, play_3, play_3, driver_device, 0, ROT0, "Pl
GAME(1985, trailer, 0, play_3, play_3, driver_device, 0, ROT0, "Playmatic", "Trailer", MACHINE_MECHANICAL | MACHINE_NOT_WORKING | MACHINE_IMPERFECT_SOUND)
GAME(1986, fldragon, 0, play_3, play_3, driver_device, 0, ROT0, "Playmatic", "Flash Dragon", MACHINE_MECHANICAL | MACHINE_NOT_WORKING | MACHINE_IMPERFECT_SOUND)
GAME(1986, fldragona, fldragon, play_3, play_3, driver_device, 0, ROT0, "Playmatic", "Flash Dragon (alternate set)", MACHINE_MECHANICAL | MACHINE_NOT_WORKING | MACHINE_IMPERFECT_SOUND)
-GAME(1987, phntmshp, 0, play_3, play_3, driver_device, 0, ROT0, "Playmatic", "Phantom Ship", MACHINE_MECHANICAL | MACHINE_NOT_WORKING | MACHINE_NO_SOUND)
-GAME(1987, sklflite, 0, play_3, play_3, driver_device, 0, ROT0, "Playmatic", "Skill Flight (Playmatic)", MACHINE_MECHANICAL | MACHINE_NOT_WORKING | MACHINE_NO_SOUND)
+GAME(1987, phntmshp, 0, sklflite, play_3, driver_device, 0, ROT0, "Playmatic", "Phantom Ship", MACHINE_MECHANICAL | MACHINE_NOT_WORKING | MACHINE_IMPERFECT_SOUND)
+GAME(1987, sklflite, 0, sklflite, play_3, driver_device, 0, ROT0, "Playmatic", "Skill Flight (Playmatic)", MACHINE_MECHANICAL | MACHINE_NOT_WORKING | MACHINE_IMPERFECT_SOUND)
// not by Playmatic, but same hardware
GAME(1986, ridersrf, 0, play_3, play_3, driver_device, 0, ROT0, "JocMatic", "Rider's Surf", MACHINE_MECHANICAL | MACHINE_NOT_WORKING | MACHINE_IMPERFECT_SOUND)
GAME(1987, ironball, 0, play_3, play_3, driver_device, 0, ROT0, "Stargame", "Iron Balls", MACHINE_MECHANICAL | MACHINE_NOT_WORKING | MACHINE_IMPERFECT_SOUND)
// "Z-Pinball" hardware, Z80 main and sound CPUs - to be split (?)
-GAME(1986, eballchps, eballchp, play_3, play_3, driver_device, 0, ROT0, "Bally (Maibesa license)", "Eight Ball Champ (Spain, Z-Pinball hardware)", MACHINE_MECHANICAL | MACHINE_NOT_WORKING | MACHINE_NO_SOUND)
-GAME(1987, cobrapb, 0, play_3, play_3, driver_device, 0, ROT0, "Playbar", "Cobra (Playbar)", MACHINE_MECHANICAL | MACHINE_NOT_WORKING | MACHINE_NO_SOUND)
+GAME(1986, eballchps, eballchp, sklflite, play_3, driver_device, 0, ROT0, "Bally (Maibesa license)", "Eight Ball Champ (Spain, Z-Pinball hardware)", MACHINE_IS_SKELETON_MECHANICAL)
+GAME(1987, cobrapb, 0, sklflite, play_3, driver_device, 0, ROT0, "Playbar", "Cobra (Playbar)", MACHINE_IS_SKELETON_MECHANICAL)
+//GAME(198?, comeback, 0, sklflite, play_3, driver_device, 0, ROT0, "Nondum", "Come Back", MACHINE_IS_SKELETON_MECHANICAL) // undumped
// bingo hardware, to be split (?)
GAME(1983, msdisco, 0, play_3, play_3, driver_device, 0, ROT0, "Playmatic", "Miss Disco (Bingo)", MACHINE_IS_SKELETON_MECHANICAL)
diff --git a/src/mame/machine/cedar_magnet_board.cpp b/src/mame/machine/cedar_magnet_board.cpp
index e56c2ea8067..5ed1364246d 100644
--- a/src/mame/machine/cedar_magnet_board.cpp
+++ b/src/mame/machine/cedar_magnet_board.cpp
@@ -1,90 +1,81 @@
// license:BSD-3-Clause
// copyright-holders:David Haywood
-
#include "emu.h"
-#include "cedar_magnet_plane.h"
-
-
-//const device_type CEDAR_MAGNET_BASE = &device_creator<cedar_magnet_board_device>;
-
-cedar_magnet_board_device::cedar_magnet_board_device(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, uint32_t clock, const char *shortname, const char *source)
- : device_t(mconfig, type, name, tag, owner, clock, shortname, source)
-// m_ram(*this, "ram")
-{
-}
+#include "cedar_magnet_board.h"
-INTERRUPT_GEN_MEMBER(cedar_magnet_board_device::irq)
+cedar_magnet_board_interface::cedar_magnet_board_interface(const machine_config &mconfig, device_t &device, const char *cputag, const char *ramtag)
+ : device_interface(device, "cedmag_board"),
+ m_cpu(device, cputag),
+ m_ram(device, ramtag)
{
- m_cpu->set_input_line(0, HOLD_LINE);
}
-void cedar_magnet_board_device::device_start()
+void cedar_magnet_board_interface::write_cpu_bus(int offset, u8 data)
{
-}
-
-void cedar_magnet_board_device::write_cpu_bus(int offset, uint8_t data)
-{
- device_t* cpu = m_cpu;
- address_space& ap = cpu->memory().space(AS_PROGRAM);
+ address_space &ap = m_cpu->space(AS_PROGRAM);
ap.write_byte(offset, data);
}
-uint8_t cedar_magnet_board_device::read_cpu_bus(int offset)
+uint8_t cedar_magnet_board_interface::read_cpu_bus(int offset)
{
- device_t* cpu = m_cpu;
- address_space& ap = cpu->memory().space(AS_PROGRAM);
+ address_space &ap = m_cpu->space(AS_PROGRAM);
return ap.read_byte(offset);
}
-bool cedar_magnet_board_device::is_running(void)
+bool cedar_magnet_board_interface::is_running() const
{
return m_is_running;
}
-TIMER_CALLBACK_MEMBER(cedar_magnet_board_device::reset_assert_callback)
+TIMER_CALLBACK_MEMBER(cedar_magnet_board_interface::reset_assert_callback)
{
m_cpu->set_input_line(INPUT_LINE_RESET, ASSERT_LINE);
}
-TIMER_CALLBACK_MEMBER(cedar_magnet_board_device::reset_clear_callback)
+TIMER_CALLBACK_MEMBER(cedar_magnet_board_interface::reset_clear_callback)
{
m_cpu->set_input_line(INPUT_LINE_RESET, CLEAR_LINE);
}
-TIMER_CALLBACK_MEMBER(cedar_magnet_board_device::halt_assert_callback)
+TIMER_CALLBACK_MEMBER(cedar_magnet_board_interface::halt_assert_callback)
{
m_cpu->set_input_line(INPUT_LINE_HALT, ASSERT_LINE);
m_is_running = false;
}
-TIMER_CALLBACK_MEMBER(cedar_magnet_board_device::halt_clear_callback)
+TIMER_CALLBACK_MEMBER(cedar_magnet_board_interface::halt_clear_callback)
{
m_cpu->set_input_line(INPUT_LINE_HALT, CLEAR_LINE);
m_is_running = true;
}
-void cedar_magnet_board_device::halt_assert(void)
+void cedar_magnet_board_interface::irq_hold()
+{
+ m_cpu->set_input_line(INPUT_LINE_IRQ0, HOLD_LINE);
+}
+
+void cedar_magnet_board_interface::halt_assert()
{
- machine().scheduler().timer_set(attotime::from_usec(2), timer_expired_delegate(FUNC(cedar_magnet_board_device::halt_assert_callback),this));
+ device().machine().scheduler().timer_set(attotime::from_usec(2), timer_expired_delegate(FUNC(cedar_magnet_board_interface::halt_assert_callback),this));
}
-void cedar_magnet_board_device::halt_clear(void)
+void cedar_magnet_board_interface::halt_clear()
{
- machine().scheduler().timer_set(attotime::from_usec(2), timer_expired_delegate(FUNC(cedar_magnet_board_device::halt_clear_callback),this));
+ device().machine().scheduler().timer_set(attotime::from_usec(2), timer_expired_delegate(FUNC(cedar_magnet_board_interface::halt_clear_callback),this));
}
-void cedar_magnet_board_device::reset_assert(void)
+void cedar_magnet_board_interface::reset_assert()
{
- machine().scheduler().timer_set(attotime::from_usec(1), timer_expired_delegate(FUNC(cedar_magnet_board_device::reset_assert_callback),this));
+ device().machine().scheduler().timer_set(attotime::from_usec(1), timer_expired_delegate(FUNC(cedar_magnet_board_interface::reset_assert_callback),this));
}
-void cedar_magnet_board_device::reset_clear(void)
+void cedar_magnet_board_interface::reset_clear()
{
- machine().scheduler().timer_set(attotime::from_usec(1), timer_expired_delegate(FUNC(cedar_magnet_board_device::reset_clear_callback),this));
+ device().machine().scheduler().timer_set(attotime::from_usec(1), timer_expired_delegate(FUNC(cedar_magnet_board_interface::reset_clear_callback),this));
}
-void cedar_magnet_board_device::device_reset()
+void cedar_magnet_board_interface::interface_pre_reset()
{
halt_assert();
}
diff --git a/src/mame/machine/cedar_magnet_board.h b/src/mame/machine/cedar_magnet_board.h
index 1672f9e5e76..dbdddbed103 100644
--- a/src/mame/machine/cedar_magnet_board.h
+++ b/src/mame/machine/cedar_magnet_board.h
@@ -1,7 +1,7 @@
// license:BSD-3-Clause
// copyright-holders:David Haywood
-// just a base device to hold some common functions of the EFO / Cedar Magnet System PCBs
+// device interface to hold some common functions of the EFO / Cedar Magnet System PCBs
#pragma once
@@ -10,41 +10,40 @@
#include "cpu/z80/z80.h"
#include "cpu/z80/z80daisy.h"
-#include "machine/z80pio.h"
-extern const device_type CEDAR_MAGNET_PLANE;
-
-class cedar_magnet_board_device : public device_t
+class cedar_magnet_board_interface : public device_interface
{
public:
// construction/destruction
- cedar_magnet_board_device(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, uint32_t clock, const char *shortname, const char *source);
+ cedar_magnet_board_interface(const machine_config &mconfig, device_t &device, const char *cputag, const char *ramtag);
- uint8_t* m_ram;
- z80_device* m_cpu;
+ z80_device &cpu() { assert(m_cpu != nullptr); return *m_cpu; }
+ u8 *ram() { return &m_ram[0]; }
- virtual uint8_t read_cpu_bus(int offset);
+ virtual u8 read_cpu_bus(int offset);
virtual void write_cpu_bus(int offset, uint8_t data);
- TIMER_CALLBACK_MEMBER(halt_assert_callback);
- TIMER_CALLBACK_MEMBER(halt_clear_callback);
- virtual TIMER_CALLBACK_MEMBER(reset_assert_callback);
- TIMER_CALLBACK_MEMBER(reset_clear_callback);
+ void irq_hold();
+ void halt_assert();
+ void halt_clear();
+ void reset_assert();
+ void reset_clear();
+ bool is_running() const;
+protected:
+ virtual void interface_pre_reset() override;
- void halt_assert(void);
- void halt_clear(void);
- void reset_assert(void);
- void reset_clear(void);
- bool is_running(void);
- bool m_is_running;
+ virtual TIMER_CALLBACK_MEMBER(reset_assert_callback);
- INTERRUPT_GEN_MEMBER(irq);
-protected:
- virtual void device_start() override;
- virtual void device_reset() override;
+ required_device<z80_device> m_cpu;
+ optional_shared_ptr<u8> m_ram;
private:
+ TIMER_CALLBACK_MEMBER(halt_assert_callback);
+ TIMER_CALLBACK_MEMBER(halt_clear_callback);
+ TIMER_CALLBACK_MEMBER(reset_clear_callback);
+
+ bool m_is_running;
};
#endif
diff --git a/src/mame/machine/cedar_magnet_plane.cpp b/src/mame/machine/cedar_magnet_plane.cpp
index 1e696e6cf39..261e3d17ecb 100644
--- a/src/mame/machine/cedar_magnet_plane.cpp
+++ b/src/mame/machine/cedar_magnet_plane.cpp
@@ -10,7 +10,8 @@ extern const device_type CEDAR_MAGNET_PLANE = &device_creator<cedar_magnet_plane
cedar_magnet_plane_device::cedar_magnet_plane_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
- : cedar_magnet_board_device(mconfig, CEDAR_MAGNET_PLANE, "Cedar Plane", tag, owner, clock, "cedmag_plane", __FILE__)
+ : device_t(mconfig, CEDAR_MAGNET_PLANE, "Cedar Plane", tag, owner, clock, "cedmag_plane", __FILE__),
+ cedar_magnet_board_interface(mconfig, *this, "planecpu", "ram")
{
}
@@ -72,7 +73,6 @@ static MACHINE_CONFIG_FRAGMENT( cedar_magnet_plane )
MCFG_CPU_ADD("planecpu", Z80,4000000)
MCFG_CPU_PROGRAM_MAP(cedar_magnet_plane_map)
MCFG_CPU_IO_MAP(cedar_magnet_plane_io)
- MCFG_CPU_VBLANK_INT_DRIVER(":screen", cedar_magnet_board_device, irq)
MCFG_DEVICE_ADD("z80pio0", Z80PIO, 4000000/2)
// MCFG_Z80PIO_OUT_INT_CB(INPUTLINE("maincpu", INPUT_LINE_IRQ0))
@@ -133,8 +133,6 @@ machine_config_constructor cedar_magnet_plane_device::device_mconfig_additions()
void cedar_magnet_plane_device::device_start()
{
- m_cpu = subdevice<z80_device>("planecpu");
- m_ram = (uint8_t*)memshare("ram")->ptr();
save_item(NAME(m_framebuffer));
}
diff --git a/src/mame/machine/cedar_magnet_plane.h b/src/mame/machine/cedar_magnet_plane.h
index 3bd254f1468..a1bafdc74b9 100644
--- a/src/mame/machine/cedar_magnet_plane.h
+++ b/src/mame/machine/cedar_magnet_plane.h
@@ -7,6 +7,7 @@
#define CEDAR_MAGNET_PLANE_DEF
#include "machine/cedar_magnet_board.h"
+#include "machine/z80pio.h"
extern const device_type CEDAR_MAGNET_PLANE;
@@ -14,7 +15,7 @@ extern const device_type CEDAR_MAGNET_PLANE;
MCFG_DEVICE_ADD(_tag, CEDAR_MAGNET_PLANE, 0)
-class cedar_magnet_plane_device : public cedar_magnet_board_device
+class cedar_magnet_plane_device : public device_t, public cedar_magnet_board_interface
{
public:
// construction/destruction
@@ -35,6 +36,8 @@ public:
DECLARE_WRITE8_MEMBER(plane_portce_w);
DECLARE_WRITE8_MEMBER(plane_portcf_w);
+ INTERRUPT_GEN_MEMBER(vblank_irq);
+
uint8_t m_framebuffer[0x10000];
int m_curline;
int m_lineoffset;
diff --git a/src/mame/machine/cedar_magnet_sound.cpp b/src/mame/machine/cedar_magnet_sound.cpp
deleted file mode 100644
index 2ff907658ed..00000000000
--- a/src/mame/machine/cedar_magnet_sound.cpp
+++ /dev/null
@@ -1,208 +0,0 @@
-// license:BSD-3-Clause
-// copyright-holders:David Haywood
-
-/*
- This is very similar to the ZSU1 Sound Control Unit, also manufactured by
- EFO SA and used in the Playmatic pinballs Skill Flight and Phantom Ship;
- the emulation here is influenced by available schematics for that board.
-
- irq vectors
-
- 0xe6 - from ctc0 channel 3 (vector = E0) used to drive MSM5205 through FIFO
- 0xee - from ctc0 channel 3 (vector = E8) ^^
- 0xf6 - drive AY (once per frame?) triggered by ctc1 channel 3 (vector = F0)
- 0xff - read sound latch (triggered by write from master board; default vector set by 5K/+5 pullups on D0-D7)
-
-*/
-
-#include "emu.h"
-#include "cedar_magnet_sound.h"
-
-#include "machine/clock.h"
-
-
-extern const device_type CEDAR_MAGNET_SOUND = &device_creator<cedar_magnet_sound_device>;
-
-
-cedar_magnet_sound_device::cedar_magnet_sound_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
- : cedar_magnet_board_device(mconfig, CEDAR_MAGNET_SOUND, "Cedar Sound", tag, owner, clock, "cedmag_sound", __FILE__),
- m_ctc0(*this, "ctc0"),
- m_ctc1(*this, "ctc1"),
- m_fifo(*this, "fifo"),
- m_adpcm(*this, "adpcm")
-{
-}
-
-
-READ8_MEMBER(cedar_magnet_sound_device::soundlatch_r)
-{
- return m_command;
-}
-
-void cedar_magnet_sound_device::write_command(uint8_t data)
-{
- m_command = data;
- // this interrupt causes it to read the soundlatch at 0x14
- m_cpu->set_input_line_and_vector(0, HOLD_LINE, 0xff);
-}
-
-
-
-static ADDRESS_MAP_START( cedar_magnet_sound_map, AS_PROGRAM, 8, cedar_magnet_sound_device )
- AM_RANGE(0x0000, 0xffff) AM_RAM AM_SHARE("ram")
-ADDRESS_MAP_END
-
-static ADDRESS_MAP_START( cedar_magnet_sound_io, AS_IO, 8, cedar_magnet_sound_device )
- ADDRESS_MAP_GLOBAL_MASK(0xff)
- ADDRESS_MAP_UNMAP_HIGH
-
- AM_RANGE(0x00, 0x03) AM_DEVREADWRITE("ctc0", z80ctc_device, read, write)
- AM_RANGE(0x04, 0x07) AM_DEVREADWRITE("ctc1", z80ctc_device, read, write)
-
- AM_RANGE(0x08, 0x08) AM_WRITE(adpcm_fifo_w)
-
- AM_RANGE(0x0c, 0x0c) AM_DEVWRITE("aysnd0", ay8910_device, address_w)
- AM_RANGE(0x0d, 0x0d) AM_DEVWRITE("aysnd0", ay8910_device, data_w)
-
- AM_RANGE(0x10, 0x10) AM_DEVWRITE("aysnd1", ay8910_device, address_w)
- AM_RANGE(0x11, 0x11) AM_DEVWRITE("aysnd1", ay8910_device, data_w)
-
- AM_RANGE(0x14, 0x14) AM_READ(soundlatch_r)
-
-ADDRESS_MAP_END
-
-WRITE8_MEMBER(cedar_magnet_sound_device::adpcm_fifo_w)
-{
- // Z80 code first unpacks 8 bytes of ADPCM sample data into nibbles
- // and, upon receiving interrupt vector E6, fills FIFO at once using OTIR
- // 4-bit data is shifted out of the FIFO to the MSM5205 by another timer
- m_fifo->write(data & 0x0f); // only low nibble is used here
- m_fifo->si_w(1);
- m_fifo->si_w(0);
-}
-
-WRITE8_MEMBER(cedar_magnet_sound_device::ay0_porta_w)
-{
- // unknown; 0x80 written on reset
-}
-
-WRITE8_MEMBER(cedar_magnet_sound_device::ay1_porta_w)
-{
- m_adpcm->reset_w(data & 1);
- if (data & 1)
- m_fifo->reset();
- // D4-D6 likely used to select clock for ctc0 channel 2
- // other bits probably used to modulate analog sound output
-}
-
-WRITE_LINE_MEMBER(cedar_magnet_sound_device::ctc0_z0_w)
-{
-// printf("USED ctc0_z0_w %d\n", state);
-}
-
-WRITE_LINE_MEMBER(cedar_magnet_sound_device::ctc0_z1_w)
-{
-// printf("USED ctc0_z1_w %d\n", state);
-}
-
-WRITE_LINE_MEMBER(cedar_magnet_sound_device::ctc1_z0_w)
-{
- printf("ctc1_z0_w %d\n", state);
-}
-
-WRITE_LINE_MEMBER(cedar_magnet_sound_device::ctc1_z1_w)
-{
- printf("ctc1_z1_w %d\n", state);
-}
-
-WRITE_LINE_MEMBER(cedar_magnet_sound_device::ctc1_z2_w)
-{
- printf("ctc1_z2_w %d\n", state);
-}
-
-WRITE_LINE_MEMBER(cedar_magnet_sound_device::ctc0_z2_w)
-{
- printf("ctc0_z2_w %d\n", state);
-}
-
-WRITE_LINE_MEMBER(cedar_magnet_sound_device::fifo_dor_w)
-{
- // combined with a clock signal and used to drive ctc0 channel 3
-}
-
-static const z80_daisy_config daisy_chain[] =
-{
- { "ctc1" },
- { "ctc0" },
- { nullptr }
-};
-
-TIMER_CALLBACK_MEMBER(cedar_magnet_sound_device::reset_assert_callback)
-{
- cedar_magnet_board_device::reset_assert_callback(ptr,param);
- // reset lines go to the ctc as well?
- m_ctc0->reset();
- m_ctc1->reset();
-}
-
-
-
-static MACHINE_CONFIG_FRAGMENT( cedar_magnet_sound )
- MCFG_CPU_ADD("topcpu", Z80, 4000000)
- MCFG_CPU_PROGRAM_MAP(cedar_magnet_sound_map)
- MCFG_CPU_IO_MAP(cedar_magnet_sound_io)
- MCFG_Z80_DAISY_CHAIN(daisy_chain)
-
- MCFG_DEVICE_ADD("ctc0", Z80CTC, 4000000)
- MCFG_Z80CTC_INTR_CB(INPUTLINE("topcpu", INPUT_LINE_IRQ0))
- MCFG_Z80CTC_ZC0_CB(WRITELINE(cedar_magnet_sound_device, ctc0_z0_w))
- MCFG_Z80CTC_ZC1_CB(WRITELINE(cedar_magnet_sound_device, ctc0_z1_w))
- MCFG_Z80CTC_ZC2_CB(WRITELINE(cedar_magnet_sound_device, ctc0_z2_w))
-
- MCFG_DEVICE_ADD("ctc1", Z80CTC, 4000000)
- MCFG_Z80CTC_INTR_CB(INPUTLINE("topcpu", INPUT_LINE_IRQ0))
- MCFG_Z80CTC_ZC0_CB(WRITELINE(cedar_magnet_sound_device, ctc1_z0_w))
- MCFG_Z80CTC_ZC1_CB(WRITELINE(cedar_magnet_sound_device, ctc1_z1_w))
- MCFG_Z80CTC_ZC2_CB(WRITELINE(cedar_magnet_sound_device, ctc1_z2_w))
-
-#if 0 // does nothing useful now
- MCFG_DEVICE_ADD("ck1mhz", CLOCK, 4000000/4)
- MCFG_CLOCK_SIGNAL_HANDLER(DEVWRITELINE("ctc1", z80ctc_device, trg0))
- MCFG_DEVCB_CHAIN_OUTPUT(DEVWRITELINE("ctc1", z80ctc_device, trg1))
- MCFG_DEVCB_CHAIN_OUTPUT(DEVWRITELINE("ctc1", z80ctc_device, trg2))
-#endif
-
- MCFG_SPEAKER_STANDARD_MONO("mono")
-
- MCFG_SOUND_ADD("aysnd0", AY8910, 4000000/2)
- MCFG_AY8910_PORT_A_WRITE_CB(WRITE8(cedar_magnet_sound_device, ay0_porta_w))
- MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 0.5)
-
- MCFG_SOUND_ADD("aysnd1", AY8910, 4000000/2)
- MCFG_AY8910_PORT_A_WRITE_CB(WRITE8(cedar_magnet_sound_device, ay1_porta_w))
- MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 0.5)
-
- MCFG_DEVICE_ADD("fifo", HC40105, 0) // HCF40105BE at IC13
- MCFG_40105_DATA_OUT_READY_CB(WRITELINE(cedar_magnet_sound_device, fifo_dor_w))
- MCFG_40105_DATA_OUT_CB(DEVWRITELINE("adpcm", msm5205_device, data_w))
-
- MCFG_SOUND_ADD("adpcm", MSM5205, 4000000/8)
- MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 0.50)
-MACHINE_CONFIG_END
-
-machine_config_constructor cedar_magnet_sound_device::device_mconfig_additions() const
-{
- return MACHINE_CONFIG_NAME( cedar_magnet_sound );
-}
-
-void cedar_magnet_sound_device::device_start()
-{
- m_cpu = subdevice<z80_device>("topcpu");
- m_ram = (uint8_t*)memshare("ram")->ptr();
-}
-
-void cedar_magnet_sound_device::device_reset()
-{
- m_command = 0;
- cedar_magnet_board_device::device_reset();
-}
diff --git a/src/mame/machine/cedar_magnet_sprite.cpp b/src/mame/machine/cedar_magnet_sprite.cpp
index 85f8898e997..74b8cedc5c5 100644
--- a/src/mame/machine/cedar_magnet_sprite.cpp
+++ b/src/mame/machine/cedar_magnet_sprite.cpp
@@ -14,7 +14,8 @@ extern const device_type CEDAR_MAGNET_SPRITE = &device_creator<cedar_magnet_spri
cedar_magnet_sprite_device::cedar_magnet_sprite_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
- : cedar_magnet_board_device(mconfig, CEDAR_MAGNET_SPRITE, "Cedar Sprite", tag, owner, clock, "cedmag_sprite", __FILE__),
+ : device_t(mconfig, CEDAR_MAGNET_SPRITE, "Cedar Sprite", tag, owner, clock, "cedmag_sprite", __FILE__),
+ cedar_magnet_board_interface(mconfig, *this, "spritecpu", "ram"),
m_sprite_ram_bankdev(*this, "sp_sub_ram"),
m_pio0(*this, "z80pio0"),
m_pio1(*this, "z80pio1"),
@@ -202,7 +203,6 @@ static MACHINE_CONFIG_FRAGMENT( cedar_magnet_sprite )
MCFG_CPU_ADD("spritecpu", Z80,4000000)
MCFG_CPU_PROGRAM_MAP(cedar_magnet_sprite_map)
MCFG_CPU_IO_MAP(cedar_magnet_sprite_io)
- MCFG_CPU_VBLANK_INT_DRIVER(":screen", cedar_magnet_board_device, irq)
MCFG_DEVICE_ADD("z80pio0", Z80PIO, 4000000/2)
// MCFG_Z80PIO_OUT_INT_CB(INPUTLINE("maincpu", INPUT_LINE_IRQ0))
@@ -291,14 +291,12 @@ machine_config_constructor cedar_magnet_sprite_device::device_mconfig_additions(
return MACHINE_CONFIG_NAME( cedar_magnet_sprite );
}
+
void cedar_magnet_sprite_device::device_start()
{
- m_cpu = subdevice<z80_device>("spritecpu");
- m_ram = (uint8_t*)memshare("ram")->ptr();
}
-
void cedar_magnet_sprite_device::device_reset()
{
halt_assert();
diff --git a/src/mame/machine/cedar_magnet_sprite.h b/src/mame/machine/cedar_magnet_sprite.h
index c2bef5e7d52..f6882e50923 100644
--- a/src/mame/machine/cedar_magnet_sprite.h
+++ b/src/mame/machine/cedar_magnet_sprite.h
@@ -18,7 +18,7 @@ extern const device_type CEDAR_MAGNET_SPRITE;
MCFG_DEVICE_ADD(_tag, CEDAR_MAGNET_SPRITE, 0)
-class cedar_magnet_sprite_device : public cedar_magnet_board_device
+class cedar_magnet_sprite_device : public device_t, public cedar_magnet_board_interface
{
public:
// construction/destruction