nightmare, cerberup, spain82: Add emulation of Sound-3 speech synthesizer board

* nightmare: Add coin counters
This commit is contained in:
AJR 2024-11-19 19:18:50 -05:00
parent f4a50aa850
commit a72c6ab3c1
5 changed files with 240 additions and 38 deletions

View File

@ -207,6 +207,7 @@
******************************************************************************/
#include "emu.h"
#include "efo_sound3.h"
#include "video/tms9928a.h"
#include "cpu/cosmac/cosmac.h"
#include "machine/cdp1852.h"
@ -226,7 +227,7 @@ public:
nightmare_state(const machine_config &mconfig, device_type type, const char *tag)
: driver_device(mconfig, type, tag)
, m_maincpu(*this, "cdp1802")
, m_soundcpu(*this,"cdp1802_sound")
, m_sound3(*this, "sound3")
, m_vdc(*this, "vdc")
, m_vdc2(*this, "vdc2")
, m_eeprom(*this,"eeprom")
@ -245,16 +246,14 @@ protected:
int ef2_r();
void q_w(int state);
void ic10_w(uint8_t data);
void unkout_w(uint8_t data);
void sound_w(uint8_t data);
void main_map(address_map &map) ATTR_COLD;
void io_map(address_map &map) ATTR_COLD;
void sound_map(address_map &map) ATTR_COLD;
void sound_io_map(address_map &map) ATTR_COLD;
uint32_t screen_update_nightmare(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect);
required_device<cosmac_device> m_maincpu;
required_device<cosmac_device> m_soundcpu;
required_device<efo_sound3_device> m_sound3;
required_device<tms9928a_device> m_vdc;
required_device<tms9928a_device> m_vdc2;
required_device<sda2006_device> m_eeprom;
@ -324,14 +323,20 @@ void nightmare_state::ic10_w(uint8_t data)
0 - ?
*/
m_eeprom->write_data((data&0x80) ?1:0);
m_eeprom->write_enable((data&0x40) ?1:0);
m_eeprom->write_data(BIT(data, 7));
m_eeprom->write_enable(BIT(data, 6));
machine().bookkeeping().coin_counter_w(0, BIT(data, 4));
machine().bookkeeping().coin_counter_w(1, BIT(data, 5));
}
void nightmare_state::unkout_w(uint8_t data)
void nightmare_state::sound_w(uint8_t data)
{
// J3
// J3
m_sound3->input_w(data);
m_sound3->clock_w(1);
m_sound3->clock_w(0);
}
void nightmare_state::main_map(address_map &map)
@ -342,22 +347,13 @@ void nightmare_state::main_map(address_map &map)
void nightmare_state::io_map(address_map &map)
{
map(1, 1).r("ic8", FUNC(cdp1852_device::read)).w(FUNC(nightmare_state::unkout_w));
map(1, 1).r("ic8", FUNC(cdp1852_device::read)).w(FUNC(nightmare_state::sound_w));
map(2, 2).r("ic9", FUNC(cdp1852_device::read)).w("ic10", FUNC(cdp1852_device::write));
map(4, 5).rw(m_vdc, FUNC(tms9928a_device::read), FUNC(tms9928a_device::write));
map(6, 7).rw(m_vdc2, FUNC(tms9928a_device::read), FUNC(tms9928a_device::write));
}
void nightmare_state::sound_map(address_map &map)
{
map(0x0000, 0x3fff).rom();
}
void nightmare_state::sound_io_map(address_map &map)
{
}
uint32_t nightmare_state::screen_update_nightmare(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect)
{
// combine two buffers (additive?)
@ -425,12 +421,6 @@ void nightmare_state::nightmare(machine_config &config)
m_maincpu->ef2_cb().set(FUNC(nightmare_state::ef2_r));
m_maincpu->tpb_cb().set("ic10", FUNC(cdp1852_device::clock_w));
// sound CPU
CDP1802(config, m_soundcpu, SOUND_CLOCK);
m_soundcpu->set_addrmap(AS_PROGRAM, &nightmare_state::sound_map);
m_soundcpu->set_addrmap(AS_IO, &nightmare_state::sound_io_map);
m_soundcpu->set_disable();
// I/O hardware
cdp1852_device &ic8(CDP1852(config, "ic8"));
ic8.mode_cb().set_constant(0);
@ -458,6 +448,8 @@ void nightmare_state::nightmare(machine_config &config)
screen_device &screen(SCREEN(config, "screen", SCREEN_TYPE_RASTER));
screen.set_screen_update(FUNC(nightmare_state::screen_update_nightmare));
EFO_SOUND3(config, m_sound3);
}
@ -467,9 +459,8 @@ ROM_START( nightmare )
ROM_LOAD( "nm1-ib1.ic12", 0x2000, 0x2000, CRC(c10695f7) SHA1(929467fe7529782e8181d3caae3a67bb0a8d8753) )
ROM_LOAD( "nm1-ic1.ic13", 0x4000, 0x2000, CRC(a3117246) SHA1(ca9601401f7ab34200c969e41ffae50bee0aca4d) )
ROM_REGION( 0x4000, "cdp1802_sound", 0 )
ROM_REGION( 0x2000, "sound3:rom", 0 )
ROM_LOAD( "scl-1a1.ic5", 0x0000, 0x2000, CRC(4bba61af) SHA1(b324344081e3d4b5db43a8ff3122c28cf75aec84) )
ROM_RELOAD( 0x2000, 0x2000 )
ROM_REGION( 0x40, "eeprom", 0 )
ROM_LOAD( "eeprom.ic7", 0x0000, 0x0040, CRC(7824e1f8) SHA1(2ccac62b4e8abcb2b3d66fa4025947fea184664e) )
@ -481,9 +472,8 @@ ROM_START( nightmarea )
ROM_LOAD( "nm1-ib1.ic12", 0x2000, 0x2000, CRC(c10695f7) SHA1(929467fe7529782e8181d3caae3a67bb0a8d8753) )
ROM_LOAD( "nm1-ic1.ic13", 0x4000, 0x2000, CRC(b0f8f163) SHA1(cbc4be2880b7a30f094c6fee9dccfa24adec3096) ) // Different from the parent set
ROM_REGION( 0x4000, "cdp1802_sound", 0 )
ROM_REGION( 0x2000, "sound3:rom", 0 )
ROM_LOAD( "scl-1a1.ic5", 0x0000, 0x2000, CRC(4bba61af) SHA1(b324344081e3d4b5db43a8ff3122c28cf75aec84) )
ROM_RELOAD( 0x2000, 0x2000 )
ROM_REGION( 0x40, "eeprom", 0 )
ROM_LOAD( "eeprom.ic7", 0x0000, 0x0040, CRC(7824e1f8) SHA1(2ccac62b4e8abcb2b3d66fa4025947fea184664e) )
@ -492,5 +482,5 @@ ROM_END
} // anonymous namespace
GAME( 1982, nightmare, 0, nightmare, nightmare, nightmare_state, empty_init, ROT90, "E.F.O.", "Night Mare (Spain, set 1)", MACHINE_NO_SOUND | MACHINE_SUPPORTS_SAVE | MACHINE_NO_COCKTAIL )
GAME( 1982, nightmarea, nightmare, nightmare, nightmare, nightmare_state, empty_init, ROT90, "E.F.O.", "Night Mare (Spain, set 2)", MACHINE_NO_SOUND | MACHINE_SUPPORTS_SAVE | MACHINE_NO_COCKTAIL )
GAME( 1982, nightmare, 0, nightmare, nightmare, nightmare_state, empty_init, ROT90, "E.F.O.", "Night Mare (Spain, set 1)", MACHINE_SUPPORTS_SAVE | MACHINE_NO_COCKTAIL )
GAME( 1982, nightmarea, nightmare, nightmare, nightmare, nightmare_state, empty_init, ROT90, "E.F.O.", "Night Mare (Spain, set 2)", MACHINE_SUPPORTS_SAVE | MACHINE_NO_COCKTAIL )

