summaryrefslogtreecommitdiffstatshomepage
path: root/src
diff options
context:
space:
mode:
author Dirk Best <mail@dirk-best.de>2020-04-02 17:58:39 +0200
committer Dirk Best <mail@dirk-best.de>2020-04-02 18:03:37 +0200
commit52e149a22c945481943261e697714eb15ec34eed (patch)
treec124c463a14674541e4cbef75cb6d1ba4ced9664 /src
parent1455df4ff57defaddac250d9fd4fb72fe600d42c (diff)
New working machines
-------------------- Lady Gum [Dirk Best]
Diffstat (limited to 'src')
-rw-r--r--src/mame/drivers/videosaa.cpp456
-rw-r--r--src/mame/layout/videosaa.lay55
2 files changed, 449 insertions, 62 deletions
diff --git a/src/mame/drivers/videosaa.cpp b/src/mame/drivers/videosaa.cpp
index 84768b1a296..4d43ba2bde0 100644
--- a/src/mame/drivers/videosaa.cpp
+++ b/src/mame/drivers/videosaa.cpp
@@ -1,37 +1,72 @@
-// license:BSD-3-Clause
-// copyright-holders:
-/*
- Skeleton driver for gambling (?) games running on very similar PCBs manufactured by 'Videos A A'.
+// license: BSD-3-Clause
+// copyright-holders: Dirk Best
+/***************************************************************************
+
+ Joker Lady
+ Lady Gum
+ Paradar
+ Winner
+
+ © 1995? Videos A A
+
+ TODO:
+ - Palette
+ - Unknown tile attributes
+
+ Notes:
- Probably manufactured in Italy since PCBs are marked 'lato componenti' (components side) and 'lato
- saldature' (solder side). Lady Gum's 68HC705 ROM contains strings in French, though.
+ Probably manufactured in Italy since PCBs are marked 'lato componenti'
+ (components side) and 'lato saldature' (solder side). Lady Gum's 68HC705
+ ROM contains strings in French, though.
PCBs couldn't be tested so game titles are taken from ROM stickers.
- The only complete dump is Lady Gum, all the others are missing at least the 68HC705 internal ROM.
+ The only complete dump is Lady Gum, all the others are missing at least
+ the 68HC705 internal ROM.
- Hardware overview:
- Main CPU: MC68HC705C8ACS (verified on Winner, stickers and PCB marks on other games say 68HC705)
- CRTC: HD46505SP-2
- Sound: NEC D7759C
- RAM: 2 x 6116 or equivalent
- OSC: 10 MHz
- Dips: 1 x 8 dips bank
-*/
+ On the first service mode screen hold PROG (HOLD5), then push COIN (HOLD1)
+ to adjust the coin values.
+
+ Hardware:
+ - CPU: MC68HC705C8ACS (verified on Winner, stickers/PCB marks say 68HC705)
+ - CRTC: HD46505SP-2
+ - Sound: NEC D7759C
+ - RAM: 2x 6116 or equivalent
+ - OSC: 10 MHz
+ - Dips: 1x 8 dips bank
+
+***************************************************************************/
#include "emu.h"
-#include "emupal.h"
#include "cpu/m6805/m68hc05.h"
#include "sound/upd7759.h"
#include "video/mc6845.h"
+
+#include "emupal.h"
#include "screen.h"
+#include "speaker.h"
+#include "tilemap.h"
+
+#include "videosaa.lh"
+
+
+//**************************************************************************
+// TYPE DEFINITIONS
+//**************************************************************************
class videosaa_state : public driver_device
{
public:
videosaa_state(const machine_config &mconfig, device_type type, const char *tag)
- : driver_device(mconfig, type, tag)
- , m_maincpu(*this, "maincpu")
+ : driver_device(mconfig, type, tag),
+ m_maincpu(*this, "maincpu"),
+ m_crtc(*this, "crtc"),
+ m_gfxdecode(*this, "gfxdecode"),
+ m_adpcm(*this, "adpcm"),
+ m_in0(*this, "in0"),
+ m_in1(*this, "in1"),
+ m_dip(*this, "dip"),
+ m_lamps(*this, "lamp%u", 0U)
{ }
void videosaa(machine_config &config);
@@ -39,78 +74,368 @@ public:
protected:
virtual void machine_start() override;
virtual void machine_reset() override;
- virtual void video_start() override;
private:
- required_device<cpu_device> m_maincpu;
-
+ required_device<m68hc705c8a_device> m_maincpu;
+ required_device<hd6845s_device> m_crtc;
+ required_device<gfxdecode_device> m_gfxdecode;
+ required_device<upd7759_device> m_adpcm;
+
+ required_ioport m_in0;
+ required_ioport m_in1;
+ required_ioport m_dip;
+
+ output_finder<6> m_lamps;
+
+ uint8_t maincpu_porta_r();
+ void maincpu_porta_w(uint8_t data);
+ void maincpu_portb_w(uint8_t data);
+ void maincpu_portc_w(uint8_t data);
+ uint8_t maincpu_portd_r();
+
+ uint8_t m_porta;
+ uint8_t m_portb;
+ uint8_t m_portc;
+
+ uint8_t m_chip_latch;
+ uint8_t m_video_latch[4];
+
+ TILE_GET_INFO_MEMBER(tile_info);
uint32_t screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect);
+ void videosaa_palette(palette_device &palette) const;
+
+ std::unique_ptr<uint8_t[]> m_vram0;
+ std::unique_ptr<uint8_t[]> m_vram1;
+
+ tilemap_t *m_tilemap;
};
-void videosaa_state::video_start()
+
+//**************************************************************************
+// INPUT PORT DEFINITIONS
+//**************************************************************************
+
+static INPUT_PORTS_START( videosaa )
+ PORT_START("in0")
+ PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_OTHER) // aux
+ PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_OTHER) // aux
+ PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_COIN1)
+ PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_COIN2)
+ PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_OTHER) // aux
+ PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_OTHER) // aux
+ PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_BUTTON1) PORT_NAME("O.GUM-LOT")
+ PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_SERVICE)
+
+ PORT_START("in1")
+ PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_POKER_HOLD1)
+ PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_POKER_HOLD2)
+ PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_POKER_HOLD3)
+ PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_POKER_HOLD4)
+ PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_POKER_HOLD5)
+ PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_START1)
+ PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_OTHER) // aux
+ PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_GAMBLE_PAYOUT) PORT_NAME("LOT")
+
+ PORT_START("dip")
+ PORT_DIPNAME(0x03, 0x03, "Payout")
+ PORT_DIPSETTING( 0x00, "40%")
+ PORT_DIPSETTING( 0x01, "50%")
+ PORT_DIPSETTING( 0x02, "60%")
+ PORT_DIPSETTING( 0x03, "70%")
+ PORT_DIPLOCATION("DIP:1,2")
+ PORT_DIPNAME(0x04, 0x04, "Limit 1 Coin")
+ PORT_DIPSETTING( 0x04, DEF_STR( No ))
+ PORT_DIPSETTING( 0x00, DEF_STR( Yes ))
+ PORT_DIPLOCATION("DIP:3")
+ PORT_DIPUNKNOWN_DIPLOC( 0x08, 0x08, "DIP:4" )
+ PORT_DIPUNKNOWN_DIPLOC( 0x10, 0x10, "DIP:5" )
+ PORT_DIPNAME(0x20, 0x20, "Auto Hold")
+ PORT_DIPSETTING( 0x20, DEF_STR( No ))
+ PORT_DIPSETTING( 0x00, DEF_STR( Yes ))
+ PORT_DIPLOCATION("DIP:6")
+ PORT_DIPNAME(0x40, 0x40, "Kings or Better")
+ PORT_DIPSETTING( 0x40, DEF_STR( No ))
+ PORT_DIPSETTING( 0x00, DEF_STR( Yes ))
+ PORT_DIPLOCATION("DIP:7")
+ PORT_DIPUNKNOWN_DIPLOC( 0x80, 0x80, "DIP:8" )
+INPUT_PORTS_END
+
+
+//**************************************************************************
+// VIDEO EMULATION
+//**************************************************************************
+
+TILE_GET_INFO_MEMBER(videosaa_state::tile_info)
{
+ // 7------- tile bit 8
+ // -65----- unknown
+ // ---4---- tile bit 9
+ // ----3--- unknown (or tile bit 9?)
+ // -----210 color
+
+ uint8_t data = m_vram0[tile_index];
+ uint8_t attr = m_vram1[tile_index];
+
+ uint16_t tile = (BIT(attr, 4) << 9) | (BIT(attr, 7) << 8) | data;
+
+ tileinfo.set(0, tile, attr & 0x07, 0);
}
uint32_t videosaa_state::screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect)
{
+ m_tilemap->draw(screen, bitmap, cliprect, 0, 0);
return 0;
}
-static INPUT_PORTS_START( videosaa )
-INPUT_PORTS_END
+static GFXDECODE_START( gfx )
+ GFXDECODE_ENTRY( "gfx", 0, gfx_8x8x3_planar, 0, 8 )
+GFXDECODE_END
-static const gfx_layout tiles_layout = // seems to give reasonable results but needs verifying
+void videosaa_state::videosaa_palette(palette_device &palette) const
{
- 8,8,
- RGN_FRAC(1,3),
- 3,
- { RGN_FRAC(1,3), RGN_FRAC(2,3), RGN_FRAC(0,3) },
- { 0, 1, 2, 3, 4, 5, 6, 7 },
- { 0*8, 1*8, 2*8, 3*8, 4*8, 5*8, 6*8, 7*8 },
- 8*8
-};
+ // basic 3 bit palette
+ for (int i = 0; i < 8; i++)
+ palette.set_indirect_color(i, rgb_t(pal1bit(i >> 0), pal1bit(i >> 2), pal1bit(i >> 1)));
+
+ // wrong
+ palette.set_pen_indirect( 0, 0);
+ palette.set_pen_indirect( 7, 7);
+ palette.set_pen_indirect( 8, 0);
+ palette.set_pen_indirect(14, 7);
+ palette.set_pen_indirect(15, 6);
+ palette.set_pen_indirect(16, 0);
+ palette.set_pen_indirect(21, 7);
+ palette.set_pen_indirect(23, 5);
+ palette.set_pen_indirect(24, 0);
+ palette.set_pen_indirect(28, 7);
+ palette.set_pen_indirect(31, 4);
+ palette.set_pen_indirect(32, 0);
+ palette.set_pen_indirect(35, 7);
+ palette.set_pen_indirect(39, 3);
+ palette.set_pen_indirect(40, 0);
+ palette.set_pen_indirect(42, 7);
+ palette.set_pen_indirect(48, 2);
+ palette.set_pen_indirect(48, 7);
+ palette.set_pen_indirect(49, 0);
+ palette.set_pen_indirect(55, 1);
+ palette.set_pen_indirect(56, 0);
+ palette.set_pen_indirect(63, 0);
+}
-static GFXDECODE_START( gfx )
- GFXDECODE_ENTRY( "gfx", 0, tiles_layout, 0, 1 )
-GFXDECODE_END
+
+//**************************************************************************
+// MACHINE EMULATION
+//**************************************************************************
+
+uint8_t videosaa_state::maincpu_porta_r()
+{
+ return m_porta;
+}
+
+void videosaa_state::maincpu_porta_w(uint8_t data)
+{
+ m_porta = data;
+}
+
+void videosaa_state::maincpu_portb_w(uint8_t data)
+{
+ // 7------- porta latch
+ // -654---- porta latch address
+ // ----3--- portc latch
+ // -----210 portc latch address
+
+ if (BIT(data, 7) == 1)
+ {
+ switch ((data >> 4) & 0x07)
+ {
+ case 0:
+ m_porta = m_in0->read();
+ break;
+
+ case 1:
+ m_porta = m_in1->read();
+ break;
+
+ case 2:
+ // 76------ always 0
+ // --5----- 1 while playing, reset with "O.GUM-LOT" key
+ // ---43--- always 0
+ // -----2-- always 1
+ // ------1- toggles on first coin in
+ // -------0 always 0
+ break;
+
+ case 3:
+ // 76------ not used
+ // --5----- start lamp
+ // ---43210 hold lamps 5 to 1
+ m_lamps[0] = BIT(m_porta, 0);
+ m_lamps[1] = BIT(m_porta, 1);
+ m_lamps[2] = BIT(m_porta, 2);
+ m_lamps[3] = BIT(m_porta, 3);
+ m_lamps[4] = BIT(m_porta, 4);
+ m_lamps[5] = BIT(m_porta, 5);
+ break;
+
+ case 4:
+ // always 0?
+ if (m_porta)
+ logerror("Latch 4 port A = %02x\n", m_porta);
+ break;
+
+ case 5:
+ m_adpcm->port_w(m_porta);
+ break;
+
+ case 6:
+ m_porta = m_dip->read();
+ break;
+
+ case 7:
+ // 7------- mc6845 cs
+ // -6------ mc6845 rs
+ // --5----- unknown
+ // ---4---- unknown
+ // ----3--- unknown
+ // -----2-- upd7759 reset
+ // ------1- upd7759 start
+ // -------0 unknown
+ m_chip_latch = m_porta;
+ m_adpcm->start_w(BIT(m_chip_latch, 1));
+ m_adpcm->reset_w(BIT(m_chip_latch, 2));
+ break;
+ }
+ }
+
+ if (BIT(data, 3) == 1)
+ {
+ switch ((data >> 0) & 0x07)
+ {
+ case 0:
+ m_video_latch[0] = m_portc;
+
+ if (m_video_latch[0] < 0x08)
+ {
+ offs_t address = (m_video_latch[0] << 8) | m_video_latch[1];
+
+ m_vram0[address] = m_video_latch[3];
+ m_vram1[address] = m_video_latch[2];
+
+ m_tilemap->mark_tile_dirty(address);
+ }
+ else
+ logerror("VRAM high write: %02x\n", m_video_latch[0]);
+
+ break;
+
+ case 1:
+ m_video_latch[1] = m_portc;
+ break;
+
+ case 2:
+ m_video_latch[2] = m_portc;
+ break;
+
+ case 3:
+ m_video_latch[3] = m_portc;
+ break;
+
+ case 4:
+ if (BIT(m_chip_latch, 7) == 0 && BIT(m_chip_latch, 6) == 0)
+ m_crtc->address_w(m_portc);
+
+ if (BIT(m_chip_latch, 7) == 0 && BIT(m_chip_latch, 6) == 1)
+ m_crtc->register_w(m_portc);
+
+ break;
+
+ default:
+ logerror("Unknown latch port C: %d = %02x\n", (data >> 0) & 0x07, m_portc);
+ }
+ }
+
+ m_portb = data;
+}
+
+void videosaa_state::maincpu_portc_w(uint8_t data)
+{
+ m_portc = data;
+}
+
+uint8_t videosaa_state::maincpu_portd_r()
+{
+ // 7------- upd7759 busy
+ // -6543210 unused
+
+ return m_adpcm->busy_r() << 7;
+}
void videosaa_state::machine_start()
{
+ // allocate space for vram
+ m_vram0 = make_unique_clear<uint8_t[]>(0x800);
+ m_vram1 = make_unique_clear<uint8_t[]>(0x800);
+
+ m_tilemap = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(*this, FUNC(videosaa_state::tile_info)), TILEMAP_SCAN_ROWS, 8, 8, 32, 32);
+
+ m_lamps.resolve();
+
+ // register for savestates
+ save_pointer(NAME(m_vram0), 0x800);
+ save_pointer(NAME(m_vram1), 0x800);
+ save_item(NAME(m_chip_latch));
+ save_pointer(NAME(m_video_latch), 4);
}
void videosaa_state::machine_reset()
{
+ m_porta = 0;
+ m_portb = 0;
+ m_portc = 0;
}
+
+//**************************************************************************
+// MACHINE DEFINTIONS
+//**************************************************************************
+
void videosaa_state::videosaa(machine_config &config)
{
- /* basic machine hardware */
- M68HC705C8A(config, m_maincpu, 10_MHz_XTAL); // unknown divider
-
- /* video hardware */
- // all wrong
+ M68HC705C8A(config, m_maincpu, 10_MHz_XTAL / 4); // unknown divider
+ m_maincpu->porta_r().set(FUNC(videosaa_state::maincpu_porta_r));
+ m_maincpu->porta_w().set(FUNC(videosaa_state::maincpu_porta_w));
+ m_maincpu->portb_w().set(FUNC(videosaa_state::maincpu_portb_w));
+ m_maincpu->portc_w().set(FUNC(videosaa_state::maincpu_portc_w));
+ m_maincpu->portd_r().set(FUNC(videosaa_state::maincpu_portd_r));
+
+ // video hardware
screen_device& screen(SCREEN(config, "screen", SCREEN_TYPE_RASTER));
- screen.set_refresh_hz(60);
- screen.set_vblank_time(ATTOSECONDS_IN_USEC(0));
- screen.set_size(640, 480);
- screen.set_visarea(0, 640-1, 0, 480-1);
+ screen.set_raw(10_MHz_XTAL / 2, 320, 0, 256, 312, 0, 256); // 5 MHz?
screen.set_screen_update(FUNC(videosaa_state::screen_update));
- HD6845S(config, "crtc", 10_MHz_XTAL); // unknown divider
+ HD6845S(config, m_crtc, 10_MHz_XTAL / 16); // 0.625 MHz?
+ m_crtc->set_screen("screen");
+ m_crtc->set_show_border_area(false);
+ m_crtc->set_char_width(8);
+ m_crtc->out_vsync_callback().set_inputline(m_maincpu, M68HC05_IRQ_LINE);
- GFXDECODE(config, "gfxdecode", "palette", gfx);
+ GFXDECODE(config, m_gfxdecode, "palette", gfx);
- PALETTE(config, "palette", palette_device::RGB_3BIT);
+ PALETTE(config, "palette", FUNC(videosaa_state::videosaa_palette), 64, 8);
- /* sound hardware */
- UPD7759(config, "upd");
-}
+ // sound hardware
+ SPEAKER(config, "mono").front_center();
-/***************************************************************************
+ UPD7759(config, m_adpcm);
+ m_adpcm->add_route(ALL_OUTPUTS, "mono", 0.50);
+
+ config.set_default_layout(layout_videosaa);
+}
- Game drivers
-***************************************************************************/
+//**************************************************************************
+// ROM DEFINITIONS
+//**************************************************************************
ROM_START( jokrlady )
ROM_REGION(0x2000, "maincpu", 0)
@@ -121,7 +446,7 @@ ROM_START( jokrlady )
ROM_LOAD( "jokerlady-video1.7b", 0x2000, 0x2000, CRC(196932d8) SHA1(5130f03dd88f841a00ef328f12c6211bec377c77) )
ROM_LOAD( "jokerlady-video2.8b", 0x4000, 0x2000, CRC(58d62dbd) SHA1(cfcab2ca0c081f62185ce59e98124e2c5d368f49) )
- ROM_REGION( 0x10000, "upd", 0 )
+ ROM_REGION( 0x10000, "adpcm", 0 )
ROM_LOAD( "jokerlady-msg0.5a", 0x00000, 0x10000, NO_DUMP ) // 27512, damaged, reads weren't consistent
ROM_REGION( 0x200, "plds", 0 )
@@ -131,13 +456,14 @@ ROM_END
ROM_START( ladygum )
ROM_REGION(0x2000, "maincpu", 0)
ROM_LOAD( "68hc705-ladygum-4.0d", 0x0000, 0x2000, CRC(ea099edf) SHA1(eb0e4ccb025cf2a71d2016d501b4da11f8d21677) ) // actual label 68hc705-ladygum-#4.0d
+ ROM_FILL(0x1353, 1, 0x0f) // increase watchdog timeout, cpu core issue?
ROM_REGION( 0x6000, "gfx", 0 ) // all 27C64
ROM_LOAD( "ladygum-video0.5b", 0x0000, 0x2000, CRC(c1b72a5b) SHA1(abb9c19be474a83e4f4568a5431634ba7a61d8db) )
ROM_LOAD( "ladygum-video1.7b", 0x2000, 0x2000, CRC(70448e1f) SHA1(3c0a94284193e7d0f4efb8ffa746b9150d0119e4) )
ROM_LOAD( "ladygum-video2.8b", 0x4000, 0x2000, CRC(58d62dbd) SHA1(cfcab2ca0c081f62185ce59e98124e2c5d368f49) )
- ROM_REGION( 0x10000, "upd", 0 )
+ ROM_REGION( 0x10000, "adpcm", 0 )
ROM_LOAD( "ladygum-msg0.5a", 0x00000, 0x10000, CRC(c1f23f58) SHA1(c89579e53545291638be66e51512458b67251f67) ) // 27512
ROM_REGION( 0x200, "plds", 0 )
@@ -153,7 +479,7 @@ ROM_START( paradar )
ROM_LOAD( "paradar-video1.7b", 0x2000, 0x2000, CRC(72b05246) SHA1(65988850188915583870a7fbb23b84193c1e753d) )
ROM_LOAD( "paradar-video2.8b", 0x4000, 0x2000, CRC(b5eb61a0) SHA1(3ce63c7a68cf3e5343ceec53d477a1322e7f2929) )
- ROM_REGION( 0x10000, "upd", 0 )
+ ROM_REGION( 0x10000, "adpcm", 0 )
ROM_LOAD( "paradar-msg0.5a", 0x00000, 0x10000, CRC(81f7c0cb) SHA1(15ee0c12a8f9c94beac7e5fe894e5f82a53d9fc1) ) // 27512
ROM_REGION( 0x200, "plds", 0 )
@@ -169,14 +495,20 @@ ROM_START( winner ) // dump confirmed from 3 different PCBs
ROM_LOAD( "winner-video1.7b", 0x2000, 0x2000, CRC(caa4ef76) SHA1(2dab5bbe2a4bd60247219a9fc38cae017b81cdbf) )
ROM_LOAD( "winner-video2.8b", 0x4000, 0x2000, CRC(ed520709) SHA1(10707aa2985eea06724c1f32c55c3c6b17e57333) )
- ROM_REGION( 0x10000, "upd", 0 )
+ ROM_REGION( 0x10000, "adpcm", 0 )
ROM_LOAD( "winner-msg0.5a", 0x00000, 0x10000, CRC(81f7c0cb) SHA1(15ee0c12a8f9c94beac7e5fe894e5f82a53d9fc1) ) // 27512
ROM_REGION( 0x200, "plds", 0 )
ROM_LOAD( "palce16v8h-25pc-4.9c", 0x000, 0x117, CRC(ac0347ee) SHA1(26b27d2037400c06e63528e0e59be6d7d1a81cab) )
ROM_END
-GAME( 1995?, jokrlady, 0, videosaa, videosaa, videosaa_state, empty_init, ROT0, "Videos A A", "Joker Lady", MACHINE_IS_SKELETON )
-GAME( 1995?, ladygum, 0, videosaa, videosaa, videosaa_state, empty_init, ROT0, "Videos A A", "Lady Gum", MACHINE_IS_SKELETON )
-GAME( 1995?, paradar, 0, videosaa, videosaa, videosaa_state, empty_init, ROT0, "Videos A A", "Paradar", MACHINE_IS_SKELETON )
-GAME( 1995?, winner, 0, videosaa, videosaa, videosaa_state, empty_init, ROT0, "Videos A A", "Winner", MACHINE_IS_SKELETON )
+
+//**************************************************************************
+// SYSTEM DRIVERS
+//**************************************************************************
+
+// YEAR NAME PARENT MACHINE INPUT CLASS INIT ROTATION COMPANY FULLNAME FLAGS
+GAME( 1995?, jokrlady, 0, videosaa, videosaa, videosaa_state, empty_init, ROT0, "Videos A A", "Joker Lady", MACHINE_SUPPORTS_SAVE | MACHINE_NOT_WORKING )
+GAME( 1995?, ladygum, 0, videosaa, videosaa, videosaa_state, empty_init, ROT0, "Videos A A", "Lady Gum", MACHINE_SUPPORTS_SAVE | MACHINE_WRONG_COLORS )
+GAME( 1995?, paradar, 0, videosaa, videosaa, videosaa_state, empty_init, ROT0, "Videos A A", "Paradar", MACHINE_SUPPORTS_SAVE | MACHINE_NOT_WORKING )
+GAME( 1995?, winner, 0, videosaa, videosaa, videosaa_state, empty_init, ROT0, "Videos A A", "Winner", MACHINE_SUPPORTS_SAVE | MACHINE_NOT_WORKING )
diff --git a/src/mame/layout/videosaa.lay b/src/mame/layout/videosaa.lay
new file mode 100644
index 00000000000..3daf74a10e7
--- /dev/null
+++ b/src/mame/layout/videosaa.lay
@@ -0,0 +1,55 @@
+<?xml version="1.0"?>
+<!--
+license: CC0
+copyright-holders: Dirk Best
+
+Simple layout for games running on Videos A A hardware
+-->
+
+<mamelayout version="2">
+ <element name="background">
+ </element>
+ <element name="button" defstate="0">
+ <rect state="0">
+ <color red="0.2" green="0.2" blue="0.2" />
+ </rect>
+ <rect state="1">
+ <color red="0.8" green="0.8" blue="0.8" />
+ </rect>
+ </element>
+ <element name="start" defstate="0">
+ <rect state="0">
+ <color red="0.2" green="0.2" blue="0.2" />
+ </rect>
+ <rect state="1">
+ <color red="0.8" green="0.8" blue="0.8" />
+ </rect>
+ <text string="START"><color red="0.1" green="0.1" blue="0.1" /></text>
+ </element>
+ <view name="Buttons">
+ <backdrop element="background">
+ <bounds x="0" y="0" width="640" height="640" />
+ </backdrop>
+ <screen index="0">
+ <bounds left="0" top="0" right="640" bottom="480" />
+ </screen>
+ <cpanel name="lamp0" element="button" inputtag="in1" inputmask="0x01">
+ <bounds x="80" y="505" width="70" height="35" />
+ </cpanel>
+ <cpanel name="lamp1" element="button" inputtag="in1" inputmask="0x02">
+ <bounds x="180" y="505" width="70" height="35" />
+ </cpanel>
+ <cpanel name="lamp2" element="button" inputtag="in1" inputmask="0x04">
+ <bounds x="280" y="505" width="70" height="35" />
+ </cpanel>
+ <cpanel name="lamp3" element="button" inputtag="in1" inputmask="0x08">
+ <bounds x="380" y="505" width="70" height="35" />
+ </cpanel>
+ <cpanel name="lamp4" element="button" inputtag="in1" inputmask="0x10">
+ <bounds x="480" y="505" width="70" height="35" />
+ </cpanel>
+ <cpanel name="lamp5" element="start" inputtag="in1" inputmask="0x20">
+ <bounds x="250" y="565" width="130" height="35" />
+ </cpanel>
+ </view>
+</mamelayout>