diff --git a/scripts/target/mame/arcade.lua b/scripts/target/mame/arcade.lua index 3b36402f618..1094d3fa818 100644 --- a/scripts/target/mame/arcade.lua +++ b/scripts/target/mame/arcade.lua @@ -851,6 +851,8 @@ files { MAME_DIR .. "src/mame/audio/dcs.h", MAME_DIR .. "src/mame/audio/decobsmt.cpp", MAME_DIR .. "src/mame/audio/decobsmt.h", + MAME_DIR .. "src/mame/audio/efo_zsu.cpp", + MAME_DIR .. "src/mame/audio/efo_zsu.h", MAME_DIR .. "src/mame/audio/segam1audio.cpp", MAME_DIR .. "src/mame/audio/segam1audio.h", } @@ -4351,7 +4353,6 @@ files { MAME_DIR .. "src/mame/machine/cdicdic.cpp", MAME_DIR .. "src/mame/machine/cdicdic.h", MAME_DIR .. "src/mame/drivers/cedar_magnet.cpp", - MAME_DIR .. "src/mame/machine/cedar_magnet_sound.cpp", MAME_DIR .. "src/mame/machine/cedar_magnet_plane.cpp", MAME_DIR .. "src/mame/machine/cedar_magnet_sprite.cpp", MAME_DIR .. "src/mame/machine/cedar_magnet_board.cpp", 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; +extern const device_type EFO_ZSU1 = &device_creator; +extern const device_type CEDAR_MAGNET_SOUND = &device_creator; + + +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(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(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 similarity index 54% rename from src/mame/machine/cedar_magnet_sound.h rename to 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 m_ctc0; required_device m_ctc1; + required_device m_soundlatch; required_device m_fifo; required_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 m_maincpu; - required_device m_audiocpu; + optional_device m_audiocpu; required_device m_4013a; required_device m_4013b; - required_device m_aysnd1; - required_device m_aysnd2; + optional_device m_aysnd1; + optional_device m_aysnd2; + optional_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" +#include "cedar_magnet_board.h" - -//const device_type CEDAR_MAGNET_BASE = &device_creator; - -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") +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) { } -INTERRUPT_GEN_MEMBER(cedar_magnet_board_device::irq) +void cedar_magnet_board_interface::write_cpu_bus(int offset, u8 data) { - m_cpu->set_input_line(0, HOLD_LINE); -} - -void cedar_magnet_board_device::device_start() -{ -} - -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() { - machine().scheduler().timer_set(attotime::from_usec(2), timer_expired_delegate(FUNC(cedar_magnet_board_device::halt_assert_callback),this)); + m_cpu->set_input_line(INPUT_LINE_IRQ0, HOLD_LINE); } -void cedar_magnet_board_device::halt_clear(void) +void cedar_magnet_board_interface::halt_assert() { - 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_assert_callback),this)); } -void cedar_magnet_board_device::reset_assert(void) +void cedar_magnet_board_interface::halt_clear() { - 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(2), timer_expired_delegate(FUNC(cedar_magnet_board_interface::halt_clear_callback),this)); } -void cedar_magnet_board_device::reset_clear(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_clear_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::device_reset() +void cedar_magnet_board_interface::reset_clear() +{ + 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_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; - - void halt_assert(void); - void halt_clear(void); - void reset_assert(void); - void reset_clear(void); - bool is_running(void); - bool m_is_running; - - INTERRUPT_GEN_MEMBER(irq); protected: - virtual void device_start() override; - virtual void device_reset() override; + virtual void interface_pre_reset() override; + + virtual TIMER_CALLBACK_MEMBER(reset_assert_callback); + + required_device m_cpu; + optional_shared_ptr 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("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(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("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("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