New working machines

--------------------
Speed Race (Seletron / Olympia) [hap, f205v]
This commit is contained in:
hap 2020-04-06 00:52:13 +02:00
parent d519ecbeb7
commit 32586d3623
3 changed files with 232 additions and 109 deletions

View File

@ -2,24 +2,32 @@
// copyright-holders:hap
/***************************************************************************
Olympia / Seletron, Long Beach
Seletron / Olympia Long Beach
Olympia probably took care of distribution, PCB and game by Seletron
PCB was broken, and there are no known references.
16MHz XTAL, M6800 @ 500kHz
2x 5101 sram 256x4bit (256 byte) battery backed
4x 4045 sram 1kx4 (2K byte)
PCB was broken, and there are no known references.
16MHz XTAL, M6800 @ 500kHz
2x 5101 sram 256x4bit (256 byte) battery backed
4x 4045 sram 1kx4 (2K byte)
Game should be in b&w? But then highlighted blocks in testmode
would be invisible.
6800 hits many illegal opcodes (0x02), though it's harmless.
Maybe they meant to inserts nops (0x01) to remove debug stuff
or to make room for future additions?
6800 hits many illegal opcodes (0x02), though it's harmless.
Maybe they meant to inserts nops (0x01) to remove debug stuff
or to make room for future additions?
Speed Race is on the same hardware, no mention of Olympia, but it is
listed online on Olympia game lists. It is a reimagination of Taito's
Speed Race, not a bootleg.
TODO:
- discrete sound
- improve colors
- unknown writes
- unknown writes (most of it is sound)
- improve colors, lbeach is monochrome but what about speedrs?
- some unknown romlabels (see "x")
- lbeach 93448.h4 rom is a bad dump? it misses animation frames compared to
speedrs, but when compared to enemy cars, it looks ok
- speedrs has nvram? high scores are not saved
- sprite x position is wrong, but moving it to the left will break speedrs
(it does a sprite collision check at boot)
***************************************************************************/
@ -31,8 +39,11 @@ TODO:
#include "tilemap.h"
#include "lbeach.lh"
#include "speedrs.lh"
namespace {
class lbeach_state : public driver_device
{
public:
@ -44,61 +55,63 @@ public:
m_scroll_y(*this, "scroll_y"),
m_sprite_x(*this, "sprite_x"),
m_sprite_code(*this, "sprite_code"),
m_collision_bg_car(0),
m_collision_fg_car(0),
m_gfxdecode(*this, "gfxdecode"),
m_screen(*this, "screen"),
m_palette(*this, "palette")
m_palette(*this, "palette"),
m_inputs(*this, "IN.%u", 0)
{ }
void lbeach(machine_config &config);
protected:
virtual void machine_start() override;
virtual void machine_reset() override;
virtual void video_start() override;
private:
/* devices / memory pointers */
required_device<cpu_device> m_maincpu;
required_shared_ptr<uint8_t> m_bg_vram;
required_shared_ptr<uint8_t> m_fg_vram;
required_shared_ptr<uint8_t> m_scroll_y;
required_shared_ptr<uint8_t> m_sprite_x;
required_shared_ptr<uint8_t> m_sprite_code;
int m_collision_bg_car;
int m_collision_fg_car;
required_shared_ptr<u8> m_bg_vram;
required_shared_ptr<u8> m_fg_vram;
required_shared_ptr<u8> m_scroll_y;
required_shared_ptr<u8> m_sprite_x;
required_shared_ptr<u8> m_sprite_code;
required_device<gfxdecode_device> m_gfxdecode;
required_device<screen_device> m_screen;
required_device<palette_device> m_palette;
required_ioport_array<3> m_inputs;
int m_collision_bg_car = 0;
int m_collision_fg_car = 0;
bitmap_ind16 m_colmap_car;
tilemap_t* m_bg_tilemap;
tilemap_t* m_fg_tilemap;
tilemap_t *m_bg_tilemap;
tilemap_t *m_fg_tilemap;
TILE_GET_INFO_MEMBER(get_bg_tile_info);
TILE_GET_INFO_MEMBER(get_fg_tile_info);
DECLARE_WRITE8_MEMBER(lbeach_bg_vram_w);
DECLARE_WRITE8_MEMBER(lbeach_fg_vram_w);
DECLARE_READ8_MEMBER(lbeach_in1_r);
DECLARE_READ8_MEMBER(lbeach_in2_r);
DECLARE_WRITE8_MEMBER(bg_vram_w);
DECLARE_WRITE8_MEMBER(fg_vram_w);
DECLARE_READ8_MEMBER(in1_r);
DECLARE_READ8_MEMBER(in2_r);
void lbeach_palette(palette_device &palette) const;
uint32_t screen_update_lbeach(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect);
void lbeach_map(address_map &map);
void init_palette(palette_device &palette) const;
u32 screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect);
void main_map(address_map &map);
};
void lbeach_state::machine_start()
{
save_item(NAME(m_collision_bg_car));
save_item(NAME(m_collision_fg_car));
}
/***************************************************************************
Video
/******************************************************************************
Video
******************************************************************************/
***************************************************************************/
void lbeach_state::lbeach_palette(palette_device &palette) const
void lbeach_state::init_palette(palette_device &palette) const
{
// tiles
palette.set_pen_color(0, 0x00, 0x00, 0x00);
@ -128,15 +141,13 @@ TILE_GET_INFO_MEMBER(lbeach_state::get_bg_tile_info)
// d0-d4: code
// d5: unused?
// d6,d7: color
uint8_t code = m_bg_vram[tile_index];
u8 code = m_bg_vram[tile_index];
tileinfo.set(1, code & 0x1f, code >> 6 & 3, 0);
}
TILE_GET_INFO_MEMBER(lbeach_state::get_fg_tile_info)
{
uint8_t code = m_fg_vram[tile_index];
u8 code = m_fg_vram[tile_index];
tileinfo.set(0, code, 0, 0);
}
@ -151,7 +162,7 @@ void lbeach_state::video_start()
}
uint32_t lbeach_state::screen_update_lbeach(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
u32 lbeach_state::screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
{
// draw bg layer (road)
m_bg_tilemap->set_scrolly(0, *m_scroll_y);
@ -159,7 +170,7 @@ uint32_t lbeach_state::screen_update_lbeach(screen_device &screen, bitmap_ind16
// check collision
int sprite_code = *m_sprite_code & 0xf;
int sprite_x = *m_sprite_x * 2 - 4;
int sprite_x = *m_sprite_x * 2 + 2;
int sprite_y = 160;
m_colmap_car.fill(0, cliprect);
@ -183,54 +194,59 @@ uint32_t lbeach_state::screen_update_lbeach(screen_device &screen, bitmap_ind16
// draw player car
m_gfxdecode->gfx(2)->transpen(bitmap,cliprect, sprite_code, 0, 0, 0, sprite_x, sprite_y, 0);
m_gfxdecode->gfx(2)->transpen(bitmap,cliprect, sprite_code | 0x10, 0, 0, 0, sprite_x, sprite_y + 16, 0);
return 0;
}
WRITE8_MEMBER(lbeach_state::lbeach_bg_vram_w)
/******************************************************************************
I/O
******************************************************************************/
WRITE8_MEMBER(lbeach_state::bg_vram_w)
{
m_bg_vram[offset] = data;
m_bg_tilemap->mark_tile_dirty(offset);
}
WRITE8_MEMBER(lbeach_state::lbeach_fg_vram_w)
WRITE8_MEMBER(lbeach_state::fg_vram_w)
{
m_fg_vram[offset] = data;
m_fg_tilemap->mark_tile_dirty(offset);
}
/***************************************************************************
Memory Map, I/O
***************************************************************************/
READ8_MEMBER(lbeach_state::lbeach_in1_r)
READ8_MEMBER(lbeach_state::in1_r)
{
// d6,7(steering wheel) need to be swapped
return bitswap<8>(ioport("IN1")->read(),6,7,5,4,3,2,1,0);
// d7: steering wheel active
// d6: steering wheel direction
return bitswap<8>(m_inputs[1]->read(),6,7,5,4,3,2,1,0);
}
READ8_MEMBER(lbeach_state::lbeach_in2_r)
READ8_MEMBER(lbeach_state::in2_r)
{
// d6 and d7 are for collision detection
uint8_t d6 = m_collision_fg_car ? 0x40 : 0;
uint8_t d7 = m_collision_bg_car ? 0x80 : 0;
u8 d6 = m_collision_bg_car ? 0x80 : 0;
u8 d7 = m_collision_fg_car ? 0x40 : 0;
return (ioport("IN2")->read() & 0x3f) | d6 | d7;
return (m_inputs[2]->read() & 0x3f) | d6 | d7;
}
void lbeach_state::lbeach_map(address_map &map)
/******************************************************************************
Address Maps
******************************************************************************/
void lbeach_state::main_map(address_map &map)
{
map(0x0000, 0x00ff).ram().share("nvram");
map(0x4000, 0x41ff).ram().w(FUNC(lbeach_state::lbeach_bg_vram_w)).share("bg_vram");
map(0x4000, 0x4000).r(FUNC(lbeach_state::lbeach_in1_r));
map(0x4000, 0x41ff).ram().w(FUNC(lbeach_state::bg_vram_w)).share("bg_vram");
map(0x4000, 0x4000).r(FUNC(lbeach_state::in1_r));
map(0x4200, 0x43ff).ram();
map(0x4400, 0x47ff).ram().w(FUNC(lbeach_state::lbeach_fg_vram_w)).share("fg_vram");
map(0x8000, 0x8000).r(FUNC(lbeach_state::lbeach_in2_r));
map(0x4400, 0x47ff).ram().w(FUNC(lbeach_state::fg_vram_w)).share("fg_vram");
map(0x8000, 0x8000).r(FUNC(lbeach_state::in2_r));
map(0x8000, 0x8000).writeonly().share("scroll_y");
map(0x8001, 0x8001).writeonly().share("sprite_x");
map(0x8002, 0x8002).writeonly().share("sprite_code");
@ -238,7 +254,7 @@ void lbeach_state::lbeach_map(address_map &map)
// map(0x8004, 0x8004).nopw(); // ?
// map(0x8005, 0x8005).nopw(); // ?
map(0x8007, 0x8007).nopw(); // probably watchdog
map(0xa000, 0xa000).portr("IN0");
map(0xa000, 0xa000).portr("IN.0");
// map(0xa003, 0xa003).nopr(); // ? tests d7 at game over
map(0xc000, 0xcfff).rom();
map(0xf000, 0xffff).rom();
@ -246,14 +262,12 @@ void lbeach_state::lbeach_map(address_map &map)
/***************************************************************************
Inputs
***************************************************************************/
/******************************************************************************
Input Ports
******************************************************************************/
static INPUT_PORTS_START( lbeach )
PORT_START("IN0")
PORT_START("IN.0")
PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_BUTTON1 ) PORT_NAME("Gas Pedal")
PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_BUTTON2 ) PORT_NAME("Shifter 1st Gear")
PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_BUTTON3 ) PORT_NAME("Shifter 2nd Gear")
@ -263,12 +277,12 @@ static INPUT_PORTS_START( lbeach )
PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_SERVICE2 ) PORT_NAME("Coin Counter") // called CC in testmode
PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_COIN1 )
PORT_START("IN1")
PORT_BIT( 0x1f, IP_ACTIVE_LOW, IPT_UNUSED )
PORT_START("IN.1")
PORT_BIT( 0x1f, IP_ACTIVE_HIGH, IPT_UNUSED )
PORT_SERVICE_NO_TOGGLE( 0x20, IP_ACTIVE_LOW )
PORT_BIT(0xc0, 0x40, IPT_PADDLE ) PORT_INVERT PORT_MINMAX(0x00,0x80) PORT_SENSITIVITY(50) PORT_KEYDELTA(1) PORT_CENTERDELTA(1)
PORT_START("IN2")
PORT_START("IN.2")
PORT_DIPNAME( 0x03, 0x00, DEF_STR( Coinage ) )
PORT_DIPSETTING( 0x03, DEF_STR( 2C_1C ) )
PORT_DIPSETTING( 0x02, DEF_STR( 2C_1C ) ) // dupe
@ -287,15 +301,28 @@ static INPUT_PORTS_START( lbeach )
PORT_BIT( 0xc0, IP_ACTIVE_HIGH, IPT_CUSTOM )
INPUT_PORTS_END
static INPUT_PORTS_START( speedrs )
PORT_INCLUDE( lbeach )
PORT_MODIFY("IN.0")
PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_BUTTON2 ) PORT_NAME("Shifter") PORT_TOGGLE
PORT_BIT( 0x7c, IP_ACTIVE_HIGH, IPT_UNUSED )
PORT_MODIFY("IN.2")
PORT_DIPNAME( 0x0c, 0x00, "Refueling Point" )
PORT_DIPSETTING( 0x00, "1500" )
PORT_DIPSETTING( 0x04, "2000" )
PORT_DIPSETTING( 0x08, "2500" )
PORT_DIPSETTING( 0x0c, "3000" )
INPUT_PORTS_END
/***************************************************************************
Machine Config
/******************************************************************************
GFX Decodes
******************************************************************************/
***************************************************************************/
static const gfx_layout tile_layout_16x8 =
static const gfx_layout layout_16x8 =
{
16,8,
RGN_FRAC(1,1),
@ -306,7 +333,7 @@ static const gfx_layout tile_layout_16x8 =
16*8
};
static const gfx_layout tile_layout_16x16 =
static const gfx_layout layout_16x16 =
{
16,16,
RGN_FRAC(1,1),
@ -318,53 +345,47 @@ static const gfx_layout tile_layout_16x16 =
};
static GFXDECODE_START( gfx_lbeach )
GFXDECODE_ENTRY( "gfx1", 0, tile_layout_16x8, 0, 1 )
GFXDECODE_ENTRY( "gfx2", 0, tile_layout_16x16, 2, 4 )
GFXDECODE_ENTRY( "gfx3", 0, tile_layout_16x16, 10, 1 )
GFXDECODE_ENTRY( "gfx1", 0, layout_16x8, 0, 1 )
GFXDECODE_ENTRY( "gfx2", 0, layout_16x16, 2, 4 )
GFXDECODE_ENTRY( "gfx3", 0, layout_16x16, 10, 1 )
GFXDECODE_END
void lbeach_state::machine_start()
{
save_item(NAME(m_collision_bg_car));
save_item(NAME(m_collision_fg_car));
}
void lbeach_state::machine_reset()
{
}
/******************************************************************************
Machine Configs
******************************************************************************/
void lbeach_state::lbeach(machine_config &config)
{
/* basic machine hardware */
M6800(config, m_maincpu, XTAL(16'000'000) / 32); // Motorola MC6800P, 500kHz
m_maincpu->set_addrmap(AS_PROGRAM, &lbeach_state::lbeach_map);
M6800(config, m_maincpu, 16_MHz_XTAL / 32); // Motorola MC6800P, 500kHz
m_maincpu->set_addrmap(AS_PROGRAM, &lbeach_state::main_map);
NVRAM(config, "nvram", nvram_device::DEFAULT_ALL_0);
/* video hardware */
SCREEN(config, m_screen, SCREEN_TYPE_RASTER);
m_screen->set_refresh_hz(60); // ~60Hz
m_screen->set_refresh_hz(60); // measured ~60Hz
m_screen->set_size(512, 256);
m_screen->set_visarea(0, 511-32, 0, 255-24);
m_screen->set_screen_update(FUNC(lbeach_state::screen_update_lbeach));
m_screen->set_screen_update(FUNC(lbeach_state::screen_update));
m_screen->set_video_attributes(VIDEO_ALWAYS_UPDATE); // needed for collision detection
m_screen->set_palette(m_palette);
m_screen->screen_vblank().set_inputline(m_maincpu, INPUT_LINE_NMI);
GFXDECODE(config, m_gfxdecode, m_palette, gfx_lbeach);
PALETTE(config, m_palette, FUNC(lbeach_state::lbeach_palette), 2 + 8 + 2);
PALETTE(config, m_palette, FUNC(lbeach_state::init_palette), 2 + 8 + 2);
/* sound hardware */
// ...
}
/***************************************************************************
Game Drivers
***************************************************************************/
/******************************************************************************
ROM Definitions
******************************************************************************/
ROM_START( lbeach )
ROM_REGION( 0x10000, "maincpu", 0 )
@ -377,12 +398,41 @@ ROM_START( lbeach )
ROM_LOAD( "15.e2", 0x0000, 0x0800, CRC(9f24897c) SHA1(5ae05b06dadf4e935e39ac289f2db7719ff3b230) )
ROM_LOAD( "s2.d2", 0x0800, 0x0800, CRC(c5d59466) SHA1(663df8397081daa89f9e3f7aec7e07557cf5b310) )
ROM_REGION( 0x0400, "gfx2", 0 )
ROM_REGION( 0x0400, "gfx2", 0 ) // road
ROM_LOAD( "r.d1", 0x0000, 0x0400, CRC(07e99395) SHA1(67a68dee8e97ae74ab13af62cdc5279c358dc897) )
ROM_REGION( 0x0200, "gfx3", 0 )
ROM_LOAD( "93448.h4", 0x0000, 0x0200, BAD_DUMP CRC(0dca040d) SHA1(d775cbf9fbb9449881ce4997187a1945d34d3cb6) ) // bad dump: stuck a5
ROM_REGION( 0x0400, "gfx3", ROMREGION_ERASE00 )
ROM_LOAD( "93448.h4", 0x0000, 0x0200, BAD_DUMP CRC(0dca040d) SHA1(d775cbf9fbb9449881ce4997187a1945d34d3cb6) ) // stuck a5
ROM_END
ROM_START( speedrs )
ROM_REGION( 0x10000, "maincpu", ROMREGION_ERASE00 )
ROM_LOAD( "40.y3", 0xc000, 0x0400, CRC(237a8593) SHA1(7f56d32a3f9ddead1eb0170807bbc0221e2d6b9a) )
ROM_LOAD( "x.y4", 0xc400, 0x0400, CRC(4e489c42) SHA1(3efeac5a194f524c5b4ae61517781e63ab7fbb5a) )
ROM_LOAD( "44.x6", 0xf000, 0x0400, CRC(37d4fd97) SHA1(f7555264db1a4a1caa429aa75239b997c4635fcd) )
ROM_LOAD( "45a.x7", 0xf400, 0x0400, CRC(e8e3854a) SHA1(79309633a3f3d19f2d2eaf92f745512d7e007ca1) )
ROM_LOAD( "46.y1", 0xf800, 0x0400, CRC(c770488e) SHA1(8eee3fe43b0ca2ed741a53c4982c1aa59bed6f9a) )
ROM_LOAD( "47a.y2", 0xfc00, 0x0400, CRC(5c5e9da9) SHA1(332e5e180b48acbee59ebf2603894e5cbecc0f3e) )
GAMEL( 1979, lbeach, 0, lbeach, lbeach, lbeach_state, empty_init, ROT0, "Olympia / Seletron", "Long Beach", MACHINE_IMPERFECT_COLORS | MACHINE_NO_SOUND | MACHINE_SUPPORTS_SAVE, layout_lbeach )
ROM_REGION( 0x1000, "gfx1", ROMREGION_ERASE00 )
ROM_LOAD( "48.x2", 0x0000, 0x0400, CRC(8516b7c6) SHA1(e75e193b746ef9cf6524efb0c642573005cf56c5) )
ROM_LOAD( "49.x3", 0x0400, 0x0400, CRC(dc39e711) SHA1(547e2d9c19bd2d91d27b395ba1f3a8e103c42da9) )
ROM_REGION( 0x0400, "gfx2", 0 )
ROM_LOAD( "x.x1", 0x0000, 0x0400, CRC(20007b6f) SHA1(036005e30a1c369fabd403d5d85a96bb7183ecdb) )
ROM_REGION( 0x0400, "gfx3", 0 )
ROM_LOAD( "x.h4", 0x0000, 0x0400, CRC(b0f2c70c) SHA1(638ccb0f50731d26bb546d9573296e4193e9ca11) )
ROM_END
} // anonymous namespace
/******************************************************************************
Drivers
******************************************************************************/
// YEAR NAME PARENT MACHINE INPUT STATE INIT COMPANY, FULLNAME, FLAGS
GAMEL( 1979, lbeach, 0, lbeach, lbeach, lbeach_state, empty_init, ROT0, "Seletron / Olympia", "Long Beach", MACHINE_IMPERFECT_COLORS | MACHINE_NO_SOUND | MACHINE_SUPPORTS_SAVE, layout_lbeach )
GAMEL( 1980, speedrs, 0, lbeach, speedrs, lbeach_state, empty_init, ROT0, "Seletron / Olympia", "Speed Race (Seletron / Olympia)", MACHINE_IMPERFECT_COLORS | MACHINE_NO_SOUND | MACHINE_SUPPORTS_SAVE, layout_speedrs )

