From 62c35fe3cec10c706792c28796a5d7d96c5164ea Mon Sep 17 00:00:00 2001 From: Vas Crabb Date: Sun, 5 Jun 2022 23:37:21 +1000 Subject: 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. --- scripts/target/mame/arcade.lua | 1 - src/mame/audio/8080bw.cpp | 45 +- src/mame/drivers/8080bw.cpp | 997 ++++++++++++++++++++++------------------- src/mame/drivers/mw8080bw.cpp | 179 ++++++-- src/mame/includes/8080bw.h | 493 +++++++++++++++----- src/mame/includes/mw8080bw.h | 66 +-- src/mame/machine/mw8080bw.cpp | 137 ------ src/mame/video/8080bw.cpp | 79 ++-- src/mame/video/mw8080bw.cpp | 2 +- 9 files changed, 1150 insertions(+), 849 deletions(-) delete mode 100644 src/mame/machine/mw8080bw.cpp diff --git a/scripts/target/mame/arcade.lua b/scripts/target/mame/arcade.lua index 2ea31db61ff..bb68b58385d 100644 --- a/scripts/target/mame/arcade.lua +++ b/scripts/target/mame/arcade.lua @@ -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", diff --git a/src/mame/audio/8080bw.cpp b/src/mame/audio/8080bw.cpp index 9f2df3d840b..06fe3588266 100644 --- a/src/mame/audio/8080bw.cpp +++ b/src/mame/audio/8080bw.cpp @@ -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; } diff --git a/src/mame/drivers/8080bw.cpp b/src/mame/drivers/8080bw.cpp index 3f6b63f6b20..77616ad1c44 100644 --- a/src/mame/drivers/8080bw.cpp +++ b/src/mame/drivers/8080bw.cpp @@ -225,7 +225,7 @@ MACHINE_START_MEMBER(_8080bw_state,extra_8080bw) { - mw8080bw_state::machine_start(); + invaders_clone_palette_state::machine_start(); MACHINE_START_CALL_MEMBER(extra_8080bw_sh); MACHINE_START_CALL_MEMBER(extra_8080bw_vh); @@ -237,24 +237,31 @@ MACHINE_START_MEMBER(_8080bw_state,extra_8080bw) /* */ /*******************************************************/ -static INPUT_PORTS_START( sicv ) +CUSTOM_INPUT_MEMBER(invaders_clone_state::sicv_in2_control_r) +{ + return m_player_controls[is_cabinet_cocktail() ? 1 : 0]->read() | ioport("P2GATE")->read(); +} + +static INPUT_PORTS_START( sicv_base ) + // common port definitions used by SICV and clones, based on sicv unless otherwise noted + PORT_START("IN0") - PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_UNKNOWN ) - PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_UNKNOWN ) - PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_UNKNOWN ) - PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_UNKNOWN ) - PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_UNKNOWN ) - PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_UNKNOWN ) - PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_UNKNOWN ) - PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_UNKNOWN ) + PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_UNKNOWN ) // sicv has a DIP switch connected here + PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_UNUSED ) // tied high via 1k resistor on schematic + PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_UNUSED ) // tied high via 1k resistor on schematic + PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_UNUSED ) // tied high via 1k resistor on schematic (shard with IN1 bit 3) + PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_UNUSED ) // tied high via 1k resistor on schematic + PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_UNUSED ) // not connected (floating) on schematic) + PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_UNUSED ) // tied high via 1k resistor on schematic + PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_UNUSED ) // tied high via 1k resistor on schematic PORT_START("IN1") PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_COIN1 ) PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_START2 ) PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_START1 ) - PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_UNKNOWN ) - PORT_BIT( 0x70, IP_ACTIVE_HIGH, IPT_CUSTOM ) PORT_CUSTOM_MEMBER(mw8080bw_state, invaders_in1_control_r) - PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_UNKNOWN ) + PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_UNUSED ) // tied high via 1k resistor on schematic (shared with IN0 bit 3) + PORT_BIT( 0x70, IP_ACTIVE_HIGH, IPT_CUSTOM ) PORT_CUSTOM_MEMBER(invaders_state, invaders_in1_control_r) + PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_UNUSED ) // not connected (floating) on schematic PORT_START("IN2") PORT_DIPNAME( 0x03, 0x00, DEF_STR( Lives ) ) PORT_DIPLOCATION("SW1:1,2") @@ -262,27 +269,49 @@ static INPUT_PORTS_START( sicv ) PORT_DIPSETTING( 0x01, "4" ) PORT_DIPSETTING( 0x02, "5" ) PORT_DIPSETTING( 0x03, "6" ) - PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_TILT ) PORT_DIPLOCATION("SW1:3") + PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_TILT ) PORT_DIPNAME( 0x08, 0x00, DEF_STR( Bonus_Life ) ) PORT_DIPLOCATION("SW1:4") PORT_DIPSETTING( 0x08, "1000" ) PORT_DIPSETTING( 0x00, "1500" ) - /* SW1:5,6,7: In OFF, PL2 can have no control of joystick, going auto left/right and other problems like no laser gun. - Be sure these are always ON */ - PORT_BIT( 0x70, IP_ACTIVE_HIGH, IPT_CUSTOM ) PORT_CUSTOM_MEMBER(mw8080bw_state, invaders_in2_control_r) PORT_DIPLOCATION("SW1:5,6,7") // Labeled as "FACTORY" + PORT_BIT( 0x70, IP_ACTIVE_HIGH, IPT_CUSTOM ) PORT_CUSTOM_MEMBER(invaders_state, invaders_in2_control_r) // P2 controls gated by DIP switches on sicv PORT_DIPNAME( 0x80, 0x00, "Coin Info" ) PORT_DIPLOCATION("SW1:8") PORT_DIPSETTING( 0x80, DEF_STR( Off ) ) PORT_DIPSETTING( 0x00, DEF_STR( On ) ) - /* Dummy controls port, P1 */ + // P1 controls (read via IN1, and also via IN2 on upright cabinets) INVADERS_CONTROL_PORT_P1 - /* Dummy controls port, P2 */ + // P2 controls on cocktail cabinet (read via IN2) INVADERS_CONTROL_PORT_P2 - /* Dummy port for cocktail mode */ + // Dummy port for cocktail mode INVADERS_CAB_TYPE_PORT INPUT_PORTS_END +static INPUT_PORTS_START( sicv ) + PORT_INCLUDE( sicv_base ) + + PORT_MODIFY("IN0") + PORT_DIPNAME( 0x01, 0x00, DEF_STR( Unknown ) ) PORT_DIPLOCATION("SW1:3") + PORT_DIPSETTING( 0x01, DEF_STR( Off ) ) + PORT_DIPSETTING( 0x00, DEF_STR( On ) ) + + PORT_MODIFY("IN2") + PORT_BIT( 0x70, IP_ACTIVE_HIGH, IPT_CUSTOM ) PORT_CUSTOM_MEMBER(invaders_clone_state, sicv_in2_control_r) + + // DIP switches for disconnecting P2 inputs - labelled "FACTORY" + PORT_START("P2GATE") + PORT_DIPNAME( 0x01, 0x00, "Leave on (P2 Fire gate)" ) PORT_DIPLOCATION("SW1:7") + PORT_DIPSETTING( 0x01, DEF_STR( Off ) ) + PORT_DIPSETTING( 0x00, DEF_STR( On ) ) + PORT_DIPNAME( 0x02, 0x00, "Leave on (P2 Left gate)" ) PORT_DIPLOCATION("SW1:6") + PORT_DIPSETTING( 0x02, DEF_STR( Off ) ) + PORT_DIPSETTING( 0x00, DEF_STR( On ) ) + PORT_DIPNAME( 0x04, 0x00, "Leave on (P2 Right gate)" ) PORT_DIPLOCATION("SW1:5") + PORT_DIPSETTING( 0x04, DEF_STR( Off ) ) + PORT_DIPSETTING( 0x00, DEF_STR( On ) ) +INPUT_PORTS_END + /*******************************************************/ @@ -297,9 +326,6 @@ static INPUT_PORTS_START( sitv ) PORT_MODIFY("IN0") PORT_SERVICE( 0x01, IP_ACTIVE_LOW ) - - PORT_MODIFY("IN1") - PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_UNKNOWN ) INPUT_PORTS_END @@ -326,7 +352,7 @@ static INPUT_PORTS_START( alieninv ) PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_START2 ) PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_START1 ) PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_UNKNOWN ) - 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_LOW, IPT_UNKNOWN ) PORT_START("IN2") @@ -338,7 +364,7 @@ static INPUT_PORTS_START( alieninv ) PORT_DIPSETTING( 0x00, DEF_STR( On ) ) PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_COIN2 ) PORT_DIPLOCATION("SW1:3") /* Pence Coin */ PORT_DIPUNKNOWN_DIPLOC( 0x08, 0x08, "SW1:4" ) /* Not bonus */ - PORT_BIT( 0x70, IP_ACTIVE_HIGH, IPT_CUSTOM ) PORT_CUSTOM_MEMBER(mw8080bw_state, invaders_in2_control_r) PORT_DIPLOCATION("SW1:5,6,7") + PORT_BIT( 0x70, IP_ACTIVE_HIGH, IPT_CUSTOM ) PORT_CUSTOM_MEMBER(invaders_state, invaders_in2_control_r) PORT_DIPLOCATION("SW1:5,6,7") PORT_DIPNAME( 0x80, 0x80, DEF_STR( Coinage ) ) PORT_DIPLOCATION("SW1:8") PORT_DIPSETTING( 0x00, "2C/1C 50p/3C (+ Bonus Life)" ) PORT_DIPSETTING( 0x80, "1C/1C 50p/5C" ) @@ -362,7 +388,7 @@ INPUT_PORTS_END /*******************************************************/ static INPUT_PORTS_START( invadrmr ) - PORT_INCLUDE( sicv ) + PORT_INCLUDE( sicv_base ) PORT_MODIFY("IN2") PORT_DIPNAME( 0x08, 0x00, DEF_STR( Bonus_Life ) ) PORT_DIPLOCATION("SW1:4") @@ -378,6 +404,16 @@ INPUT_PORTS_END /* */ /*******************************************************/ +CUSTOM_INPUT_MEMBER(invaders_clone_state::invadpt2_in1_control_r) +{ + return m_player_controls[0]->read() | (m_player_controls[1]->read() & ~m_cabinet_type->read()); +} + +CUSTOM_INPUT_MEMBER(invaders_clone_state::invadpt2_in2_control_r) +{ + return m_player_controls[1]->read() | (m_player_controls[0]->read() & ~m_cabinet_type->read()); +} + void _8080bw_state::invadpt2_io_map(address_map &map) { map(0x00, 0x00).portr("IN0"); @@ -391,26 +427,48 @@ void _8080bw_state::invadpt2_io_map(address_map &map) static INPUT_PORTS_START( invadpt2 ) - PORT_INCLUDE( sicv ) - - PORT_MODIFY("IN0") - // Name Reset - if name of high scorer was rude, owner can press this button - PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_OTHER ) PORT_NAME("Name Reset") PORT_CODE(KEYCODE_F1) + PORT_START("IN0") + PORT_DIPUNUSED_DIPLOC( 0x01, 0x00, "SW1:8" ) // manual suggests this if for an unavailable test mode + PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_UNUSED ) // tied low on schematic + PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_UNUSED ) // tied high via 1k resistor on schematic (shared with IN0 bit 4, IN0 bit 5, IN0 bit 7, IN1 bit 7, IN2 bit 2) + PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_UNUSED ) // tied low on schematic + PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_UNUSED ) // tied high via 1k resistor on schematic (shared with IN0 bits 3/5/7, IN1 bit 7, IN2 bit 2) + PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_UNUSED ) // tied high via 1k resistor on schematic (shared with IN0 bits 3/4/7, IN1 bit 7, IN2 bit 2) + PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_MEMORY_RESET ) PORT_NAME("Name Reset") // if name of high scorer was rude, owner can press this button + PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_UNUSED ) // tied high via 1k resistor on schematic (shared with IN0 bits 3/4/5, IN1 bit 7, IN2 bit 2) - PORT_MODIFY("IN1") - PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_UNKNOWN ) + PORT_START("IN1") + PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_COIN1 ) + PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_START2 ) + PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_START1 ) + PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_UNUSED ) // tied low on schematic + PORT_BIT( 0x70, IP_ACTIVE_HIGH, IPT_CUSTOM ) PORT_CUSTOM_MEMBER(invaders_clone_state, invadpt2_in1_control_r) + PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_UNUSED ) // tied high via 1k resistor on schematic (shared with IN0 bits 3/4/5/7, IN2 bit 2) - PORT_MODIFY("IN2") - PORT_DIPNAME( 0x01, 0x00, DEF_STR( Lives ) ) PORT_DIPLOCATION("SW1:1") + PORT_START("IN2") + PORT_DIPNAME( 0x01, 0x00, DEF_STR( Lives ) ) PORT_DIPLOCATION("SW1:4") PORT_DIPSETTING( 0x00, "3" ) PORT_DIPSETTING( 0x01, "4" ) - // SW1:2 doesn't seem to work? - PORT_DIPNAME( 0x02, 0x00, "Rotate Images" ) PORT_DIPLOCATION("SW1:2") // "When ON, the images on screen will be rotated. Default is ON." - PORT_DIPSETTING( 0x02, DEF_STR( Off ) ) + PORT_DIPUNUSED_DIPLOC( 0x02, 0x00, "SW1:3" ) // previously called "Image Rotation" - "When ON, the images on screen will be rotated. Default is ON." + PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_UNUSED ) // tied high via 1k resistor on schematic (shared with IN0 bits 3/4/5/7, IN1 bit 7), but triggers tilt - must be pulled low somehow + PORT_DIPNAME( 0x08, 0x00, "Preset Mode" ) PORT_DIPLOCATION("SW1:2") // in preset mode, 1P start increases score by 1000 to pre-set high score/name + PORT_DIPSETTING( 0x00, "Game Mode" ) + PORT_DIPSETTING( 0x08, "Name Entry" ) + PORT_BIT( 0x70, IP_ACTIVE_HIGH, IPT_CUSTOM ) PORT_CUSTOM_MEMBER(invaders_clone_state, invadpt2_in2_control_r) + PORT_DIPNAME( 0x80, 0x00, "Coin Info" ) PORT_DIPLOCATION("SW1:1") + PORT_DIPSETTING( 0x80, DEF_STR( Off ) ) PORT_DIPSETTING( 0x00, DEF_STR( On ) ) - PORT_DIPNAME( 0x08, 0x00, "Preset Mode" ) PORT_DIPLOCATION("SW1:4") // Preset Mode: "Switch for checking, when OFF checking can be done." - PORT_DIPSETTING( 0x00, DEF_STR( Off ) ) - PORT_DIPSETTING( 0x08, DEF_STR( On ) ) + + // P1 controls (read via IN1, and also via IN2 on upright cabinets) + INVADERS_CONTROL_PORT_P1 + + // P2 controls (read via IN2, and also via IN1 on upright cabinets) + INVADERS_CONTROL_PORT_P2 + + PORT_START(INVADERS_CAB_TYPE_PORT_TAG) + PORT_DIPNAME( 0x07, 0x00, DEF_STR( Cabinet ) ) PORT_DIPLOCATION("SW1:5,6,7") // couples player inputs in upright mode + PORT_DIPSETTING( 0x00, DEF_STR( Upright ) ) + PORT_DIPSETTING( 0x07, DEF_STR( Cocktail ) ) INPUT_PORTS_END @@ -486,10 +544,7 @@ void _8080bw_state::spcewars_io_map(address_map &map) static INPUT_PORTS_START( spcewars ) - PORT_INCLUDE( sicv ) - - PORT_MODIFY("IN1") - PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_UNKNOWN ) + PORT_INCLUDE( sicv_base ) PORT_MODIFY("IN2") PORT_DIPNAME( 0x01, 0x00, DEF_STR( Lives ) ) PORT_DIPLOCATION("SW1:1") @@ -648,10 +703,7 @@ void _8080bw_state::cosmo_io_map(address_map &map) static INPUT_PORTS_START( cosmo ) - PORT_INCLUDE( sicv ) - - PORT_MODIFY("IN1") - PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_UNKNOWN ) + PORT_INCLUDE( sicv_base ) PORT_MODIFY("IN2") PORT_DIPNAME( 0x01, 0x00, DEF_STR( Lives ) ) PORT_DIPLOCATION("SW1:1") @@ -692,10 +744,7 @@ void _8080bw_state::cosmo(machine_config &config) /*******************************************************/ static INPUT_PORTS_START( searthin ) - PORT_INCLUDE( sicv ) - - PORT_MODIFY("IN1") - PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_UNKNOWN ) + PORT_INCLUDE( sicv_base ) PORT_MODIFY("IN2") PORT_DIPNAME( 0x01, 0x01, DEF_STR( Lives ) ) PORT_DIPLOCATION("SW1:1") @@ -720,20 +769,20 @@ INPUT_PORTS_END /*******************************************************/ static INPUT_PORTS_START( sinvzen ) - PORT_INCLUDE( sicv ) + PORT_INCLUDE( sicv_base ) PORT_MODIFY("IN0") - PORT_DIPNAME( 0x01, 0x00, DEF_STR( Difficulty ) ) /* [code: 0x18ca-d1] */ + PORT_DIPNAME( 0x01, 0x00, DEF_STR( Difficulty ) ) PORT_DIPLOCATION("SW1:3") PORT_DIPSETTING( 0x00, DEF_STR( Easy ) ) PORT_DIPSETTING( 0x01, DEF_STR( Hard ) ) PORT_MODIFY("IN2") - PORT_DIPNAME( 0x80, 0x00, DEF_STR( Coinage ) ) PORT_DIPLOCATION("SW1:8") + PORT_DIPNAME( 0x80, 0x00, DEF_STR( Coinage ) ) PORT_DIPLOCATION("SW1:8") PORT_DIPSETTING( 0x80, DEF_STR( 2C_1C ) ) PORT_DIPSETTING( 0x00, DEF_STR( 1C_1C ) ) - PORT_MODIFY(CABINET_PORT_TAG) /* Dummy port for cocktail mode */ - PORT_BIT( 0xff, IP_ACTIVE_LOW, IPT_UNKNOWN ) + PORT_MODIFY(CABINET_PORT_TAG) + PORT_BIT( 0xff, IP_ACTIVE_LOW, IPT_UNUSED ) // no cocktail mode? INPUT_PORTS_END @@ -745,7 +794,7 @@ INPUT_PORTS_END /*******************************************************/ static INPUT_PORTS_START( spaceat2 ) - PORT_INCLUDE( sicv ) + PORT_INCLUDE( sicv_base ) PORT_MODIFY("IN0") PORT_DIPNAME( 0x04, 0x00, DEF_STR( Difficulty ) ) /* [code: 0x18ca-d1] */ @@ -760,8 +809,8 @@ static INPUT_PORTS_START( spaceat2 ) PORT_DIPSETTING( 0x80, DEF_STR( 2C_1C ) ) PORT_DIPSETTING( 0x00, DEF_STR( 1C_1C ) ) - PORT_MODIFY(CABINET_PORT_TAG) /* Dummy port for cocktail mode */ - PORT_BIT( 0xff, IP_ACTIVE_LOW, IPT_UNKNOWN ) + PORT_MODIFY(CABINET_PORT_TAG) + PORT_BIT( 0xff, IP_ACTIVE_LOW, IPT_UNUSED ) // no cocktail mode? INPUT_PORTS_END @@ -785,7 +834,7 @@ INPUT_PORTS_END /*******************************************************/ static INPUT_PORTS_START( spacecom ) - PORT_START("IN0") // 5-pos dipsw at ic79 (row F) + PORT_START("IN0") // 5-pos DIP switch at ic79 (row F) PORT_DIPNAME( 0x01, 0x01, DEF_STR( Unknown ) ) PORT_DIPSETTING( 0x01, DEF_STR( Off ) ) PORT_DIPSETTING( 0x00, DEF_STR( On ) ) @@ -824,44 +873,47 @@ static INPUT_PORTS_START( spacecom ) INPUT_PORTS_END -void _8080bw_state::spacecom_map(address_map &map) +void spacecom_state::main_map(address_map &map) { map(0x0000, 0x1fff).rom(); map(0x2000, 0x3fff).ram().share("main_ram"); // other RAM not hooked up? } -void _8080bw_state::spacecom_io_map(address_map &map) +void spacecom_state::io_map(address_map &map) { map(0x41, 0x41).portr("IN0"); map(0x42, 0x42).portr("IN1").w("soundboard", FUNC(invaders_audio_device::p1_w)); map(0x44, 0x44).portr("IN2").w("soundboard", FUNC(invaders_audio_device::p2_w)); } -void _8080bw_state::spacecom(machine_config &config) +void spacecom_state::spacecom(machine_config &config) { - /* basic machine hardware */ + // basic machine hardware i8080a_cpu_device &maincpu(I8080A(config, m_maincpu, XTAL(18'000'000) / 9)); // divider guessed // TODO: move irq handling away from mw8080.c, this game runs on custom hardware - maincpu.set_addrmap(AS_PROGRAM, &_8080bw_state::spacecom_map); - maincpu.set_addrmap(AS_IO, &_8080bw_state::spacecom_io_map); - maincpu.set_irq_acknowledge_callback(FUNC(_8080bw_state::interrupt_vector)); - maincpu.out_inte_func().set(FUNC(_8080bw_state::int_enable_w)); + maincpu.set_addrmap(AS_PROGRAM, &spacecom_state::main_map); + maincpu.set_addrmap(AS_IO, &spacecom_state::io_map); + maincpu.set_irq_acknowledge_callback(FUNC(spacecom_state::interrupt_vector)); + maincpu.out_inte_func().set(FUNC(spacecom_state::int_enable_w)); - MCFG_MACHINE_RESET_OVERRIDE(mw8080bw_state, mw8080bw) - - /* video hardware */ + // video hardware SCREEN(config, m_screen, SCREEN_TYPE_RASTER); m_screen->set_raw(XTAL(18'000'000) / 3, 384, 0, 256, 260, 0, 224); // parameters guessed - m_screen->set_screen_update(FUNC(_8080bw_state::screen_update_spacecom)); + m_screen->set_screen_update(FUNC(spacecom_state::screen_update_spacecom)); PALETTE(config, m_palette, palette_device::MONOCHROME); - /* sound 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; }); + // sound hardware + 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; + }); } -void _8080bw_state::init_spacecom() +void spacecom_state::init_spacecom() { uint8_t *ROM = memregion("maincpu")->base(); @@ -877,28 +929,21 @@ void _8080bw_state::init_spacecom() /* */ /*******************************************************/ -uint8_t _8080bw_state::invrvnge_02_r() -{ - uint8_t data = ioport("IN2")->read(); - if (m_flip_screen) return data; - return (data & 0x8f) | (ioport("IN1")->read() & 0x70); -} - -void _8080bw_state::invrvnge_io_map(address_map &map) +void invrvnge_state::io_map(address_map &map) { map(0x00, 0x00).portr("IN0"); map(0x01, 0x01).portr("IN1"); - map(0x02, 0x02).r(FUNC(_8080bw_state::invrvnge_02_r)).w(m_mb14241, FUNC(mb14241_device::shift_count_w)); - map(0x03, 0x03).r(m_mb14241, FUNC(mb14241_device::shift_result_r)).w(FUNC(_8080bw_state::invrvnge_port03_w)); + map(0x02, 0x02).portr("IN2").w(m_mb14241, FUNC(mb14241_device::shift_count_w)); + map(0x03, 0x03).r(m_mb14241, FUNC(mb14241_device::shift_result_r)).w(FUNC(invrvnge_state::port03_w)); map(0x04, 0x04).w(m_mb14241, FUNC(mb14241_device::shift_data_w)); - map(0x05, 0x05).w(FUNC(_8080bw_state::invrvnge_port05_w)); + map(0x05, 0x05).w(FUNC(invrvnge_state::port05_w)); map(0x06, 0x06).w(m_watchdog, FUNC(watchdog_timer_device::reset_w)); } -void _8080bw_state::invrvnge_sound_map(address_map &map) +void invrvnge_state::sound_map(address_map &map) { - map(0xa001, 0xa001).r("psg",FUNC(ay8910_device::data_r)); - map(0xa002, 0xa003).w("psg",FUNC(ay8910_device::data_address_w)); + map(0xa001, 0xa001).r("psg", FUNC(ay8910_device::data_r)); + map(0xa002, 0xa003).w("psg", FUNC(ay8910_device::data_address_w)); map(0xc000, 0xc7ff).mirror(0x1800).rom(); map(0xe000, 0xe7ff).mirror(0x1800).rom(); } @@ -925,9 +970,7 @@ static INPUT_PORTS_START( invrvnge ) PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_START2 ) PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_START1 ) PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_UNKNOWN ) - PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_BUTTON1 ) - PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_JOYSTICK_LEFT ) PORT_2WAY - PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_JOYSTICK_RIGHT ) PORT_2WAY + PORT_BIT( 0x70, IP_ACTIVE_HIGH, IPT_CUSTOM ) PORT_CUSTOM_MEMBER(invaders_state, invaders_in1_control_r) PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_UNKNOWN ) PORT_START("IN2") @@ -940,38 +983,50 @@ static INPUT_PORTS_START( invrvnge ) PORT_DIPNAME( 0x08, 0x08, DEF_STR( Bonus_Life ) ) PORT_DIPLOCATION("SW1:4") PORT_DIPSETTING( 0x00, "1500" ) PORT_DIPSETTING( 0x08, "2000" ) - PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_BUTTON1 ) PORT_PLAYER(2) - PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_JOYSTICK_LEFT ) PORT_2WAY PORT_PLAYER(2) - PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_JOYSTICK_RIGHT ) PORT_2WAY PORT_PLAYER(2) + PORT_BIT( 0x70, IP_ACTIVE_HIGH, IPT_CUSTOM ) PORT_CUSTOM_MEMBER(invaders_state, invaders_in2_control_r) PORT_DIPNAME( 0x80, 0x00, DEF_STR( Coinage ) ) PORT_DIPLOCATION("SW1:8") PORT_DIPSETTING( 0x80, DEF_STR( 2C_1C ) ) // 1 play 10p, 2 play 20p, 6 play 50p PORT_DIPSETTING( 0x00, DEF_STR( 1C_1C ) ) // 1 play 20p, 2 play 40p, 3 play 50p - /* Dummy port for cocktail mode */ + // P1 controls (read via IN1, and also via IN2 on upright cabinets) + INVADERS_CONTROL_PORT_P1 + + // P2 controls on cocktail cabinet (read via IN2) + INVADERS_CONTROL_PORT_P2 + + // Dummy port for cocktail mode INVADERS_CAB_TYPE_PORT INPUT_PORTS_END -void _8080bw_state::invrvnge(machine_config &config) +void invrvnge_state::machine_start() +{ + _8080bw_state::machine_start(); + + MACHINE_START_CALL_MEMBER(extra_8080bw_vh); + + save_item(NAME(m_sound_data)); + save_item(NAME(m_timer_state)); +} + +void invrvnge_state::invrvnge(machine_config &config) { mw8080bw_root(config); - /* basic machine hardware */ - m_maincpu->set_addrmap(AS_IO, &_8080bw_state::invrvnge_io_map); + // basic machine hardware + m_maincpu->set_addrmap(AS_IO, &invrvnge_state::io_map); WATCHDOG_TIMER(config, m_watchdog); // 4 MHz crystal connected directly to the CPU M6802(config, m_audiocpu, XTAL(4'000'000)); - m_audiocpu->set_addrmap(AS_PROGRAM, &_8080bw_state::invrvnge_sound_map); + m_audiocpu->set_addrmap(AS_PROGRAM, &invrvnge_state::sound_map); /* add shifter */ MB14241(config, m_mb14241); - MCFG_MACHINE_START_OVERRIDE(_8080bw_state,extra_8080bw) - /* video hardware */ - m_screen->set_screen_update(FUNC(_8080bw_state::screen_update_invadpt2)); + m_screen->set_screen_update(FUNC(invrvnge_state::screen_update_invadpt2)); PALETTE(config, m_palette, palette_device::RBG_3BIT); @@ -985,10 +1040,10 @@ void _8080bw_state::invrvnge(machine_config &config) psg.add_route(ALL_OUTPUTS, "mono", 0.75); // CPU E-pin also connects to a 4040 divider. The Q8 output goes to the CPU's NMI pin. - TIMER(config, "nmi").configure_periodic(FUNC(_8080bw_state::nmi_timer), attotime::from_hz((XTAL(4'000'000)/4)/256)); + TIMER(config, "nmi").configure_periodic(FUNC(invrvnge_state::nmi_timer), attotime::from_hz((XTAL(4'000'000)/4)/256)); } -void _8080bw_state::init_invrvnge() +void invrvnge_state::init_invrvnge() { uint8_t *rom = memregion("audiocpu")->base(); for (offs_t i = 0xc000; i < 0xc800; i++) @@ -1072,13 +1127,7 @@ INPUT_PORTS_END /*******************************************************/ static INPUT_PORTS_START( galxwars ) - PORT_INCLUDE( sicv ) - - PORT_MODIFY("IN0") - PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_UNKNOWN ) /* must be IP_ACTIVE_LOW for Universal Sets */ - - PORT_MODIFY("IN1") - PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_UNKNOWN ) + PORT_INCLUDE( sicv_base ) PORT_MODIFY("IN2") PORT_DIPNAME( 0x03, 0x01, DEF_STR( Lives ) ) PORT_DIPLOCATION("SW1:1,2") @@ -1149,10 +1198,7 @@ void _8080bw_state::lrescuem2_io_map(address_map &map) static INPUT_PORTS_START( lrescue ) - PORT_INCLUDE( sicv ) - - PORT_MODIFY("IN1") - PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_UNKNOWN ) + PORT_INCLUDE( sicv_base ) PORT_MODIFY("IN2") /* SW1:3-8 Unused according to manual: "Factory Adjustments". Default is ON. */ @@ -1208,7 +1254,6 @@ void _8080bw_state::escmars(machine_config &config) maincpu.out_inte_func().set(FUNC(_8080bw_state::int_enable_w)); MCFG_MACHINE_START_OVERRIDE(_8080bw_state, extra_8080bw) - MCFG_MACHINE_RESET_OVERRIDE(_8080bw_state, mw8080bw) /* add shifter */ MB14241(config, m_mb14241); @@ -1238,22 +1283,24 @@ void _8080bw_state::escmars(machine_config &config) /*******************************************************/ /* */ /* Universal "Cosmic Monsters" */ -/* The dipswitches are as stated in the manual, but */ +/* The DIP switches are as stated in the manual, but */ /* some of them are incorrect. */ /* - You need at the very least 3000 points to get */ /* a bonus life. */ -/* - The cabinet switch does nothing in the cpu, it */ +/* - The cabinet switch does nothing in the CPU, it */ /* is all done by wires. */ /* */ /* These issues may be due to manual/romset conflicts */ /* */ /*******************************************************/ -static INPUT_PORTS_START( cosmicmo ) - PORT_INCLUDE( sicv ) +READ_LINE_MEMBER(_8080bw_state::cosmicmo_cab_r) +{ + return m_cabinet_type->read(); +} - PORT_MODIFY("IN1") - PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_UNKNOWN ) +static INPUT_PORTS_START( cosmicmo ) + PORT_INCLUDE( sicv_base ) PORT_MODIFY("IN2") PORT_DIPNAME( 0x03, 0x01, DEF_STR( Lives ) ) PORT_DIPLOCATION("SW1:1,2") @@ -1261,21 +1308,19 @@ static INPUT_PORTS_START( cosmicmo ) PORT_DIPSETTING( 0x01, "3" ) PORT_DIPSETTING( 0x02, "4" ) PORT_DIPSETTING( 0x03, "5" ) - PORT_DIPNAME( 0x04, 0x00, DEF_STR( Cabinet ) ) PORT_DIPLOCATION("SW1:3") - PORT_DIPSETTING( 0x00, DEF_STR( Upright ) ) - PORT_DIPSETTING( 0x04, DEF_STR( Cocktail ) ) + PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_CUSTOM ) PORT_READ_LINE_MEMBER(_8080bw_state, cosmicmo_cab_r) PORT_DIPNAME( 0x08, 0x00, DEF_STR( Bonus_Life ) ) PORT_DIPLOCATION("SW1:4") PORT_DIPSETTING( 0x00, "1500" ) PORT_DIPSETTING( 0x08, "2500" ) - PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_BUTTON1 ) PORT_PLAYER(2) - PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_JOYSTICK_LEFT ) PORT_2WAY PORT_PLAYER(2) - PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_JOYSTICK_RIGHT ) PORT_2WAY PORT_PLAYER(2) + PORT_BIT( 0x70, IP_ACTIVE_HIGH, IPT_CUSTOM ) PORT_CUSTOM_MEMBER(_8080bw_state, invaders_in2_control_r) PORT_DIPNAME( 0x80, 0x00, DEF_STR( Coinage ) ) PORT_DIPLOCATION("SW1:8") PORT_DIPSETTING( 0x00, DEF_STR( 1C_1C ) ) PORT_DIPSETTING( 0x80, DEF_STR( 1C_2C ) ) - PORT_MODIFY(CABINET_PORT_TAG) /* Dummy port for cocktail mode */ - PORT_BIT( 0xff, IP_ACTIVE_HIGH, IPT_UNKNOWN ) + PORT_MODIFY(CABINET_PORT_TAG) + PORT_DIPNAME( 0x01, 0x00, DEF_STR( Cabinet ) ) PORT_DIPLOCATION("SW1:3") // put this here to avoid infinite recursion on P2 read + PORT_DIPSETTING( 0x00, DEF_STR( Upright ) ) + PORT_DIPSETTING( 0x01, DEF_STR( Cocktail ) ) INPUT_PORTS_END void _8080bw_state::cosmicmo_io_map(address_map &map) @@ -1283,7 +1328,7 @@ void _8080bw_state::cosmicmo_io_map(address_map &map) map.global_mask(0x7); map(0x00, 0x00).mirror(0x04).portr("IN0"); map(0x01, 0x01).mirror(0x04).portr("IN1"); - map(0x02, 0x02).mirror(0x04).r(FUNC(_8080bw_state::invrvnge_02_r)); + map(0x02, 0x02).mirror(0x04).portr("IN2"); map(0x03, 0x03).mirror(0x04).r(m_mb14241, FUNC(mb14241_device::shift_result_r)); map(0x02, 0x02).w(m_mb14241, FUNC(mb14241_device::shift_count_w)); @@ -1323,7 +1368,7 @@ void _8080bw_state::cosmicmo(machine_config &config) /*******************************************************/ static INPUT_PORTS_START( invasion ) - PORT_INCLUDE( sicv ) + PORT_INCLUDE( sicv_base ) PORT_MODIFY("IN1") PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_COIN1 ) @@ -1355,7 +1400,7 @@ INPUT_PORTS_END /*******************************************************/ static INPUT_PORTS_START( superinv ) - PORT_INCLUDE( sicv ) + PORT_INCLUDE( sicv_base ) PORT_MODIFY("IN1") PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_COIN1 ) @@ -1378,54 +1423,58 @@ INPUT_PORTS_END /* */ /*******************************************************/ -uint8_t _8080bw_state::rollingc_scattered_colorram_r(offs_t offset) +CUSTOM_INPUT_MEMBER(rollingc_state::game_select_r) +{ + // need the joystick left/right inputs to show in two places + return bitswap<2>(m_player_controls[0]->read(), 1, 2); +} + +uint8_t rollingc_state::scattered_colorram_r(offs_t offset) { return m_scattered_colorram[(offset & 0x1f) | ((offset & 0x1f00) >> 3)]; } -void _8080bw_state::rollingc_scattered_colorram_w(offs_t offset, uint8_t data) +void rollingc_state::scattered_colorram_w(offs_t offset, uint8_t data) { m_scattered_colorram[(offset & 0x1f) | ((offset & 0x1f00) >> 3)] = data; } -uint8_t _8080bw_state::rollingc_scattered_colorram2_r(offs_t offset) +uint8_t rollingc_state::scattered_colorram2_r(offs_t offset) { return m_scattered_colorram2[(offset & 0x1f) | ((offset & 0x1f00) >> 3)]; } -void _8080bw_state::rollingc_scattered_colorram2_w(offs_t offset, uint8_t data) +void rollingc_state::scattered_colorram2_w(offs_t offset, uint8_t data) { m_scattered_colorram2[(offset & 0x1f) | ((offset & 0x1f00) >> 3)] = data; } -void _8080bw_state::rollingc_map(address_map &map) +void rollingc_state::main_map(address_map &map) { map(0x0000, 0x1fff).rom(); map(0x2000, 0x3fff).ram().share("main_ram"); map(0x4000, 0x5fff).rom(); - map(0xa000, 0xbfff).rw(FUNC(_8080bw_state::rollingc_scattered_colorram_r), FUNC(_8080bw_state::rollingc_scattered_colorram_w)); - map(0xe000, 0xffff).rw(FUNC(_8080bw_state::rollingc_scattered_colorram2_r), FUNC(_8080bw_state::rollingc_scattered_colorram2_w)); + map(0xa000, 0xbfff).rw(FUNC(rollingc_state::scattered_colorram_r), FUNC(rollingc_state::scattered_colorram_w)); + map(0xe000, 0xffff).rw(FUNC(rollingc_state::scattered_colorram2_r), FUNC(rollingc_state::scattered_colorram2_w)); } -void _8080bw_state::rollingc_io_map(address_map &map) +void rollingc_state::io_map(address_map &map) { - map(0x00, 0x00).portr("IN0").w(FUNC(_8080bw_state::rollingc_sh_port_w)); + map(0x00, 0x00).portr("IN0").w(FUNC(rollingc_state::rollingc_sh_port_w)); map(0x01, 0x01).portr("IN1"); map(0x02, 0x02).portr("IN2").w(m_mb14241, FUNC(mb14241_device::shift_count_w)); - map(0x03, 0x03).r(m_mb14241, FUNC(mb14241_device::shift_result_r)).w(FUNC(_8080bw_state::invadpt2_sh_port_1_w)); + map(0x03, 0x03).r(m_mb14241, FUNC(mb14241_device::shift_result_r)).w(FUNC(rollingc_state::invadpt2_sh_port_1_w)); map(0x04, 0x04).w(m_mb14241, FUNC(mb14241_device::shift_data_w)); - map(0x05, 0x05).w(FUNC(_8080bw_state::invadpt2_sh_port_2_w)); + map(0x05, 0x05).w(FUNC(rollingc_state::invadpt2_sh_port_2_w)); } static INPUT_PORTS_START( rollingc ) - PORT_INCLUDE( sicv ) + PORT_INCLUDE( sicv_base ) PORT_MODIFY("IN0") - /* Duplicate control required (both must be mapped to same key for input to work for game select and in-game) */ - PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_JOYSTICK_RIGHT ) /* Game Select */ - PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_JOYSTICK_LEFT ) /* Game Select */ + PORT_BIT( 0x06, IP_ACTIVE_LOW, IPT_CUSTOM ) PORT_CUSTOM_MEMBER(rollingc_state, game_select_r) PORT_MODIFY("IN1") PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_COIN1 ) @@ -1436,36 +1485,38 @@ static INPUT_PORTS_START( rollingc ) PORT_DIPSETTING( 0x00, "RC=5000 / MB=2000" ) INPUT_PORTS_END -MACHINE_START_MEMBER(_8080bw_state,rollingc) +void rollingc_state::machine_start() { - mw8080bw_state::machine_start(); + invaders_clone_palette_state::machine_start(); + + MACHINE_START_CALL_MEMBER(extra_8080bw_sh); m_scattered_colorram = std::make_unique(0x400); m_scattered_colorram2 = std::make_unique(0x400); - save_pointer(&m_scattered_colorram[0], "m_scattered_colorram", 0x400); - save_pointer(&m_scattered_colorram2[0], "m_scattered_colorram2", 0x400); + + save_pointer(NAME(m_scattered_colorram), 0x400); + save_pointer(NAME(m_scattered_colorram2), 0x400); + save_item(NAME(m_port_3_last)); } -void _8080bw_state::rollingc(machine_config &config) +void rollingc_state::rollingc(machine_config &config) { mw8080bw_root(config); - /* basic machine hardware */ - m_maincpu->set_addrmap(AS_PROGRAM, &_8080bw_state::rollingc_map); - m_maincpu->set_addrmap(AS_IO, &_8080bw_state::rollingc_io_map); + // basic machine hardware + m_maincpu->set_addrmap(AS_PROGRAM, &rollingc_state::main_map); + m_maincpu->set_addrmap(AS_IO, &rollingc_state::io_map); - /* add shifter */ + // add shifter MB14241(config, m_mb14241); - /* video hardware */ - m_screen->set_screen_update(FUNC(_8080bw_state::screen_update_rollingc)); + // video hardware + m_screen->set_screen_update(FUNC(rollingc_state::screen_update_rollingc)); - PALETTE(config, m_palette, FUNC(_8080bw_state::rollingc_palette), 16); + PALETTE(config, m_palette, FUNC(rollingc_state::rollingc_palette), 16); - /* sound hardware */ + // sound hardware invaders_samples_audio(config); - - MCFG_MACHINE_START_OVERRIDE(_8080bw_state,rollingc) } @@ -1574,7 +1625,7 @@ INPUT_PORTS_END MACHINE_START_MEMBER(_8080bw_state,schaser) { - mw8080bw_state::machine_start(); + invaders_clone_palette_state::machine_start(); m_scattered_colorram = std::make_unique(0x800); save_pointer(&m_scattered_colorram[0], "m_scattered_colorram", 0x800); @@ -1584,16 +1635,17 @@ MACHINE_START_MEMBER(_8080bw_state,schaser) MACHINE_RESET_MEMBER(_8080bw_state,schaser) { + invaders_clone_palette_state::machine_reset(); + MACHINE_RESET_CALL_MEMBER(schaser_sh); - MACHINE_RESET_CALL_MEMBER(mw8080bw); } void _8080bw_state::schaser(machine_config &config) { mw8080bw_root(config); - /* basic machine hardware */ - i8080_cpu_device &maincpu(I8080(config.replace(), m_maincpu, 1996800)); /* 19.968MHz / 10 */ + // basic machine hardware + i8080_cpu_device &maincpu(I8080(config.replace(), m_maincpu, 1996800)); // 19.968MHz / 10 maincpu.set_addrmap(AS_PROGRAM, &_8080bw_state::schaser_map); maincpu.set_addrmap(AS_IO, &_8080bw_state::schaser_io_map); maincpu.set_irq_acknowledge_callback(FUNC(_8080bw_state::interrupt_vector)); @@ -1603,34 +1655,34 @@ void _8080bw_state::schaser(machine_config &config) MCFG_MACHINE_START_OVERRIDE(_8080bw_state,schaser) MCFG_MACHINE_RESET_OVERRIDE(_8080bw_state,schaser) - TIMER(config, "schaser_sh_555").configure_generic(FUNC(_8080bw_state::schaser_effect_555_cb)); + TIMER(config, m_schaser_effect_555_timer).configure_generic(FUNC(_8080bw_state::schaser_effect_555_cb)); - /* add shifter */ + // add shifter MB14241(config, m_mb14241); - /* video hardware */ + // video hardware m_screen->set_screen_update(FUNC(_8080bw_state::screen_update_schaser)); PALETTE(config, m_palette, palette_device::RBG_3BIT); - /* sound hardware */ + // sound hardware SPEAKER(config, "mono").front_center(); - sn76477_device &snsnd(SN76477(config, "snsnd")); - snsnd.set_noise_params(RES_K(47), RES_K(330), CAP_P(470)); - snsnd.set_decay_res(RES_M(2.2)); - snsnd.set_attack_params(CAP_U(1.0), RES_K(4.7)); - snsnd.set_amp_res(0); - snsnd.set_feedback_res(RES_K(33)); - snsnd.set_vco_params(0, CAP_U(0.1), RES_K(39)); - snsnd.set_pitch_voltage(5.0); - snsnd.set_slf_params(CAP_U(1.0), RES_K(120)); - snsnd.set_oneshot_params(CAP_U(0.1), RES_K(220)); - snsnd.set_vco_mode(1); - snsnd.set_mixer_params(0, 0, 0); - snsnd.set_envelope_params(1, 0); - snsnd.set_enable(1); - snsnd.add_route(0, "discrete", 1.0, 0); + SN76477(config, m_sn); + m_sn->set_noise_params(RES_K(47), RES_K(330), CAP_P(470)); + m_sn->set_decay_res(RES_M(2.2)); + m_sn->set_attack_params(CAP_U(1.0), RES_K(4.7)); + m_sn->set_amp_res(0); + m_sn->set_feedback_res(RES_K(33)); + m_sn->set_vco_params(0, CAP_U(0.1), RES_K(39)); + m_sn->set_pitch_voltage(5.0); + m_sn->set_slf_params(CAP_U(1.0), RES_K(120)); + m_sn->set_oneshot_params(CAP_U(0.1), RES_K(220)); + m_sn->set_vco_mode(1); + m_sn->set_mixer_params(0, 0, 0); + m_sn->set_envelope_params(1, 0); + m_sn->set_enable(1); + m_sn->add_route(0, "discrete", 1.0, 0); DISCRETE(config, m_discrete, schaser_discrete); m_discrete->add_route(ALL_OUTPUTS, "mono", 1.0); @@ -1717,7 +1769,7 @@ INPUT_PORTS_END MACHINE_START_MEMBER(_8080bw_state,schasercv) { - mw8080bw_state::machine_start(); + invaders_clone_palette_state::machine_start(); m_scattered_colorram = std::make_unique(0x800); save_pointer(&m_scattered_colorram[0], "m_scattered_colorram", 0x800); @@ -1826,7 +1878,7 @@ INPUT_PORTS_END MACHINE_START_MEMBER(_8080bw_state,sflush) { - mw8080bw_state::machine_start(); + invaders_clone_palette_state::machine_start(); m_scattered_colorram = std::make_unique(0x800); save_pointer(&m_scattered_colorram[0], "m_scattered_colorram", 0x800); @@ -2019,10 +2071,10 @@ WRITE_LINE_MEMBER(_8080bw_state::polaris_60hz_w) MACHINE_START_MEMBER(_8080bw_state,polaris) { - mw8080bw_state::machine_start(); + invaders_clone_palette_state::machine_start(); m_scattered_colorram = std::make_unique(0x800); - save_pointer(&m_scattered_colorram[0], "m_scattered_colorram", 0x800); + save_pointer(NAME(m_scattered_colorram), 0x800); save_item(NAME(m_polaris_cloud_speed)); save_item(NAME(m_polaris_cloud_pos)); @@ -2032,8 +2084,10 @@ MACHINE_START_MEMBER(_8080bw_state,polaris) uint8_t _8080bw_state::polaris_port00_r() { uint8_t data = ioport("IN0")->read(); - if (m_flip_screen) return data; - return (data & 7) | (ioport("IN1")->read() & 0xf8); + if (m_flip_screen) + return data; + else + return (data & 7) | (ioport("IN1")->read() & 0xf8); } // Port 5 is used to reset the watchdog timer. @@ -2087,8 +2141,7 @@ static INPUT_PORTS_START( polaris ) PORT_DIPNAME( 0x08, 0x00, "Invincible Test" ) PORT_DIPLOCATION("SW1:4") PORT_DIPSETTING( 0x00, DEF_STR( Off ) ) PORT_DIPSETTING( 0x08, DEF_STR( On ) ) - /* The Demo Sounds dip switch does function. - It allows the sonar sounds to play in demo mode. */ + // The Demo Sounds DIP switch does function - it allows the sonar sounds to play in demo mode. PORT_DIPNAME( 0x10, 0x10, DEF_STR( Demo_Sounds ) ) PORT_DIPLOCATION("SW1:5") PORT_DIPSETTING( 0x00, DEF_STR( Off ) ) PORT_DIPSETTING( 0x10, DEF_STR( On ) ) @@ -2145,7 +2198,7 @@ void _8080bw_state::polaris(machine_config &config) /*******************************************************/ static INPUT_PORTS_START( ozmawars ) - PORT_INCLUDE( sicv ) + PORT_INCLUDE( sicv_base ) PORT_MODIFY("IN1") PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_COIN1 ) @@ -2182,10 +2235,7 @@ INPUT_PORTS_END /*******************************************************/ static INPUT_PORTS_START( sinvemag ) - PORT_INCLUDE( sicv ) - - PORT_MODIFY("IN1") - PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_UNKNOWN ) + PORT_INCLUDE( sicv_base ) PORT_MODIFY("IN2") PORT_DIPUNKNOWN_DIPLOC( 0x04, 0x00, "SW1:3" ) @@ -2203,11 +2253,12 @@ INPUT_PORTS_END /*******************************************************/ static INPUT_PORTS_START( jspecter ) - PORT_INCLUDE( sicv ) + PORT_INCLUDE( sicv_base ) PORT_MODIFY("IN1") // Hold right when starting game to play game B PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_JOYSTICK_RIGHT ) PORT_2WAY PORT_PLAYER(1) + PORT_MODIFY("IN2") PORT_DIPUNKNOWN_DIPLOC( 0x04, 0x00, "SW1:3" ) INPUT_PORTS_END @@ -2232,7 +2283,7 @@ void _8080bw_state::ballbomb_io_map(address_map &map) static INPUT_PORTS_START( ballbomb ) - PORT_INCLUDE( sicv ) + PORT_INCLUDE( sicv_base ) PORT_MODIFY("IN1") PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_COIN1 ) @@ -2273,20 +2324,20 @@ void _8080bw_state::ballbomb(machine_config &config) /* */ /*******************************************************/ -void _8080bw_state::yosakdon_map(address_map &map) +void yosakdon_state::main_map(address_map &map) { map(0x0000, 0x1fff).rom(); map(0x2000, 0x3fff).ram().share("main_ram"); - map(0x4000, 0x43ff).nopw(); /* what's this? */ + map(0x4000, 0x43ff).nopw(); // what's this? } -void _8080bw_state::yosakdon_io_map(address_map &map) +void yosakdon_state::io_map(address_map &map) { map(0x01, 0x01).portr("IN0"); map(0x02, 0x02).portr("IN1"); - map(0x03, 0x03).w(FUNC(_8080bw_state::yosakdon_sh_port_1_w)); - map(0x05, 0x05).w(FUNC(_8080bw_state::yosakdon_sh_port_2_w)); - map(0x06, 0x06).nopw(); /* character numbers */ + map(0x03, 0x03).w(FUNC(yosakdon_state::sh_port_1_w)); + map(0x05, 0x05).w(FUNC(yosakdon_state::sh_port_2_w)); + map(0x06, 0x06).nopw(); // character numbers } @@ -2296,7 +2347,7 @@ static INPUT_PORTS_START( yosakdon ) PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_START2 ) PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_START1 ) PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_UNKNOWN ) - 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(yosakdon_state, invaders_in1_control_r) PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_UNUSED ) PORT_START("IN1") @@ -2311,34 +2362,41 @@ static INPUT_PORTS_START( yosakdon ) PORT_DIPNAME( 0x08, 0x00, DEF_STR( Unknown ) ) PORT_DIPSETTING( 0x08, DEF_STR( Off ) ) PORT_DIPSETTING( 0x00, DEF_STR( On ) ) - 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(yosakdon_state, invaders_in2_control_r) PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_UNUSED ) - /* Dummy controls port, P1 */ + // Dummy controls port, P1 INVADERS_CONTROL_PORT_P1 - /* Dummy controls port, P2 */ + // Dummy controls port, P2 INVADERS_CONTROL_PORT_P2 - /* Dummy port for cocktail mode */ + // Dummy port for cocktail mode INVADERS_CAB_TYPE_PORT INPUT_PORTS_END -void _8080bw_state::yosakdon(machine_config &config) +void yosakdon_state::machine_start() +{ + invaders_clone_state::machine_start(); + + save_item(NAME(m_port_1_last)); + save_item(NAME(m_port_2_last)); +} + +void yosakdon_state::yosakdon(machine_config &config) { mw8080bw_root(config); - /* basic machine hardware */ - m_maincpu->set_addrmap(AS_PROGRAM, &_8080bw_state::yosakdon_map); - m_maincpu->set_addrmap(AS_IO, &_8080bw_state::yosakdon_io_map); - MCFG_MACHINE_START_OVERRIDE(_8080bw_state,extra_8080bw) + // basic machine hardware + m_maincpu->set_addrmap(AS_PROGRAM, &yosakdon_state::main_map); + m_maincpu->set_addrmap(AS_IO, &yosakdon_state::io_map); - /* sound hardware */ + // sound hardware invaders_samples_audio(config); - /* video hardware */ - m_screen->set_screen_update(FUNC(_8080bw_state::screen_update_invaders)); + // video hardware + m_screen->set_screen_update(FUNC(yosakdon_state::screen_update_invaders)); } @@ -2346,7 +2404,7 @@ void _8080bw_state::yosakdon(machine_config &config) /*******************************************************/ /* */ /* Taito "Indian battle" */ -/* In "indianbtbr", the "number of animals" dipswitch */ +/* In "indianbtbr", the "number of animals" DIP switch */ /* is ineffective because they compare for 8 kills at */ /* 0x811, which is not possible. This byte should be */ /* 0x03. */ @@ -2359,9 +2417,7 @@ static INPUT_PORTS_START( indianbt ) PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_START2 ) PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_START1 ) PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_UNKNOWN ) - PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_BUTTON1 ) - PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_JOYSTICK_LEFT ) PORT_2WAY - PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_JOYSTICK_RIGHT ) PORT_2WAY + PORT_BIT( 0x70, IP_ACTIVE_HIGH, IPT_CUSTOM ) PORT_CUSTOM_MEMBER(invaders_state, invaders_in1_control_r) PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_UNKNOWN ) PORT_START("IN2") @@ -2374,18 +2430,24 @@ static INPUT_PORTS_START( indianbt ) PORT_DIPNAME( 0x08, 0x00, "Number of Catch Animals" ) PORT_DIPSETTING( 0x00, "6" ) PORT_DIPSETTING( 0x08, "3" ) - PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_BUTTON1 ) PORT_PLAYER(2) - PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_JOYSTICK_LEFT ) PORT_2WAY PORT_PLAYER(2) - PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_JOYSTICK_RIGHT ) PORT_2WAY PORT_PLAYER(2) + PORT_BIT( 0x70, IP_ACTIVE_HIGH, IPT_CUSTOM ) PORT_CUSTOM_MEMBER(invaders_state, invaders_in2_control_r) PORT_DIPNAME(0x80, 0x00, "Invulnerability (Cheat)") PORT_DIPSETTING( 0x00, DEF_STR( Off ) ) PORT_DIPSETTING( 0x80, DEF_STR( On ) ) - /* Dummy port for cocktail mode */ + // P1 controls (read via IN1, and also via IN2 on upright cabinets) + INVADERS_CONTROL_PORT_P1 + + // P2 controls on cocktail cabinet (read via IN2) + INVADERS_CONTROL_PORT_P2 + + // Dummy port for cocktail mode INVADERS_CAB_TYPE_PORT INPUT_PORTS_END static INPUT_PORTS_START( indianbtbr ) + PORT_INCLUDE( indianbt ) + PORT_START("IN0") PORT_DIPNAME( 0x03, 0x00, DEF_STR( Lives ) ) PORT_DIPSETTING( 0x00, "3" ) @@ -2399,30 +2461,14 @@ static INPUT_PORTS_START( indianbtbr ) PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_UNUSED ) PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_UNKNOWN ) //Length of manufacturer's logo (0x11 or 0x16) - PORT_START("IN1") - PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_COIN1 ) - PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_START2 ) - PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_START1 ) - PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_UNKNOWN ) - PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_BUTTON1 ) - PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_JOYSTICK_LEFT ) PORT_2WAY - PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_JOYSTICK_RIGHT ) PORT_2WAY - PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_UNKNOWN ) - - PORT_START("IN2") + PORT_MODIFY("IN2") PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_UNUSED ) PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_UNUSED ) PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_UNUSED ) PORT_DIPNAME(0x08, 0x00, "Invulnerability (Cheat)") PORT_DIPSETTING( 0x00, DEF_STR( Off ) ) PORT_DIPSETTING( 0x08, DEF_STR( On ) ) - PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_BUTTON1 ) PORT_PLAYER(2) - PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_JOYSTICK_LEFT ) PORT_2WAY PORT_PLAYER(2) - PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_JOYSTICK_RIGHT ) PORT_2WAY PORT_PLAYER(2) PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_UNKNOWN ) - - /* Dummy port for cocktail mode */ - INVADERS_CAB_TYPE_PORT INPUT_PORTS_END @@ -2458,18 +2504,21 @@ uint8_t _8080bw_state::indianbt_r() return machine().rand(); } -uint8_t _8080bw_state::indianbtbr_01_r() +uint8_t _8080bw_state::indianbt_01_r() { + // this is a hack - how are you supposed to get the game to read P2 inputs properly? uint8_t data = ioport("IN1")->read(); - if (!m_flip_screen) return data; - return (data & 0x8f) | (ioport("IN2")->read() & 0x70); + if (!m_flip_screen) + return data; + else + return (data & 0x8f) | (ioport("IN2")->read() & 0x70); } void _8080bw_state::indianbt_io_map(address_map &map) { map(0x00, 0x00).r(FUNC(_8080bw_state::indianbt_r)); - map(0x01, 0x01).portr("IN1"); - map(0x02, 0x02).r(FUNC(_8080bw_state::invrvnge_02_r)).w(m_mb14241, FUNC(mb14241_device::shift_count_w)); + map(0x01, 0x01).r(FUNC(_8080bw_state::indianbt_01_r)); + map(0x02, 0x02).portr("IN2").w(m_mb14241, FUNC(mb14241_device::shift_count_w)); map(0x03, 0x03).r(m_mb14241, FUNC(mb14241_device::shift_result_r)).w(FUNC(_8080bw_state::indianbt_sh_port_1_w)); map(0x04, 0x04).w(m_mb14241, FUNC(mb14241_device::shift_data_w)); map(0x05, 0x05).w(FUNC(_8080bw_state::indianbt_sh_port_2_w)); @@ -2480,7 +2529,7 @@ void _8080bw_state::indianbt_io_map(address_map &map) void _8080bw_state::indianbtbr_io_map(address_map &map) { map(0x00, 0x00).portr("IN0"); - map(0x01, 0x01).r(FUNC(_8080bw_state::indianbtbr_01_r)); + map(0x01, 0x01).r(FUNC(_8080bw_state::indianbt_01_r)); map(0x02, 0x02).portr("IN2").w(m_mb14241, FUNC(mb14241_device::shift_count_w)); map(0x03, 0x03).r(m_mb14241, FUNC(mb14241_device::shift_result_r)).w(FUNC(_8080bw_state::indianbtbr_sh_port_1_w)); map(0x04, 0x04).w(m_mb14241, FUNC(mb14241_device::shift_data_w)); @@ -2554,7 +2603,7 @@ void _8080bw_state::steelwkr_sh_port_3_w(uint8_t data) void _8080bw_state::steelwkr_io_map(address_map &map) { map(0x01, 0x01).portr("IN1"); - map(0x02, 0x02).r(FUNC(_8080bw_state::invrvnge_02_r)).w(m_mb14241, FUNC(mb14241_device::shift_count_w)); + map(0x02, 0x02).portr("IN2").w(m_mb14241, FUNC(mb14241_device::shift_count_w)); map(0x03, 0x03).r(m_mb14241, FUNC(mb14241_device::shift_result_r)).w(FUNC(_8080bw_state::invadpt2_sh_port_1_w)); map(0x04, 0x04).w(m_mb14241, FUNC(mb14241_device::shift_data_w)); map(0x05, 0x05).w(FUNC(_8080bw_state::invadpt2_sh_port_2_w)); @@ -2562,17 +2611,14 @@ void _8080bw_state::steelwkr_io_map(address_map &map) } static INPUT_PORTS_START( steelwkr ) - /* PORT_START("IN0") - never read */ + // PORT_START("IN0") - never read PORT_START("IN1") PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_COIN1 ) PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_START2 ) PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_START1 ) PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_UNKNOWN ) - PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_BUTTON1 ) - PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_JOYSTICK_LEFT ) PORT_2WAY - PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_JOYSTICK_RIGHT ) PORT_2WAY - PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_BUTTON2 ) + PORT_BIT( 0xf0, IP_ACTIVE_HIGH, IPT_CUSTOM ) PORT_CUSTOM_MEMBER(invaders_state, invaders_in1_control_r) PORT_START("IN2") PORT_DIPNAME( 0x03, 0x02, DEF_STR( Lives ) ) PORT_DIPLOCATION("SW1:1,2") @@ -2582,12 +2628,17 @@ static INPUT_PORTS_START( steelwkr ) PORT_DIPSETTING( 0x03, "4" ) PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_TILT ) PORT_DIPLOCATION("SW1:3") PORT_DIPUNKNOWN_DIPLOC( 0x08, 0x00, "SW1:4" ) - PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_BUTTON1 ) PORT_PLAYER(2) - PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_JOYSTICK_LEFT ) PORT_2WAY PORT_PLAYER(2) - PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_JOYSTICK_RIGHT ) PORT_2WAY PORT_PLAYER(2) - PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_BUTTON2 ) PORT_PLAYER(2) + PORT_BIT( 0xf0, IP_ACTIVE_HIGH, IPT_CUSTOM ) PORT_CUSTOM_MEMBER(invaders_state, invaders_in2_control_r) - /* Dummy port for cocktail mode */ + // P1 controls (read via IN1, and also via IN2 on upright cabinets) + INVADERS_CONTROL_PORT_P1 + PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_BUTTON2 ) PORT_PLAYER(1) + + // P2 controls (read via IN2, and also via IN1 on upright cabinets) + INVADERS_CONTROL_PORT_P2 + PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_BUTTON2 ) PORT_PLAYER(2) + + // Dummy port for cocktail mode INVADERS_CAB_TYPE_PORT INPUT_PORTS_END @@ -2776,14 +2827,16 @@ static INPUT_PORTS_START( skylove ) INVADERS_CAB_TYPE_PORT INPUT_PORTS_END -uint8_t _8080bw_state::shuttlei_ff_r() +uint8_t shuttlei_state::port_ff_r() { - uint8_t data = ioport("INPUTS")->read(); - if (!m_flip_screen) return data; - return (data & 0x3b) | ioport("P2")->read(); + uint8_t data = m_inputs->read(); + if (!m_flip_screen) + return data; + else + return (data & 0x3b) | m_p2->read(); } -void _8080bw_state::shuttlei_ff_w(uint8_t data) +void shuttlei_state::port_ff_w(uint8_t data) { /* bit 0 goes high when first coin inserted bit 1 also goes high when subsequent coins are inserted @@ -2793,7 +2846,7 @@ void _8080bw_state::shuttlei_ff_w(uint8_t data) m_flip_screen = BIT(data, 2) & BIT(ioport(CABINET_PORT_TAG)->read(), 0); } -void _8080bw_state::shuttlei_map(address_map &map) +void shuttlei_state::main_map(address_map &map) { map(0x0000, 0x1fff).rom(); map(0x2000, 0x37ff).ram().share("main_ram"); @@ -2802,27 +2855,31 @@ void _8080bw_state::shuttlei_map(address_map &map) map(0x6000, 0x63ff).ram().share("share1"); // skylove (is it mirrored, or different PCB hookup?) } -void _8080bw_state::shuttlei_io_map(address_map &map) +void shuttlei_state::io_map(address_map &map) { - map(0xfc, 0xfc).nopw(); /* game writes 0xAA every so often (perhaps when base hit?) */ - map(0xfd, 0xfd).w(FUNC(_8080bw_state::shuttlei_sh_port_1_w)); - map(0xfe, 0xfe).portr("DSW").w(FUNC(_8080bw_state::shuttlei_sh_port_2_w)); - map(0xff, 0xff).rw(FUNC(_8080bw_state::shuttlei_ff_r), FUNC(_8080bw_state::shuttlei_ff_w)); + map(0xfc, 0xfc).nopw(); // game writes 0xAA every so often (perhaps when base hit?) + map(0xfd, 0xfd).w(FUNC(shuttlei_state::sh_port_1_w)); + map(0xfe, 0xfe).portr("DSW").w(FUNC(shuttlei_state::sh_port_2_w)); + map(0xff, 0xff).rw(FUNC(shuttlei_state::port_ff_r), FUNC(shuttlei_state::port_ff_w)); +} + +void shuttlei_state::machine_start() +{ + invaders_clone_state::machine_start(); + + save_item(NAME(m_port_1_last)); } -void _8080bw_state::shuttlei(machine_config &config) +void shuttlei_state::shuttlei(machine_config &config) { /* basic machine hardware */ i8080_cpu_device &maincpu(I8080(config, m_maincpu, XTAL(18'000'000) / 9)); // TODO: move irq handling away from mw8080.cpp, this game runs on custom hardware - maincpu.set_addrmap(AS_PROGRAM, &_8080bw_state::shuttlei_map); - maincpu.set_addrmap(AS_IO, &_8080bw_state::shuttlei_io_map); - maincpu.set_irq_acknowledge_callback(FUNC(_8080bw_state::interrupt_vector)); - maincpu.out_inte_func().set(FUNC(_8080bw_state::int_enable_w)); - - MCFG_MACHINE_START_OVERRIDE(_8080bw_state, extra_8080bw) - MCFG_MACHINE_RESET_OVERRIDE(_8080bw_state, mw8080bw) + maincpu.set_addrmap(AS_PROGRAM, &shuttlei_state::main_map); + maincpu.set_addrmap(AS_IO, &shuttlei_state::io_map); + maincpu.set_irq_acknowledge_callback(FUNC(shuttlei_state::interrupt_vector)); + maincpu.out_inte_func().set(FUNC(shuttlei_state::int_enable_w)); /* video hardware */ SCREEN(config, m_screen, SCREEN_TYPE_RASTER); @@ -2830,7 +2887,7 @@ void _8080bw_state::shuttlei(machine_config &config) m_screen->set_vblank_time(ATTOSECONDS_IN_USEC(2500)); m_screen->set_size(32*8, 32*8); m_screen->set_visarea(0*8, 32*8-1, 0*8, 24*8-1); - m_screen->set_screen_update(FUNC(_8080bw_state::screen_update_shuttlei)); + m_screen->set_screen_update(FUNC(shuttlei_state::screen_update_shuttlei)); PALETTE(config, m_palette, palette_device::MONOCHROME); @@ -2863,55 +2920,50 @@ Another (same checksums) dump came from board labeled SI-7811M-2 */ -MACHINE_START_MEMBER(_8080bw_state,darthvdr) +void darthvdr_state::machine_start() { - /* do nothing for now - different interrupt system */ + // don't call base member for now - different interrupt system + m_fleet_step = 3; + + save_item(NAME(m_port_1_last)); + save_item(NAME(m_fleet_step)); } -MACHINE_RESET_MEMBER(_8080bw_state,darthvdr) +void darthvdr_state::machine_reset() { - /* do nothing for now - different interrupt system */ + // don't call base member for now - different interrupt system } -IRQ_CALLBACK_MEMBER(_8080bw_state::darthvdr_interrupt_vector) +IRQ_CALLBACK_MEMBER(darthvdr_state::darthvdr_interrupt_vector) { m_maincpu->set_input_line(0, CLEAR_LINE); return 0xff; } -uint8_t _8080bw_state::darthvdr_01_r() -{ - uint8_t data = ioport("P2")->read(); - if (m_flip_screen) return data; - return (data & 0xe1) | (ioport("P1")->read() & 0x0e); -} - -void _8080bw_state::darthvdr_map(address_map &map) +void darthvdr_state::main_map(address_map &map) { map(0x0000, 0x17ff).rom(); map(0x1800, 0x1fff).ram(); map(0x4000, 0x5fff).ram().share("main_ram"); } -void _8080bw_state::darthvdr_io_map(address_map &map) +void darthvdr_state::io_map(address_map &map) { map(0x00, 0x00).portr("P1"); - map(0x01, 0x01).r(FUNC(_8080bw_state::darthvdr_01_r)); + map(0x01, 0x01).portr("P2"); - map(0x00, 0x00).w(FUNC(_8080bw_state::darthvdr_00_w)); // flipscreen + map(0x00, 0x00).w(FUNC(darthvdr_state::darthvdr_00_w)); // flipscreen map(0x04, 0x04).nopw(); - map(0x08, 0x08).w(FUNC(_8080bw_state::darthvdr_08_w)); // sound + map(0x08, 0x08).w(FUNC(darthvdr_state::darthvdr_08_w)); // sound } static INPUT_PORTS_START( darthvdr ) PORT_START("P1") PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_START1 ) - PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_BUTTON1 ) - PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_JOYSTICK_LEFT ) PORT_2WAY - PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_JOYSTICK_RIGHT ) PORT_2WAY + PORT_BIT( 0x0e, IP_ACTIVE_LOW, IPT_CUSTOM ) PORT_CUSTOM_MEMBER(invaders_state, invaders_in1_control_r) PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_COIN1 ) PORT_DIPNAME( 0x20, 0x20, DEF_STR( Bonus_Life ) ) PORT_DIPSETTING( 0x00, "1000" ) @@ -2920,14 +2972,14 @@ static INPUT_PORTS_START( darthvdr ) PORT_DIPSETTING( 0x40, DEF_STR( Off ) ) PORT_DIPSETTING( 0x00, DEF_STR( On ) ) PORT_DIPNAME( 0x80, 0x00, DEF_STR( Lives ) ) - PORT_DIPSETTING( 0x00, "4" ) - PORT_DIPSETTING( 0x80, "6" ) + PORT_DIPSETTING( 0x00, "3" ) PORT_CONDITION("P2", 0x10, EQUALS, 0x00) + PORT_DIPSETTING( 0x80, "5" ) PORT_CONDITION("P2", 0x10, EQUALS, 0x00) + PORT_DIPSETTING( 0x00, "4" ) PORT_CONDITION("P2", 0x10, EQUALS, 0x10) + PORT_DIPSETTING( 0x80, "6" ) PORT_CONDITION("P2", 0x10, EQUALS, 0x10) PORT_START("P2") PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_START2 ) - PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_BUTTON1 ) PORT_PLAYER(2) - PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_JOYSTICK_LEFT ) PORT_2WAY PORT_PLAYER(2) - PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_JOYSTICK_RIGHT ) PORT_2WAY PORT_PLAYER(2) + PORT_BIT( 0x0e, IP_ACTIVE_LOW, IPT_CUSTOM ) PORT_CUSTOM_MEMBER(invaders_state, invaders_in2_control_r) PORT_DIPNAME( 0x10, 0x10, "One less life" ) PORT_DIPSETTING( 0x10, DEF_STR( Off ) ) PORT_DIPSETTING( 0x00, DEF_STR( On ) ) @@ -2941,27 +2993,30 @@ static INPUT_PORTS_START( darthvdr ) PORT_DIPSETTING( 0x80, DEF_STR( Off ) ) PORT_DIPSETTING( 0x00, DEF_STR( On ) ) - /* Dummy port for cocktail mode */ + // P1 controls (read via IN1, and also via IN2 on upright cabinets) + INVADERS_CONTROL_PORT_P1 + + // P2 controls on cocktail cabinet (read via IN2) + INVADERS_CONTROL_PORT_P2 + + // Dummy port for cocktail mode INVADERS_CAB_TYPE_PORT INPUT_PORTS_END -void _8080bw_state::darthvdr(machine_config &config) +void darthvdr_state::darthvdr(machine_config &config) { mw8080bw_root(config); - /* basic machine hardware */ - m_maincpu->set_addrmap(AS_PROGRAM, &_8080bw_state::darthvdr_map); - m_maincpu->set_addrmap(AS_IO, &_8080bw_state::darthvdr_io_map); - m_maincpu->set_irq_acknowledge_callback(FUNC(_8080bw_state::darthvdr_interrupt_vector)); - - MCFG_MACHINE_START_OVERRIDE(_8080bw_state,darthvdr) - MCFG_MACHINE_RESET_OVERRIDE(_8080bw_state,darthvdr) + // basic machine hardware + m_maincpu->set_addrmap(AS_PROGRAM, &darthvdr_state::main_map); + m_maincpu->set_addrmap(AS_IO, &darthvdr_state::io_map); + m_maincpu->set_irq_acknowledge_callback(FUNC(darthvdr_state::darthvdr_interrupt_vector)); /* sound hardware */ invaders_samples_audio(config); /* video hardware */ - m_screen->set_screen_update(FUNC(_8080bw_state::screen_update_invaders)); + m_screen->set_screen_update(FUNC(darthvdr_state::screen_update_invaders)); m_screen->screen_vblank().set_inputline(m_maincpu, 0, ASSERT_LINE); } @@ -2971,7 +3026,7 @@ void _8080bw_state::darthvdr(machine_config &config) * * Vortex (by Zilec AKA Zenitone-Microsec) * Runs on Space Invaders CV (color)/PV (part 2) board with - * some color mods, and an epoxy brick for rom encryption + * some color mods, and an epoxy brick for ROM encryption * see below for decryption function (A0, A3, A9 invert) * It uses its own I/O function since A9 is inverted (and A9 mirrors A1 for I/O) * @@ -2979,10 +3034,11 @@ void _8080bw_state::darthvdr(machine_config &config) * *************************************/ -void _8080bw_state::vortex_io_map(address_map &map) +void vortex_state::io_map(address_map &map) { // I/O map is same as invaders but with A9 (used as A1 for I/O) inverted - map.global_mask(0xFF); + map.global_mask(0xff); + map(0x02, 0x02).mirror(0x04).portr("IN0"); map(0x03, 0x03).mirror(0x04).portr("IN1"); map(0x00, 0x00).mirror(0x04).portr("IN2"); @@ -2997,7 +3053,7 @@ void _8080bw_state::vortex_io_map(address_map &map) static INPUT_PORTS_START( vortex ) - PORT_INCLUDE( sicv ) + PORT_INCLUDE( sicv_base ) PORT_MODIFY("IN1") PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_UNKNOWN ) @@ -3020,30 +3076,33 @@ static INPUT_PORTS_START( vortex ) PORT_DIPSETTING( 0x80, DEF_STR( 1C_1C ) ) INPUT_PORTS_END -void _8080bw_state::vortex(machine_config &config) +void vortex_state::vortex(machine_config &config) { mw8080bw_root(config); - /* basic machine hardware */ - m_maincpu->set_addrmap(AS_IO, &_8080bw_state::vortex_io_map); - - MCFG_MACHINE_START_OVERRIDE(_8080bw_state,extra_8080bw) + // basic machine hardware + m_maincpu->set_addrmap(AS_IO, &vortex_state::io_map); WATCHDOG_TIMER(config, m_watchdog).set_time(attotime::from_usec(255000000 / (MW8080BW_PIXEL_CLOCK / MW8080BW_HTOTAL / MW8080BW_VTOTAL))); /* video hardware */ - m_screen->set_screen_update(FUNC(_8080bw_state::screen_update_vortex)); + m_screen->set_screen_update(FUNC(vortex_state::screen_update_vortex)); /* 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; }); + // audio hardware + 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; + }); } /* decrypt function for vortex */ -void _8080bw_state::init_vortex() +void vortex_state::init_vortex() { uint8_t *rom = memregion("maincpu")->base(); int length = memregion("maincpu")->bytes(); @@ -3216,18 +3275,18 @@ Claybuster is on the same hardware, PCB labels CS 235A and CS 238A as well */ -TIMER_DEVICE_CALLBACK_MEMBER(_8080bw_state::claybust_gun_callback) +TIMER_DEVICE_CALLBACK_MEMBER(claybust_state::gun_callback) { // reset gun latch - m_claybust_gun_pos = 0; + m_gun_pos = 0; } -READ_LINE_MEMBER(_8080bw_state::claybust_gun_on_r) +READ_LINE_MEMBER(claybust_state::gun_on_r) { - return (m_claybust_gun_pos != 0) ? 1 : 0; + return m_gun_pos ? 1 : 0; } -INPUT_CHANGED_MEMBER(_8080bw_state::claybust_gun_trigger) +INPUT_CHANGED_MEMBER(claybust_state::gun_trigger) { if (newval) { @@ -3249,39 +3308,39 @@ INPUT_CHANGED_MEMBER(_8080bw_state::claybust_gun_trigger) ana a rz */ - uint8_t const gunx = m_gunx.read_safe(0x00); - uint8_t const guny = m_guny.read_safe(0x20); - m_claybust_gun_pos = ((gunx >> 3) | (guny << 5)) + 2; - m_claybust_gun_on->adjust(attotime::from_msec(250)); // timing is a guess + uint8_t const gunx = m_gunx->read(); + uint8_t const guny = m_guny->read(); + m_gun_pos = ((gunx >> 3) | (guny << 5)) + 2; + m_gun_on->adjust(attotime::from_msec(250)); // timing is a guess } } -uint8_t _8080bw_state::claybust_gun_lo_r() +uint8_t claybust_state::gun_lo_r() { - return m_claybust_gun_pos & 0xff; + return m_gun_pos & 0xff; } -uint8_t _8080bw_state::claybust_gun_hi_r() +uint8_t claybust_state::gun_hi_r() { - return m_claybust_gun_pos >> 8; + return m_gun_pos >> 8; } -void _8080bw_state::claybust_io_map(address_map &map) +void claybust_state::io_map(address_map &map) { //map(0x00, 0x00).nopw(); // ? map(0x01, 0x01).portr("IN1").w(m_mb14241, FUNC(mb14241_device::shift_count_w)); - map(0x02, 0x02).r(FUNC(_8080bw_state::claybust_gun_lo_r)).w(m_mb14241, FUNC(mb14241_device::shift_data_w)); + map(0x02, 0x02).r(FUNC(claybust_state::gun_lo_r)).w(m_mb14241, FUNC(mb14241_device::shift_data_w)); map(0x03, 0x03).r(m_mb14241, FUNC(mb14241_device::shift_result_r)); //.nopw(); // port3 write looks sound-related map(0x04, 0x04).w(m_watchdog, FUNC(watchdog_timer_device::reset_w)); //map(0x05, 0x05).nopw(); // ? - map(0x06, 0x06).r(FUNC(_8080bw_state::claybust_gun_hi_r)); + map(0x06, 0x06).r(FUNC(claybust_state::gun_hi_r)); } static INPUT_PORTS_START( claybust ) PORT_START("IN1") - PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_CUSTOM ) PORT_READ_LINE_MEMBER(_8080bw_state, claybust_gun_on_r) - PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_BUTTON1 ) PORT_IMPULSE(2) PORT_CHANGED_MEMBER(DEVICE_SELF, _8080bw_state, claybust_gun_trigger, 0) + PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_CUSTOM ) PORT_READ_LINE_MEMBER(claybust_state, gun_on_r) + PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_BUTTON1 ) PORT_IMPULSE(2) PORT_CHANGED_MEMBER(DEVICE_SELF, claybust_state, gun_trigger, 0) PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_COIN1 ) PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_START1 ) @@ -3322,24 +3381,23 @@ static INPUT_PORTS_START( gunchamp ) INPUT_PORTS_END -MACHINE_START_MEMBER(_8080bw_state, claybust) +void claybust_state::machine_start() { - mw8080bw_state::machine_start(); + invaders_state::machine_start(); - m_claybust_gun_pos = 0; - save_item(NAME(m_claybust_gun_pos)); + m_gun_pos = 0; + + save_item(NAME(m_gun_pos)); } -void _8080bw_state::claybust(machine_config &config) +void claybust_state::claybust(machine_config &config) { invaders(config); /* basic machine hardware */ - m_maincpu->set_addrmap(AS_IO, &_8080bw_state::claybust_io_map); - - TIMER(config, "claybust_gun").configure_generic(FUNC(_8080bw_state::claybust_gun_callback)); + m_maincpu->set_addrmap(AS_IO, &claybust_state::io_map); - MCFG_MACHINE_START_OVERRIDE(_8080bw_state, claybust) + TIMER(config, "claybust_gun").configure_generic(FUNC(claybust_state::gun_callback)); /* sound hardware */ // TODO: discrete sound @@ -3374,7 +3432,7 @@ static INPUT_PORTS_START( galactic ) PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_START2 ) PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_START1 ) PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_UNKNOWN ) - 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_UNKNOWN ) PORT_START("IN2") @@ -3389,7 +3447,7 @@ static INPUT_PORTS_START( galactic ) PORT_DIPNAME( 0x08, 0x00, DEF_STR( Lives ) ) PORT_DIPSETTING( 0x00, "3" ) PORT_DIPSETTING( 0x08, "6" ) - 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_BIT( 0x80, IP_ACTIVE_HIGH, IPT_UNKNOWN ) /* Dummy controls port, P1 */ @@ -3525,17 +3583,17 @@ static INPUT_PORTS_START( invmulti ) /* same as Midway Space Invaders, except that SW is unused */ PORT_START("IN0") PORT_DIPUNUSED_DIPLOC( 0x01, 0x00, "SW:8" ) - 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(invmulti_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(invmulti_state, invaders_in0_control_r) + PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_CUSTOM ) PORT_CUSTOM_MEMBER(invmulti_state, invaders_sw5_r) PORT_START("IN1") - PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_COIN1 ) PORT_CHANGED_MEMBER(DEVICE_SELF, mw8080bw_state, direct_coin_count, 0) + PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_COIN1 ) PORT_CHANGED_MEMBER(DEVICE_SELF, invmulti_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(invmulti_state, invaders_in1_control_r) PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_UNUSED ) PORT_START("IN2") @@ -3543,7 +3601,7 @@ static INPUT_PORTS_START( invmulti ) PORT_DIPUNUSED_DIPLOC( 0x02, 0x00, "SW:4" ) PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_UNUSED ) PORT_DIPUNUSED_DIPLOC( 0x08, 0x00, "SW:2" ) - 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(invmulti_state, invaders_in2_control_r) PORT_DIPUNUSED_DIPLOC( 0x80, 0x00, "SW:1" ) /* Dummy port for cocktail mode */ @@ -3567,66 +3625,69 @@ static INPUT_PORTS_START( invmulti ) INPUT_PORTS_END -void _8080bw_state::invmulti_map(address_map &map) +void invmulti_state::main_map(address_map &map) { - map(0x0000, 0x1fff).mirror(0x8000).bankr("bank1"); + map(0x0000, 0x1fff).mirror(0x8000).bankr(m_banks[0]); map(0x2000, 0x3fff).mirror(0x8000).ram().share("main_ram"); - map(0x4000, 0x5fff).mirror(0x8000).bankr("bank2"); - map(0x6000, 0x6000).mirror(0x1fff).rw(FUNC(_8080bw_state::invmulti_eeprom_r), FUNC(_8080bw_state::invmulti_eeprom_w)); - map(0xe000, 0xe000).mirror(0x1fff).w(FUNC(_8080bw_state::invmulti_bank_w)); + map(0x4000, 0x5fff).mirror(0x8000).bankr(m_banks[1]); + map(0x6000, 0x6000).mirror(0x1fff).rw(FUNC(invmulti_state::eeprom_r), FUNC(invmulti_state::eeprom_w)); + map(0xe000, 0xe000).mirror(0x1fff).w(FUNC(invmulti_state::bank_w)); } -uint8_t _8080bw_state::invmulti_eeprom_r() +uint8_t invmulti_state::eeprom_r() { return m_eeprom->do_read(); } -void _8080bw_state::invmulti_eeprom_w(uint8_t data) +void invmulti_state::eeprom_w(uint8_t data) { // d0: latch bit - m_eeprom->di_write(data & 1); + m_eeprom->di_write(BIT(data, 0)); // d6: reset - m_eeprom->cs_write((data & 0x40) ? ASSERT_LINE : CLEAR_LINE); + m_eeprom->cs_write(BIT(data, 6)); // d4: write latch or select next bit to read - m_eeprom->clk_write((data & 0x10) ? ASSERT_LINE : CLEAR_LINE); + m_eeprom->clk_write(BIT(data, 4)); } -void _8080bw_state::invmulti_bank_w(uint8_t data) +void invmulti_state::bank_w(uint8_t data) { // d0, d4, d6: bank - int bank = (data & 1) | (data >> 3 & 2) | (data >> 4 & 4); - membank("bank1")->set_entry(bank); - membank("bank2")->set_entry(bank); + uint8_t const bank = bitswap<3>(data, 6, 4, 0); + m_banks[0]->set_entry(bank); + m_banks[1]->set_entry(bank); } -void _8080bw_state::invmulti(machine_config &config) +void invmulti_state::invmulti(machine_config &config) { invaders(config); - /* basic machine hardware */ - m_maincpu->set_addrmap(AS_PROGRAM, &_8080bw_state::invmulti_map); + // basic machine hardware + m_maincpu->set_addrmap(AS_PROGRAM, &invmulti_state::main_map); EEPROM_93C46_8BIT(config, m_eeprom); +} - MCFG_MACHINE_RESET_OVERRIDE(_8080bw_state, mw8080bw) +void invmulti_state::machine_start() +{ + invaders_state::machine_start(); + + m_banks[0]->configure_entries(0, 8, memregion("maincpu")->base(), 0x4000); + m_banks[0]->set_entry(0); + m_banks[1]->configure_entries(0, 8, memregion("maincpu")->base() + 0x2000, 0x4000); + m_banks[1]->set_entry(0); } -void _8080bw_state::init_invmulti() +void invmulti_state::init_invmulti() { - uint8_t *src = memregion("user1")->base(); - int len = memregion("user1")->bytes(); - uint8_t *dest = memregion("maincpu")->base(); + uint8_t const *const src = memregion("user1")->base(); + auto const len = memregion("user1")->bytes(); + uint8_t *const dest = memregion("maincpu")->base(); - // decrypt rom + // unscramble ROM for (int i = 0; i < len; i++) dest[i] = bitswap<8>(src[(i & 0x100ff) | (bitswap<8>(i >> 8 & 0xff, 7,3,4,5,0,6,1,2) << 8)],0,6,5,7,4,3,1,2); - - membank("bank1")->configure_entries(0, 8, memregion("maincpu")->base(), 0x4000); - membank("bank1")->set_entry(0); - membank("bank2")->configure_entries(0, 8, memregion("maincpu")->base() + 0x2000, 0x4000); - membank("bank2")->set_entry(0); } @@ -4018,7 +4079,7 @@ INPUT_PORTS_END void orbite_state::machine_start() { - _8080bw_state::machine_start(); + invaders_clone_palette_state::machine_start(); m_scattered_colorram = std::make_unique(0x800); save_pointer(&m_scattered_colorram[0], "m_scattered_colorram", 0x800); @@ -5736,60 +5797,60 @@ ROM_END // year rom parent machine inp class init monitor ... // Taito games (+clones), starting with Space Invaders -GAME( 1978, sisv1, invaders, invaders, sitv, mw8080bw_state, empty_init, ROT270, "Taito", "Space Invaders (SV Version rev 1)", MACHINE_NOT_WORKING | MACHINE_IMPERFECT_SOUND | MACHINE_SUPPORTS_SAVE ) -GAME( 1978, sisv2, invaders, invaders, sitv, mw8080bw_state, empty_init, ROT270, "Taito", "Space Invaders (SV Version rev 2)", MACHINE_IMPERFECT_SOUND | MACHINE_SUPPORTS_SAVE ) -GAME( 1978, sisv3, invaders, invaders, sitv, mw8080bw_state, empty_init, ROT270, "Taito", "Space Invaders (SV Version rev 3)", MACHINE_IMPERFECT_SOUND | MACHINE_SUPPORTS_SAVE ) -GAME( 1978, sisv, invaders, invaders, sitv, mw8080bw_state, empty_init, ROT270, "Taito", "Space Invaders (SV Version rev 4)", MACHINE_IMPERFECT_SOUND | MACHINE_SUPPORTS_SAVE ) -GAMEL(1978, sitv1, invaders, invaders, sitv, mw8080bw_state, empty_init, ROT270, "Taito", "Space Invaders (TV Version rev 1)", MACHINE_SUPPORTS_SAVE, layout_invaders ) -GAMEL(1978, sitv, invaders, invaders, sitv, mw8080bw_state, empty_init, ROT270, "Taito", "Space Invaders (TV Version rev 2)", MACHINE_SUPPORTS_SAVE, layout_invaders ) +GAME( 1978, sisv1, invaders, invaders, sitv, sisv_state, empty_init, ROT270, "Taito", "Space Invaders (SV Version rev 1)", MACHINE_NOT_WORKING | MACHINE_IMPERFECT_SOUND | MACHINE_SUPPORTS_SAVE ) +GAME( 1978, sisv2, invaders, invaders, sitv, sisv_state, empty_init, ROT270, "Taito", "Space Invaders (SV Version rev 2)", MACHINE_IMPERFECT_SOUND | MACHINE_SUPPORTS_SAVE ) +GAME( 1978, sisv3, invaders, invaders, sitv, sisv_state, empty_init, ROT270, "Taito", "Space Invaders (SV Version rev 3)", MACHINE_IMPERFECT_SOUND | MACHINE_SUPPORTS_SAVE ) +GAME( 1978, sisv, invaders, invaders, sitv, sisv_state, empty_init, ROT270, "Taito", "Space Invaders (SV Version rev 4)", MACHINE_IMPERFECT_SOUND | MACHINE_SUPPORTS_SAVE ) +GAMEL(1978, sitv1, invaders, invaders, sitv, sisv_state, empty_init, ROT270, "Taito", "Space Invaders (TV Version rev 1)", MACHINE_SUPPORTS_SAVE, layout_invaders ) +GAMEL(1978, sitv, invaders, invaders, sitv, sisv_state, empty_init, ROT270, "Taito", "Space Invaders (TV Version rev 2)", MACHINE_SUPPORTS_SAVE, layout_invaders ) GAME( 1979, sicv, invaders, invadpt2, sicv, _8080bw_state, empty_init, ROT270, "Taito", "Space Invaders (CV Version, larger roms)", MACHINE_IMPERFECT_SOUND | MACHINE_SUPPORTS_SAVE ) GAME( 1979, sicv1, invaders, invadpt2, sicv, _8080bw_state, empty_init, ROT270, "Taito", "Space Invaders (CV Version, smaller roms)", MACHINE_IMPERFECT_SOUND | MACHINE_SUPPORTS_SAVE ) -GAMEL(1978, invadrmr, invaders, invaders, invadrmr, mw8080bw_state, empty_init, ROT270, "Taito / Model Racing", "Space Invaders (Model Racing)", MACHINE_SUPPORTS_SAVE, layout_invaders ) // Unclassified, licensed or bootleg? -GAMEL(1978, invaderl, invaders, invaders, sicv, mw8080bw_state, empty_init, ROT270, "Taito / Logitec", "Space Invaders (Logitec)", MACHINE_SUPPORTS_SAVE, layout_invaders ) // Unclassified, licensed or bootleg? -GAMEL(1978, invadernc, invaders, invaders, sicv, mw8080bw_state, empty_init, ROT270, "bootleg (Nas Corp)", "Space Invaders (Nas Corp bootleg)", MACHINE_WRONG_COLORS | MACHINE_SUPPORTS_SAVE, layout_invaders ) // Runs on original Logitec PCB, PROM dump might be bad, needs correct decoding anyway +GAMEL(1978, invadrmr, invaders, invaders, invadrmr, invaders_state, empty_init, ROT270, "Taito / Model Racing", "Space Invaders (Model Racing)", MACHINE_SUPPORTS_SAVE, layout_invaders ) // Unclassified, licensed or bootleg? +GAMEL(1978, invaderl, invaders, invaders, sicv, sisv_state, empty_init, ROT270, "Taito / Logitec", "Space Invaders (Logitec)", MACHINE_SUPPORTS_SAVE, layout_invaders ) // Unclassified, licensed or bootleg? +GAMEL(1978, invadernc, invaders, invaders, sicv, sisv_state, empty_init, ROT270, "bootleg (Nas Corp)", "Space Invaders (Nas Corp bootleg)", MACHINE_WRONG_COLORS | MACHINE_SUPPORTS_SAVE, layout_invaders ) // Runs on original Logitec PCB, PROM dump might be bad, needs correct decoding anyway GAMEL(1978, spcewars, invaders, spcewars, spcewars, _8080bw_state, empty_init, ROT270, "Taito / Sanritsu", "Space War (Sanritsu)", MACHINE_IMPERFECT_SOUND | MACHINE_SUPPORTS_SAVE, layout_invaders ) // Unclassified, licensed or bootleg? GAME( 1979, spcewarla, invaders, spcewarla, spcewars, _8080bw_state, empty_init, ROT270, "bootleg (Leisure and Allied)", "Space War (Leisure and Allied)", MACHINE_IMPERFECT_COLORS | MACHINE_IMPERFECT_SOUND | MACHINE_SUPPORTS_SAVE ) // unclassified, licensed or bootleg? -GAMEL(1978, spceking, invaders, invaders, sicv, mw8080bw_state, empty_init, ROT270, "Taito / Leijac Corporation", "Space King", MACHINE_SUPPORTS_SAVE, layout_invaders ) // Unclassified, licensed or bootleg? +GAMEL(1978, spceking, invaders, invaders, sicv, sisv_state, empty_init, ROT270, "Taito / Leijac Corporation", "Space King", MACHINE_SUPPORTS_SAVE, layout_invaders ) // Unclassified, licensed or bootleg? GAMEL(1979, cosmicmo, invaders, cosmicmo, cosmicmo, _8080bw_state, empty_init, ROT270, "bootleg (Universal)", "Cosmic Monsters (version II)", MACHINE_SUPPORTS_SAVE, layout_cosmicm ) // Taito sued, and as settlement they were allowed to sell Universal's Galaxy Wars GAMEL(1979, cosmicm2, invaders, cosmicmo, cosmicmo, _8080bw_state, empty_init, ROT270, "bootleg (Universal)", "Cosmic Monsters 2", MACHINE_SUPPORTS_SAVE, layout_cosmicm ) // " -GAMEL(1980?,sinvzen, invaders, invaders, sinvzen, mw8080bw_state, empty_init, ROT270, "Taito / Zenitone-Microsec Ltd.", "Super Invaders (Zenitone-Microsec)", MACHINE_SUPPORTS_SAVE, layout_invaders ) // Unclassified, licensed or bootleg? -GAMEL(1980, spaceat2, invaders, invaders, spaceat2, mw8080bw_state, empty_init, ROT270, "bootleg (Video Games UK)", "Space Attack II (bootleg of Super Invaders)", MACHINE_SUPPORTS_SAVE, layout_invaders ) // Bootleg of Zenitone-Microsec Super Invaders -GAMEL(1980, invader4, invaders, invaders, spaceat2, mw8080bw_state, empty_init, ROT270, "bootleg", "Space Invaders Part Four (bootleg of Space Attack II)", MACHINE_SUPPORTS_SAVE, layout_invaders ) // Bootleg of Space Attack II -GAMEL(1980, ultrainv, invaders, invaders, sicv, mw8080bw_state, empty_init, ROT270, "Taito / Konami", "Ultra Invaders", MACHINE_SUPPORTS_SAVE, layout_invaders ) // Unclassified, licensed or bootleg? -GAMEL(1978, spaceatt, invaders, invaders, sicv, mw8080bw_state, empty_init, ROT270, "bootleg (Video Games GmbH)", "Space Attack (bootleg of Space Invaders)", MACHINE_SUPPORTS_SAVE, layout_invaders ) -GAMEL(1978, spaceattbp, invaders, invaders, sicv, mw8080bw_state, empty_init, ROT270, "bootleg (Video Games GmbH)", "Space Attack (bootleg of Space Invaders, bproms)", MACHINE_SUPPORTS_SAVE, layout_invaders ) -GAMEL(1978, spaceatt2k, invaders, invaders, sicv, mw8080bw_state, empty_init, ROT270, "bootleg (Video Games GmbH)", "Space Attack (bootleg of Space Invaders, 2k roms)", MACHINE_SUPPORTS_SAVE, layout_invaders ) -GAMEL(1978, cosmicin, invaders, invaders, sicv, mw8080bw_state, empty_init, ROT270, "bootleg", "Cosmic Invaders (bootleg of Space Invaders)", MACHINE_SUPPORTS_SAVE, layout_invaders ) -GAMEL(1978, galmonst, invaders, invaders, sicv, mw8080bw_state, empty_init, ROT270, "bootleg (Laguna S.A.)", "Galaxy Monsters (Laguna S.A. Spanish bootleg of Space Invaders)", MACHINE_SUPPORTS_SAVE, layout_invaders ) -GAMEL(1979, spacecom, invaders, spacecom, spacecom, _8080bw_state, init_spacecom, ROT270, "bootleg", "Space Combat (bootleg of Space Invaders)", MACHINE_IMPERFECT_SOUND | MACHINE_SUPPORTS_SAVE, layout_spacecom ) +GAMEL(1980?,sinvzen, invaders, invaders, sinvzen, invaders_state, empty_init, ROT270, "Taito / Zenitone-Microsec Ltd.", "Super Invaders (Zenitone-Microsec)", MACHINE_SUPPORTS_SAVE, layout_invaders ) // Unclassified, licensed or bootleg? +GAMEL(1980, spaceat2, invaders, invaders, spaceat2, invaders_state, empty_init, ROT270, "bootleg (Video Games UK)", "Space Attack II (bootleg of Super Invaders)", MACHINE_SUPPORTS_SAVE, layout_invaders ) // Bootleg of Zenitone-Microsec Super Invaders +GAMEL(1980, invader4, invaders, invaders, spaceat2, invaders_state, empty_init, ROT270, "bootleg", "Space Invaders Part Four (bootleg of Space Attack II)", MACHINE_SUPPORTS_SAVE, layout_invaders ) // Bootleg of Space Attack II +GAMEL(1980, ultrainv, invaders, invaders, sicv, sisv_state, empty_init, ROT270, "Taito / Konami", "Ultra Invaders", MACHINE_SUPPORTS_SAVE, layout_invaders ) // Unclassified, licensed or bootleg? +GAMEL(1978, spaceatt, invaders, invaders, sicv, sisv_state, empty_init, ROT270, "bootleg (Video Games GmbH)", "Space Attack (bootleg of Space Invaders)", MACHINE_SUPPORTS_SAVE, layout_invaders ) +GAMEL(1978, spaceattbp, invaders, invaders, sicv, sisv_state, empty_init, ROT270, "bootleg (Video Games GmbH)", "Space Attack (bootleg of Space Invaders, bproms)", MACHINE_SUPPORTS_SAVE, layout_invaders ) +GAMEL(1978, spaceatt2k, invaders, invaders, sicv, sisv_state, empty_init, ROT270, "bootleg (Video Games GmbH)", "Space Attack (bootleg of Space Invaders, 2k roms)", MACHINE_SUPPORTS_SAVE, layout_invaders ) +GAMEL(1978, cosmicin, invaders, invaders, sicv, sisv_state, empty_init, ROT270, "bootleg", "Cosmic Invaders (bootleg of Space Invaders)", MACHINE_SUPPORTS_SAVE, layout_invaders ) +GAMEL(1978, galmonst, invaders, invaders, sicv, sisv_state, empty_init, ROT270, "bootleg (Laguna S.A.)", "Galaxy Monsters (Laguna S.A. Spanish bootleg of Space Invaders)", MACHINE_SUPPORTS_SAVE, layout_invaders ) +GAMEL(1979, spacecom, invaders, spacecom, spacecom, spacecom_state, init_spacecom, ROT270, "bootleg", "Space Combat (bootleg of Space Invaders)", MACHINE_IMPERFECT_SOUND | MACHINE_SUPPORTS_SAVE, layout_spacecom ) GAME( 1978, spacerng, invaders, spacerng, sitv, _8080bw_state, empty_init, ROT90, "bootleg (Leisure Time Electronics)", "Space Ranger", MACHINE_WRONG_COLORS | MACHINE_SUPPORTS_SAVE | MACHINE_IMPERFECT_SOUND ) // Many modifications -GAMEL(19??, invasion, invaders, invaders, invasion, mw8080bw_state, empty_init, ROT270, "bootleg (Sidam)", "Invasion (Sidam)", MACHINE_SUPPORTS_SAVE, layout_invaders ) -GAMEL(1979, invasiona, invaders, invaders, invasion, mw8080bw_state, empty_init, ROT270, "bootleg", "UFO Robot Attack (bootleg of Invasion, newer set)", MACHINE_SUPPORTS_SAVE, layout_invaders ) // Has Sidam replaced with 'UFO Monster Attack' and standard GFX -GAMEL(1979, invasiona2, invaders, invaders, invasion, mw8080bw_state, empty_init, ROT270, "bootleg", "UFO Robot Attack (bootleg of Invasion, older set)", MACHINE_SUPPORTS_SAVE, layout_invaders ) // Has Sidam replaced with 'UFO Monster Attack' and standard GFX -GAMEL(1979, invasionb, invaders, invaders, invasion, mw8080bw_state, empty_init, ROT270, "bootleg", "Invasion (Italian bootleg)", MACHINE_SUPPORTS_SAVE, layout_invaders ) -GAMEL(1979, invasionrz, invaders, invaders, invasion, mw8080bw_state, empty_init, ROT270, "bootleg (R Z SRL Bologna)", "Invasion (bootleg set 1, R Z SRL Bologna)", MACHINE_SUPPORTS_SAVE | MACHINE_NOT_WORKING, layout_invaders ) -GAMEL(1979, invasionrza, invaders, invaders, invasion, mw8080bw_state, empty_init, ROT270, "bootleg (R Z SRL Bologna)", "Invasion (bootleg set 2, R Z SRL Bologna)", MACHINE_SUPPORTS_SAVE | MACHINE_NOT_WORKING, layout_invaders ) -GAMEL(19??, invadersem, invaders, invaders, sitv, mw8080bw_state, empty_init, ROT270, "Electromar", "Space Invaders (Electromar, Spanish)", MACHINE_SUPPORTS_SAVE, layout_invaders ) // Possibly licensed -GAMEL(1978, superinv, invaders, invaders, superinv, mw8080bw_state, empty_init, ROT270, "bootleg", "Super Invaders (bootleg set 1)", MACHINE_SUPPORTS_SAVE, layout_invaders ) // Not related to Zenitone-Microsec version -GAMEL(1978, sinvemag, invaders, invaders, sinvemag, mw8080bw_state, empty_init, ROT270, "bootleg (Emag)", "Super Invaders (bootleg set 2)", MACHINE_SUPPORTS_SAVE, layout_invaders ) // Not related to Zenitone-Microsec version -GAMEL(1980, searthin, invaders, invaders, searthin, mw8080bw_state, empty_init, ROT270, "bootleg (Competitive Video)", "Super Earth Invasion (set 1)", MACHINE_SUPPORTS_SAVE, layout_invaders ) -GAMEL(1980, searthina, invaders, invaders, searthin, mw8080bw_state, empty_init, ROT270, "bootleg (Competitive Video)", "Super Earth Invasion (set 2)", MACHINE_SUPPORTS_SAVE, layout_invaders ) -GAMEL(1979, supinvsion, invaders, invaders, searthin, mw8080bw_state, empty_init, ROT270, "bootleg (Electromar / Irecsa)", "Super Invasion (Electromar, Spanish)", MACHINE_SUPPORTS_SAVE | MACHINE_IMPERFECT_CONTROLS, layout_invaders ) -GAMEL(1980, searthie, invaders, invaders, searthin, mw8080bw_state, empty_init, ROT270, "bootleg (Electrocoin)", "Super Earth Invasion (set 3)", MACHINE_SUPPORTS_SAVE, layout_invaders ) -GAMEL(19??, alieninv, invaders, invaders, alieninv, mw8080bw_state, empty_init, ROT270, "bootleg (Margamatics)", "Alien Invasion", MACHINE_SUPPORTS_SAVE, layout_invaders ) -GAMEL(19??, alieninvp2, invaders, invaders, searthin, mw8080bw_state, empty_init, ROT270, "bootleg", "Alien Invasion Part II", MACHINE_SUPPORTS_SAVE, layout_invaders ) -GAMEL(1979, jspecter, invaders, invaders, jspecter, mw8080bw_state, empty_init, ROT270, "bootleg (Jatre)", "Jatre Specter (set 1)", MACHINE_SUPPORTS_SAVE, layout_invaders ) -GAMEL(1979, jspecter2, invaders, invaders, jspecter, mw8080bw_state, empty_init, ROT270, "bootleg (Jatre)", "Jatre Specter (set 2)", MACHINE_SUPPORTS_SAVE, layout_invaders ) +GAMEL(19??, invasion, invaders, invaders, invasion, invaders_state, empty_init, ROT270, "bootleg (Sidam)", "Invasion (Sidam)", MACHINE_IMPERFECT_SOUND | MACHINE_SUPPORTS_SAVE, layout_invaders ) +GAMEL(1979, invasiona, invaders, invaders, invasion, invaders_state, empty_init, ROT270, "bootleg", "UFO Robot Attack (bootleg of Invasion, newer set)", MACHINE_SUPPORTS_SAVE, layout_invaders ) // Has Sidam replaced with 'UFO Monster Attack' and standard GFX +GAMEL(1979, invasiona2, invaders, invaders, invasion, invaders_state, empty_init, ROT270, "bootleg", "UFO Robot Attack (bootleg of Invasion, older set)", MACHINE_SUPPORTS_SAVE, layout_invaders ) // Has Sidam replaced with 'UFO Monster Attack' and standard GFX +GAMEL(1979, invasionb, invaders, invaders, invasion, invaders_state, empty_init, ROT270, "bootleg", "Invasion (Italian bootleg)", MACHINE_SUPPORTS_SAVE, layout_invaders ) +GAMEL(1979, invasionrz, invaders, invaders, invasion, invaders_state, empty_init, ROT270, "bootleg (R Z SRL Bologna)", "Invasion (bootleg set 1, R Z SRL Bologna)", MACHINE_SUPPORTS_SAVE | MACHINE_NOT_WORKING, layout_invaders ) +GAMEL(1979, invasionrza, invaders, invaders, invasion, invaders_state, empty_init, ROT270, "bootleg (R Z SRL Bologna)", "Invasion (bootleg set 2, R Z SRL Bologna)", MACHINE_SUPPORTS_SAVE | MACHINE_NOT_WORKING, layout_invaders ) +GAMEL(19??, invadersem, invaders, invaders, sitv, sisv_state, empty_init, ROT270, "Electromar", "Space Invaders (Electromar, Spanish)", MACHINE_SUPPORTS_SAVE, layout_invaders ) // Possibly licensed +GAMEL(1978, superinv, invaders, invaders, superinv, invaders_state, empty_init, ROT270, "bootleg", "Super Invaders (bootleg set 1)", MACHINE_SUPPORTS_SAVE, layout_invaders ) // Not related to Zenitone-Microsec version +GAMEL(1978, sinvemag, invaders, invaders, sinvemag, invaders_state, empty_init, ROT270, "bootleg (Emag)", "Super Invaders (bootleg set 2)", MACHINE_SUPPORTS_SAVE, layout_invaders ) // Not related to Zenitone-Microsec version +GAMEL(1980, searthin, invaders, invaders, searthin, invaders_state, empty_init, ROT270, "bootleg (Competitive Video)", "Super Earth Invasion (set 1)", MACHINE_SUPPORTS_SAVE, layout_invaders ) +GAMEL(1980, searthina, invaders, invaders, searthin, invaders_state, empty_init, ROT270, "bootleg (Competitive Video)", "Super Earth Invasion (set 2)", MACHINE_SUPPORTS_SAVE, layout_invaders ) +GAMEL(1979, supinvsion, invaders, invaders, searthin, invaders_state, empty_init, ROT270, "bootleg (Electromar / Irecsa)", "Super Invasion (Electromar, Spanish)", MACHINE_SUPPORTS_SAVE | MACHINE_IMPERFECT_CONTROLS, layout_invaders ) +GAMEL(1980, searthie, invaders, invaders, searthin, invaders_state, empty_init, ROT270, "bootleg (Electrocoin)", "Super Earth Invasion (set 3)", MACHINE_SUPPORTS_SAVE, layout_invaders ) +GAMEL(19??, alieninv, invaders, invaders, alieninv, invaders_state, empty_init, ROT270, "bootleg (Margamatics)", "Alien Invasion", MACHINE_SUPPORTS_SAVE, layout_invaders ) +GAMEL(19??, alieninvp2, invaders, invaders, searthin, invaders_state, empty_init, ROT270, "bootleg", "Alien Invasion Part II", MACHINE_SUPPORTS_SAVE, layout_invaders ) +GAMEL(1979, jspecter, invaders, invaders, jspecter, invaders_state, empty_init, ROT270, "bootleg (Jatre)", "Jatre Specter (set 1)", MACHINE_SUPPORTS_SAVE, layout_invaders ) +GAMEL(1979, jspecter2, invaders, invaders, jspecter, invaders_state, empty_init, ROT270, "bootleg (Jatre)", "Jatre Specter (set 2)", MACHINE_SUPPORTS_SAVE, layout_invaders ) GAMEL(1978, spacewr3, invaders, spcewars, sicv, _8080bw_state, empty_init, ROT270, "bootleg", "Space War Part 3", MACHINE_IMPERFECT_SOUND | MACHINE_SUPPORTS_SAVE, layout_invaders ) // Bootleg of Sanritsu's Space War GAMEL(1978, swipeout, invaders, spcewars, sicv, _8080bw_state, empty_init, ROT270, "bootleg (Beyer and Brown)", "Space Wipeout", MACHINE_IMPERFECT_SOUND | MACHINE_SUPPORTS_SAVE, layout_invaders ) // Bootleg of Sanritsu's Space War -GAME( 1978, darthvdr, invaders, darthvdr, darthvdr, _8080bw_state, empty_init, ROT270, "bootleg", "Darth Vader (bootleg of Space Invaders)", MACHINE_SUPPORTS_SAVE | MACHINE_IMPERFECT_SOUND ) -GAMEL(19??, tst_invd, invaders, invaders, sicv, mw8080bw_state, empty_init, ROT0, "", "Space Invaders Test ROM", MACHINE_SUPPORTS_SAVE, layout_invaders ) +GAME( 1978, darthvdr, invaders, darthvdr, darthvdr, darthvdr_state, empty_init, ROT270, "bootleg", "Darth Vader (bootleg of Space Invaders)", MACHINE_SUPPORTS_SAVE | MACHINE_IMPERFECT_SOUND ) +GAMEL(19??, tst_invd, invaders, invaders, sicv, sisv_state, empty_init, ROT0, "", "Space Invaders Test ROM", MACHINE_SUPPORTS_SAVE, layout_invaders ) // Other Taito GAME( 1979, invadpt2, 0, invadpt2, invadpt2, _8080bw_state, empty_init, ROT270, "Taito", "Space Invaders Part II (Taito, bigger ROMs)", MACHINE_SUPPORTS_SAVE | MACHINE_IMPERFECT_SOUND ) GAME( 1979, invadpt2a, invadpt2, invadpt2, invadpt2, _8080bw_state, empty_init, ROT270, "Taito", "Space Invaders Part II (Taito, smaller ROMs)", MACHINE_SUPPORTS_SAVE | MACHINE_IMPERFECT_SOUND ) GAME( 1979, invadpt2br, invadpt2, invadpt2, invadpt2, _8080bw_state, empty_init, ROT270, "Taito do Brasil", "Space Invaders Part II (Brazil)", MACHINE_SUPPORTS_SAVE | MACHINE_IMPERFECT_SOUND ) -GAME( 1980, invaddlx, invadpt2, invaders, invadpt2, mw8080bw_state, empty_init, ROT270, "Taito (Midway license)", "Space Invaders Deluxe", MACHINE_SUPPORTS_SAVE ) +GAME( 1980, invaddlx, invadpt2, invaders, invadpt2, sisv_state, empty_init, ROT270, "Taito (Midway license)", "Space Invaders Deluxe", MACHINE_SUPPORTS_SAVE ) GAME( 1979, moonbase, invadpt2, invadpt2, invadpt2, _8080bw_state, empty_init, ROT270, "Taito / Nichibutsu", "Moon Base Zeta (set 1)", MACHINE_SUPPORTS_SAVE | MACHINE_IMPERFECT_SOUND ) // This has a 'Taito Corp' string hidden away in the rom - to display it, press P1 Right+P1 Fire+2P Start then P1 Left+P1 Fire+P1 Start at the attract gameplay sequence GAME( 1979, moonbasea, invadpt2, invadpt2, invadpt2, _8080bw_state, empty_init, ROT270, "Taito / Nichibutsu", "Moon Base Zeta (set 2)", MACHINE_SUPPORTS_SAVE | MACHINE_IMPERFECT_SOUND ) // This has the same string replaced with Nichibutsu, no other differences @@ -5833,43 +5894,43 @@ GAME( 1983, indianbtbr, indianbt, indianbtbr,indianbtbr,_8080bw_state, empty_i GAME( 1980, steelwkr, 0, steelwkr, steelwkr, _8080bw_state, empty_init, ROT0 , "Taito", "Steel Worker", MACHINE_SUPPORTS_SAVE | MACHINE_IMPERFECT_SOUND ) -GAMEL(1980?,galactic, 0, invaders, galactic, mw8080bw_state, empty_init, ROT270, "Taito do Brasil", "Galactica - Batalha Espacial", MACHINE_SUPPORTS_SAVE | MACHINE_IMPERFECT_SOUND, layout_galactic ) -GAMEL(1980?,spacmiss, galactic, invaders, galactic, mw8080bw_state, empty_init, ROT270, "bootleg?", "Space Missile - Space Fighting Game", MACHINE_SUPPORTS_SAVE | MACHINE_IMPERFECT_SOUND, layout_galactic ) +GAMEL(1980?,galactic, 0, invaders, galactic, invaders_state, empty_init, ROT270, "Taito do Brasil", "Galactica - Batalha Espacial", MACHINE_SUPPORTS_SAVE | MACHINE_IMPERFECT_SOUND, layout_galactic ) +GAMEL(1980?,spacmiss, galactic, invaders, galactic, invaders_state, empty_init, ROT270, "bootleg?", "Space Missile - Space Fighting Game", MACHINE_SUPPORTS_SAVE | MACHINE_IMPERFECT_SOUND, layout_galactic ) // Misc. manufacturers GAME( 1979, galxwars, 0, invadpt2, galxwars, _8080bw_state, empty_init, ROT270, "Universal", "Galaxy Wars (Universal set 1)", MACHINE_WRONG_COLORS | MACHINE_SUPPORTS_SAVE ) GAME( 1979, galxwars2, galxwars, invadpt2, galxwars, _8080bw_state, empty_init, ROT270, "Universal", "Galaxy Wars (Universal set 2)", MACHINE_WRONG_COLORS | MACHINE_SUPPORTS_SAVE ) GAME( 1979, galxwarst, galxwars, invadpt2, galxwars, _8080bw_state, empty_init, ROT270, "Universal (Taito license?)", "Galaxy Wars (Taito?)" , MACHINE_WRONG_COLORS | MACHINE_SUPPORTS_SAVE ) // Copyright not displayed GAME( 1979, galxwarst2, galxwars, invadpt2, galxwars, _8080bw_state, empty_init, ROT270, "Universal (Taito Corporation license)", "Galaxy Wars (Taito)" , MACHINE_WRONG_COLORS | MACHINE_SUPPORTS_SAVE ) // Copyright displayed, quite different codebase from galxwarst -GAME( 1979, starw, galxwars, invaders, galxwars, mw8080bw_state, empty_init, ROT270, "bootleg", "Star Wars (bootleg of Galaxy Wars, set 1)", MACHINE_SUPPORTS_SAVE ) +GAME( 1979, starw, galxwars, invaders, galxwars, invaders_state, empty_init, ROT270, "bootleg", "Star Wars (bootleg of Galaxy Wars, set 1)", MACHINE_SUPPORTS_SAVE ) GAME( 1979, starw1, galxwars, starw1, galxwars, _8080bw_state, empty_init, ROT270, "bootleg (Yamashita)", "Star Wars (bootleg of Galaxy Wars, set 2)", MACHINE_SUPPORTS_SAVE ) GAME( 1979, cosmo, 0, cosmo, cosmo, _8080bw_state, empty_init, ROT90, "TDS & MINTS", "Cosmo", MACHINE_SUPPORTS_SAVE | MACHINE_IMPERFECT_SOUND ) -GAME( 1980?,invrvnge, 0, invrvnge, invrvnge, _8080bw_state, init_invrvnge, ROT270, "Zenitone-Microsec Ltd.", "Invader's Revenge (set 1)", MACHINE_SUPPORTS_SAVE ) // Copyright is either late-1980, or early-1981 -GAME( 1980?,invrvngea, invrvnge, invrvnge, invrvnge, _8080bw_state, init_invrvnge, ROT270, "Zenitone-Microsec Ltd.", "Invader's Revenge (set 2)", MACHINE_SUPPORTS_SAVE ) -GAME( 1980?,invrvngeb, invrvnge, invrvnge, invrvnge, _8080bw_state, init_invrvnge, ROT270, "Zenitone-Microsec Ltd.", "Invader's Revenge (set 3)", MACHINE_SUPPORTS_SAVE ) -GAME( 1980?,invrvngedu, invrvnge, invrvnge, invrvnge, _8080bw_state, init_invrvnge, ROT270, "Zenitone-Microsec Ltd. (Dutchford license)", "Invader's Revenge (Dutchford, single PCB)", MACHINE_SUPPORTS_SAVE ) -GAME( 1980?,invrvngegw, invrvnge, invrvnge, invrvnge, _8080bw_state, empty_init, ROT270, "Zenitone-Microsec Ltd. (Game World license)", "Invader's Revenge (Game World, single PCB)", MACHINE_SUPPORTS_SAVE | MACHINE_NO_SOUND ) +GAME( 1980?,invrvnge, 0, invrvnge, invrvnge, invrvnge_state, init_invrvnge, ROT270, "Zenitone-Microsec Ltd.", "Invader's Revenge (set 1)", MACHINE_SUPPORTS_SAVE ) // Copyright is either late-1980, or early-1981 +GAME( 1980?,invrvngea, invrvnge, invrvnge, invrvnge, invrvnge_state, init_invrvnge, ROT270, "Zenitone-Microsec Ltd.", "Invader's Revenge (set 2)", MACHINE_SUPPORTS_SAVE ) +GAME( 1980?,invrvngeb, invrvnge, invrvnge, invrvnge, invrvnge_state, init_invrvnge, ROT270, "Zenitone-Microsec Ltd.", "Invader's Revenge (set 3)", MACHINE_SUPPORTS_SAVE ) +GAME( 1980?,invrvngedu, invrvnge, invrvnge, invrvnge, invrvnge_state, init_invrvnge, ROT270, "Zenitone-Microsec Ltd. (Dutchford license)", "Invader's Revenge (Dutchford, single PCB)", MACHINE_SUPPORTS_SAVE ) +GAME( 1980?,invrvngegw, invrvnge, invrvnge, invrvnge, invrvnge_state, empty_init, ROT270, "Zenitone-Microsec Ltd. (Game World license)", "Invader's Revenge (Game World, single PCB)", MACHINE_SUPPORTS_SAVE | MACHINE_NO_SOUND ) -GAME( 1980, vortex, 0, vortex, vortex, _8080bw_state, init_vortex, ROT270, "Zilec Electronics", "Vortex", MACHINE_SUPPORTS_SAVE | MACHINE_IMPERFECT_SOUND ) // Encrypted 8080/IO +GAME( 1980, vortex, 0, vortex, vortex, vortex_state, init_vortex, ROT270, "Zilec Electronics", "Vortex", MACHINE_SUPPORTS_SAVE | MACHINE_IMPERFECT_SOUND ) // Encrypted 8080/IO -GAME( 1979, rollingc, 0, rollingc, rollingc, _8080bw_state, empty_init, ROT270, "Nichibutsu", "Rolling Crash / Moon Base", MACHINE_IMPERFECT_SOUND | MACHINE_IMPERFECT_COLORS | MACHINE_SUPPORTS_SAVE ) +GAME( 1979, rollingc, 0, rollingc, rollingc, rollingc_state, empty_init, ROT270, "Nichibutsu", "Rolling Crash / Moon Base", MACHINE_IMPERFECT_SOUND | MACHINE_IMPERFECT_COLORS | MACHINE_SUPPORTS_SAVE ) GAME( 1979, ozmawars, 0, invadpt2, ozmawars, _8080bw_state, empty_init, ROT270, "SNK", "Ozma Wars (set 1)", MACHINE_SUPPORTS_SAVE ) GAME( 1979, ozmawars2, ozmawars, invadpt2, ozmawars, _8080bw_state, empty_init, ROT270, "SNK", "Ozma Wars (set 2)", MACHINE_SUPPORTS_SAVE ) // Uses Taito's three board color version of Space Invaders PCB -GAME( 1979, ozmawarsmr, ozmawars, invaders, ozmawars, mw8080bw_state, empty_init, ROT270, "bootleg (Model Racing)", "Ozma Wars (Model Racing bootleg)", MACHINE_SUPPORTS_SAVE ) -GAME( 1979, spaceph, ozmawars, invaders, spaceph, mw8080bw_state, empty_init, ROT270, "bootleg? (Zilec Games)", "Space Phantoms (bootleg of Ozma Wars)", MACHINE_SUPPORTS_SAVE ) -GAME( 1979, solfight, ozmawars, invaders, ozmawars, mw8080bw_state, empty_init, ROT270, "bootleg", "Solar Fight (bootleg of Ozma Wars)", MACHINE_SUPPORTS_SAVE ) +GAME( 1979, ozmawarsmr, ozmawars, invaders, ozmawars, invaders_state, empty_init, ROT270, "bootleg (Model Racing)", "Ozma Wars (Model Racing bootleg)", MACHINE_SUPPORTS_SAVE ) +GAME( 1979, spaceph, ozmawars, invaders, spaceph, invaders_state, empty_init, ROT270, "bootleg? (Zilec Games)", "Space Phantoms (bootleg of Ozma Wars)", MACHINE_SUPPORTS_SAVE ) +GAME( 1979, solfight, ozmawars, invaders, ozmawars, invaders_state, empty_init, ROT270, "bootleg", "Solar Fight (bootleg of Ozma Wars)", MACHINE_SUPPORTS_SAVE ) -GAMEL(1979, yosakdon, 0, yosakdon, yosakdon, _8080bw_state, empty_init, ROT270, "Wing", "Yosaku To Donbei (set 1)", MACHINE_SUPPORTS_SAVE | MACHINE_IMPERFECT_SOUND, layout_yosakdon ) -GAMEL(1979, yosakdona, yosakdon, yosakdon, yosakdon, _8080bw_state, empty_init, ROT270, "Wing", "Yosaku To Donbei (set 2)", MACHINE_SUPPORTS_SAVE | MACHINE_IMPERFECT_SOUND, layout_yosakdon ) +GAMEL(1979, yosakdon, 0, yosakdon, yosakdon, yosakdon_state, empty_init, ROT270, "Wing", "Yosaku to Donbei (set 1)", MACHINE_SUPPORTS_SAVE | MACHINE_IMPERFECT_SOUND, layout_yosakdon ) +GAMEL(1979, yosakdona, yosakdon, yosakdon, yosakdon, yosakdon_state, empty_init, ROT270, "Wing", "Yosaku to Donbei (set 2)", MACHINE_SUPPORTS_SAVE | MACHINE_IMPERFECT_SOUND, layout_yosakdon ) -GAMEL(1979, shuttlei, 0, shuttlei, shuttlei, _8080bw_state, empty_init, ROT270, "Omori Electric Co., Ltd.", "Shuttle Invader", MACHINE_SUPPORTS_SAVE | MACHINE_IMPERFECT_SOUND, layout_shuttlei ) -GAMEL(1979, skylove, 0, shuttlei, skylove, _8080bw_state, empty_init, ROT270, "Omori Electric Co., Ltd.", "Sky Love", MACHINE_SUPPORTS_SAVE | MACHINE_IMPERFECT_SOUND, layout_shuttlei ) +GAMEL(1979, shuttlei, 0, shuttlei, shuttlei, shuttlei_state, empty_init, ROT270, "Omori Electric Co., Ltd.", "Shuttle Invader", MACHINE_SUPPORTS_SAVE | MACHINE_IMPERFECT_SOUND, layout_shuttlei ) +GAMEL(1979, skylove, 0, shuttlei, skylove, shuttlei_state, empty_init, ROT270, "Omori Electric Co., Ltd.", "Sky Love", MACHINE_SUPPORTS_SAVE | MACHINE_IMPERFECT_SOUND, layout_shuttlei ) -GAME( 1978, claybust, 0, claybust, claybust, _8080bw_state, empty_init, ROT0, "Model Racing", "Claybuster", MACHINE_SUPPORTS_SAVE | MACHINE_NO_SOUND ) // No titlescreen, Claybuster according to flyers -GAMEL(1980, gunchamp, 0, claybust, gunchamp, _8080bw_state, empty_init, ROT0, "Model Racing", "Gun Champ", MACHINE_SUPPORTS_SAVE | MACHINE_NO_SOUND, layout_gunchamp ) // No titlescreen, Gun Champ according to original cab +GAME( 1978, claybust, 0, claybust, claybust, claybust_state, empty_init, ROT0, "Model Racing", "Claybuster", MACHINE_SUPPORTS_SAVE | MACHINE_NO_SOUND ) // No titlescreen, Claybuster according to flyers +GAMEL(1980, gunchamp, 0, claybust, gunchamp, claybust_state, empty_init, ROT0, "Model Racing", "Gun Champ", MACHINE_SUPPORTS_SAVE | MACHINE_NO_SOUND, layout_gunchamp ) // No titlescreen, Gun Champ according to original cab GAME( 1979?,cane, 0, cane, cane, cane_state, empty_init, ROT0, "Model Racing", "Cane (prototype)", MACHINE_SUPPORTS_SAVE | MACHINE_IMPERFECT_SOUND ) GAME( 1979?,orbite, 0, orbite, orbite, orbite_state, empty_init, ROT270, "Model Racing", "Orbite (prototype)", MACHINE_SUPPORTS_SAVE | MACHINE_IS_INCOMPLETE | MACHINE_NO_SOUND_HW ) @@ -5878,13 +5939,13 @@ GAME( 1980?,astropal, 0, astropal, astropal, _8080bw_state, empty_i GAMEL(1979?,attackfc, 0, attackfc, attackfc, _8080bw_state, init_attackfc, ROT0, "Electronic Games Systems", "Attack Force (encrypted)", MACHINE_SUPPORTS_SAVE | MACHINE_NO_SOUND, layout_attackfc ) GAMEL(1979?,attackfcu, attackfc, attackfcu, attackfcu, _8080bw_state, empty_init, ROT0, "bootleg?", "Attack Force (unencrypted)", MACHINE_SUPPORTS_SAVE | MACHINE_NO_SOUND, layout_attackfc ) -GAME( 2002, invmulti, 0, invmulti, invmulti, _8080bw_state, init_invmulti, ROT270, "hack (Braze Technologies)", "Space Invaders Multigame (M8.03D)", MACHINE_IMPERFECT_SOUND | MACHINE_SUPPORTS_SAVE ) -GAME( 2002, invmultim3a, invmulti, invmulti, invmulti, _8080bw_state, init_invmulti, ROT270, "hack (Braze Technologies)", "Space Invaders Multigame (M8.03A)", MACHINE_IMPERFECT_SOUND | MACHINE_SUPPORTS_SAVE ) -GAME( 2002, invmultim2c, invmulti, invmulti, invmulti, _8080bw_state, init_invmulti, ROT270, "hack (Braze Technologies)", "Space Invaders Multigame (M8.02C)", MACHINE_IMPERFECT_SOUND | MACHINE_SUPPORTS_SAVE ) -GAME( 2002, invmultim2a, invmulti, invmulti, invmulti, _8080bw_state, init_invmulti, ROT270, "hack (Braze Technologies)", "Space Invaders Multigame (M8.02A)", MACHINE_IMPERFECT_SOUND | MACHINE_SUPPORTS_SAVE ) -GAME( 2002, invmultim1a, invmulti, invmulti, invmulti, _8080bw_state, init_invmulti, ROT270, "hack (Braze Technologies)", "Space Invaders Multigame (M8.01A)", MACHINE_IMPERFECT_SOUND | MACHINE_SUPPORTS_SAVE ) -GAME( 2002, invmultit3d, invmulti, invmulti, invmulti, _8080bw_state, init_invmulti, ROT270, "hack (Braze Technologies)", "Space Invaders Multigame (T8.03D)", MACHINE_IMPERFECT_SOUND | MACHINE_SUPPORTS_SAVE ) -GAME( 2002, invmultis3a, invmulti, invmulti, invmulti, _8080bw_state, init_invmulti, ROT270, "hack (Braze Technologies)", "Space Invaders Multigame (S0.83A)", MACHINE_IMPERFECT_SOUND | MACHINE_SUPPORTS_SAVE ) -GAME( 2002, invmultis2a, invmulti, invmulti, invmulti, _8080bw_state, init_invmulti, ROT270, "hack (Braze Technologies)", "Space Invaders Multigame (S0.82A)", MACHINE_IMPERFECT_SOUND | MACHINE_SUPPORTS_SAVE ) -GAME( 2002, invmultis1a, invmulti, invmulti, invmulti, _8080bw_state, init_invmulti, ROT270, "hack (Braze Technologies)", "Space Invaders Multigame (S0.81A)", MACHINE_IMPERFECT_SOUND | MACHINE_SUPPORTS_SAVE ) -GAME( 2002, invmultip, invmulti, invmulti, invmulti, _8080bw_state, init_invmulti, ROT270, "hack (Braze Technologies)", "Space Invaders Multigame (prototype)", MACHINE_IMPERFECT_SOUND | MACHINE_SUPPORTS_SAVE ) +GAME( 2002, invmulti, 0, invmulti, invmulti, invmulti_state, init_invmulti, ROT270, "hack (Braze Technologies)", "Space Invaders Multigame (M8.03D)", MACHINE_IMPERFECT_SOUND | MACHINE_SUPPORTS_SAVE ) +GAME( 2002, invmultim3a, invmulti, invmulti, invmulti, invmulti_state, init_invmulti, ROT270, "hack (Braze Technologies)", "Space Invaders Multigame (M8.03A)", MACHINE_IMPERFECT_SOUND | MACHINE_SUPPORTS_SAVE ) +GAME( 2002, invmultim2c, invmulti, invmulti, invmulti, invmulti_state, init_invmulti, ROT270, "hack (Braze Technologies)", "Space Invaders Multigame (M8.02C)", MACHINE_IMPERFECT_SOUND | MACHINE_SUPPORTS_SAVE ) +GAME( 2002, invmultim2a, invmulti, invmulti, invmulti, invmulti_state, init_invmulti, ROT270, "hack (Braze Technologies)", "Space Invaders Multigame (M8.02A)", MACHINE_IMPERFECT_SOUND | MACHINE_SUPPORTS_SAVE ) +GAME( 2002, invmultim1a, invmulti, invmulti, invmulti, invmulti_state, init_invmulti, ROT270, "hack (Braze Technologies)", "Space Invaders Multigame (M8.01A)", MACHINE_IMPERFECT_SOUND | MACHINE_SUPPORTS_SAVE ) +GAME( 2002, invmultit3d, invmulti, invmulti, invmulti, invmulti_state, init_invmulti, ROT270, "hack (Braze Technologies)", "Space Invaders Multigame (T8.03D)", MACHINE_IMPERFECT_SOUND | MACHINE_SUPPORTS_SAVE ) +GAME( 2002, invmultis3a, invmulti, invmulti, invmulti, invmulti_state, init_invmulti, ROT270, "hack (Braze Technologies)", "Space Invaders Multigame (S0.83A)", MACHINE_IMPERFECT_SOUND | MACHINE_SUPPORTS_SAVE ) +GAME( 2002, invmultis2a, invmulti, invmulti, invmulti, invmulti_state, init_invmulti, ROT270, "hack (Braze Technologies)", "Space Invaders Multigame (S0.82A)", MACHINE_IMPERFECT_SOUND | MACHINE_SUPPORTS_SAVE ) +GAME( 2002, invmultis1a, invmulti, invmulti, invmulti, invmulti_state, init_invmulti, ROT270, "hack (Braze Technologies)", "Space Invaders Multigame (S0.81A)", MACHINE_IMPERFECT_SOUND | MACHINE_SUPPORTS_SAVE ) +GAME( 2002, invmultip, invmulti, invmulti, invmulti, invmulti_state, init_invmulti, ROT270, "hack (Braze Technologies)", "Space Invaders Multigame (prototype)", MACHINE_IMPERFECT_SOUND | MACHINE_SUPPORTS_SAVE ) diff --git a/src/mame/drivers/mw8080bw.cpp b/src/mame/drivers/mw8080bw.cpp index 74ce44b8eff..2415ba8f4aa 100644 --- a/src/mame/drivers/mw8080bw.cpp +++ b/src/mame/drivers/mw8080bw.cpp @@ -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 ) diff --git a/src/mame/includes/8080bw.h b/src/mame/includes/8080bw.h index 62a680c18d9..806b7c1385d 100644 --- a/src/mame/includes/8080bw.h +++ b/src/mame/includes/8080bw.h @@ -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 m_sn; + optional_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 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 m_audiocpu; optional_device m_schaser_effect_555_timer; - optional_device m_claybust_gun_on; - optional_device m_sn; - optional_device m_samples; optional_device m_speaker; - optional_device m_eeprom; - optional_device m_palette; optional_shared_ptr 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 m_scattered_colorram; - std::unique_ptr 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 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 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 m_scattered_colorram; + std::unique_ptr 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 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 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 m_main_ram; - std::unique_ptr 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 m_main_ram; + std::unique_ptr 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 m_eeprom; }; #endif // MAME_INCLUDES_8080BW_H diff --git a/src/mame/includes/mw8080bw.h b/src/mame/includes/mw8080bw.h index ad6e14f5efa..a96e61de592 100644 --- a/src/mame/includes/mw8080bw.h +++ b/src/mame/includes/mw8080bw.h @@ -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 m_discrete; required_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) \ diff --git a/src/mame/machine/mw8080bw.cpp b/src/mame/machine/mw8080bw.cpp deleted file mode 100644 index 482b7f1bb9a..00000000000 --- a/src/mame/machine/mw8080bw.cpp +++ /dev/null @@ -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(); -} diff --git a/src/mame/video/8080bw.cpp b/src/mame/video/8080bw.cpp index 552e03fb0fd..5fa841197ac 100644 --- a/src/mame/video/8080bw.cpp +++ b/src/mame/video/8080bw.cpp @@ -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(); diff --git a/src/mame/video/mw8080bw.cpp b/src/mame/video/mw8080bw.cpp index cf86bf10f13..1dfe3c5e72c 100644 --- a/src/mame/video/mw8080bw.cpp +++ b/src/mame/video/mw8080bw.cpp @@ -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; -- cgit v1.2.3