mirror of
https://github.com/holub/mame
synced 2025-04-26 02:07:14 +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
|
// license:BSD-3-Clause
|
||||||
// copyright-holders:David Haywood
|
// copyright-holders:David Haywood, Angelo Salese
|
||||||
/*
|
/*
|
||||||
|
|
||||||
Twins
|
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
|
video is not banked in this case instead palette data is sent to the ports
|
||||||
strange palette format.
|
strange palette format.
|
||||||
|
|
||||||
todo:
|
TODO:
|
||||||
hook up eeprom (doesn't seem to work when hooked up??)
|
- Proper fix for twins & twinsed2 crash after round 1 (MT #07516):
|
||||||
Twins set 1 takes a long time to boot (eeprom?)
|
after clearing 1-5 it pings i2c for a couple times, expect it to be 0 then 1 otherwise
|
||||||
Improve blitter / clear logic for Spider.
|
jumps to lalaland;
|
||||||
|
- Improve blitter / clear logic for Spider.
|
||||||
|
- Merge with hotblock.cpp;
|
||||||
|
|
||||||
Electronic Devices was printed on rom labels
|
Electronic Devices was printed on rom labels
|
||||||
1994 date string is in ROM
|
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.
|
Spider PCB appears almost identical but uses additional 'blitter' features.
|
||||||
It is possible the Twins PCB has them too and doesn't use them.
|
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:
|
||||||
|
- twins, twinsed2: you must boot with coin 1 and start 1 held down
|
||||||
|
(there's a test button on the PCB tho?)
|
||||||
To access Service Mode in Spider you must boot with P1 Left and P1 Right held down,
|
- spider, twinsed1: you must boot with P1 Left and P1 Right held down,
|
||||||
this requires the -joystick_contradictory switch on the commandline.
|
this requires the -joystick_contradictory switch on the commandline;
|
||||||
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "emu.h"
|
#include "emu.h"
|
||||||
#include "cpu/nec/nec.h"
|
#include "cpu/nec/nec.h"
|
||||||
#include "sound/ay8910.h"
|
#include "sound/ay8910.h"
|
||||||
|
#include "machine/bankdev.h"
|
||||||
#include "machine/i2cmem.h"
|
#include "machine/i2cmem.h"
|
||||||
#include "video/ramdac.h"
|
#include "video/ramdac.h"
|
||||||
#include "emupal.h"
|
#include "emupal.h"
|
||||||
@ -104,87 +108,195 @@ public:
|
|||||||
twins_state(const machine_config &mconfig, device_type type, const char *tag)
|
twins_state(const machine_config &mconfig, device_type type, const char *tag)
|
||||||
: driver_device(mconfig, type, tag)
|
: driver_device(mconfig, type, tag)
|
||||||
, m_maincpu(*this, "maincpu")
|
, m_maincpu(*this, "maincpu")
|
||||||
, m_paletteram(*this, "paletteram")
|
, m_screen(*this, "screen")
|
||||||
, m_palette(*this, "palette")
|
, m_palette(*this, "palette")
|
||||||
, m_i2cmem(*this, "i2cmem")
|
, m_i2cmem(*this, "i2cmem")
|
||||||
|
, m_overlay(*this, "overlay")
|
||||||
, m_spritesinit(0)
|
, m_spritesinit(0)
|
||||||
, m_videorambank(0)
|
, m_videorambank(0)
|
||||||
{ }
|
{ }
|
||||||
|
|
||||||
void spider(machine_config &config);
|
|
||||||
void twinsed1(machine_config &config);
|
|
||||||
void twins(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:
|
private:
|
||||||
required_device<cpu_device> m_maincpu;
|
DECLARE_WRITE16_MEMBER(access_w);
|
||||||
optional_shared_ptr<uint16_t> m_paletteram;
|
DECLARE_READ16_MEMBER(access_r);
|
||||||
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);
|
|
||||||
|
|
||||||
|
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_18_r);
|
||||||
DECLARE_READ16_MEMBER(spider_port_1e_r);
|
DECLARE_READ16_MEMBER(spider_port_1e_r);
|
||||||
DECLARE_WRITE16_MEMBER(spider_port_1a_w);
|
DECLARE_WRITE16_MEMBER(spider_port_1a_w);
|
||||||
DECLARE_WRITE16_MEMBER(spider_port_1c_w);
|
DECLARE_WRITE16_MEMBER(spider_port_1c_w);
|
||||||
int m_spritesinit;
|
DECLARE_WRITE16_MEMBER(spider_pal_w);
|
||||||
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);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
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()
|
void twins_state::machine_start()
|
||||||
{
|
{
|
||||||
m_rom16 = (uint16_t*)memregion("maincpu")->base();
|
m_rom8 = memregion("ipl")->base();
|
||||||
m_rom8 = memregion("maincpu")->base();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* port 4 is eeprom */
|
READ16_MEMBER(twins_state::eeprom_r)
|
||||||
READ16_MEMBER(twins_state::twins_port4_r)
|
|
||||||
{
|
{
|
||||||
// doesn't work??
|
// printf("%08x: eeprom_r %04x\n", m_maincpu->pc(), mem_mask);
|
||||||
// printf("%08x: twins_port4_r %04x\n", m_maincpu->pc(), mem_mask);
|
|
||||||
// return m_i2cmem->read_sda();// | 0xfffe;
|
// return m_i2cmem->read_sda();// | 0xfffe;
|
||||||
|
// TODO: bit 1, i2c clock readback?
|
||||||
return 0x0001;
|
|
||||||
|
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_clk = BIT(data, 1);
|
||||||
int i2c_mem = BIT(data, 0);
|
int i2c_mem = BIT(data, 0);
|
||||||
m_i2cmem->write_scl(i2c_clk);
|
m_i2cmem->write_scl(i2c_clk);
|
||||||
m_i2cmem->write_sda(i2c_mem);
|
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]);
|
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);
|
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_palette->set_pen_color(m_paloff, pal5bit(r),pal5bit(g),pal5bit(b));
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
m_paloff = (m_paloff + 1) & 0xff;
|
m_paloff = (m_paloff + 1) & 0xff;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ??? weird ..*/
|
/* ??? weird ..*/
|
||||||
WRITE16_MEMBER(twins_state::porte_paloff0_w)
|
WRITE16_MEMBER(twinsed1_state::porte_paloff0_w)
|
||||||
{
|
{
|
||||||
// printf("porte_paloff0_w %04x\n", data);
|
// printf("porte_paloff0_w %04x\n", data);
|
||||||
m_paloff = 0;
|
m_paloff = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
READ16_MEMBER(twins_state::spider_blitter_r)
|
inline u16 *twins_state::get_vram_base()
|
||||||
{
|
{
|
||||||
uint16_t* vram;
|
return (m_videorambank & 1) ? m_fgvram.get() : m_bgvram.get();
|
||||||
if (m_videorambank & 1)
|
}
|
||||||
vram = m_videoram2;
|
|
||||||
else
|
|
||||||
vram = m_videoram;
|
|
||||||
|
|
||||||
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];
|
uint8_t data;
|
||||||
}
|
|
||||||
else if (offset < 0x20000 / 2)
|
data = (m_rom8[(m_spritesaddr * 2) + 1]);
|
||||||
{
|
|
||||||
return vram[offset&0x7fff];
|
if (data)
|
||||||
}
|
vram[offset] = (vram[offset] & 0x00ff) | data << 8;
|
||||||
else
|
|
||||||
{
|
data = m_rom8[(m_spritesaddr*2)];
|
||||||
uint16_t *src = m_rom16;
|
|
||||||
return src[offset];
|
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..
|
// 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?
|
// 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)
|
if (m_spritesinit == 1)
|
||||||
{
|
{
|
||||||
@ -264,239 +396,12 @@ WRITE16_MEMBER(twins_state::spider_blitter_w)
|
|||||||
m_spriteswidth = 80;
|
m_spriteswidth = 80;
|
||||||
|
|
||||||
m_spritesinit = 0;
|
m_spritesinit = 0;
|
||||||
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
m_overlay->write16(offset, data, mem_mask);
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
WRITE16_MEMBER(spider_state::spider_pal_w)
|
||||||
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)
|
|
||||||
{
|
{
|
||||||
// ths first write doesn't appear to be a palette value
|
// ths first write doesn't appear to be a palette value
|
||||||
if (m_paloff!=0)
|
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
|
// this seems to be video ram banking
|
||||||
COMBINE_DATA(&m_videorambank);
|
COMBINE_DATA(&m_videorambank);
|
||||||
}
|
}
|
||||||
|
|
||||||
WRITE16_MEMBER(twins_state::spider_port_1a_w)
|
WRITE16_MEMBER(spider_state::spider_port_1a_w)
|
||||||
{
|
{
|
||||||
// writes 1
|
// writes 1
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
WRITE16_MEMBER(twins_state::spider_port_1c_w)
|
WRITE16_MEMBER(spider_state::spider_port_1c_w)
|
||||||
{
|
{
|
||||||
// done before the 'sprite' read / writes
|
// done before the 'sprite' read / writes
|
||||||
// might clear a buffer?
|
// 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
|
// 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
|
// otherwise you get garbage sprites between rounds and the bg incorrectly wiped
|
||||||
|
|
||||||
uint16_t* vram;
|
for (int i = 0; i < ram_size; i++)
|
||||||
// if (m_videorambank & 1)
|
m_fgvram[i] = 0x0000;
|
||||||
vram = m_videoram2;
|
|
||||||
// else
|
|
||||||
// vram = m_videoram;
|
|
||||||
|
|
||||||
for (int i = 0; i < 0x8000; i++)
|
|
||||||
{
|
|
||||||
vram[i] = 0x0000;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
READ16_MEMBER(twins_state::spider_port_18_r)
|
READ16_MEMBER(spider_state::spider_port_18_r)
|
||||||
{
|
{
|
||||||
// read before each blitter command
|
// 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
|
// 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;
|
return 0xff;
|
||||||
}
|
}
|
||||||
|
|
||||||
READ16_MEMBER(twins_state::spider_port_1e_r)
|
READ16_MEMBER(spider_state::spider_port_1e_r)
|
||||||
{
|
{
|
||||||
// done before each sprite pixel 'write'
|
// done before each sprite pixel 'write'
|
||||||
// the data read is the data written, but only reads one pixel??
|
// the data read is the data written, but only reads one pixel??
|
||||||
return 0xff;
|
return 0xff;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void twins_state::twins_map(address_map &map)
|
||||||
void twins_state::spider_io(address_map &map)
|
|
||||||
{
|
{
|
||||||
map(0x0000, 0x0003).w("aysnd", FUNC(ay8910_device::address_data_w)).umask16(0x00ff);
|
map(0x00000, 0xfffff).rw(FUNC(twins_state::access_r), FUNC(twins_state::access_w));
|
||||||
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));
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void twins_state::base_map(address_map &map)
|
||||||
void twins_state::spider(machine_config &config)
|
|
||||||
{
|
{
|
||||||
/* basic machine hardware */
|
map(0x00000, 0x0ffff).ram();
|
||||||
V30(config, m_maincpu, 8000000);
|
map(0x10000, 0x1ffff).rw(FUNC(twins_state::vram_r), FUNC(twins_state::vram_w));
|
||||||
m_maincpu->set_addrmap(AS_PROGRAM, &twins_state::twins_map);
|
map(0x20000, 0x2ffff).w(FUNC(twins_state::vram_rmw_w));
|
||||||
m_maincpu->set_addrmap(AS_IO, &twins_state::spider_io);
|
map(0x20000, 0xfffff).rom().region("ipl", 0x20000);
|
||||||
|
}
|
||||||
|
|
||||||
/* video hardware */
|
void twinsed1_state::twinsed1_io(address_map &map)
|
||||||
screen_device &screen(SCREEN(config, "screen", SCREEN_TYPE_RASTER));
|
{
|
||||||
screen.set_raw(8000000, 512, 0, 320, 312, 0, 200); // 15.625 kHz horizontal???
|
map(0x0000, 0x0001).nopr();
|
||||||
screen.set_screen_update(FUNC(twins_state::screen_update_spider));
|
map(0x0000, 0x0003).w("aysnd", FUNC(ay8910_device::address_data_w)).umask16(0x00ff);
|
||||||
screen.set_palette(m_palette);
|
map(0x0002, 0x0002).r("aysnd", FUNC(ay8910_device::data_r));
|
||||||
screen.screen_vblank().set_inputline(m_maincpu, INPUT_LINE_NMI);
|
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);
|
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();
|
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_a_read_callback().set_ioport("P1");
|
||||||
aysnd.port_b_read_callback().set_ioport("P2");
|
aysnd.port_b_read_callback().set_ioport("P2");
|
||||||
aysnd.add_route(ALL_OUTPUTS, "mono", 1.0);
|
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 */
|
/* ECOGAMES Twins */
|
||||||
ROM_START( 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( "2.u8", 0x000000, 0x080000, CRC(1ec942b0) SHA1(627deb739c50f93c4cb61b8baf2a07213f1613b3) )
|
||||||
ROM_LOAD16_BYTE( "1.u9", 0x000001, 0x080000, CRC(4417ff34) SHA1(be992128fe48556a0a7c018953702b4ce9076526) )
|
ROM_LOAD16_BYTE( "1.u9", 0x000001, 0x080000, CRC(4417ff34) SHA1(be992128fe48556a0a7c018953702b4ce9076526) )
|
||||||
|
|
||||||
/* Unused */
|
ROM_REGION( 0x100, "i2cmem", 0 )
|
||||||
ROM_REGION( 0x000100, "extra", 0 )
|
ROM_LOAD("24c02.u15", 0x000, 0x100, CRC(2ff05b0e) SHA1(df6854446ba83f4a13ddf68bd2d0bc35be21be79) )
|
||||||
ROM_LOAD("24c02.u15", 0x000000, 0x000100, CRC(5ba30b14) SHA1(461f701879b76f1784705e067a5b6b31bfda4606) )
|
|
||||||
ROM_END
|
ROM_END
|
||||||
|
|
||||||
/** Electronic Devices Twins */
|
/** Electronic Devices Twins */
|
||||||
ROM_START( twinsed1 )
|
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( "1.bin", 0x000000, 0x080000, CRC(d5ef7b0d) SHA1(7261dca5bb0aef755b4f2b85a159b356e7ac8219) )
|
||||||
ROM_LOAD16_BYTE( "2.bin", 0x000001, 0x080000, CRC(8a5392f4) SHA1(e6a2ecdb775138a87d27aa4ad267bdec33c26baa) )
|
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
|
ROM_END
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -652,24 +663,55 @@ Electronic Devices
|
|||||||
1x jamma edge connector
|
1x jamma edge connector
|
||||||
1x trimmer (volume)
|
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_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( "lp.bin", 0x000000, 0x080000, CRC(4f07862e) SHA1(fbda1973f79c6938c7f026a4db706e78781c2df8) )
|
||||||
ROM_LOAD16_BYTE( "hp.bin", 0x000001, 0x080000, CRC(aaf74b83) SHA1(09bd76b9fc5cb7ba6ffe1a2581ffd5633fe440b3) )
|
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_END
|
||||||
|
|
||||||
ROM_START( spider )
|
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( "20.bin", 0x000001, 0x080000, CRC(25e15f11) SHA1(b728f35c817f60a294e38d66559da8977b94a1f5) )
|
||||||
ROM_LOAD16_BYTE( "21.bin", 0x000000, 0x080000, CRC(ff224206) SHA1(d8d45850983542e811facc917d016841fc56a97f) )
|
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
|
ROM_END
|
||||||
|
|
||||||
GAME( 1993, twins, 0, twins, twins, twins_state, empty_init, ROT0, "Ecogames", "Twins", MACHINE_SUPPORTS_SAVE )
|
void twins_state::init_twins()
|
||||||
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 )
|
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