View File

@ -31,7 +31,8 @@ Adjustments:
Status:
- antar, storm, evlfight, attack, blkfever: Working
- Mad Race: J is the outhole. Working, no sound.
- Zira, Cerberus: not working
- Zira: not working
- Cerberus: not working (can't even coin up)
- Hold down the outhole key (usually X), when starting a game.
ToDo:
@ -43,6 +44,7 @@ ToDo:
#include "emu.h"
#include "genpin.h"
#include "efo_sound3.h"
#include "cpu/cop400/cop400.h"
#include "cpu/cosmac/cosmac.h"
@ -69,12 +71,14 @@ public:
, m_4020(*this, "4020")
, m_1863(*this, "1863")
, m_snd_off(*this, "snd_off")
, m_sound3(*this, "sound3")
, m_io_keyboard(*this, "X%d", 0U)
, m_digits(*this, "digit%d", 0U)
, m_io_outputs(*this, "out%d", 0U)
{ }
void play_2(machine_config &config);
void sound3(machine_config &config);
protected:
void port01_w(u8 data);
@ -109,6 +113,7 @@ protected:
required_device<ripple_counter_device> m_4020;
required_device<cdp1863_device> m_1863;
required_device<timer_device> m_snd_off;
optional_device<efo_sound3_device> m_sound3;
required_ioport_array<8> m_io_keyboard;
output_finder<55> m_digits;
output_finder<56> m_io_outputs; // 8 solenoids + 48 lamps
@ -332,6 +337,8 @@ void play_2_state::port07_w(u8 data)
{
u8 t = 30;
m_soundlatch = BIT(data, 4, 3); // Zira, Cerberus
if (m_sound3.found())
m_sound3->input_w(m_soundlatch);
m_4013b->clear_w(0);
m_4013b->clear_w(1);
// Solenoids
@ -498,6 +505,12 @@ void zira_state::init_zira()
membank("bank1")->set_entry(0);
}
void play_2_state::sound3(machine_config &config)
{
play_2(config);
EFO_SOUND3(config, m_sound3);
}
/* PLAYMATIC MPU-2 ALTERNATE ROMS =======================================================================
This is a list of known alternate roms. Nothing has been tested.
@ -611,7 +624,7 @@ ROM_START(cerberup)
ROM_LOAD("cerb9.9", 0x0800, 0x0800, CRC(0fd41156) SHA1(95d1bf42c82f480825e3d907ae3c87b5f994fd2a))
ROM_LOAD("cerb10.10", 0x1000, 0x0800, CRC(785602e0) SHA1(f38df3156cd14ab21752dbc849c654802079eb33))
ROM_REGION(0x10000, "audiocpu", 0)
ROM_REGION(0x2000, "sound3:rom", 0)
ROM_LOAD("cerb.snd", 0x0000, 0x2000, CRC(8af53a23) SHA1(a80b57576a1eb1b4544b718b9abba100531e3942))
ROM_END
@ -637,6 +650,6 @@ GAME(1979, storm, 0, play_2, play_2, play_2_state, empty_init, ROT0, "Se
GAME(1980, evlfight, 0, play_2, play_2, play_2_state, empty_init, ROT0, "Playmatic", "Evil Fight", MACHINE_IS_SKELETON_MECHANICAL | MACHINE_SUPPORTS_SAVE )
GAME(1980, attack, 0, play_2, play_2, play_2_state, empty_init, ROT0, "Playmatic", "Attack", MACHINE_IS_SKELETON_MECHANICAL | MACHINE_SUPPORTS_SAVE )
GAME(1980, blkfever, 0, play_2, play_2, play_2_state, empty_init, ROT0, "Playmatic", "Black Fever", MACHINE_IS_SKELETON_MECHANICAL | MACHINE_SUPPORTS_SAVE )
GAME(1982, cerberup, 0, play_2, play_2, play_2_state, empty_init, ROT0, "Playmatic", "Cerberus (Pinball)", MACHINE_IS_SKELETON_MECHANICAL | MACHINE_SUPPORTS_SAVE )
GAME(1982, cerberup, 0, sound3, play_2, play_2_state, empty_init, ROT0, "Playmatic", "Cerberus (Pinball)", MACHINE_IS_SKELETON_MECHANICAL | MACHINE_SUPPORTS_SAVE )
GAME(1985, madrace, 0, play_2, play_2, play_2_state, empty_init, ROT0, "Playmatic", "Mad Race", MACHINE_IS_SKELETON_MECHANICAL | MACHINE_SUPPORTS_SAVE )
GAME(1980, zira, 0, zira, play_2, zira_state, init_zira, ROT0, "Playmatic", "Zira", MACHINE_IS_SKELETON_MECHANICAL | MACHINE_SUPPORTS_SAVE )

View File

@ -45,8 +45,8 @@ ToDo:
- Mechanical sounds
- Skill Flight: not working
- Miss Disco: not working (no manual available). Uses different hardware. No sound rom.
- Spain82: can start a game but it's not really playable, has no sound (no manual available;
uses same sound board as Cerberus). The test buttons are unknown. The ball number doesn't show.
- Spain82: can start a game but it's not really playable (no manual available).
The test buttons are unknown. The ball number doesn't show.
So, after starting the machine, make sure the displays cycle between blank and 700000. If it
just sits there it has hung up, exit and restart. Insert a coin, hold X and press 1. Now,
you need to jiggle F and G and perhaps other nearby keys until the 0 starts flashing. You
@ -62,6 +62,7 @@ ToDo:
#include "emu.h"
#include "genpin.h"
#include "efo_sound3.h"
#include "efo_zsu.h"
#include "cpu/cosmac/cosmac.h"
@ -87,6 +88,7 @@ public:
, m_4020(*this, "4020")
, m_ay1(*this, "ay1")
, m_ay2(*this, "ay2")
, m_sound3(*this, "sound3")
, m_zsu(*this, "zsu")
, m_io_keyboard(*this, "X%d", 0U)
, m_digits(*this, "digit%d", 0U)
@ -94,6 +96,7 @@ public:
{ }
void play_3(machine_config &config);
void spain82(machine_config &config);
void flashman(machine_config &config);
void megaaton(machine_config &config);
void sklflite(machine_config &config);
@ -103,7 +106,9 @@ private:
void port01_w(u8 data);
void terrlake_port01_w(u8 data);
void port02_w(u8 data);
void spain82_port02_w(u8 data);
void port03_w(u8 data);
void spain82_port03_w(u8 data);
void sklflite_port03_w(u8 data);
u8 port04_r();
u8 port05_r();
@ -127,6 +132,7 @@ private:
void mem_map(address_map &map) ATTR_COLD;
void flashman_io(address_map &map) ATTR_COLD;
void sklflite_io(address_map &map) ATTR_COLD;
void spain82_io(address_map &map) ATTR_COLD;
u8 m_resetcnt = 0U;
u8 m_resetcnt_a = 0U;
@ -146,6 +152,7 @@ private:
required_device<ripple_counter_device> m_4020;
optional_device<ay8910_device> m_ay1;
optional_device<ay8910_device> m_ay2;
optional_device<efo_sound3_device> m_sound3;
optional_device<efo_zsu_device> m_zsu;
required_ioport_array<10> m_io_keyboard;
output_finder<70> m_digits;
@ -170,6 +177,13 @@ void play_3_state::io_map(address_map &map)
map(0x07, 0x07).w(FUNC(play_3_state::port07_w)); // flipflop clear
}
void play_3_state::spain82_io(address_map &map)
{
io_map(map);
map(0x02, 0x02).w(FUNC(play_3_state::spain82_port02_w));
map(0x03, 0x03).w(FUNC(play_3_state::spain82_port03_w));
}
void play_3_state::flashman_io(address_map &map)
{
io_map(map);
@ -384,6 +398,12 @@ void play_3_state::port02_w(u8 data)
m_soundlatch = data;
}
void play_3_state::spain82_port02_w(u8 data)
{
m_soundlatch = data;
m_sound3->input_w(data);
}
void play_3_state::port03_w(u8 data)
{
if (!BIT(data, 6))
@ -398,6 +418,19 @@ void play_3_state::port03_w(u8 data)
}
}
void play_3_state::spain82_port03_w(u8 data)
{
m_sound3->clock_w(BIT(data, 6));
if (BIT(data, 5))
{
if (m_soundlatch == 11)
m_samples->start(0, 5); // outhole
for (u8 i = 0; i < 16; i++)
m_io_outputs[i] = (m_soundlatch == i) ? 1 : 0;
}
}
void play_3_state::sklflite_port03_w(u8 data)
{
if (BIT(data, 6) && !BIT(m_port03_old, 6))
@ -573,6 +606,20 @@ void play_3_state::play_3(machine_config &config)
m_ay2->port_a_write_callback().set_nop();
}
void play_3_state::spain82(machine_config &config)
{
play_3(config);
m_maincpu->set_addrmap(AS_IO, &play_3_state::spain82_io);
config.device_remove("audiocpu");
config.device_remove("ay1");
config.device_remove("ay2");
config.device_remove("lspeaker");
config.device_remove("rspeaker");
EFO_SOUND3(config, m_sound3);
}
void play_3_state::flashman(machine_config &config)
{
play_3(config);
@ -630,7 +677,7 @@ ROM_START(spain82)
ROM_LOAD("spaic12.bin", 0x0000, 0x1000, CRC(cd37ecdc) SHA1(ff2d406b6ac150daef868121e5857a956aabf005))
ROM_LOAD("spaic11.bin", 0x1000, 0x0800, CRC(c86c0801) SHA1(1b52539538dae883f9c8fe5bc6454f9224780d11))
ROM_REGION(0x4000, "audiocpu", 0)
ROM_REGION(0x2000, "sound3:rom", 0)
ROM_LOAD("spasnd.bin", 0x0000, 0x2000, CRC(62412e2e) SHA1(9e48dc3295e78e1024f726906be6e8c3fe3e61b1))
ROM_END
@ -866,7 +913,7 @@ ROM_END
} // anonymous namespace
GAME(1982, spain82, 0, play_3, spain82, play_3_state, empty_init, ROT0, "Playmatic", "Spain '82", MACHINE_IS_SKELETON_MECHANICAL | MACHINE_SUPPORTS_SAVE )
GAME(1982, spain82, 0, spain82, spain82, play_3_state, empty_init, ROT0, "Playmatic", "Spain '82", MACHINE_IS_SKELETON_MECHANICAL | MACHINE_SUPPORTS_SAVE )
GAME(1983, megaaton, 0, megaaton, megaaton, play_3_state, empty_init, ROT0, "Playmatic", "Meg-Aaton", MACHINE_IS_SKELETON_MECHANICAL | MACHINE_SUPPORTS_SAVE )
GAME(1983, megaatona, megaaton, megaaton, megaaton, play_3_state, empty_init, ROT0, "Playmatic", "Meg-Aaton (alternate set)", MACHINE_IS_SKELETON_MECHANICAL | MACHINE_SUPPORTS_SAVE )
GAME(1984, nautilus, 0, play_3, play_3, play_3_state, empty_init, ROT0, "Playmatic", "Nautilus", MACHINE_IS_SKELETON_MECHANICAL | MACHINE_SUPPORTS_SAVE )

View File

@ -0,0 +1,110 @@
// license:BSD-3-Clause
// copyright-holders:AJR
/**********************************************************************
EFO Sound-3 speech synthesizer board
The CPU is identified on schematics as a custom "90435" type, but
board photos confirm it really is a CDP1802ACE as the pinout
and support ICs suggest. Its XTAL value is specified as 2.95 MHz,
but 3 MHZ has also been seen on one set of Night Mare.
The synthesizer IC is custom-marked as EFO90503, but it also bears
a TI logo and is obviously some sort of TMS5220 variant. Its
discrete oscillator circuit is tuned for a 160 KHz operating
frequency, according to both schematics and board markings.
(Unlike other EFO sound boards, Sound-3 has no PSG.)
The PCB has space for two TMS2532 EPROMs, but normally they are
both replaced by one TMS2564 EPROM.
Either of two pin headers may be used for input. J2 allows 8-bit
parallel data to be strobed in by a clock signal. J3 carries only
D0-D2 (+ ground) and is used with the older IOS-II board.
**********************************************************************/
#include "emu.h"
#include "efo_sound3.h"
#include "cpu/cosmac/cosmac.h"
#include "speaker.h"
DEFINE_DEVICE_TYPE(EFO_SOUND3, efo_sound3_device, "efo_sound3", "EFO Sound-3 board")
efo_sound3_device::efo_sound3_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock)
: device_t(mconfig, EFO_SOUND3, tag, owner, clock)
, m_inputlatch(*this, "inputlatch")
, m_intflatch(*this, "intflatch")
, m_tms(*this, "tms")
, m_input(0)
{
}
void efo_sound3_device::device_start()
{
save_item(NAME(m_input));
}
void efo_sound3_device::input_w(u8 data)
{
m_input = data;
}
void efo_sound3_device::clock_w(int state)
{
m_inputlatch->clock_w(state);
}
u8 efo_sound3_device::input_r()
{
return m_input;
}
void efo_sound3_device::intf_cs_w(int state)
{
// slightly hacky, but the data path must be enabled somehow
if (!m_tms->readyq_r() && !m_intflatch->sr_r())
m_tms->data_w(m_intflatch->read());
}
void efo_sound3_device::efo90435_mem(address_map &map)
{
map(0x0000, 0x1fff).mirror(0xc000).rom().region("rom", 0);
map(0x2000, 0x201f).mirror(0xdfe0).ram(); // CDP1824 @ IC6
}
void efo_sound3_device::efo90435_io(address_map &map)
{
map(1, 1).mirror(4).w(m_intflatch, FUNC(cdp1852_device::write_strobe));
map(2, 2).mirror(4).r(m_inputlatch, FUNC(cdp1852_device::read));
}
void efo_sound3_device::device_add_mconfig(machine_config &config)
{
cdp1802_device &soundcpu(CDP1802(config, "soundcpu", 2.95_MHz_XTAL)); // IC3 90435 "Microprocesador"
soundcpu.set_addrmap(AS_PROGRAM, &efo_sound3_device::efo90435_mem);
soundcpu.set_addrmap(AS_IO, &efo_sound3_device::efo90435_io);
soundcpu.ef3_cb().set(m_tms, FUNC(tms5220_device::status_r)).bit(6).invert();
soundcpu.ef4_cb().set(m_tms, FUNC(tms5220_device::status_r)).bit(7).invert();
soundcpu.q_cb().set(m_tms, FUNC(tms5220_device::rsq_w)).invert();
CDP1852(config, m_inputlatch); // IC7 "Entradas"
m_inputlatch->mode_cb().set_constant(0);
m_inputlatch->sr_cb().set_inputline("soundcpu", COSMAC_INPUT_LINE_EF2).invert();
m_inputlatch->di_cb().set(FUNC(efo_sound3_device::input_r));
CDP1852(config, m_intflatch); // IC8 "Interface Sintetizador"
m_intflatch->mode_cb().set_constant(0);
m_intflatch->sr_cb().set(m_tms, FUNC(tms5220_device::wsq_w));
m_intflatch->sr_cb().append(FUNC(efo_sound3_device::intf_cs_w));
TMS5220(config, m_tms, 640000); // IC9 90503 "Sintetizador"
m_tms->add_route(ALL_OUTPUTS, "mono", 1.0);
m_tms->irq_cb().set_inputline("soundcpu", COSMAC_INPUT_LINE_INT).invert();
m_tms->ready_cb().set_inputline("soundcpu", COSMAC_INPUT_LINE_EF1).invert();
m_tms->ready_cb().append(FUNC(efo_sound3_device::intf_cs_w));
SPEAKER(config, "mono"); // J5 "Altavoz"
}

View File

@ -0,0 +1,42 @@
// license:BSD-3-Clause
// copyright-holders:AJR
#ifndef MAME_SHARED_EFO_SOUND3_H
#define MAME_SHARED_EFO_SOUND3_H
#pragma once
#include "machine/cdp1852.h"
#include "sound/tms5220.h"
class efo_sound3_device : public device_t
{
public:
// construction/destruction
efo_sound3_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock = 0);
void input_w(u8 data);
void clock_w(int state);
protected:
virtual void device_add_mconfig(machine_config &config) override ATTR_COLD;
virtual void device_start() override ATTR_COLD;
private:
void efo90435_mem(address_map &map) ATTR_COLD;
void efo90435_io(address_map &map) ATTR_COLD;
u8 input_r();
void intf_cs_w(int state);
required_device<cdp1852_device> m_inputlatch;
required_device<cdp1852_device> m_intflatch;
required_device<tms5220_device> m_tms;
u8 m_input;
};
DECLARE_DEVICE_TYPE(EFO_SOUND3, efo_sound3_device)
#endif // MAME_SHARED_EFO_SOUND3_H