ladybug: put sraider driver and ladybug_video device in their own files

This commit is contained in:
hap 2022-08-28 23:27:17 +02:00
parent ac0b18a080
commit aa67ab477f
12 changed files with 1092 additions and 1049 deletions

View File

@ -1494,6 +1494,7 @@ universal/docastle.cpp
universal/getaway.cpp
universal/ladybug.cpp
universal/mrdo.cpp
universal/sraider.cpp
universal/superdq.cpp
universal/zerohour.cpp
upl/mouser.cpp

View File

@ -20132,9 +20132,7 @@ dorodon2 // Falcon
ladybug // 8110 (c) 1981
ladybugb // bootleg
ladybugb2 // bootleg
mrsdyna // 8203 (c) 1982 Universal
snapjack // ???? (c)
sraider // 8203 (c) 1982 Universal
@source:misc/ladyfrog.cpp
ladyfrog // (c) 1990 Mondial Games
@ -40013,6 +40011,10 @@ spyhuntpr // (c) 1985 Recreativos Franco S.A.
@source:skeleton/squale.cpp
squale //
@source:universal/sraider.cpp
mrsdyna // 8203 (c) 1982 Universal
sraider // 8203 (c) 1982 Universal
@source:seta/srmp2.cpp
mjyuugi // (c) 1990 Visco
mjyuugia // (c) 1990 Visco

View File

