new machines marked as working

-----------------------------
Super Motor (prototype) [Mirko Buffoni, Roberto Fresca, Retromaniacs, recreativas.org]
This commit is contained in:
Mirko 2020-06-11 15:57:55 +02:00
parent d3a7b0ddc1
commit 0658d35ee8

478
src/mame/drivers/smotor.cpp Normal file
View File

@ -0,0 +1,478 @@
// license:BSD-3-Clause
// copyright-holders: Roberto Fresca, Mirko Buffoni
/********************************************************************
Super Motor (prototype)
19??, Duintronic.
Driver by Roberto Fresca and Mirko Buffoni.
*********************************************************************
Seems to be a prototype, since there are some issues.
You can choose motorcycle <-> car game throug a DIP switch.
Also there are four difficult modes:
- Easy: You only have slow trucks in the game, and gas cans on
the road that extend 10 seconds the game time.
- Normal: You have trucks and cars on the street. Also gas cans.
- Medium: You have trucks and cars on the street, but no gas cans.
Trucks and cars can stop.
- Hard: You have trucks and cars on the street, but no gas cans.
Trucks and cars can stop. Seems a bit harder.
Maybe the easy option was meant for kids cabs.
Duintronic, the manufacturer, is a Spanish company from Barcelona,
created by someone from Ampetronic, and finally adquired by one of
the Tecfri CEOs. The only arcade game known released by them was
Buccanneers, running in IREM Vigilante hardware.
*********************************************************************
Hardware specs...
It's a dedicated PCB that has etched the Duintronic logo.
1x Z80 @ 5MHz. (stickered: S.P.V. -BR BRI NC)
1x YM2413 @ 2.5 MHz.
1x NEC D446C-2, 2K x 8 SRAM. (near CPU)
1x NEC D4016C2 SRAM 32K x 8 SRAM. (VRAM?)
4x 27C512 ROM.
3x N82S129N bipolar PROMs.
1x LM324N low-power quad op amp. (audio amp)
3x GAL16V8-20. (marked 1, 2, 3)
1x 5.000 MHz. crystal.
1x 20.00 MHz. crystal.
2x 8 DIP switches banks.
1x (2x28) JAMMA edge connector.
*********************************************************************/
#include "emu.h"
#include "cpu/z80/z80.h"
#include "video/resnet.h"
#include "sound/ym2413.h"
#include "emupal.h"
#include "screen.h"
#include "speaker.h"
#include "tilemap.h"
#define FIRST_CLOCK XTAL(5'000'000)
#define SECOND_CLOCK XTAL(20'000'000)
#define CPU_CLOCK (FIRST_CLOCK) // verified 5 MHz.
#define SND_CLOCK (SECOND_CLOCK / 8) // verified 2.5 MHz.
class smotor_state : public driver_device
{
public:
smotor_state(const machine_config &mconfig, device_type type, const char *tag) :
driver_device(mconfig, type, tag),
m_maincpu(*this, "maincpu"),
m_ym2413(*this, "ymsnd"),
m_gfxdecode(*this, "gfxdecode"),
m_palette(*this, "palette"),
m_videoreg(*this, "videoreg"),
m_videoram(*this, "videoram")
{ }
void smotor(machine_config &config);
private:
required_device<cpu_device> m_maincpu;
required_device<ym2413_device> m_ym2413;
required_device<gfxdecode_device> m_gfxdecode;
required_device<palette_device> m_palette;
required_shared_ptr<uint8_t> m_videoreg;
required_shared_ptr<uint8_t> m_videoram;
tilemap_t *m_bg_tilemap;
tilemap_t *m_fg_tilemap;
DECLARE_WRITE8_MEMBER(videoram_w);
DECLARE_WRITE8_MEMBER(cpu_io_videoreg_w);
TILE_GET_INFO_MEMBER(get_fg_tile_info);
TILE_GET_INFO_MEMBER(get_bg_tile_info);
virtual void machine_start() override;
virtual void video_start() override;
void smotor_palette(palette_device &palette) const;
uint32_t screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect);
void smotor_cpu_map(address_map &map);
void smotor_cpu_io(address_map &map);
};
/*********************************************
* Video Hardware *
*********************************************/
WRITE8_MEMBER(smotor_state::videoram_w)
{
m_videoram[offset] = data;
m_fg_tilemap->mark_tile_dirty(offset/2);
}
TILE_GET_INFO_MEMBER(smotor_state::get_fg_tile_info)
{
tile_index *= 2;
int attr = m_videoram[tile_index + 1];
int code = m_videoram[tile_index] | ((attr & 0x0f) << 8);
int color = (attr) >> 4;
tileinfo.set(0, code, color, 0);
}
TILE_GET_INFO_MEMBER(smotor_state::get_bg_tile_info)
{
uint8_t *tilerom = memregion("bgmap")->base();
tile_index *= 2;
int data = tilerom[tile_index];
int attr = tilerom[tile_index + 1];
int code = (data | ((attr & 0x07) << 8)) + 0x800;
int color = attr >> 4;
tileinfo.set(0, code, color, 0);
}
void smotor_state::video_start()
{
m_fg_tilemap = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(*this, FUNC(smotor_state::get_fg_tile_info)), TILEMAP_SCAN_ROWS, 8, 8, 32, 32);
m_bg_tilemap = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(*this, FUNC(smotor_state::get_bg_tile_info)), TILEMAP_SCAN_ROWS, 8, 8, 32, 1024);
m_bg_tilemap->set_scroll_rows(32);
m_fg_tilemap->set_transparent_pen(0);
}
uint32_t smotor_state::screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
{
if (BIT(m_videoreg[0],0)) {
m_bg_tilemap->set_scrolly((m_videoreg[3] + (m_videoreg[5] << 8)));
m_bg_tilemap->draw(screen, bitmap, cliprect, 0, 0);
} else {
bitmap.fill(rgb_t::black(), cliprect);
}
m_fg_tilemap->draw(screen, bitmap, cliprect, 0, 0);
return 0;
}
/***************************************************************************
Convert the color PROMs into a more useable format.
There are three 256x4 palette PROMs (one per gun).
The palette PROMs are connected to the RGB output this way:
bit 3 -- 220 ohm resistor -- RED/GREEN/BLUE
-- 680 ohm resistor -- RED/GREEN/BLUE
-- 1.0kohm resistor -- RED/GREEN/BLUE
bit 0 -- 2.2kohm resistor -- RED/GREEN/BLUE
***************************************************************************/
void smotor_state::smotor_palette(palette_device &palette) const
{
uint8_t const *const color_prom = memregion("proms")->base();
static constexpr int resistances[4] = { 2200, 1000, 680, 220 };
// compute the color output resistor weights
double rweights[4], gweights[4], bweights[4];
compute_resistor_weights(0, 255, -1.0,
4, &resistances[0], rweights, 330, 0,
4, &resistances[0], gweights, 330, 0,
4, &resistances[0], bweights, 330, 0);
// initialize the palette with these colors
for (int i = 0; i < palette.entries(); i++)
{
int bit0, bit1, bit2, bit3;
// red component
bit0 = BIT(color_prom[i], 0);
bit1 = BIT(color_prom[i], 1);
bit2 = BIT(color_prom[i], 2);
bit3 = BIT(color_prom[i], 3);
int const r = combine_weights(rweights, bit0, bit1, bit2, bit3);
// green component
bit0 = BIT(color_prom[i+0x100], 0);
bit1 = BIT(color_prom[i+0x100], 1);
bit2 = BIT(color_prom[i+0x100], 2);
bit3 = BIT(color_prom[i+0x100], 3);
int const g = combine_weights(gweights, bit0, bit1, bit2, bit3);
// blue component
bit0 = BIT(color_prom[i+0x200], 0);
bit1 = BIT(color_prom[i+0x200], 1);
bit2 = BIT(color_prom[i+0x200], 2);
bit3 = BIT(color_prom[i+0x200], 3);
int const b = combine_weights(bweights, bit0, bit1, bit2, bit3);
palette.set_pen_color(i, rgb_t(r, g, b));
}
}
/*********************************************
* Memory Map Information *
*********************************************/
void smotor_state::smotor_cpu_map(address_map &map)
{
map(0x0000, 0xbfff).rom();
map(0xf000, 0xf7ff).ram().w(FUNC(smotor_state::videoram_w)).share("videoram");
map(0xf800, 0xffff).ram();
}
void smotor_state::smotor_cpu_io(address_map &map)
{
map.global_mask(0xff);
map(0x00, 0x00).portr("IN0");
map(0x01, 0x01).portr("DSW1");
map(0x00, 0x01).w("ymsnd", FUNC(ym2413_device::write));
map(0x02, 0x02).portr("DSW2");
map(0x02, 0x07).w(FUNC(smotor_state::cpu_io_videoreg_w)).share("videoreg");
/*
00: RW ; port_r / ym2413_w #1
01: RW ; dsw1_r / ym2413_w #2
02: RW ; dsw2_r / bg_enable_w, coin counters (values written: 0x30 [boot], 0x20 [attract], 0x11 [ingame])
04: W ; / ??? (values written: 0x00)
05: W ; / LSB Scrolly
06: W ; / BG offset reset (values written: 0xff)
07: W ; / MSB Scrolly
*/
}
WRITE8_MEMBER(smotor_state::cpu_io_videoreg_w)
{
switch (offset) {
case 0x00:
m_videoreg[offset] = data;
m_ym2413->set_output_gain(ALL_OUTPUTS, BIT(data, 4) ? 1.0f : 0.0f);
if ((BIT(data, 0)) & (BIT(data, 2))) // coin lock + coin a, used for init.
break;
machine().bookkeeping().coin_lockout_global_w(BIT(data, 0)); // coin lock.
machine().bookkeeping().coin_counter_w(1, BIT(data, 1)); // coin b counter.
machine().bookkeeping().coin_counter_w(0, BIT(data, 2)); // coin a counter.
break;
case 0x02:
case 0x03:
m_videoreg[3] = data;
break;
case 0x04:
case 0x05:
m_videoreg[5] = data;
break;
default:
logerror("OUT[%02x] = %02X\n", offset + 2, data);
}
}
/*********************************************
* Input Ports *
*********************************************/
static INPUT_PORTS_START( smotor )
PORT_START("IN0")
PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_COIN1 )
PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_COIN2 )
PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_START1 )
PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_START2 )
PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_JOYSTICK_LEFT ) PORT_2WAY
PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_JOYSTICK_RIGHT ) PORT_2WAY
PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_BUTTON1 )
PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_BUTTON2 )
PORT_START("DSW1")
PORT_DIPNAME( 0x0f, 0x0f, DEF_STR( Coin_A ) ) PORT_DIPLOCATION("SW1:1,2,3,4")
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( 0x0a, DEF_STR( 2C_1C ) )
PORT_DIPSETTING( 0x09, DEF_STR( 2C_3C ) )
PORT_DIPSETTING( 0x08, DEF_STR( 2C_5C ) )
PORT_DIPSETTING( 0x07, DEF_STR( 3C_1C ) )
PORT_DIPSETTING( 0x06, DEF_STR( 3C_2C ) )
PORT_DIPSETTING( 0x05, DEF_STR( 3C_5C ) )
PORT_DIPSETTING( 0x04, DEF_STR( 4C_1C ) )
PORT_DIPSETTING( 0x03, DEF_STR( 4C_3C ) )
PORT_DIPSETTING( 0x02, DEF_STR( 4C_5C ) )
PORT_DIPSETTING( 0x01, DEF_STR( 5C_1C ) )
PORT_DIPSETTING( 0x00, DEF_STR( 5C_2C ) )
PORT_DIPNAME( 0xf0, 0xf0, DEF_STR( Coin_B ) ) PORT_DIPLOCATION("SW1:5,6,7,8")
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( 0xa0, DEF_STR( 2C_1C ) )
PORT_DIPSETTING( 0x90, DEF_STR( 2C_3C ) )
PORT_DIPSETTING( 0x80, DEF_STR( 2C_5C ) )
PORT_DIPSETTING( 0x70, DEF_STR( 3C_1C ) )
PORT_DIPSETTING( 0x60, DEF_STR( 3C_2C ) )
PORT_DIPSETTING( 0x50, DEF_STR( 3C_5C ) )
PORT_DIPSETTING( 0x40, DEF_STR( 4C_1C ) )
PORT_DIPSETTING( 0x30, DEF_STR( 4C_3C ) )
PORT_DIPSETTING( 0x20, DEF_STR( 4C_5C ) )
PORT_DIPSETTING( 0x10, DEF_STR( 5C_1C ) )
PORT_DIPSETTING( 0x00, DEF_STR( 5C_2C ) )
PORT_START("DSW2")
PORT_DIPNAME( 0x01, 0x00, DEF_STR( Demo_Sounds ) ) PORT_DIPLOCATION("SW2:1")
PORT_DIPSETTING( 0x01, DEF_STR( Off ) )
PORT_DIPSETTING( 0x00, DEF_STR( On ) )
PORT_DIPNAME( 0x06, 0x04, DEF_STR( Difficult ) ) PORT_DIPLOCATION("SW2:2,3")
PORT_DIPSETTING( 0x06, "Easy (with gas cans, only trucks)" )
PORT_DIPSETTING( 0x04, "Normal (with gas cans, trucks and cars)" )
PORT_DIPSETTING( 0x02, "Medium (no gas cans, both trucks and cars)" )
PORT_DIPSETTING( 0x00, "Hard (no gas cans, both trucks and cars)" )
PORT_DIPNAME( 0x18, 0x18, DEF_STR( Game_Time ) ) PORT_DIPLOCATION("SW2:4,5")
PORT_DIPSETTING( 0x18, "1:00" )
PORT_DIPSETTING( 0x10, "1:20" )
PORT_DIPSETTING( 0x08, "1:40" )
PORT_DIPSETTING( 0x00, "2:00" )
PORT_DIPNAME( 0x20, 0x20, "Cycle / Car" ) PORT_DIPLOCATION("SW2:6")
PORT_DIPSETTING( 0x20, "Cycle" )
PORT_DIPSETTING( 0x00, "Car" )
PORT_DIPNAME( 0x40, 0x40, DEF_STR( Unused ) ) PORT_DIPLOCATION("SW2:7")
PORT_DIPSETTING( 0x40, DEF_STR( Off ) )
PORT_DIPSETTING( 0x00, DEF_STR( On ) )
PORT_DIPNAME( 0x80, 0x80, DEF_STR( Unused ) ) PORT_DIPLOCATION("SW2:8")
PORT_DIPSETTING( 0x80, DEF_STR( Off ) )
PORT_DIPSETTING( 0x00, DEF_STR( On ) )
INPUT_PORTS_END
/*********************************************
* Graphics Layouts *
*********************************************/
static const gfx_layout tiles8x8_layout =
{
8, 8,
0x1000,
4,
{ 0, 2, 4, 6 },
{ 1, 0, 9, 8, 17, 16, 25, 24 },
{ 0*32, 1*32, 2*32, 3*32, 4*32, 5*32, 6*32, 7*32 },
32 * 8
};
/**************************************************
* Graphics Decode Information *
**************************************************/
static GFXDECODE_START( gfx_smotor )
GFXDECODE_ENTRY( "gfx1", 0, tiles8x8_layout, 0, 16 )
GFXDECODE_END
/*********************************************
* Machine Start & Reset *
*********************************************/
void smotor_state::machine_start()
{
}
/*********************************************
* Machine Config *
*********************************************/
void smotor_state::smotor(machine_config &config)
{
// basic machine hardware
Z80(config, m_maincpu, CPU_CLOCK);
m_maincpu->set_addrmap(AS_PROGRAM, &smotor_state::smotor_cpu_map);
m_maincpu->set_addrmap(AS_IO, &smotor_state::smotor_cpu_io);
m_maincpu->set_vblank_int("screen", FUNC(smotor_state::irq0_line_hold));
// 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(256, 256);
screen.set_visarea(0*8, 32*8-1, 0*8, 32*8-1);
screen.set_screen_update(FUNC(smotor_state::screen_update));
screen.set_palette(m_palette);
GFXDECODE(config, m_gfxdecode, m_palette, gfx_smotor);
PALETTE(config, m_palette, FUNC(smotor_state::smotor_palette), 256); // 256 static colors
// sound hardware
SPEAKER(config, "speaker").front_center();
YM2413(config, "ymsnd", SND_CLOCK).add_route(ALL_OUTPUTS, "speaker", 2.0);
}
/*********************************************
* ROM Load *
*********************************************/
ROM_START( smotor )
ROM_REGION( 0x10000, "maincpu", 0 )
ROM_LOAD( "2_27c512.d4", 0x00000, 0x10000, CRC(82ca877d) SHA1(fc11c793c25865ebd3d5199c61ce14c535e0d2a8) )
ROM_REGION( 0x20000, "gfx1", 0 )
ROM_LOAD( "1_27c512.a2", 0x00000, 0x10000, CRC(f12cb8bb) SHA1(0aaa7040b3bdba01e823212550cc0f990eee02e8) )
ROM_LOAD( "4_27c512.i1", 0x10000, 0x10000, CRC(4c82a10b) SHA1(215354f37f6c13378aca85c96c209610f774711a) )
ROM_REGION( 0x10000, "bgmap", 0 )
ROM_LOAD( "3_27c512.g3", 0x00000, 0x10000, CRC(0f67d74b) SHA1(90bb8884f95c883fa3d95e97fba2c0420668dab3) )
ROM_REGION( 0x300, "proms", 0 )
ROM_LOAD( "82s129.l4", 0x000, 0x100, CRC(cd06515a) SHA1(589961f0438b889d20223d8139992dc8bf35b935) ) // R
ROM_LOAD( "82s129.j4", 0x100, 0x100, CRC(26472e34) SHA1(c08f61911135cf1fe847a109f25de7f32646f5ec) ) // G
ROM_LOAD( "82s129.k4", 0x200, 0x100, CRC(b4cffc3b) SHA1(1536ea938f1dc8e506ad98ae6810279e83fe9192) ) // B
ROM_REGION( 0x0600, "plds", 0 )
ROM_LOAD( "1_gal16v8.a3", 0x0000, 0x0117, NO_DUMP ) // device is dead
ROM_LOAD( "2_gal16v8.k3", 0x0000, 0x0117, NO_DUMP ) // device is dead
ROM_LOAD( "3_gal16v8.l2", 0x0000, 0x0117, NO_DUMP ) // device is dead
ROM_END
/*********************************************
* Game Drivers *
*********************************************/
// YEAR NAME PARENT MACHINE INPUT CLASS INIT ROT COMPANY FULLNAME FLAGS
GAME( 19??, smotor, 0, smotor, smotor, smotor_state, empty_init, ROT0, "Duintronic", "Super Motor (prototype)", 0 )