View File

@ -0,0 +1,72 @@
<?xml version="1.0"?>
<!--
license:CC0
-->
<mamelayout version="2">
<element name="shifter" defstate="0">
<rect>
<bounds left="0" right="32" top="0" bottom="64" />
<color red="0.85" green="0.4" blue="0.3" />
</rect>
<rect>
<bounds left="2" right="30" top="2" bottom="62" />
<color red="0.14" green="0.17" blue="0.2" />
</rect>
<rect>
<bounds left="14" right="18" top="15" bottom="49" />
<color red="0.44" green="0.47" blue="0.5" />
</rect>
<disk>
<bounds left="14" right="18" top="13" bottom="17" />
<color red="0.44" green="0.47" blue="0.5" />
</disk>
<disk>
<bounds left="14" right="18" top="47" bottom="51" />
<color red="0.44" green="0.47" blue="0.5" />
</disk>
<text string="LOW" state="0">
<bounds left="3" right="29" top="2" bottom="12" />
<color red="1.0" green="1.0" blue="0.4" />
</text>
<text string="LOW" state="1">
<bounds left="3" right="29" top="2" bottom="12" />
<color red="1.0" green="1.0" blue="1.0" />
</text>
<text string="HIGH" state="0">
<bounds left="3" right="29" top="52" bottom="62" />
<color red="1.0" green="1.0" blue="1.0" />
</text>
<text string="HIGH" state="1">
<bounds left="3" right="29" top="52" bottom="62" />
<color red="1.0" green="1.0" blue="0.4" />
</text>
<disk state="0">
<bounds left="9" right="23" top="14" bottom="28" />
<color red="0.85" green="0.4" blue="0.3" />
</disk>
<disk state="1">
<bounds left="9" right="23" top="36" bottom="50" />
<color red="0.85" green="0.4" blue="0.3" />
</disk>
</element>
<view name="Shifter-R">
<screen index="0">
<bounds x="0" y="0" width="640" height="480" />
</screen>
<bezel element="shifter" inputtag="IN.0" inputmask="0x02">
<bounds x="606" y="414" width="32" height="64" />
<color alpha="0.6" />
</bezel>
</view>
<view name="Shifter-L">
<screen index="0">
<bounds x="0" y="0" width="640" height="480" />
</screen>
<bezel element="shifter" inputtag="IN.0" inputmask="0x02">
<bounds x="2" y="414" width="32" height="64" />
<color alpha="0.6" />
</bezel>
</view>
</mamelayout>

View File

@ -19020,7 +19020,8 @@ medlanes // [1977?]
lb186 // Ampro Little Board/186
@source:lbeach.cpp
lbeach // (c) 1979 Olympia / Seletron
lbeach
speedrs
@source:lbpc.cpp
lbpc // Ampro Little Board/PC