@ -47,82 +47,225 @@ Coin insertion in left slot generates a NMI, in right slot an IRQ.
TODO:
- Coin lockouts are missing. The game only accepts 9 coins, so there has to be
a lockout call somewhere.
- split into 2 drivers (ladybug, mrsdyna/sraider), not much common code since
the bg/sprites are already in a device. ladybug_video device can be put into
a separate file.
***************************************************************************/
/***************************************************************************
Universal 8203-A + 8203-B PCB set
Mrs. Dynamite
Space Raider
Space Raider also uses the Starfield generator board from Zero Hour,
Connected via flywires to these boards
TODO:
decode cpu#2 writes to port 0x30 and 0x38 - resistors for sound
decode cpu#2 writes to port 0x28-0x2f - ???
examine other bits from cpu#2 write to 0xe800
unknown dips
***************************************************************************/
#include "emu.h"
#include "ladybug.h"
#include "ladybug_video.h"
#include "cpu/z80/z80.h"
#include "machine/74259.h"
#include "machine/gen_latch.h"
#include "sound/sn76496.h"
#include "video/resnet.h"
#include "emupal.h"
#include "screen.h"
#include "speaker.h"
#include "tilemap.h"
#include <algorithm>
namespace {
// documentation TBD - 556 dual timer
uint8_t mrsdyna_state::mrsdyna_rnd_r()
// base ladybug platform
class ladybug_state : public driver_device
{
return rand() % 4;
public:
ladybug_state(const machine_config &mconfig, device_type type, const char *tag)
: driver_device(mconfig, type, tag)
, m_maincpu(*this, "maincpu")
, m_video(*this, "video")
, m_port_dsw0(*this, "DSW0")
, m_p1_control(*this, "CONTP1")
, m_p2_control(*this, "CONTP2")
{ }
DECLARE_CUSTOM_INPUT_MEMBER(ladybug_p1_control_r);
DECLARE_CUSTOM_INPUT_MEMBER(ladybug_p2_control_r);
DECLARE_INPUT_CHANGED_MEMBER(coin1_inserted);
DECLARE_INPUT_CHANGED_MEMBER(coin2_inserted);
void ladybug(machine_config &config);
protected:
DECLARE_WRITE_LINE_MEMBER(flipscreen_w);
void ladybug_palette(palette_device &palette) const;
uint32_t screen_update_ladybug(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect);
void ladybug_map(address_map &map);
required_device<cpu_device> m_maincpu;
private:
required_device<ladybug_video_device> m_video;
required_ioport m_port_dsw0;
optional_ioport m_p1_control;
optional_ioport m_p2_control;
};
// ladybug plus program decryption
class dorodon_state : public ladybug_state
{
public:
dorodon_state(const machine_config &mconfig, device_type type, const char *tag)
: ladybug_state(mconfig, type, tag)
, m_decrypted_opcodes(*this, "decrypted_opcodes")
{ }
void init_dorodon();
void dorodon(machine_config &config);
protected:
void decrypted_opcodes_map(address_map &map);
private:
required_shared_ptr<uint8_t> m_decrypted_opcodes;
};
void dorodon_state::init_dorodon()
{
/* decode the opcodes */
uint8_t *rom = memregion("maincpu")->base();
uint8_t *table = memregion("user1")->base();
for (offs_t i = 0; i < 0x6000; i++)
m_decrypted_opcodes[i] = table[rom[i]];
}
// Protection - documentation TBD
uint8_t mrsdyna_state::mrsdyna_protection_r()
/***************************************************************************
Video
***************************************************************************/
/***************************************************************************
Convert the color PROMs into a more useable format.
Lady Bug has a 32 bytes palette PROM and a 32 bytes sprite color lookup
table PROM.
The palette PROM is connected to the RGB output this way:
bit 7 -- inverter -- 220 ohm resistor -- BLUE
-- inverter -- 220 ohm resistor -- GREEN
-- inverter -- 220 ohm resistor -- RED
-- inverter -- 470 ohm resistor -- BLUE
-- unused
-- inverter -- 470 ohm resistor -- GREEN
-- unused
bit 0 -- inverter -- 470 ohm resistor -- RED
***************************************************************************/
void ladybug_state::ladybug_palette(palette_device &palette) const
{
// This must return X011111X or cpu #1 will hang
// see code at rst $10
return 0x3e;
static constexpr int resistances[2] = { 470, 220 };
// compute the color output resistor weights
double rweights[2], gweights[2], bweights[2];
compute_resistor_weights(0, 255, -1.0,
2, resistances, rweights, 470, 0,
2, resistances, gweights, 470, 0,
2, resistances, bweights, 470, 0);
const uint8_t *color_prom = memregion("proms")->base();
// create a lookup table for the palette
for (int i = 0; i < 0x20; i++)
{
int bit0, bit1;
// red component
bit0 = BIT(~color_prom[i], 0);
bit1 = BIT(~color_prom[i], 5);
int const r = combine_weights(rweights, bit0, bit1);
// green component
bit0 = BIT(~color_prom[i], 2);
bit1 = BIT(~color_prom[i], 6);
int const g = combine_weights(gweights, bit0, bit1);
// blue component
bit0 = BIT(~color_prom[i], 4);
bit1 = BIT(~color_prom[i], 7);
int const b = combine_weights(bweights, bit0, bit1);
palette.set_indirect_color(i, rgb_t(r, g, b));
}
// color_prom now points to the beginning of the lookup table
color_prom += 0x20;
// characters
for (int i = 0; i < 0x20; i++)
{
uint8_t const ctabentry = ((i << 3) & 0x18) | ((i >> 2) & 0x07);
palette.set_pen_indirect(i, ctabentry);
}
// sprites
for (int i = 0; i < 0x20; i++)
{
uint8_t ctabentry;
ctabentry = bitswap<4>((color_prom[i] >> 0) & 0x0f, 0,1,2,3);
palette.set_pen_indirect(i + 0x20, ctabentry);
ctabentry = bitswap<4>((color_prom[i] >> 4) & 0x0f, 0,1,2,3);
palette.set_pen_indirect(i + 0x40, ctabentry);
}
}
// Unknown IO - documentation TBD
void mrsdyna_state::mrsdyna_weird_w(offs_t offset, uint8_t data)
uint32_t ladybug_state::screen_update_ladybug(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
{
// These 8 bits are stored in the LS259 latch at A7,
// and connected to all the select lines on 2 4066s at B7/C7
m_weird_value[offset & 7] = data & 1;
bitmap.fill(0, cliprect);
m_video->draw(screen, bitmap, cliprect, flip_screen());
return 0;
}
// documentation TBD
void mrsdyna_state::mrsdyna_0x30_w(offs_t offset, uint8_t data)
/***************************************************************************
I/O
***************************************************************************/
WRITE_LINE_MEMBER(ladybug_state::flipscreen_w)
{
// bits 0-2 select 4051s at M7 and M8
// bits 3-5 select 4051s at K7 and K8
m_0x30 = data & 0x3f;
if (flip_screen() != state)
{
flip_screen_set(state);
machine().tilemap().mark_all_dirty();
}
}
// documentation TBD
void mrsdyna_state::mrsdyna_0x38_w(offs_t offset, uint8_t data)
INPUT_CHANGED_MEMBER(ladybug_state::coin1_inserted)
{
// These 6 bits are stored in the LS174 latch at N8
// bits 0-2 select 4051s at H7 and H8
// bits 3-5 select 4051s at E7 and E8
m_0x38 = data & 0x3f;
/* left coin insertion causes an NMI */
m_maincpu->set_input_line(INPUT_LINE_NMI, newval ? ASSERT_LINE : CLEAR_LINE);
}
INPUT_CHANGED_MEMBER(ladybug_state::coin2_inserted)
{
/* right coin insertion causes an IRQ */
if (newval)
m_maincpu->set_input_line(0, HOLD_LINE);
}
CUSTOM_INPUT_MEMBER(ladybug_state::ladybug_p1_control_r)
{
return m_p1_control->read();
}
CUSTOM_INPUT_MEMBER(ladybug_state::ladybug_p2_control_r)
{
// upright cabinet only uses a single set of controls */
return ((m_port_dsw0->read() & 0x20) ? m_p2_control : m_p1_control)->read();
}
/***************************************************************************
Address Maps
***************************************************************************/
void ladybug_state::ladybug_map(address_map &map)
{
map(0x0000, 0x5fff).rom();
@ -140,110 +283,16 @@ void ladybug_state::ladybug_map(address_map &map)
map(0xe000, 0xe000).portr("IN2");
}
void dorodon_state::decrypted_opcodes_map(address_map &map)
{
map(0x0000, 0x5fff).rom().share("decrypted_opcodes");
}
void mrsdyna_state::mrsdyna_cpu1_map(address_map &map)
{
// LS138 @ J4
map(0x0000, 0x5fff).rom(); // 2764s at R4, N4, and M4
// LS138 @ J4 and LS139 @ H4
map(0x6000, 0x6fff).ram(); // 6116s @ K3 & M3, also connected to clk on PAL K2 (16R6, U001)
map(0x7000, 0x73ff).w("video", FUNC(ladybug_video_device::spr_w)); // pin 29 on ribbon
//map(0x77ff, 0x7fff); // LS139 @ H4 pin7 is NC
// LS138 @ J4, Pin11 (0x8000-0x9fff) and
// LS138 @ N3 (bottom 3 bits)
// (all of these are read/write)
map(0x8005, 0x8005).mirror(0x1ff8).r(FUNC(mrsdyna_state::mrsdyna_protection_r)); // OE on PAL @ K2 (16R6, U001) (100x xxxx xxxx x101)
map(0x8006, 0x8006).mirror(0x1ff8).w("soundlatch_low", FUNC(generic_latch_8_device::write)); // LS374 @ P6
map(0x8007, 0x8007).mirror(0x1ff8).w("soundlatch_high", FUNC(generic_latch_8_device::write)); // LS374 @ R6
map(0x8000, 0x8000).mirror(0x1ff8).portr("IN0");
map(0x8001, 0x8001).mirror(0x1ff8).portr("IN1");
map(0x8002, 0x8002).mirror(0x1ff8).portr("DSW0");
map(0x8003, 0x8003).mirror(0x1ff8).portr("DSW1");
//map(0x8004, 0x8004).mirror(0x1ff8).portr("IN2"); // extra JAMMA pins
// LS138 @ J4, Pin10 (0xa000-0xbfff) // NC
// LS138 @ J4, Pin9 (0xc000-0xdfff)
map(0xd000, 0xd7ff).w("video", FUNC(ladybug_video_device::bg_w)); // pin 27 on ribbon
// LS138 @ J4, Pin7 (0xe000-0xffff)
map(0xe000, 0xe000).nopw(); //unknown 0x10 when in attract, 0x20 when coined/playing - disabled watchdog based on LS123 @ F4
}
void mrsdyna_state::mrsdyna_cpu2_map(address_map &map)
{
// LS138 @ P7
map(0x0000, 0x5fff).rom(); // 2764s at H6,J6, and L6
map(0x6000, 0x63ff).mirror(0x0400).ram(); // 2x2114 @ M6/N6
map(0x8000, 0x8000).mirror(0x1fff).r("soundlatch_low", FUNC(generic_latch_8_device::read)); // LS374 @ P6
map(0xa000, 0xa000).mirror(0x1fff).r("soundlatch_high", FUNC(generic_latch_8_device::read)); // LS374 @ R6
map(0xc000, 0xc000).mirror(0x1fff).r(FUNC(mrsdyna_state::mrsdyna_rnd_r)); // LS125 @ P8 - reads 556 outputs to D1 and D0?
// LS138 @ P7 (nY7) and LS139 @ H4
map(0xe000, 0xe0ff).mirror(0x0300).writeonly().share("grid_data"); // HD6148P @ D6
map(0xe800, 0xefff).w(FUNC(mrsdyna_state::mrsdyna_io_w)); // LS273 @ D4
//map(0xf000, 0xf7ff) // NC
//map(0xf800, 0xffff) // NC
}
void sraider_state::sraider_cpu2_map(address_map &map)
{
// LS138 @ P7
map(0x0000, 0x5fff).rom(); // 2764s at H6, J6, and L6
map(0x6000, 0x63ff).mirror(0x0400).ram(); // 2x2114 @ M6/N6
map(0x8000, 0x8000).mirror(0x1fff).r("soundlatch_low", FUNC(generic_latch_8_device::read)); // LS374 @ P6
map(0xa000, 0xa000).mirror(0x1fff).r("soundlatch_high", FUNC(generic_latch_8_device::read)); // LS374 @ R6
map(0xc000, 0xc000).mirror(0x1fff).r(FUNC(sraider_state::mrsdyna_rnd_r)); // LS125 @ P8 - reads 556 outputs to D1 and D0?
// LS138 @ P7 (nY7) and LS139 @ H4
map(0xe000, 0xe0ff).mirror(0x0300).writeonly().share("grid_data"); // HD6148P @ D6
map(0xe800, 0xefff).w(FUNC(sraider_state::sraider_io_w)); // LS273 @ D4
//map(0xf000, 0xf7ff) // NC
//map(0xf800, 0xffff) // NC
}
void mrsdyna_state::mrsdyna_cpu2_io_map(address_map &map)
{
map.global_mask(0xff);
// LS138 @ A8
map(0x00, 0x07).w("sn1", FUNC(sn76489_device::write)); // J214X2 @ N9
map(0x08, 0x0f).w("sn2", FUNC(sn76489_device::write)); // J214X2 @ M9
map(0x10, 0x17).w("sn3", FUNC(sn76489_device::write)); // J214X2 @ L9
map(0x18, 0x1f).w("sn4", FUNC(sn76489_device::write)); // J214X2 @ K9
map(0x20, 0x27).w("sn5", FUNC(sn76489_device::write)); // J214X2 @ J9
map(0x28, 0x2f).w(FUNC(sraider_state::mrsdyna_weird_w)); // LS259 @ A7 ************
map(0x30, 0x37).w(FUNC(sraider_state::mrsdyna_0x30_w)); // LS174 @ N7 ************
map(0x38, 0x3f).w(FUNC(sraider_state::mrsdyna_0x38_w)); // LS174 @ N8 ************
}
INPUT_CHANGED_MEMBER(ladybug_state::coin1_inserted)
{
/* left coin insertion causes an NMI */
m_maincpu->set_input_line(INPUT_LINE_NMI, newval ? ASSERT_LINE : CLEAR_LINE);
}
INPUT_CHANGED_MEMBER(ladybug_state::coin2_inserted)
{
/* right coin insertion causes an IRQ */
if (newval)
m_maincpu->set_input_line(0, HOLD_LINE);
}
CUSTOM_INPUT_MEMBER(ladybug_state::ladybug_p1_control_r)
{
return m_p1_control->read();
}
CUSTOM_INPUT_MEMBER(ladybug_state::ladybug_p2_control_r)
{
// upright cabinet only uses a single set of controls */
return ((m_port_dsw0->read() & 0x20) ? m_p2_control : m_p1_control)->read();
}
/***************************************************************************
Input Ports
***************************************************************************/
static INPUT_PORTS_START( ladybug )
PORT_START("IN0")
@ -589,157 +638,11 @@ static INPUT_PORTS_START( dorodon )
PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_COIN2 ) PORT_CHANGED_MEMBER(DEVICE_SELF, ladybug_state,coin2_inserted, 0)
INPUT_PORTS_END
static INPUT_PORTS_START( mrsdyna )
PORT_START("IN0") /* IN0 */
PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_JOYSTICK_LEFT ) PORT_4WAY
PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_JOYSTICK_DOWN ) PORT_4WAY
PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_JOYSTICK_RIGHT ) PORT_4WAY
PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_JOYSTICK_UP ) PORT_4WAY
PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_BUTTON1 )
PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_START1 )
PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_START2 )
PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_UNKNOWN ) // JAMMA PIN 12
PORT_START("IN1") /* IN1 */
PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_JOYSTICK_LEFT ) PORT_4WAY PORT_COCKTAIL
PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_JOYSTICK_DOWN ) PORT_4WAY PORT_COCKTAIL
PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_JOYSTICK_RIGHT ) PORT_4WAY PORT_COCKTAIL
PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_JOYSTICK_UP ) PORT_4WAY PORT_COCKTAIL
PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_BUTTON1 ) PORT_COCKTAIL
PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_UNKNOWN ) // VBLANK????
PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_COIN1 )
PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_COIN2 )
PORT_START("DSW0") /* DSW0 @ R3 via '244 @ R2 */
PORT_DIPNAME( 0x01, 0x01, DEF_STR( Unknown ) ) PORT_DIPLOCATION("SW0:8")
PORT_DIPSETTING( 0x01, DEF_STR( Off ) )
PORT_DIPSETTING( 0x00, DEF_STR( On ) )
PORT_DIPNAME( 0x02, 0x02, DEF_STR( Unknown ) ) PORT_DIPLOCATION("SW0:7")
PORT_DIPSETTING( 0x02, DEF_STR( Off ) )
PORT_DIPSETTING( 0x00, DEF_STR( On ) )
PORT_DIPNAME( 0x04, 0x04, "High Score Names" ) PORT_DIPLOCATION("SW0:6")
PORT_DIPSETTING( 0x00, "3 Letters" )
PORT_DIPSETTING( 0x04, "12 Letters" )
PORT_DIPNAME( 0x08, 0x08, DEF_STR( Unknown ) ) PORT_DIPLOCATION("SW0:5")
PORT_DIPSETTING( 0x08, DEF_STR( Off ) )
PORT_DIPSETTING( 0x00, DEF_STR( On ) )
PORT_DIPNAME( 0x10, 0x10, DEF_STR( Unknown ) ) PORT_DIPLOCATION("SW0:4")
PORT_DIPSETTING( 0x10, DEF_STR( Off ) )
PORT_DIPSETTING( 0x00, DEF_STR( On ) )
PORT_DIPNAME( 0x20, 0x00, DEF_STR( Cabinet ) ) PORT_DIPLOCATION("SW0:3")
PORT_DIPSETTING( 0x00, DEF_STR( Upright ) )
PORT_DIPSETTING( 0x20, DEF_STR( Cocktail ) )
PORT_DIPNAME( 0xc0, 0xc0, DEF_STR( Lives ) ) PORT_DIPLOCATION("SW0:1,2")
PORT_DIPSETTING( 0x00, "2" )
PORT_DIPSETTING( 0xc0, "3" )
PORT_DIPSETTING( 0x80, "4" )
PORT_DIPSETTING( 0x40, "5" )
/* Free Play setting works when it's set for both */
PORT_START("DSW1") /* DSW1 @ P3 via '244 @ P2 */
PORT_DIPNAME( 0x0f, 0x0f, DEF_STR( Coin_A ) ) PORT_DIPLOCATION("SW1:8,7,6,5")
/* settings 0x00 through 0x05 all give 1 Coin/1 Credit */
PORT_DIPSETTING( 0x06, DEF_STR( 4C_1C ) )
PORT_DIPSETTING( 0x08, DEF_STR( 3C_1C ) )
PORT_DIPSETTING( 0x0a, DEF_STR( 2C_1C ) )
PORT_DIPSETTING( 0x07, DEF_STR( 3C_2C ) )
PORT_DIPSETTING( 0x09, DEF_STR( 2C_2C ) )
PORT_DIPSETTING( 0x0f, DEF_STR( 1C_1C ) )
PORT_DIPSETTING( 0x0e, DEF_STR( 1C_2C ) )
PORT_DIPSETTING( 0x0d, DEF_STR( 1C_3C ) )
PORT_DIPSETTING( 0x0c, DEF_STR( 1C_4C ) )
PORT_DIPSETTING( 0x0b, DEF_STR( 1C_5C ) )
PORT_DIPSETTING( 0x00, DEF_STR( Free_Play ) )
PORT_DIPNAME( 0xf0, 0xf0, DEF_STR( Coin_B ) ) PORT_DIPLOCATION("SW1:4,3,2,1")
/* settings 0x00 through 0x50 all give 1 Coin/1 Credit */
PORT_DIPSETTING( 0x60, DEF_STR( 4C_1C ) )
PORT_DIPSETTING( 0x80, DEF_STR( 3C_1C ) )
PORT_DIPSETTING( 0xa0, DEF_STR( 2C_1C ) )
PORT_DIPSETTING( 0x70, DEF_STR( 3C_2C ) )
PORT_DIPSETTING( 0x90, DEF_STR( 2C_2C ) )
PORT_DIPSETTING( 0xf0, DEF_STR( 1C_1C ) )
PORT_DIPSETTING( 0xe0, DEF_STR( 1C_2C ) )
PORT_DIPSETTING( 0xd0, DEF_STR( 1C_3C ) )
PORT_DIPSETTING( 0xc0, DEF_STR( 1C_4C ) )
PORT_DIPSETTING( 0xb0, DEF_STR( 1C_5C ) )
PORT_DIPSETTING( 0x00, DEF_STR( Free_Play ) )
INPUT_PORTS_END
static INPUT_PORTS_START( sraider )
PORT_START("IN0") /* IN0 */
PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_JOYSTICK_LEFT ) PORT_4WAY
PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_JOYSTICK_DOWN ) PORT_4WAY
PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_JOYSTICK_RIGHT ) PORT_4WAY
PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_JOYSTICK_UP ) PORT_4WAY
PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_BUTTON1 )
PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_START1 )
PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_START2 )
PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_UNKNOWN ) // JAMMA PIN 12
PORT_START("IN1") /* IN1 */
PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_JOYSTICK_LEFT ) PORT_4WAY PORT_COCKTAIL
PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_JOYSTICK_DOWN ) PORT_4WAY PORT_COCKTAIL
PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_JOYSTICK_RIGHT ) PORT_4WAY PORT_COCKTAIL
PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_JOYSTICK_UP ) PORT_4WAY PORT_COCKTAIL
PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_BUTTON1 ) PORT_COCKTAIL
PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_UNKNOWN ) // VBLANK????
PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_COIN1 )
PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_COIN2 )
PORT_START("DSW0") /* DSW0 @ R3 via '244 @ R2 */
PORT_DIPNAME( 0x03, 0x03, DEF_STR( Difficulty ) ) PORT_DIPLOCATION("SW0:7,8")
PORT_DIPSETTING( 0x03, DEF_STR( Easy ) )
PORT_DIPSETTING( 0x02, DEF_STR( Medium ) )
PORT_DIPSETTING( 0x01, DEF_STR( Hard ) )
PORT_DIPSETTING( 0x00, DEF_STR( Hardest ) )
PORT_DIPNAME( 0x04, 0x04, "High Score Names" ) PORT_DIPLOCATION("SW0:6")
PORT_DIPSETTING( 0x00, "3 Letters" )
PORT_DIPSETTING( 0x04, "10 Letters" )
PORT_DIPNAME( 0x08, 0x08, DEF_STR( Allow_Continue ) ) PORT_DIPLOCATION("SW0:5")
PORT_DIPSETTING( 0x08, DEF_STR( No ) )
PORT_DIPSETTING( 0x00, DEF_STR( Yes ) )
PORT_DIPNAME( 0x10, 0x10, DEF_STR( Unknown ) ) PORT_DIPLOCATION("SW0:4")
PORT_DIPSETTING( 0x10, DEF_STR( Off ) )
PORT_DIPSETTING( 0x00, DEF_STR( On ) )
PORT_DIPNAME( 0x20, 0x00, DEF_STR( Cabinet ) ) PORT_DIPLOCATION("SW0:3")
PORT_DIPSETTING( 0x00, DEF_STR( Upright ) )
PORT_DIPSETTING( 0x20, DEF_STR( Cocktail ) )
PORT_DIPNAME( 0xc0, 0xc0, DEF_STR( Lives ) ) PORT_DIPLOCATION("SW0:1,2")
PORT_DIPSETTING( 0x00, "2" )
PORT_DIPSETTING( 0xc0, "3" )
PORT_DIPSETTING( 0x80, "4" )
PORT_DIPSETTING( 0x40, "5" )
/* Free Play setting works when it's set for both */
PORT_START("DSW1") /* DSW1 @ P3 via '244 @ P2 */
PORT_DIPNAME( 0x0f, 0x0f, DEF_STR( Coin_A ) ) PORT_DIPLOCATION("SW1:8,7,6,5")
/* settings 0x00 through 0x05 all give 1 Coin/1 Credit */
PORT_DIPSETTING( 0x06, DEF_STR( 4C_1C ) )
PORT_DIPSETTING( 0x08, DEF_STR( 3C_1C ) )
PORT_DIPSETTING( 0x0a, DEF_STR( 2C_1C ) )
PORT_DIPSETTING( 0x07, DEF_STR( 3C_2C ) )
PORT_DIPSETTING( 0x09, DEF_STR( 2C_2C ) )
PORT_DIPSETTING( 0x0f, DEF_STR( 1C_1C ) )
PORT_DIPSETTING( 0x0e, DEF_STR( 1C_2C ) )
PORT_DIPSETTING( 0x0d, DEF_STR( 1C_3C ) )
PORT_DIPSETTING( 0x0c, DEF_STR( 1C_4C ) )
PORT_DIPSETTING( 0x0b, DEF_STR( 1C_5C ) )
PORT_DIPSETTING( 0x00, DEF_STR( Free_Play ) )
PORT_DIPNAME( 0xf0, 0xf0, DEF_STR( Coin_B ) ) PORT_DIPLOCATION("SW1:4,3,2,1")
/* settings 0x00 through 0x50 all give 1 Coin/1 Credit */
PORT_DIPSETTING( 0x60, DEF_STR( 4C_1C ) )
PORT_DIPSETTING( 0x80, DEF_STR( 3C_1C ) )
PORT_DIPSETTING( 0xa0, DEF_STR( 2C_1C ) )
PORT_DIPSETTING( 0x70, DEF_STR( 3C_2C ) )
PORT_DIPSETTING( 0x90, DEF_STR( 2C_2C ) )
PORT_DIPSETTING( 0xf0, DEF_STR( 1C_1C ) )
PORT_DIPSETTING( 0xe0, DEF_STR( 1C_2C ) )
PORT_DIPSETTING( 0xd0, DEF_STR( 1C_3C ) )
PORT_DIPSETTING( 0xc0, DEF_STR( 1C_4C ) )
PORT_DIPSETTING( 0xb0, DEF_STR( 1C_5C ) )
PORT_DIPSETTING( 0x00, DEF_STR( Free_Play ) )
INPUT_PORTS_END
/***************************************************************************
GFX Layouts
***************************************************************************/
static const gfx_layout charlayout =
{
@ -775,62 +678,17 @@ static const gfx_layout spritelayout2 =
16*8 /* every sprite takes 16 consecutive bytes */
};
static const gfx_layout gridlayout =
{
8,8, /* 8*8 characters */
512, /* 512 characters */
1, /* 1 bit per pixel */
{ 0 },
{ 7, 6, 5, 4, 3, 2, 1, 0 },
{ 0*8, 1*8, 2*8, 3*8, 4*8, 5*8, 6*8, 7*8},
8*8 /* every char takes 8 consecutive bytes */
};
static const gfx_layout gridlayout2 =
{
8,8, /* 8*8 characters */
512, /* 512 characters */
1, /* 1 bit per pixel */
{ 0 },
{ 7, 6, 5, 4, 3, 2, 1, 0 },
{ 7*8, 6*8, 5*8, 4*8, 3*8, 2*8, 1*8, 0*8 },
8*8 /* every char takes 8 consecutive bytes */
};
static GFXDECODE_START( gfx_ladybug )
GFXDECODE_ENTRY( "gfx1", 0, charlayout, 0, 8 )
GFXDECODE_ENTRY( "gfx2", 0, spritelayout, 4*8, 16 )
GFXDECODE_ENTRY( "gfx2", 0, spritelayout2, 4*8, 16 )
GFXDECODE_END
static GFXDECODE_START( gfx_sraider )
GFXDECODE_ENTRY( "gfx1", 0, charlayout, 0, 8 )
GFXDECODE_ENTRY( "gfx2", 0, spritelayout, 4*8, 16 )
GFXDECODE_ENTRY( "gfx2", 0, spritelayout2, 4*8, 16 )
GFXDECODE_ENTRY( "gfx3", 0, gridlayout, 4*8+4*16+32, 1 )
GFXDECODE_ENTRY( "gfx3", 0, gridlayout2, 4*8+4*16+32, 1 )
GFXDECODE_END
void mrsdyna_state::machine_start()
{
ladybug_base_state::machine_start();
save_item(NAME(m_grid_color));
save_item(NAME(m_0x30));
save_item(NAME(m_0x38));
save_item(NAME(m_weird_value));
}
void mrsdyna_state::machine_reset()
{
ladybug_base_state::machine_reset();
m_grid_color = 0;
m_0x30 = 0;
m_0x38 = 0;
std::fill(std::begin(m_weird_value), std::end(m_weird_value), 0);
}
/***************************************************************************
Machine Configs
***************************************************************************/
void ladybug_state::ladybug(machine_config &config)
{
@ -866,86 +724,10 @@ void dorodon_state::dorodon(machine_config &config)
m_maincpu->set_addrmap(AS_OPCODES, &dorodon_state::decrypted_opcodes_map);
}
void mrsdyna_state::mrsdyna(machine_config &config)
{
/* basic machine hardware */
z80_device &maincpu(Z80(config, "maincpu", 4000000)); /* 4 MHz */
maincpu.set_addrmap(AS_PROGRAM, &mrsdyna_state::mrsdyna_cpu1_map);
maincpu.set_vblank_int("screen", FUNC(mrsdyna_state::irq0_line_hold));
GENERIC_LATCH_8(config, "soundlatch_low");
GENERIC_LATCH_8(config, "soundlatch_high");
z80_device &sub(Z80(config, "sub", 4000000)); /* 4 MHz */
sub.set_addrmap(AS_PROGRAM, &mrsdyna_state::mrsdyna_cpu2_map);
sub.set_addrmap(AS_IO, &mrsdyna_state::mrsdyna_cpu2_io_map);
sub.set_vblank_int("screen", FUNC(mrsdyna_state::irq0_line_hold));
/* video hardware */
screen_device &screen(SCREEN(config, "screen", SCREEN_TYPE_RASTER));
screen.set_raw(9'828'000 / 2, 312, 8, 248, 262, 32, 224);
screen.set_screen_update(FUNC(mrsdyna_state::screen_update_mrsdyna));
//screen.screen_vblank().set(FUNC(sraider_state::screen_vblank_sraider));
screen.set_palette(m_palette);
GFXDECODE(config, m_gfxdecode, m_palette, gfx_ladybug);
PALETTE(config, m_palette, FUNC(mrsdyna_state::mrsdyna_palette), 4*8 + 4*16 + 32 + 2, 32 + 32 + 1);
LADYBUG_VIDEO(config, m_video, 4000000).set_gfxdecode_tag(m_gfxdecode);
/* sound hardware */
SPEAKER(config, "mono").front_center();
SN76489(config, "sn1", 4000000).add_route(ALL_OUTPUTS, "mono", 0.2);
SN76489(config, "sn2", 4000000).add_route(ALL_OUTPUTS, "mono", 0.2);
SN76489(config, "sn3", 4000000).add_route(ALL_OUTPUTS, "mono", 0.2);
SN76489(config, "sn4", 4000000).add_route(ALL_OUTPUTS, "mono", 0.2);
SN76489(config, "sn5", 4000000).add_route(ALL_OUTPUTS, "mono", 0.2);
}
void sraider_state::sraider(machine_config &config)
{
/* basic machine hardware */
z80_device &maincpu(Z80(config, "maincpu", 4000000)); /* 4 MHz */
maincpu.set_addrmap(AS_PROGRAM, &sraider_state::mrsdyna_cpu1_map);
maincpu.set_vblank_int("screen", FUNC(mrsdyna_state::irq0_line_hold));
GENERIC_LATCH_8(config, "soundlatch_low");
GENERIC_LATCH_8(config, "soundlatch_high");
z80_device &sub(Z80(config, "sub", 4000000)); /* 4 MHz */
sub.set_addrmap(AS_PROGRAM, &sraider_state::sraider_cpu2_map);
sub.set_addrmap(AS_IO, &sraider_state::mrsdyna_cpu2_io_map);
sub.set_vblank_int("screen", FUNC(mrsdyna_state::irq0_line_hold));
/* video hardware */
screen_device &screen(SCREEN(config, "screen", SCREEN_TYPE_RASTER));
screen.set_raw(9'828'000 / 2, 312, 8, 248, 262, 32, 224);
screen.set_screen_update(FUNC(sraider_state::screen_update_sraider));
screen.screen_vblank().set(FUNC(sraider_state::screen_vblank_sraider));
screen.set_palette(m_palette);
GFXDECODE(config, m_gfxdecode, m_palette, gfx_sraider);
PALETTE(config, m_palette, FUNC(sraider_state::sraider_palette), 4*8 + 4*16 + 32 + 2, 32 + 32 + 1);
LADYBUG_VIDEO(config, m_video, 4000000).set_gfxdecode_tag(m_gfxdecode);
ZEROHOUR_STARS(config, m_stars).has_va_bit(false);
/* sound hardware */
SPEAKER(config, "mono").front_center();
SN76489(config, "sn1", 4000000).add_route(ALL_OUTPUTS, "mono", 0.2);
SN76489(config, "sn2", 4000000).add_route(ALL_OUTPUTS, "mono", 0.2);
SN76489(config, "sn3", 4000000).add_route(ALL_OUTPUTS, "mono", 0.2);
SN76489(config, "sn4", 4000000).add_route(ALL_OUTPUTS, "mono", 0.2);
SN76489(config, "sn5", 4000000).add_route(ALL_OUTPUTS, "mono", 0.2);
}
/***************************************************************************
Game driver(s)
ROM Definitions
***************************************************************************/
ROM_START( ladybug )
@ -1117,74 +899,15 @@ ROM_START( dorodon2 )
ROM_LOAD( "dorodon.bp2", 0x0040, 0x0020, CRC(27fa3a50) SHA1(7cf59b7a37c156640d6ea91554d1c4276c1780e0) ) /* timing?? */
ROM_END
ROM_START( mrsdyna )
ROM_REGION( 0x10000, "maincpu", 0 )
// NOTE: Mrs. Dynamite returns ROM ERROR in test mode. It does an 8-bit checksum on these 3
// ROMs and computes 0xFF. The answer to pass the test is 0x00.
// However, these images were dumped twice, and seem to work fine.
ROM_LOAD( "mrsd-8203a-r4.f3", 0x0000, 0x2000, CRC(c944062c) SHA1(c61fc327d67595e601f6a7e5e337646f5f9d351b) )
ROM_LOAD( "mrsd-8203a-n4.f2", 0x2000, 0x2000, CRC(d1b9c7bb) SHA1(c139c8ae5b14924eb04a265095a7ab95ac5370af) )
ROM_LOAD( "mrsd-8203a-m4.f1", 0x4000, 0x2000, CRC(d25b1dfe) SHA1(f68c6fb2cda37fcffbe7c3c2a3cc5cb372c4101b) )
ROM_REGION( 0x10000, "sub", 0 )
ROM_LOAD( "mrsd-8203a-h6.f4", 0x0000, 0x2000, CRC(04f8617b) SHA1(64deef2269790d8460d0ad510548e178f0f61607) )
ROM_LOAD( "mrsd-8203a-j6.f5", 0x2000, 0x2000, CRC(1ffb5fc3) SHA1(e8fc7b95663a396ef7d46ba6ce24973a3c343381) )
ROM_LOAD( "mrsd-8203a-l6.f6", 0x4000, 0x2000, CRC(5a0f5030) SHA1(d1530230fe6c666f7920cb82cb47f5fcc7e1ecc8) )
ROM_REGION( 0x2000, "gfx1", 0 )
ROM_LOAD( "mrsd-8203b-k6.f10", 0x0000, 0x1000, CRC(e33cb26e) SHA1(207fa986754f8d7cd0bb3e56fd271ee0c1990269) )
ROM_LOAD( "mrsd-8203b-l6.f11", 0x1000, 0x1000, CRC(a327ba05) SHA1(5eac27b48d14fec179919fe0902a6c7ada95f2b2) )
ROM_REGION( 0x2000, "gfx2", 0 )
ROM_LOAD( "mrsd-8203b-m2.f7", 0x0000, 0x1000, CRC(a00ae797) SHA1(adff7f38870b7e8fa114886792a3acbb7a5726ab) )
ROM_LOAD( "mrsd-8203b-n2.f8", 0x1000, 0x1000, CRC(81f2bdbd) SHA1(45ee1d62462cfadf7d2c46767f03ccfb3c876c08) )
ROM_REGION( 0x0060, "proms", 0 )
ROM_LOAD( "mrsd-10-1.a2", 0x0000, 0x0020, CRC(4a819ad4) SHA1(d9072af7e52b506c1bcf8a327242d470eb240857) )
ROM_LOAD( "mrsd-10-2.l3", 0x0020, 0x0020, CRC(2d926a3a) SHA1(129fb60ce3df67614e39dcaac9c93f0652addbbb) )
ROM_LOAD( "mrsd-10-3.c1", 0x0040, 0x0020, CRC(27fa3a50) SHA1(7cf59b7a37c156640d6ea91554d1c4276c1780e0) ) /* ?? */
ROM_END
ROM_START( sraider )
ROM_REGION( 0x10000, "maincpu", 0 )
ROM_LOAD( "sraid3.r4", 0x0000, 0x2000, CRC(0f389774) SHA1(c67596e6bf00175ff0a241506cd2f88114d05933) )
ROM_LOAD( "sraid2.n4", 0x2000, 0x2000, CRC(38a48db0) SHA1(6f4f384d702fb8ee4bb2ef579638239d57e32ddd) )
ROM_LOAD( "sraid1.m4", 0x4000, 0x2000, CRC(2f302a4e) SHA1(3a902ce6858f38df88b60830bef4b1d45b09b2df) )
ROM_REGION( 0x10000, "sub", 0 )
ROM_LOAD( "sraid-s4.h6", 0x0000, 0x2000, CRC(57173a12) SHA1(6cb8fd4826e499f9a4e63621d58bc4b596cc261e) )
ROM_LOAD( "sraid-s5.j6", 0x2000, 0x2000, CRC(5a459179) SHA1(a261c8f3c7c4cd4587c003bbbe815d2c4e01ffbc) )
ROM_LOAD( "sraid-s6.l6", 0x4000, 0x2000, CRC(ea3aa25d) SHA1(353c0d075d5e0a3bc25a65e2748f5eb5212a844d) )
ROM_REGION( 0x2000, "gfx1", 0 )
ROM_LOAD( "sraid-s0.k6", 0x0000, 0x1000, CRC(a0373909) SHA1(00e3bd5dd90769d670fc3c51edd1cd4b69e6132d) )
ROM_LOAD( "sraids11.l6", 0x1000, 0x1000, CRC(ba22d949) SHA1(83762ced1df92ff594887e44d5b783826bbfb0c9) )
ROM_REGION( 0x2000, "gfx2", 0 )
ROM_LOAD( "sraid-s7.m2", 0x0000, 0x1000, CRC(299f8e07) SHA1(1de71f251286088487da7285d6f8070147002af5) )
ROM_LOAD( "sraid-s8.n2", 0x1000, 0x1000, CRC(57ba8888) SHA1(2aa1a5f682d146a55a96e471bb78e5c60da02bf9) )
ROM_REGION( 0x1000, "gfx3", 0 ) /* fixed portion of the grid */
ROM_LOAD( "sraid-s9.f6", 0x0000, 0x1000, CRC(2380b90f) SHA1(0310554e3f2ec973c2bb6e816d04e5c0c1e0a0b9) )
ROM_REGION( 0x0060, "proms", 0 )
ROM_LOAD( "srpr10-1.a2", 0x0000, 0x0020, CRC(121fdb99) SHA1(3bc092da40beb129a4df3db2f55d22bbbcf7bad8) )
ROM_LOAD( "srpr10-2.l3", 0x0020, 0x0020, CRC(88b67e70) SHA1(e21ee2939e96dffee101bd92c62ed975b6b64001) )
ROM_LOAD( "srpr10-3.c1", 0x0040, 0x0020, CRC(27fa3a50) SHA1(7cf59b7a37c156640d6ea91554d1c4276c1780e0) ) /* ?? */
ROM_END
} // anonymous namespace
void dorodon_state::init_dorodon()
{
/* decode the opcodes */
uint8_t *rom = memregion("maincpu")->base();
uint8_t *table = memregion("user1")->base();
for (offs_t i = 0; i < 0x6000; i++)
m_decrypted_opcodes[i] = table[rom[i]];
}
/***************************************************************************
Drivers
***************************************************************************/
// YEAR NAME PARENT MACHINE INPUT STATE INIT SCREEN COMPANY FULLNAME FLAGS
GAME( 1981, cavenger, 0, ladybug, cavenger, ladybug_state, empty_init, ROT0, "Universal", "Cosmic Avenger", MACHINE_SUPPORTS_SAVE )
GAME( 1981, ladybug, 0, ladybug, ladybug, ladybug_state, empty_init, ROT270, "Universal", "Lady Bug", MACHINE_SUPPORTS_SAVE )
GAME( 1981, ladybugb, ladybug, ladybug, ladybug, ladybug_state, empty_init, ROT270, "bootleg", "Lady Bug (bootleg)", MACHINE_SUPPORTS_SAVE )
@ -1192,5 +915,3 @@ GAME( 1981, ladybugb2, ladybug, ladybug, ladybug, ladybug_state, empty_init,
GAME( 1981, snapjack, 0, ladybug, snapjack, ladybug_state, empty_init, ROT0, "Universal", "Snap Jack", MACHINE_SUPPORTS_SAVE )
GAME( 1982, dorodon, 0, dorodon, dorodon, dorodon_state, init_dorodon, ROT270, "UPL (Falcon license?)", "Dorodon (set 1)", MACHINE_SUPPORTS_SAVE ) // license or bootleg?
GAME( 1982, dorodon2, dorodon, dorodon, dorodon, dorodon_state, init_dorodon, ROT270, "UPL (Falcon license?)", "Dorodon (set 2)", MACHINE_SUPPORTS_SAVE ) // "
GAME( 1982, mrsdyna, 0, mrsdyna, mrsdyna, mrsdyna_state, empty_init, ROT270, "Universal", "Mrs. Dynamite", MACHINE_SUPPORTS_SAVE )
GAME( 1982, sraider, 0, sraider, sraider, sraider_state, empty_init, ROT270, "Universal", "Space Raider", MACHINE_SUPPORTS_SAVE )

View File

@ -1,160 +0,0 @@
// license:BSD-3-Clause
// copyright-holders:Nicola Salmoria
/*************************************************************************
Universal 8106-A2 + 8106-B PCB set
*************************************************************************/
#ifndef MAME_INCLUDES_LADYBUG_H
#define MAME_INCLUDES_LADYBUG_H
#pragma once
#include "ladybug_v.h"
#include "zerohour_stars.h"
#include "emupal.h"
#include "tilemap.h"
class ladybug_base_state : public driver_device
{
protected:
using driver_device::driver_device;
void palette_init_common(
palette_device &palette, const uint8_t *color_prom,
int r_bit0, int r_bit1,
int g_bit0, int g_bit1,
int b_bit0, int b_bit1) const;
};
// ladybug platform
class ladybug_state : public ladybug_base_state
{
public:
ladybug_state(const machine_config &mconfig, device_type type, const char *tag)
: ladybug_base_state(mconfig, type, tag)
, m_maincpu(*this, "maincpu")
, m_video(*this, "video")
, m_port_dsw0(*this, "DSW0")
, m_p1_control(*this, "CONTP1")
, m_p2_control(*this, "CONTP2")
{ }
DECLARE_CUSTOM_INPUT_MEMBER(ladybug_p1_control_r);
DECLARE_CUSTOM_INPUT_MEMBER(ladybug_p2_control_r);
DECLARE_INPUT_CHANGED_MEMBER(coin1_inserted);
DECLARE_INPUT_CHANGED_MEMBER(coin2_inserted);
void ladybug(machine_config &config);
protected:
DECLARE_WRITE_LINE_MEMBER(flipscreen_w);
void ladybug_palette(palette_device &palette) const;
uint32_t screen_update_ladybug(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect);
void ladybug_map(address_map &map);
required_device<cpu_device> m_maincpu;
private:
required_device<ladybug_video_device> m_video;
required_ioport m_port_dsw0;
optional_ioport m_p1_control;
optional_ioport m_p2_control;
};
// ladybug plus program decryption
class dorodon_state : public ladybug_state
{
public:
dorodon_state(const machine_config &mconfig, device_type type, const char *tag)
: ladybug_state(mconfig, type, tag)
, m_decrypted_opcodes(*this, "decrypted_opcodes")
{ }
void init_dorodon();
void dorodon(machine_config &config);
protected:
void decrypted_opcodes_map(address_map &map);
private:
required_shared_ptr<uint8_t> m_decrypted_opcodes;
};
// 8203 hardware adds grid tilemap, 2nd audio CPU
class mrsdyna_state : public ladybug_base_state
{
public:
mrsdyna_state(const machine_config &mconfig, device_type type, const char *tag)
: ladybug_base_state(mconfig, type, tag)
, m_palette(*this, "palette")
, m_gfxdecode(*this, "gfxdecode")
, m_video(*this, "video")
{ }
void mrsdyna(machine_config &config);
protected:
uint8_t mrsdyna_protection_r();
void mrsdyna_weird_w(offs_t offset, uint8_t data);
void mrsdyna_0x30_w(offs_t offset, uint8_t data);
void mrsdyna_0x38_w(offs_t offset, uint8_t data);
uint8_t mrsdyna_rnd_r();
void mrsdyna_io_w(uint8_t data);
void mrsdyna_palette(palette_device &palette) const;
DECLARE_WRITE_LINE_MEMBER(screen_vblank_sraider);
TILE_GET_INFO_MEMBER(get_grid_tile_info);
virtual void machine_start() override;
virtual void machine_reset() override;
uint32_t screen_update_mrsdyna(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect);
void mrsdyna_cpu1_map(address_map &map);
void mrsdyna_cpu2_io_map(address_map &map);
void mrsdyna_cpu2_map(address_map &map);
required_device<palette_device> m_palette;
required_device<gfxdecode_device> m_gfxdecode;
required_device<ladybug_video_device> m_video;
tilemap_t *m_grid_tilemap = nullptr;
uint8_t m_grid_color = 0U;
uint8_t m_0x30 = 0U;
uint8_t m_0x38 = 0U;
uint8_t m_weird_value[8]{};
};
// add stars from zerohour, uses grid layer
class sraider_state : public mrsdyna_state
{
public:
sraider_state(const machine_config &mconfig, device_type type, const char *tag)
: mrsdyna_state(mconfig, type, tag)
, m_grid_data(*this, "grid_data")
, m_stars(*this, "stars")
{ }
void sraider(machine_config &config);
protected:
void sraider_io_w(uint8_t data);
void sraider_palette(palette_device &palette) const;
DECLARE_WRITE_LINE_MEMBER(screen_vblank_sraider);
TILE_GET_INFO_MEMBER(get_grid_tile_info);
virtual void video_start() override;
uint32_t screen_update_sraider(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect);
void sraider_cpu2_map(address_map &map);
private:
required_shared_ptr<uint8_t> m_grid_data;
required_device<zerohour_stars_device> m_stars;
};
#endif // MAME_INCLUDES_LADYBUG_H

View File

@ -1,386 +0,0 @@
// license:BSD-3-Clause
// copyright-holders:Nicola Salmoria
/***************************************************************************
video.c
Functions to emulate the video hardware of the machine.
***************************************************************************/
#include "emu.h"
#include "ladybug_v.h"
#include "ladybug.h"
#include "video/resnet.h"
#include <algorithm>
DEFINE_DEVICE_TYPE(LADYBUG_VIDEO, ladybug_video_device, "ladybug_video", "Lady Bug/Space Raider background")
/***************************************************************************
ladybug/sraider video
***************************************************************************/
ladybug_video_device::ladybug_video_device(machine_config const &mconfig, char const *tag, device_t *owner, u32 clock)
: device_t(mconfig, LADYBUG_VIDEO, tag, owner, clock)
, m_gfxdecode(*this, finder_base::DUMMY_TAG)
, m_spr_ram()
, m_bg_ram()
, m_bg_tilemap(nullptr)
{
}
void ladybug_video_device::bg_w(offs_t offset, uint8_t data)
{
m_bg_ram[offset & 0x07ff] = data;
m_bg_tilemap->mark_tile_dirty(offset & 0x03ff);
}
void ladybug_video_device::draw(screen_device &screen, bitmap_ind16 &bitmap, rectangle const &cliprect, bool flip)
{
// TODO: confirm whether sraider hardware actually does this - not used by the game
for (unsigned offs = 0; offs < 32; ++offs)
{
int const scroll = m_bg_ram[((offs & 0x03) << 5) | (offs >> 2)];
m_bg_tilemap->set_scrollx(offs, flip ? -scroll : scroll);
}
m_bg_tilemap->draw(screen, bitmap, cliprect, 0);
for (int offs = 0x400 - (0x40 << 1); (0x40 << 1) <= offs; offs -= 0x40)
{
int i = 0;
while ((0x40 > i) && m_spr_ram[offs + i])
i += 4;
while (0 < i)
{
/*
abccdddd eeeeeeee fffghhhh iiiiiiii
a enable?
b size (0 = 8x8, 1 = 16x16)
cc flip
dddd y offset
eeeeeeee sprite code (shift right 2 bits for 16x16 sprites)
fff unknown
g sprite bank
hhhh color
iiiiiiii x position
*/
i -= 4;
bool const enable(m_spr_ram[offs + i] & 0x80);
if (enable)
{
bool const big(m_spr_ram[offs + i] & 0x40);
bool const xflip(m_spr_ram[offs + i] & 0x20);
bool const yflip(m_spr_ram[offs + i] & 0x10);
int const code(m_spr_ram[offs + i + 1] | (BIT(m_spr_ram[offs + i + 2], 4) << 8));
int const color(m_spr_ram[offs + i + 2] & 0x0f);
int const xpos(m_spr_ram[offs + i + 3]);
int const ypos((offs >> 2) | (m_spr_ram[offs + i] & 0x0f));
if (big) // 16x16
m_gfxdecode->gfx(1)->transpen(bitmap, cliprect, code >> 2, color, xflip, yflip, xpos, ypos - 8, 0);
else // 8x8
m_gfxdecode->gfx(2)->transpen(bitmap, cliprect, code, color, xflip, yflip, xpos, ypos, 0);
}
}
}
}
void ladybug_video_device::device_start()
{
m_spr_ram = std::make_unique<u8 []>(0x0400);
m_bg_ram = std::make_unique<u8 []>(0x0800);
std::fill_n(m_spr_ram.get(), 0x0400, 0);
std::fill_n(m_bg_ram.get(), 0x0800, 0);
m_bg_tilemap = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(*this, FUNC(ladybug_video_device::get_bg_tile_info)), TILEMAP_SCAN_ROWS, 8, 8, 32, 32);
m_bg_tilemap->set_scroll_rows(32);
m_bg_tilemap->set_transparent_pen(0);
save_pointer(NAME(m_spr_ram), 0x0400);
save_pointer(NAME(m_bg_ram), 0x0800);
}
TILE_GET_INFO_MEMBER(ladybug_video_device::get_bg_tile_info)
{
int const code = m_bg_ram[tile_index] + (BIT(m_bg_ram[0x0400 | tile_index], 3) << 8);
int const color = m_bg_ram[0x0400 | tile_index] & 0x07;
tileinfo.set(0, code, color, 0);
}
/***************************************************************************
Convert the color PROMs into a more useable format.
Lady Bug has a 32 bytes palette PROM and a 32 bytes sprite color lookup
table PROM.
The palette PROM is connected to the RGB output this way:
bit 7 -- inverter -- 220 ohm resistor -- BLUE
-- inverter -- 220 ohm resistor -- GREEN
-- inverter -- 220 ohm resistor -- RED
-- inverter -- 470 ohm resistor -- BLUE
-- unused
-- inverter -- 470 ohm resistor -- GREEN
-- unused
bit 0 -- inverter -- 470 ohm resistor -- RED
***************************************************************************/
void ladybug_base_state::palette_init_common(palette_device &palette, const uint8_t *color_prom,
int r_bit0, int r_bit1, int g_bit0, int g_bit1, int b_bit0, int b_bit1) const
{
static constexpr int resistances[2] = { 470, 220 };
// compute the color output resistor weights
double rweights[2], gweights[2], bweights[2];
compute_resistor_weights(0, 255, -1.0,
2, resistances, rweights, 470, 0,
2, resistances, gweights, 470, 0,
2, resistances, bweights, 470, 0);
// create a lookup table for the palette
for (int i = 0; i < 0x20; i++)
{
int bit0, bit1;
// red component
bit0 = BIT(~color_prom[i], r_bit0);
bit1 = BIT(~color_prom[i], r_bit1);
int const r = combine_weights(rweights, bit0, bit1);
// green component
bit0 = BIT(~color_prom[i], g_bit0);
bit1 = BIT(~color_prom[i], g_bit1);
int const g = combine_weights(gweights, bit0, bit1);
// blue component
bit0 = BIT(~color_prom[i], b_bit0);
bit1 = BIT(~color_prom[i], b_bit1);
int const b = combine_weights(bweights, bit0, bit1);
palette.set_indirect_color(i, rgb_t(r, g, b));
}
// color_prom now points to the beginning of the lookup table
color_prom += 0x20;
// characters
for (int i = 0; i < 0x20; i++)
{
uint8_t const ctabentry = ((i << 3) & 0x18) | ((i >> 2) & 0x07);
palette.set_pen_indirect(i, ctabentry);
}
// sprites
for (int i = 0; i < 0x20; i++)
{
uint8_t ctabentry;
ctabentry = bitswap<4>((color_prom[i] >> 0) & 0x0f, 0,1,2,3);
palette.set_pen_indirect(i + 0x20, ctabentry);
ctabentry = bitswap<4>((color_prom[i] >> 4) & 0x0f, 0,1,2,3);
palette.set_pen_indirect(i + 0x40, ctabentry);
}
}
void ladybug_state::ladybug_palette(palette_device &palette) const
{
palette_init_common(palette, memregion("proms")->base(), 0, 5, 2, 6, 4, 7);
}
WRITE_LINE_MEMBER(ladybug_state::flipscreen_w)
{
if (flip_screen() != state)
{
flip_screen_set(state);
machine().tilemap().mark_all_dirty();
}
}
uint32_t ladybug_state::screen_update_ladybug(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
{
bitmap.fill(0, cliprect);
m_video->draw(screen, bitmap, cliprect, flip_screen());
return 0;
}
void mrsdyna_state::mrsdyna_palette(palette_device &palette) const
{
const uint8_t *color_prom = memregion("proms")->base();
// the resistor net may be probably different than Lady Bug
palette_init_common(palette, color_prom, 3, 0, 5, 4, 7, 6);
for (int i = 0; i < 0x20; i++)
palette.set_pen_indirect(i + 0x60, i + 0x20);
// stationary part of grid
palette.set_pen_indirect(0x81, 0x40);
}
void sraider_state::sraider_palette(palette_device &palette) const
{
const uint8_t *color_prom = memregion("proms")->base();
// the resistor net may be probably different than Lady Bug
palette_init_common(palette, color_prom, 3, 0, 5, 4, 7, 6);
// star colors
for (int i = 0; i < 0x20; i++)
{
int bit0, bit1;
// red component
bit0 = BIT(i, 3);
bit1 = BIT(i, 4);
int const b = 0x47 * bit0 + 0x97 * bit1;
// green component
bit0 = BIT(i, 1);
bit1 = BIT(i, 2);
int const g = 0x47 * bit0 + 0x97 * bit1;
// blue component
bit0 = BIT(i, 0);
int const r = 0x47 * bit0;
palette.set_indirect_color(i + 0x20, rgb_t(r, g, b));
}
for (int i = 0; i < 0x20; i++)
palette.set_pen_indirect(i + 0x60, i + 0x20);
// stationary part of grid
palette.set_pen_indirect(0x81, 0x40);
}
TILE_GET_INFO_MEMBER(sraider_state::get_grid_tile_info)
{
if (tile_index < 512)
{
tileinfo.set(3, tile_index, 0, 0);
}
else
{
int temp = tile_index / 32;
tile_index = (31 - temp) * 32 + (tile_index % 32);
tileinfo.set(4, tile_index, 0, 0);
}
}
void mrsdyna_state::mrsdyna_io_w(uint8_t data)
{
// bit7 = flip
// bit6 = grid red
// bit5 = grid green
// bit4 = grid blue
// bit3 = enable stars
// bit210 = stars speed/dir
if (flip_screen() != (data & 0x80))
{
flip_screen_set(data & 0x80);
machine().tilemap().mark_all_dirty();
}
m_grid_color = data & 0x70;
}
void sraider_state::sraider_io_w(uint8_t data)
{
mrsdyna_state::mrsdyna_io_w(data);
m_stars->set_enable(BIT(data, 3));
// There must be a subtle clocking difference between
// Space Raider and the other games using this star generator,
// hence the -1 here
m_stars->set_speed((data & 0x07) - 1, 0x07);
}
void sraider_state::video_start()
{
mrsdyna_state::video_start();
m_grid_tilemap = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(*this, FUNC(sraider_state::get_grid_tile_info)), TILEMAP_SCAN_ROWS, 8, 8, 32, 32);
m_grid_tilemap->set_scroll_rows(32);
m_grid_tilemap->set_transparent_pen(0);
}
WRITE_LINE_MEMBER(sraider_state::screen_vblank_sraider)/* update starfield position */
{
// falling edge
if (!state)
m_stars->update_state();
}
uint32_t mrsdyna_state::screen_update_mrsdyna(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
{
// clear the bg bitmap
bitmap.fill(0, cliprect);
// now the chars/sprites
m_video->draw(screen, bitmap, cliprect, flip_screen());
return 0;
}
uint32_t sraider_state::screen_update_sraider(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
{
// clear the bg bitmap
bitmap.fill(0, cliprect);
// draw the stars
rectangle stars_clip = cliprect;
if (flip_screen())
{
stars_clip.min_x = 0x27;
stars_clip.max_x = 0xff;
}
else
{
stars_clip.min_x = 0x00;
stars_clip.max_x = 0xd8;
}
stars_clip &= cliprect;
m_stars->draw(bitmap, stars_clip);
// draw the gridlines
m_palette->set_indirect_color(0x40, rgb_t(
m_grid_color & 0x40 ? 0xff : 0,
m_grid_color & 0x20 ? 0xff : 0,
m_grid_color & 0x10 ? 0xff : 0));
m_grid_tilemap->draw(screen, bitmap, cliprect, 0, flip_screen());
for (unsigned i = 0; i < 0x100; i++)
{
if (m_grid_data[i] != 0)
{
uint8_t x = i;
int height = cliprect.max_y - cliprect.min_y + 1;
if (flip_screen())
x = ~x;
bitmap.plot_box(x, cliprect.min_y, 1, height, 0x81);
}
}
// now the chars/sprites
m_video->draw(screen, bitmap, cliprect, flip_screen());
return 0;
}

View File

@ -0,0 +1,109 @@
// license:BSD-3-Clause
// copyright-holders:Nicola Salmoria
/***************************************************************************
ladybug/sraider tile/sprite hardware
***************************************************************************/
#include "emu.h"
#include "ladybug_video.h"
#include <algorithm>
DEFINE_DEVICE_TYPE(LADYBUG_VIDEO, ladybug_video_device, "ladybug_video", "Lady Bug/Space Raider video")
ladybug_video_device::ladybug_video_device(machine_config const &mconfig, char const *tag, device_t *owner, u32 clock)
: device_t(mconfig, LADYBUG_VIDEO, tag, owner, clock)
, m_gfxdecode(*this, finder_base::DUMMY_TAG)
{
}
void ladybug_video_device::device_start()
{
m_spr_ram = std::make_unique<u8 []>(0x0400);
m_bg_ram = std::make_unique<u8 []>(0x0800);
std::fill_n(m_spr_ram.get(), 0x0400, 0);
std::fill_n(m_bg_ram.get(), 0x0800, 0);
m_bg_tilemap = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(*this, FUNC(ladybug_video_device::get_bg_tile_info)), TILEMAP_SCAN_ROWS, 8, 8, 32, 32);
m_bg_tilemap->set_scroll_rows(32);
m_bg_tilemap->set_transparent_pen(0);
save_pointer(NAME(m_spr_ram), 0x0400);
save_pointer(NAME(m_bg_ram), 0x0800);
}
void ladybug_video_device::bg_w(offs_t offset, uint8_t data)
{
m_bg_ram[offset & 0x07ff] = data;
m_bg_tilemap->mark_tile_dirty(offset & 0x03ff);
}
TILE_GET_INFO_MEMBER(ladybug_video_device::get_bg_tile_info)
{
int const code = m_bg_ram[tile_index] + (BIT(m_bg_ram[0x0400 | tile_index], 3) << 8);
int const color = m_bg_ram[0x0400 | tile_index] & 0x07;
tileinfo.set(0, code, color, 0);
}
void ladybug_video_device::draw(screen_device &screen, bitmap_ind16 &bitmap, rectangle const &cliprect, bool flip)
{
// TODO: confirm whether sraider hardware actually does this - not used by the game
for (unsigned offs = 0; offs < 32; ++offs)
{
int const scroll = m_bg_ram[((offs & 0x03) << 5) | (offs >> 2)];
m_bg_tilemap->set_scrollx(offs, flip ? -scroll : scroll);
}
m_bg_tilemap->draw(screen, bitmap, cliprect, 0);
draw_sprites(bitmap, cliprect);
}
void ladybug_video_device::draw_sprites(bitmap_ind16 &bitmap, const rectangle &cliprect)
{
for (int offs = 0x400 - (0x40 << 1); (0x40 << 1) <= offs; offs -= 0x40)
{
// find last valid sprite of current block
int i = 0;
while ((0x40 > i) && m_spr_ram[offs + i])
i += 4;
while (0 < i)
{
/*
abccdddd eeeeeeee fffghhhh iiiiiiii
a enable?
b size (0 = 8x8, 1 = 16x16)
cc flip
dddd y offset
eeeeeeee sprite code (shift right 2 bits for 16x16 sprites)
fff unknown
g sprite bank
hhhh color
iiiiiiii x position
*/
i -= 4;
bool const enable(m_spr_ram[offs + i] & 0x80);
if (enable)
{
bool const big(m_spr_ram[offs + i] & 0x40);
bool const xflip(m_spr_ram[offs + i] & 0x20);
bool const yflip(m_spr_ram[offs + i] & 0x10);
int const code(m_spr_ram[offs + i + 1] | (BIT(m_spr_ram[offs + i + 2], 4) << 8));
int const color(m_spr_ram[offs + i + 2] & 0x0f);
int const xpos(m_spr_ram[offs + i + 3]);
int const ypos((offs >> 2) | (m_spr_ram[offs + i] & 0x0f));
if (big) // 16x16
m_gfxdecode->gfx(1)->transpen(bitmap, cliprect, code >> 2, color, xflip, yflip, xpos, ypos - 8, 0);
else // 8x8
m_gfxdecode->gfx(2)->transpen(bitmap, cliprect, code, color, xflip, yflip, xpos, ypos, 0);
}
}
}
}

View File

@ -30,6 +30,8 @@ protected:
TILE_GET_INFO_MEMBER(get_bg_tile_info);
private:
void draw_sprites(bitmap_ind16 &bitmap, rectangle const &cliprect);
required_device<gfxdecode_device> m_gfxdecode;
std::unique_ptr<u8 []> m_spr_ram;
std::unique_ptr<u8 []> m_bg_ram;

View File

@ -0,0 +1,755 @@
// license:BSD-3-Clause
// copyright-holders:Frank Palazzolo
/***************************************************************************
Universal 8203-A + 8203-B PCB set
Space Raider
Mrs. Dynamite
Space Raider also uses the Starfield generator board from Zero Hour,
Connected via flywires to these boards
TODO:
- decode cpu#2 writes to port 0x30 and 0x38 - resistors for sound
- decode cpu#2 writes to port 0x28-0x2f - ???
- unknown dips
***************************************************************************/
#include "emu.h"
#include "ladybug_video.h"
#include "zerohour_stars.h"
#include "cpu/z80/z80.h"
#include "machine/74259.h"
#include "machine/gen_latch.h"
#include "sound/sn76496.h"
#include "video/resnet.h"
#include "emupal.h"
#include "screen.h"
#include "speaker.h"
#include "tilemap.h"
#include <algorithm>
namespace {
// stripped down hardware, mrsdyna runs on this
class mrsdyna_state : public driver_device
{
public:
mrsdyna_state(const machine_config &mconfig, device_type type, const char *tag)
: driver_device(mconfig, type, tag)
, m_maincpu(*this, "maincpu")
, m_subcpu(*this, "sub")
, m_palette(*this, "palette")
, m_gfxdecode(*this, "gfxdecode")
, m_video(*this, "video")
{ }
void mrsdyna(machine_config &config);
protected:
uint8_t protection_r();
void unk_0x28_w(uint8_t data);
void unk_0x30_w(uint8_t data);
void unk_0x38_w(uint8_t data);
uint8_t rnd_r();
virtual void io_w(uint8_t data);
void mrsdyna_palette(palette_device &palette) const;
DECLARE_WRITE_LINE_MEMBER(update_stars);
virtual void machine_start() override;
virtual uint32_t screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect);
void cpu1_map(address_map &map);
void cpu2_map(address_map &map);
void cpu2_io_map(address_map &map);
required_device<cpu_device> m_maincpu;
required_device<cpu_device> m_subcpu;
required_device<palette_device> m_palette;
required_device<gfxdecode_device> m_gfxdecode;
required_device<ladybug_video_device> m_video;
uint8_t m_grid_color = 0;
uint8_t m_0x28 = 0;
uint8_t m_0x30 = 0;
uint8_t m_0x38 = 0;
};
// add stars from zerohour, uses grid layer
class sraider_state : public mrsdyna_state
{
public:
sraider_state(const machine_config &mconfig, device_type type, const char *tag)
: mrsdyna_state(mconfig, type, tag)
, m_grid_data(*this, "grid_data")
, m_stars(*this, "stars")
{ }
void sraider(machine_config &config);
protected:
virtual void io_w(uint8_t data) override;
void sraider_palette(palette_device &palette) const;
DECLARE_WRITE_LINE_MEMBER(update_stars);
TILE_GET_INFO_MEMBER(get_grid_tile_info);
tilemap_t *m_grid_tilemap = nullptr;
virtual void video_start() override;
virtual uint32_t screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect) override;
private:
required_shared_ptr<uint8_t> m_grid_data;
required_device<zerohour_stars_device> m_stars;
};
void mrsdyna_state::machine_start()
{
save_item(NAME(m_grid_color));
save_item(NAME(m_0x28));
save_item(NAME(m_0x30));
save_item(NAME(m_0x38));
}
/***************************************************************************
Video
***************************************************************************/
void mrsdyna_state::mrsdyna_palette(palette_device &palette) const
{
// assumed to be the same as Lady Bug
static constexpr int resistances[2] = { 470, 220 };
// compute the color output resistor weights
double rweights[2], gweights[2], bweights[2];
compute_resistor_weights(0, 255, -1.0,
2, resistances, rweights, 470, 0,
2, resistances, gweights, 470, 0,
2, resistances, bweights, 470, 0);
const uint8_t *color_prom = memregion("proms")->base();
// create a lookup table for the palette
for (int i = 0; i < 0x20; i++)
{
int bit0, bit1;
// red component
bit0 = BIT(~color_prom[i], 3);
bit1 = BIT(~color_prom[i], 0);
int const r = combine_weights(rweights, bit0, bit1);
// green component
bit0 = BIT(~color_prom[i], 5);
bit1 = BIT(~color_prom[i], 4);
int const g = combine_weights(gweights, bit0, bit1);
// blue component
bit0 = BIT(~color_prom[i], 7);
bit1 = BIT(~color_prom[i], 6);
int const b = combine_weights(bweights, bit0, bit1);
palette.set_indirect_color(i, rgb_t(r, g, b));
}
// color_prom now points to the beginning of the lookup table
color_prom += 0x20;
// characters
for (int i = 0; i < 0x20; i++)
{
uint8_t const ctabentry = ((i << 3) & 0x18) | ((i >> 2) & 0x07);
palette.set_pen_indirect(i, ctabentry);
}
// sprites
for (int i = 0; i < 0x20; i++)
{
uint8_t ctabentry;
ctabentry = bitswap<4>((color_prom[i] >> 0) & 0x0f, 0,1,2,3);
palette.set_pen_indirect(i + 0x20, ctabentry);
ctabentry = bitswap<4>((color_prom[i] >> 4) & 0x0f, 0,1,2,3);
palette.set_pen_indirect(i + 0x40, ctabentry);
}
}
void sraider_state::sraider_palette(palette_device &palette) const
{
mrsdyna_palette(palette);
// star colors
for (int i = 0; i < 0x20; i++)
{
int bit0, bit1;
// red component
bit0 = BIT(i, 0);
int const r = 0x97 * bit0;
// green component
bit0 = BIT(i, 2);
bit1 = BIT(i, 1);
int const g = 0x47 * bit0 + 0x97 * bit1;
// blue component
bit0 = BIT(i, 4);
bit1 = BIT(i, 3);
int const b = 0x47 * bit0 + 0x97 * bit1;
palette.set_indirect_color(i + 0x20, rgb_t(r, g, b));
palette.set_pen_indirect(i + 0x60, i + 0x20);
}
// stationary part of grid
palette.set_pen_indirect(0x80, 0x00);
palette.set_pen_indirect(0x81, 0x40);
}
TILE_GET_INFO_MEMBER(sraider_state::get_grid_tile_info)
{
if (tile_index < 512)
{
tileinfo.set(3, tile_index, 0, 0);
}
else
{
int temp = tile_index / 32;
tile_index = (31 - temp) * 32 + (tile_index % 32);
tileinfo.set(4, tile_index, 0, 0);
}
}
void sraider_state::video_start()
{
mrsdyna_state::video_start();
m_grid_tilemap = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(*this, FUNC(sraider_state::get_grid_tile_info)), TILEMAP_SCAN_ROWS, 8, 8, 32, 32);
m_grid_tilemap->set_scroll_rows(32);
m_grid_tilemap->set_transparent_pen(0);
}
WRITE_LINE_MEMBER(sraider_state::update_stars)
{
if (!state)
m_stars->update_state();
}
uint32_t mrsdyna_state::screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
{
// clear the bg bitmap
bitmap.fill(0, cliprect);
// now the chars/sprites
m_video->draw(screen, bitmap, cliprect, flip_screen());
return 0;
}
uint32_t sraider_state::screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
{
// clear the bg bitmap
bitmap.fill(0, cliprect);
// draw the stars
rectangle stars_clip = cliprect;
if (flip_screen())
{
stars_clip.min_x = 0x27;
stars_clip.max_x = 0xff;
}
else
{
stars_clip.min_x = 0x00;
stars_clip.max_x = 0xd8;
}
stars_clip &= cliprect;
m_stars->draw(bitmap, stars_clip);
// draw the gridlines
m_palette->set_indirect_color(0x40, rgb_t(
m_grid_color & 0x40 ? 0xff : 0,
m_grid_color & 0x20 ? 0xff : 0,
m_grid_color & 0x10 ? 0xff : 0));
m_grid_tilemap->draw(screen, bitmap, cliprect, 0, flip_screen());
for (unsigned i = 0; i < 0x100; i++)
{
if (m_grid_data[i] != 0)
{
uint8_t x = i;
int height = cliprect.max_y - cliprect.min_y + 1;
if (flip_screen())
x = ~x;
bitmap.plot_box(x, cliprect.min_y, 1, height, 0x81);
}
}
// now the chars/sprites
m_video->draw(screen, bitmap, cliprect, flip_screen());
return 0;
}
/***************************************************************************
I/O
***************************************************************************/
void mrsdyna_state::io_w(uint8_t data)
{
// bit7 = flip
// bit6 = grid red
// bit5 = grid green
// bit4 = grid blue
// bit3 = enable stars (not used for mrsdyna)
// bit210 = stars speed/dir (not used for mrsdyna)
if (flip_screen() != (data & 0x80))
{
flip_screen_set(data & 0x80);
machine().tilemap().mark_all_dirty();
}
m_grid_color = data & 0x70;
}
void sraider_state::io_w(uint8_t data)
{
mrsdyna_state::io_w(data);
m_stars->set_enable(BIT(data, 3));
// There must be a subtle clocking difference between
// Space Raider and the other games using this star generator,
// hence the -1 here
m_stars->set_speed((data & 0x07) - 1, 0x07);
}
// documentation TBD - 556 dual timer
uint8_t mrsdyna_state::rnd_r()
{
return machine().rand() & 3;
}
// Protection - documentation TBD
uint8_t mrsdyna_state::protection_r()
{
// This must return X011111X or cpu #1 will hang
// see code at rst $10
return 0x3e;
}
// Unknown IO - documentation TBD
void mrsdyna_state::unk_0x28_w(uint8_t data)
{
// These 8 bits are stored in the LS259 latch at A7,
// and connected to all the select lines on 2 4066s at B7/C7
m_0x28 = data;
}
// documentation TBD
void mrsdyna_state::unk_0x30_w(uint8_t data)
{
// bits 0-2 select 4051s at M7 and M8
// bits 3-5 select 4051s at K7 and K8
m_0x30 = data & 0x3f;
}
// documentation TBD
void mrsdyna_state::unk_0x38_w(uint8_t data)
{
// These 6 bits are stored in the LS174 latch at N8
// bits 0-2 select 4051s at H7 and H8
// bits 3-5 select 4051s at E7 and E8
m_0x38 = data & 0x3f;
}
/***************************************************************************
Address Maps
***************************************************************************/
void mrsdyna_state::cpu1_map(address_map &map)
{
// LS138 @ J4
map(0x0000, 0x5fff).rom(); // 2764s at R4, N4, and M4
// LS138 @ J4 and LS139 @ H4
map(0x6000, 0x6fff).ram(); // 6116s @ K3 & M3, also connected to clk on PAL K2 (16R6, U001)
map(0x7000, 0x73ff).w("video", FUNC(ladybug_video_device::spr_w)); // pin 29 on ribbon
//map(0x77ff, 0x7fff); // LS139 @ H4 pin7 is NC
// LS138 @ J4, Pin11 (0x8000-0x9fff) and
// LS138 @ N3 (bottom 3 bits)
// (all of these are read/write)
map(0x8005, 0x8005).mirror(0x1ff8).r(FUNC(mrsdyna_state::protection_r)); // OE on PAL @ K2 (16R6, U001) (100x xxxx xxxx x101)
map(0x8006, 0x8006).mirror(0x1ff8).w("soundlatch_low", FUNC(generic_latch_8_device::write)); // LS374 @ P6
map(0x8007, 0x8007).mirror(0x1ff8).w("soundlatch_high", FUNC(generic_latch_8_device::write)); // LS374 @ R6
map(0x8000, 0x8000).mirror(0x1ff8).portr("IN0");
map(0x8001, 0x8001).mirror(0x1ff8).portr("IN1");
map(0x8002, 0x8002).mirror(0x1ff8).portr("DSW0");
map(0x8003, 0x8003).mirror(0x1ff8).portr("DSW1");
//map(0x8004, 0x8004).mirror(0x1ff8).portr("IN2"); // extra JAMMA pins
// LS138 @ J4, Pin10 (0xa000-0xbfff) // NC
// LS138 @ J4, Pin9 (0xc000-0xdfff)
map(0xd000, 0xd7ff).w("video", FUNC(ladybug_video_device::bg_w)); // pin 27 on ribbon
// LS138 @ J4, Pin7 (0xe000-0xffff)
map(0xe000, 0xe000).nopw(); //unknown 0x10 when in attract, 0x20 when coined/playing - disabled watchdog based on LS123 @ F4
}
void mrsdyna_state::cpu2_map(address_map &map)
{
// LS138 @ P7
map(0x0000, 0x5fff).rom(); // 2764s at H6,J6, and L6
map(0x6000, 0x63ff).mirror(0x0400).ram(); // 2x2114 @ M6/N6
map(0x8000, 0x8000).mirror(0x1fff).r("soundlatch_low", FUNC(generic_latch_8_device::read)); // LS374 @ P6
map(0xa000, 0xa000).mirror(0x1fff).r("soundlatch_high", FUNC(generic_latch_8_device::read)); // LS374 @ R6
map(0xc000, 0xc000).mirror(0x1fff).r(FUNC(mrsdyna_state::rnd_r)); // LS125 @ P8 - reads 556 outputs to D1 and D0?
// LS138 @ P7 (nY7) and LS139 @ H4
map(0xe000, 0xe0ff).mirror(0x0300).writeonly().share("grid_data"); // HD6148P @ D6
map(0xe800, 0xefff).w(FUNC(mrsdyna_state::io_w)); // LS273 @ D4
//map(0xf000, 0xf7ff) // NC
//map(0xf800, 0xffff) // NC
}
void mrsdyna_state::cpu2_io_map(address_map &map)
{
map.global_mask(0xff);
// LS138 @ A8
map(0x00, 0x07).w("sn1", FUNC(sn76489_device::write)); // J214X2 @ N9
map(0x08, 0x0f).w("sn2", FUNC(sn76489_device::write)); // J214X2 @ M9
map(0x10, 0x17).w("sn3", FUNC(sn76489_device::write)); // J214X2 @ L9
map(0x18, 0x1f).w("sn4", FUNC(sn76489_device::write)); // J214X2 @ K9
map(0x20, 0x27).w("sn5", FUNC(sn76489_device::write)); // J214X2 @ J9
map(0x28, 0x2f).w("unklatch", FUNC(ls259_device::write_d0)); // LS259 @ A7
map(0x30, 0x37).w(FUNC(mrsdyna_state::unk_0x30_w)); // LS174 @ N7
map(0x38, 0x3f).w(FUNC(mrsdyna_state::unk_0x38_w)); // LS174 @ N8
}
/***************************************************************************
Input Ports
***************************************************************************/
static INPUT_PORTS_START( sraider )
PORT_START("IN0")
PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_JOYSTICK_LEFT ) PORT_4WAY
PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_JOYSTICK_DOWN ) PORT_4WAY
PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_JOYSTICK_RIGHT ) PORT_4WAY
PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_JOYSTICK_UP ) PORT_4WAY
PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_BUTTON1 )
PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_START1 )
PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_START2 )
PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_UNKNOWN ) // JAMMA PIN 12
PORT_START("IN1")
PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_JOYSTICK_LEFT ) PORT_4WAY PORT_COCKTAIL
PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_JOYSTICK_DOWN ) PORT_4WAY PORT_COCKTAIL
PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_JOYSTICK_RIGHT ) PORT_4WAY PORT_COCKTAIL
PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_JOYSTICK_UP ) PORT_4WAY PORT_COCKTAIL
PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_BUTTON1 ) PORT_COCKTAIL
PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_UNKNOWN ) // VBLANK????
PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_COIN1 )
PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_COIN2 )
PORT_START("DSW0") // DSW0 @ R3 via '244 @ R2
PORT_DIPNAME( 0x03, 0x03, DEF_STR( Difficulty ) ) PORT_DIPLOCATION("SW0:7,8")
PORT_DIPSETTING( 0x03, DEF_STR( Easy ) )
PORT_DIPSETTING( 0x02, DEF_STR( Medium ) )
PORT_DIPSETTING( 0x01, DEF_STR( Hard ) )
PORT_DIPSETTING( 0x00, DEF_STR( Hardest ) )
PORT_DIPNAME( 0x04, 0x04, "High Score Names" ) PORT_DIPLOCATION("SW0:6")
PORT_DIPSETTING( 0x00, "3 Letters" )
PORT_DIPSETTING( 0x04, "10 Letters" )
PORT_DIPNAME( 0x08, 0x08, DEF_STR( Allow_Continue ) ) PORT_DIPLOCATION("SW0:5")
PORT_DIPSETTING( 0x08, DEF_STR( No ) )
PORT_DIPSETTING( 0x00, DEF_STR( Yes ) )
PORT_DIPNAME( 0x10, 0x10, DEF_STR( Unknown ) ) PORT_DIPLOCATION("SW0:4")
PORT_DIPSETTING( 0x10, DEF_STR( Off ) )
PORT_DIPSETTING( 0x00, DEF_STR( On ) )
PORT_DIPNAME( 0x20, 0x00, DEF_STR( Cabinet ) ) PORT_DIPLOCATION("SW0:3")
PORT_DIPSETTING( 0x00, DEF_STR( Upright ) )
PORT_DIPSETTING( 0x20, DEF_STR( Cocktail ) )
PORT_DIPNAME( 0xc0, 0xc0, DEF_STR( Lives ) ) PORT_DIPLOCATION("SW0:1,2")
PORT_DIPSETTING( 0x00, "2" )
PORT_DIPSETTING( 0xc0, "3" )
PORT_DIPSETTING( 0x80, "4" )
PORT_DIPSETTING( 0x40, "5" )
// Free Play setting works when it's set for both
PORT_START("DSW1") // DSW1 @ P3 via '244 @ P2
PORT_DIPNAME( 0x0f, 0x0f, DEF_STR( Coin_A ) ) PORT_DIPLOCATION("SW1:8,7,6,5")
// settings 0x00 through 0x05 all give 1 Coin/1 Credit
PORT_DIPSETTING( 0x06, DEF_STR( 4C_1C ) )
PORT_DIPSETTING( 0x08, DEF_STR( 3C_1C ) )
PORT_DIPSETTING( 0x0a, DEF_STR( 2C_1C ) )
PORT_DIPSETTING( 0x07, DEF_STR( 3C_2C ) )
PORT_DIPSETTING( 0x09, DEF_STR( 2C_2C ) )
PORT_DIPSETTING( 0x0f, DEF_STR( 1C_1C ) )
PORT_DIPSETTING( 0x0e, DEF_STR( 1C_2C ) )
PORT_DIPSETTING( 0x0d, DEF_STR( 1C_3C ) )
PORT_DIPSETTING( 0x0c, DEF_STR( 1C_4C ) )
PORT_DIPSETTING( 0x0b, DEF_STR( 1C_5C ) )
PORT_DIPSETTING( 0x00, DEF_STR( Free_Play ) )
PORT_DIPNAME( 0xf0, 0xf0, DEF_STR( Coin_B ) ) PORT_DIPLOCATION("SW1:4,3,2,1")
// settings 0x00 through 0x50 all give 1 Coin/1 Credit
PORT_DIPSETTING( 0x60, DEF_STR( 4C_1C ) )
PORT_DIPSETTING( 0x80, DEF_STR( 3C_1C ) )
PORT_DIPSETTING( 0xa0, DEF_STR( 2C_1C ) )
PORT_DIPSETTING( 0x70, DEF_STR( 3C_2C ) )
PORT_DIPSETTING( 0x90, DEF_STR( 2C_2C ) )
PORT_DIPSETTING( 0xf0, DEF_STR( 1C_1C ) )
PORT_DIPSETTING( 0xe0, DEF_STR( 1C_2C ) )
PORT_DIPSETTING( 0xd0, DEF_STR( 1C_3C ) )
PORT_DIPSETTING( 0xc0, DEF_STR( 1C_4C ) )
PORT_DIPSETTING( 0xb0, DEF_STR( 1C_5C ) )
PORT_DIPSETTING( 0x00, DEF_STR( Free_Play ) )
INPUT_PORTS_END
static INPUT_PORTS_START( mrsdyna )
PORT_INCLUDE( sraider )
PORT_MODIFY("DSW0")
PORT_DIPNAME( 0x01, 0x01, DEF_STR( Unknown ) ) PORT_DIPLOCATION("SW0:8")
PORT_DIPSETTING( 0x01, DEF_STR( Off ) )
PORT_DIPSETTING( 0x00, DEF_STR( On ) )
PORT_DIPNAME( 0x02, 0x02, DEF_STR( Unknown ) ) PORT_DIPLOCATION("SW0:7")
PORT_DIPSETTING( 0x02, DEF_STR( Off ) )
PORT_DIPSETTING( 0x00, DEF_STR( On ) )
PORT_DIPNAME( 0x04, 0x04, "High Score Names" ) PORT_DIPLOCATION("SW0:6")
PORT_DIPSETTING( 0x00, "3 Letters" )
PORT_DIPSETTING( 0x04, "12 Letters" )
PORT_DIPNAME( 0x08, 0x08, DEF_STR( Unknown ) ) PORT_DIPLOCATION("SW0:5")
PORT_DIPSETTING( 0x08, DEF_STR( Off ) )
PORT_DIPSETTING( 0x00, DEF_STR( On ) )
PORT_DIPNAME( 0x10, 0x10, DEF_STR( Unknown ) ) PORT_DIPLOCATION("SW0:4")
PORT_DIPSETTING( 0x10, DEF_STR( Off ) )
PORT_DIPSETTING( 0x00, DEF_STR( On ) )
PORT_DIPNAME( 0x20, 0x00, DEF_STR( Cabinet ) ) PORT_DIPLOCATION("SW0:3")
PORT_DIPSETTING( 0x00, DEF_STR( Upright ) )
PORT_DIPSETTING( 0x20, DEF_STR( Cocktail ) )
PORT_DIPNAME( 0xc0, 0xc0, DEF_STR( Lives ) ) PORT_DIPLOCATION("SW0:1,2")
PORT_DIPSETTING( 0x00, "2" )
PORT_DIPSETTING( 0xc0, "3" )
PORT_DIPSETTING( 0x80, "4" )
PORT_DIPSETTING( 0x40, "5" )
INPUT_PORTS_END
/***************************************************************************
GFX Layouts
***************************************************************************/
static const gfx_layout charlayout =
{
8,8, /* 8*8 characters */
512, /* 512 characters */
2, /* 2 bits per pixel */
{ 0, 512*8*8 }, /* the two bitplanes are separated */
{ 7, 6, 5, 4, 3, 2, 1, 0 },
{ 0*8, 1*8, 2*8, 3*8, 4*8, 5*8, 6*8, 7*8 },
8*8 /* every char takes 8 consecutive bytes */
};
static const gfx_layout spritelayout =
{
16,16, /* 16*16 sprites */
128, /* 128 sprites */
2, /* 2 bits per pixel */
{ 1, 0 }, /* the two bitplanes are packed in two consecutive bits */
{ 0, 2, 4, 6, 8, 10, 12, 14,
8*16+0, 8*16+2, 8*16+4, 8*16+6, 8*16+8, 8*16+10, 8*16+12, 8*16+14 },
{ 23*16, 22*16, 21*16, 20*16, 19*16, 18*16, 17*16, 16*16,
7*16, 6*16, 5*16, 4*16, 3*16, 2*16, 1*16, 0*16 },
64*8 /* every sprite takes 64 consecutive bytes */
};
static const gfx_layout spritelayout2 =
{
8,8, /* 8*8 sprites */
512, /* 512 sprites */
2, /* 2 bits per pixel */
{ 1, 0 }, /* the two bitplanes are packed in two consecutive bits */
{ 0, 2, 4, 6, 8, 10, 12, 14 },
{ 7*16, 6*16, 5*16, 4*16, 3*16, 2*16, 1*16, 0*16 },
16*8 /* every sprite takes 16 consecutive bytes */
};
static const gfx_layout gridlayout =
{
8,8, /* 8*8 characters */
512, /* 512 characters */
1, /* 1 bit per pixel */
{ 0 },
{ 7, 6, 5, 4, 3, 2, 1, 0 },
{ 0*8, 1*8, 2*8, 3*8, 4*8, 5*8, 6*8, 7*8},
8*8 /* every char takes 8 consecutive bytes */
};
static const gfx_layout gridlayout2 =
{
8,8, /* 8*8 characters */
512, /* 512 characters */
1, /* 1 bit per pixel */
{ 0 },
{ 7, 6, 5, 4, 3, 2, 1, 0 },
{ 7*8, 6*8, 5*8, 4*8, 3*8, 2*8, 1*8, 0*8 },
8*8 /* every char takes 8 consecutive bytes */
};
static GFXDECODE_START( gfx_mrsdyna )
GFXDECODE_ENTRY( "gfx1", 0, charlayout, 0, 8 )
GFXDECODE_ENTRY( "gfx2", 0, spritelayout, 4*8, 16 )
GFXDECODE_ENTRY( "gfx2", 0, spritelayout2, 4*8, 16 )
GFXDECODE_END
static GFXDECODE_START( gfx_sraider )
GFXDECODE_ENTRY( "gfx1", 0, charlayout, 0, 8 )
GFXDECODE_ENTRY( "gfx2", 0, spritelayout, 4*8, 16 )
GFXDECODE_ENTRY( "gfx2", 0, spritelayout2, 4*8, 16 )
GFXDECODE_ENTRY( "gfx3", 0, gridlayout, 4*8+4*16+32, 1 )
GFXDECODE_ENTRY( "gfx3", 0, gridlayout2, 4*8+4*16+32, 1 )
GFXDECODE_END
/***************************************************************************
Machine Configs
***************************************************************************/
void mrsdyna_state::mrsdyna(machine_config &config)
{
// basic machine hardware
Z80(config, m_maincpu, 4000000);
m_maincpu->set_addrmap(AS_PROGRAM, &mrsdyna_state::cpu1_map);
m_maincpu->set_vblank_int("screen", FUNC(mrsdyna_state::irq0_line_hold));
Z80(config, m_subcpu, 4000000);
m_subcpu->set_addrmap(AS_PROGRAM, &mrsdyna_state::cpu2_map);
m_subcpu->set_addrmap(AS_IO, &mrsdyna_state::cpu2_io_map);
m_subcpu->set_vblank_int("screen", FUNC(mrsdyna_state::irq0_line_hold));
GENERIC_LATCH_8(config, "soundlatch_low");
GENERIC_LATCH_8(config, "soundlatch_high");
ls259_device &unklatch(LS259(config, "unklatch"));
unklatch.parallel_out_cb().set(FUNC(mrsdyna_state::unk_0x28_w));
// video hardware
screen_device &screen(SCREEN(config, "screen", SCREEN_TYPE_RASTER));
screen.set_raw(9'828'000 / 2, 312, 8, 248, 262, 32, 224);
screen.set_screen_update(FUNC(mrsdyna_state::screen_update));
screen.set_palette(m_palette);
GFXDECODE(config, m_gfxdecode, m_palette, gfx_mrsdyna);
PALETTE(config, m_palette, FUNC(mrsdyna_state::mrsdyna_palette), 4*8 + 4*16, 32);
LADYBUG_VIDEO(config, m_video, 4000000).set_gfxdecode_tag(m_gfxdecode);
// sound hardware
SPEAKER(config, "mono").front_center();
SN76489(config, "sn1", 4000000).add_route(ALL_OUTPUTS, "mono", 0.2);
SN76489(config, "sn2", 4000000).add_route(ALL_OUTPUTS, "mono", 0.2);
SN76489(config, "sn3", 4000000).add_route(ALL_OUTPUTS, "mono", 0.2);
SN76489(config, "sn4", 4000000).add_route(ALL_OUTPUTS, "mono", 0.2);
SN76489(config, "sn5", 4000000).add_route(ALL_OUTPUTS, "mono", 0.2);
}
void sraider_state::sraider(machine_config &config)
{
mrsdyna(config);
// video hardware
GFXDECODE(config.replace(), m_gfxdecode, m_palette, gfx_sraider);
PALETTE(config.replace(), m_palette, FUNC(sraider_state::sraider_palette), 4*8 + 4*16 + 32 + 2, 32 + 32 + 1);
ZEROHOUR_STARS(config, m_stars).has_va_bit(false);
subdevice<screen_device>("screen")->screen_vblank().set(FUNC(sraider_state::update_stars));
}
/***************************************************************************
ROM Definitions
***************************************************************************/
ROM_START( sraider )
ROM_REGION( 0x10000, "maincpu", 0 )
ROM_LOAD( "sraid3.r4", 0x0000, 0x2000, CRC(0f389774) SHA1(c67596e6bf00175ff0a241506cd2f88114d05933) )
ROM_LOAD( "sraid2.n4", 0x2000, 0x2000, CRC(38a48db0) SHA1(6f4f384d702fb8ee4bb2ef579638239d57e32ddd) )
ROM_LOAD( "sraid1.m4", 0x4000, 0x2000, CRC(2f302a4e) SHA1(3a902ce6858f38df88b60830bef4b1d45b09b2df) )
ROM_REGION( 0x10000, "sub", 0 )
ROM_LOAD( "sraid-s4.h6", 0x0000, 0x2000, CRC(57173a12) SHA1(6cb8fd4826e499f9a4e63621d58bc4b596cc261e) )
ROM_LOAD( "sraid-s5.j6", 0x2000, 0x2000, CRC(5a459179) SHA1(a261c8f3c7c4cd4587c003bbbe815d2c4e01ffbc) )
ROM_LOAD( "sraid-s6.l6", 0x4000, 0x2000, CRC(ea3aa25d) SHA1(353c0d075d5e0a3bc25a65e2748f5eb5212a844d) )
ROM_REGION( 0x2000, "gfx1", 0 )
ROM_LOAD( "sraid-s0.k6", 0x0000, 0x1000, CRC(a0373909) SHA1(00e3bd5dd90769d670fc3c51edd1cd4b69e6132d) )
ROM_LOAD( "sraids11.l6", 0x1000, 0x1000, CRC(ba22d949) SHA1(83762ced1df92ff594887e44d5b783826bbfb0c9) )
ROM_REGION( 0x2000, "gfx2", 0 )
ROM_LOAD( "sraid-s7.m2", 0x0000, 0x1000, CRC(299f8e07) SHA1(1de71f251286088487da7285d6f8070147002af5) )
ROM_LOAD( "sraid-s8.n2", 0x1000, 0x1000, CRC(57ba8888) SHA1(2aa1a5f682d146a55a96e471bb78e5c60da02bf9) )
ROM_REGION( 0x1000, "gfx3", 0 ) /* fixed portion of the grid */
ROM_LOAD( "sraid-s9.f6", 0x0000, 0x1000, CRC(2380b90f) SHA1(0310554e3f2ec973c2bb6e816d04e5c0c1e0a0b9) )
ROM_REGION( 0x0060, "proms", 0 )
ROM_LOAD( "srpr10-1.a2", 0x0000, 0x0020, CRC(121fdb99) SHA1(3bc092da40beb129a4df3db2f55d22bbbcf7bad8) )
ROM_LOAD( "srpr10-2.l3", 0x0020, 0x0020, CRC(88b67e70) SHA1(e21ee2939e96dffee101bd92c62ed975b6b64001) )
ROM_LOAD( "srpr10-3.c1", 0x0040, 0x0020, CRC(27fa3a50) SHA1(7cf59b7a37c156640d6ea91554d1c4276c1780e0) ) /* ?? */
ROM_END
ROM_START( mrsdyna )
ROM_REGION( 0x10000, "maincpu", 0 )
// NOTE: Mrs. Dynamite returns ROM ERROR in test mode. It does an 8-bit checksum on these 3
// ROMs and computes 0xFF. The answer to pass the test is 0x00.
// However, these images were dumped twice, and seem to work fine.
ROM_LOAD( "mrsd-8203a-r4.f3", 0x0000, 0x2000, CRC(c944062c) SHA1(c61fc327d67595e601f6a7e5e337646f5f9d351b) )
ROM_LOAD( "mrsd-8203a-n4.f2", 0x2000, 0x2000, CRC(d1b9c7bb) SHA1(c139c8ae5b14924eb04a265095a7ab95ac5370af) )
ROM_LOAD( "mrsd-8203a-m4.f1", 0x4000, 0x2000, CRC(d25b1dfe) SHA1(f68c6fb2cda37fcffbe7c3c2a3cc5cb372c4101b) )
ROM_REGION( 0x10000, "sub", 0 )
ROM_LOAD( "mrsd-8203a-h6.f4", 0x0000, 0x2000, CRC(04f8617b) SHA1(64deef2269790d8460d0ad510548e178f0f61607) )
ROM_LOAD( "mrsd-8203a-j6.f5", 0x2000, 0x2000, CRC(1ffb5fc3) SHA1(e8fc7b95663a396ef7d46ba6ce24973a3c343381) )
ROM_LOAD( "mrsd-8203a-l6.f6", 0x4000, 0x2000, CRC(5a0f5030) SHA1(d1530230fe6c666f7920cb82cb47f5fcc7e1ecc8) )
ROM_REGION( 0x2000, "gfx1", 0 )
ROM_LOAD( "mrsd-8203b-k6.f10", 0x0000, 0x1000, CRC(e33cb26e) SHA1(207fa986754f8d7cd0bb3e56fd271ee0c1990269) )
ROM_LOAD( "mrsd-8203b-l6.f11", 0x1000, 0x1000, CRC(a327ba05) SHA1(5eac27b48d14fec179919fe0902a6c7ada95f2b2) )
ROM_REGION( 0x2000, "gfx2", 0 )
ROM_LOAD( "mrsd-8203b-m2.f7", 0x0000, 0x1000, CRC(a00ae797) SHA1(adff7f38870b7e8fa114886792a3acbb7a5726ab) )
ROM_LOAD( "mrsd-8203b-n2.f8", 0x1000, 0x1000, CRC(81f2bdbd) SHA1(45ee1d62462cfadf7d2c46767f03ccfb3c876c08) )
ROM_REGION( 0x0060, "proms", 0 )
ROM_LOAD( "mrsd-10-1.a2", 0x0000, 0x0020, CRC(4a819ad4) SHA1(d9072af7e52b506c1bcf8a327242d470eb240857) )
ROM_LOAD( "mrsd-10-2.l3", 0x0020, 0x0020, CRC(2d926a3a) SHA1(129fb60ce3df67614e39dcaac9c93f0652addbbb) )
ROM_LOAD( "mrsd-10-3.c1", 0x0040, 0x0020, CRC(27fa3a50) SHA1(7cf59b7a37c156640d6ea91554d1c4276c1780e0) ) /* ?? */
ROM_END
} // anonymous namespace
/***************************************************************************
Drivers
***************************************************************************/
// YEAR NAME PARENT MACHINE INPUT STATE INIT SCREEN COMPANY FULLNAME FLAGS
GAME( 1982, sraider, 0, sraider, sraider, sraider_state, empty_init, ROT270, "Universal", "Space Raider", MACHINE_SUPPORTS_SAVE )
GAME( 1982, mrsdyna, 0, mrsdyna, mrsdyna, mrsdyna_state, empty_init, ROT270, "Universal", "Mrs. Dynamite", MACHINE_SUPPORTS_SAVE )

