Skip to content
Permalink
Branch: master
Find file Copy path
Find file Copy path
Fetching contributors…
Cannot retrieve contributors at this time
5758 lines (4719 sloc) 283 KB
// license:BSD-3-Clause
// copyright-holders:Nicola Salmoria, Tormod Tjaberg, Mirko Buffoni, Lee Taylor, Valerio Verrando, Zsolt Vasvari, Aaron Giles, Jonathan Gevaryahu, hap, Robbbert
// thanks-to:Michael Strutts, Marco Cassili
/*****************************************************************************
8080bw.cpp
Michael Strutts, Nicola Salmoria, Tormod Tjaberg, Mirko Buffoni
Lee Taylor, Valerio Verrando, Marco Cassili, Zsolt Vasvari, and others
Much information about Space Invaders PCBs and other Taito and Midway
sets and hardware contributed by Andrew Welburn
Notes:
-----
- Space Invaders Deluxe still says Space Invaders Part II,
because according to KLOV, Midway was only allowed to make minor
modifications of the Taito code.
- DIP settings/locations verified from manual for:
sitv, sicv, invadpt2, lrescue, invasion, invrvnge
- The Taito Space invaders hardware comes on at least five board types;
The Taito manufactured ones are:
* The "L-shaped" PCB set, Upright, B&W only
* Three pcbs in a stack, often called the '3 layer pcb set' (most common)
* Two pcbs in a stack, with the function of two of the three pcb stack
pcbs combined.
* In general, discounting revision specific differences, the pcbs are
arranged in a stack, connected end-to-end by ribbon cables and folded
such that the middle pcb (of 3 pcb stack) or the bottom pcb (of 2 pcb
stack) is upside down.
* Keep in mind specific differences on the pcbs (especially the TVN pcbs
vs the others) sometimes prevent exchanging 'equivalent' pcbs between stacks.
* L-shaped pcb set details:
* One large, square board with ROM, RAM, CPU, Video circuitry on it.
* One smaller pcb with audio/io/shifter circuitry on it, plugged into
the main pcb at a right angle (hence the entire pcb set is 'L-shaped')
* Does not have the capability of any sort of electronic color overlay.
* 3 layer pcb set details:
* This pcb set came in 3 versions: TVN, CVN, PVN; see below for differences.
* Top pcb: Audio/IO/Shifter pcb
- discrete audio and sn76477, and volume knobs
- data shifter, using either ~11 74xx chips, AM25S10s, Fujitsu MB14221
or Fujitsu MB14241 chips, which all do the same thing.
- has the dipswitches
- has the main "G" edge connector for the wiring harness
- has the gating circuitry for the color overlay
(these are not present and/or populated on some TVN pcbs)
- despite there being at least six versions of this pcb, the discrete
audio section is identical in all of them.
* Middle pcb: CPU/RAM/Color overlay pcb
- has DRAMS on it
- has the 8080 CPU on it
- has the two PROMS for color overlay on it (one for each player flip)
(these are not populated on TVN pcbs and the related circuitry is not
present and/or populated on some TVN pcbs)
* Bottom pcb: Power/Video/ROM pcb
- has the game roms on it
- has the main B&W video generation logic on it
- has the larger connection to the PSU, and B&W composite output "T" connector
* 2 layer pcb set details:
* This pcb set came in one version: PVN, and is entirely exchangeable
with the 3 layer PVN pcb set.
* Top pcb is same as 3 layer pcb set
* Bottom pcb combines the function of the Middle and Bottom pcbs
of the 3 layer set.
* The different pcb set versions are noted by a different version code on
a paper sticker on the pcb; The code will be of the format mVNnnnnn where
m is a letter and nnnnn is a number.
Codes:
* TVNxxxxx (3 layer pcbset) - B&W only, used on "T.T Space Invaders"
cocktail with 'blended' single-sheet gel color overlay.
***TODO: this overlay is not supported yet!
Several revisions (at least 5 rom, 3 cpu, 3 audio) of each pcb exist
for this set.
Does support flipscreen.
Does not have the color overlay circuitry nor places for it on the pcbs.
(Later TVNxxxxx are actually rebadged CVNxxxxx, see below)
Came from factory with one of the SV or TV romsets.
Capable of running TV, SV or CV romsets.
This pcb set is probably the oldest one and was designed at Taito.
* SVNxxxxx? (L-shaped pcbset) - B&W only, used on "Space Invaders" Upright
with 3-separate-sheets-of-gel 'strips' color overlay.
***TODO: this overlay might not be supported properly yet!
Does not support flipscreen, was intended for upright cabinets only.
Audio PCB daughterboard has part number SVN00001 or SVN00003.
Came from factory with one of the 6x 0x400 or 4x 0x800 romsets
Capable of running TV, SV or CV romsets.
This is probably the second-oldest pcb set and may have been made to
allow closer physical interchangeability with Midway's m8080bw hardware,
which had a similar board shape?
* CVNxxxxx (3 layer pcbset) - Color, used on "T.T Space Invaders Color"
cocktail with electronic color overlay.
Does support flipscreen.
Note that later TVNxxxxx pcbsets are actually 'rebadged' CVNxxxxx
pcbsets with the color overlay circuitry unpopulated, and can be
'upgraded' to CVNxxxxx by adding a few components and proms.
Came from factory with one of the CV romsets.
Capable of running TV, SV or CV romsets.
* PVNxxxxx (2&3 layer pcbsets) - Color, used on "T.T Space Invaders Part
II" cocktail with electronic color overlay.
Several revisions (at least 3 rom, 1 cpu, 2 audio) of each pcb exist
for this set.
Came from factory with UV (2708) or PV (2716) romsets.
Capable of running TV, SV, CV, UV or PV romsets.
* The following Romsets are known, ROUGHLY from oldest to newest:
SV01, SV02, SV03, SV04, SV05, SV06 - undumped (rev 1), If this exists at all this would be the very first japan release of space invaders (Andy W may call this 'SV0'?)
SV01, SV02, SV10, SV04, SV09, SV06 - sisv2 (rev 2) (Andy W calls this 'SV1', and the midway 'invaders' set is based on this romset)
SV0H, SV02, SV10, SV04, SV09, SV06 - sisv3 (rev 3) (Andy W calls this 'SV2')
SV0H, SV11, SV12, SV04, SV13, SV14 - sisv (rev 4, 5-digit scoring) (Andy W calls this 'SV3') (this set is likely newer than the TV0x sets)
TV01, TV02, TV03, TV04 - sitv1 (rev 1)
TV0H, TV02, TV03, TV04 - sitv (rev 2 with bug fixes)
CV03, CV04, CV05, CV06 w/proms - undumped (but may be the same as one of the sisv sets with the roms combined to 2716 size)
CV17, CV18, CV19, CV20 w/proms - sicv
UV1, UV2, UV3, UV4, UV5, UV6, UV7, UV8, UV9, UV10 w/proms - undumped (probably same as pvxx set just split differently)
PV01, PV02, PV03, PV04, PV05 w/proms - invadpt2
Note: SV0H and TV0H are called in taito documentation "SV01-1" and "TV01-1" most likely due to someone along the line mistaking the '1-1' for an H or vice versa when writing the documentation or creating the labels.
- Midway PCB sets: (cursory descripton)
* All Midway Space Invaders games ([Space Invader Upright], [Space Invader Cocktail],
[Deluxe Space Invaders Upright], [Deluxe Space Invaders Cocktail], and [Space Invaders II])
use the same m8080bw mainboard, with no emulation-relevant differences between revisions.
* [Space Invaders II] from Midway (only produced as a cocktail) uses
an extra sound board for the simultaneous 2 player head-to-head sounds.
- Taito-USA-made 'trimline' PCBS do not match the taito japan-made pcbs either.
To Do:
-----
- Midway PCB sets
* The discrete components, particularly for the shot sound, differ
between Taito and Midway audio daughterboards.
+ Figure out the difference between the Taito and Midway discrete
boards and emulate them both properly.
+ Figure out what the current discrete setup is trying to emulate.
* Remove Space Invaders 'invaders' set from mw8080bw.c, it does not belong
there at all
- Space Chaser (schaser)
1. Schematic has SX2 & 4 swapped by mistake.
2. Dipswitch 4 we have listed as "Easy/Hard", however the manual says
it should not be used. The Hard position displays many bugs.
3. Confirmation of these on a real machine (schaserb set) have been
received from the owner of the PCB.
"Hi Rob,
I seem to get the same bugs as you with Dip4 set to off. Score starts at 9000,
2 missiles on first level etc.. It makes no mention of dip4 adjusting the hardness
in the manual, are you guys sure that's what it was intended for "in the factory"?
However you were correct in thinking the schematics were wrong. My multimeter found
the following:
15k resistor - pin 7
39k - pin 10
82k - pin 12
It looks like they have Sx2 and Sx4 the wrong way round on a latter page of the schematics."
Thanks to Andy Raven for getting this information.
4. The "Hard" mode bug can be fixed with a single byte patch: ROM_FILL( 0x47e5, 1, 0xc3)
5. I have seen real machines with Hard mode set, that worked properly, thus there
must be yet another romset still waiting to be found.
6. Strange bug; sometimes the missile sound continues into and past the
music/explosion. This didn't happen on the real machines I played.
- Space Chaser (schasercv)
These cheats exist in this game:
1. Hold down 2P DOWN (the F key) while it says INSERT COIN. Then
insert a coin and play. You will have 2 extra ships.
2. In the Hard difficulty setting, you normally start at level 4.
Hold down the 1P START (the 1 key) while it says INSERT COIN.
Then insert a coin and play. You will start at level 5.
- Space War (Sanritsu)
* I seem to recall that the flashing ufo had its own sample
sound, a sort of rattling noise. Unable to find evidence
of this (so far).
- Steel Worker, Space Combat
Holding down the coin button causes the credits to rapidly increase.
*****************************************************************************/
#include "emu.h"
#include "includes/8080bw.h"
#include "cpu/m6800/m6800.h"
#include "cpu/i8085/i8085.h"
#include "machine/watchdog.h"
#include "sound/ay8910.h"
#include "speaker.h"
#include "attackfc.lh"
#include "cosmicm.lh"
#include "escmars.lh"
#include "galactic.lh"
#include "gunchamp.lh"
#include "shuttlei.lh"
#include "spacecom.lh"
#include "yosakdon.lh"
/*******************************************************/
/* */
/* Games with additional sound / video hardware */
/* */
/*******************************************************/
MACHINE_START_MEMBER(_8080bw_state,extra_8080bw)
{
mw8080bw_state::machine_start();
MACHINE_START_CALL_MEMBER(extra_8080bw_sh);
MACHINE_START_CALL_MEMBER(extra_8080bw_vh);
}
/*******************************************************/
/* */
/* Space Invaders CV Version (Taito) */
/* */
/*******************************************************/
static INPUT_PORTS_START( sicv )
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_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_START("IN2")
PORT_DIPNAME( 0x03, 0x00, DEF_STR( Lives ) ) PORT_DIPLOCATION("SW1:1,2")
PORT_DIPSETTING( 0x00, "3" )
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_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_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 */
INVADERS_CONTROL_PORT_P1
/* Dummy controls port, P2 */
INVADERS_CONTROL_PORT_P2
/* Dummy port for cocktail mode */
INVADERS_CAB_TYPE_PORT
INPUT_PORTS_END
/*******************************************************/
/* */
/* Space Invaders TV Version (Taito) */
/* */
/*******************************************************/
/* same as the CV version with a test mode switch */
static INPUT_PORTS_START( sitv )
PORT_INCLUDE( sicv )
PORT_MODIFY("IN0")
PORT_SERVICE( 0x01, IP_ACTIVE_LOW )
PORT_MODIFY("IN1")
PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_UNKNOWN )
INPUT_PORTS_END
/*******************************************************/
/* */
/* Alien Invasion */
/* */
/*******************************************************/
static INPUT_PORTS_START( alieninv )
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_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_LOW, IPT_UNKNOWN )
PORT_START("IN2")
PORT_DIPNAME( 0x01, 0x01, DEF_STR( Lives ) ) PORT_DIPLOCATION("SW1:1")
PORT_DIPSETTING( 0x00, "2" )
PORT_DIPSETTING( 0x01, "3" )
PORT_DIPNAME( 0x02, 0x02, "Pence Coinage" ) PORT_DIPLOCATION("SW1:2")
PORT_DIPSETTING( 0x02, DEF_STR( Off ) )
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_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" )
/* Dummy controls port, P1 */
INVADERS_CONTROL_PORT_P1
/* Dummy controls port, P2 */
INVADERS_CONTROL_PORT_P2
/* Dummy port for cocktail mode */
INVADERS_CAB_TYPE_PORT
INPUT_PORTS_END
/*******************************************************/
/* */
/* Space Invaders Model Racing */
/* */
/*******************************************************/
static INPUT_PORTS_START( invadrmr )
PORT_INCLUDE( sicv )
PORT_MODIFY("IN2")
PORT_DIPNAME( 0x08, 0x00, DEF_STR( Bonus_Life ) ) PORT_DIPLOCATION("SW1:4")
PORT_DIPSETTING( 0x00, "1500" )
PORT_DIPSETTING( 0x08, "3000" ) /* This is different to invaders */
INPUT_PORTS_END
/*******************************************************/
/* */
/* Midway "Space Invaders Part II" */
/* */
/*******************************************************/
void _8080bw_state::invadpt2_io_map(address_map &map)
{
map(0x00, 0x00).portr("IN0");
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(0x04, 0x04).w(m_mb14241, FUNC(mb14241_device::shift_data_w));
map(0x05, 0x05).w(FUNC(_8080bw_state::invadpt2_sh_port_2_w));
map(0x06, 0x06).w(m_watchdog, FUNC(watchdog_timer_device::reset_w));
}
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_MODIFY("IN1")
PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_UNKNOWN )
PORT_MODIFY("IN2")
PORT_DIPNAME( 0x01, 0x00, DEF_STR( Lives ) ) PORT_DIPLOCATION("SW1:1")
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_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 ) )
INPUT_PORTS_END
/* same as regular invaders, but with a color board added */
void _8080bw_state::invadpt2(machine_config &config)
{
mw8080bw_root(config);
/* basic machine hardware */
m_maincpu->set_addrmap(AS_IO, &_8080bw_state::invadpt2_io_map);
MCFG_MACHINE_START_OVERRIDE(_8080bw_state,extra_8080bw)
/* 60 Hz signal clocks two LS161. Ripple carry will */
/* reset circuit, if LS161 not cleared before. */
WATCHDOG_TIMER(config, m_watchdog).set_vblank_count("screen", 255);
/* add shifter */
MB14241(config, m_mb14241);
/* video hardware */
m_screen->set_screen_update(FUNC(_8080bw_state::screen_update_invadpt2));
PALETTE(config, m_palette, palette_device::RBG_3BIT);
/* sound hardware */
invaders_samples_audio(config);
}
/*******************************************************/
/* */
/* Space Ranger */
/* */
/*******************************************************/
void _8080bw_state::spacerng_io_map(address_map &map)
{
map(0x00, 0x00).portr("IN0");
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(0x04, 0x04).w(m_mb14241, FUNC(mb14241_device::shift_data_w));
map(0x05, 0x05).w(FUNC(_8080bw_state::spacerng_sh_port_2_w));
map(0x06, 0x06).w(m_watchdog, FUNC(watchdog_timer_device::reset_w));
}
void _8080bw_state::spacerng(machine_config &config)
{
invadpt2(config);
/* basic machine hardware */
m_maincpu->set_addrmap(AS_IO, &_8080bw_state::spacerng_io_map);
}
/*******************************************************/
/* */
/* Space Wars (Sanritsu) */
/* */
/*******************************************************/
void _8080bw_state::spcewars_io_map(address_map &map)
{
map(0x00, 0x00).portr("IN0");
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::spcewars_sh_port_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));
}
static INPUT_PORTS_START( spcewars )
PORT_INCLUDE( sicv )
PORT_MODIFY("IN1")
PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_UNKNOWN )
PORT_MODIFY("IN2")
PORT_DIPNAME( 0x01, 0x00, DEF_STR( Lives ) ) PORT_DIPLOCATION("SW1:1")
PORT_DIPSETTING( 0x00, "3" )
PORT_DIPSETTING( 0x01, "4" )
PORT_DIPUNKNOWN_DIPLOC( 0x02, 0x00, "SW1:2" )
PORT_DIPNAME( 0x08, 0x00, DEF_STR( Bonus_Life ) ) PORT_DIPLOCATION("SW1:4")
PORT_DIPSETTING( 0x00, "1500" )
PORT_DIPSETTING( 0x08, "2000" )
INPUT_PORTS_END
void _8080bw_state::spcewars(machine_config &config)
{
mw8080bw_root(config);
/* basic machine hardware */
m_maincpu->set_addrmap(AS_IO, &_8080bw_state::spcewars_io_map);
MCFG_MACHINE_START_OVERRIDE(_8080bw_state,extra_8080bw)
/* add shifter */
MB14241(config, m_mb14241);
/* sound hardware */
invaders_samples_audio(config);
/* extra audio channel */
SPEAKER_SOUND(config, m_speaker);
m_speaker->add_route(ALL_OUTPUTS, "mono", 0.25);
/* video hardware */
m_screen->set_screen_update(FUNC(_8080bw_state::screen_update_invaders));
}
/*******************************************************/
/* */
/* Space War (Leisure and Allied) */
/* */
/*******************************************************/
// has a slightly rearranged io map and has PROMs and watchdog
void _8080bw_state::spcewarla_io_map(address_map &map)
{
map(0x00, 0x00).portr("IN0");
map(0x01, 0x01).portr("IN1");
map(0x02, 0x02).portr("IN2");
map(0x04, 0x04).w(FUNC(_8080bw_state::spcewars_sh_port_w));
map(0x05, 0x05).w(FUNC(_8080bw_state::invadpt2_sh_port_2_w));
map(0x06, 0x06).r(m_mb14241, FUNC(mb14241_device::shift_result_r)).w(m_watchdog, FUNC(watchdog_timer_device::reset_w));
map(0x08, 0x08).w(m_mb14241, FUNC(mb14241_device::shift_count_w));
map(0x0c, 0x0c).w(m_mb14241, FUNC(mb14241_device::shift_data_w));
}
void _8080bw_state::spcewarla(machine_config &config)
{
spcewars(config);
m_maincpu->set_addrmap(AS_IO, &_8080bw_state::spcewarla_io_map);
WATCHDOG_TIMER(config, m_watchdog).set_vblank_count("screen", 255);
PALETTE(config, m_palette, palette_device::RBG_3BIT);
m_screen->set_screen_update(FUNC(_8080bw_state::screen_update_invadpt2));
}
/*******************************************************/
/* */
/* Astro Sidam? */
/* */
/*******************************************************/
void _8080bw_state::astropal_io_map(address_map &map)
{
map.global_mask(0x7);
map(0x00, 0x00).mirror(0x04).portr("IN0");
map(0x01, 0x01).mirror(0x04).portr("IN1");
map(0x03, 0x03).mirror(0x04).portr("IN3");
map(0x03, 0x03).w("soundboard", FUNC(invaders_audio_device::p1_w));
map(0x05, 0x05).w("soundboard", FUNC(invaders_audio_device::p2_w));
map(0x06, 0x06).w(m_watchdog, FUNC(watchdog_timer_device::reset_w));
}
static INPUT_PORTS_START( astropal )
PORT_START("IN0")
PORT_DIPNAME( 0x03, 0x00, DEF_STR( Lives ) )
PORT_DIPSETTING( 0x00, "2" )
PORT_DIPSETTING( 0x01, "3" )
PORT_DIPSETTING( 0x02, "4" )
PORT_DIPSETTING( 0x03, "5" )
PORT_BIT( 0xfc, IP_ACTIVE_LOW, IPT_UNUSED ) /* 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_BUTTON2 )
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") - never read */
PORT_START("IN3")
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_BIT( 0x08, IP_ACTIVE_HIGH, IPT_UNUSED )
PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_UNUSED )
PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_UNUSED )
PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_UNUSED )
PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_BUTTON3 )
/* Dummy port for cocktail mode (not used) */
PORT_START(INVADERS_CAB_TYPE_PORT_TAG)
PORT_BIT( 0xff, IP_ACTIVE_HIGH, IPT_UNKNOWN )
INPUT_PORTS_END
void _8080bw_state::astropal(machine_config &config)
{
invaders(config);
/* basic machine hardware */
m_maincpu->set_addrmap(AS_IO, &_8080bw_state::astropal_io_map);
}
/*******************************************************/
/* */
/* Cosmo */
/* */
/*******************************************************/
void _8080bw_state::cosmo_map(address_map &map)
{
map(0x0000, 0x1fff).rom();
map(0x2000, 0x3fff).ram().share("main_ram");
map(0x4000, 0x57ff).rom();
map(0x5c00, 0x5fff).ram().share("colorram");
}
/* at least one of these MWA8_NOPs must be sound related */
void _8080bw_state::cosmo_io_map(address_map &map)
{
map(0x00, 0x00).portr("IN0").nopw();
map(0x01, 0x01).portr("IN1").nopw();
map(0x02, 0x02).portr("IN2").nopw();
map(0x03, 0x03).w(FUNC(_8080bw_state::invadpt2_sh_port_1_w));
map(0x05, 0x05).w(FUNC(_8080bw_state::cosmo_sh_port_2_w));
map(0x06, 0x06).w(m_watchdog, FUNC(watchdog_timer_device::reset_w));
map(0x07, 0x07).nopw();
}
static INPUT_PORTS_START( cosmo )
PORT_INCLUDE( sicv )
PORT_MODIFY("IN1")
PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_UNKNOWN )
PORT_MODIFY("IN2")
PORT_DIPNAME( 0x01, 0x00, DEF_STR( Lives ) ) PORT_DIPLOCATION("SW1:1")
PORT_DIPSETTING( 0x00, "3" )
PORT_DIPSETTING( 0x01, "5" )
PORT_DIPUNKNOWN_DIPLOC( 0x02, 0x00, "SW1:2" )
PORT_DIPUNKNOWN_DIPLOC( 0x04, 0x00, "SW1:3" )
PORT_DIPUNKNOWN_DIPLOC( 0x08, 0x00, "SW1:4" )
PORT_DIPUNKNOWN_DIPLOC( 0x80, 0x80, "SW1:8" ) /* must be HIGH normally or the joystick won't work */
INPUT_PORTS_END
void _8080bw_state::cosmo(machine_config &config)
{
mw8080bw_root(config);
/* basic machine hardware */
m_maincpu->set_addrmap(AS_PROGRAM, &_8080bw_state::cosmo_map);
m_maincpu->set_addrmap(AS_IO, &_8080bw_state::cosmo_io_map);
WATCHDOG_TIMER(config, m_watchdog);
MCFG_MACHINE_START_OVERRIDE(_8080bw_state,extra_8080bw)
/* video hardware */
m_screen->set_screen_update(FUNC(_8080bw_state::screen_update_cosmo));
PALETTE(config, m_palette, palette_device::RGB_3BIT);
/* sound hardware */
invaders_samples_audio(config);
}
/*******************************************************/
/* */
/* bootleg "Super Earth Invasion" */
/* */
/*******************************************************/
static INPUT_PORTS_START( searthin )
PORT_INCLUDE( sicv )
PORT_MODIFY("IN1")
PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_UNKNOWN )
PORT_MODIFY("IN2")
PORT_DIPNAME( 0x01, 0x01, DEF_STR( Lives ) ) PORT_DIPLOCATION("SW1:1")
PORT_DIPSETTING( 0x00, "2" )
PORT_DIPSETTING( 0x01, "3" )
PORT_DIPNAME( 0x02, 0x02, "Pence Coinage" ) PORT_DIPLOCATION("SW1:2")
PORT_DIPSETTING( 0x02, DEF_STR( Off ) )
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_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" )
INPUT_PORTS_END
/*******************************************************/
/* */
/* bootleg "Super Invaders (Zenitone-Microsec)" */
/* */
/*******************************************************/
static INPUT_PORTS_START( sinvzen )
PORT_INCLUDE( sicv )
PORT_MODIFY("IN2")
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 ) )
INPUT_PORTS_END
/*******************************************************/
/* */
/* bootleg "Space Attack II" */
/* */
/*******************************************************/
static INPUT_PORTS_START( spaceat2 )
PORT_INCLUDE( sicv )
PORT_MODIFY("IN2")
PORT_DIPUNKNOWN_DIPLOC( 0x10, 0x00, "SW1:5" )
PORT_DIPUNKNOWN_DIPLOC( 0x20, 0x00, "SW1:6" )
PORT_DIPUNKNOWN_DIPLOC( 0x40, 0x00, "SW1:7" )
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 ) )
/* Dummy port for cocktail mode (not used) */
PORT_MODIFY(INVADERS_CAB_TYPE_PORT_TAG)
PORT_BIT( 0xff, IP_ACTIVE_HIGH, IPT_UNKNOWN )
INPUT_PORTS_END
/*******************************************************/
/* */
/* bootleg "Space Combat", 1979 */
/* 8080A + 18MHz XTAL, SN76477, 10MHz XTAL */
/* 8*8116 2KB RAM(!), 8*1KB ROM, maybe some PROMs */
/* */
/* Preliminary emulation. PCB was working fine, but */
/* it's not certain that this is a good dump */
/* */
/* TODO: */
/* - dip settings/locs need confirming */
/* - it doesn't have a mb14241 video shifter? */
/* - using space invaders audio as placeholder until */
/* more is known about the sound hw */
/* - always in cocktail mode but flipscreen not found */
/* */
/*******************************************************/
static INPUT_PORTS_START( spacecom )
PORT_START("IN0") // 5-pos dipsw at ic79 (row F)
PORT_DIPNAME( 0x01, 0x01, DEF_STR( Unknown ) )
PORT_DIPSETTING( 0x01, DEF_STR( Off ) )
PORT_DIPSETTING( 0x00, DEF_STR( On ) )
PORT_DIPNAME( 0x02, 0x02, DEF_STR( Unknown ) )
PORT_DIPSETTING( 0x02, DEF_STR( Off ) )
PORT_DIPSETTING( 0x00, DEF_STR( On ) )
PORT_DIPNAME( 0x04, 0x00, DEF_STR( Lives ) )
PORT_DIPSETTING( 0x00, "3" )
PORT_DIPSETTING( 0x04, "5" )
PORT_DIPNAME( 0x08, 0x08, DEF_STR( Bonus_Life ) )
PORT_DIPSETTING( 0x00, "2500" ) // not confirmed
PORT_DIPSETTING( 0x08, "1500" )
PORT_DIPNAME( 0x10, 0x10, DEF_STR( Unknown ) )
PORT_DIPSETTING( 0x10, DEF_STR( Off ) )
PORT_DIPSETTING( 0x00, DEF_STR( On ) )
PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_BUTTON1 ) PORT_PLAYER(2)
PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_JOYSTICK_LEFT ) PORT_2WAY PORT_PLAYER(2)
PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_JOYSTICK_RIGHT ) PORT_2WAY PORT_PLAYER(2)
PORT_START("IN1")
PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_COIN1 )
PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_START2 )
PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_START1 )
PORT_SERVICE( 0x08, IP_ACTIVE_HIGH )
PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_UNKNOWN )
PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_BUTTON1 )
PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_JOYSTICK_LEFT ) PORT_2WAY
PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_JOYSTICK_RIGHT ) PORT_2WAY
PORT_START("IN2")
PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_CUSTOM ) PORT_VBLANK("screen")
PORT_BIT( 0xfe, IP_ACTIVE_HIGH, IPT_UNKNOWN ) // unused?
PORT_START(CABINET_PORT_TAG) /* Dummy port for cocktail mode */
PORT_BIT( 0xff, IP_ACTIVE_LOW, IPT_UNKNOWN )
INPUT_PORTS_END
void _8080bw_state::spacecom_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)
{
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)
{
/* basic machine hardware */
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
m_maincpu->set_addrmap(AS_PROGRAM, &_8080bw_state::spacecom_map);
m_maincpu->set_addrmap(AS_IO, &_8080bw_state::spacecom_io_map);
m_maincpu->set_irq_acknowledge_callback(FUNC(_8080bw_state::interrupt_vector));
MCFG_MACHINE_RESET_OVERRIDE(mw8080bw_state, mw8080bw)
/* 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));
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; });
}
void _8080bw_state::init_spacecom()
{
uint8_t *ROM = memregion("maincpu")->base();
// bad byte: should be push a at RST 10h
ROM[0x10] = 0xf5;
}
/*******************************************************/
/* */
/* Zenitone Microsec "Invaders Revenge" */
/* */
/*******************************************************/
READ8_MEMBER(_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)
{
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(0x04, 0x04).w(m_mb14241, FUNC(mb14241_device::shift_data_w));
map(0x05, 0x05).w(FUNC(_8080bw_state::invrvnge_port05_w));
map(0x06, 0x06).w(m_watchdog, FUNC(watchdog_timer_device::reset_w));
}
void _8080bw_state::invrvnge_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(0xc000, 0xc7ff).mirror(0x1800).rom();
map(0xe000, 0xe7ff).mirror(0x1800).rom();
}
static INPUT_PORTS_START( invrvnge )
PORT_START("IN0")
PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_UNUSED )
PORT_DIPNAME( 0x06, 0x00, DEF_STR( Difficulty ) ) PORT_DIPLOCATION("SW1:5,6") // [code: 0x3b1-3b5]
PORT_DIPSETTING( 0x00, DEF_STR( Easy ) )
PORT_DIPSETTING( 0x02, DEF_STR( Hard ) )
PORT_DIPSETTING( 0x04, DEF_STR( Harder ) )
PORT_DIPSETTING( 0x06, DEF_STR( Hardest ) )
PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_UNKNOWN ) // must be low or game won't boot [code: 0x1a9-1af]
PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_UNUSED )
PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_UNUSED )
PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_UNUSED )
PORT_DIPNAME( 0x80, 0x80, "Fuel Destroyed by Comet" ) PORT_DIPLOCATION("SW1:7") // [code: 0x1cb0-1cb6]
PORT_DIPSETTING( 0x00, "3" )
PORT_DIPSETTING( 0x80, "6" )
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_DIPNAME( 0x03, 0x00, DEF_STR( Lives ) ) PORT_DIPLOCATION("SW1:1,2")
PORT_DIPSETTING( 0x00, "3" )
PORT_DIPSETTING( 0x01, "4" )
PORT_DIPSETTING( 0x02, "5" )
PORT_DIPSETTING( 0x03, "6" )
PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_TILT )
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_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 */
INVADERS_CAB_TYPE_PORT
INPUT_PORTS_END
void _8080bw_state::invrvnge(machine_config &config)
{
mw8080bw_root(config);
/* basic machine hardware */
m_maincpu->set_addrmap(AS_IO, &_8080bw_state::invrvnge_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);
/* 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));
PALETTE(config, m_palette, palette_device::RBG_3BIT);
/* sound hardware */
SPEAKER(config, "mono").front_center();
// CPU E-pin connects to AY clock pin
ay8910_device &psg(AY8910(config, "psg", XTAL(4'000'000)/2));
psg.port_a_read_callback().set([this] () { return m_sound_data >> 1; });
psg.port_b_read_callback().set_constant(0xff);
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)/2)/512));
}
void _8080bw_state::init_invrvnge()
{
uint8_t *rom = memregion("audiocpu")->base();
for (offs_t i = 0xc000; i < 0xc800; i++)
rom[i] = bitswap<8>(rom[i], 7, 6, 5, 3, 4, 2, 1, 0);
for (offs_t i = 0xe000; i < 0xe800; i++)
rom[i] = bitswap<8>(rom[i], 7, 6, 5, 3, 4, 2, 1, 0);
}
/*******************************************************/
/* */
/* Taito "Space Laser" */
/* */
/*******************************************************/
static INPUT_PORTS_START( spclaser )
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_START("IN1")
PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_COIN1 )
PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_START2 ) /* This is not 2 Player ??? */
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_HIGH, IPT_UNKNOWN )
// TODO: figure out where dipswitch is read, it's not IN0 or IN2 in the current implementation.
// ROM disassembly doesn't show any dipswitch reads on portmapped I/O, maybe the manual is for a different ROM set? (that we don't have the dump for)
#if 0
// these are the settings according to Gameplan Intruder manual
PORT_DIPNAME( 0x03, 0x02, DEF_STR( Lives ) ) PORT_DIPLOCATION("SW1:1,2")
PORT_DIPSETTING( 0x00, "3" )
PORT_DIPSETTING( 0x01, "4" )
PORT_DIPSETTING( 0x02, "5" )
PORT_DIPSETTING( 0x03, "6" )
PORT_SERVICE_DIPLOC( 0x04, IP_ACTIVE_LOW, "SW1:3" )
PORT_DIPNAME( 0x08, 0x08, DEF_STR( Bonus_Life ) ) PORT_DIPLOCATION("SW1:4")
PORT_DIPSETTING( 0x08, "1000" )
PORT_DIPSETTING( 0x00, "1500" )
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_DIPNAME( 0x80, 0x80, "Display Coinage" ) PORT_DIPLOCATION("SW:8")
PORT_DIPSETTING( 0x80, DEF_STR( Off ) )
PORT_DIPSETTING( 0x00, DEF_STR( On ) )
#endif
PORT_START("IN2")
PORT_DIPUNKNOWN_DIPLOC( 0x01, 0x00, "SW1:1" )
PORT_DIPUNKNOWN_DIPLOC( 0x02, 0x00, "SW1:2" )
PORT_DIPUNKNOWN_DIPLOC( 0x04, 0x00, "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_DIPNAME( 0x80, 0x00, DEF_STR(Coinage) ) PORT_DIPLOCATION("SW1:8")
PORT_DIPSETTING( 0x00, "1 Coin/1 Or 2 Players" )
PORT_DIPSETTING( 0x80, "1 Coin/1 Player 2 Coins/2 Players" ) /* Irrelevant, causes bugs */
/* Dummy port for cocktail mode (not used) */
PORT_START(CABINET_PORT_TAG)
PORT_BIT( 0xff, IP_ACTIVE_HIGH, IPT_UNKNOWN )
INPUT_PORTS_END
/*******************************************************/
/* */
/* Taito "Galaxy Wars" */
/* */
/*******************************************************/
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_MODIFY("IN2")
PORT_DIPNAME( 0x03, 0x01, DEF_STR( Lives ) ) PORT_DIPLOCATION("SW1:1,2")
PORT_DIPSETTING( 0x00, "2" )
PORT_DIPSETTING( 0x01, "3" )
PORT_DIPSETTING( 0x02, "4" )
PORT_DIPSETTING( 0x03, "5" )
PORT_DIPUNKNOWN_DIPLOC( 0x04, 0x00, "SW1:3" )
PORT_DIPNAME( 0x08, 0x00, DEF_STR( Bonus_Life ) ) PORT_DIPLOCATION("SW1:4")
PORT_DIPSETTING( 0x00, "3000" )
PORT_DIPSETTING( 0x08, "5000" )
PORT_DIPNAME( 0x80, 0x00, DEF_STR( Coinage ) ) PORT_DIPLOCATION("SW1:8")
PORT_DIPSETTING( 0x80, DEF_STR( 1C_2C ) )
PORT_DIPSETTING( 0x00, DEF_STR( 1C_1C ) )
INPUT_PORTS_END
void _8080bw_state::starw1_io_map(address_map &map)
{
map(0x01, 0x01).portr("IN1");
map(0x02, 0x02).portr("IN2");
map(0x03, 0x03).nopw(); /* writes 9B at boot */
map(0x04, 0x04).w(FUNC(_8080bw_state::invadpt2_sh_port_1_w));
map(0x05, 0x05).w(FUNC(_8080bw_state::invadpt2_sh_port_2_w));
map(0x06, 0x06).w(m_watchdog, FUNC(watchdog_timer_device::reset_w));
map(0x07, 0x07).nopw(); /* writes 89 at boot */
}
void _8080bw_state::starw1(machine_config &config)
{
invadpt2(config);
m_maincpu->set_addrmap(AS_IO, &_8080bw_state::starw1_io_map);
}
/*******************************************************/
/* */
/* Taito "Lunar Rescue" */
/* */
/*******************************************************/
void _8080bw_state::escmars_map(address_map &map)
{
map(0x0000, 0x1fff).rom();
map(0x2000, 0x3fff).ram().share("main_ram");
map(0x4000, 0x4fff).rom();
}
void _8080bw_state::lrescue_io_map(address_map &map)
{
map(0x00, 0x00).portr("IN0");
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::lrescue_sh_port_1_w));
map(0x04, 0x04).w(m_mb14241, FUNC(mb14241_device::shift_data_w));
map(0x05, 0x05).w(FUNC(_8080bw_state::lrescue_sh_port_2_w));
}
static INPUT_PORTS_START( lrescue )
PORT_INCLUDE( sicv )
PORT_MODIFY("IN1")
PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_UNKNOWN )
PORT_MODIFY("IN2")
/* SW1:3-8 Unused according to manual: "Factory Adjustments". Default is ON. */
PORT_DIPUNUSED_DIPLOC( 0x08, 0x00, "SW1:4" )
PORT_DIPUNUSED_DIPLOC( 0x80, 0x00, "SW1:8" )
INPUT_PORTS_END
void _8080bw_state::lrescue(machine_config &config)
{
mw8080bw_root(config);
/* basic machine hardware */
m_maincpu->set_addrmap(AS_IO, &_8080bw_state::lrescue_io_map);
MCFG_MACHINE_START_OVERRIDE(_8080bw_state,extra_8080bw)
/* add shifter */
MB14241(config, m_mb14241);
/* video hardware */
m_screen->set_screen_update(FUNC(_8080bw_state::screen_update_invadpt2));
PALETTE(config, m_palette, palette_device::RBG_3BIT);
/* sound hardware */
SPEAKER(config, "mono").front_center();
SAMPLES(config, m_samples);
m_samples->set_channels(4);
m_samples->set_samples_names(lrescue_sample_names);
m_samples->add_route(ALL_OUTPUTS, "mono", 0.75);
/* extra audio channel */
SPEAKER_SOUND(config, m_speaker);
m_speaker->add_route(ALL_OUTPUTS, "mono", 0.25);
}
void _8080bw_state::escmars(machine_config &config)
{
/* basic machine hardware */
I8080(config, m_maincpu, XTAL(18'000'000) / 10); // divider guessed
m_maincpu->set_addrmap(AS_PROGRAM, &_8080bw_state::escmars_map);
m_maincpu->set_addrmap(AS_IO, &_8080bw_state::lrescue_io_map);
m_maincpu->set_irq_acknowledge_callback(FUNC(_8080bw_state::interrupt_vector));
MCFG_MACHINE_START_OVERRIDE(_8080bw_state, extra_8080bw)
MCFG_MACHINE_RESET_OVERRIDE(_8080bw_state, mw8080bw)
/* add shifter */
MB14241(config, m_mb14241);
/* 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);
m_screen->set_screen_update(FUNC(_8080bw_state::screen_update_mw8080bw));
PALETTE(config, m_palette, palette_device::MONOCHROME);
/* sound hardware */
SPEAKER(config, "mono").front_center();
SAMPLES(config, m_samples);
m_samples->set_channels(4);
m_samples->set_samples_names(lrescue_sample_names);
m_samples->add_route(ALL_OUTPUTS, "mono", 0.75);
/* extra audio channel */
SPEAKER_SOUND(config, m_speaker);
m_speaker->add_route(ALL_OUTPUTS, "mono", 0.25);
}
/*******************************************************/
/* */
/* Universal "Cosmic Monsters" */
/* The dipswitches 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 */
/* is all done by wires. */
/* */
/* These issues may be due to manual/romset conflicts */
/* */
/*******************************************************/
static INPUT_PORTS_START( cosmicmo )
PORT_INCLUDE( sicv )
PORT_MODIFY("IN1")
PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_UNKNOWN )
PORT_MODIFY("IN2")
PORT_DIPNAME( 0x03, 0x01, DEF_STR( Lives ) ) PORT_DIPLOCATION("SW1:1,2")
PORT_DIPSETTING( 0x00, "2" )
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_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_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)
PORT_BIT( 0xff, IP_ACTIVE_HIGH, IPT_UNKNOWN )
INPUT_PORTS_END
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(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));
map(0x03, 0x03).w("soundboard", FUNC(invaders_audio_device::p1_w));
map(0x04, 0x04).w(m_mb14241, FUNC(mb14241_device::shift_data_w));
map(0x05, 0x05).w("soundboard", FUNC(invaders_audio_device::p2_w));
map(0x06, 0x06).w(m_watchdog, FUNC(watchdog_timer_device::reset_w));
}
void _8080bw_state::cosmicmo(machine_config &config)
{
mw8080bw_root(config);
// basic machine hardware
m_maincpu->set_addrmap(AS_IO, &_8080bw_state::cosmicmo_io_map);
MCFG_MACHINE_START_OVERRIDE(_8080bw_state,extra_8080bw)
WATCHDOG_TIMER(config, m_watchdog).set_vblank_count("screen", 255);
// add shifter
MB14241(config, m_mb14241);
// sound hardware
INVADERS_AUDIO(config, "soundboard").
flip_screen_out().set([this] (int state) { m_flip_screen = (state && BIT(ioport("IN2")->read(), 2)) ? 1 : 0; });
/* video hardware */
m_screen->set_screen_update(FUNC(_8080bw_state::screen_update_invaders));
}
/*******************************************************/
/* */
/* Sidam "Invasion" */
/* */
/*******************************************************/
static INPUT_PORTS_START( invasion )
PORT_INCLUDE( sicv )
PORT_MODIFY("IN1")
PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_COIN1 )
PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_COIN2 )
PORT_MODIFY("IN2")
/* SW1:5-8 Unused according to manual. */
PORT_DIPNAME( 0x03, 0x03, DEF_STR( Lives ) ) PORT_DIPLOCATION("SW1:4,3") /* Default is OFF, OFF (6) */
PORT_DIPSETTING( 0x00, "3" )
PORT_DIPSETTING( 0x01, "4" )
PORT_DIPSETTING( 0x02, "5" )
PORT_DIPSETTING( 0x03, "6" )
PORT_DIPUNUSED_DIPLOC( 0x04, 0x04, "SW1:8" ) /* Default OFF */
PORT_DIPNAME( 0x08, 0x00, DEF_STR( Bonus_Life ) ) PORT_DIPLOCATION("SW1:2") /* Default is ON (2500) */
PORT_DIPSETTING( 0x08, "1500" )
PORT_DIPSETTING( 0x00, "2500" )
/* SW1:5,6,7 Default ON */
PORT_DIPNAME( 0x80, 0x80, "Laser Bonus Info" ) PORT_DIPLOCATION("SW1:1") /* Default is OFF (Info on) */
PORT_DIPSETTING( 0x00, DEF_STR( Off ) )
PORT_DIPSETTING( 0x80, DEF_STR( On ) )
INPUT_PORTS_END
/*******************************************************/
/* */
/* bootleg "Super Invaders" */
/* */
/*******************************************************/
static INPUT_PORTS_START( superinv )
PORT_INCLUDE( sicv )
PORT_MODIFY("IN1")
PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_COIN1 )
PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_COIN2 )
PORT_MODIFY("IN2")
PORT_DIPUNKNOWN_DIPLOC( 0x04, 0x00, "SW1:3" )
PORT_DIPNAME( 0x08, 0x00, DEF_STR( Bonus_Life ) ) PORT_DIPLOCATION("SW1:4")
PORT_DIPSETTING( 0x08, "1500" )
PORT_DIPSETTING( 0x00, "2500" )
PORT_DIPUNKNOWN_DIPLOC( 0x80, 0x00, "SW1:8" )
INPUT_PORTS_END
/*******************************************************/
/* */
/* Nichibutsu "Rolling Crash" */
/* Press left-arrow to play "Moon Base" */
/* */
/*******************************************************/
READ8_MEMBER(_8080bw_state::rollingc_scattered_colorram_r)
{
return m_scattered_colorram[(offset & 0x1f) | ((offset & 0x1f00) >> 3)];
}
WRITE8_MEMBER(_8080bw_state::rollingc_scattered_colorram_w)
{
m_scattered_colorram[(offset & 0x1f) | ((offset & 0x1f00) >> 3)] = data;
}
READ8_MEMBER(_8080bw_state::rollingc_scattered_colorram2_r)
{
return m_scattered_colorram2[(offset & 0x1f) | ((offset & 0x1f00) >> 3)];
}
WRITE8_MEMBER(_8080bw_state::rollingc_scattered_colorram2_w)
{
m_scattered_colorram2[(offset & 0x1f) | ((offset & 0x1f00) >> 3)] = data;
}
void _8080bw_state::rollingc_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));
}
void _8080bw_state::rollingc_io_map(address_map &map)
{
map(0x00, 0x00).portr("IN0").w(FUNC(_8080bw_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(0x04, 0x04).w(m_mb14241, FUNC(mb14241_device::shift_data_w));
map(0x05, 0x05).w(FUNC(_8080bw_state::invadpt2_sh_port_2_w));
}
static INPUT_PORTS_START( rollingc )
PORT_INCLUDE( sicv )
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_MODIFY("IN1")
PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_COIN1 )
PORT_MODIFY("IN2")
PORT_DIPUNKNOWN_DIPLOC( 0x08, 0x00, "SW1:4" )
INPUT_PORTS_END
MACHINE_START_MEMBER(_8080bw_state,rollingc)
{
mw8080bw_state::machine_start();
m_scattered_colorram = std::make_unique<uint8_t []>(0x400);
m_scattered_colorram2 = std::make_unique<uint8_t []>(0x400);
save_pointer(&m_scattered_colorram[0], "m_scattered_colorram", 0x400);
save_pointer(&m_scattered_colorram2[0], "m_scattered_colorram2", 0x400);
}
void _8080bw_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);
/* add shifter */
MB14241(config, m_mb14241);
/* video hardware */
m_screen->set_screen_update(FUNC(_8080bw_state::screen_update_rollingc));
PALETTE(config, m_palette, FUNC(_8080bw_state::rollingc_palette), 16);
/* sound hardware */
invaders_samples_audio(config);
MCFG_MACHINE_START_OVERRIDE(_8080bw_state,rollingc)
}
/*******************************************************/
/* */
/* Taito "Space Chaser" */
/* */
/*******************************************************/
READ8_MEMBER(_8080bw_state::schaser_scattered_colorram_r)
{
return m_scattered_colorram[(offset & 0x1f) | ((offset & 0x1f80) >> 2)];
}
WRITE8_MEMBER(_8080bw_state::schaser_scattered_colorram_w)
{
m_scattered_colorram[(offset & 0x1f) | ((offset & 0x1f80) >> 2)] = data;
}
void _8080bw_state::schaser_map(address_map &map)
{
map(0x0000, 0x1fff).rom();
map(0x2000, 0x3fff).ram().share("main_ram");
map(0x4000, 0x5fff).rom();
map(0xc000, 0xdfff).rw(FUNC(_8080bw_state::schaser_scattered_colorram_r), FUNC(_8080bw_state::schaser_scattered_colorram_w));
}
void _8080bw_state::schaser_io_map(address_map &map)
{
map(0x00, 0x00).portr("IN0");
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::schaser_sh_port_1_w));
map(0x04, 0x04).w(m_mb14241, FUNC(mb14241_device::shift_data_w));
map(0x05, 0x05).w(FUNC(_8080bw_state::schaser_sh_port_2_w));
map(0x06, 0x06).w(m_watchdog, FUNC(watchdog_timer_device::reset_w));
}
static INPUT_PORTS_START( schaser )
PORT_START("IN0")
PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_JOYSTICK_UP ) PORT_4WAY PORT_PLAYER(2)
PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_JOYSTICK_LEFT ) PORT_4WAY PORT_PLAYER(2)
PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_JOYSTICK_DOWN ) PORT_4WAY PORT_PLAYER(2)
PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_JOYSTICK_RIGHT ) PORT_4WAY PORT_PLAYER(2)
PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_BUTTON1 ) PORT_PLAYER(2)
PORT_DIPNAME( 0x60, 0x00, "Hard Starting Level" ) PORT_DIPLOCATION("SW1:5,7")
PORT_DIPSETTING( 0x00, "3" )
PORT_DIPSETTING( 0x20, "4" )
PORT_DIPSETTING( 0x40, "5" )
PORT_DIPSETTING( 0x60, "6" )
PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_UNUSED )
PORT_START("IN1")
PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_JOYSTICK_UP ) PORT_4WAY
PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_JOYSTICK_LEFT ) PORT_4WAY
PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_JOYSTICK_DOWN ) PORT_4WAY
PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_JOYSTICK_RIGHT ) PORT_4WAY
PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_BUTTON1 )
PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_START2 )
PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_START1 )
PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_COIN1 )
PORT_START("IN2") // port 2
PORT_DIPNAME( 0x03, 0x00, DEF_STR( Lives ) ) PORT_DIPLOCATION("SW1:1,2")
PORT_DIPSETTING( 0x00, "3" )
PORT_DIPSETTING( 0x01, "4" )
PORT_DIPSETTING( 0x02, "5" )
PORT_DIPSETTING( 0x03, "6" )
PORT_DIPUNKNOWN_DIPLOC( 0x04, 0x00, "SW1:3" )
PORT_DIPNAME( 0x08, 0x00, DEF_STR( Difficulty ) ) PORT_DIPLOCATION("SW1:4")
PORT_DIPSETTING( 0x00, DEF_STR( Easy ) )
PORT_DIPSETTING( 0x08, DEF_STR( Hard ) )
// Name Reset - if name of high scorer was rude, owner can press this button
PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("Name Reset") PORT_CODE(KEYCODE_F1)
PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_TILT )
PORT_DIPNAME( 0x40, 0x00, DEF_STR( Cabinet ) ) PORT_DIPLOCATION("SW1:6")
PORT_DIPSETTING( 0x00, DEF_STR( Upright ) )
PORT_DIPSETTING( 0x40, DEF_STR( Cocktail ) )
PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_UNUSED )
PORT_START("VR1")
PORT_ADJUSTER( 70, "VR1 - Music Volume" )
PORT_START("VR2")
PORT_ADJUSTER( 90, "VR2 - Explosion/Effect Volume" )
PORT_START("VR3")
PORT_ADJUSTER( 70, "VR3 - Dot Volume" )
INPUT_PORTS_END
static INPUT_PORTS_START( schaserm )
PORT_INCLUDE( schaser )
PORT_MODIFY("IN2")
PORT_DIPNAME( 0x03, 0x00, DEF_STR( Lives ) ) PORT_DIPLOCATION("SW1:1,2")
PORT_DIPSETTING( 0x00, "1" )
PORT_DIPSETTING( 0x01, "2" )
PORT_DIPSETTING( 0x02, "3" )
PORT_DIPSETTING( 0x03, "4" )
INPUT_PORTS_END
MACHINE_START_MEMBER(_8080bw_state,schaser)
{
mw8080bw_state::machine_start();
m_scattered_colorram = std::make_unique<uint8_t []>(0x800);
save_pointer(&m_scattered_colorram[0], "m_scattered_colorram", 0x800);
MACHINE_START_CALL_MEMBER(schaser_sh);
MACHINE_START_CALL_MEMBER(extra_8080bw_vh);
}
MACHINE_RESET_MEMBER(_8080bw_state,schaser)
{
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(config.replace(), m_maincpu, 1996800); /* 19.968MHz / 10 */
m_maincpu->set_addrmap(AS_PROGRAM, &_8080bw_state::schaser_map);
m_maincpu->set_addrmap(AS_IO, &_8080bw_state::schaser_io_map);
m_maincpu->set_irq_acknowledge_callback(FUNC(_8080bw_state::interrupt_vector));
WATCHDOG_TIMER(config, m_watchdog).set_vblank_count("screen", 255);
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));
/* add shifter */
MB14241(config, m_mb14241);
/* video hardware */
m_screen->set_screen_update(FUNC(_8080bw_state::screen_update_schaser));
PALETTE(config, m_palette, palette_device::RBG_3BIT);
/* 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);
DISCRETE(config, m_discrete, schaser_discrete);
m_discrete->add_route(ALL_OUTPUTS, "mono", 1.0);
}
/*******************************************************/
/* */
/* Taito "Space Chaser" (CV version) */
/* */
/*******************************************************/
READ8_MEMBER(_8080bw_state::schasercv_02_r)
{
uint8_t data = ioport("IN2")->read();
if (m_flip_screen) return data;
uint8_t in1 = ioport("IN1")->read();
return (data & 0x89) | (in1 & 0x70) | (BIT(in1, 3) << 1) | (BIT(in1, 7) << 2);
}
void _8080bw_state::schasercv_io_map(address_map &map)
{
map(0x00, 0x00).portr("IN0");
map(0x01, 0x01).portr("IN1");
map(0x02, 0x02).r(FUNC(_8080bw_state::schasercv_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::schasercv_sh_port_1_w));
map(0x04, 0x04).w(m_mb14241, FUNC(mb14241_device::shift_data_w));
map(0x05, 0x05).w(FUNC(_8080bw_state::schasercv_sh_port_2_w));
//map(0x06, 0x06).w(m_watchdog, FUNC(watchdog_timer_device::reset_w));
}
void _8080bw_state::crashrd_io_map(address_map &map)
{
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::crashrd_port03_w));
map(0x04, 0x04).w(m_mb14241, FUNC(mb14241_device::shift_data_w));
map(0x05, 0x05).w(FUNC(_8080bw_state::crashrd_port05_w));
map(0x06, 0x06).w(m_watchdog, FUNC(watchdog_timer_device::reset_w));
}
static INPUT_PORTS_START( schasercv )
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_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_JOYSTICK_DOWN ) PORT_4WAY
PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_BUTTON1 )
PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_JOYSTICK_LEFT ) PORT_4WAY
PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_JOYSTICK_RIGHT ) PORT_4WAY
PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_JOYSTICK_UP ) PORT_4WAY
PORT_START("IN2")
PORT_DIPNAME( 0x01, 0x00, DEF_STR( Lives ) ) PORT_DIPLOCATION("SW1:1")
PORT_DIPSETTING( 0x00, "3" )
PORT_DIPSETTING( 0x01, "4" )
PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_JOYSTICK_DOWN ) PORT_4WAY PORT_PLAYER(2) PORT_DIPLOCATION("SW1:2")
PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_JOYSTICK_UP ) PORT_4WAY PORT_PLAYER(2) PORT_DIPLOCATION("SW1:3")
PORT_DIPNAME( 0x08, 0x00, DEF_STR( Difficulty ) ) PORT_DIPLOCATION("SW1:4")
PORT_DIPSETTING( 0x00, DEF_STR( Easy ) )
PORT_DIPSETTING( 0x08, DEF_STR( Hard ) )
PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_BUTTON1 ) PORT_PLAYER(2) PORT_DIPLOCATION("SW1:5")
PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_JOYSTICK_LEFT ) PORT_4WAY PORT_PLAYER(2) PORT_DIPLOCATION("SW1:6")
PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_JOYSTICK_RIGHT ) PORT_4WAY PORT_PLAYER(2) PORT_DIPLOCATION("SW1:7")
PORT_DIPUNKNOWN_DIPLOC( 0x80, 0x00, "SW1:8" )
/* Dummy port for cocktail mode */
INVADERS_CAB_TYPE_PORT
INPUT_PORTS_END
MACHINE_START_MEMBER(_8080bw_state,schasercv)
{
mw8080bw_state::machine_start();
m_scattered_colorram = std::make_unique<uint8_t []>(0x800);
save_pointer(&m_scattered_colorram[0], "m_scattered_colorram", 0x800);
MACHINE_START_CALL_MEMBER(extra_8080bw_sh);
MACHINE_START_CALL_MEMBER(extra_8080bw_vh);
}
void _8080bw_state::schasercv(machine_config &config)
{
mw8080bw_root(config);
/* basic machine hardware */
m_maincpu->set_addrmap(AS_PROGRAM, &_8080bw_state::schaser_map);
m_maincpu->set_addrmap(AS_IO, &_8080bw_state::schasercv_io_map);
MCFG_MACHINE_START_OVERRIDE(_8080bw_state, schasercv)
/* add shifter */
MB14241(config, m_mb14241);
/* video hardware */
m_screen->set_screen_update(FUNC(_8080bw_state::screen_update_schasercv));
PALETTE(config, m_palette, palette_device::RBG_3BIT);
/* sound hardware */
invaders_samples_audio(config);
SPEAKER_SOUND(config, m_speaker);
m_speaker->add_route(ALL_OUTPUTS, "mono", 0.25);
}
void _8080bw_state::crashrd(machine_config &config)
{
schaser(config);
m_maincpu->set_addrmap(AS_IO, &_8080bw_state::crashrd_io_map);
}
/*******************************************************/
/* */
/* Taito "Straight Flush" */
/* */
/*******************************************************/
READ_LINE_MEMBER(_8080bw_state::sflush_80_r)
{
return (m_screen->vpos() & 0x80) ? 1 : 0;
}
uint8_t _8080bw_state::sflush_in0_r()
{
// guess at interrupt acknowledgement
if (!machine().side_effects_disabled())
m_maincpu->set_input_line(0, CLEAR_LINE);
return ioport("IN0")->read();
}
void _8080bw_state::sflush_map(address_map &map)
{
map(0x0000, 0x1fff).ram();
map(0x4000, 0x5fff).ram().share("main_ram");
map(0x8008, 0x8008).portr("PADDLE");
map(0x8009, 0x8009).r(m_mb14241, FUNC(mb14241_device::shift_result_r));
map(0x800a, 0x800a).portr("IN2");
map(0x800b, 0x800b).r(FUNC(_8080bw_state::sflush_in0_r));
map(0x8018, 0x8018).w(m_mb14241, FUNC(mb14241_device::shift_data_w));
map(0x8019, 0x8019).w(m_mb14241, FUNC(mb14241_device::shift_count_w));
map(0x801a, 0x801a).nopw();
map(0x801c, 0x801c).nopw();
map(0x801d, 0x801d).nopw();
map(0xa000, 0xbfff).rw(FUNC(_8080bw_state::schaser_scattered_colorram_r), FUNC(_8080bw_state::schaser_scattered_colorram_w));
map(0xd800, 0xffff).rom();
}
static INPUT_PORTS_START( sflush )
PORT_START("IN0")
PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_COIN1 )
PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_START1 )
PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_START2 )
PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_TILT )
PORT_DIPNAME( 0x80, 0x80, DEF_STR( Cabinet ) )
PORT_DIPSETTING( 0x80, DEF_STR( Upright ) )
PORT_DIPSETTING( 0x00, DEF_STR( Cocktail ) )
PORT_START("IN2")
PORT_DIPNAME( 0x03, 0x00, DEF_STR( Lives ) )
PORT_DIPSETTING( 0x00, "3" )
PORT_DIPSETTING( 0x01, "4" )
PORT_DIPSETTING( 0x02, "5" )
PORT_DIPSETTING( 0x03, "6" )
PORT_DIPNAME( 0x08, 0x00, "Hiscore" )
PORT_DIPSETTING( 0x00, "0" )
PORT_DIPSETTING( 0x08, "30 000" )
PORT_DIPNAME( 0x40, 0x00, "Coinage Display" )
PORT_DIPSETTING( 0x00, DEF_STR( Off ) )
PORT_DIPSETTING( 0x40, DEF_STR( On ) )
PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_CUSTOM ) PORT_READ_LINE_MEMBER(_8080bw_state, sflush_80_r) // 128V?
PORT_START("PADDLE")
PORT_BIT( 0xff, 0x6a, IPT_PADDLE ) PORT_MINMAX(0x16,0xbf) PORT_SENSITIVITY(30) PORT_KEYDELTA(30) PORT_CENTERDELTA(0)
INPUT_PORTS_END
MACHINE_START_MEMBER(_8080bw_state,sflush)
{
mw8080bw_state::machine_start();
m_scattered_colorram = std::make_unique<uint8_t []>(0x800);
save_pointer(&m_scattered_colorram[0], "m_scattered_colorram", 0x800);
}
void _8080bw_state::sflush(machine_config &config)
{
mw8080bw_root(config);
/* basic machine hardware */
M6800(config.replace(), m_maincpu, 1500000); // ?
m_maincpu->set_addrmap(AS_PROGRAM, &_8080bw_state::sflush_map);
MCFG_MACHINE_START_OVERRIDE(_8080bw_state,sflush)
/* add shifter */
MB14241(config, m_mb14241);
/* video hardware */
m_screen->set_screen_update(FUNC(_8080bw_state::screen_update_sflush));
PALETTE(config, m_palette, FUNC(_8080bw_state::sflush_palette), 8);
}
/*******************************************************************************************/
/* */
/* Taito "Lupin III" */
/* */
/* The rom at 5000 is optional. It contains code for colour ram, and all tunes except */
/* when the moneybag has been stolen. If you remove this rom, bits 0 and 1 of port 0 */
/* must be set High. The colour will then be determined by the 2 proms instead. Bit 6 */
/* of port 5 will select which prom to use. */
/* */
/* Differences between the 2 sets: */
/* - Set 2 has a language selection switch. In the Japanese position, it looks */
/* the same as set 1. Set 1 is always in Japanese. */
/* - Set 1, bit 6 of port 3 activates when the wife is kicking the man. */
/* - The dogs and policemen are yellow in set 1, and different colours in set 2. */
/* */
/*******************************************************************************************/
void _8080bw_state::lupin3_io_map(address_map &map)
{
map(0x00, 0x00).portr("IN0").w(FUNC(_8080bw_state::lupin3_00_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::lupin3_sh_port_1_w));
map(0x04, 0x04).w(m_mb14241, FUNC(mb14241_device::shift_data_w));
map(0x05, 0x05).w(FUNC(_8080bw_state::lupin3_sh_port_2_w));
map(0x06, 0x06).w(m_watchdog, FUNC(watchdog_timer_device::reset_w));
}
static INPUT_PORTS_START( lupin3 )
PORT_START("IN0")
PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_UNKNOWN )
PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_UNKNOWN )
PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_TILT )
PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_BUTTON1) PORT_COCKTAIL
PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_JOYSTICK_RIGHT ) PORT_4WAY PORT_COCKTAIL
PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_JOYSTICK_DOWN ) PORT_4WAY PORT_COCKTAIL
PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_JOYSTICK_LEFT ) PORT_4WAY PORT_COCKTAIL
PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_JOYSTICK_UP ) PORT_4WAY PORT_COCKTAIL
PORT_START("IN1")
PORT_BIT( 0x01, IP_ACTIVE_HIGH, 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_BUTTON1 )
PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_JOYSTICK_RIGHT ) PORT_4WAY
PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_JOYSTICK_DOWN ) PORT_4WAY
PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_JOYSTICK_LEFT ) PORT_4WAY
PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_JOYSTICK_UP ) PORT_4WAY
PORT_START("IN2")
PORT_DIPNAME( 0x03, 0x00, DEF_STR( Lives ) ) PORT_DIPLOCATION("SW1:1,2")
PORT_DIPSETTING( 0x00, "3" )
PORT_DIPSETTING( 0x01, "4" )
PORT_DIPSETTING( 0x02, "5" )
PORT_DIPSETTING( 0x03, "6" )
PORT_DIPNAME( 0x04, 0x00, DEF_STR( Cabinet ) ) PORT_DIPLOCATION("SW1:3")
PORT_DIPSETTING( 0x00, DEF_STR( Upright ) )
PORT_DIPSETTING( 0x04, DEF_STR( Cocktail ) )
PORT_DIPNAME( 0x08, 0x00, "Bags To Collect" ) PORT_DIPLOCATION("SW1:4")
PORT_DIPSETTING( 0x08, "2" )
PORT_DIPSETTING( 0x00, "8" )
PORT_DIPUNUSED_DIPLOC( 0x10, 0x00, "SW1:5" )
PORT_DIPUNUSED_DIPLOC( 0x20, 0x00, "SW1:6" )
PORT_DIPUNUSED_DIPLOC( 0x40, 0x00, "SW1:7" )
PORT_DIPNAME(0x80, 0x00, "Invulnerability (Cheat)") PORT_DIPLOCATION("SW1:8")
PORT_DIPSETTING( 0x00, DEF_STR( Off ) )
PORT_DIPSETTING( 0x80, DEF_STR( On ) )
INPUT_PORTS_END
static INPUT_PORTS_START( lupin3a )
PORT_INCLUDE( lupin3 )
PORT_MODIFY("IN0")
PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_UNKNOWN ) /* selects color mode (dynamic vs. static) */
PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_UNKNOWN ) /* something has to do with sound */
PORT_MODIFY("IN2")
PORT_DIPNAME( 0x10, 0x00, DEF_STR( Language ) ) PORT_DIPLOCATION("SW1:5")
PORT_DIPSETTING( 0x00, DEF_STR( English ) )
PORT_DIPSETTING( 0x10, DEF_STR( Japanese ) )
INPUT_PORTS_END
void _8080bw_state::lupin3(machine_config &config)
{
mw8080bw_root(config);
/* basic machine hardware */
m_maincpu->set_addrmap(AS_IO, &_8080bw_state::lupin3_io_map);
WATCHDOG_TIMER(config, m_watchdog);
MCFG_MACHINE_START_OVERRIDE(_8080bw_state,extra_8080bw)
/* add shifter */
MB14241(config, m_mb14241);
/* video hardware */
m_screen->set_screen_update(FUNC(_8080bw_state::screen_update_indianbt));
PALETTE(config, m_palette, palette_device::RGB_3BIT);
/* sound hardware */
SPEAKER(config, "mono").front_center();
sn76477_device &snsnd(SN76477(config, "snsnd"));
snsnd.set_noise_params(0, 0, 0);
snsnd.set_decay_res(0);
snsnd.set_attack_params(0, RES_K(100));
snsnd.set_amp_res(RES_K(56));
snsnd.set_feedback_res(RES_K(10));
snsnd.set_vco_params(0, CAP_U(0.1), RES_K(8.2));
snsnd.set_pitch_voltage(5.0);
snsnd.set_slf_params(CAP_U(1.0), RES_K(120));
snsnd.set_oneshot_params(0, 0);
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(ALL_OUTPUTS, "mono", 0.5);
SAMPLES(config, m_samples);
m_samples->set_channels(4);
m_samples->set_samples_names(lupin3_sample_names);
m_samples->add_route(ALL_OUTPUTS, "mono", 1.0);
DISCRETE(config, m_discrete, indianbt_discrete);
m_discrete->add_route(ALL_OUTPUTS, "mono", 1.0);
}
void _8080bw_state::lupin3a(machine_config &config)
{
lupin3(config);
m_maincpu->set_addrmap(AS_PROGRAM, &_8080bw_state::schaser_map);
MCFG_MACHINE_START_OVERRIDE(_8080bw_state,sflush)
/* video hardware */
m_screen->set_screen_update(FUNC(_8080bw_state::screen_update_lupin3));
PALETTE(config.replace(), m_palette, palette_device::RBG_3BIT);
}
/*******************************************************/
/* */
/* Taito "Polaris" */
/* */
/*******************************************************/
WRITE_LINE_MEMBER(_8080bw_state::polaris_60hz_w)
{
if (state)
{
m_polaris_cloud_speed++;
if (m_polaris_cloud_speed >= 4) /* every 4 frames - this was verified against real machine */
{
m_polaris_cloud_speed = 0;
m_polaris_cloud_pos++;
}
}
}
MACHINE_START_MEMBER(_8080bw_state,polaris)
{
mw8080bw_state::machine_start();
m_scattered_colorram = std::make_unique<uint8_t []>(0x800);
save_pointer(&m_scattered_colorram[0], "m_scattered_colorram", 0x800);
save_item(NAME(m_polaris_cloud_speed));
save_item(NAME(m_polaris_cloud_pos));
}
READ8_MEMBER(_8080bw_state::polaris_port00_r)
{
uint8_t data = ioport("IN0")->read();
if (m_flip_screen) return data;
return (data & 7) | (ioport("IN1")->read() & 0xf8);
}
// Port 5 is used to reset the watchdog timer.
// This port is also written to when the boss plane is going up and down.
// If you write this value to a note ciruit similar to the music,
// you will get a nice sound that accurately follows the plane.
// It sounds better then the actual circuit used.
// Probably an unfinished feature.
void _8080bw_state::polaris_io_map(address_map &map)
{
map(0x00, 0x00).r(FUNC(_8080bw_state::polaris_port00_r)).w(m_mb14241, FUNC(mb14241_device::shift_count_w));
map(0x01, 0x01).portr("IN1");
map(0x02, 0x02).portr("IN2").w(FUNC(_8080bw_state::polaris_sh_port_1_w));
map(0x03, 0x03).rw(m_mb14241, FUNC(mb14241_device::shift_result_r), FUNC(mb14241_device::shift_data_w));
map(0x04, 0x04).w(FUNC(_8080bw_state::polaris_sh_port_2_w));
map(0x05, 0x05).w(m_watchdog, FUNC(watchdog_timer_device::reset_w));
map(0x06, 0x06).w(FUNC(_8080bw_state::polaris_sh_port_3_w));
}
static INPUT_PORTS_START( polaris )
PORT_START("IN0")
PORT_DIPUNUSED_DIPLOC( 0x01, 0x00, "SW?:1" )
PORT_DIPUNUSED_DIPLOC( 0x02, 0x00, "SW?:2" )
PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_TILT )
PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_BUTTON1 ) PORT_PLAYER(2)
PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_JOYSTICK_RIGHT ) PORT_8WAY PORT_PLAYER(2)
PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_JOYSTICK_DOWN ) PORT_8WAY PORT_PLAYER(2)
PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_JOYSTICK_LEFT ) PORT_8WAY PORT_PLAYER(2)
PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_JOYSTICK_UP ) PORT_8WAY PORT_PLAYER(2)
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_BUTTON1 ) PORT_PLAYER(1)
PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_JOYSTICK_RIGHT ) PORT_8WAY PORT_PLAYER(1)
PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_JOYSTICK_DOWN ) PORT_8WAY PORT_PLAYER(1)
PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_JOYSTICK_LEFT ) PORT_8WAY PORT_PLAYER(1)
PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_JOYSTICK_UP ) PORT_8WAY PORT_PLAYER(1)
PORT_START("IN2")
PORT_DIPNAME( 0x03, 0x00, DEF_STR( Lives ) ) PORT_DIPLOCATION("SW1:1,2")
PORT_DIPSETTING( 0x00, "3" )
PORT_DIPSETTING( 0x01, "4" )
PORT_DIPSETTING( 0x02, "5" )
PORT_DIPSETTING( 0x03, "6" )
PORT_DIPNAME( 0x04, 0x00, DEF_STR( Cabinet ) ) PORT_DIPLOCATION("SW1:3")
PORT_DIPSETTING( 0x00, DEF_STR( Upright ) )
PORT_DIPSETTING( 0x04, DEF_STR( Cocktail ) )
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. */
PORT_DIPNAME( 0x10, 0x10, DEF_STR( Demo_Sounds ) ) PORT_DIPLOCATION("SW1:5")
PORT_DIPSETTING( 0x00, DEF_STR( Off ) )
PORT_DIPSETTING( 0x10, DEF_STR( On ) )
PORT_DIPUNUSED_DIPLOC( 0x20, 0x00, "SW1:6" )
PORT_DIPUNUSED_DIPLOC( 0x40, 0x00, "SW1:7" )
PORT_DIPNAME( 0x80, 0x00, "High Score Preset Mode" ) PORT_DIPLOCATION("SW1:8")
PORT_DIPSETTING( 0x00, DEF_STR( Off ) )
PORT_DIPSETTING( 0x80, DEF_STR( On ) )
PORT_START("VR1")
PORT_ADJUSTER( 80, "Sub Volume VR1" )
PORT_START("VR2")
PORT_ADJUSTER( 70, "Sub Volume VR2" )
PORT_START("VR3")
PORT_ADJUSTER( 90, "Sub Volume VR3" )
INPUT_PORTS_END
void _8080bw_state::polaris(machine_config &config)
{
mw8080bw_root(config);
/* basic machine hardware */
m_maincpu->set_addrmap(AS_PROGRAM, &_8080bw_state::schaser_map);
m_maincpu->set_addrmap(AS_IO, &_8080bw_state::polaris_io_map);
WATCHDOG_TIMER(config, m_watchdog).set_vblank_count("screen", 255);
MCFG_MACHINE_START_OVERRIDE(_8080bw_state,polaris)
/* add shifter */
MB14241(config, m_mb14241);
/* video hardware */
m_screen->set_screen_update(FUNC(_8080bw_state::screen_update_polaris));
m_screen->screen_vblank().set(FUNC(_8080bw_state::polaris_60hz_w));
PALETTE(config, m_palette, palette_device::RBG_3BIT);
/* sound hardware */
SPEAKER(config, "mono").front_center();
DISCRETE(config, m_discrete, polaris_discrete);
m_discrete->add_route(ALL_OUTPUTS, "mono", 1.0);
}
/*******************************************************/
/* */
/* Taito "Ozma Wars" */
/* */
/*******************************************************/
static INPUT_PORTS_START( ozmawars )
PORT_INCLUDE( sicv )
PORT_MODIFY("IN1")
PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_COIN1 )
PORT_MODIFY("IN2")
PORT_DIPNAME( 0x03, 0x00, "Energy" ) PORT_DIPLOCATION("SW1:1,2")
PORT_DIPSETTING( 0x00, "15000" )
PORT_DIPSETTING( 0x01, "20000" )
PORT_DIPSETTING( 0x02, "25000" )
PORT_DIPSETTING( 0x03, "35000" )
PORT_DIPUNKNOWN_DIPLOC( 0x04, 0x00, "SW1:3" )
PORT_DIPNAME( 0x08, 0x00, "Bonus Energy" ) PORT_DIPLOCATION("SW1:4")
PORT_DIPSETTING( 0x00, "15000" )
PORT_DIPSETTING( 0x08, "10000" )
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 ) )
INPUT_PORTS_END
static INPUT_PORTS_START( spaceph )
PORT_INCLUDE( ozmawars )
PORT_MODIFY("IN1")
PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_UNKNOWN )
INPUT_PORTS_END
/*******************************************************/
/* */
/* Emag "Super Invaders" */
/* */
/*******************************************************/
static INPUT_PORTS_START( sinvemag )
PORT_INCLUDE( sicv )
PORT_MODIFY("IN1")
PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_UNKNOWN )
PORT_MODIFY("IN2")
PORT_DIPUNKNOWN_DIPLOC( 0x04, 0x00, "SW1:3" )
PORT_DIPNAME( 0x08, 0x00, DEF_STR( Bonus_Life ) ) PORT_DIPLOCATION("SW1:4")
PORT_DIPSETTING( 0x08, "2000" )
PORT_DIPSETTING( 0x00, "3000" )
INPUT_PORTS_END
/*******************************************************/
/* */
/* Jatre Specter (Taito?) */
/* */
/*******************************************************/
static INPUT_PORTS_START( jspecter )
PORT_INCLUDE( sicv )
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
/*******************************************************/
/* */
/* Taito "Balloon Bomber" */
/* */
/*******************************************************/
void _8080bw_state::ballbomb_io_map(address_map &map)
{
map(0x00, 0x00).portr("IN0");
map(0x01, 0x01).portr("IN1").w(FUNC(_8080bw_state::ballbomb_01_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::ballbomb_sh_port_1_w));
map(0x04, 0x04).w(m_mb14241, FUNC(mb14241_device::shift_data_w));
map(0x05, 0x05).w(FUNC(_8080bw_state::ballbomb_sh_port_2_w));
}
static INPUT_PORTS_START( ballbomb )
PORT_INCLUDE( sicv )
PORT_MODIFY("IN1")
PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_COIN1 )
PORT_MODIFY("IN2")
PORT_DIPUNKNOWN_DIPLOC( 0x08, 0x00, "SW1:4" )
PORT_DIPUNKNOWN_DIPLOC( 0x80, 0x00, "SW1:8" )
INPUT_PORTS_END
void _8080bw_state::ballbomb(machine_config &config)
{
mw8080bw_root(config);
/* basic machine hardware */
m_maincpu->set_addrmap(AS_IO, &_8080bw_state::ballbomb_io_map);
MCFG_MACHINE_START_OVERRIDE(_8080bw_state,extra_8080bw)
/* add shifter */
MB14241(config, m_mb14241);
/* video hardware */
m_screen->set_screen_update(FUNC(_8080bw_state::screen_update_ballbomb));
PALETTE(config, m_palette, palette_device::RBG_3BIT);
/* sound hardware */
invaders_samples_audio(config);
DISCRETE(config, m_discrete, ballbomb_discrete);
m_discrete->add_route(ALL_OUTPUTS, "mono", 1.0);
}
/*******************************************************/
/* */
/* Wing "Yosaku To Donbei" */
/* */
/*******************************************************/
void _8080bw_state::yosakdon_map(address_map &map)
{
map(0x0000, 0x1fff).rom();
map(0x2000, 0x3fff).ram().share("main_ram");
map(0x4000, 0x43ff).writeonly(); /* what's this? */
}
void _8080bw_state::yosakdon_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 */
}
static INPUT_PORTS_START( yosakdon )
PORT_START("IN0")
PORT_BIT( 0x01, IP_ACTIVE_HIGH, 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_UNUSED )
PORT_START("IN1")
PORT_DIPNAME( 0x03, 0x00, DEF_STR( Lives ) )
PORT_DIPSETTING( 0x00, "3" )
PORT_DIPSETTING( 0x01, "4" )
PORT_DIPSETTING( 0x02, "5" )
PORT_DIPSETTING( 0x03, "6" )
PORT_DIPNAME( 0x04, 0x00, DEF_STR( Unknown ) )
PORT_DIPSETTING( 0x04, DEF_STR( Off ) )
PORT_DIPSETTING( 0x00, DEF_STR( On ) )
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( 0x80, IP_ACTIVE_HIGH, IPT_UNUSED )
/* Dummy controls port, P1 */
INVADERS_CONTROL_PORT_P1
INVADERS_CONTROL_PORT_P2
/* Dummy port for cocktail mode (not used) */
INVADERS_CAB_TYPE_PORT
INPUT_PORTS_END
void _8080bw_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)
/* sound hardware */
invaders_samples_audio(config);
/* video hardware */
m_screen->set_screen_update(FUNC(_8080bw_state::screen_update_invaders));
}
/*******************************************************/
/* */
/* Taito "Indian battle" */
/* In "indianbtbr", the "number of animals" dipswitch */
/* is ineffective because they compare for 8 kills at */
/* 0x811, which is not possible. This byte should be */
/* 0x03. */
/* */
/*******************************************************/
static INPUT_PORTS_START( indianbt )
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_DIPNAME( 0x03, 0x00, DEF_STR( Lives ) )
PORT_DIPSETTING( 0x00, "3" )
PORT_DIPSETTING( 0x01, "4" )
PORT_DIPSETTING( 0x02, "5" )
PORT_DIPSETTING( 0x03, "6" )
PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_TILT )
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_DIPNAME(0x80, 0x00, "Invulnerability (Cheat)")
PORT_DIPSETTING( 0x00, DEF_STR( Off ) )
PORT_DIPSETTING( 0x80, DEF_STR( On ) )
/* Dummy port for cocktail mode */
INVADERS_CAB_TYPE_PORT
INPUT_PORTS_END
static INPUT_PORTS_START( indianbtbr )
PORT_START("IN0")
PORT_DIPNAME( 0x03, 0x00, DEF_STR( Lives ) )
PORT_DIPSETTING( 0x00, "3" )
PORT_DIPSETTING( 0x01, "4" )
PORT_DIPSETTING( 0x02, "5" )
PORT_DIPSETTING( 0x03, "6" )
PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_UNUSED )
PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_UNUSED )
PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_UNUSED )
PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_UNKNOWN ) //Enable color map to be in C400-DFFF
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_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
/*
Protection / sound hw checks ?
ld a ,$b
out ($03),a
out ($01),a
in a,($00)
and $f0
cp $10
jp nz,$3000
ld a,$03
out ($03),a
out ($01),a
in a,($00)
jp $5de7
and $f0
jp z,$052b
jp $3000
*/
READ8_MEMBER(_8080bw_state::indianbt_r)
{
switch(m_maincpu->pc())
{
case 0x5fed: return 0x10;
case 0x5ffc: return 0;
}
logerror("unknown port 0 read @ %x\n",m_maincpu->pc());
return machine().rand();
}
READ8_MEMBER(_8080bw_state::indianbtbr_01_r)
{
uint8_t data = ioport("IN1")->read();
if (!m_flip_screen) return data;
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(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));
map(0x06, 0x06).w(m_watchdog, FUNC(watchdog_timer_device::reset_w));
map(0x07, 0x07).w(FUNC(_8080bw_state::indianbt_sh_port_3_w));
}
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(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));
map(0x05, 0x05).w(FUNC(_8080bw_state::indianbtbr_sh_port_2_w));
map(0x06, 0x06).w(m_watchdog, FUNC(watchdog_timer_device::reset_w));
map(0x07, 0x07).nopw();
}
void _8080bw_state::indianbt(machine_config &config)
{
mw8080bw_root(config);
/* basic machine hardware */
m_maincpu->set_addrmap(AS_IO, &_8080bw_state::indianbt_io_map);
WATCHDOG_TIMER(config, m_watchdog);
MCFG_MACHINE_START_OVERRIDE(_8080bw_state,extra_8080bw)
/* add shifter */
MB14241(config, m_mb14241);
/* video hardware */
m_screen->set_screen_update(FUNC(_8080bw_state::screen_update_indianbt));
PALETTE(config, m_palette, palette_device::RGB_3BIT);
/* sound hardware */
invaders_samples_audio(config);
DISCRETE(config, m_discrete, indianbt_discrete);
m_discrete->add_route(ALL_OUTPUTS, "mono", 0.25);
}
void _8080bw_state::indianbtbr(machine_config &config)
{
mw8080bw_root(config);
/* basic machine hardware */
m_maincpu->set_addrmap(AS_PROGRAM, &_8080bw_state::schaser_map);
m_maincpu->set_addrmap(AS_IO, &_8080bw_state::indianbtbr_io_map);
WATCHDOG_TIMER(config, m_watchdog);
MCFG_MACHINE_START_OVERRIDE(_8080bw_state,extra_8080bw)
/* add shifter */
MB14241(config, m_mb14241);
/* video hardware */
m_screen->set_screen_update(FUNC(_8080bw_state::screen_update_indianbt));
PALETTE(config, m_palette, palette_device::RGB_3BIT);
/* sound hardware */
invaders_samples_audio(config);
}
/*******************************************************/
/* */
/* Taito "Steel Worker" */
/* */
/*******************************************************/
WRITE8_MEMBER(_8080bw_state::steelwkr_sh_port_3_w)
{
machine().bookkeeping().coin_lockout_global_w(!(~data & 0x03)); /* possibly */
}
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(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));
map(0x06, 0x06).w(FUNC(_8080bw_state::steelwkr_sh_port_3_w));
}
static INPUT_PORTS_START( steelwkr )
/* 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_START("IN2")
PORT_DIPNAME( 0x03, 0x02, DEF_STR( Lives ) ) PORT_DIPLOCATION("SW1:1,2")
PORT_DIPSETTING( 0x00, "1" )
PORT_DIPSETTING( 0x01, "2" )
PORT_DIPSETTING( 0x02, "3" )
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)
/* Dummy port for cocktail mode */
INVADERS_CAB_TYPE_PORT
INPUT_PORTS_END
void _8080bw_state::steelwkr(machine_config &config)
{
mw8080bw_root(config);
/* basic machine hardware */
m_maincpu->set_addrmap(AS_IO, &_8080bw_state::steelwkr_io_map);
MCFG_MACHINE_START_OVERRIDE(_8080bw_state,extra_8080bw)
/* add shifter */
MB14241(config, m_mb14241);
/* video hardware */
m_screen->set_screen_update(FUNC(_8080bw_state::screen_update_invadpt2));
PALETTE(config, m_palette, palette_device::RBG_3BIT);
/* sound hardware */
invaders_samples_audio(config);
}
/*****************************************************
Guru Readme for Shuttle Invader (Omori 1979)
PCB Layout
----------
OEC-3C
|----------------------------------------------------------|
| LM556 DIP16 |
|VR1 |
| LM458 SN76477 |
|VR2 5.545MHz |
| LM380 |
| 4045 4045 |
| 2.11C 1.13C |
| 18MHz 4027 4027 4027 4027 |
| 4.11D 3.13D |
| AM8224 4027 4027 4027 4027 |
| i8080 DIP24 5.13E |
| DSW 4027 4027 4027 4027 |
| |
|SN75452 SN75452 8.11F 4027 4027 4027 4027 |
| CN2 8216 8216 CN1 |
|----------------------------------------------------------|
Notes:
i8080 - Intel 8080 CPU. Clock input 2.000MHz [18/9]. Note the /9 comes from the AM8224
SN76477 - Texas Instruments SN76477 Complex Sound Generator
SN75452 - Texas Instruments SN75452 Dual High Speed High Current Peripheral Driver
8216 - NEC uPB8216 4 Bit Parallel Bi-Directional Bus Driver
4045 - Texas Instruments TMS4045 1k x 4-bit Static RAM (Work RAM)
4027 - Motorola MCM4027 4k x 1-bit Dynamic RAM (Video RAM)
AM8224 - AMD AM8224 Clock Generator and Driver for 8080-Compatible Microprocessors
DIP16 - DIP16 socket for connection of 16-wire flat cable joining to OEC-4A PCB
LM556 - Texas Instruments LM556 Dual Timer
LM458 - Texas Instruments LM458 Low Power Dual Operational Amplifier
LM380 - Texas Instruments LM380 2.5W Audio Power Amplifier
CN1 - 11-pin Power Input Connector. Pinout (left to right) is GND,GND,GND,+5V,+5V,+5V,+12V,+12V,+12V,[SPACE],-5V
CN2 - 25-pin Connector for Control Inputs/Audio Output etc.
VR1 - Potentiometer (Master Volume)
VR2 - Potentiometer (volume of other sounds? maybe background sounds?)
DSW - 8-position DIP Switch
Additional PCB (more sounds?)
--------------
OEC-4A
|-------------------|
| VR1 74121 |
| 7400 7404 74S287 |
|75452 CN2 CN1 LM723|
|75452 |
| |
|--| 22-WAY |--|
|-------------|
Notes: (All IC's shown)
LM723 - Texas Instruments LM723 Voltage Regulator
74S287 - Texas Instruments SN74S287 256-bit x 4-bit Bi-Polar PROM at location 2B
75452 - Texas Instruments SN75452 Dual High Speed High Current Peripheral Driver
VR1 - Potentiometer connected to LM723 pin 5
CN1 - DIP16 socket for connection of 16-wire flat cable joining to Main PCB
CN2 - Empty DIP16 socket
22-WAY - Single-Sided 22-WAY Card Edge Connector. Has many tracks coming from it, as well as power.
It's purpose and what it plugs into is unknown.
******************************************************/
static INPUT_PORTS_START( shuttlei )
PORT_START("DSW")
PORT_DIPNAME( 0x01, 0x00, DEF_STR( Coinage ) )
PORT_DIPSETTING( 0x01, DEF_STR( 2C_1C ) )
PORT_DIPSETTING( 0x00, DEF_STR( 1C_1C ) )
PORT_DIPNAME( 0x06, 0x00, DEF_STR( Lives ) )
PORT_DIPSETTING( 0x00, "3" )
PORT_DIPSETTING( 0x02, "4" )
PORT_DIPSETTING( 0x04, "5" )
PORT_DIPSETTING( 0x06, "6" )
PORT_DIPNAME( 0x08, 0x00, DEF_STR( Unknown ) )
PORT_DIPSETTING( 0x08, DEF_STR( Off ) )
PORT_DIPSETTING( 0x00, DEF_STR( On ) )
PORT_DIPNAME( 0x10, 0x00, DEF_STR( Unknown ) )
PORT_DIPSETTING( 0x10, DEF_STR( Off ) )
PORT_DIPSETTING( 0x00, DEF_STR( On ) )
PORT_DIPNAME( 0x20, 0x00, DEF_STR( Unknown ) )
PORT_DIPSETTING( 0x20, DEF_STR( Off ) )
PORT_DIPSETTING( 0x00, DEF_STR( On ) )
PORT_DIPNAME( 0x40, 0x00, DEF_STR( Unknown ) )
PORT_DIPSETTING( 0x40, DEF_STR( Off ) )
PORT_DIPSETTING( 0x00, DEF_STR( On ) )
PORT_DIPNAME( 0x80, 0x00, DEF_STR( Unknown ) )
PORT_DIPSETTING( 0x80, DEF_STR( Off ) )
PORT_DIPSETTING( 0x00, DEF_STR( On ) )
PORT_START("INPUTS")
PORT_DIPNAME( 0x01, 0x00, DEF_STR( Unknown ) )
PORT_DIPSETTING( 0x01, DEF_STR( Off ) )
PORT_DIPSETTING( 0x00, DEF_STR( On ) )
PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_CUSTOM ) PORT_VBLANK("screen")
PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_BUTTON1 )
PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_COIN1 )
PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_START1 )
PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_START2 )
PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_JOYSTICK_RIGHT ) PORT_2WAY PORT_PLAYER(1)
PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_JOYSTICK_LEFT ) PORT_2WAY PORT_PLAYER(1)
PORT_START("P2")
PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_BUTTON1 ) PORT_PLAYER(2)
PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_JOYSTICK_RIGHT ) PORT_2WAY PORT_PLAYER(2)
PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_JOYSTICK_LEFT ) PORT_2WAY PORT_PLAYER(2)
/* Dummy port for cocktail mode */
INVADERS_CAB_TYPE_PORT
INPUT_PORTS_END
// 'no 1' which is displayed before each player plays actually refers to the wave number, not the player number!
static INPUT_PORTS_START( skylove )
PORT_START("DSW")
PORT_DIPNAME( 0x01, 0x00, DEF_STR( Coinage ) )
PORT_DIPSETTING( 0x01, DEF_STR( 2C_1C ) )
PORT_DIPSETTING( 0x00, DEF_STR( 1C_1C ) )
PORT_DIPNAME( 0x06, 0x00, DEF_STR( Lives ) )
PORT_DIPSETTING( 0x00, "3" )
PORT_DIPSETTING( 0x02, "4" )
PORT_DIPSETTING( 0x04, "5" )
PORT_DIPSETTING( 0x06, "6" )
PORT_DIPNAME( 0x08, 0x00, DEF_STR( Unknown ) )
PORT_DIPSETTING( 0x08, DEF_STR( Off ) )
PORT_DIPSETTING( 0x00, DEF_STR( On ) )
PORT_DIPNAME( 0x10, 0x00, DEF_STR( Unknown ) )
PORT_DIPSETTING( 0x10, DEF_STR( Off ) )
PORT_DIPSETTING( 0x00, DEF_STR( On ) )
PORT_DIPNAME( 0x20, 0x00, DEF_STR( Unknown ) )
PORT_DIPSETTING( 0x20, DEF_STR( Off ) )
PORT_DIPSETTING( 0x00, DEF_STR( On ) )
PORT_DIPNAME( 0x40, 0x00, DEF_STR( Unknown ) )
PORT_DIPSETTING( 0x40, DEF_STR( Off ) )
PORT_DIPSETTING( 0x00, DEF_STR( On ) )
PORT_DIPNAME( 0x80, 0x00, DEF_STR( Unknown ) )
PORT_DIPSETTING( 0x80, DEF_STR( Off ) )
PORT_DIPSETTING( 0x00, DEF_STR( On ) )
PORT_START("INPUTS")
PORT_DIPNAME( 0x01, 0x01, DEF_STR( Unknown ) )
PORT_DIPSETTING( 0x01, DEF_STR( Off ) ) // must be off to boot
PORT_DIPSETTING( 0x00, DEF_STR( On ) )
PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_CUSTOM ) PORT_VBLANK("screen")
PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_BUTTON1 )
PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_COIN1 )
PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_START1 )
PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_START2 )
PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_JOYSTICK_RIGHT ) PORT_2WAY PORT_PLAYER(1)
PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_JOYSTICK_LEFT ) PORT_2WAY PORT_PLAYER(1)
PORT_START("P2")
PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_BUTTON1 ) PORT_PLAYER(2)
PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_JOYSTICK_RIGHT ) PORT_2WAY PORT_PLAYER(2)
PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_JOYSTICK_LEFT ) PORT_2WAY PORT_PLAYER(2)
/* Dummy port for cocktail mode */
INVADERS_CAB_TYPE_PORT
INPUT_PORTS_END
READ8_MEMBER(_8080bw_state::shuttlei_ff_r)
{
uint8_t data = ioport("INPUTS")->read();
if (!m_flip_screen) return data;
return (data & 0x3b) | ioport("P2")->read();
}
WRITE8_MEMBER(_8080bw_state::shuttlei_ff_w)
{
/* bit 0 goes high when first coin inserted
bit 1 also goes high when subsequent coins are inserted
These may be for indicator lamps under the start buttons.
bit 2 goes high while player 2 is playing
*/
m_flip_screen = BIT(data, 2) & BIT(ioport(CABINET_PORT_TAG)->read(), 0);
}
void _8080bw_state::shuttlei_map(address_map &map)
{
map(0x0000, 0x1fff).rom();
map(0x2000, 0x37ff).ram().share("main_ram");
map(0x3800, 0x3fff).ram();
map(0x4000, 0x43ff).ram().share("share1"); // shuttlei
map(0x6000, 0x63ff).ram().share("share1"); // skylove (is it mirrored, or different PCB hookup?)
}
void _8080bw_state::shuttlei_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));
}
void _8080bw_state::shuttlei(machine_config &config)
{
/* basic machine hardware */
I8080(config, m_maincpu, XTAL(18'000'000) / 9);
// TODO: move irq handling away from mw8080.cpp, this game runs on custom hardware
m_maincpu->set_addrmap(AS_PROGRAM, &_8080bw_state::shuttlei_map);
m_maincpu->set_addrmap(AS_IO, &_8080bw_state::shuttlei_io_map);
m_maincpu->set_irq_acknowledge_callback(FUNC(_8080bw_state::interrupt_vector));
MCFG_MACHINE_START_OVERRIDE(_8080bw_state, extra_8080bw)
MCFG_MACHINE_RESET_OVERRIDE(_8080bw_state, mw8080bw)
/* video hardware */
SCREEN(config, m_screen, SCREEN_TYPE_RASTER);
m_screen->set_refresh_hz(60);
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));
PALETTE(config, m_palette, palette_device::MONOCHROME);
/* sound hardware */
invaders_samples_audio(config);
}
/*
------------------------------------
Darth Vader - Space Invaders bootleg
------------------------------------
Location Device File ID Checksum
--------------------------------------------
0 2708 ROM0 6F9A
1 2708 ROM1 7D2A
2 2708 ROM2 67AA
3 2708 ROM3 7D8D
4 2708 ROM4 493D
5 2708 ROM5 12CE
Notes: PCB No. DV-SI-7811M2a
CPU - 8080
Another (same checksums) dump came from board labeled SI-7811M-2
*/
MACHINE_START_MEMBER(_8080bw_state,darthvdr)
{
/* do nothing for now - different interrupt system */
m_fleet_step = 3;
}
MACHINE_RESET_MEMBER(_8080bw_state,darthvdr)
{
/* do nothing for now - different interrupt system */
}
IRQ_CALLBACK_MEMBER(_8080bw_state::darthvdr_interrupt_vector)
{
m_maincpu->set_input_line(0, CLEAR_LINE);
return 0xff;
}
READ8_MEMBER(_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)
{
map(0x0000, 0x17ff).rom();
map(0x1800, 0x1fff).ram();
map(0x4000, 0x5fff).ram().share("main_ram");
}
void _8080bw_state::darthvdr_io_map(address_map &map)
{
map(0x00, 0x00).portr("P1");
map(0x01, 0x01).r(FUNC(_8080bw_state::darthvdr_01_r));
map(0x00, 0x00).w(FUNC(_8080bw_state::darthvdr_00_w)); // flipscreen
map(0x04, 0x04).nopw();
map(0x08, 0x08).w(FUNC(_8080bw_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( 0x10, IP_ACTIVE_LOW, IPT_COIN1 )
PORT_DIPNAME( 0x20, 0x20, DEF_STR( Bonus_Life ) )
PORT_DIPSETTING( 0x00, "1000" )
PORT_DIPSETTING( 0x20, "3000" )
PORT_DIPNAME( 0x40, 0x40, DEF_STR( Unknown ) )
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_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_DIPNAME( 0x10, 0x10, "One less life" )
PORT_DIPSETTING( 0x10, DEF_STR( Off ) )
PORT_DIPSETTING( 0x00, DEF_STR( On ) )
PORT_DIPNAME( 0x20, 0x20, DEF_STR( Unknown ) )
PORT_DIPSETTING( 0x20, DEF_STR( Off ) )
PORT_DIPSETTING( 0x00, DEF_STR( On ) )
PORT_DIPNAME( 0x40, 0x40, DEF_STR( Unknown ) )
PORT_DIPSETTING( 0x40, DEF_STR( Off ) )
PORT_DIPSETTING( 0x00, DEF_STR( On ) )
PORT_DIPNAME( 0x80, 0x80, DEF_STR( Unknown ) )
PORT_DIPSETTING( 0x80, DEF_STR( Off ) )
PORT_DIPSETTING( 0x00, DEF_STR( On ) )
/* Dummy port for cocktail mode */
INVADERS_CAB_TYPE_PORT
INPUT_PORTS_END
void _8080bw_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)
/* sound hardware */
invaders_samples_audio(config);
/* video hardware */
m_screen->set_screen_update(FUNC(_8080bw_state::screen_update_invaders));
m_screen->screen_vblank().set_inputline(m_maincpu, 0, ASSERT_LINE);
}
/*************************************
*
* 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
* 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)
*
* Hold down fire button to activate thrust.
*
*************************************/
void _8080bw_state::vortex_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(0x02, 0x02).mirror(0x04).portr("IN0");
map(0x03, 0x03).mirror(0x04).portr("IN1");
map(0x00, 0x00).mirror(0x04).portr("IN2");
map(0x01, 0x01).mirror(0x04).r(m_mb14241, FUNC(mb14241_device::shift_result_r));
map(0x00, 0x00).w(m_mb14241, FUNC(mb14241_device::shift_count_w));
map(0x01, 0x01).w("soundboard", FUNC(invaders_audio_device::p1_w));
map(0x06, 0x06).w(m_mb14241, FUNC(mb14241_device::shift_data_w));
map(0x07, 0x07).w("soundboard", FUNC(invaders_audio_device::p2_w));
map(0x04, 0x04).w(m_watchdog, FUNC(watchdog_timer_device::reset_w));
}
static INPUT_PORTS_START( vortex )
PORT_INCLUDE( sicv )
PORT_MODIFY("IN1")
PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_UNKNOWN )
PORT_MODIFY("IN2")
PORT_DIPNAME( 0x01, 0x01, DEF_STR( Unknown ) ) PORT_DIPLOCATION("SW1:1")
PORT_DIPSETTING( 0x01, DEF_STR( Off ) )
PORT_DIPSETTING( 0x00, DEF_STR( On ) )
PORT_DIPNAME( 0x02, 0x02, DEF_STR( Unknown ) ) PORT_DIPLOCATION("SW1:2")
PORT_DIPSETTING( 0x02, DEF_STR( Off ) )
PORT_DIPSETTING( 0x00, DEF_STR( On ) )
PORT_DIPNAME( 0x04, 0x04, DEF_STR( Unknown ) ) PORT_DIPLOCATION("SW1:3")
PORT_DIPSETTING( 0x04, DEF_STR( Off ) )
PORT_DIPSETTING( 0x00, DEF_STR( On ) )
PORT_DIPNAME( 0x08, 0x08, DEF_STR( Unknown ) ) PORT_DIPLOCATION("SW1:4")
PORT_DIPSETTING( 0x08, DEF_STR( Off ) )
PORT_DIPSETTING( 0x00, DEF_STR( On ) )
PORT_DIPNAME( 0x80, 0x80, DEF_STR( Coinage ) ) PORT_DIPLOCATION("SW1:8")
PORT_DIPSETTING( 0x00, DEF_STR( 2C_1C ) )
PORT_DIPSETTING( 0x80, DEF_STR( 1C_1C ) )
INPUT_PORTS_END
void _8080bw_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)
WATCHDOG_TIMER(config, m_watchdog).set_time(attotime::from_usec(255000000 / (MW8080BW_PIXEL_CLOCK / MW8080BW_HTOTAL / MW8080BW_VTOTAL)));
/* video hardware */
// TODO: replace with modified invaders color renderer code allowing midscanline color writes
m_screen->set_screen_update(FUNC(_8080bw_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; });
}
/* decrypt function for vortex */
void _8080bw_state::init_vortex()
{
uint8_t *rom = memregion("maincpu")->base();
int length = memregion("maincpu")->bytes();
std::vector<uint8_t> buf1(length);
for (uint32_t x = 0; x < length; x++)
{
uint32_t addr = x;
/*
A15 A14 A13 A0 A3 A9
0 0 0 I I I
0 0 1 I I I
0 1 0 N N N
0 1 1 N I I
1 0 0 N I I
1 0 1 N I I
1 1 0 N I I
1 1 1 N I I
*/
switch (x&0xE000) // inputs are A13 A14 A15
{
case 0x0000: case 0x2000: // A0 A3 A9
addr ^= 0x0209;
break;
case 0x4000: // none, but doesn't decode right with none
addr ^= 0x0209; // hack: this doesn't match schematic but gets code running. Why does this work? Is there something I'm not undertstanding about how the memory_region maps? or was the zilec/zinitone-microsec epoxy brick simply a bad design which is always stuck on the 0x0000 encryption no matter what?
break;
case 0x6000: case 0x8000: case 0xa000: case 0xc000: case 0xe000: // A3 and A9
addr ^= 0x0208;
break;
/*
case 0x0000: case 0x2000: // A0 A3 A9
addr ^= 0x0001;
break;
case 0x4000:
addr ^= 0x0208;
break;
case 0x6000: case 0x8000: case 0xa000: case 0xc000: case 0xe000:
break;*/
}
buf1[addr] = rom[x];
}
memcpy(rom, &buf1[0], length);
}
/* unlabeled gun game by Model Racing, verified to be Gun Champ
BOARD 1:
_________________________________________________________________________________________________________________________________
| 12 13 14 15 16 17 18 19 |
| _________ _______ ___ ___ ___ ___ ___ ___ ___ ___ |
|___ 11 |74LS241N | |74LS159| |AM9| |AM9| |AM9| |AM9| |AM9| |AM9| |AM9| |AM9| |
| _| |_________| |_______| |060| |060| |060| |060| |060| |060| |060| |060| |
| _| _____________ |CPC| |CPC| |CPC| |CPC| |CPC| |CPC| |CPC| |CPC| |
| _| |258 | | | | | | | | | | | | | | | | | |
| _| | | _________ _______ | | | | | | | | | | | | | | | | |
| _| 10 | 2708| |74LS241N | |74LS153| | | | | | | | | | | | | | | | | |
| _| |_____________| |_________| |_______| | | | | | | | | | | | | | | | | |
| _| |___| |___| |___| |___| |___| |___| |___| |___| |
| _| _____________ |
| _| |257 | _______ _______ |
| _| 9 | | |74LS174| |74LS153| __|
| _| | 2708| |_______| |_______| ___ ___ ___ ___ ___ ___ ___ ___ |
| _| |_____________| |AM9| |AM9| |AM9| |AM9| |AM9| |AM9| |AM9| |AM9| |__
| _| |060| |060| |060| |060| |060| |060| |060| |060| =|
| _| _____________ _______ _______ |CPC| |CPC| |CPC| |CPC| |CPC| |CPC| |CPC| |CPC| =|
| _| 8 |256 | |74LS174| |74LS153| | | | | | | | | | | | | | | | | =|
| _| | | |_______| |_______| | | | | | | | | | | | | | | | | =|
| _| | 2708| | | | | | | | | | | | | | | | | =|
| _| |_____________| | | | | | | | | | | | | | | | | =|
| _| _______ _______ |___| |___| |___| |___| |___| |___| |___| |___| =|
|___| 7 _____________ |74LS166| |74LS174| =|
| |255 | |_______| |_______| =|
| | | =|
| | 2708| _______ _______ =|
| 6 |_____________| |74LS86 | | 74LS04| =|
| |_______| |_______| =|
|___ _____________ =|
| _| |254 | _______ _______ _______ _______ _______ _______ _______ =|
| _| | | |74LS00N| |SN7404N| |74LS74 | |74LS157| |74LS157| |74LS157| |74LS157| 5 =|
| _| | 2708| |_______| |_______| |_______| |_______| |_______| |_______| |_______| =|
| _| |_____________| =|
| _| _________ _________ _______ _______ _______ _______ =|
| _| _____________ |74LS244N | |74LS244N | |74161N | |74161N | |74161N | |74161N | 4 __|
| _| |253 | |_________| |_________| |_______| |_______| |_______| |_______| |
| _| | | |__
| _| | 2708| |
| _| |_____________| _______ _______ _______ _______ |
| _| |74LS04N| |SN7474N| |74LS04N| |74160N | 3 |
| _| _____________ _____________________ |_______| |_______| |_______| |_______| |
| _| |252 | | 341 | .XTAL. |
| _| | | _______ | INS8080AD | _______ _______ _______ _______ |
| _| | 2708| |74LS42 | | C8080A | |74LS00 | |74LS55 | |74LS00 | |74LS42 | 2 |
| _| |_____________| |_______| |_____________________| |_______| |_______| |_______| |_______| |
| _| |
| _| _____________ _______ _______ _______ _______ |
| _| |251 | |74LS02N| |74LS20N| |75365N | |SN7474N| 1 |
| _| | | |_______| |_______| |_______| |_______| |
|___| | 2708| |
| |_____________| Model Racing |
| CS 235A |
| A B C D E F G H |
|_________________________________________________________________________________________________________________________________|
XTAL=19,66080MHz
BOARD 2:
_________________________________________________________________________________________________________________________________
| |
| _______ _______ _______ _______ _________ |
|___ 11 |74LS175| |74LS151| |74LS151| |74LS153| |74LS244N | Model |
| _| |_______| |_______| |_______| |_______| |_________| Racing |
| _| |
| _| CS 238A |
| _| _______ _______ _______ _______ |
| _| 10 |74LS174| |74LS151| |74LS151| |74LS153| |
| _| |_______| |_______| |_______| |_______| |
| _| |
| _| |
| _| _______ _______ _______ _______ ____________ |
| _| |74LS174| |74LS151| |74LS151| |74LS153| 9 | | __|
| _| |_______| |_______| |_______| |_______| | | |
| _| | | |__
| _| | | =|
| _| _______ _______ _______ _______ | | =|
| _| |74LS174| |74LS151| |74LS151| |74LS153| 8 | | =|
| _| |_______| |_______| |_______| |_______| | | =|
| _| | | =|
| _| | | =|
| _| _______ _______ _______ _______ | UNKNOWN | =|
|___| |74LS273| |74LS175| |74LS14N| |74LS42N| 7 | | =|
| |_______| |_______| |_______| |_______| | | =|
| | | =|
| | | =|
| | | =|
| | | _______ =|
|___ _______ _______ _______ _________ | | |CA8100 | 6 =|
| _| |74LS161| |74LS74A| |74LS161| |74LS374N | 5 | | |_______| =|
| _| |_______| |_______| |_______| |_________| | | =|
| _| | | =|
| _| |____________| =|
| _| _______ _______ _______ _________ =|
| _| |74LS161| |74LS00 | |74LS161| |74LS374N | 4 =|
| _| |_______| |_______| |_______| |_________| =|
| _| =|
| _| =|
| _| _______ _______ ______________ _______ ____ __|
| _| 3 |74LS14N| |74LS74A| | SN76477N | |74LS107| |DIP1| |
| _| |_______| |_______| | 7923XY | |_______| |____| |__
| _| | SINGAPORE | |
| _| |______________| |
| _| _______ _______ _______ _______ _______ |
| _| 2 |74LS26 | |74LS00N| |CD4016B| |74LS221| |74LS00N| |
| _| |_______| |_______| |_______| |_______| |_______| |
| _| |
| _| NE555P |
| _| _______ _______ _______ ___ _______ _______ |
|___| 1 |74LS74A| |74LS74A| |74LS74A| | | |74LS90N| |74LS14N| |
| |_______| |_______| |_______| |___| |_______| |_______| |
| |
| P R S T U V W X |
|_________________________________________________________________________________________________________________________________|
Claybuster is on the same hardware, PCB labels CS 235A and CS 238A as well
*/
TIMER_DEVICE_CALLBACK_MEMBER(_8080bw_state::claybust_gun_callback)
{
// reset gun latch
m_claybust_gun_pos = 0;
}
READ_LINE_MEMBER(_8080bw_state::claybust_gun_on_r)
{
return (m_claybust_gun_pos != 0) ? 1 : 0;
}
INPUT_CHANGED_MEMBER(_8080bw_state::claybust_gun_trigger)
{
if (newval)
{
/*
The game registers a valid shot after the gun trigger is pressed, and IN1 d0 is high.
It latches the gun position and then compares it with VRAM contents: 1 byte/8 pixels, 0 means miss.
IN1 d0 probably indicates if the latch is ready or not (glitches happen otherwise)
in $06
cpi $04
rc
mov h,a
in $02
mov l,a
lxi d,$1ffe <-- this is where the +2 comes from
dad d
out $00
mov a,m
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
}
}
READ8_MEMBER(_8080bw_state::claybust_gun_lo_r)
{
return m_claybust_gun_pos & 0xff;
}
READ8_MEMBER(_8080bw_state::claybust_gun_hi_r)
{
return m_claybust_gun_pos >> 8;
}
void _8080bw_state::claybust_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(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));
}
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( 0x04, IP_ACTIVE_LOW, IPT_COIN1 )
PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_START1 )
// switch is 6-pos, but DNS06:5 and DNS06:6 are not connected
PORT_DIPNAME( 0x10, 0x10, "Shots" ) PORT_DIPLOCATION("DNS06:1")
PORT_DIPSETTING( 0x10, "4" )
PORT_DIPSETTING( 0x00, "2" )
PORT_DIPUNKNOWN_DIPLOC( 0x20, 0x20, "DNS06:2" )
PORT_DIPUNKNOWN_DIPLOC( 0x40, 0x40, "DNS06:3" )
PORT_DIPUNKNOWN_DIPLOC( 0x80, 0x80, "DNS06:4" )
PORT_START( "GUNX" )
PORT_BIT( 0xff, 0x80, IPT_LIGHTGUN_X ) PORT_MINMAX(0x00, 0xff) PORT_CROSSHAIR(X, 1.0 - (MW8080BW_HPIXCOUNT-256)/256.0, (MW8080BW_HPIXCOUNT-256)/256.0, 0) PORT_SENSITIVITY(56) PORT_KEYDELTA(5)
PORT_START( "GUNY" )
PORT_BIT( 0xff, 0xa0, IPT_LIGHTGUN_Y ) PORT_MINMAX(0x20, 0xff) PORT_CROSSHAIR(Y, 1.0, 0.0, 0) PORT_SENSITIVITY(64) PORT_KEYDELTA(5)
INPUT_PORTS_END
static INPUT_PORTS_START( gunchamp )
PORT_INCLUDE( claybust )
PORT_MODIFY("IN1")
// switch is 6-pos, but DNS06:5 and DNS06:6 are not connected
PORT_DIPNAME( 0x10, 0x10, DEF_STR( Unknown ) ) PORT_DIPLOCATION("DNS06:1")
PORT_DIPSETTING( 0x10, DEF_STR( Off ) )
PORT_DIPSETTING( 0x00, DEF_STR( On ) )
PORT_DIPNAME( 0xe0, 0x40, DEF_STR( Coinage ) ) PORT_DIPLOCATION("DNS06:2,3,4")
PORT_DIPSETTING( 0xa0, DEF_STR( 4C_1C ) )
PORT_DIPSETTING( 0xc0, DEF_STR( 3C_1C ) )
PORT_DIPSETTING( 0xe0, DEF_STR( 2C_1C ) )
PORT_DIPSETTING( 0x40, DEF_STR( 1C_1C ) )
PORT_DIPSETTING( 0x20, DEF_STR( 1C_2C ) )
PORT_DIPSETTING( 0x00, DEF_STR( 2C_3C ) )
PORT_DIPSETTING( 0x60, DEF_STR( 1C_3C ) )
PORT_DIPSETTING( 0x80, DEF_STR( 1C_4C ) )
INPUT_PORTS_END
MACHINE_START_MEMBER(_8080bw_state, claybust)
{
mw8080bw_state::machine_start();
m_claybust_gun_pos = 0;
save_item(NAME(m_claybust_gun_pos));
}
void _8080bw_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));
MCFG_MACHINE_START_OVERRIDE(_8080bw_state, claybust)
/* sound hardware */
// TODO: discrete sound
}
/**************************************************************************************
Taito Galactica / Space Missile
This game was officially only distributed in Brazil.
Regarding release data, not much information is available online.
ROM dump came from a collection of old 5 1/4 disks (Apple II) that used to be in the
possession of an arcade operator in the early 80s.
TODO:
- correct sound (currently same as invaders)
* sound mutes when a few aliens are left?
* port 7 write is used too, looks like it's for music similar to indianbt
Note that bass background hum and sound effects are already basically correct.
***************************************************************************************/
static INPUT_PORTS_START( galactic )
PORT_START("IN0")
PORT_BIT( 0xff, IP_ACTIVE_HIGH, IPT_UNKNOWN ) // gets read into memory (0x2012) then never used
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_START("IN2")
PORT_DIPNAME( 0x03, 0x02, DEF_STR( Bonus_Life ) )
PORT_DIPSETTING( 0x00, DEF_STR( Off ) )
PORT_DIPSETTING( 0x01, "4000" )
PORT_DIPSETTING( 0x02, "5000" )
PORT_DIPSETTING( 0x03, "7000" )
PORT_DIPNAME( 0x04, 0x00, DEF_STR( Unknown ) )
PORT_DIPSETTING( 0x00, DEF_STR( Off ) )
PORT_DIPSETTING( 0x04, DEF_STR( On ) )
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( 0x80, IP_ACTIVE_HIGH, IPT_UNKNOWN )
/* Dummy controls port, P1 */
INVADERS_CONTROL_PORT_P1
/* Dummy controls port, P2 */
INVADERS_CONTROL_PORT_P2
/* Dummy port for cocktail mode */
INVADERS_CAB_TYPE_PORT
INPUT_PORTS_END
/*****************************************************
Attack Force, by E.G.S., Italy
Not much information is available for this game.
20MHz XTAL, 2MHz CPU
video: 15625Hz
TODO: sound
PORT 02 : 10 while your missile is on-screen
PORT 04 : 01 while game is playing. Sound enable.
PORT 05 : Watchdog?
PORT 06 : 01=Helicopter; 02=Tank; 03=Motorcycle
08=Explosion; 10=Walking
*****************************************************/
void _8080bw_state::attackfc_io_map(address_map &map)
{
map(0x00, 0x00).portr("IN0");
map(0x02, 0x02).nopw(); // lamp?
map(0x03, 0x03).rw(m_mb14241, FUNC(mb14241_device::shift_result_r), FUNC(mb14241_device::shift_data_w));
map(0x04, 0x04).nopw(); // sound enable?
map(0x05, 0x05).nopw(); // watchdog?
map(0x06, 0x06).nopw(); // sound?
map(0x07, 0x07).w(m_mb14241, FUNC(mb14241_device::shift_count_w));
}
static INPUT_PORTS_START( attackfc )
PORT_START("IN0")
PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_JOYSTICK_RIGHT ) PORT_2WAY
PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_JOYSTICK_LEFT ) PORT_2WAY
PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_BUTTON1 )
PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_UNKNOWN )
PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_UNKNOWN )
PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_UNKNOWN )
PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_UNKNOWN )
PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_COIN1 )
INPUT_PORTS_END
void _8080bw_state::attackfc(machine_config &config)
{
mw8080bw_root(config);
/* basic machine hardware */
m_maincpu->set_addrmap(AS_IO, &_8080bw_state::attackfc_io_map);
/* add shifter */
MB14241(config, m_mb14241);
/* sound hardware */
// TODO: custom discrete
}
void _8080bw_state::init_attackfc()
{
uint8_t *rom = memregion("maincpu")->base();
uint32_t len = memregion("maincpu")->bytes();
std::vector<uint8_t> buffer(len);
// swap a8/a9
for (int i = 0; i < len; i++)
buffer[bitswap<16>(i, 15,14,13,12,11,10,8,9, 7,6,5,4,3,2,1,0)] = rom[i];
memcpy(rom, &buffer[0], len);
}
/*****************************************************
Space Invaders Multigame kit, Braze Technologies,
produced from 2002(version 1A) to 2006(version 3D).
This is an 8-in-1 hack on a daughterboard, containing:
- 8080 CPU taken from main PCB
- SST 29EE010 or AM27C010 (or other similar) 128KB EEPROM
(EEPROM functionality not used)
- 93C46P E2PROM for saving highscore/settings
- PALCE22V10H-25PC/4
The kit is compatible with the original Midway boardset
******************************************************/
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( 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_START("IN1")
PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_COIN1 ) PORT_CHANGED_MEMBER(DEVICE_SELF, mw8080bw_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( 0x80, IP_ACTIVE_HIGH, IPT_UNUSED )
PORT_START("IN2")
PORT_DIPUNUSED_DIPLOC( 0x01, 0x00, "SW:3" )
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_DIPUNUSED_DIPLOC( 0x80, 0x00, "SW:1" )
/* fake port for cabinet type */
PORT_START(INVADERS_CAB_TYPE_PORT_TAG)
PORT_CONFNAME( 0x01, 0x00, DEF_STR( Cabinet ) )
PORT_CONFSETTING( 0x00, DEF_STR( Upright ) )
PORT_CONFSETTING( 0x01, DEF_STR( Cocktail ) )
PORT_BIT( 0xfe, IP_ACTIVE_HIGH, IPT_UNUSED )
/* fake ports for handling the various input ports based on cabinet type */
PORT_START(INVADERS_SW6_SW7_PORT_TAG)
PORT_DIPUNUSED_DIPLOC( 0x01, 0x00, "SW:7" )
PORT_DIPUNUSED_DIPLOC( 0x02, 0x00, "SW:6" )
PORT_BIT( 0xfc, IP_ACTIVE_HIGH, IPT_UNUSED )
PORT_START(INVADERS_SW5_PORT_TAG)
PORT_DIPUNUSED_DIPLOC( 0x01, 0x00, "SW:5" )
PORT_BIT( 0xfe, IP_ACTIVE_HIGH, IPT_UNUSED )
PORT_START(INVADERS_P1_CONTROL_PORT_TAG)
PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_BUTTON1 ) PORT_PLAYER(1)
PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_JOYSTICK_LEFT ) PORT_2WAY PORT_PLAYER(1)
PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_JOYSTICK_RIGHT ) PORT_2WAY PORT_PLAYER(1)
PORT_BIT( 0xf8, IP_ACTIVE_HIGH, IPT_UNUSED )
PORT_START(INVADERS_P2_CONTROL_PORT_TAG)
PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_BUTTON1 ) PORT_PLAYER(2)
PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_JOYSTICK_LEFT ) PORT_2WAY PORT_PLAYER(2)
PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_JOYSTICK_RIGHT ) PORT_2WAY PORT_PLAYER(2)
PORT_BIT( 0xf8, IP_ACTIVE_HIGH, IPT_UNUSED )
INPUT_PORTS_END
void _8080bw_state::invmulti_map(address_map &map)
{
map(0x0000, 0x1fff).mirror(0x8000).bankr("bank1");
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));
}
READ8_MEMBER(_8080bw_state::invmulti_eeprom_r)
{
return m_eeprom->do_read();
}
WRITE8_MEMBER(_8080bw_state::invmulti_eeprom_w)
{
// d0: latch bit
m_eeprom->di_write(data & 1);
// d6: reset
m_eeprom->cs_write((data & 0x40) ? ASSERT_LINE : CLEAR_LINE);
// d4: write latch or select next bit to read
m_eeprom->clk_write((data & 0x10) ? ASSERT_LINE : CLEAR_LINE);
}
WRITE8_MEMBER(_8080bw_state::invmulti_bank_w)
{
// d0, d4, d6: bank
int bank = (data & 1) | (data >> 3 & 2) | (data >> 4 & 4);
membank("bank1")->set_entry(bank);
membank("bank2")->set_entry(bank);
}
void _8080bw_state::invmulti(machine_config &config)
{
invaders(config);
/* basic machine hardware */
m_maincpu->set_addrmap(AS_PROGRAM, &_8080bw_state::invmulti_map);
EEPROM_93C46_8BIT(config, m_eeprom);
MCFG_MACHINE_RESET_OVERRIDE(_8080bw_state, mw8080bw)
}
void _8080bw_state::init_invmulti()
{
uint8_t *src = memregion("user1")->base();
int len = memregion("user1")->bytes();
uint8_t *dest = memregion("maincpu")->base();
// decrypt 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);
}
/*******************************************************/
/* */
/* Cane (Model Racing) */
/* */
/*******************************************************/
/***********************************************************************************************************************************
This game was never released by Model Racing to the public.
The assembler source files for this game were extracted from the original floppy disks used by the former Model Racing developer
Adolfo Melilli (adolfo@melilli.com).
Those disks were retrieved by Alessandro Bolgia (xadhoom76@gmail.com) and Lorenzo Fongaro (lorenzo.fongaro@virgilio.it) and
dumped by Piero Andreini (pieroandreini@gmail.com) using KryoFlux hardware and software.
Subsequently Jean Paul Piccato (j2pguard-spam@yahoo.com) mounted the images and compiled the source files, managed to set up a
romset and wrote a MAME driver that aims to reproduce in the most faithful way the work of Melilli at Model Racing in late '70s.
The game driver is not based on hardware inspection and is solely derived from assumptions I've made looking at the assembler
code and comments written into the source files of the game. Several of those hypotheses came following the directions of
previous yet contemporary Model Racing works (Eg: Claybuster) and were confirmed by Melilli himself.
Being unreleased this game lacks an official name, thus the name used in the source files was used instead.
***********************************************************************************************************************************/
void cane_state::cane_map(address_map &map)