More miscellaneous cleanup:

emu/render.cpp: Use I/O filter for zlib decompression, avoiding the need
to use zlib directly.

audo/bally.cpp: Moved several constructors out of the header, fixed a
save state issue, and made outputs use finders.

exidy.cpp: Split up state class and reduced reliance on driver init
functions.

Changed various drivers to use output finders.
This commit is contained in:
Vas Crabb 2021-08-30 23:05:02 +10:00
parent cd17ea8829
commit 7e1795ae6b
14 changed files with 1094 additions and 1041 deletions

View File

@ -1973,10 +1973,8 @@ files {
MAME_DIR .. "src/mame/audio/circus.cpp",
MAME_DIR .. "src/mame/video/circus.cpp",
MAME_DIR .. "src/mame/drivers/exidy.cpp",
MAME_DIR .. "src/mame/includes/exidy.h",
MAME_DIR .. "src/mame/audio/exidy.cpp",
MAME_DIR .. "src/mame/audio/exidy.h",
MAME_DIR .. "src/mame/video/exidy.cpp",
MAME_DIR .. "src/mame/drivers/exidy440.cpp",
MAME_DIR .. "src/mame/includes/exidy440.h",
MAME_DIR .. "src/mame/audio/exidy440.cpp",

View File

@ -50,11 +50,10 @@
#include "ui/uimain.h"
#include "util/ioprocsfilter.h"
#include "util/path.h"
#include "util/xmlfile.h"
#include <zlib.h>
#include <algorithm>
@ -2118,58 +2117,56 @@ void render_target::load_additional_layout_files(const char *basename, bool have
bool render_target::load_layout_file(const char *dirname, const internal_layout &layout_data, device_t *device)
{
// +1 to ensure data is terminated for XML parser
auto tempout = make_unique_clear<u8 []>(layout_data.decompressed_size + 1);
z_stream stream;
int zerr;
// initialize the stream
memset(&stream, 0, sizeof(stream));
stream.next_out = tempout.get();
stream.avail_out = layout_data.decompressed_size;
zerr = inflateInit(&stream);
if (zerr != Z_OK)
std::unique_ptr<u8 []> tempout(new (std::nothrow) u8 [layout_data.decompressed_size + 1]);
auto inflater(util::zlib_read(util::ram_read(layout_data.data, layout_data.compressed_size), 8192));
if (!tempout || !inflater)
{
osd_printf_error("render_target::load_layout_file: zlib initialization error\n");
osd_printf_error("render_target::load_layout_file: not enough memory to decompress layout\n");
return false;
}
// decompress this chunk
stream.next_in = (unsigned char *)layout_data.data;
stream.avail_in = layout_data.compressed_size;
zerr = inflate(&stream, Z_NO_FLUSH);
// stop at the end of the stream
if (zerr == Z_STREAM_END)
size_t decompressed = 0;
do
{
// OK
}
else if (zerr != Z_OK)
size_t actual;
std::error_condition const err = inflater->read(
&tempout[decompressed],
layout_data.decompressed_size - decompressed,
actual);
decompressed += actual;
if (err)
{
osd_printf_error("render_target::load_layout_file: zlib decompression error\n");
inflateEnd(&stream);
osd_printf_error(
"render_target::load_layout_file: error decompressing layout (%s:%d %s)\n",
err.category().name(),
err.value(),
err.message());
return false;
}
if (!actual && (layout_data.decompressed_size < decompressed))
{
osd_printf_warning(
"render_target::load_layout_file: expected %u bytes of decompressed data but only got %u\n",
layout_data.decompressed_size,
decompressed);
break;
}
}
while (layout_data.decompressed_size > decompressed);
inflater.reset();
// clean up
zerr = inflateEnd(&stream);
if (zerr != Z_OK)
osd_printf_error("render_target::load_layout_file: zlib cleanup error\n");
tempout[decompressed] = 0U;
util::xml::file::ptr rootnode(util::xml::file::string_read(reinterpret_cast<char const *>(tempout.get()), nullptr));
tempout.reset();
// if we didn't get a properly-formatted XML file, record a warning and exit
if (!load_layout_file(device ? *device : m_manager.machine().root_device(), *rootnode, m_manager.machine().options().art_path(), dirname))
{
osd_printf_warning("Improperly formatted XML string, ignoring\n");
osd_printf_warning("render_target::load_layout_file: Improperly formatted XML string, ignoring\n");
return false;
}
else
{
return true;
}
}
bool render_target::load_layout_file(const char *dirname, const char *filename)

View File

@ -444,6 +444,28 @@ static INPUT_PORTS_START(cheap_squeak)
PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_SERVICE3 ) PORT_NAME("Sound Test") PORT_CHANGED_MEMBER(DEVICE_SELF, bally_cheap_squeak_device, sw1, 0)
INPUT_PORTS_END
bally_cheap_squeak_device::bally_cheap_squeak_device(
const machine_config &mconfig,
const char *tag,
device_t *owner,
uint32_t clock) :
bally_cheap_squeak_device(mconfig, BALLY_CHEAP_SQUEAK, tag, owner, clock)
{ }
bally_cheap_squeak_device::bally_cheap_squeak_device(
const machine_config &mconfig,
device_type type,
const char *tag,
device_t *owner,
uint32_t clock) :
device_t(mconfig, type, tag, owner, clock),
device_mixer_interface(mconfig, *this),
m_cpu(*this, "cpu"),
m_dac(*this, "dac"),
m_sound_ack_w_handler(*this),
m_leds(*this, "sound_led%u", 0U)
{ }
ioport_constructor bally_cheap_squeak_device::device_input_ports() const
{
return INPUT_PORTS_NAME(cheap_squeak);
@ -451,7 +473,6 @@ ioport_constructor bally_cheap_squeak_device::device_input_ports() const
INPUT_CHANGED_MEMBER(bally_cheap_squeak_device::sw1)
{
if (newval != oldval)
m_cpu->set_input_line(INPUT_LINE_NMI, (newval ? ASSERT_LINE : CLEAR_LINE));
}
@ -517,6 +538,8 @@ void bally_cheap_squeak_device::device_add_mconfig(machine_config &config)
void bally_cheap_squeak_device::device_start()
{
m_sound_ack_w_handler.resolve();
m_leds.resolve();
save_item(NAME(m_sound_select));
save_item(NAME(m_sound_int));
}
@ -557,8 +580,7 @@ void bally_cheap_squeak_device::out_p2_cb(uint8_t data)
void bally_cheap_squeak_device::update_led()
{
// Either input or output can pull the led line high
bool led_state = m_sound_int || m_sound_ack;
machine().output().set_value("sound_led0", led_state);
m_leds[0] = m_sound_int || m_sound_ack;
}
@ -566,6 +588,41 @@ void bally_cheap_squeak_device::update_led()
// Squawk & Talk
//**************************************************************************
bally_squawk_n_talk_device::bally_squawk_n_talk_device(
const machine_config &mconfig,
const char *tag,
device_t *owner,
uint32_t clock) :
bally_squawk_n_talk_device(mconfig, BALLY_SQUAWK_N_TALK, tag, owner, clock)
{ }
bally_squawk_n_talk_device::bally_squawk_n_talk_device(
const machine_config &mconfig,
device_type type,
const char *tag,
device_t *owner,
uint32_t clock) :
device_t(mconfig, type, tag, owner, clock),
device_mixer_interface(mconfig, *this),
m_cpu(*this, "cpu"),
m_pia1(*this, "pia1"),
m_pia2(*this, "pia2"),
m_dac_filter(*this, "dac_filter"),
m_dac(*this, "dac"),
m_speech_filter(*this, "speech_filter"),
m_tms5200(*this, "tms5200")
{ }
bally_squawk_n_talk_ay_device::bally_squawk_n_talk_ay_device(
const machine_config &mconfig,
const char *tag,
device_t *owner,
uint32_t clock) :
bally_squawk_n_talk_device(mconfig, BALLY_SQUAWK_N_TALK_AY, tag, owner, clock),
m_ay_filters(*this, "ay_filter%u", 0),
m_ay(*this, "ay")
{ }
//--------------------------------------------------------------------------
// IO ports
//--------------------------------------------------------------------------
@ -648,7 +705,7 @@ void bally_squawk_n_talk_device::device_add_mconfig(machine_config &config)
PIA6821(config, m_pia2, 0);
m_pia2->readpa_handler().set(FUNC(bally_squawk_n_talk_device::pia2_porta_r));
m_pia2->ca2_handler().set(FUNC(bally_squawk_n_talk_device::pia2_ca2_w));
m_pia2->ca2_handler().set_output("sound_led0");
m_pia2->irqa_handler().set(FUNC(bally_squawk_n_talk_device::pia_irq_w));
m_pia2->irqb_handler().set(FUNC(bally_squawk_n_talk_device::pia_irq_w));
@ -696,15 +753,6 @@ uint8_t bally_squawk_n_talk_device::pia2_porta_r()
return ~m_sound_select & 0x1f;
}
//-------------------------------------------------
// pia2_ca2_w - PIA 2 CA2 writes
//-------------------------------------------------
WRITE_LINE_MEMBER(bally_squawk_n_talk_device::pia2_ca2_w)
{
machine().output().set_value("sound_led0", state);
}
//-------------------------------------------------
// pia_irq_w - IRQ line state changes
//-------------------------------------------------
@ -726,10 +774,11 @@ void bally_squawk_n_talk_ay_device::device_add_mconfig(machine_config &config)
m_pia2->writepb_handler().set(FUNC(bally_squawk_n_talk_ay_device::pia2_portb_w));
m_pia2->cb2_handler().set(FUNC(bally_squawk_n_talk_ay_device::pia2_cb2_w));
for (optional_device<filter_rc_device> &filter : m_ay_filters)
// TODO: Calculate exact filter values. An AC filter is good enough for now
// and required as the chip likes to output a DC offset at idle.
for (auto &filter : m_ay_filters)
FILTER_RC(config, filter).set_ac().add_route(ALL_OUTPUTS, *this, 1.0);
AY8910(config, m_ay, DERIVED_CLOCK(1, 4));
m_ay->add_route(0, "ay_filter0", 0.33);
m_ay->add_route(1, "ay_filter1", 0.33);
@ -742,6 +791,8 @@ void bally_squawk_n_talk_ay_device::device_add_mconfig(machine_config &config)
//-------------------------------------------------
void bally_squawk_n_talk_ay_device::device_start()
{
bally_squawk_n_talk_device::device_start();
// Set volumes to a sane default.
m_ay->set_volume(0, 0);
m_ay->set_volume(1, 0);

View File

@ -205,9 +205,7 @@ public:
const machine_config &mconfig,
const char *tag,
device_t *owner,
uint32_t clock = 3'579'545) :
bally_cheap_squeak_device(mconfig, BALLY_CHEAP_SQUEAK, tag, owner, clock)
{ }
uint32_t clock = 3'579'545);
auto sound_ack_w_handler() { return m_sound_ack_w_handler.bind(); }
@ -224,13 +222,7 @@ protected:
device_type type,
const char *tag,
device_t *owner,
uint32_t clock) :
device_t(mconfig, type, tag, owner, clock),
device_mixer_interface(mconfig, *this),
m_cpu(*this, "cpu"),
m_dac(*this, "dac"),
m_sound_ack_w_handler(*this)
{ }
uint32_t clock);
// device-level overrides
virtual void device_add_mconfig(machine_config &config) override;
@ -247,6 +239,7 @@ private:
bool m_sound_ack;
devcb_write_line m_sound_ack_w_handler;
output_finder<1> m_leds;
// internal communications
TIMER_CALLBACK_MEMBER(sound_select_sync);
@ -269,9 +262,7 @@ public:
const machine_config &mconfig,
const char *tag,
device_t *owner,
uint32_t clock = 3'579'545) :
bally_squawk_n_talk_device(mconfig, BALLY_SQUAWK_N_TALK, tag, owner, clock)
{ }
uint32_t clock = 3'579'545);
// read/write
DECLARE_INPUT_CHANGED_MEMBER(sw1);
@ -286,19 +277,7 @@ protected:
device_type type,
const char *tag,
device_t *owner,
uint32_t clock) :
device_t(mconfig, type, tag, owner, clock),
device_mixer_interface(mconfig, *this),
m_cpu(*this, "cpu"),
m_pia1(*this, "pia1"),
m_pia2(*this, "pia2"),
m_dac_filter(*this, "dac_filter"),
m_dac(*this, "dac"),
m_speech_filter(*this, "speech_filter"),
m_tms5200(*this, "tms5200"),
m_ay_filters(*this, "ay_filter%u", 0),
m_ay(*this, "ay")
{ }
uint32_t clock);
// device-level overrides
virtual void device_add_mconfig(machine_config &config) override;
@ -313,8 +292,6 @@ protected:
required_device<dac_byte_interface> m_dac;
required_device<filter_rc_device> m_speech_filter;
required_device<tms5200_device> m_tms5200;
optional_device_array<filter_rc_device, 3> m_ay_filters;
optional_device<ay8910_device> m_ay;
uint8_t m_sound_select;
@ -325,7 +302,6 @@ private:
TIMER_CALLBACK_MEMBER(sound_select_sync);
TIMER_CALLBACK_MEMBER(sound_int_sync);
void pia1_portb_w(uint8_t data);
DECLARE_WRITE_LINE_MEMBER(pia2_ca2_w);
DECLARE_WRITE_LINE_MEMBER(pia_irq_w);
};
@ -337,9 +313,7 @@ public:
const machine_config &mconfig,
const char *tag,
device_t *owner,
uint32_t clock = 3'579'545) :
bally_squawk_n_talk_device(mconfig, BALLY_SQUAWK_N_TALK_AY, tag, owner, clock)
{ }
uint32_t clock = 3'579'545);
protected:
// device-level overrides
@ -353,6 +327,9 @@ private:
bool m_bdir;
uint8_t m_ay_data;
required_device_array<filter_rc_device, 3> m_ay_filters;
required_device<ay8910_device> m_ay;
void pia2_porta_w(uint8_t data);
void pia2_portb_w(uint8_t data);
DECLARE_WRITE_LINE_MEMBER(pia2_cb2_w);