View File

@ -15,7 +15,7 @@ Notes:
TODO:
- Colors are not right. In zerohour P1 score should be white, the top score green,
and "TOP" should be magenta. How is this determined? It's as if only the top part
of the screen has this exception. Maybe via the unknown PROM? Sprite colors look ok.
of the screen has this exception. Sprite colors look ok.
- Some graphical problems in both games
- redclash supports more background layer effects: white+mixed with other colors,
used in canyon parts and during the big ufo explosion
@ -323,7 +323,7 @@ void zerohour_state::zerohour(machine_config &config)
screen_device &screen(SCREEN(config, "screen", SCREEN_TYPE_RASTER));
screen.set_raw(9.828_MHz_XTAL / 2, 312, 8, 248, 262, 32, 224);
screen.set_screen_update(FUNC(zerohour_state::screen_update));
screen.screen_vblank().set(FUNC(zerohour_state::screen_vblank));
screen.screen_vblank().set(FUNC(zerohour_state::update_stars));
screen.set_palette(m_palette);
GFXDECODE(config, m_gfxdecode, m_palette, gfx_zerohour);

View File

@ -41,7 +41,7 @@ protected:
virtual void video_start() override;
private:
DECLARE_WRITE_LINE_MEMBER(screen_vblank);
DECLARE_WRITE_LINE_MEMBER(update_stars);
void videoram_w(offs_t offset, uint8_t data);
DECLARE_WRITE_LINE_MEMBER(gfxbank_w);
DECLARE_WRITE_LINE_MEMBER(flipscreen_w);

