8080bw.cpp, mw8080bw.cpp: Some cleanup/untangling: (#9884)

Updated Space Invaders C.V. and Space Invaders Part II input definitions
based on schematics and manuals.

Got Space Invaders specific stuff out of the Midway 8080 B/W base class.

Got some of the game-specific stuff out of the _8080bw_state class.
It's still a bit of a mess because sound hardware is implemented in the
driver classes so some games pull in a more derived class than they
really should just for sound handlers.

Got rid of the duplicate joystick inputs in rollingc.

Fixed cocktail mode input and DIP switches in a few games.
This commit is contained in:
Vas Crabb 2022-06-05 23:37:21 +10:00 committed by GitHub
parent c1ef4e0e24
commit 62c35fe3ce
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 1150 additions and 849 deletions

View File

@ -2777,7 +2777,6 @@ files {
MAME_DIR .. "src/mame/audio/m79amb.cpp",
MAME_DIR .. "src/mame/drivers/mw8080bw.cpp",
MAME_DIR .. "src/mame/includes/mw8080bw.h",
MAME_DIR .. "src/mame/machine/mw8080bw.cpp",
MAME_DIR .. "src/mame/audio/mw8080bw.cpp",
MAME_DIR .. "src/mame/audio/mw8080bw.h",
MAME_DIR .. "src/mame/audio/nl_gunfight.cpp",

View File

@ -26,7 +26,6 @@ MACHINE_START_MEMBER(_8080bw_state,extra_8080bw_sh)
{
save_item(NAME(m_port_1_last_extra));
save_item(NAME(m_port_2_last_extra));
save_item(NAME(m_port_3_last_extra));
}
/*************************************
@ -71,7 +70,7 @@ static const char *const invaders_sample_names[] =
/* left in for all games that hack into invaders samples for audio */
void _8080bw_state::invaders_samples_audio(machine_config &config)
void invaders_clone_state::invaders_samples_audio(machine_config &config)
{
SPEAKER(config, "mono").front_center();
@ -1073,12 +1072,12 @@ MACHINE_RESET_MEMBER(_8080bw_state,schaser_sh)
/* */
/*******************************************************/
void _8080bw_state::invrvnge_port03_w(uint8_t data)
void invrvnge_state::port03_w(uint8_t data)
{
m_sound_data = data;
}
void _8080bw_state::invrvnge_port05_w(uint8_t data)
void invrvnge_state::port05_w(uint8_t data)
{
/*
00 - normal play
@ -1090,11 +1089,11 @@ void _8080bw_state::invrvnge_port05_w(uint8_t data)
m_screen_red = BIT(data, 4);
m_flip_screen = BIT(data, 5) & ioport(CABINET_PORT_TAG)->read();
// no sound-related writes?
// no sound-related writes?
}
// The timer frequency controls the speed of the sounds
TIMER_DEVICE_CALLBACK_MEMBER(_8080bw_state::nmi_timer)
TIMER_DEVICE_CALLBACK_MEMBER(invrvnge_state::nmi_timer)
{
m_timer_state ^= 1;
m_audiocpu->set_input_line(INPUT_LINE_NMI, m_timer_state ? ASSERT_LINE : CLEAR_LINE );
@ -1107,15 +1106,15 @@ TIMER_DEVICE_CALLBACK_MEMBER(_8080bw_state::nmi_timer)
/* - Press Left or Right to choose game to play */
/****************************************************/
void _8080bw_state::rollingc_sh_port_w(uint8_t data)
void rollingc_state::rollingc_sh_port_w(uint8_t data)
{
uint8_t rising_bits = data & ~m_port_3_last_extra;
uint8_t rising_bits = data & ~m_port_3_last;
if (BIT(rising_bits, 1)) m_samples->start(4, 0); // Steering
if (BIT(rising_bits, 2)) m_samples->start(0, 1); // Collision
if (BIT(rising_bits, 4)) m_samples->start(1, 8); // Computer car is starting to move
m_port_3_last_extra = data;
m_port_3_last = data;
}
@ -1259,9 +1258,9 @@ void _8080bw_state::crashrd_port05_w(uint8_t data)
/* No information available as what the correct sounds are */
/*******************************************************************/
void _8080bw_state::yosakdon_sh_port_1_w(uint8_t data)
void yosakdon_state::sh_port_1_w(uint8_t data)
{
uint8_t rising_bits = data & ~m_port_1_last_extra;
uint8_t rising_bits = data & ~m_port_1_last;
if (BIT(rising_bits, 0)) m_samples->start(0, 3); // Game Over
if (BIT(rising_bits, 1)) m_samples->start(2, 0); // Bird dead
@ -1271,12 +1270,12 @@ void _8080bw_state::yosakdon_sh_port_1_w(uint8_t data)
machine().sound().system_mute(!BIT(data, 5));
m_port_1_last_extra = data;
m_port_1_last = data;
}
void _8080bw_state::yosakdon_sh_port_2_w(uint8_t data)
void yosakdon_state::sh_port_2_w(uint8_t data)
{
uint8_t rising_bits = data & ~m_port_2_last_extra;
uint8_t rising_bits = data & ~m_port_2_last;
if (BIT(rising_bits, 0)) m_samples->start(1, 6); // Ready? , Game Over
if (BIT(rising_bits, 2)) m_samples->start(3, 7); // Big bird dead
@ -1287,7 +1286,7 @@ void _8080bw_state::yosakdon_sh_port_2_w(uint8_t data)
m_flip_screen = BIT(data, 5) & ioport(CABINET_PORT_TAG)->read();
m_port_2_last_extra = data;
m_port_2_last = data;
}
@ -1297,20 +1296,20 @@ void _8080bw_state::yosakdon_sh_port_2_w(uint8_t data)
/* Proper samples are unavailable */
/*****************************************/
void _8080bw_state::shuttlei_sh_port_1_w(uint8_t data)
void shuttlei_state::sh_port_1_w(uint8_t data)
{
/* bit 3 is high while you are alive and playing */
uint8_t rising_bits = data & ~m_port_1_last_extra;
uint8_t rising_bits = data & ~m_port_1_last;
if (rising_bits & 0x01) m_samples->start(4, 4); /* Fleet move */
if (rising_bits & 0x02) m_samples->start(5, 8); /* Extra Tank */
m_sn->enable_w(data & 0x04 ? 0:1); /* UFO */
m_port_1_last_extra = data;
m_port_1_last = data;
}
void _8080bw_state::shuttlei_sh_port_2_w(uint8_t data)
void shuttlei_state::sh_port_2_w(uint8_t data)
{
switch (data)
{
@ -1338,14 +1337,14 @@ void _8080bw_state::shuttlei_sh_port_2_w(uint8_t data)
/* Proper samples are unavailable */
/*****************************************/
void _8080bw_state::darthvdr_00_w(uint8_t data)
void darthvdr_state::darthvdr_00_w(uint8_t data)
{
m_flip_screen = BIT(data, 0) & ioport(CABINET_PORT_TAG)->read();
}
void _8080bw_state::darthvdr_08_w(uint8_t data)
void darthvdr_state::darthvdr_08_w(uint8_t data)
{
uint8_t rising_bits = data & ~m_port_1_last_extra;
uint8_t rising_bits = data & ~m_port_1_last;
machine().sound().system_mute(!BIT(data, 0));
@ -1365,7 +1364,7 @@ void _8080bw_state::darthvdr_08_w(uint8_t data)
if (m_fleet_step > 6) m_fleet_step = 3;
}
m_port_1_last_extra = data;
m_port_1_last = data;
}

File diff suppressed because it is too large Load Diff

View File

@ -178,6 +178,117 @@ INPUT_CHANGED_MEMBER(mw8080bw_state::direct_coin_count)
}
/*************************************
*
* Interrupt generation
*
*************************************/
uint8_t mw8080bw_state::vpos_to_vysnc_chain_counter( int vpos )
{
/* convert from a vertical position to the actual values on the vertical sync counters */
uint8_t counter;
int vblank = (vpos >= MW8080BW_VBSTART);
if (vblank)
counter = vpos - MW8080BW_VBSTART + MW8080BW_VCOUNTER_START_VBLANK;
else
counter = vpos + MW8080BW_VCOUNTER_START_NO_VBLANK;
return counter;
}
int mw8080bw_state::vysnc_chain_counter_to_vpos( uint8_t counter, int vblank )
{
/* convert from the vertical sync counters to an actual vertical position */
int vpos;
if (vblank)
vpos = counter - MW8080BW_VCOUNTER_START_VBLANK + MW8080BW_VBSTART;
else
vpos = counter - MW8080BW_VCOUNTER_START_NO_VBLANK;
return vpos;
}
TIMER_CALLBACK_MEMBER(mw8080bw_state::interrupt_trigger)
{
int const vpos = m_screen->vpos();
uint8_t const counter = vpos_to_vysnc_chain_counter(vpos);
if (m_int_enable)
{
m_maincpu->set_input_line(0, ASSERT_LINE);
m_interrupt_time = machine().time();
}
else
m_maincpu->set_input_line(0, CLEAR_LINE);
// set up for next interrupt
uint8_t next_counter;
int next_vblank;
if (counter == MW8080BW_INT_TRIGGER_COUNT_1)
{
next_counter = MW8080BW_INT_TRIGGER_COUNT_2;
next_vblank = MW8080BW_INT_TRIGGER_VBLANK_2;
}
else
{
next_counter = MW8080BW_INT_TRIGGER_COUNT_1;
next_vblank = MW8080BW_INT_TRIGGER_VBLANK_1;
}
int const next_vpos = vysnc_chain_counter_to_vpos(next_counter, next_vblank);
m_interrupt_timer->adjust(m_screen->time_until_pos(next_vpos));
}
WRITE_LINE_MEMBER(mw8080bw_state::int_enable_w)
{
m_int_enable = state;
}
IRQ_CALLBACK_MEMBER(mw8080bw_state::interrupt_vector)
{
int vpos = m_screen->vpos();
// MAME scheduling quirks cause this to happen more often than you might think, in fact far too often
if (machine().time() < m_interrupt_time)
vpos++;
uint8_t counter = vpos_to_vysnc_chain_counter(vpos);
uint8_t vector = 0xc7 | ((counter & 0x40) >> 2) | ((~counter & 0x40) >> 3);
m_maincpu->set_input_line(0, CLEAR_LINE);
return vector;
}
/*************************************
*
* Machine setup
*
*************************************/
void mw8080bw_state::machine_start()
{
m_interrupt_timer = timer_alloc(FUNC(mw8080bw_state::interrupt_trigger), this);
}
void mw8080bw_state::machine_reset()
{
int vpos = vysnc_chain_counter_to_vpos(MW8080BW_INT_TRIGGER_COUNT_1, MW8080BW_INT_TRIGGER_VBLANK_1);
m_interrupt_timer->adjust(m_screen->time_until_pos(vpos));
m_interrupt_time = attotime::zero;
}
/*************************************
*
* Special shifter circuit
@ -223,8 +334,6 @@ void mw8080bw_state::mw8080bw_root(machine_config &config)
maincpu.set_irq_acknowledge_callback(FUNC(mw8080bw_state::interrupt_vector));
maincpu.out_inte_func().set(FUNC(mw8080bw_state::int_enable_w));
MCFG_MACHINE_RESET_OVERRIDE(mw8080bw_state,mw8080bw)
/* video hardware */
SCREEN(config, m_screen, SCREEN_TYPE_RASTER);
m_screen->set_raw(MW8080BW_PIXEL_CLOCK, MW8080BW_HTOTAL, MW8080BW_HBEND, MW8080BW_HPIXCOUNT, MW8080BW_VTOTAL, MW8080BW_VBEND, MW8080BW_VBSTART);
@ -2432,7 +2541,7 @@ void mw8080bw_state::bowler(machine_config &config)
*
*************************************/
MACHINE_START_MEMBER(mw8080bw_state,invaders)
void invaders_state::machine_start()
{
mw8080bw_state::machine_start();
@ -2443,67 +2552,64 @@ MACHINE_START_MEMBER(mw8080bw_state,invaders)
CUSTOM_INPUT_MEMBER(mw8080bw_state::invaders_sw6_sw7_r)
CUSTOM_INPUT_MEMBER(invaders_state::invaders_sw6_sw7_r)
{
// upright PCB : switches visible
// cocktail PCB: HI
if (invaders_is_cabinet_cocktail())
if (is_cabinet_cocktail())
return 0x03;
else
return ioport(INVADERS_SW6_SW7_PORT_TAG)->read();
}
CUSTOM_INPUT_MEMBER(mw8080bw_state::invaders_sw5_r)
CUSTOM_INPUT_MEMBER(invaders_state::invaders_sw5_r)
{
// upright PCB : switch visible
// cocktail PCB: HI
if (invaders_is_cabinet_cocktail())
if (is_cabinet_cocktail())
return 0x01;
else
return ioport(INVADERS_SW5_PORT_TAG)->read();
}
CUSTOM_INPUT_MEMBER(mw8080bw_state::invaders_in0_control_r)
CUSTOM_INPUT_MEMBER(invaders_state::invaders_in0_control_r)
{
// upright PCB : P1 controls
// cocktail PCB: HI
if (invaders_is_cabinet_cocktail())
if (is_cabinet_cocktail())
return 0x07;
else
return ioport(INVADERS_P1_CONTROL_PORT_TAG)->read();
return m_player_controls[0]->read();
}
CUSTOM_INPUT_MEMBER(mw8080bw_state::invaders_in1_control_r)
CUSTOM_INPUT_MEMBER(invaders_state::invaders_in1_control_r)
{
return ioport(INVADERS_P1_CONTROL_PORT_TAG)->read();
return m_player_controls[0]->read();
}
CUSTOM_INPUT_MEMBER(mw8080bw_state::invaders_in2_control_r)
CUSTOM_INPUT_MEMBER(invaders_state::invaders_in2_control_r)
{
// upright PCB : P1 controls
// cocktail PCB: P2 controls
if (invaders_is_cabinet_cocktail())
return ioport(INVADERS_P2_CONTROL_PORT_TAG)->read();
else
return ioport(INVADERS_P1_CONTROL_PORT_TAG)->read();
return m_player_controls[is_cabinet_cocktail() ? 1 : 0]->read();
}
int mw8080bw_state::invaders_is_cabinet_cocktail()
bool invaders_state::is_cabinet_cocktail()
{
return ioport(INVADERS_CAB_TYPE_PORT_TAG)->read();
return BIT(m_cabinet_type->read(), 0);
}
void mw8080bw_state::invaders_io_map(address_map &map)
void invaders_state::io_map(address_map &map)
{
map.global_mask(0x7);
map(0x00, 0x00).mirror(0x04).portr("IN0");
@ -2524,17 +2630,17 @@ static INPUT_PORTS_START( invaders )
PORT_DIPNAME( 0x01, 0x00, DEF_STR( Unknown ) ) PORT_DIPLOCATION("SW:8")
PORT_DIPSETTING( 0x00, DEF_STR( Off ) )
PORT_DIPSETTING( 0x01, DEF_STR( On ) )
PORT_BIT( 0x06, IP_ACTIVE_HIGH, IPT_CUSTOM ) PORT_CUSTOM_MEMBER(mw8080bw_state, invaders_sw6_sw7_r)
PORT_BIT( 0x06, IP_ACTIVE_HIGH, IPT_CUSTOM ) PORT_CUSTOM_MEMBER(invaders_state, invaders_sw6_sw7_r)
PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_UNUSED )
PORT_BIT( 0x70, IP_ACTIVE_HIGH, IPT_CUSTOM ) PORT_CUSTOM_MEMBER(mw8080bw_state, invaders_in0_control_r)
PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_CUSTOM ) PORT_CUSTOM_MEMBER(mw8080bw_state, invaders_sw5_r)
PORT_BIT( 0x70, IP_ACTIVE_HIGH, IPT_CUSTOM ) PORT_CUSTOM_MEMBER(invaders_state, invaders_in0_control_r)
PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_CUSTOM ) PORT_CUSTOM_MEMBER(invaders_state, invaders_sw5_r)
PORT_START("IN1")
PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_COIN1 ) PORT_CHANGED_MEMBER(DEVICE_SELF, mw8080bw_state, direct_coin_count, 0)
PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_COIN1 ) PORT_CHANGED_MEMBER(DEVICE_SELF, invaders_state, direct_coin_count, 0)
PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_START2 )
PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_START1 )
PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_UNUSED )
PORT_BIT( 0x70, IP_ACTIVE_HIGH, IPT_CUSTOM ) PORT_CUSTOM_MEMBER(mw8080bw_state, invaders_in1_control_r)
PORT_BIT( 0x70, IP_ACTIVE_HIGH, IPT_CUSTOM ) PORT_CUSTOM_MEMBER(invaders_state, invaders_in1_control_r)
PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_UNUSED )
PORT_START("IN2")
@ -2543,11 +2649,11 @@ static INPUT_PORTS_START( invaders )
PORT_DIPSETTING( 0x01, "4" )
PORT_DIPSETTING( 0x02, "5" )
PORT_DIPSETTING( 0x03, "6" )
PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_UNUSED ) /* in the software, this is TILI, but not connected on the Midway PCB. Is this correct? */
PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_UNUSED ) // in the software, this is TILI, but not connected on the Midway PCB. Is this correct?
PORT_DIPNAME( 0x08, 0x00, DEF_STR( Bonus_Life ) ) PORT_DIPLOCATION("SW:2")
PORT_DIPSETTING( 0x08, "1000" )
PORT_DIPSETTING( 0x00, "1500" )
PORT_BIT( 0x70, IP_ACTIVE_HIGH, IPT_CUSTOM ) PORT_CUSTOM_MEMBER(mw8080bw_state, invaders_in2_control_r)
PORT_BIT( 0x70, IP_ACTIVE_HIGH, IPT_CUSTOM ) PORT_CUSTOM_MEMBER(invaders_state, invaders_in2_control_r)
PORT_DIPNAME( 0x80, 0x00, "Display Coinage" ) PORT_DIPLOCATION("SW:1")
PORT_DIPSETTING( 0x80, DEF_STR( Off ) )
PORT_DIPSETTING( 0x00, DEF_STR( On ) )
@ -2577,26 +2683,29 @@ static INPUT_PORTS_START( invaders )
INPUT_PORTS_END
void mw8080bw_state::invaders(machine_config &config)
void invaders_state::invaders(machine_config &config)
{
mw8080bw_root(config);
// basic machine hardware
m_maincpu->set_addrmap(AS_IO, &mw8080bw_state::invaders_io_map);
MCFG_MACHINE_START_OVERRIDE(mw8080bw_state,invaders)
m_maincpu->set_addrmap(AS_IO, &invaders_state::io_map);
WATCHDOG_TIMER(config, m_watchdog).set_time(255 * attotime::from_hz(MW8080BW_60HZ));
// video hardware
m_screen->set_screen_update(FUNC(mw8080bw_state::screen_update_invaders));
m_screen->set_screen_update(FUNC(invaders_state::screen_update_invaders));
// add shifter
MB14241(config, m_mb14241);
// audio hardware
INVADERS_AUDIO(config, "soundboard"). // the flip screen line is only connected on the cocktail PCB
flip_screen_out().set([this] (int state) { if (invaders_is_cabinet_cocktail()) m_flip_screen = state ? 1 : 0; });
INVADERS_AUDIO(config, "soundboard")
.flip_screen_out().set(
[this] (int state)
{
if (is_cabinet_cocktail()) // the flip screen line is only connected on the cocktail PCB
m_flip_screen = state ? 1 : 0;
});
}
@ -3121,7 +3230,7 @@ ROM_END
/* 645 */ GAMEL( 1980, spcenctr, 0, spcenctr, spcenctr, spcenctr_state, empty_init, ROT0, "Midway", "Space Encounters", MACHINE_IMPERFECT_SOUND | MACHINE_SUPPORTS_SAVE, layout_spcenctr )
/* 652 */ GAMEL( 1979, phantom2, 0, phantom2, phantom2, mw8080bw_state, empty_init, ROT0, "Midway", "Phantom II", MACHINE_IMPERFECT_SOUND | MACHINE_SUPPORTS_SAVE, layout_phantom2 )
/* 730 */ GAME( 1978, bowler, 0, bowler, bowler, mw8080bw_state, empty_init, ROT90, "Midway", "Bowling Alley", MACHINE_IMPERFECT_SOUND | MACHINE_SUPPORTS_SAVE )
/* 739 */ GAMEL( 1978, invaders, 0, invaders, invaders, mw8080bw_state, empty_init, ROT270, "Taito / Midway", "Space Invaders / Space Invaders M", MACHINE_SUPPORTS_SAVE, layout_invaders )
/* 739 */ GAMEL( 1978, invaders, 0, invaders, invaders, invaders_state, empty_init, ROT270, "Taito / Midway", "Space Invaders / Space Invaders M", MACHINE_SUPPORTS_SAVE, layout_invaders )
/* 742 */ GAME( 1978, blueshrk, 0, blueshrk, blueshrk, mw8080bw_state, empty_init, ROT0, "Midway", "Blue Shark", MACHINE_IMPERFECT_SOUND | MACHINE_SUPPORTS_SAVE )
GAME( 1978, blueshrkmr, blueshrk, blueshrk, blueshrk, mw8080bw_state, empty_init, ROT0, "bootleg (Model Racing)", "Blue Shark (Model Racing bootleg, set 1)", MACHINE_IMPERFECT_SOUND | MACHINE_SUPPORTS_SAVE )
GAME( 1978, blueshrkmr2,blueshrk, blueshrk, blueshrk, mw8080bw_state, empty_init, ROT0, "bootleg (Model Racing)", "Blue Shark (Model Racing bootleg, set 2)", MACHINE_IMPERFECT_SOUND | MACHINE_SUPPORTS_SAVE )