View File

@ -75,6 +75,7 @@ public:
, m_dac(*this, "dac")
, m_switch(*this, "SWITCH.%u", 0)
, m_digits(*this, "digit%u", 0U)
, m_player_lamps(*this, "text%u", 0U)
{ }
void midearth(machine_config &config);
@ -82,8 +83,8 @@ public:
void atarians(machine_config &config);
protected:
virtual void machine_start() override;
virtual void machine_reset() override;
virtual void machine_start() override { m_digits.resolve(); }
private:
uint8_t m1080_r();
@ -121,6 +122,7 @@ private:
required_device<dac_4bit_r2r_device> m_dac;
required_ioport_array<10> m_switch;
output_finder<78> m_digits;
output_finder<8> m_player_lamps;
};
void atari_s1_state::atari_s1_map(address_map &map)
@ -384,26 +386,25 @@ uint8_t atari_s1_state::switch_r(offs_t offset)
TIMER_DEVICE_CALLBACK_MEMBER( atari_s1_state::nmi )
{
static const uint8_t patterns[16] = { 0x3f, 0x06, 0x5b, 0x4f, 0x66, 0x6d, 0x7c, 0x07, 0x7f, 0x67, 0, 0, 0, 0, 0, 0 }; // 4511
m_bit6++;
if (m_t_c > 0x40)
m_maincpu->pulse_input_line(INPUT_LINE_NMI, attotime::zero);
else
m_t_c++;
m_out_offs++;
m_out_offs &= 0x1f;
if ((m_out_offs & 3) == 3)
m_out_offs = (m_out_offs + 1) & 0x1f;
uint8_t const p_val = m_p_ram[m_out_offs];
if ((m_out_offs & 0x03) == 0x03)
{
// Player number
char wordnum[8];
sprintf(wordnum,"text%d",m_out_offs>>2);
output().set_value(wordnum, !BIT(patterns[m_p_ram[m_out_offs]&15], 6)); // uses 'g' segment
m_player_lamps[m_out_offs >> 2] = !BIT(patterns[p_val & 0x0f], 6); // uses 'g' segment
}
else
{
// Digits
m_digits[m_out_offs << 1] = patterns[m_p_ram[m_out_offs]>>4];
m_digits[(m_out_offs << 1)+1] = patterns[m_p_ram[m_out_offs]&15];
m_digits[(m_out_offs << 1) + 0] = patterns[p_val >> 4];
m_digits[(m_out_offs << 1) + 1] = patterns[p_val & 0x0f];
}
}
@ -445,6 +446,12 @@ void atari_s1_state::audiores_w(uint8_t data)
}
void atari_s1_state::machine_start()
{
m_digits.resolve();
m_player_lamps.resolve();
}
void atari_s1_state::machine_reset()
{
m_vol = 0;

View File

@ -20,13 +20,18 @@ ToDo:
#include "emu.h"
#include "machine/genpin.h"
#include "cpu/m6800/m6800.h"
#include "machine/6821pia.h"
#include "machine/timer.h"
#include "by17.lh"
#include "by17_pwerplay.lh"
#include "by17_matahari.lh"
namespace {
class by17_state : public genpin_class
{
public:
@ -118,7 +123,6 @@ private:
DECLARE_WRITE_LINE_MEMBER(u10_cb2_w);
DECLARE_READ_LINE_MEMBER(u11_ca1_r);
DECLARE_READ_LINE_MEMBER(u11_cb1_r);
DECLARE_WRITE_LINE_MEMBER(u11_ca2_w);
DECLARE_WRITE_LINE_MEMBER(u11_cb2_w);
TIMER_DEVICE_CALLBACK_MEMBER(timer_z_freq);
@ -577,11 +581,6 @@ WRITE_LINE_MEMBER( by17_state::u10_cb2_w )
m_u10_cb2 = state;
}
WRITE_LINE_MEMBER( by17_state::u11_ca2_w )
{
output().set_value("led0", state);
}
READ_LINE_MEMBER( by17_state::u11_ca1_r )
{
return m_u11_ca1;
@ -1014,8 +1013,8 @@ void by17_state::by17(machine_config &config)
m_pia_u10->readcb1_handler().set(FUNC(by17_state::u10_cb1_r));
m_pia_u10->ca2_handler().set(FUNC(by17_state::u10_ca2_w));
m_pia_u10->cb2_handler().set(FUNC(by17_state::u10_cb2_w));
m_pia_u10->irqa_handler().set_inputline("maincpu", M6800_IRQ_LINE);
m_pia_u10->irqb_handler().set_inputline("maincpu", M6800_IRQ_LINE);
m_pia_u10->irqa_handler().set_inputline(m_maincpu, M6800_IRQ_LINE);
m_pia_u10->irqb_handler().set_inputline(m_maincpu, M6800_IRQ_LINE);
TIMER(config, "timer_z_freq").configure_periodic(FUNC(by17_state::timer_z_freq), attotime::from_hz(100)); // Mains Line Frequency * 2
TIMER(config, m_zero_crossing_active_timer).configure_generic(FUNC(by17_state::timer_z_pulse)); // Active pulse length from Zero Crossing detector
@ -1025,10 +1024,10 @@ void by17_state::by17(machine_config &config)
m_pia_u11->writepb_handler().set(FUNC(by17_state::u11_b_w));
m_pia_u11->readca1_handler().set(FUNC(by17_state::u11_ca1_r));
m_pia_u11->readcb1_handler().set(FUNC(by17_state::u11_cb1_r));
m_pia_u11->ca2_handler().set(FUNC(by17_state::u11_ca2_w));
m_pia_u11->ca2_handler().set_output("led0");
m_pia_u11->cb2_handler().set(FUNC(by17_state::u11_cb2_w));
m_pia_u11->irqa_handler().set_inputline("maincpu", M6800_IRQ_LINE);
m_pia_u11->irqb_handler().set_inputline("maincpu", M6800_IRQ_LINE);
m_pia_u11->irqa_handler().set_inputline(m_maincpu, M6800_IRQ_LINE);
m_pia_u11->irqb_handler().set_inputline(m_maincpu, M6800_IRQ_LINE);
TIMER(config, "timer_d_freq").configure_periodic(FUNC(by17_state::u11_timer), attotime::from_hz(317)); // 555 timer
TIMER(config, m_display_refresh_timer).configure_generic(FUNC(by17_state::timer_d_pulse)); // 555 Active pulse length
}
@ -1149,6 +1148,8 @@ ROM_END
/ Stellar Airship / Geiger-Automatenbau GMBH, of Germany (1981)
/---------------------------------------------------------------*/
} // anonymous namespace
GAME( 1976, bowarrow, 0, by17, by17, by17_state, init_by17, ROT0, "Bally", "Bow & Arrow (Prototype, rev. 23)", MACHINE_IS_SKELETON_MECHANICAL)
GAME( 1976, bowarrowa, bowarrow, by17, by17, by17_state, init_by17, ROT0, "Bally", "Bow & Arrow (Prototype, rev. 22)", MACHINE_IS_SKELETON_MECHANICAL)

View File

@ -82,6 +82,8 @@ ToDo:
#include "by35_playboy.lh"
namespace {
class by35_state : public genpin_class
{
public:
@ -157,7 +159,6 @@ protected:
DECLARE_WRITE_LINE_MEMBER(u10_cb2_w);
DECLARE_READ_LINE_MEMBER(u11_ca1_r);
DECLARE_READ_LINE_MEMBER(u11_cb1_r);
DECLARE_WRITE_LINE_MEMBER(u11_ca2_w);
DECLARE_WRITE_LINE_MEMBER(u11_cb2_w);
virtual void machine_start() override;
virtual void machine_reset() override;
@ -1066,11 +1067,6 @@ WRITE_LINE_MEMBER( by35_state::u10_cb2_w )
m_u10_cb2 = state;
}
WRITE_LINE_MEMBER( by35_state::u11_ca2_w )
{
output().set_value("led0", state);
}
READ_LINE_MEMBER( by35_state::u11_ca1_r )
{
return m_u11_ca1;
@ -1473,8 +1469,8 @@ void by35_state::by35(machine_config &config)
m_pia_u10->readcb1_handler().set(FUNC(by35_state::u10_cb1_r));
m_pia_u10->ca2_handler().set(FUNC(by35_state::u10_ca2_w));
m_pia_u10->cb2_handler().set(FUNC(by35_state::u10_cb2_w));
m_pia_u10->irqa_handler().set_inputline("maincpu", M6800_IRQ_LINE);
m_pia_u10->irqb_handler().set_inputline("maincpu", M6800_IRQ_LINE);
m_pia_u10->irqa_handler().set_inputline(m_maincpu, M6800_IRQ_LINE);
m_pia_u10->irqb_handler().set_inputline(m_maincpu, M6800_IRQ_LINE);
TIMER(config, "timer_z_freq").configure_periodic(FUNC(by35_state::timer_z_freq), attotime::from_hz(100)); // Mains Line Frequency * 2
TIMER(config, m_zero_crossing_active_timer).configure_generic(FUNC(by35_state::timer_z_pulse)); // Active pulse length from Zero Crossing detector
@ -1484,10 +1480,10 @@ void by35_state::by35(machine_config &config)
m_pia_u11->writepb_handler().set(FUNC(by35_state::u11_b_w));
m_pia_u11->readca1_handler().set(FUNC(by35_state::u11_ca1_r));
m_pia_u11->readcb1_handler().set(FUNC(by35_state::u11_cb1_r));
m_pia_u11->ca2_handler().set(FUNC(by35_state::u11_ca2_w));
m_pia_u11->ca2_handler().set_output("led0");
m_pia_u11->cb2_handler().set(FUNC(by35_state::u11_cb2_w));
m_pia_u11->irqa_handler().set_inputline("maincpu", M6800_IRQ_LINE);
m_pia_u11->irqb_handler().set_inputline("maincpu", M6800_IRQ_LINE);
m_pia_u11->irqa_handler().set_inputline(m_maincpu, M6800_IRQ_LINE);
m_pia_u11->irqb_handler().set_inputline(m_maincpu, M6800_IRQ_LINE);
TIMER(config, "timer_d_freq").configure_periodic(FUNC(by35_state::u11_timer), attotime::from_hz(317)); // 555 timer
TIMER(config, m_display_refresh_timer).configure_generic(FUNC(by35_state::timer_d_pulse)); // 555 Active pulse length
}
@ -2790,6 +2786,9 @@ ROM_START(suprbowl)
ROM_LOAD("suprbowl.snd", 0xf000, 0x1000, CRC(97fc0f7a) SHA1(595aa080a6d2c1ab7e718974c4d01e846e142cc1))
ROM_END
} // anonymous namespace
// AS-2888 sound
GAME( 1979, sst, 0, as2888, by35, by35_state, init_by35_6, ROT0, "Bally", "Supersonic", MACHINE_MECHANICAL | MACHINE_NOT_WORKING)
GAMEL(1978, playboy, 0, as2888, playboy, by35_state, init_by35_6, ROT0, "Bally", "Playboy", MACHINE_MECHANICAL | MACHINE_NOT_WORKING, layout_by35_playboy)

View File

@ -21,15 +21,19 @@ ToDo:
#include "emu.h"
//#include "audio/midway.h"
#include "machine/genpin.h"
#include "cpu/m6800/m6801.h"
//#include "cpu/m6809/m6809.h"
#include "machine/6821pia.h"
#include "machine/timer.h"
//#include "audio/midway.h"
//#include "by6803.lh"
namespace {
class by6803_state : public genpin_class
{
public:
@ -39,12 +43,9 @@ public:
, m_pia0(*this, "pia0")
, m_pia1(*this, "pia1")
, m_io_test(*this, "TEST")
, m_io_x0(*this, "X0")
, m_io_x1(*this, "X1")
, m_io_x2(*this, "X2")
, m_io_x3(*this, "X3")
, m_io_x4(*this, "X4")
, m_io_x(*this, "X%u", 0U)
, m_digits(*this, "digit%u", 0U)
, m_leds(*this, "led%u", 0U)
{ }
void init_by6803();
@ -53,6 +54,10 @@ public:
DECLARE_INPUT_CHANGED_MEMBER(activity_test);
DECLARE_INPUT_CHANGED_MEMBER(self_test);
protected:
virtual void machine_start() override;
virtual void machine_reset() override;
private:
uint8_t port1_r();
void port1_w(uint8_t data);
@ -81,18 +86,13 @@ private:
uint8_t m_port1, m_port2;
//uint8_t m_digit;
uint8_t m_segment;
virtual void machine_reset() override;
virtual void machine_start() override { m_digits.resolve(); }
required_device<m6803_cpu_device> m_maincpu;
required_device<pia6821_device> m_pia0;
required_device<pia6821_device> m_pia1;
required_ioport m_io_test;
required_ioport m_io_x0;
required_ioport m_io_x1;
required_ioport m_io_x2;
required_ioport m_io_x3;
required_ioport m_io_x4;
required_ioport_array<5> m_io_x;
output_finder<40> m_digits;
output_finder<1> m_leds;
};
@ -193,7 +193,7 @@ uint8_t by6803_state::port2_r()
void by6803_state::port2_w(uint8_t data)
{
m_port2 = data;
output().set_value("led0", BIT(data, 2)); // P22 drives LED
m_leds[0] = BIT(data, 2); // P22 drives LED
}
// display latch strobes; display blanking
@ -254,20 +254,9 @@ uint8_t by6803_state::pia0_b_r()
{
uint8_t data = 0;
if (BIT(m_pia0_a, 0))
data |= m_io_x0->read();
if (BIT(m_pia0_a, 1))
data |= m_io_x1->read();
if (BIT(m_pia0_a, 2))
data |= m_io_x2->read();
if (BIT(m_pia0_a, 3))
data |= m_io_x3->read();
if (BIT(m_pia0_a, 4))
data |= m_io_x4->read();
for (unsigned i = 0; m_io_x.size() > i; ++i)
if (BIT(m_pia0_a, i))
data |= m_io_x[i]->read();
return data;
}
@ -342,6 +331,12 @@ void by6803_state::pia1_b_w(uint8_t data)
}
}
void by6803_state::machine_start()
{
m_digits.resolve();
m_leds.resolve();
}
void by6803_state::machine_reset()
{
m_pia0_a = 0;
@ -750,6 +745,8 @@ ROM_START(trucksp2)
ROM_RELOAD(0x20000 +0x8000, 0x8000)
ROM_END
} // anonymous namespace
GAME( 1985, eballchp, 0, by6803, by6803, by6803_state, init_by6803, ROT0, "Bally", "Eight Ball Champ", MACHINE_IS_SKELETON_MECHANICAL)
GAME( 1985, beatclck, 0, by6803, by6803, by6803_state, init_by6803, ROT0, "Bally", "Beat the Clock", MACHINE_IS_SKELETON_MECHANICAL)