View File

@ -13,7 +13,7 @@
These will scroll at a rate controlled by the speed register
I'm basically doing the same thing by drawing each
starfield on alternate frames, and then offseting them
starfield on alternate frames, and then offsetting them
***************************************************************************/
@ -112,12 +112,12 @@ void zerohour_stars_device::draw(bitmap_ind16 &bitmap, rectangle const &cliprect
bool const feedback((state & 0x00020) ? !tempbit : tempbit);
bool const hcond(BIT(xloc + 8, 4));
bool const vcond(!m_has_va_bit || BIT(yloc, 0));
bool const vcond(m_has_va_bit || BIT(yloc, 0));
if (cliprect.contains(xloc, yloc) && (hcond == vcond))
{
if (((state & 0x000ff) == 0x000ff) && !feedback)
bitmap.pix(yloc, xloc) = m_pal_offset + ((state >> 9) & 0x1f);
bitmap.pix(yloc, xloc) = m_pal_offset + (state >> 9 & 0x1f);
}
// update LFSR state

View File

@ -52,18 +52,18 @@ void zerohour_state::palette(palette_device &palette) const
int bit0, bit1;
// red component
bit0 = BIT(i, 3);
bit1 = BIT(i, 4);
int const b = 0x47 * bit0 + 0x97 * bit1;
bit0 = BIT(i, 0);
int const r = 0x97 * bit0;
// green component
bit0 = BIT(i, 1);
bit1 = BIT(i, 2);
bit0 = BIT(i, 2);
bit1 = BIT(i, 1);
int const g = 0x47 * bit0 + 0x97 * bit1;
// blue component
bit0 = BIT(i, 0);
int const r = 0x47 * bit0;
bit0 = BIT(i, 4);
bit1 = BIT(i, 3);
int const b = 0x47 * bit0 + 0x97 * bit1;
palette.set_indirect_color(i + 0x20, rgb_t(r, g, b));
}
@ -239,9 +239,8 @@ void zerohour_state::draw_bullets(bitmap_ind16 &bitmap, const rectangle &cliprec
}
}
WRITE_LINE_MEMBER(zerohour_state::screen_vblank)
WRITE_LINE_MEMBER(zerohour_state::update_stars)
{
// falling edge
if (!state)
m_stars->update_state();
}