View File

@ -28,41 +28,75 @@
#define CABINET_PORT_TAG "CAB"
class _8080bw_state : public mw8080bw_state
// TODO: turn the "Space Invaders samples" audio into a device and get rid of this class
class invaders_clone_state : public invaders_state
{
public:
DECLARE_CUSTOM_INPUT_MEMBER(sicv_in2_control_r);
DECLARE_CUSTOM_INPUT_MEMBER(invadpt2_in1_control_r);
DECLARE_CUSTOM_INPUT_MEMBER(invadpt2_in2_control_r);
protected:
invaders_clone_state(const machine_config &mconfig, device_type type, const char *tag) :
invaders_state(mconfig, type, tag),
m_sn(*this, "snsnd"),
m_samples(*this, "samples")
{
}
void invaders_samples_audio(machine_config &config);
optional_device<sn76477_device> m_sn;
optional_device<samples_device> m_samples;
};
class sisv_state : public invaders_clone_state // only using invaders_clone_state for the custom input handler
{
public:
sisv_state(const machine_config &mconfig, device_type type, const char *tag) :
invaders_clone_state(mconfig, type, tag)
{
}
};
class invaders_clone_palette_state : public invaders_clone_state
{
protected:
invaders_clone_palette_state(const machine_config &mconfig, device_type type, const char *tag) :
invaders_clone_state(mconfig, type, tag),
m_palette(*this, "palette")
{
}
void set_pixel( bitmap_rgb32 &bitmap, uint8_t y, uint8_t x, int color );
void set_8_pixels(bitmap_rgb32 &bitmap, uint8_t y, uint8_t x, uint8_t data, int fore_color, int back_color);
void clear_extra_columns( bitmap_rgb32 &bitmap, int color );
optional_device<palette_device> m_palette; // TODO: make this required when things are untangled more
};
class _8080bw_state : public invaders_clone_palette_state
{
public:
_8080bw_state(const machine_config &mconfig, device_type type, const char *tag)
: mw8080bw_state(mconfig, type, tag)
, m_audiocpu(*this, "audiocpu")
: invaders_clone_palette_state(mconfig, type, tag)
, m_schaser_effect_555_timer(*this, "schaser_sh_555")
, m_claybust_gun_on(*this, "claybust_gun")
, m_sn(*this, "snsnd")
, m_samples(*this, "samples")
, m_speaker(*this, "speaker")
, m_eeprom(*this, "eeprom")
, m_palette(*this, "palette")
, m_colorram(*this, "colorram")
, m_gunx(*this, "GUNX")
, m_guny(*this, "GUNY")
, m_timer_state(1)
{ }
void indianbtbr(machine_config &config);
void claybust(machine_config &config);
void shuttlei(machine_config &config);
void spcewarla(machine_config &config);
void escmars(machine_config &config);
void lrescue(machine_config &config);
void lrescuem2(machine_config &config);
void invmulti(machine_config &config);
void yosakdon(machine_config &config);
void polaris(machine_config &config);
void attackfc(machine_config &config);
void attackfcu(machine_config &config);
void astropal(machine_config &config);
void rollingc(machine_config &config);
void vortex(machine_config &config);
void invrvnge(machine_config &config);
void sflush(machine_config &config);
void invadpt2(machine_config &config);
void lupin3a(machine_config &config);
@ -71,9 +105,7 @@ public:
void cosmo(machine_config &config);
void spcewars(machine_config &config);
void cosmicmo(machine_config &config);
void darthvdr(machine_config &config);
void ballbomb(machine_config &config);
void spacecom(machine_config &config);
void crashrd(machine_config &config);
void schasercv(machine_config &config);
void lupin3(machine_config &config);
@ -81,78 +113,57 @@ public:
void steelwkr(machine_config &config);
void schaser(machine_config &config);
void init_invmulti();
void init_spacecom();
void init_vortex();
void init_attackfc();
void init_invrvnge();
DECLARE_READ_LINE_MEMBER(cosmicmo_cab_r);
DECLARE_READ_LINE_MEMBER(sflush_80_r);
uint8_t sflush_in0_r();
DECLARE_INPUT_CHANGED_MEMBER(claybust_gun_trigger);
DECLARE_READ_LINE_MEMBER(claybust_gun_on_r);
protected:
virtual void video_start() override { m_color_map = m_screen_red = m_flip_screen = 0; }
void clear_extra_columns( bitmap_rgb32 &bitmap, int color );
inline void set_8_pixels( bitmap_rgb32 &bitmap, uint8_t y, uint8_t x, uint8_t data, int fore_color, int back_color );
virtual void video_start() override { m_color_map = m_screen_red = 0; }
void invadpt2_sh_port_1_w(uint8_t data);
void invadpt2_sh_port_2_w(uint8_t data);
DECLARE_MACHINE_START(extra_8080bw_vh);
DECLARE_MACHINE_START(extra_8080bw_sh);
uint32_t screen_update_invadpt2(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect);
/* devices/memory pointers */
optional_device<cpu_device> m_audiocpu;
optional_device<timer_device> m_schaser_effect_555_timer;
optional_device<timer_device> m_claybust_gun_on;
optional_device<sn76477_device> m_sn;
optional_device<samples_device> m_samples;
optional_device<speaker_sound_device> m_speaker;
optional_device<eeprom_serial_93cxx_device> m_eeprom;
optional_device<palette_device> m_palette;
optional_shared_ptr<uint8_t> m_colorram;
private:
/* misc game specific */
optional_ioport m_gunx;
optional_ioport m_guny;
uint8_t m_color_map = 0;
uint8_t m_screen_red = 0;
uint8_t m_fleet_step = 0;
private:
std::unique_ptr<uint8_t[]> m_scattered_colorram;
std::unique_ptr<uint8_t[]> m_scattered_colorram2;
/* sound-related */
uint8_t m_port_1_last_extra = 0;
uint8_t m_port_2_last_extra = 0;
uint8_t m_port_3_last_extra = 0;
attotime m_schaser_effect_555_time_remain;
int32_t m_schaser_effect_555_time_remain_savable = 0;
int m_schaser_effect_555_is_low = 0;
int m_schaser_explosion = 0;
int m_schaser_last_effect = 0;
uint8_t m_polaris_cloud_speed = 0;
uint8_t m_polaris_cloud_pos = 0;
uint8_t m_schaser_background_disable = 0;
uint8_t m_schaser_background_select = 0;
uint16_t m_claybust_gun_pos = 0;
u8 m_sound_data = 0;
bool m_timer_state = false;
TIMER_DEVICE_CALLBACK_MEMBER(nmi_timer);
uint8_t indianbt_r();
uint8_t polaris_port00_r();
void steelwkr_sh_port_3_w(uint8_t data);
void invadpt2_sh_port_1_w(uint8_t data);
void invadpt2_sh_port_2_w(uint8_t data);
void spacerng_sh_port_2_w(uint8_t data);
void spcewars_sh_port_w(uint8_t data);
void lrescue_sh_port_1_w(uint8_t data);
void lrescue_sh_port_2_w(uint8_t data);
void cosmo_sh_port_2_w(uint8_t data);
uint8_t darthvdr_01_r();
void darthvdr_00_w(uint8_t data);
void darthvdr_08_w(uint8_t data);
IRQ_CALLBACK_MEMBER(darthvdr_interrupt_vector);
void ballbomb_01_w(uint8_t data);
void ballbomb_sh_port_1_w(uint8_t data);
void ballbomb_sh_port_2_w(uint8_t data);
@ -160,13 +171,10 @@ private:
void indianbt_sh_port_2_w(uint8_t data);
void indianbtbr_sh_port_1_w(uint8_t data);
void indianbtbr_sh_port_2_w(uint8_t data);
uint8_t indianbtbr_01_r();
uint8_t indianbt_01_r();
void schaser_sh_port_1_w(uint8_t data);
void schaser_sh_port_2_w(uint8_t data);
void rollingc_sh_port_w(uint8_t data);
uint8_t invrvnge_02_r();
void invrvnge_port03_w(uint8_t data);
void invrvnge_port05_w(uint8_t data);
uint8_t sflush_in0_r();
void lupin3_00_w(uint8_t data);
void lupin3_sh_port_1_w(uint8_t data);
void lupin3_sh_port_2_w(uint8_t data);
@ -175,46 +183,22 @@ private:
void schasercv_sh_port_2_w(uint8_t data);
void crashrd_port03_w(uint8_t data);
void crashrd_port05_w(uint8_t data);
void yosakdon_sh_port_1_w(uint8_t data);
void yosakdon_sh_port_2_w(uint8_t data);
uint8_t shuttlei_ff_r();
void shuttlei_ff_w(uint8_t data);
void shuttlei_sh_port_1_w(uint8_t data);
void shuttlei_sh_port_2_w(uint8_t data);
uint8_t claybust_gun_lo_r();
uint8_t claybust_gun_hi_r();
uint8_t invmulti_eeprom_r();
void invmulti_eeprom_w(uint8_t data);
void invmulti_bank_w(uint8_t data);
uint8_t rollingc_scattered_colorram_r(offs_t offset);
void rollingc_scattered_colorram_w(offs_t offset, uint8_t data);
uint8_t rollingc_scattered_colorram2_r(offs_t offset);
void rollingc_scattered_colorram2_w(offs_t offset, uint8_t data);
uint8_t schaser_scattered_colorram_r(offs_t offset);
void schaser_scattered_colorram_w(offs_t offset, uint8_t data);
DECLARE_MACHINE_START(extra_8080bw);
DECLARE_MACHINE_START(rollingc);
DECLARE_MACHINE_START(sflush);
DECLARE_MACHINE_START(schaser);
DECLARE_MACHINE_START(schasercv);
DECLARE_MACHINE_RESET(schaser);
DECLARE_MACHINE_START(polaris);
DECLARE_MACHINE_START(darthvdr);
DECLARE_MACHINE_RESET(darthvdr);
DECLARE_MACHINE_START(extra_8080bw_sh);
DECLARE_MACHINE_START(extra_8080bw_vh);
DECLARE_MACHINE_START(schaser_sh);
DECLARE_MACHINE_RESET(schaser_sh);
DECLARE_MACHINE_START(claybust);
void rollingc_palette(palette_device &palette) const;
void sflush_palette(palette_device &palette) const;
uint32_t screen_update_invadpt2(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect);
uint32_t screen_update_cosmo(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect);
uint32_t screen_update_rollingc(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect);
uint32_t screen_update_schaser(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect);
uint32_t screen_update_schasercv(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect);
uint32_t screen_update_sflush(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect);
@ -222,12 +206,8 @@ private:
uint32_t screen_update_lupin3(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect);
uint32_t screen_update_polaris(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect);
uint32_t screen_update_ballbomb(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect);
uint32_t screen_update_shuttlei(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect);
uint32_t screen_update_spacecom(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect);
uint32_t screen_update_vortex(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect);
DECLARE_WRITE_LINE_MEMBER(polaris_60hz_w);
TIMER_DEVICE_CALLBACK_MEMBER(claybust_gun_callback);
TIMER_DEVICE_CALLBACK_MEMBER(schaser_effect_555_cb);
void indianbt_sh_port_3_w(uint8_t data);
void polaris_sh_port_1_w(uint8_t data);
@ -235,50 +215,32 @@ private:
void polaris_sh_port_3_w(uint8_t data);
void schaser_reinit_555_time_remain();
inline void set_pixel( bitmap_rgb32 &bitmap, uint8_t y, uint8_t x, int color );
void invaders_samples_audio(machine_config &config);
void astropal_io_map(address_map &map);
void attackfc_io_map(address_map &map);
void attackfcu_io_map(address_map &map);
void ballbomb_io_map(address_map &map);
void claybust_io_map(address_map &map);
void cosmicmo_io_map(address_map &map);
void cosmo_io_map(address_map &map);
void cosmo_map(address_map &map);
void crashrd_io_map(address_map &map);
void darthvdr_io_map(address_map &map);
void darthvdr_map(address_map &map);
void escmars_map(address_map &map);
void indianbt_io_map(address_map &map);
void indianbtbr_io_map(address_map &map);
void invadpt2_io_map(address_map &map);
void invmulti_map(address_map &map);
void invrvnge_io_map(address_map &map);
void invrvnge_sound_map(address_map &map);
void lrescue_io_map(address_map &map);
void lrescuem2_io_map(address_map &map);
void lupin3_io_map(address_map &map);
void polaris_io_map(address_map &map);
void rollingc_io_map(address_map &map);
void rollingc_map(address_map &map);
void schaser_io_map(address_map &map);
void schaser_map(address_map &map);
void schasercv_io_map(address_map &map);
void sflush_map(address_map &map);
void shuttlei_io_map(address_map &map);
void shuttlei_map(address_map &map);
void spacecom_io_map(address_map &map);
void spacecom_map(address_map &map);
void spacerng_io_map(address_map &map);
void spcewarla_io_map(address_map &map);
void spcewars_io_map(address_map &map);
void starw1_io_map(address_map &map);
void steelwkr_io_map(address_map &map);
void vortex_io_map(address_map &map);
void yosakdon_io_map(address_map &map);
void yosakdon_map(address_map &map);
};
@ -291,16 +253,280 @@ DISCRETE_SOUND_EXTERN( indianbt_discrete );
DISCRETE_SOUND_EXTERN( polaris_discrete );
DISCRETE_SOUND_EXTERN( schaser_discrete );
/*******************************************************/
/* Darth Vader bootleg */
/*******************************************************/
class darthvdr_state : public invaders_clone_state
{
public:
darthvdr_state(machine_config const &mconfig, device_type type, char const *tag) :
invaders_clone_state(mconfig, type, tag)
{
}
void darthvdr(machine_config &config);
protected:
virtual void machine_start() override;
virtual void machine_reset() override;
private:
void darthvdr_00_w(uint8_t data);
void darthvdr_08_w(uint8_t data);
IRQ_CALLBACK_MEMBER(darthvdr_interrupt_vector);
void main_map(address_map &map);
void io_map(address_map &map);
uint8_t m_port_1_last = 0;
uint8_t m_fleet_step = 0;
};
/*******************************************************/
/* Space Combat bootleg */
/*******************************************************/
class spacecom_state : public invaders_state
{
public:
spacecom_state(machine_config const &mconfig, device_type type, char const *tag) :
invaders_state(mconfig, type, tag),
m_palette(*this, "palette")
{
}
void spacecom(machine_config &config);
void init_spacecom();
private:
uint32_t screen_update_spacecom(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect);
void main_map(address_map &map);
void io_map(address_map &map);
required_device<palette_device> m_palette;
};
/*******************************************************/
/* Zenitone-Microsec Invader's Revenge */
/*******************************************************/
class invrvnge_state : public _8080bw_state
{
public:
invrvnge_state(machine_config const &mconfig, device_type type, char const *tag) :
_8080bw_state(mconfig, type, tag),
m_audiocpu(*this, "audiocpu")
{
}
void invrvnge(machine_config &config);
void init_invrvnge();
protected:
virtual void machine_start() override;
private:
void port03_w(uint8_t data);
void port05_w(uint8_t data);
TIMER_DEVICE_CALLBACK_MEMBER(nmi_timer);
void io_map(address_map &map);
void sound_map(address_map &map);
required_device<cpu_device> m_audiocpu;
uint8_t m_sound_data = 0;
uint8_t m_timer_state = 1;
};
/*******************************************************/
/* Zilec Vortex */
/*******************************************************/
class vortex_state : public invaders_state
{
public:
vortex_state(machine_config const &mconfig, device_type type, char const *tag) :
invaders_state(mconfig, type, tag)
{
}
void vortex(machine_config &config);
void init_vortex();
private:
uint32_t screen_update_vortex(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect);
void io_map(address_map &map);
};
/*******************************************************/
/* Nichibutsu Rolling Crash / Moon Base */
/*******************************************************/
class rollingc_state : public _8080bw_state // TODO: untangle the invadpt2 sounds from _8080bw_state
{
public:
rollingc_state(machine_config const &mconfig, device_type type, char const *tag) :
_8080bw_state(mconfig, type, tag)
{
}
void rollingc(machine_config &config);
DECLARE_CUSTOM_INPUT_MEMBER(game_select_r);
protected:
virtual void machine_start() override;
private:
void rollingc_sh_port_w(uint8_t data);
uint8_t scattered_colorram_r(offs_t offset);
void scattered_colorram_w(offs_t offset, uint8_t data);
uint8_t scattered_colorram2_r(offs_t offset);
void scattered_colorram2_w(offs_t offset, uint8_t data);
void rollingc_palette(palette_device &palette) const;
uint32_t screen_update_rollingc(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect);
void main_map(address_map &map);
void io_map(address_map &map);
std::unique_ptr<uint8_t []> m_scattered_colorram;
std::unique_ptr<uint8_t []> m_scattered_colorram2;
uint8_t m_port_3_last = 0;
};
/*******************************************************/
/* Wing Yosaku to Donbei */
/*******************************************************/
class yosakdon_state : public invaders_clone_state
{
public:
yosakdon_state(machine_config const &mconfig, device_type type, char const *tag) :
invaders_clone_state(mconfig, type, tag)
{
}
void yosakdon(machine_config &config);
protected:
virtual void machine_start() override;
private:
void sh_port_1_w(uint8_t data);
void sh_port_2_w(uint8_t data);
void main_map(address_map &map);
void io_map(address_map &map);
uint8_t m_port_1_last;
uint8_t m_port_2_last;
};
/*******************************************************/
/* Omori Shuttle Invader */
/*******************************************************/
class shuttlei_state : public invaders_clone_state
{
public:
shuttlei_state(machine_config const &mconfig, device_type type, char const *tag) :
invaders_clone_state(mconfig, type, tag),
m_inputs(*this, "INPUTS"),
m_p2(*this, "P2"),
m_palette(*this, "palette")
{
}
void shuttlei(machine_config &config);
protected:
virtual void machine_start() override;
private:
uint8_t port_ff_r();
void port_ff_w(uint8_t data);
void sh_port_1_w(uint8_t data);
void sh_port_2_w(uint8_t data);
uint32_t screen_update_shuttlei(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect);
void main_map(address_map &map);
void io_map(address_map &map);
required_ioport m_inputs;
required_ioport m_p2;
required_device<palette_device> m_palette;
uint8_t m_port_1_last = 0;
};
/*******************************************************/
/* Model Racing Claybuster */
/*******************************************************/
class claybust_state : public invaders_state
{
public:
claybust_state(machine_config const &mconfig, device_type type, char const *tag) :
invaders_state(mconfig, type, tag),
m_gunx(*this, "GUNX"),
m_guny(*this, "GUNY"),
m_gun_on(*this, "claybust_gun")
{
}
void claybust(machine_config &config);
DECLARE_INPUT_CHANGED_MEMBER(gun_trigger);
DECLARE_READ_LINE_MEMBER(gun_on_r);
protected:
virtual void machine_start() override;
private:
uint8_t gun_lo_r();
uint8_t gun_hi_r();
TIMER_DEVICE_CALLBACK_MEMBER(gun_callback);
void io_map(address_map &map);
required_ioport m_gunx;
required_ioport m_guny;
required_device<timer_device> m_gun_on;
uint16_t m_gun_pos = 0;
};
/*******************************************************/
/* */
/* Cane (Model Racing) */
/* */
/*******************************************************/
class cane_state : public _8080bw_state
class cane_state : public mw8080bw_state
{
public:
cane_state(machine_config const &mconfig, device_type type, char const *tag) :
_8080bw_state(mconfig, type, tag)
mw8080bw_state(mconfig, type, tag)
{
}
@ -317,16 +543,16 @@ private:
DISCRETE_SOUND_EXTERN( cane_discrete );
/*******************************************************/
/* */
/* Model Racing "Orbite" */
/* */
/* Model Racing Orbite */
/*******************************************************/
class orbite_state : public _8080bw_state
class orbite_state : public invaders_clone_palette_state
{
public:
orbite_state(machine_config const &mconfig, device_type type, char const *tag) :
_8080bw_state(mconfig, type, tag),
invaders_clone_palette_state(mconfig, type, tag),
m_main_ram(*this, "main_ram")
{
}
@ -334,9 +560,6 @@ public:
void orbite(machine_config &config);
protected:
required_shared_ptr<uint8_t> m_main_ram;
std::unique_ptr<uint8_t[]> m_scattered_colorram;
virtual void machine_start() override;
u8 orbite_scattered_colorram_r(address_space &space, offs_t offset, u8 mem_mask = 0xff);
@ -347,6 +570,42 @@ private:
void orbite_map(address_map &map);
u32 screen_update_orbite(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect);
required_shared_ptr<uint8_t> m_main_ram;
std::unique_ptr<uint8_t []> m_scattered_colorram;
};
/*******************************************************/
/* Braze Technologies Space Invaders Multigame hacks */
/*******************************************************/
class invmulti_state : public invaders_state
{
public:
invmulti_state(machine_config const &mconfig, device_type type, char const *tag) :
invaders_state(mconfig, type, tag),
m_banks(*this, "bank%u", 1U),
m_eeprom(*this, "eeprom")
{
}
void invmulti(machine_config &config);
void init_invmulti();
protected:
virtual void machine_start() override;
private:
uint8_t eeprom_r();
void eeprom_w(uint8_t data);
void bank_w(uint8_t data);
void main_map(address_map &map);
required_memory_bank_array<2> m_banks;
required_device<eeprom_serial_93cxx_device> m_eeprom;
};
#endif // MAME_INCLUDES_8080BW_H

View File

@ -60,7 +60,6 @@ public:
void checkmat(machine_config &config);
void dogpatch(machine_config &config);
void invad2ct(machine_config &config);
void invaders(machine_config &config);
void maze(machine_config &config);
void mw8080bw_root(machine_config &config);
void phantom2(machine_config &config);
@ -76,26 +75,16 @@ public:
DECLARE_CUSTOM_INPUT_MEMBER(tornbase_score_input_r);
DECLARE_CUSTOM_INPUT_MEMBER(blueshrk_coin_input_r);
DECLARE_CUSTOM_INPUT_MEMBER(invaders_sw6_sw7_r);
DECLARE_CUSTOM_INPUT_MEMBER(invaders_sw5_r);
DECLARE_CUSTOM_INPUT_MEMBER(invaders_in0_control_r);
DECLARE_CUSTOM_INPUT_MEMBER(invaders_in1_control_r);
DECLARE_CUSTOM_INPUT_MEMBER(invaders_in2_control_r);
DECLARE_MACHINE_RESET(mw8080bw);
IRQ_CALLBACK_MEMBER(interrupt_vector);
protected:
virtual void machine_start() override;
virtual void machine_reset() override;
DECLARE_WRITE_LINE_MEMBER(int_enable_w);
u8 mw8080bw_shift_result_rev_r();
int invaders_is_cabinet_cocktail();
uint32_t screen_update_invaders(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect);
uint32_t screen_update_mw8080bw(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect);
// device/memory pointers
@ -106,9 +95,6 @@ protected:
optional_device<discrete_sound_device> m_discrete;
required_device<screen_device> m_screen;
// misc game specific
uint8_t m_flip_screen = 0;
private:
// misc game specific
uint16_t m_phantom2_cloud_counter = 0;
@ -136,7 +122,6 @@ private:
void bowler_audio_6_w(uint8_t data);
DECLARE_MACHINE_START(maze);
DECLARE_MACHINE_START(phantom2);
DECLARE_MACHINE_START(invaders);
uint32_t screen_update_phantom2(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect);
DECLARE_WRITE_LINE_MEMBER(screen_vblank_phantom2);
TIMER_CALLBACK_MEMBER(maze_tone_timing_timer_callback);
@ -151,8 +136,6 @@ private:
void maze_write_discrete(uint8_t maze_tone_timing_state);
uint8_t vpos_to_vysnc_chain_counter(int vpos);
int vysnc_chain_counter_to_vpos(uint8_t counter, int vblank);
void mw8080bw_create_interrupt_timer();
void mw8080bw_start_interrupt_timer();
uint8_t tornbase_get_cabinet_type();
void blueshrk_audio(machine_config &config);
@ -167,7 +150,6 @@ private:
void checkmat_io_map(address_map &map);
void dogpatch_io_map(address_map &map);
void invad2ct_io_map(address_map &map);
void invaders_io_map(address_map &map);
void main_map(address_map &map);
void maze_io_map(address_map &map);
void phantom2_io_map(address_map &map);
@ -400,16 +382,51 @@ private:
};
#define TORNBASE_CAB_TYPE_UPRIGHT_OLD (0)
#define TORNBASE_CAB_TYPE_UPRIGHT_NEW (1)
#define TORNBASE_CAB_TYPE_COCKTAIL (2)
#define INVADERS_CAB_TYPE_PORT_TAG ("CAB")
#define INVADERS_P1_CONTROL_PORT_TAG ("CONTP1")
#define INVADERS_P2_CONTROL_PORT_TAG ("CONTP2")
#define INVADERS_SW6_SW7_PORT_TAG ("SW6SW7")
#define INVADERS_SW5_PORT_TAG ("SW5")
class invaders_state : public mw8080bw_state
{
public:
invaders_state(machine_config const &mconfig, device_type type, char const *tag) :
mw8080bw_state(mconfig, type, tag),
m_player_controls(*this, "CONTP%u", 1U),
m_cabinet_type(*this, INVADERS_CAB_TYPE_PORT_TAG)
{
}
void invaders(machine_config &config);
DECLARE_CUSTOM_INPUT_MEMBER(invaders_sw6_sw7_r);
DECLARE_CUSTOM_INPUT_MEMBER(invaders_sw5_r);
DECLARE_CUSTOM_INPUT_MEMBER(invaders_in0_control_r);
DECLARE_CUSTOM_INPUT_MEMBER(invaders_in1_control_r);
DECLARE_CUSTOM_INPUT_MEMBER(invaders_in2_control_r);
protected:
void machine_start() override;
bool is_cabinet_cocktail();
uint32_t screen_update_invaders(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect);
optional_ioport_array<2> m_player_controls;
optional_ioport m_cabinet_type;
uint8_t m_flip_screen = 0;
private:
void io_map(address_map &map);
};
#define TORNBASE_CAB_TYPE_UPRIGHT_OLD (0)
#define TORNBASE_CAB_TYPE_UPRIGHT_NEW (1)
#define TORNBASE_CAB_TYPE_COCKTAIL (2)
#define BLUESHRK_SPEAR_PORT_TAG ("IN0")
#define INVADERS_CONTROL_PORT_P1 \
@ -423,8 +440,7 @@ private:
#define INVADERS_CONTROL_PORT_PLAYER(player) \
PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_BUTTON1 ) PORT_PLAYER(player) \
PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_JOYSTICK_LEFT ) PORT_2WAY PORT_PLAYER(player) \
PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_JOYSTICK_RIGHT ) PORT_2WAY PORT_PLAYER(player) \
PORT_BIT( 0xf8, IP_ACTIVE_HIGH, IPT_UNUSED )
PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_JOYSTICK_RIGHT ) PORT_2WAY PORT_PLAYER(player)
#define INVADERS_CAB_TYPE_PORT \
PORT_START(INVADERS_CAB_TYPE_PORT_TAG) \