File diff suppressed because it is too large Load Diff

View File

@ -108,7 +108,7 @@ public:
fe132_state(mconfig, type, tag),
m_nvram(*this, "nvram"),
m_hopper(*this, "hopper"),
m_lamps(*this, "lamps%u", 0U)
m_lamps(*this, "lamp%u", 0U)
{ }
void royalpk2(machine_config &config);

View File

@ -272,16 +272,19 @@ register. So what is controlling priority.
***************************************************************************/
#include "emu.h"
#include "audio/taitosnd.h"
#include "includes/taitoipt.h"
#include "machine/taitocchip.h"
#include "video/pc080sn.h"
#include "video/pc090oj.h"
#include "cpu/m68000/m68000.h"
#include "cpu/z80/z80.h"
#include "machine/timer.h"
#include "machine/taitocchip.h"
#include "sound/msm5205.h"
#include "sound/ymopm.h"
#include "includes/taitoipt.h"
#include "video/pc080sn.h"
#include "video/pc090oj.h"
#include "audio/taitosnd.h"
#include "emupal.h"
#include "screen.h"
#include "speaker.h"
@ -312,7 +315,9 @@ public:
m_pc090oj(*this, "pc090oj"),
m_msm(*this, "msm%u", 0),
m_lspeaker(*this, "lspeaker"),
m_rspeaker(*this, "rspeaker")
m_rspeaker(*this, "rspeaker"),
m_z80bank(*this, "z80bank"),
m_recoil(*this, "Player%u_Recoil_Piston", 1U)
{ }
void opwolf(machine_config &config);
@ -336,7 +341,6 @@ private:
void opwolf_adpcm_d_w(uint8_t data);
void opwolf_adpcm_e_w(uint8_t data);
void opwolf_spritectrl_w(offs_t offset, uint16_t data);
void sound_bankswitch_w(uint8_t data);
void opwolf_adpcm_b_w(offs_t offset, uint8_t data);
void opwolf_adpcm_c_w(offs_t offset, uint8_t data);
void counters_w(uint8_t data);
@ -382,6 +386,8 @@ private:
required_device_array<msm5205_device, 2> m_msm;
required_device<speaker_device> m_lspeaker;
required_device<speaker_device> m_rspeaker;
required_memory_bank m_z80bank;
output_finder<1> m_recoil;
};
@ -461,7 +467,7 @@ void opwolf_state::opwolfp_map(address_map &map)
void opwolf_state::opwolf_sound_z80_map(address_map &map)
{
map(0x0000, 0x3fff).rom();
map(0x4000, 0x7fff).bankr("z80bank");
map(0x4000, 0x7fff).bankr(m_z80bank);
map(0x8000, 0x8fff).ram();
map(0x9000, 0x9001).rw("ymsnd", FUNC(ym2151_device::read), FUNC(ym2151_device::write));
map(0x9002, 0x9100).nopr();
@ -644,31 +650,24 @@ void opwolf_state::opwolf_spritectrl_w(offs_t offset, uint16_t data)
// popmessage("opwolf_spritectrl_w ctrl = %4x", data);
if (offset == 0)
{
/* bit 0 -> MOTOR1 transistor */
/* bit 1 -> MOTOR2 transistor */
/* bit 2 -> Reset c-chip and coin custom PC050CM (active low) */
/* bit 3 -> Not connected */
/* bit 4 -> LATCH - used to signal light gun position can be latched to inputs on v-blank */
/* bits 5-7 are the sprite palette bank */
// bit 0 -> MOTOR1 transistor
// bit 1 -> MOTOR2 transistor
// bit 2 -> Reset c-chip and coin custom PC050CM (active low)
// bit 3 -> Not connected
// bit 4 -> LATCH - used to signal light gun position can be latched to inputs on v-blank
// bits 5-7 are the sprite palette bank
m_pc090oj->sprite_ctrl_w(data);
/* If data & 3, the Piston Motor is activated via M-1/M-2 connector */
if (data & 3)
{
output().set_value("Player1_Recoil_Piston", 1);
}
else
{
output().set_value("Player1_Recoil_Piston", 0);
}
// If data & 3, the Piston Motor is activated via M-1/M-2 connector
m_recoil[0] = (data & 3) ? 1 : 0;
}
}
void opwolf_state::opwolf_colpri_cb(u32 &sprite_colbank, u32 &pri_mask, u16 sprite_ctrl)
{
sprite_colbank = (sprite_ctrl & 0xe0) >> 1;
pri_mask = 0xfc; /* sprites under top bg layer */
pri_mask = 0xfc; // sprites under top bg layer
}
uint32_t opwolf_state::screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
@ -709,11 +708,6 @@ GFXDECODE_END
// SOUND
//**************************************************************************
void opwolf_state::sound_bankswitch_w(uint8_t data)
{
membank("z80bank")->set_entry(data & 0x03);
}
//0 - start ROM offset LSB
//1 - start ROM offset MSB
//2 - end ROM offset LSB
@ -817,8 +811,6 @@ void opwolf_state::init_opwolf()
// World & US version have different gun offsets, presumably slightly different gun hardware
m_opwolf_gun_xoffs = 0xec - (rom[0x03ffb0 / 2] & 0xff);
m_opwolf_gun_yoffs = 0x1c - (rom[0x03ffae / 2] & 0xff);
membank("z80bank")->configure_entries(0, 4, memregion("audiocpu")->base(), 0x4000);
}
void opwolf_state::init_opwolfb()
@ -826,20 +818,20 @@ void opwolf_state::init_opwolfb()
/* bootleg needs different range of raw gun coords */
m_opwolf_gun_xoffs = -2;
m_opwolf_gun_yoffs = 17;
membank("z80bank")->configure_entries(0, 4, memregion("audiocpu")->base(), 0x4000);
}
void opwolf_state::init_opwolfp()
{
m_opwolf_gun_xoffs = 5;
m_opwolf_gun_yoffs = 30;
membank("z80bank")->configure_entries(0, 4, memregion("audiocpu")->base(), 0x4000);
}
void opwolf_state::machine_start()
{
m_recoil.resolve();
m_z80bank->configure_entries(0, 4, memregion("audiocpu")->base(), 0x4000);
save_item(NAME(m_sprite_ctrl));
save_item(NAME(m_sprites_flipscreen));
@ -938,7 +930,7 @@ void opwolf_state::opwolf(machine_config &config)
ym2151_device &ymsnd(YM2151(config, "ymsnd", SOUND_CPU_CLOCK)); /* 4 MHz */
ymsnd.irq_handler().set_inputline(m_audiocpu, 0);
ymsnd.port_write_handler().set(FUNC(opwolf_state::sound_bankswitch_w));
ymsnd.port_write_handler().set_membank(m_z80bank).mask(0x03);
ymsnd.add_route(0, "lspeaker", 1.0);
ymsnd.add_route(1, "rspeaker", 1.0);
@ -1012,7 +1004,7 @@ void opwolf_state::opwolfb(machine_config &config) /* OSC clocks unknown for the
ym2151_device &ymsnd(YM2151(config, "ymsnd", SOUND_CPU_CLOCK));
ymsnd.irq_handler().set_inputline(m_audiocpu, 0);
ymsnd.port_write_handler().set(FUNC(opwolf_state::sound_bankswitch_w));
ymsnd.port_write_handler().set_membank(m_z80bank).mask(0x03);
ymsnd.add_route(0, "lspeaker", 1.0);
ymsnd.add_route(1, "rspeaker", 1.0);

View File

@ -315,7 +315,6 @@ public:
, m_maincpu(*this, "maincpu")
, m_soundcpu(*this, "soundcpu")
, m_gfxdecode(*this, "gfxdecode")
, m_aysnd(*this, "aysnd")
, m_digits(*this, "digit%u", 0U)
, m_lamps(*this, "lamp%u", 0U)
{ }
@ -323,15 +322,13 @@ public:
void videopkr(machine_config &config);
void blckjack(machine_config &config);
void videodad(machine_config &config);
void babypkr(machine_config &config);
void fortune1(machine_config &config);
void bpoker(machine_config &config);
protected:
virtual void machine_start() override;
virtual void video_start() override;
private:
//private:
uint8_t videopkr_io_r(offs_t offset);
void videopkr_io_w(offs_t offset, uint8_t data);
uint8_t videopkr_p1_data_r();
@ -344,14 +341,9 @@ private:
void sound_io_w(uint8_t data);
uint8_t sound_p2_r();
void sound_p2_w(uint8_t data);
uint8_t baby_sound_p0_r();
void baby_sound_p0_w(uint8_t data);
uint8_t baby_sound_p1_r();
void baby_sound_p3_w(uint8_t data);
TILE_GET_INFO_MEMBER(get_bg_tile_info);
void videopkr_palette(palette_device &palette) const;
DECLARE_VIDEO_START(vidadcba);
void babypkr_palette(palette_device &palette) const;
void fortune1_palette(palette_device &palette) const;
uint32_t screen_update_videopkr(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect);
TIMER_DEVICE_CALLBACK_MEMBER(sound_t1_callback);
@ -361,10 +353,6 @@ private:
void i8039_map(address_map &map);
void i8039_sound_mem(address_map &map);
void i8039_sound_port(address_map &map);
void i8051_sound_mem(address_map &map);
void i8051_sound_port(address_map &map);
void i8751_io_port(address_map &map);
void i8751_map(address_map &map);
memory_share_creator<uint8_t> m_data_ram;
memory_share_creator<uint8_t> m_video_ram;
@ -395,17 +383,50 @@ private:
unsigned long m_count2;
unsigned long m_count3;
unsigned long m_count4;
uint8_t m_sbp0;
tilemap_t *m_bg_tilemap;
required_device<cpu_device> m_maincpu;
required_device<cpu_device> m_soundcpu;
required_device<gfxdecode_device> m_gfxdecode;
optional_device<ay8910_device> m_aysnd;
output_finder<28> m_digits;
output_finder<14> m_lamps;
};
class babypkr_state : public videopkr_state
{
public:
babypkr_state(const machine_config &mconfig, device_type type, const char *tag)
: videopkr_state(mconfig, type, tag)
, m_aysnd(*this, "aysnd")
, m_top_lamps(*this, "TOP_%u", 1U)
{
}
void babypkr(machine_config &config);
void bpoker(machine_config &config);
protected:
virtual void machine_start() override;
private:
uint8_t baby_sound_p0_r();
void baby_sound_p0_w(uint8_t data);
uint8_t baby_sound_p1_r();
void baby_sound_p3_w(uint8_t data);
void babypkr_palette(palette_device &palette) const;
void i8751_map(address_map &map);
void i8751_io_port(address_map &map);
void i8051_sound_mem(address_map &map);
void i8051_sound_port(address_map &map);
required_device<ay8910_device> m_aysnd;
output_finder<3> m_top_lamps;
uint8_t m_sbp0;
};
#define DATA_NVRAM_SIZE 0x100
/*************************
@ -468,7 +489,7 @@ void videopkr_state::videopkr_palette(palette_device &palette) const
}
}
void videopkr_state::babypkr_palette(palette_device &palette) const
void babypkr_state::babypkr_palette(palette_device &palette) const
{
uint8_t const *const color_prom = memregion("proms")->base();
for (int j = 0; j < palette.entries(); j++)
@ -875,17 +896,17 @@ void videopkr_state::sound_p2_w(uint8_t data)
/* Baby Sound Handlers */
uint8_t videopkr_state::baby_sound_p0_r()
uint8_t babypkr_state::baby_sound_p0_r()
{
return m_sbp0;
}
void videopkr_state::baby_sound_p0_w(uint8_t data)
void babypkr_state::baby_sound_p0_w(uint8_t data)
{
m_sbp0 = data;
}
uint8_t videopkr_state::baby_sound_p1_r()
uint8_t babypkr_state::baby_sound_p1_r()
{
m_c_io = (m_p1 >> 5) & 1;
m_hp_1 = (~m_p24_data >> 6) & 1;
@ -895,14 +916,11 @@ uint8_t videopkr_state::baby_sound_p1_r()
return m_c_io | (m_hp_1 << 1) | (m_hp_2 << 2) | (m_bell << 3) | (m_aux3 << 4) | 0xe0;
}
void videopkr_state::baby_sound_p3_w(uint8_t data)
void babypkr_state::baby_sound_p3_w(uint8_t data)
{
uint8_t lmp_ports, ay_intf;
lmp_ports = data >> 1 & 0x07;
output().set_value("TOP_1", (lmp_ports >> 0) & 1);
output().set_value("TOP_2", (lmp_ports >> 1) & 1);
output().set_value("TOP_3", (lmp_ports >> 2) & 1);
m_top_lamps[0] = BIT(data, 1);
m_top_lamps[1] = BIT(data, 2);
m_top_lamps[2] = BIT(data, 3);
if (!(data & 0x10))
{
@ -910,8 +928,7 @@ void videopkr_state::baby_sound_p3_w(uint8_t data)
logerror("AY3-8910: Reset\n");
}
ay_intf = (data >> 5) & 0x07;
uint8_t ay_intf = (data >> 5) & 0x07;
switch (ay_intf)
{
case 0x00: break;
@ -953,12 +970,12 @@ void videopkr_state::i8039_io_port(address_map &map)
map(0x00, 0xff).rw(FUNC(videopkr_state::videopkr_io_r), FUNC(videopkr_state::videopkr_io_w));
}
void videopkr_state::i8751_map(address_map &map)
void babypkr_state::i8751_map(address_map &map)
{
map(0x0000, 0x7fff).rom();
}
void videopkr_state::i8751_io_port(address_map &map)
void babypkr_state::i8751_io_port(address_map &map)
{
map(0x0000, 0x0fff).ram(); // NVRAM?
map(0x8000, 0x8000).noprw(); // ???
@ -979,12 +996,12 @@ void videopkr_state::i8039_sound_port(address_map &map)
}
void videopkr_state::i8051_sound_mem(address_map &map)
void babypkr_state::i8051_sound_mem(address_map &map)
{
map(0x0000, 0x0fff).rom();
}
void videopkr_state::i8051_sound_port(address_map &map)
void babypkr_state::i8051_sound_port(address_map &map)
{
map(0x0000, 0x1ff).ram();
}
@ -1212,6 +1229,7 @@ void videopkr_state::machine_start()
{
m_digits.resolve();
m_lamps.resolve();
m_vp_sound_p2 = 0xff; /* default P2 latch value */
m_sound_latch = 0xff; /* default sound data latch value */
m_p24_data = 0xff;
@ -1227,6 +1245,13 @@ void videopkr_state::machine_start()
subdevice<nvram_device>("nvram")->set_base(m_data_ram, sizeof(m_data_ram));
}
void babypkr_state::machine_start()
{
videopkr_state::machine_start();
m_top_lamps.resolve();
}
/************************
* Machine Drivers *
************************/
@ -1303,8 +1328,19 @@ void videopkr_state::videodad(machine_config &config)
MCFG_VIDEO_START_OVERRIDE(videopkr_state,vidadcba)
}
void videopkr_state::fortune1(machine_config &config)
{
videopkr(config);
void videopkr_state::babypkr(machine_config &config)
/* basic machine hardware */
m_maincpu->set_clock(CPU_CLOCK_ALT);
/* video hardware */
subdevice<palette_device>("palette")->set_init(FUNC(videopkr_state::fortune1_palette));
}
void babypkr_state::babypkr(machine_config &config)
{
videopkr(config);
@ -1313,43 +1349,34 @@ void videopkr_state::babypkr(machine_config &config)
/* most likely romless or eprom */
i8031_device &soundcpu(I8031(config.replace(), m_soundcpu, CPU_CLOCK));
soundcpu.set_addrmap(AS_PROGRAM, &videopkr_state::i8051_sound_mem);
soundcpu.set_addrmap(AS_IO, &videopkr_state::i8051_sound_port);
soundcpu.port_in_cb<0>().set(FUNC(videopkr_state::baby_sound_p0_r));
soundcpu.port_out_cb<0>().set(FUNC(videopkr_state::baby_sound_p0_w));
soundcpu.port_in_cb<1>().set(FUNC(videopkr_state::baby_sound_p1_r));
soundcpu.set_addrmap(AS_PROGRAM, &babypkr_state::i8051_sound_mem);
soundcpu.set_addrmap(AS_IO, &babypkr_state::i8051_sound_port);
soundcpu.port_in_cb<0>().set(FUNC(babypkr_state::baby_sound_p0_r));
soundcpu.port_out_cb<0>().set(FUNC(babypkr_state::baby_sound_p0_w));
soundcpu.port_in_cb<1>().set(FUNC(babypkr_state::baby_sound_p1_r));
soundcpu.port_out_cb<2>().set("dac", FUNC(dac_byte_interface::data_w));
soundcpu.port_out_cb<3>().set(FUNC(videopkr_state::baby_sound_p3_w));
soundcpu.port_out_cb<3>().set(FUNC(babypkr_state::baby_sound_p3_w));
/* video hardware */
screen_device &screen(*subdevice<screen_device>("screen"));
screen.set_size(32*16, 32*8);
screen.set_visarea(5*16, 31*16-1, 3*8, 29*8-1);
subdevice<palette_device>("palette")->set_init(FUNC(videopkr_state::babypkr_palette));
subdevice<palette_device>("palette")->set_init(FUNC(babypkr_state::babypkr_palette));
m_gfxdecode->set_info(gfx_videodad);
MCFG_VIDEO_START_OVERRIDE(videopkr_state,vidadcba)
MCFG_VIDEO_START_OVERRIDE(babypkr_state,vidadcba)
AY8910(config, m_aysnd, CPU_CLOCK / 6).add_route(ALL_OUTPUTS, "speaker", 0.3); /* no ports used */
AY8910(config, m_aysnd, CPU_CLOCK / 6); // no ports used
m_aysnd->add_route(ALL_OUTPUTS, "speaker", 0.3);
}
void videopkr_state::fortune1(machine_config &config)
{
videopkr(config);
/* basic machine hardware */
m_maincpu->set_clock(CPU_CLOCK_ALT);
subdevice<palette_device>("palette")->set_init(FUNC(videopkr_state::fortune1_palette));
}
void videopkr_state::bpoker(machine_config &config)
void babypkr_state::bpoker(machine_config &config)
{
babypkr(config);
i8751_device &maincpu(I8751(config.replace(), m_maincpu, XTAL(6'000'000)));
maincpu.set_addrmap(AS_PROGRAM, &videopkr_state::i8751_map);
maincpu.set_addrmap(AS_IO, &videopkr_state::i8751_io_port);
maincpu.set_addrmap(AS_PROGRAM, &babypkr_state::i8751_map);
maincpu.set_addrmap(AS_IO, &babypkr_state::i8751_io_port);
maincpu.port_in_cb<0>().set_constant(0); // ???
maincpu.port_in_cb<1>().set_constant(0); // ???
maincpu.port_out_cb<1>().set_nop(); // ???
@ -1590,6 +1617,6 @@ GAMEL( 1984, fortune1, videopkr, fortune1, videopkr, videopkr_state, empty_init,
GAMEL( 1984, blckjack, videopkr, blckjack, blckjack, videopkr_state, empty_init, ROT0, "InterFlip", "Black Jack", 0, layout_blckjack )
GAMEL( 1987, videodad, videopkr, videodad, videodad, videopkr_state, empty_init, ROT0, "InterFlip", "Video Dado", 0, layout_videodad )
GAMEL( 1987, videocba, videopkr, videodad, videocba, videopkr_state, empty_init, ROT0, "InterFlip", "Video Cordoba", 0, layout_videocba )
GAMEL( 1987, babypkr, videopkr, babypkr, babypkr, videopkr_state, empty_init, ROT0, "Recreativos Franco", "Baby Poker", 0, layout_babypkr )
GAMEL( 1987, babydad, videopkr, babypkr, babydad, videopkr_state, empty_init, ROT0, "Recreativos Franco", "Baby Dado", 0, layout_babydad )
GAMEL( 198?, bpoker, videopkr, bpoker, babypkr, videopkr_state, empty_init, ROT0, "Recreativos Franco", "Video Poker (v1403)", MACHINE_NOT_WORKING, layout_babypkr )
GAMEL( 1987, babypkr, videopkr, babypkr, babypkr, babypkr_state, empty_init, ROT0, "Recreativos Franco", "Baby Poker", 0, layout_babypkr )
GAMEL( 1987, babydad, videopkr, babypkr, babydad, babypkr_state, empty_init, ROT0, "Recreativos Franco", "Baby Dado", 0, layout_babydad )
GAMEL( 198?, bpoker, videopkr, bpoker, babypkr, babypkr_state, empty_init, ROT0, "Recreativos Franco", "Video Poker (v1403)", MACHINE_NOT_WORKING, layout_babypkr )

View File

@ -1,156 +0,0 @@
// license:BSD-3-Clause
// copyright-holders:Aaron Giles
/*************************************************************************
Exidy 6502 hardware
*************************************************************************/
#include "sound/dac.h"
#include "sound/samples.h"
#include "emupal.h"
#include "screen.h"
#define EXIDY_MASTER_CLOCK (XTAL(11'289'000))
#define EXIDY_CPU_CLOCK (EXIDY_MASTER_CLOCK / 16)
#define EXIDY_PIXEL_CLOCK (EXIDY_MASTER_CLOCK / 2)
#define EXIDY_HTOTAL (0x150)
#define EXIDY_HBEND (0x000)
#define EXIDY_HBSTART (0x100)
#define EXIDY_HSEND (0x140)
#define EXIDY_HSSTART (0x120)
#define EXIDY_VTOTAL (0x118)
#define EXIDY_VBEND (0x000)
#define EXIDY_VBSTART (0x100)
#define EXIDY_VSEND (0x108)
#define EXIDY_VSSTART (0x100)
class exidy_state : public driver_device
{
public:
enum
{
TIMER_COLLISION_IRQ
};
exidy_state(const machine_config &mconfig, device_type type, const char *tag)
: driver_device(mconfig, type, tag),
m_maincpu(*this, "maincpu"),
m_dac(*this, "dac"),
m_samples(*this, "samples"),
m_gfxdecode(*this, "gfxdecode"),
m_screen(*this, "screen"),
m_palette(*this, "palette"),
m_videoram(*this, "videoram"),
m_sprite1_xpos(*this, "sprite1_xpos"),
m_sprite1_ypos(*this, "sprite1_ypos"),
m_sprite2_xpos(*this, "sprite2_xpos"),
m_sprite2_ypos(*this, "sprite2_ypos"),
m_spriteno(*this, "spriteno"),
m_sprite_enable(*this, "sprite_enable"),
m_color_latch(*this, "color_latch"),
m_characterram(*this, "characterram") { }
void base(machine_config &config);
void mtrap(machine_config &config);
void venture(machine_config &config);
void fax(machine_config &config);
void teetert(machine_config &config);
void sidetrac(machine_config &config);
void spectar(machine_config &config);
void spectar_audio(machine_config &config);
void rallys(machine_config &config);
void pepper2(machine_config &config);
void targ(machine_config &config);
void targ_audio(machine_config &config);
void init_fax();
void init_sidetrac();
void init_pepper2();
void init_targ();
void init_rallys();
void init_mtrap();
void init_teetert();
void init_venture();
void init_spectar();
void init_phantoma();
DECLARE_CUSTOM_INPUT_MEMBER(teetert_input_r);
private:
required_device<cpu_device> m_maincpu;
optional_device<dac_bit_interface> m_dac;
optional_device<samples_device> m_samples;
required_device<gfxdecode_device> m_gfxdecode;
required_device<screen_device> m_screen;
required_device<palette_device> m_palette;
required_shared_ptr<uint8_t> m_videoram;
required_shared_ptr<uint8_t> m_sprite1_xpos;
required_shared_ptr<uint8_t> m_sprite1_ypos;
required_shared_ptr<uint8_t> m_sprite2_xpos;
required_shared_ptr<uint8_t> m_sprite2_ypos;
required_shared_ptr<uint8_t> m_spriteno;
required_shared_ptr<uint8_t> m_sprite_enable;
required_shared_ptr<uint8_t> m_color_latch;
optional_shared_ptr<uint8_t> m_characterram;
uint8_t m_last_dial;
uint8_t m_collision_mask;
uint8_t m_collision_invert;
int m_is_2bpp;
uint8_t m_int_condition;
bitmap_ind16 m_background_bitmap;
bitmap_ind16 m_motion_object_1_vid;
bitmap_ind16 m_motion_object_2_vid;
bitmap_ind16 m_motion_object_2_clip;
void fax_bank_select_w(uint8_t data);
uint8_t exidy_interrupt_r();
void mtrap_ocl_w(uint8_t data);
virtual void video_start() override;
DECLARE_MACHINE_START(teetert);
uint32_t screen_update_exidy(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect);
INTERRUPT_GEN_MEMBER(exidy_vblank_interrupt);
void exidy_video_config(uint8_t _collision_mask, uint8_t _collision_invert, int _is_2bpp);
inline void latch_condition(int collision);
inline void set_1_color(int index, int which);
void set_colors();
void draw_background();
inline int sprite_1_enabled();
void draw_sprites(bitmap_ind16 &bitmap, const rectangle &cliprect);
void check_collision();
/* Targ and Spectar samples */
int m_max_freq;
uint8_t m_port_1_last;
uint8_t m_port_2_last;
uint8_t m_tone_freq;
uint8_t m_tone_active;
uint8_t m_tone_pointer;
void targ_audio_1_w(uint8_t data);
void targ_audio_2_w(uint8_t data);
void spectar_audio_2_w(uint8_t data);
void adjust_sample(uint8_t freq);
void common_audio_start(int freq);
SAMPLES_START_CB_MEMBER(spectar_audio_start);
SAMPLES_START_CB_MEMBER(targ_audio_start);
void exidy_map(address_map &map);
void fax_map(address_map &map);
void mtrap_map(address_map &map);
void pepper2_map(address_map &map);
void rallys_map(address_map &map);
void sidetrac_map(address_map &map);
void spectar_map(address_map &map);
void targ_map(address_map &map);
void venture_map(address_map &map);
protected:
virtual void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr) override;
};

View File

@ -1,374 +0,0 @@
// license:BSD-3-Clause
// copyright-holders:Aaron Giles
/*************************************************************************
Exidy 6502 hardware
*************************************************************************/
#include "emu.h"
#include "includes/exidy.h"
/*************************************
*
* Video configuration
*
*************************************/
void exidy_state::exidy_video_config(uint8_t _collision_mask, uint8_t _collision_invert, int _is_2bpp)
{
m_collision_mask = _collision_mask;
m_collision_invert = _collision_invert;
m_is_2bpp = _is_2bpp;
}
/*************************************
*
* Video startup
*
*************************************/
void exidy_state::video_start()
{
m_screen->register_screen_bitmap(m_background_bitmap);
m_motion_object_1_vid.allocate(16, 16);
m_motion_object_2_vid.allocate(16, 16);
m_motion_object_2_clip.allocate(16, 16);
save_item(NAME(m_collision_mask));
save_item(NAME(m_collision_invert));
save_item(NAME(m_is_2bpp));
save_item(NAME(m_int_condition));
save_item(NAME(m_background_bitmap));
save_item(NAME(m_motion_object_1_vid));
save_item(NAME(m_motion_object_2_vid));
save_item(NAME(m_motion_object_2_clip));
}
/*************************************
*
* Interrupt generation
*
*************************************/
inline void exidy_state::latch_condition(int collision)
{
collision ^= m_collision_invert;
m_int_condition = (ioport("INTSOURCE")->read() & ~0x1c) | (collision & m_collision_mask);
}
INTERRUPT_GEN_MEMBER(exidy_state::exidy_vblank_interrupt)
{
/* latch the current condition */
latch_condition(0);
m_int_condition &= ~0x80;
/* set the IRQ line */
device.execute().set_input_line(0, ASSERT_LINE);
}
uint8_t exidy_state::exidy_interrupt_r()
{
/* clear any interrupts */
m_maincpu->set_input_line(0, CLEAR_LINE);
/* return the latched condition */
return m_int_condition;
}
/*************************************
*
* Palette handling
*
*************************************/
inline void exidy_state::set_1_color(int index, int which)
{
m_palette->set_pen_color(index,
pal1bit(m_color_latch[2] >> which),
pal1bit(m_color_latch[1] >> which),
pal1bit(m_color_latch[0] >> which));
}
void exidy_state::set_colors()
{
/* motion object 1 */
set_1_color(0, 0);
set_1_color(1, 7);
/* motion object 2 */
set_1_color(2, 0);
set_1_color(3, 6);
/* characters */
set_1_color(4, 4);
set_1_color(5, 3);
set_1_color(6, 2);
set_1_color(7, 1);
}
/*************************************
*
* Background update
*
*************************************/
void exidy_state::draw_background()
{
const u8 *cram = m_characterram ? (u8 *)m_characterram : memregion("maincpu")->base() + 0x4800;
offs_t offs;
pen_t off_pen = 0;
for (offs = 0; offs < 0x400; offs++)
{
uint8_t y = offs >> 5 << 3;
uint8_t const code = m_videoram[offs];
pen_t on_pen_1, on_pen_2;
if (m_is_2bpp)
{
on_pen_1 = 4 + ((code >> 6) & 0x02);
on_pen_2 = 5 + ((code >> 6) & 0x02);
}
else
{
on_pen_1 = 4 + ((code >> 6) & 0x03);
on_pen_2 = off_pen; /* unused */
}
for (uint8_t cy = 0; cy < 8; cy++)
{
uint8_t x = offs << 3;
if (m_is_2bpp)
{
uint8_t data1 = cram[0x000 | (code << 3) | cy];
uint8_t data2 = cram[0x800 | (code << 3) | cy];
for (int i = 0; i < 8; i++)
{
if (data1 & 0x80)
m_background_bitmap.pix(y, x) = (data2 & 0x80) ? on_pen_2 : on_pen_1;
else
m_background_bitmap.pix(y, x) = off_pen;
x++;
data1 <<= 1;
data2 <<= 1;
}
}
/* 1bpp */
else
{
uint8_t data = cram[(code << 3) | cy];
for (int i = 0; i < 8; i++)
{
m_background_bitmap.pix(y, x) = (data & 0x80) ? on_pen_1 : off_pen;
x++;
data <<= 1;
}
}
y++;
}
}
}
/*************************************
*
* Sprite hardware
*
*************************************/
inline int exidy_state::sprite_1_enabled()
{
/* if the collision_mask is 0x00, then we are on old hardware that always has */
/* sprite 1 enabled regardless */
return (!(*m_sprite_enable & 0x80) || (*m_sprite_enable & 0x10) || (m_collision_mask == 0x00));
}
void exidy_state::draw_sprites(bitmap_ind16 &bitmap, const rectangle &cliprect)
{
/* draw sprite 2 first */
int sprite_set_2 = ((*m_sprite_enable & 0x40) != 0);
int sx = 236 - *m_sprite2_xpos - 4;
int sy = 244 - *m_sprite2_ypos - 4;
m_gfxdecode->gfx(0)->transpen(bitmap,cliprect,
((*m_spriteno >> 4) & 0x0f) + 32 + 16 * sprite_set_2, 1,
0, 0, sx, sy, 0);
/* draw sprite 1 next */
if (sprite_1_enabled())
{
int sprite_set_1 = ((*m_sprite_enable & 0x20) != 0);
sx = 236 - *m_sprite1_xpos - 4;
sy = 244 - *m_sprite1_ypos - 4;
if (sy < 0) sy = 0;
m_gfxdecode->gfx(0)->transpen(bitmap,cliprect,
(*m_spriteno & 0x0f) + 16 * sprite_set_1, 0,
0, 0, sx, sy, 0);
}
}
/*************************************
*
* Collision detection
*
*************************************/
/***************************************************************************
Exidy hardware checks for two types of collisions based on the video
signals. If the Motion Object 1 and Motion Object 2 signals are on at
the same time, an M1M2 collision bit gets set. If the Motion Object 1
and Background Character signals are on at the same time, an M1CHAR
collision bit gets set. So effectively, there's a pixel-by-pixel
collision check comparing Motion Object 1 (the player) to the
background and to the other Motion Object (typically a bad guy).
***************************************************************************/
void exidy_state::device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr)
{
switch (id)
{
case TIMER_COLLISION_IRQ:
/* latch the collision bits */
latch_condition(param);
/* set the IRQ line */
m_maincpu->set_input_line(0, ASSERT_LINE);
break;
default:
throw emu_fatalerror("Unknown id in exidy_state::device_timer");
}
}
void exidy_state::check_collision()
{
uint8_t sprite_set_1 = ((*m_sprite_enable & 0x20) != 0);
uint8_t sprite_set_2 = ((*m_sprite_enable & 0x40) != 0);
const rectangle clip(0, 15, 0, 15);
int org_1_x = 0, org_1_y = 0;
int org_2_x = 0, org_2_y = 0;
int count = 0;
/* if there is nothing to detect, bail */
if (m_collision_mask == 0)
return;
/* draw sprite 1 */
m_motion_object_1_vid.fill(0xff, clip);
if (sprite_1_enabled())
{
org_1_x = 236 - *m_sprite1_xpos - 4;
org_1_y = 244 - *m_sprite1_ypos - 4;
m_gfxdecode->gfx(0)->transpen(m_motion_object_1_vid,clip,
(*m_spriteno & 0x0f) + 16 * sprite_set_1, 0,
0, 0, 0, 0, 0);
}
/* draw sprite 2 */
m_motion_object_2_vid.fill(0xff, clip);
org_2_x = 236 - *m_sprite2_xpos - 4;
org_2_y = 244 - *m_sprite2_ypos - 4;
m_gfxdecode->gfx(0)->transpen(m_motion_object_2_vid,clip,
((*m_spriteno >> 4) & 0x0f) + 32 + 16 * sprite_set_2, 0,
0, 0, 0, 0, 0);
/* draw sprite 2 clipped to sprite 1's location */
m_motion_object_2_clip.fill(0xff, clip);
if (sprite_1_enabled())
{
int sx = org_2_x - org_1_x;
int sy = org_2_y - org_1_y;
m_gfxdecode->gfx(0)->transpen(m_motion_object_2_clip,clip,
((*m_spriteno >> 4) & 0x0f) + 32 + 16 * sprite_set_2, 0,
0, 0, sx, sy, 0);
}
/* scan for collisions */
for (int sy = 0; sy < 16; sy++)
for (int sx = 0; sx < 16; sx++)
{
if (m_motion_object_1_vid.pix(sy, sx) != 0xff)
{
uint8_t current_collision_mask = 0;
/* check for background collision (M1CHAR) */
if (m_background_bitmap.pix(org_1_y + sy, org_1_x + sx) != 0)
current_collision_mask |= 0x04;
/* check for motion object collision (M1M2) */
if (m_motion_object_2_clip.pix(sy, sx) != 0xff)
current_collision_mask |= 0x10;
/* if we got one, trigger an interrupt */
if ((current_collision_mask & m_collision_mask) && (count++ < 128))
timer_set(m_screen->time_until_pos(org_1_x + sx, org_1_y + sy), TIMER_COLLISION_IRQ, current_collision_mask);
}
if (m_motion_object_2_vid.pix(sy, sx) != 0xff)
{
/* check for background collision (M2CHAR) */
if (m_background_bitmap.pix(org_2_y + sy, org_2_x + sx) != 0)
if ((m_collision_mask & 0x08) && (count++ < 128))
timer_set(m_screen->time_until_pos(org_2_x + sx, org_2_y + sy), TIMER_COLLISION_IRQ, 0x08);
}
}
}
/*************************************
*
* Standard screen refresh callback
*
*************************************/
uint32_t exidy_state::screen_update_exidy(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
{
/* refresh the colors from the palette (static or dynamic) */
set_colors();
/* update the background and draw it */
draw_background();
copybitmap(bitmap, m_background_bitmap, 0, 0, 0, 0, cliprect);
/* draw the sprites */
draw_sprites(bitmap, cliprect);
/* check for collision, this will set the appropriate bits in collision_mask */
check_collision();
return 0;
}