mirror of
https://github.com/holub/mame
synced 2025-04-25 17:56:43 +03:00
twins.cpp: major cleanups, add default NVRAM for all games, worked around crash after stages 1-5 in twins/twinsed2 [Angelo Salese]
This commit is contained in:
parent
087dd67ecd
commit
9ce190865b
@ -1,5 +1,5 @@
|
||||
// license:BSD-3-Clause
|
||||
// copyright-holders:David Haywood
|
||||
// copyright-holders:David Haywood, Angelo Salese
|
||||
/*
|
||||
|
||||
Twins
|
||||
@ -69,10 +69,12 @@ AY3-8910 instead of YM2149 (compatible)
|
||||
video is not banked in this case instead palette data is sent to the ports
|
||||
strange palette format.
|
||||
|
||||
todo:
|
||||
hook up eeprom (doesn't seem to work when hooked up??)
|
||||
Twins set 1 takes a long time to boot (eeprom?)
|
||||
Improve blitter / clear logic for Spider.
|
||||
TODO:
|
||||
- Proper fix for twins & twinsed2 crash after round 1 (MT #07516):
|
||||
after clearing 1-5 it pings i2c for a couple times, expect it to be 0 then 1 otherwise
|
||||
jumps to lalaland;
|
||||
- Improve blitter / clear logic for Spider.
|
||||
- Merge with hotblock.cpp;
|
||||
|
||||
Electronic Devices was printed on rom labels
|
||||
1994 date string is in ROM
|
||||
@ -80,18 +82,20 @@ Electronic Devices was printed on rom labels
|
||||
Spider PCB appears almost identical but uses additional 'blitter' features.
|
||||
It is possible the Twins PCB has them too and doesn't use them.
|
||||
|
||||
twinsed1 is significantly changed hardware, uses a regular RAMDAC hookup for palette etc.
|
||||
|
||||
Twins (Electronic Devices license, set 2) is significantly changed hardware, uses a regular RAMDAC hookup for plaette etc.
|
||||
|
||||
|
||||
To access Service Mode in Spider you must boot with P1 Left and P1 Right held down,
|
||||
this requires the -joystick_contradictory switch on the commandline.
|
||||
To access Service Mode:
|
||||
- twins, twinsed2: you must boot with coin 1 and start 1 held down
|
||||
(there's a test button on the PCB tho?)
|
||||
- spider, twinsed1: you must boot with P1 Left and P1 Right held down,
|
||||
this requires the -joystick_contradictory switch on the commandline;
|
||||
|
||||
*/
|
||||
|
||||
#include "emu.h"
|
||||
#include "cpu/nec/nec.h"
|
||||
#include "sound/ay8910.h"
|
||||
#include "machine/bankdev.h"
|
||||
#include "machine/i2cmem.h"
|
||||
#include "video/ramdac.h"
|
||||
#include "emupal.h"
|
||||
@ -104,87 +108,195 @@ public:
|
||||
twins_state(const machine_config &mconfig, device_type type, const char *tag)
|
||||
: driver_device(mconfig, type, tag)
|
||||
, m_maincpu(*this, "maincpu")
|
||||
, m_paletteram(*this, "paletteram")
|
||||
, m_screen(*this, "screen")
|
||||
, m_palette(*this, "palette")
|
||||
, m_i2cmem(*this, "i2cmem")
|
||||
, m_overlay(*this, "overlay")
|
||||
, m_spritesinit(0)
|
||||
, m_videorambank(0)
|
||||
{ }
|
||||
|
||||
void spider(machine_config &config);
|
||||
void twinsed1(machine_config &config);
|
||||
void twins(machine_config &config);
|
||||
void init_twins();
|
||||
void init_twinsed2();
|
||||
|
||||
protected:
|
||||
required_device<cpu_device> m_maincpu;
|
||||
required_device<screen_device> m_screen;
|
||||
required_device<palette_device> m_palette;
|
||||
required_device<i2cmem_device> m_i2cmem;
|
||||
required_device<address_map_bank_device> m_overlay;
|
||||
|
||||
std::unique_ptr<u16 []> m_bgvram;
|
||||
std::unique_ptr<u16 []> m_fgvram;
|
||||
std::unique_ptr<u16 []> m_paletteram;
|
||||
uint16_t m_paloff;
|
||||
int m_spritesinit;
|
||||
int m_spriteswidth;
|
||||
int m_spritesaddr;
|
||||
uint16_t m_videorambank;
|
||||
uint8_t* m_rom8;
|
||||
|
||||
void base_config(machine_config &config);
|
||||
void video_config(machine_config &config);
|
||||
void sound_config(machine_config &config);
|
||||
void base_map(address_map &map);
|
||||
void twins_map(address_map &map);
|
||||
uint32_t screen_update_twins(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect);
|
||||
|
||||
DECLARE_READ16_MEMBER(eeprom_r);
|
||||
DECLARE_WRITE16_MEMBER(eeprom_w);
|
||||
|
||||
void draw_background(bitmap_ind16 &bitmap, const rectangle &cliprect);
|
||||
virtual void video_start() override;
|
||||
|
||||
static constexpr u32 ram_size = 0x10000/2;
|
||||
|
||||
inline u16* get_vram_base();
|
||||
DECLARE_READ16_MEMBER(vram_r);
|
||||
DECLARE_WRITE16_MEMBER(vram_w);
|
||||
DECLARE_WRITE16_MEMBER(vram_rmw_w);
|
||||
|
||||
private:
|
||||
required_device<cpu_device> m_maincpu;
|
||||
optional_shared_ptr<uint16_t> m_paletteram;
|
||||
required_device<palette_device> m_palette;
|
||||
optional_device<i2cmem_device> m_i2cmem;
|
||||
uint16_t m_paloff;
|
||||
DECLARE_READ16_MEMBER(twins_port4_r);
|
||||
DECLARE_WRITE16_MEMBER(twins_port4_w);
|
||||
DECLARE_WRITE16_MEMBER(twins_pal_w);
|
||||
DECLARE_WRITE16_MEMBER(spider_pal_w);
|
||||
DECLARE_WRITE16_MEMBER(porte_paloff0_w);
|
||||
DECLARE_WRITE16_MEMBER(spider_paloff0_w);
|
||||
DECLARE_WRITE16_MEMBER(spider_blitter_w);
|
||||
DECLARE_READ16_MEMBER(spider_blitter_r);
|
||||
DECLARE_WRITE16_MEMBER(access_w);
|
||||
DECLARE_READ16_MEMBER(access_r);
|
||||
|
||||
virtual void machine_start() override;
|
||||
|
||||
void ramdac_map(address_map &map);
|
||||
void twins_io(address_map &map);
|
||||
};
|
||||
|
||||
class twinsed1_state : public twins_state
|
||||
{
|
||||
public:
|
||||
twinsed1_state(const machine_config &mconfig, device_type type, const char *tag)
|
||||
: twins_state(mconfig, type, tag)
|
||||
{}
|
||||
|
||||
void twinsed1(machine_config &config);
|
||||
|
||||
private:
|
||||
void twinsed1_io(address_map &map);
|
||||
DECLARE_WRITE16_MEMBER(porte_paloff0_w);
|
||||
DECLARE_WRITE16_MEMBER(twins_pal_w);
|
||||
};
|
||||
|
||||
class spider_state : public twins_state
|
||||
{
|
||||
public:
|
||||
spider_state(const machine_config &mconfig, device_type type, const char *tag)
|
||||
: twins_state(mconfig, type, tag)
|
||||
{}
|
||||
|
||||
void spider(machine_config &config);
|
||||
|
||||
private:
|
||||
uint32_t screen_update_spider(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect);
|
||||
|
||||
void draw_foreground(bitmap_ind16 &bitmap, const rectangle &cliprect);
|
||||
|
||||
void spider_io(address_map &map);
|
||||
DECLARE_WRITE16_MEMBER(spider_paloff0_w);
|
||||
DECLARE_READ16_MEMBER(spider_port_18_r);
|
||||
DECLARE_READ16_MEMBER(spider_port_1e_r);
|
||||
DECLARE_WRITE16_MEMBER(spider_port_1a_w);
|
||||
DECLARE_WRITE16_MEMBER(spider_port_1c_w);
|
||||
int m_spritesinit;
|
||||
int m_spriteswidth;
|
||||
int m_spritesaddr;
|
||||
|
||||
uint16_t m_mainram[0x10000 / 2];
|
||||
uint16_t m_videoram[0x10000 / 2];
|
||||
uint16_t m_videoram2[0x10000 / 2];
|
||||
uint16_t m_videorambank;
|
||||
|
||||
uint32_t screen_update_twins(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect);
|
||||
uint32_t screen_update_spider(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect);
|
||||
|
||||
virtual void machine_start() override;
|
||||
virtual void video_start() override;
|
||||
uint16_t* m_rom16;
|
||||
uint8_t* m_rom8;
|
||||
|
||||
void ramdac_map(address_map &map);
|
||||
void spider_io(address_map &map);
|
||||
void twinsed1_io(address_map &map);
|
||||
void twins_map(address_map &map);
|
||||
void twins_io(address_map &map);
|
||||
DECLARE_WRITE16_MEMBER(spider_pal_w);
|
||||
};
|
||||
|
||||
void twins_state::video_start()
|
||||
{
|
||||
m_paloff = 0;
|
||||
|
||||
save_item(NAME(m_paloff));
|
||||
save_item(NAME(m_spritesinit));
|
||||
save_item(NAME(m_spriteswidth));
|
||||
save_item(NAME(m_spritesaddr));
|
||||
|
||||
m_bgvram = std::make_unique<u16 []>(ram_size);
|
||||
std::fill_n(m_bgvram.get(), ram_size, 0);
|
||||
save_pointer(NAME(m_bgvram), ram_size);
|
||||
|
||||
m_fgvram = std::make_unique<u16 []>(ram_size);
|
||||
std::fill_n(m_fgvram.get(), ram_size, 0);
|
||||
save_pointer(NAME(m_fgvram), ram_size);
|
||||
|
||||
const u16 palette_size = 0x100;
|
||||
m_paletteram = std::make_unique<u16 []>(palette_size);
|
||||
std::fill_n(m_paletteram.get(), palette_size, 0);
|
||||
save_pointer(NAME(m_paletteram), palette_size);
|
||||
|
||||
save_item(NAME(m_videorambank));
|
||||
}
|
||||
|
||||
void twins_state::draw_background(bitmap_ind16 &bitmap, const rectangle &cliprect)
|
||||
{
|
||||
uint8_t *videoram = (uint8_t*)m_bgvram.get();
|
||||
|
||||
for (int y = cliprect.top(); y <= cliprect.bottom(); y++)
|
||||
{
|
||||
int count = (y * 320) + cliprect.left();
|
||||
for(int x = cliprect.left(); x <= cliprect.right(); x++)
|
||||
bitmap.pix16(y, x) = videoram[BYTE_XOR_LE(count++)];
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t twins_state::screen_update_twins(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
|
||||
{
|
||||
bitmap.fill(m_palette->black_pen());
|
||||
draw_background(bitmap, cliprect);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void spider_state::draw_foreground(bitmap_ind16 &bitmap, const rectangle &cliprect)
|
||||
{
|
||||
uint8_t *videoram = (uint8_t*)m_fgvram.get();
|
||||
|
||||
for (int y = cliprect.top(); y <= cliprect.bottom(); y++)
|
||||
{
|
||||
int count = (y * 320) + cliprect.left();
|
||||
for(int x = cliprect.left(); x <= cliprect.right(); x++)
|
||||
{
|
||||
u8 pixel = videoram[BYTE_XOR_LE(count++)];
|
||||
if (pixel)
|
||||
bitmap.pix16(y, x) = pixel;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t spider_state::screen_update_spider(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
|
||||
{
|
||||
bitmap.fill(m_palette->black_pen());
|
||||
draw_background(bitmap, cliprect);
|
||||
draw_foreground(bitmap, cliprect);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void twins_state::machine_start()
|
||||
{
|
||||
m_rom16 = (uint16_t*)memregion("maincpu")->base();
|
||||
m_rom8 = memregion("maincpu")->base();
|
||||
m_rom8 = memregion("ipl")->base();
|
||||
}
|
||||
|
||||
/* port 4 is eeprom */
|
||||
READ16_MEMBER(twins_state::twins_port4_r)
|
||||
READ16_MEMBER(twins_state::eeprom_r)
|
||||
{
|
||||
// doesn't work??
|
||||
// printf("%08x: twins_port4_r %04x\n", m_maincpu->pc(), mem_mask);
|
||||
// printf("%08x: eeprom_r %04x\n", m_maincpu->pc(), mem_mask);
|
||||
// return m_i2cmem->read_sda();// | 0xfffe;
|
||||
|
||||
return 0x0001;
|
||||
// TODO: bit 1, i2c clock readback?
|
||||
|
||||
return m_i2cmem->read_sda();
|
||||
}
|
||||
|
||||
WRITE16_MEMBER(twins_state::twins_port4_w)
|
||||
WRITE16_MEMBER(twins_state::eeprom_w)
|
||||
{
|
||||
// printf("%08x: twins_port4_w %04x %04x\n", m_maincpu->pc(), data, mem_mask);
|
||||
// printf("%08x: eeprom_w %04x %04x\n", m_maincpu->pc(), data, mem_mask);
|
||||
int i2c_clk = BIT(data, 1);
|
||||
int i2c_mem = BIT(data, 0);
|
||||
m_i2cmem->write_scl(i2c_clk);
|
||||
m_i2cmem->write_sda(i2c_mem);
|
||||
}
|
||||
|
||||
WRITE16_MEMBER(twins_state::twins_pal_w)
|
||||
WRITE16_MEMBER(twinsed1_state::twins_pal_w)
|
||||
{
|
||||
COMBINE_DATA(&m_paletteram[m_paloff]);
|
||||
|
||||
@ -202,52 +314,72 @@ WRITE16_MEMBER(twins_state::twins_pal_w)
|
||||
b = bitswap<8>(b,7,6,5,0,1,2,3,4);
|
||||
|
||||
m_palette->set_pen_color(m_paloff, pal5bit(r),pal5bit(g),pal5bit(b));
|
||||
|
||||
}
|
||||
|
||||
m_paloff = (m_paloff + 1) & 0xff;
|
||||
}
|
||||
|
||||
/* ??? weird ..*/
|
||||
WRITE16_MEMBER(twins_state::porte_paloff0_w)
|
||||
WRITE16_MEMBER(twinsed1_state::porte_paloff0_w)
|
||||
{
|
||||
// printf("porte_paloff0_w %04x\n", data);
|
||||
m_paloff = 0;
|
||||
}
|
||||
|
||||
READ16_MEMBER(twins_state::spider_blitter_r)
|
||||
inline u16 *twins_state::get_vram_base()
|
||||
{
|
||||
uint16_t* vram;
|
||||
if (m_videorambank & 1)
|
||||
vram = m_videoram2;
|
||||
else
|
||||
vram = m_videoram;
|
||||
return (m_videorambank & 1) ? m_fgvram.get() : m_bgvram.get();
|
||||
}
|
||||
|
||||
if (offset < 0x10000 / 2)
|
||||
READ16_MEMBER(twins_state::vram_r)
|
||||
{
|
||||
u16 *vram = get_vram_base();
|
||||
return vram[offset];
|
||||
}
|
||||
|
||||
WRITE16_MEMBER(twins_state::vram_w)
|
||||
{
|
||||
u16 *vram = get_vram_base();
|
||||
COMBINE_DATA(&vram[offset]);
|
||||
}
|
||||
|
||||
// TODO: confirm this area being present on twins versions
|
||||
WRITE16_MEMBER(twins_state::vram_rmw_w)
|
||||
{
|
||||
u16 *vram = get_vram_base();
|
||||
|
||||
// printf("spider_blitter_w %08x %04x %04x (previous data width %d address %08x)\n", offset * 2, data, mem_mask, m_spriteswidth, m_spritesaddr);
|
||||
|
||||
for (int i = 0; i < m_spriteswidth; i++)
|
||||
{
|
||||
return m_mainram[offset&0x7fff];
|
||||
}
|
||||
else if (offset < 0x20000 / 2)
|
||||
{
|
||||
return vram[offset&0x7fff];
|
||||
}
|
||||
else
|
||||
{
|
||||
uint16_t *src = m_rom16;
|
||||
return src[offset];
|
||||
uint8_t data;
|
||||
|
||||
data = (m_rom8[(m_spritesaddr * 2) + 1]);
|
||||
|
||||
if (data)
|
||||
vram[offset] = (vram[offset] & 0x00ff) | data << 8;
|
||||
|
||||
data = m_rom8[(m_spritesaddr*2)];
|
||||
|
||||
if (data)
|
||||
vram[offset] = (vram[offset] & 0xff00) | data;
|
||||
|
||||
m_spritesaddr ++;
|
||||
offset++;
|
||||
|
||||
offset &= 0x7fff;
|
||||
}
|
||||
}
|
||||
|
||||
READ16_MEMBER(twins_state::access_r)
|
||||
{
|
||||
return m_overlay->read16(offset, mem_mask);
|
||||
}
|
||||
|
||||
WRITE16_MEMBER(twins_state::spider_blitter_w)
|
||||
WRITE16_MEMBER(twins_state::access_w)
|
||||
{
|
||||
// this is very strange, we use the offset (address bits) not data bits to set values..
|
||||
// I get the impression this might actually overlay the entire address range, including RAM and regular VRAM?
|
||||
uint16_t* vram;
|
||||
if (m_videorambank & 1)
|
||||
vram = m_videoram2;
|
||||
else
|
||||
vram = m_videoram;
|
||||
|
||||
if (m_spritesinit == 1)
|
||||
{
|
||||
@ -264,239 +396,12 @@ WRITE16_MEMBER(twins_state::spider_blitter_w)
|
||||
m_spriteswidth = 80;
|
||||
|
||||
m_spritesinit = 0;
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
if (offset < 0x10000 / 2)
|
||||
{
|
||||
COMBINE_DATA(&m_mainram[offset&0x7fff]);
|
||||
}
|
||||
else if (offset < 0x20000 / 2)
|
||||
{
|
||||
COMBINE_DATA(&vram[offset&0x7fff]);
|
||||
}
|
||||
else if (offset < 0x30000 / 2)
|
||||
{
|
||||
uint8_t *src = m_rom8;
|
||||
|
||||
// printf("spider_blitter_w %08x %04x %04x (previous data width %d address %08x)\n", offset * 2, data, mem_mask, m_spriteswidth, m_spritesaddr);
|
||||
offset &= 0x7fff;
|
||||
|
||||
for (int i = 0; i < m_spriteswidth; i++)
|
||||
{
|
||||
uint8_t data;
|
||||
|
||||
data = (src[(m_spritesaddr * 2) + 1]);
|
||||
|
||||
if (data)
|
||||
vram[offset] = (vram[offset] & 0x00ff) | data << 8;
|
||||
|
||||
|
||||
data = src[(m_spritesaddr*2)];
|
||||
|
||||
if (data)
|
||||
vram[offset] = (vram[offset] & 0xff00) | data;
|
||||
|
||||
|
||||
m_spritesaddr ++;
|
||||
offset++;
|
||||
|
||||
offset &= 0x7fff;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("spider_blitter_w unhandled RAM access %08x %04x %04x", offset * 2, data, mem_mask);
|
||||
}
|
||||
}
|
||||
m_overlay->write16(offset, data, mem_mask);
|
||||
}
|
||||
|
||||
|
||||
void twins_state::twins_map(address_map &map)
|
||||
{
|
||||
map(0x00000, 0xfffff).rw(FUNC(twins_state::spider_blitter_r), FUNC(twins_state::spider_blitter_w));
|
||||
}
|
||||
|
||||
void twins_state::twinsed1_io(address_map &map)
|
||||
{
|
||||
map(0x0000, 0x0003).w("aysnd", FUNC(ay8910_device::address_data_w)).umask16(0x00ff);
|
||||
map(0x0002, 0x0002).r("aysnd", FUNC(ay8910_device::data_r));
|
||||
map(0x0004, 0x0005).rw(FUNC(twins_state::twins_port4_r), FUNC(twins_state::twins_port4_w));
|
||||
map(0x0006, 0x0007).w(FUNC(twins_state::twins_pal_w)).share("paletteram");
|
||||
map(0x000e, 0x000f).w(FUNC(twins_state::porte_paloff0_w));
|
||||
}
|
||||
|
||||
void twins_state::video_start()
|
||||
{
|
||||
m_paloff = 0;
|
||||
|
||||
save_item(NAME(m_paloff));
|
||||
save_item(NAME(m_spritesinit));
|
||||
save_item(NAME(m_spriteswidth));
|
||||
save_item(NAME(m_spritesaddr));
|
||||
save_item(NAME(m_mainram));
|
||||
save_item(NAME(m_videoram));
|
||||
save_item(NAME(m_videoram2));
|
||||
save_item(NAME(m_videorambank));
|
||||
}
|
||||
|
||||
|
||||
uint32_t twins_state::screen_update_twins(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
|
||||
{
|
||||
int y,x,count;
|
||||
static const int xxx=320,yyy=204;
|
||||
|
||||
bitmap.fill(m_palette->black_pen());
|
||||
|
||||
count=0;
|
||||
uint8_t *videoram = (uint8_t*)m_videoram;
|
||||
for (y=0;y<yyy;y++)
|
||||
{
|
||||
for(x=0;x<xxx;x++)
|
||||
{
|
||||
bitmap.pix16(y, x) = videoram[BYTE_XOR_LE(count)];
|
||||
count++;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint32_t twins_state::screen_update_spider(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
|
||||
{
|
||||
int y,x,count;
|
||||
static const int xxx=320,yyy=204;
|
||||
|
||||
bitmap.fill(m_palette->black_pen());
|
||||
|
||||
count=0;
|
||||
uint8_t *videoram = (uint8_t*)m_videoram;
|
||||
for (y=0;y<yyy;y++)
|
||||
{
|
||||
for(x=0;x<xxx;x++)
|
||||
{
|
||||
bitmap.pix16(y, x) = videoram[BYTE_XOR_LE(count)];
|
||||
count++;
|
||||
}
|
||||
}
|
||||
|
||||
count = 0;
|
||||
videoram = (uint8_t*)m_videoram2;
|
||||
for (y=0;y<yyy;y++)
|
||||
{
|
||||
for(x=0;x<xxx;x++)
|
||||
{
|
||||
uint8_t pixel = videoram[BYTE_XOR_LE(count)];
|
||||
if (pixel) bitmap.pix16(y, x) = pixel;
|
||||
count++;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static INPUT_PORTS_START(twins)
|
||||
PORT_START("P1") /* 8bit */
|
||||
PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_COIN1 )
|
||||
PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_START1 )
|
||||
PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_JOYSTICK_UP ) PORT_PLAYER(1) PORT_8WAY
|
||||
PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_JOYSTICK_DOWN ) PORT_PLAYER(1) PORT_8WAY
|
||||
PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_JOYSTICK_LEFT ) PORT_PLAYER(1) PORT_8WAY
|
||||
PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_JOYSTICK_RIGHT ) PORT_PLAYER(1) PORT_8WAY
|
||||
PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_BUTTON1 ) PORT_PLAYER(1)
|
||||
PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_BUTTON2 ) PORT_PLAYER(1)
|
||||
|
||||
PORT_START("P2") /* 8bit */
|
||||
PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_COIN2 )
|
||||
PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_START2 )
|
||||
PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_JOYSTICK_UP ) PORT_PLAYER(2) PORT_8WAY
|
||||
PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_JOYSTICK_DOWN ) PORT_PLAYER(2) PORT_8WAY
|
||||
PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_JOYSTICK_LEFT ) PORT_PLAYER(2) PORT_8WAY
|
||||
PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_JOYSTICK_RIGHT ) PORT_PLAYER(2) PORT_8WAY
|
||||
PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_BUTTON1 ) PORT_PLAYER(2)
|
||||
PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_BUTTON2 ) PORT_PLAYER(2)
|
||||
INPUT_PORTS_END
|
||||
|
||||
|
||||
void twins_state::twinsed1(machine_config &config)
|
||||
{
|
||||
/* basic machine hardware */
|
||||
V30(config, m_maincpu, 8000000);
|
||||
m_maincpu->set_addrmap(AS_PROGRAM, &twins_state::twins_map);
|
||||
m_maincpu->set_addrmap(AS_IO, &twins_state::twinsed1_io);
|
||||
|
||||
/* video hardware */
|
||||
screen_device &screen(SCREEN(config, "screen", SCREEN_TYPE_RASTER));
|
||||
screen.set_raw(8000000, 512, 0, 320, 312, 0, 200); // 15.625 kHz horizontal???
|
||||
screen.set_screen_update(FUNC(twins_state::screen_update_twins));
|
||||
screen.set_palette(m_palette);
|
||||
screen.screen_vblank().set_inputline(m_maincpu, INPUT_LINE_NMI);
|
||||
|
||||
I2C_24C02(config, m_i2cmem);
|
||||
|
||||
PALETTE(config, m_palette).set_entries(0x100);
|
||||
|
||||
/* sound hardware */
|
||||
SPEAKER(config, "mono").front_center();
|
||||
|
||||
ay8910_device &aysnd(AY8910(config, "aysnd", 2000000));
|
||||
aysnd.port_a_read_callback().set_ioport("P1");
|
||||
aysnd.port_b_read_callback().set_ioport("P2");
|
||||
aysnd.add_route(ALL_OUTPUTS, "mono", 1.0);
|
||||
}
|
||||
|
||||
|
||||
/* The Ecogames set and the Electronic Devices second set has different palette hardware
|
||||
and a different port map than Electronic Devices first set */
|
||||
|
||||
void twins_state::twins_io(address_map &map)
|
||||
{
|
||||
map(0x0000, 0x0000).w("ramdac", FUNC(ramdac_device::index_w));
|
||||
map(0x0002, 0x0002).w("ramdac", FUNC(ramdac_device::mask_w));
|
||||
map(0x0004, 0x0004).rw("ramdac", FUNC(ramdac_device::pal_r), FUNC(ramdac_device::pal_w));
|
||||
map(0x0008, 0x0008).w("aysnd", FUNC(ay8910_device::address_w));
|
||||
map(0x0010, 0x0010).rw("aysnd", FUNC(ay8910_device::data_r), FUNC(ay8910_device::data_w));
|
||||
map(0x0018, 0x0019).r(FUNC(twins_state::twins_port4_r)).w(FUNC(twins_state::twins_port4_w));
|
||||
}
|
||||
|
||||
|
||||
void twins_state::ramdac_map(address_map &map)
|
||||
{
|
||||
map(0x000, 0x3ff).rw("ramdac", FUNC(ramdac_device::ramdac_pal_r), FUNC(ramdac_device::ramdac_rgb666_w));
|
||||
}
|
||||
|
||||
|
||||
void twins_state::twins(machine_config &config)
|
||||
{
|
||||
/* basic machine hardware */
|
||||
V30(config, m_maincpu, XTAL(16'000'000)/2); /* verified on pcb */
|
||||
m_maincpu->set_addrmap(AS_PROGRAM, &twins_state::twins_map);
|
||||
m_maincpu->set_addrmap(AS_IO, &twins_state::twins_io);
|
||||
|
||||
/* video hardware */
|
||||
screen_device &screen(SCREEN(config, "screen", SCREEN_TYPE_RASTER));
|
||||
screen.set_raw(8000000, 512, 0, 320, 312, 0, 200); // 15.625 kHz horizontal???
|
||||
screen.set_screen_update(FUNC(twins_state::screen_update_twins));
|
||||
screen.set_palette(m_palette);
|
||||
screen.screen_vblank().set_inputline(m_maincpu, INPUT_LINE_NMI);
|
||||
|
||||
PALETTE(config, m_palette).set_entries(256);
|
||||
ramdac_device &ramdac(RAMDAC(config, "ramdac", 0, m_palette));
|
||||
ramdac.set_addrmap(0, &twins_state::ramdac_map);
|
||||
ramdac.set_split_read(0);
|
||||
|
||||
I2C_24C02(config, m_i2cmem);
|
||||
|
||||
/* sound hardware */
|
||||
SPEAKER(config, "mono").front_center();
|
||||
|
||||
ay8910_device &aysnd(AY8910(config, "aysnd", XTAL(16'000'000)/8)); /* verified on pcb */
|
||||
aysnd.port_a_read_callback().set_ioport("P1");
|
||||
aysnd.port_b_read_callback().set_ioport("P2");
|
||||
aysnd.add_route(ALL_OUTPUTS, "mono", 1.0);
|
||||
}
|
||||
|
||||
WRITE16_MEMBER(twins_state::spider_pal_w)
|
||||
WRITE16_MEMBER(spider_state::spider_pal_w)
|
||||
{
|
||||
// ths first write doesn't appear to be a palette value
|
||||
if (m_paloff!=0)
|
||||
@ -522,19 +427,19 @@ WRITE16_MEMBER(twins_state::spider_pal_w)
|
||||
}
|
||||
|
||||
|
||||
WRITE16_MEMBER(twins_state::spider_paloff0_w)
|
||||
WRITE16_MEMBER(spider_state::spider_paloff0_w)
|
||||
{
|
||||
// this seems to be video ram banking
|
||||
COMBINE_DATA(&m_videorambank);
|
||||
}
|
||||
|
||||
WRITE16_MEMBER(twins_state::spider_port_1a_w)
|
||||
WRITE16_MEMBER(spider_state::spider_port_1a_w)
|
||||
{
|
||||
// writes 1
|
||||
}
|
||||
|
||||
|
||||
WRITE16_MEMBER(twins_state::spider_port_1c_w)
|
||||
WRITE16_MEMBER(spider_state::spider_port_1c_w)
|
||||
{
|
||||
// done before the 'sprite' read / writes
|
||||
// might clear a buffer?
|
||||
@ -544,21 +449,12 @@ WRITE16_MEMBER(twins_state::spider_port_1c_w)
|
||||
// data written is always 00, only seems to want the upper layer to be cleared
|
||||
// otherwise you get garbage sprites between rounds and the bg incorrectly wiped
|
||||
|
||||
uint16_t* vram;
|
||||
// if (m_videorambank & 1)
|
||||
vram = m_videoram2;
|
||||
// else
|
||||
// vram = m_videoram;
|
||||
|
||||
for (int i = 0; i < 0x8000; i++)
|
||||
{
|
||||
vram[i] = 0x0000;
|
||||
}
|
||||
|
||||
for (int i = 0; i < ram_size; i++)
|
||||
m_fgvram[i] = 0x0000;
|
||||
}
|
||||
|
||||
|
||||
READ16_MEMBER(twins_state::spider_port_18_r)
|
||||
READ16_MEMBER(spider_state::spider_port_18_r)
|
||||
{
|
||||
// read before each blitter command
|
||||
// seems to put the bus in a state where the next 2 bus access offsets (anywhere) are the blitter params
|
||||
@ -567,75 +463,190 @@ READ16_MEMBER(twins_state::spider_port_18_r)
|
||||
return 0xff;
|
||||
}
|
||||
|
||||
READ16_MEMBER(twins_state::spider_port_1e_r)
|
||||
READ16_MEMBER(spider_state::spider_port_1e_r)
|
||||
{
|
||||
// done before each sprite pixel 'write'
|
||||
// the data read is the data written, but only reads one pixel??
|
||||
return 0xff;
|
||||
}
|
||||
|
||||
|
||||
void twins_state::spider_io(address_map &map)
|
||||
void twins_state::twins_map(address_map &map)
|
||||
{
|
||||
map(0x0000, 0x0003).w("aysnd", FUNC(ay8910_device::address_data_w)).umask16(0x00ff);
|
||||
map(0x0002, 0x0002).r("aysnd", FUNC(ay8910_device::data_r));
|
||||
map(0x0004, 0x0005).rw(FUNC(twins_state::twins_port4_r), FUNC(twins_state::twins_port4_w));
|
||||
map(0x0008, 0x0009).w(FUNC(twins_state::spider_pal_w)).share("paletteram");
|
||||
map(0x0010, 0x0011).w(FUNC(twins_state::spider_paloff0_w));
|
||||
|
||||
map(0x0018, 0x0019).r(FUNC(twins_state::spider_port_18_r));
|
||||
map(0x001a, 0x001b).w(FUNC(twins_state::spider_port_1a_w));
|
||||
map(0x001c, 0x001d).w(FUNC(twins_state::spider_port_1c_w));
|
||||
map(0x001e, 0x001f).r(FUNC(twins_state::spider_port_1e_r));
|
||||
|
||||
|
||||
map(0x00000, 0xfffff).rw(FUNC(twins_state::access_r), FUNC(twins_state::access_w));
|
||||
}
|
||||
|
||||
|
||||
void twins_state::spider(machine_config &config)
|
||||
void twins_state::base_map(address_map &map)
|
||||
{
|
||||
/* basic machine hardware */
|
||||
V30(config, m_maincpu, 8000000);
|
||||
m_maincpu->set_addrmap(AS_PROGRAM, &twins_state::twins_map);
|
||||
m_maincpu->set_addrmap(AS_IO, &twins_state::spider_io);
|
||||
map(0x00000, 0x0ffff).ram();
|
||||
map(0x10000, 0x1ffff).rw(FUNC(twins_state::vram_r), FUNC(twins_state::vram_w));
|
||||
map(0x20000, 0x2ffff).w(FUNC(twins_state::vram_rmw_w));
|
||||
map(0x20000, 0xfffff).rom().region("ipl", 0x20000);
|
||||
}
|
||||
|
||||
/* video hardware */
|
||||
screen_device &screen(SCREEN(config, "screen", SCREEN_TYPE_RASTER));
|
||||
screen.set_raw(8000000, 512, 0, 320, 312, 0, 200); // 15.625 kHz horizontal???
|
||||
screen.set_screen_update(FUNC(twins_state::screen_update_spider));
|
||||
screen.set_palette(m_palette);
|
||||
screen.screen_vblank().set_inputline(m_maincpu, INPUT_LINE_NMI);
|
||||
void twinsed1_state::twinsed1_io(address_map &map)
|
||||
{
|
||||
map(0x0000, 0x0001).nopr();
|
||||
map(0x0000, 0x0003).w("aysnd", FUNC(ay8910_device::address_data_w)).umask16(0x00ff);
|
||||
map(0x0002, 0x0002).r("aysnd", FUNC(ay8910_device::data_r));
|
||||
map(0x0004, 0x0005).rw(FUNC(twinsed1_state::eeprom_r), FUNC(twinsed1_state::eeprom_w));
|
||||
map(0x0006, 0x0007).w(FUNC(twinsed1_state::twins_pal_w));
|
||||
map(0x000e, 0x000f).w(FUNC(twinsed1_state::porte_paloff0_w));
|
||||
}
|
||||
|
||||
PALETTE(config, m_palette).set_entries(0x100);
|
||||
/* The Ecogames set and the Electronic Devices second set has different palette hardware
|
||||
and a different port map than Electronic Devices first set */
|
||||
|
||||
void twins_state::twins_io(address_map &map)
|
||||
{
|
||||
map(0x0000, 0x0001).nopr();
|
||||
map(0x0000, 0x0000).w("ramdac", FUNC(ramdac_device::index_w));
|
||||
map(0x0002, 0x0002).w("ramdac", FUNC(ramdac_device::mask_w));
|
||||
map(0x0004, 0x0004).rw("ramdac", FUNC(ramdac_device::pal_r), FUNC(ramdac_device::pal_w));
|
||||
map(0x0008, 0x0008).w("aysnd", FUNC(ay8910_device::address_w));
|
||||
map(0x0010, 0x0010).rw("aysnd", FUNC(ay8910_device::data_r), FUNC(ay8910_device::data_w));
|
||||
map(0x0018, 0x0019).r(FUNC(twins_state::eeprom_r)).w(FUNC(twins_state::eeprom_w));
|
||||
}
|
||||
|
||||
void spider_state::spider_io(address_map &map)
|
||||
{
|
||||
map(0x0000, 0x0001).nopr();
|
||||
map(0x0000, 0x0003).w("aysnd", FUNC(ay8910_device::address_data_w)).umask16(0x00ff);
|
||||
map(0x0002, 0x0002).r("aysnd", FUNC(ay8910_device::data_r));
|
||||
map(0x0004, 0x0005).rw(FUNC(spider_state::eeprom_r), FUNC(spider_state::eeprom_w));
|
||||
map(0x0008, 0x0009).w(FUNC(spider_state::spider_pal_w));
|
||||
map(0x0010, 0x0011).w(FUNC(spider_state::spider_paloff0_w));
|
||||
|
||||
map(0x0018, 0x0019).r(FUNC(spider_state::spider_port_18_r));
|
||||
map(0x001a, 0x001b).w(FUNC(spider_state::spider_port_1a_w));
|
||||
map(0x001c, 0x001d).w(FUNC(spider_state::spider_port_1c_w));
|
||||
map(0x001e, 0x001f).r(FUNC(spider_state::spider_port_1e_r));
|
||||
}
|
||||
|
||||
void twins_state::ramdac_map(address_map &map)
|
||||
{
|
||||
map(0x000, 0x3ff).rw("ramdac", FUNC(ramdac_device::ramdac_pal_r), FUNC(ramdac_device::ramdac_rgb666_w));
|
||||
}
|
||||
|
||||
static INPUT_PORTS_START(twins)
|
||||
PORT_START("P1") /* 8bit */
|
||||
PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_COIN1 )
|
||||
PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_START1 )
|
||||
PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_JOYSTICK_UP ) PORT_PLAYER(1) PORT_8WAY
|
||||
PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_JOYSTICK_DOWN ) PORT_PLAYER(1) PORT_8WAY
|
||||
PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_JOYSTICK_LEFT ) PORT_PLAYER(1) PORT_8WAY
|
||||
PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_JOYSTICK_RIGHT ) PORT_PLAYER(1) PORT_8WAY
|
||||
PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_BUTTON1 ) PORT_PLAYER(1)
|
||||
PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_BUTTON2 ) PORT_PLAYER(1)
|
||||
|
||||
PORT_START("P2") /* 8bit */
|
||||
PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_COIN2 )
|
||||
PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_START2 )
|
||||
PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_JOYSTICK_UP ) PORT_PLAYER(2) PORT_8WAY
|
||||
PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_JOYSTICK_DOWN ) PORT_PLAYER(2) PORT_8WAY
|
||||
PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_JOYSTICK_LEFT ) PORT_PLAYER(2) PORT_8WAY
|
||||
PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_JOYSTICK_RIGHT ) PORT_PLAYER(2) PORT_8WAY
|
||||
PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_BUTTON1 ) PORT_PLAYER(2)
|
||||
PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_BUTTON2 ) PORT_PLAYER(2)
|
||||
INPUT_PORTS_END
|
||||
|
||||
void twins_state::base_config(machine_config &config)
|
||||
{
|
||||
I2C_24C02(config, m_i2cmem);
|
||||
|
||||
ADDRESS_MAP_BANK(config, m_overlay).set_map(&twins_state::base_map).set_options(ENDIANNESS_LITTLE, 16, 24, 0x100000);
|
||||
}
|
||||
|
||||
/* sound hardware */
|
||||
void twins_state::video_config(machine_config &config)
|
||||
{
|
||||
SCREEN(config, m_screen, SCREEN_TYPE_RASTER);
|
||||
m_screen->set_raw(8000000, 512, 0, 320, 312, 0, 204); // Common PAL values, HSync of 15.625 kHz unverified
|
||||
m_screen->set_palette(m_palette);
|
||||
m_screen->screen_vblank().set_inputline(m_maincpu, INPUT_LINE_NMI);
|
||||
}
|
||||
|
||||
void twins_state::sound_config(machine_config &config)
|
||||
{
|
||||
SPEAKER(config, "mono").front_center();
|
||||
|
||||
ay8910_device &aysnd(AY8910(config, "aysnd", 2000000));
|
||||
ay8910_device &aysnd(AY8910(config, "aysnd", XTAL(16'000'000)/8)); /* verified on pcb */
|
||||
aysnd.port_a_read_callback().set_ioport("P1");
|
||||
aysnd.port_b_read_callback().set_ioport("P2");
|
||||
aysnd.add_route(ALL_OUTPUTS, "mono", 1.0);
|
||||
}
|
||||
|
||||
void twinsed1_state::twinsed1(machine_config &config)
|
||||
{
|
||||
/* basic machine hardware */
|
||||
V30(config, m_maincpu, 8000000);
|
||||
m_maincpu->set_addrmap(AS_PROGRAM, &twinsed1_state::twins_map);
|
||||
m_maincpu->set_addrmap(AS_IO, &twinsed1_state::twinsed1_io);
|
||||
|
||||
video_config(config);
|
||||
m_screen->set_screen_update(FUNC(twinsed1_state::screen_update_twins));
|
||||
|
||||
base_config(config);
|
||||
PALETTE(config, m_palette).set_entries(0x100);
|
||||
|
||||
sound_config(config);
|
||||
}
|
||||
|
||||
void twins_state::twins(machine_config &config)
|
||||
{
|
||||
/* basic machine hardware */
|
||||
V30(config, m_maincpu, XTAL(16'000'000)/2); /* verified on pcb */
|
||||
m_maincpu->set_addrmap(AS_PROGRAM, &twins_state::twins_map);
|
||||
m_maincpu->set_addrmap(AS_IO, &twins_state::twins_io);
|
||||
|
||||
video_config(config);
|
||||
m_screen->set_screen_update(FUNC(twins_state::screen_update_twins));
|
||||
|
||||
PALETTE(config, m_palette).set_entries(256);
|
||||
ramdac_device &ramdac(RAMDAC(config, "ramdac", 0, m_palette));
|
||||
ramdac.set_addrmap(0, &twins_state::ramdac_map);
|
||||
ramdac.set_split_read(0);
|
||||
|
||||
base_config(config);
|
||||
|
||||
sound_config(config);
|
||||
}
|
||||
|
||||
void spider_state::spider(machine_config &config)
|
||||
{
|
||||
/* basic machine hardware */
|
||||
V30(config, m_maincpu, 8000000);
|
||||
m_maincpu->set_addrmap(AS_PROGRAM, &spider_state::twins_map);
|
||||
m_maincpu->set_addrmap(AS_IO, &spider_state::spider_io);
|
||||
|
||||
/* video hardware */
|
||||
video_config(config);
|
||||
m_screen->set_screen_update(FUNC(spider_state::screen_update_spider));
|
||||
|
||||
PALETTE(config, m_palette).set_entries(0x100);
|
||||
|
||||
base_config(config);
|
||||
|
||||
sound_config(config);
|
||||
}
|
||||
|
||||
|
||||
/* ECOGAMES Twins */
|
||||
ROM_START( twins )
|
||||
ROM_REGION( 0x100000, "maincpu", 0 )
|
||||
ROM_REGION16_LE( 0x100000, "ipl", 0 )
|
||||
ROM_LOAD16_BYTE( "2.u8", 0x000000, 0x080000, CRC(1ec942b0) SHA1(627deb739c50f93c4cb61b8baf2a07213f1613b3) )
|
||||
ROM_LOAD16_BYTE( "1.u9", 0x000001, 0x080000, CRC(4417ff34) SHA1(be992128fe48556a0a7c018953702b4ce9076526) )
|
||||
|
||||
/* Unused */
|
||||
ROM_REGION( 0x000100, "extra", 0 )
|
||||
ROM_LOAD("24c02.u15", 0x000000, 0x000100, CRC(5ba30b14) SHA1(461f701879b76f1784705e067a5b6b31bfda4606) )
|
||||
ROM_REGION( 0x100, "i2cmem", 0 )
|
||||
ROM_LOAD("24c02.u15", 0x000, 0x100, CRC(2ff05b0e) SHA1(df6854446ba83f4a13ddf68bd2d0bc35be21be79) )
|
||||
ROM_END
|
||||
|
||||
/** Electronic Devices Twins */
|
||||
ROM_START( twinsed1 )
|
||||
ROM_REGION( 0x100000, "maincpu", 0 )
|
||||
ROM_REGION16_LE( 0x100000, "ipl", 0 )
|
||||
ROM_LOAD16_BYTE( "1.bin", 0x000000, 0x080000, CRC(d5ef7b0d) SHA1(7261dca5bb0aef755b4f2b85a159b356e7ac8219) )
|
||||
ROM_LOAD16_BYTE( "2.bin", 0x000001, 0x080000, CRC(8a5392f4) SHA1(e6a2ecdb775138a87d27aa4ad267bdec33c26baa) )
|
||||
|
||||
ROM_REGION( 0x100, "i2cmem", 0 )
|
||||
ROM_LOAD("24c02.u15", 0x000, 0x100, CRC(2ff05b0e) SHA1(df6854446ba83f4a13ddf68bd2d0bc35be21be79) )
|
||||
ROM_END
|
||||
|
||||
/*
|
||||
@ -652,24 +663,55 @@ Electronic Devices
|
||||
1x jamma edge connector
|
||||
1x trimmer (volume)
|
||||
|
||||
hmm, we're only emulating 1x ay-3-8910, is the other at port 0 on this?
|
||||
===
|
||||
|
||||
Author note: we're only emulating 1x ay-3-8910, assume being unused or dumper typo (unaccessed by the game)
|
||||
twinsed2 is basically the same game as twins except having nudity pics (and inps are interchangeable between the sets)
|
||||
|
||||
*/
|
||||
|
||||
ROM_START( twinsed2 )
|
||||
ROM_REGION( 0x100000, "maincpu", 0 )
|
||||
ROM_REGION16_LE( 0x100000, "ipl", 0 )
|
||||
ROM_LOAD16_BYTE( "lp.bin", 0x000000, 0x080000, CRC(4f07862e) SHA1(fbda1973f79c6938c7f026a4db706e78781c2df8) )
|
||||
ROM_LOAD16_BYTE( "hp.bin", 0x000001, 0x080000, CRC(aaf74b83) SHA1(09bd76b9fc5cb7ba6ffe1a2581ffd5633fe440b3) )
|
||||
|
||||
ROM_REGION( 0x100, "i2cmem", 0 )
|
||||
ROM_LOAD("24c02.u15", 0x000, 0x100, CRC(2ff05b0e) SHA1(df6854446ba83f4a13ddf68bd2d0bc35be21be79) )
|
||||
ROM_END
|
||||
|
||||
ROM_START( spider )
|
||||
ROM_REGION( 0x100000, "maincpu", 0 )
|
||||
ROM_REGION16_LE( 0x100000, "ipl", 0 )
|
||||
ROM_LOAD16_BYTE( "20.bin", 0x000001, 0x080000, CRC(25e15f11) SHA1(b728f35c817f60a294e38d66559da8977b94a1f5) )
|
||||
ROM_LOAD16_BYTE( "21.bin", 0x000000, 0x080000, CRC(ff224206) SHA1(d8d45850983542e811facc917d016841fc56a97f) )
|
||||
|
||||
ROM_REGION( 0x100, "i2cmem", 0 )
|
||||
ROM_LOAD("24c02", 0x000, 0x100, CRC(6f710d66) SHA1(1cc6d1134c5b81b7d0913f09c07d73675770d817) )
|
||||
ROM_END
|
||||
|
||||
GAME( 1993, twins, 0, twins, twins, twins_state, empty_init, ROT0, "Ecogames", "Twins", MACHINE_SUPPORTS_SAVE )
|
||||
GAME( 1994, twinsed1, twins, twinsed1, twins, twins_state, empty_init, ROT0, "Ecogames (Electronic Devices license)", "Twins (Electronic Devices license, set 1)", MACHINE_SUPPORTS_SAVE )
|
||||
GAME( 1994, twinsed2, twins, twins, twins, twins_state, empty_init, ROT0, "Ecogames (Electronic Devices license)", "Twins (Electronic Devices license, set 2)", MACHINE_SUPPORTS_SAVE )
|
||||
void twins_state::init_twins()
|
||||
{
|
||||
u8 *rom = (u8 *)memregion("ipl")->base();
|
||||
|
||||
rom[0x3497d] = 0x90;
|
||||
rom[0x3497e] = 0x90;
|
||||
|
||||
GAME( 1994, spider, 0, spider, twins, twins_state, empty_init, ROT0, "Buena Vision", "Spider", MACHINE_IMPERFECT_GRAPHICS | MACHINE_SUPPORTS_SAVE )
|
||||
rom[0x34986] = 0x90;
|
||||
rom[0x34987] = 0x90;
|
||||
}
|
||||
|
||||
void twins_state::init_twinsed2()
|
||||
{
|
||||
u8 *rom = (u8 *)memregion("ipl")->base();
|
||||
|
||||
rom[0x349d3] = 0x90;
|
||||
rom[0x349d4] = 0x90;
|
||||
|
||||
rom[0x349dc] = 0x90;
|
||||
rom[0x349dd] = 0x90;
|
||||
}
|
||||
|
||||
GAME( 1993, twins, 0, twins, twins, twins_state, init_twins, ROT0, "Ecogames", "Twins", MACHINE_SUPPORTS_SAVE )
|
||||
GAME( 1994, twinsed1, twins, twinsed1, twins, twinsed1_state, empty_init, ROT0, "Ecogames (Electronic Devices license)", "Twins (Electronic Devices license, set 1)", MACHINE_SUPPORTS_SAVE )
|
||||
GAME( 1994, twinsed2, twins, twins, twins, twins_state, init_twinsed2, ROT0, "Ecogames (Electronic Devices license)", "Twins (Electronic Devices license, set 2)", MACHINE_SUPPORTS_SAVE )
|
||||
|
||||
GAME( 1994, spider, 0, spider, twins, spider_state, empty_init, ROT0, "Buena Vision", "Spider", MACHINE_IMPERFECT_GRAPHICS | MACHINE_SUPPORTS_SAVE )
|
||||
|
Loading…
Reference in New Issue
Block a user