View File

@ -1,137 +0,0 @@
// license:BSD-3-Clause
// copyright-holders:Nicola Salmoria, Tormod Tjaberg, Mirko Buffoni,Lee Taylor, Valerio Verrando, Zsolt Vasvari
// thanks-to:Michael Strutts, Marco Cassili
/***************************************************************************
Midway 8080-based black and white hardware
****************************************************************************/
#include "emu.h"
#include "includes/mw8080bw.h"
/*************************************
*
* Interrupt generation
*
*************************************/
uint8_t mw8080bw_state::vpos_to_vysnc_chain_counter( int vpos )
{
/* convert from a vertical position to the actual values on the vertical sync counters */
uint8_t counter;
int vblank = (vpos >= MW8080BW_VBSTART);
if (vblank)
counter = vpos - MW8080BW_VBSTART + MW8080BW_VCOUNTER_START_VBLANK;
else
counter = vpos + MW8080BW_VCOUNTER_START_NO_VBLANK;
return counter;
}
int mw8080bw_state::vysnc_chain_counter_to_vpos( uint8_t counter, int vblank )
{
/* convert from the vertical sync counters to an actual vertical position */
int vpos;
if (vblank)
vpos = counter - MW8080BW_VCOUNTER_START_VBLANK + MW8080BW_VBSTART;
else
vpos = counter - MW8080BW_VCOUNTER_START_NO_VBLANK;
return vpos;
}
TIMER_CALLBACK_MEMBER(mw8080bw_state::interrupt_trigger)
{
int vpos = m_screen->vpos();
uint8_t counter = vpos_to_vysnc_chain_counter(vpos);
if (m_int_enable)
{
m_maincpu->set_input_line(0, ASSERT_LINE);
m_interrupt_time = machine().time();
}
else
m_maincpu->set_input_line(0, CLEAR_LINE);
/* set up for next interrupt */
uint8_t next_counter;
int next_vblank;
if (counter == MW8080BW_INT_TRIGGER_COUNT_1)
{
next_counter = MW8080BW_INT_TRIGGER_COUNT_2;
next_vblank = MW8080BW_INT_TRIGGER_VBLANK_2;
}
else
{
next_counter = MW8080BW_INT_TRIGGER_COUNT_1;
next_vblank = MW8080BW_INT_TRIGGER_VBLANK_1;
}
int next_vpos = vysnc_chain_counter_to_vpos(next_counter, next_vblank);
m_interrupt_timer->adjust(m_screen->time_until_pos(next_vpos));
}
WRITE_LINE_MEMBER(mw8080bw_state::int_enable_w)
{
m_int_enable = state;
}
IRQ_CALLBACK_MEMBER(mw8080bw_state::interrupt_vector)
{
int vpos = m_screen->vpos();
// MAME scheduling quirks cause this to happen more often than you might think, in fact far too often
if (machine().time() < m_interrupt_time)
vpos++;
uint8_t counter = vpos_to_vysnc_chain_counter(vpos);
uint8_t vector = 0xc7 | ((counter & 0x40) >> 2) | ((~counter & 0x40) >> 3);
m_maincpu->set_input_line(0, CLEAR_LINE);
return vector;
}
void mw8080bw_state::mw8080bw_create_interrupt_timer( )
{
m_interrupt_timer = timer_alloc(FUNC(mw8080bw_state::interrupt_trigger), this);
}
void mw8080bw_state::mw8080bw_start_interrupt_timer( )
{
int vpos = vysnc_chain_counter_to_vpos(MW8080BW_INT_TRIGGER_COUNT_1, MW8080BW_INT_TRIGGER_VBLANK_1);
m_interrupt_timer->adjust(m_screen->time_until_pos(vpos));
m_interrupt_time = attotime::zero;
}
/*************************************
*
* Machine setup
*
*************************************/
void mw8080bw_state::machine_start()
{
mw8080bw_create_interrupt_timer();
}
/*************************************
*
* Machine reset
*
*************************************/
MACHINE_RESET_MEMBER(mw8080bw_state,mw8080bw)
{
mw8080bw_start_interrupt_timer();
}

View File

@ -15,7 +15,6 @@
MACHINE_START_MEMBER(_8080bw_state,extra_8080bw_vh)
{
save_item(NAME(m_flip_screen));
save_item(NAME(m_color_map));
save_item(NAME(m_screen_red));
@ -26,7 +25,7 @@ MACHINE_START_MEMBER(_8080bw_state,extra_8080bw_vh)
}
void _8080bw_state::rollingc_palette(palette_device &palette) const
void rollingc_state::rollingc_palette(palette_device &palette) const
{
// palette is 3bpp + intensity
for (int i = 0; i < 8; i++)
@ -51,7 +50,7 @@ void _8080bw_state::sflush_palette(palette_device &palette) const
}
inline void _8080bw_state::set_pixel( bitmap_rgb32 &bitmap, uint8_t y, uint8_t x, int color )
inline void invaders_clone_palette_state::set_pixel(bitmap_rgb32 &bitmap, uint8_t y, uint8_t x, int color)
{
if (y >= MW8080BW_VCOUNTER_START_NO_VBLANK)
{
@ -63,33 +62,29 @@ inline void _8080bw_state::set_pixel( bitmap_rgb32 &bitmap, uint8_t y, uint8_t x
}
inline void _8080bw_state::set_8_pixels( bitmap_rgb32 &bitmap, uint8_t y, uint8_t x, uint8_t data, int fore_color, int back_color )
inline void invaders_clone_palette_state::set_8_pixels(bitmap_rgb32 &bitmap, uint8_t y, uint8_t x, uint8_t data, int fore_color, int back_color)
{
int i;
for (i = 0; i < 8; i++)
for (int i = 0; i < 8; i++)
{
set_pixel(bitmap, y, x, (data & 0x01) ? fore_color : back_color);
set_pixel(bitmap, y, x, BIT(data, 0) ? fore_color : back_color);
x = x + 1;
data = data >> 1;
x += 1;
data >>= 1;
}
}
/* this is needed as this driver doesn't emulate the shift register like mw8080bw does */
void _8080bw_state::clear_extra_columns( bitmap_rgb32 &bitmap, int color )
// this is needed as this driver doesn't emulate the shift register like mw8080bw does
void invaders_clone_palette_state::clear_extra_columns(bitmap_rgb32 &bitmap, int color)
{
for (uint8_t x = 0; x < 4; x++)
{
uint8_t y;
for (y = MW8080BW_VCOUNTER_START_NO_VBLANK; y != 0; y++)
for (uint8_t y = MW8080BW_VCOUNTER_START_NO_VBLANK; y != 0; y++)
{
if (m_flip_screen)
bitmap.pix(MW8080BW_VBSTART - 1 - (y - MW8080BW_VCOUNTER_START_NO_VBLANK), MW8080BW_HPIXCOUNT - 1 - (256 + x)) = m_palette->pen_color(color);
else
bitmap.pix(y - MW8080BW_VCOUNTER_START_NO_VBLANK, 256 + x) = m_palette->pen_color(color);
bitmap.pix(y - MW8080BW_VCOUNTER_START_NO_VBLANK, 256 + x) = m_palette->pen_color(color);
}
}
}
@ -97,18 +92,18 @@ void _8080bw_state::clear_extra_columns( bitmap_rgb32 &bitmap, int color )
uint32_t _8080bw_state::screen_update_invadpt2(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect)
{
uint8_t *prom = memregion("proms")->base();
uint8_t *color_map_base = m_color_map ? &prom[0x0400] : &prom[0x0000];
uint8_t const *const prom = memregion("proms")->base();
uint8_t const *const color_map_base = m_color_map ? &prom[0x0400] : &prom[0x0000];
for (offs_t offs = 0; offs < m_main_ram.bytes(); offs++)
{
uint8_t y = offs >> 5;
uint8_t x = offs << 3;
uint8_t const y = offs >> 5;
uint8_t const x = offs << 3;
offs_t color_address = (offs >> 8 << 5) | (offs & 0x1f);
offs_t const color_address = (offs >> 8 << 5) | (offs & 0x1f);
uint8_t data = m_main_ram[offs];
uint8_t fore_color = m_screen_red ? 1 : color_map_base[color_address] & 0x07;
uint8_t const data = m_main_ram[offs];
uint8_t const fore_color = m_screen_red ? 1 : color_map_base[color_address] & 0x07;
set_8_pixels(bitmap, y, x, data, fore_color, 0);
}
@ -121,20 +116,20 @@ uint32_t _8080bw_state::screen_update_invadpt2(screen_device &screen, bitmap_rgb
uint32_t _8080bw_state::screen_update_ballbomb(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect)
{
uint8_t *prom = memregion("proms")->base();
uint8_t *color_map_base = m_color_map ? &prom[0x0400] : &prom[0x0000];
uint8_t const *const prom = memregion("proms")->base();
uint8_t const *const color_map_base = m_color_map ? &prom[0x0400] : &prom[0x0000];
for (offs_t offs = 0; offs < m_main_ram.bytes(); offs++)
{
uint8_t y = offs >> 5;
uint8_t x = offs << 3;
uint8_t const y = offs >> 5;
uint8_t const x = offs << 3;
offs_t color_address = (offs >> 8 << 5) | (offs & 0x1f);
offs_t const color_address = (offs >> 8 << 5) | (offs & 0x1f);
uint8_t data = m_main_ram[offs];
uint8_t fore_color = m_screen_red ? 1 : color_map_base[color_address] & 0x07;
uint8_t const data = m_main_ram[offs];
uint8_t const fore_color = m_screen_red ? 1 : color_map_base[color_address] & 0x07;
/* blue background */
// blue background
set_8_pixels(bitmap, y, x, data, fore_color, 2);
}
@ -188,7 +183,7 @@ uint32_t _8080bw_state::screen_update_schasercv(screen_device &screen, bitmap_rg
uint8_t data = m_main_ram[offs];
uint8_t fore_color = m_scattered_colorram[(offs & 0x1f) | ((offs & 0x1f80) >> 2)] & 0x07;
/* blue background */
// blue background
set_8_pixels(bitmap, y, x, data, fore_color, 2);
}
@ -198,7 +193,7 @@ uint32_t _8080bw_state::screen_update_schasercv(screen_device &screen, bitmap_rg
}
uint32_t _8080bw_state::screen_update_rollingc(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect)
uint32_t rollingc_state::screen_update_rollingc(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect)
{
for (offs_t offs = 0; offs < m_main_ram.bytes(); offs++)
{
@ -365,12 +360,12 @@ uint32_t _8080bw_state::screen_update_sflush(screen_device &screen, bitmap_rgb32
}
uint32_t _8080bw_state::screen_update_shuttlei(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect)
uint32_t shuttlei_state::screen_update_shuttlei(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect)
{
for (offs_t offs = 0; offs < m_main_ram.bytes(); offs++)
{
uint8_t y = offs >> 5;
uint8_t x = offs << 3;
uint8_t const y = offs >> 5;
uint8_t const x = offs << 3;
uint8_t data = m_main_ram[offs];
@ -388,19 +383,19 @@ uint32_t _8080bw_state::screen_update_shuttlei(screen_device &screen, bitmap_rgb
}
uint32_t _8080bw_state::screen_update_spacecom(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect)
uint32_t spacecom_state::screen_update_spacecom(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect)
{
for (offs_t offs = 0; offs < 0x1c00; offs++)
{
uint8_t y = offs >> 5;
uint8_t x = offs << 3;
uint8_t flipx = m_flip_screen ? 7 : 0;
uint8_t const y = offs >> 5;
uint8_t const x = offs << 3;
uint8_t const flipx = m_flip_screen ? 7 : 0;
uint8_t data = m_main_ram[offs+0x400];
for (int i = 0; i < 8; i++)
{
bitmap.pix(y, x | (i^flipx)) = m_palette->pen_color(BIT(data, 0));
bitmap.pix(y, x | (i ^ flipx)) = m_palette->pen_color(BIT(data, 0));
data >>= 1;
}
}
@ -408,7 +403,7 @@ uint32_t _8080bw_state::screen_update_spacecom(screen_device &screen, bitmap_rgb
return 0;
}
uint32_t _8080bw_state::screen_update_vortex(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect)
uint32_t vortex_state::screen_update_vortex(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect)
{
uint8_t video_data = 0;
rgb_t col = rgb_t::black();

View File

@ -353,7 +353,7 @@ WRITE_LINE_MEMBER(mw8080bw_state::screen_vblank_phantom2)
// the flip screen circuit is just a couple of relays on the monitor PCB
uint32_t mw8080bw_state::screen_update_invaders(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect)
uint32_t invaders_state::screen_update_invaders(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect)
{
uint8_t x = 0;
uint8_t y = MW8080BW_VCOUNTER_START_NO_VBLANK;