New machines marked as NOT_WORKING

----------------------------------
Super Mario Bros. 3 (NES bootleg) [Victor Fernandez (City Game)]

- misc/mcatadv.cpp, misc/oneshot.cpp, taito/retofinv.cpp: consolidated drivers in single files, minor cleanups
This commit is contained in:
Ivan Vangelista 2022-09-02 06:52:20 +02:00
parent 051c380fd1
commit 02e4269211
12 changed files with 1391 additions and 1221 deletions

View File

@ -1014,6 +1014,7 @@ nintendo/mario.cpp
nintendo/mmagic.cpp
nintendo/multigam.cpp
nintendo/n8080.cpp
nintendo/nes_arcade_bl.cpp
nintendo/nss.cpp
nintendo/playch10.cpp
nintendo/popeye.cpp

View File

@ -33391,6 +33391,9 @@ m82p // Nintendo M82 Display Unit PAL
nes // Nintendo Entertainment System
nespal // Nintendo Entertainment System PAL
@source:nintendo/nes_arcade_bl.cpp
smb3bl
@source:nintendo/nes_clone.cpp
afbm7800
dancexpt

View File

@ -1,5 +1,6 @@
// license:BSD-3-Clause
// copyright-holders:Paul Priest, David Haywood
// copyright-holders: Paul Priest, David Haywood
/******************************************************************************
'Face' LINDA board
@ -66,8 +67,8 @@ NOS-B0-01.U59 \ Background (separate for each 038 chip?)
NOS-B1-00.U60 /
NOS-B1-01.U61-
YMF286-K is compatible to YM2610 - see psikyo.c driver
038 9320EX702 / 038 9330EX705 - see Cave.c driver
YMF286-K is compatible to YM2610 - see psikyo/psikyo.cpp driver
038 9320EX702 / 038 9330EX705 - see misc/cave.cpp driver
Note # = Pin #1 PCB Layout:
@ -124,9 +125,9 @@ Stephh's notes (based on the games M68000 code and some tests) :
*******************************************************************************
todo:
TODO:
Flip Screen
Fix Sprites & Rowscroll/Select for Cocktail
*******************************************************************************
@ -138,15 +139,299 @@ Stephh's notes (based on the games M68000 code and some tests) :
******************************************************************************/
#include "emu.h"
#include "mcatadv.h"
#include "cpu/m68000/m68000.h"
#include "cpu/z80/z80.h"
#include "machine/gen_latch.h"
#include "machine/watchdog.h"
#include "sound/ymopn.h"
#include "video/bufsprite.h"
#include "video/tmap038.h"
#include "emupal.h"
#include "screen.h"
#include "speaker.h"
#include <algorithm>
// configurable logging
#define LOG_SPRITEBANK (1U << 1)
#define LOG_ROWSCROLL (1U << 2)
//#define VERBOSE (LOG_GENERAL | LOG_SPRITEBANK | LOG_ROWSCROLL)
#include "logmacro.h"
#define LOGSPRITEBANK(...) LOGMASKED(LOG_SPRITEBANK, __VA_ARGS__)
#define LOGROWSCROLL(...) LOGMASKED(LOG_ROWSCROLL, __VA_ARGS__)
namespace {
class mcatadv_state : public driver_device
{
public:
mcatadv_state(const machine_config &mconfig, device_type type, const char *tag)
: driver_device(mconfig, type, tag)
, m_sprdata(*this, "sprdata")
, m_soundbank(*this, "soundbank")
, m_maincpu(*this, "maincpu")
, m_soundcpu(*this, "soundcpu")
, m_watchdog(*this, "watchdog")
, m_gfxdecode(*this, "gfxdecode")
, m_palette(*this, "palette")
, m_tilemap(*this, "tilemap_%u", 0U)
, m_spriteram(*this, "spriteram")
, m_vidregs(*this, "vidregs")
{ }
void nost(machine_config &config);
void mcatadv(machine_config &config);
protected:
virtual void machine_start() override;
virtual void video_start() override;
private:
// memory pointers
required_region_ptr<u8> m_sprdata;
required_memory_bank m_soundbank;
// video-related
u8 m_palette_bank[2] = {};
// devices
required_device<cpu_device> m_maincpu;
required_device<cpu_device> m_soundcpu;
required_device<watchdog_timer_device> m_watchdog;
required_device<gfxdecode_device> m_gfxdecode;
required_device<palette_device> m_palette;
required_device_array<tilemap038_device, 2> m_tilemap;
required_device<buffered_spriteram16_device> m_spriteram;
required_device<buffered_spriteram16_device> m_vidregs;
u16 mcatadv_wd_r(); // mcatadv only
void sound_banking_w(u8 data);
template<int Chip> void get_banked_color(bool tiledim, u32 &color, u32 &pri, u32 &code);
u32 screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect);
DECLARE_WRITE_LINE_MEMBER(screen_vblank);
void draw_sprites(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect);
void draw_tilemap_part(screen_device &screen, int layer, int i, bitmap_ind16 &bitmap, const rectangle &cliprect);
void main_map(address_map &map);
void mcatadv_sound_io_map(address_map &map);
void mcatadv_sound_map(address_map &map);
void nost_sound_io_map(address_map &map);
void nost_sound_map(address_map &map);
};
// video
void mcatadv_state::draw_sprites(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
{
u16 *source = (m_spriteram->buffer() + (m_spriteram->bytes() / 2) /2);
source -= 4;
u16 *finish = m_spriteram->buffer();
int const global_x = m_vidregs->live()[0] - 0x184;
int const global_y = m_vidregs->live()[1] - 0x1f1;
u32 const sprmask = m_sprdata.bytes() - 1;
int xstart, xend, xinc;
int ystart, yend, yinc;
if (m_vidregs->buffer()[2] == 0x0001) // double buffered
{
source += (m_spriteram->bytes() / 2) / 2;
finish += (m_spriteram->bytes() / 2) / 2;
}
else if (m_vidregs->buffer()[2]) // I suppose it's possible that there is 4 banks, haven't seen it used though
{
LOGSPRITEBANK("Spritebank != 0/1\n");
}
while (source >= finish)
{
u32 const pen = (source[0] & 0x3f00) >> 8;
u32 const tileno = source[1] & 0xffff;
u8 pri = (source[0] & 0xc000) >> 14;
pri |= 0x8;
int x = source[2] & 0x3ff;
int y = source[3] & 0x3ff;
int flipy = source[0] & 0x0040;
int flipx = source[0] & 0x0080;
int const height = ((source[3] & 0xf000) >> 12) * 16;
int const width = ((source[2] & 0xf000) >> 12) * 16;
u32 offset = tileno * 256;
if (x & 0x200) x -= 0x400;
if (y & 0x200) y -= 0x400;
#if 0 // For Flipscreen/Cocktail
if (m_vidregs->live()[0] & 0x8000)
{
flipx = !flipx;
}
if (m_vidregs->live()[1] & 0x8000)
{
flipy = !flipy;
}
#endif
if (source[3] != source[0]) // 'hack' don't draw sprites while it's testing the RAM!
{
if (!flipx) { xstart = 0; xend = width; xinc = 1; }
else { xstart = width-1; xend = -1; xinc = -1; }
if (!flipy) { ystart = 0; yend = height; yinc = 1; }
else { ystart = height-1; yend = -1; yinc = -1; }
for (int ycnt = ystart; ycnt != yend; ycnt += yinc)
{
const int drawypos = y + ycnt - global_y;
if ((drawypos >= cliprect.min_y) && (drawypos <= cliprect.max_y))
{
u16 *const destline = &bitmap.pix(drawypos);
u8 *const priline = &screen.priority().pix(drawypos);
for (int xcnt = xstart; xcnt != xend; xcnt += xinc)
{
const int drawxpos = x + xcnt - global_x;
if ((drawxpos >= cliprect.min_x) && (drawxpos <= cliprect.max_x))
{
const int pridata = priline[drawxpos];
if (!(pridata & 0x10)) // if we haven't already drawn a sprite pixel here (sprite masking)
{
u8 pix = m_sprdata[(offset / 2)&sprmask];
if (offset & 1)
pix = pix >> 4;
pix &= 0x0f;
if (pix)
{
if ((priline[drawxpos] < pri))
destline[drawxpos] = (pix + (pen << 4));
priline[drawxpos] |= 0x10;
}
}
}
offset++;
}
}
else
{
offset += width;
}
}
}
source -= 4;
}
}
void mcatadv_state::draw_tilemap_part(screen_device &screen, int layer, int i, bitmap_ind16 &bitmap, const rectangle &cliprect)
{
if (!m_tilemap[layer]->enable())
return;
rectangle clip;
clip.min_x = cliprect.min_x;
clip.max_x = cliprect.max_x;
for (u32 drawline = cliprect.min_y; drawline <= cliprect.max_y; drawline++)
{
clip.min_y = drawline;
clip.max_y = drawline;
int scrollx = (m_tilemap[layer]->scrollx() & 0x1ff) - 0x194;
int scrolly = (m_tilemap[layer]->scrolly() & 0x1ff) - 0x1df;
if (m_tilemap[layer]->rowselect_en())
{
const int rowselect = m_tilemap[layer]->rowselect(drawline + scrolly);
scrolly = rowselect - drawline;
}
if (m_tilemap[layer]->rowscroll_en())
{
const int rowscroll = m_tilemap[layer]->rowscroll(drawline + scrolly);
scrollx += rowscroll;
}
// global flip
if (m_tilemap[layer]->flipx()) scrollx -= 0x19;
if (m_tilemap[layer]->flipy()) scrolly -= 0x141;
int flip = (m_tilemap[layer]->flipx() ? TILEMAP_FLIPX : 0) | (m_tilemap[layer]->flipy() ? TILEMAP_FLIPY : 0);
m_tilemap[layer]->set_scrollx(0, scrollx);
m_tilemap[layer]->set_scrolly(0, scrolly);
m_tilemap[layer]->set_flip(flip);
m_tilemap[layer]->draw(screen, bitmap, clip, i, i);
}
}
u32 mcatadv_state::screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
{
bitmap.fill(0x3f0, cliprect);
screen.priority().fill(0, cliprect);
for (int i = 0; i < 2; i++)
{
m_tilemap[i]->prepare();
if (m_tilemap[i]->external() != m_palette_bank[i])
{
m_palette_bank[i] = m_tilemap[i]->external() & 0xf;
m_tilemap[i]->mark_all_dirty();
}
}
LOGROWSCROLL("%02x %02x %02x %02x",
m_tilemap[0]->rowscroll_en(),
m_tilemap[0]->rowselect_en(),
m_tilemap[1]->rowscroll_en(),
m_tilemap[1]->rowselect_en());
for (int i = 0; i <= 3; i++)
{
#ifdef MAME_DEBUG
if (!machine().input().code_pressed(KEYCODE_Q))
#endif
draw_tilemap_part(screen, 0, i | 0x8, bitmap, cliprect);
#ifdef MAME_DEBUG
if (!machine().input().code_pressed(KEYCODE_W))
#endif
draw_tilemap_part(screen, 1, i | 0x8, bitmap, cliprect);
}
g_profiler.start(PROFILER_USER1);
#ifdef MAME_DEBUG
if (!machine().input().code_pressed(KEYCODE_E))
#endif
draw_sprites(screen, bitmap, cliprect);
g_profiler.stop();
return 0;
}
void mcatadv_state::video_start()
{
m_palette_bank[0] = m_palette_bank[1] = 0;
}
// machine
template<int Chip>
void mcatadv_state::get_banked_color(bool tiledim, u32 &color, u32 &pri, u32 &code)
@ -167,7 +452,7 @@ void mcatadv_state::mcat_coin_w(u8 data)
}
#endif
u16 mcatadv_state::mcat_wd_r()
u16 mcatadv_state::mcatadv_wd_r()
{
if (!machine().side_effects_disabled())
m_watchdog->watchdog_reset();
@ -175,7 +460,7 @@ u16 mcatadv_state::mcat_wd_r()
}
void mcatadv_state::mcatadv_map(address_map &map)
void mcatadv_state::main_map(address_map &map)
{
map(0x000000, 0x0fffff).rom();
map(0x100000, 0x10ffff).ram();
@ -185,8 +470,8 @@ void mcatadv_state::mcatadv_map(address_map &map)
map(0x200000, 0x200005).rw(m_tilemap[0], FUNC(tilemap038_device::vregs_r), FUNC(tilemap038_device::vregs_w));
map(0x300000, 0x300005).rw(m_tilemap[1], FUNC(tilemap038_device::vregs_r), FUNC(tilemap038_device::vregs_w));
map(0x400000, 0x401fff).m(m_tilemap[0], FUNC(tilemap038_device::vram_16x16_map)); // Tilemap 0
map(0x500000, 0x501fff).m(m_tilemap[1], FUNC(tilemap038_device::vram_16x16_map)); // Tilemap 1
map(0x400000, 0x401fff).m(m_tilemap[0], FUNC(tilemap038_device::vram_16x16_map));
map(0x500000, 0x501fff).m(m_tilemap[1], FUNC(tilemap038_device::vram_16x16_map));
map(0x600000, 0x601fff).ram().w(m_palette, FUNC(palette_device::write16)).share("palette");
map(0x602000, 0x602fff).ram(); // Bigger than needs to be?
@ -203,14 +488,14 @@ void mcatadv_state::mcatadv_map(address_map &map)
map(0xb00000, 0xb0000f).ram().share("vidregs");
map(0xb00018, 0xb00019).w(m_watchdog, FUNC(watchdog_timer_device::reset16_w)); // NOST Only
map(0xb0001e, 0xb0001f).r(FUNC(mcatadv_state::mcat_wd_r)); // MCAT Only
map(0xb0001e, 0xb0001f).r(FUNC(mcatadv_state::mcatadv_wd_r)); // MCAT Only
map(0xc00001, 0xc00001).r("soundlatch2", FUNC(generic_latch_8_device::read));
map(0xc00000, 0xc00001).w("soundlatch", FUNC(generic_latch_8_device::write)).umask16(0x00ff).cswidth(16);
}
/*** Sound ***/
void mcatadv_state::mcatadv_sound_bw_w(u8 data)
void mcatadv_state::sound_banking_w(u8 data)
{
m_soundbank->set_entry(data);
}
@ -218,11 +503,11 @@ void mcatadv_state::mcatadv_sound_bw_w(u8 data)
void mcatadv_state::mcatadv_sound_map(address_map &map)
{
map(0x0000, 0x3fff).rom(); // ROM
map(0x4000, 0xbfff).bankr("soundbank"); // ROM
map(0xc000, 0xdfff).ram(); // RAM
map(0x0000, 0x3fff).rom();
map(0x4000, 0xbfff).bankr(m_soundbank);
map(0xc000, 0xdfff).ram();
map(0xe000, 0xe003).rw("ymsnd", FUNC(ym2610_device::read), FUNC(ym2610_device::write));
map(0xf000, 0xf000).w(FUNC(mcatadv_state::mcatadv_sound_bw_w));
map(0xf000, 0xf000).w(FUNC(mcatadv_state::sound_banking_w));
}
void mcatadv_state::mcatadv_sound_io_map(address_map &map)
@ -234,9 +519,9 @@ void mcatadv_state::mcatadv_sound_io_map(address_map &map)
void mcatadv_state::nost_sound_map(address_map &map)
{
map(0x0000, 0x7fff).rom(); // ROM
map(0x8000, 0xbfff).bankr("soundbank"); // ROM
map(0xc000, 0xdfff).ram(); // RAM
map(0x0000, 0x7fff).rom();
map(0x8000, 0xbfff).bankr(m_soundbank);
map(0xc000, 0xdfff).ram();
}
void mcatadv_state::nost_sound_io_map(address_map &map)
@ -244,7 +529,7 @@ void mcatadv_state::nost_sound_io_map(address_map &map)
map.global_mask(0xff);
map(0x00, 0x03).w("ymsnd", FUNC(ym2610_device::write));
map(0x04, 0x07).r("ymsnd", FUNC(ym2610_device::read));
map(0x40, 0x40).w(FUNC(mcatadv_state::mcatadv_sound_bw_w));
map(0x40, 0x40).w(FUNC(mcatadv_state::sound_banking_w));
map(0x80, 0x80).r("soundlatch", FUNC(generic_latch_8_device::read)).w("soundlatch2", FUNC(generic_latch_8_device::write));
}
@ -325,8 +610,8 @@ static INPUT_PORTS_START( mcatadv )
PORT_DIPNAME( 0xc000, 0xc000, DEF_STR( Cabinet ) ) PORT_DIPLOCATION("SW2:7,8")
PORT_DIPSETTING( 0x4000, "Upright 1 Player" )
PORT_DIPSETTING( 0xc000, "Upright 2 Players" )
PORT_DIPSETTING( 0x0000, "Upright 2 Players" ) // duplicated setting (NEVER tested)
PORT_DIPSETTING( 0x8000, DEF_STR( Cocktail ) )
// PORT_DIPSETTING( 0x0000, "Upright 2 Players" ) // duplicated setting (NEVER tested)
INPUT_PORTS_END
static INPUT_PORTS_START( nost )
@ -399,7 +684,7 @@ static INPUT_PORTS_START( nost )
PORT_DIPSETTING( 0x1800, DEF_STR( 2C_3C ) )
PORT_DIPSETTING( 0x3000, DEF_STR( 1C_2C ) )
PORT_DIPSETTING( 0x2800, DEF_STR( 1C_3C ) )
PORT_DIPUNUSED_DIPLOC( 0x4000, 0x4000, "SW2:7" ) /* Listed as "Unused" */
PORT_DIPUNUSED_DIPLOC( 0x4000, 0x4000, "SW2:7" ) // Listed as "Unused"
PORT_SERVICE_DIPLOC( 0x8000, IP_ACTIVE_LOW, "SW2:8" )
INPUT_PORTS_END
@ -413,7 +698,7 @@ GFXDECODE_END
void mcatadv_state::machine_start()
{
const u32 max = memregion("soundcpu")->bytes()/0x4000;
const u32 max = memregion("soundcpu")->bytes() / 0x4000;
m_soundbank->configure_entries(0, max, memregion("soundcpu")->base(), 0x4000);
m_soundbank->set_entry(1);
@ -423,27 +708,28 @@ void mcatadv_state::machine_start()
void mcatadv_state::mcatadv(machine_config &config)
{
/* basic machine hardware */
M68000(config, m_maincpu, XTAL(16'000'000)); /* verified on pcb */
m_maincpu->set_addrmap(AS_PROGRAM, &mcatadv_state::mcatadv_map);
// basic machine hardware
M68000(config, m_maincpu, XTAL(16'000'000)); // verified on PCB
m_maincpu->set_addrmap(AS_PROGRAM, &mcatadv_state::main_map);
m_maincpu->set_vblank_int("screen", FUNC(mcatadv_state::irq1_line_hold));
Z80(config, m_soundcpu, XTAL(16'000'000)/4); /* verified on pcb */
Z80(config, m_soundcpu, XTAL(16'000'000) / 4); // verified on PCB
m_soundcpu->set_addrmap(AS_PROGRAM, &mcatadv_state::mcatadv_sound_map);
m_soundcpu->set_addrmap(AS_IO, &mcatadv_state::mcatadv_sound_io_map);
/* video hardware */
// 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(320, 256);
screen.set_visarea(0, 320-1, 0, 224-1);
screen.set_screen_update(FUNC(mcatadv_state::screen_update_mcatadv));
screen.screen_vblank().set(FUNC(mcatadv_state::screen_vblank_mcatadv));
screen.set_screen_update(FUNC(mcatadv_state::screen_update));
screen.screen_vblank().set(m_spriteram, FUNC(buffered_spriteram16_device::vblank_copy_rising));
screen.screen_vblank().append(m_vidregs, FUNC(buffered_spriteram16_device::vblank_copy_rising));
screen.set_palette(m_palette);
GFXDECODE(config, m_gfxdecode, m_palette, gfx_mcatadv);
PALETTE(config, m_palette).set_format(palette_device::xGRB_555, 0x2000/2);
PALETTE(config, m_palette).set_format(palette_device::xGRB_555, 0x2000 / 2);
TMAP038(config, m_tilemap[0]);
m_tilemap[0]->set_gfxdecode_tag(m_gfxdecode);
@ -455,16 +741,20 @@ void mcatadv_state::mcatadv(machine_config &config)
m_tilemap[1]->set_gfx(1);
m_tilemap[1]->set_tile_callback(FUNC(mcatadv_state::get_banked_color<1>));
WATCHDOG_TIMER(config, m_watchdog).set_time(attotime::from_seconds(3)); /* a guess, and certainly wrong */
BUFFERED_SPRITERAM16(config, m_spriteram);
/* sound hardware */
BUFFERED_SPRITERAM16(config, m_vidregs);
WATCHDOG_TIMER(config, m_watchdog).set_time(attotime::from_seconds(3)); // a guess, and certainly wrong
// sound hardware
SPEAKER(config, "mono").front_center();
GENERIC_LATCH_8(config, "soundlatch").data_pending_callback().set_inputline(m_soundcpu, INPUT_LINE_NMI);
GENERIC_LATCH_8(config, "soundlatch2");
ym2610_device &ymsnd(YM2610(config, "ymsnd", XTAL(16'000'000)/2)); /* verified on pcb */
ym2610_device &ymsnd(YM2610(config, "ymsnd", XTAL(16'000'000) / 2)); // verified on PCB
ymsnd.irq_handler().set_inputline(m_soundcpu, 0);
ymsnd.add_route(0, "mono", 0.32);
ymsnd.add_route(1, "mono", 0.5);
@ -478,7 +768,7 @@ void mcatadv_state::nost(machine_config &config)
m_soundcpu->set_addrmap(AS_PROGRAM, &mcatadv_state::nost_sound_map);
m_soundcpu->set_addrmap(AS_IO, &mcatadv_state::nost_sound_io_map);
ym2610_device &ymsnd(YM2610(config.replace(), "ymsnd", XTAL(16'000'000)/2)); /* verified on pcb */
ym2610_device &ymsnd(YM2610(config.replace(), "ymsnd", XTAL(16'000'000) / 2)); // verified on PCB
ymsnd.irq_handler().set_inputline(m_soundcpu, 0);
ymsnd.add_route(0, "mono", 0.2);
ymsnd.add_route(1, "mono", 0.5);
@ -487,14 +777,14 @@ void mcatadv_state::nost(machine_config &config)
ROM_START( mcatadv )
ROM_REGION( 0x100000, "maincpu", 0 ) /* M68000 */
ROM_REGION( 0x100000, "maincpu", 0 ) // M68000
ROM_LOAD16_BYTE( "mca-u30e", 0x00000, 0x80000, CRC(c62fbb65) SHA1(39a30a165d4811141db8687a4849626bef8e778e) )
ROM_LOAD16_BYTE( "mca-u29e", 0x00001, 0x80000, CRC(cf21227c) SHA1(4012811ebfe3c709ab49946f8138bc4bad881ef7) )
ROM_REGION( 0x020000, "soundcpu", 0 ) /* Z80-A */
ROM_REGION( 0x020000, "soundcpu", 0 ) // Z80-A
ROM_LOAD( "u9.bin", 0x00000, 0x20000, CRC(fda05171) SHA1(2c69292573ec35034572fa824c0cae2839d23919) )
ROM_REGION( 0x800000, "sprdata", ROMREGION_ERASEFF ) /* Sprites */
ROM_REGION( 0x800000, "sprdata", ROMREGION_ERASEFF )
ROM_LOAD16_BYTE( "mca-u82.bin", 0x000000, 0x100000, CRC(5f01d746) SHA1(11b241456e15299912ee365eedb8f9d5e5ca875d) )
ROM_LOAD16_BYTE( "mca-u83.bin", 0x000001, 0x100000, CRC(4e1be5a6) SHA1(cb19aad42dba54d6a4a33859f27254c2a3271e8c) )
ROM_LOAD16_BYTE( "mca-u84.bin", 0x200000, 0x080000, CRC(df202790) SHA1(f6ae54e799af195860ed0ab3c85138cf2f10efa6) )
@ -502,27 +792,27 @@ ROM_START( mcatadv )
ROM_LOAD16_BYTE( "mca-u86e", 0x400000, 0x080000, CRC(017bf1da) SHA1(f6446a7219275c0eff62129f59fdfa3a6a3e06c8) )
ROM_LOAD16_BYTE( "mca-u87e", 0x400001, 0x080000, CRC(bc9dc9b9) SHA1(f525c9f994d5107752aa4d3a499ee376ec75f42b) )
ROM_REGION( 0x080000, "bg0", 0 ) /* BG0 */
ROM_REGION( 0x080000, "bg0", 0 )
ROM_LOAD( "mca-u58.bin", 0x000000, 0x080000, CRC(3a8186e2) SHA1(129c220d72608a8839f779ce1a6cfec8646dbf23) )
ROM_REGION( 0x280000, "bg1", 0 ) /* BG1 */
ROM_REGION( 0x280000, "bg1", 0 )
ROM_LOAD( "mca-u60.bin", 0x000000, 0x100000, CRC(c8942614) SHA1(244fccb9abbb04e33839dd2cd0e2de430819a18c) )
ROM_LOAD( "mca-u61.bin", 0x100000, 0x100000, CRC(51af66c9) SHA1(1055cf78ea286f02003b0d1bf08c2d7829b36f90) )
ROM_LOAD( "mca-u100", 0x200000, 0x080000, CRC(b273f1b0) SHA1(39318fe2aaf2792b85426ec6791b3360ac964de3) )
ROM_REGION( 0x80000, "ymsnd:adpcma", 0 ) /* Samples */
ROM_REGION( 0x80000, "ymsnd:adpcma", 0 )
ROM_LOAD( "mca-u53.bin", 0x00000, 0x80000, CRC(64c76e05) SHA1(379cef5e0cba78d0e886c9cede41985850a3afb7) )
ROM_END
ROM_START( mcatadvj )
ROM_REGION( 0x100000, "maincpu", 0 ) /* M68000 */
ROM_REGION( 0x100000, "maincpu", 0 ) // M68000
ROM_LOAD16_BYTE( "u30.bin", 0x00000, 0x80000, CRC(05762f42) SHA1(3675fb606bf9d7be9462324e68263f4a6c2fea1c) )
ROM_LOAD16_BYTE( "u29.bin", 0x00001, 0x80000, CRC(4c59d648) SHA1(2ab77ea254f2c11fc016078cedcab2fffbe5ee1b) )
ROM_REGION( 0x020000, "soundcpu", 0 ) /* Z80-A */
ROM_REGION( 0x020000, "soundcpu", 0 ) // Z80-A
ROM_LOAD( "u9.bin", 0x00000, 0x20000, CRC(fda05171) SHA1(2c69292573ec35034572fa824c0cae2839d23919) )
ROM_REGION( 0x800000, "sprdata", ROMREGION_ERASEFF ) /* Sprites */
ROM_REGION( 0x800000, "sprdata", ROMREGION_ERASEFF )
ROM_LOAD16_BYTE( "mca-u82.bin", 0x000000, 0x100000, CRC(5f01d746) SHA1(11b241456e15299912ee365eedb8f9d5e5ca875d) )
ROM_LOAD16_BYTE( "mca-u83.bin", 0x000001, 0x100000, CRC(4e1be5a6) SHA1(cb19aad42dba54d6a4a33859f27254c2a3271e8c) )
ROM_LOAD16_BYTE( "mca-u84.bin", 0x200000, 0x080000, CRC(df202790) SHA1(f6ae54e799af195860ed0ab3c85138cf2f10efa6) )
@ -530,27 +820,27 @@ ROM_START( mcatadvj )
ROM_LOAD16_BYTE( "u86.bin", 0x400000, 0x080000, CRC(2d3725ed) SHA1(8b4c0f280eb901113d842848ffc26371be7b6067) )
ROM_LOAD16_BYTE( "u87.bin", 0x400001, 0x080000, CRC(4ddefe08) SHA1(5ade0a694d73f4f3891c1ab7757e37a88afcbf54) )
ROM_REGION( 0x080000, "bg0", 0 ) /* BG0 */
ROM_REGION( 0x080000, "bg0", 0 )
ROM_LOAD( "mca-u58.bin", 0x000000, 0x080000, CRC(3a8186e2) SHA1(129c220d72608a8839f779ce1a6cfec8646dbf23) )
ROM_REGION( 0x280000, "bg1", 0 ) /* BG1 */
ROM_REGION( 0x280000, "bg1", 0 )
ROM_LOAD( "mca-u60.bin", 0x000000, 0x100000, CRC(c8942614) SHA1(244fccb9abbb04e33839dd2cd0e2de430819a18c) )
ROM_LOAD( "mca-u61.bin", 0x100000, 0x100000, CRC(51af66c9) SHA1(1055cf78ea286f02003b0d1bf08c2d7829b36f90) )
ROM_LOAD( "u100.bin", 0x200000, 0x080000, CRC(e2c311da) SHA1(cc3217484524de94704869eaa9ce1b90393039d8) )
ROM_REGION( 0x80000, "ymsnd:adpcma", 0 ) /* Samples */
ROM_REGION( 0x80000, "ymsnd:adpcma", 0 )
ROM_LOAD( "mca-u53.bin", 0x00000, 0x80000, CRC(64c76e05) SHA1(379cef5e0cba78d0e886c9cede41985850a3afb7) )
ROM_END
ROM_START( catt )
ROM_REGION( 0x100000, "maincpu", 0 ) /* M68000 */
ROM_REGION( 0x100000, "maincpu", 0 ) // M68000
ROM_LOAD16_BYTE( "catt-u30.bin", 0x00000, 0x80000, CRC(8c921e1e) SHA1(2fdaa9b743e1731f3cfe9d8334f1b759cf46855d) )
ROM_LOAD16_BYTE( "catt-u29.bin", 0x00001, 0x80000, CRC(e725af6d) SHA1(78c08fa5744a6a953e13c0ff39736ccd4875fb72) )
ROM_REGION( 0x020000, "soundcpu", 0 ) /* Z80-A */
ROM_REGION( 0x020000, "soundcpu", 0 ) // Z80-A
ROM_LOAD( "u9.bin", 0x00000, 0x20000, CRC(fda05171) SHA1(2c69292573ec35034572fa824c0cae2839d23919) )
ROM_REGION( 0x800000, "sprdata", ROMREGION_ERASEFF ) /* Sprites */
ROM_REGION( 0x800000, "sprdata", ROMREGION_ERASEFF )
ROM_LOAD16_BYTE( "mca-u82.bin", 0x000000, 0x100000, CRC(5f01d746) SHA1(11b241456e15299912ee365eedb8f9d5e5ca875d) )
ROM_LOAD16_BYTE( "mca-u83.bin", 0x000001, 0x100000, CRC(4e1be5a6) SHA1(cb19aad42dba54d6a4a33859f27254c2a3271e8c) )
ROM_LOAD16_BYTE( "u84.bin", 0x200000, 0x100000, CRC(843fd624) SHA1(2e16d8a909fe9447da37a87428bff0734af59a00) )
@ -558,15 +848,15 @@ ROM_START( catt )
ROM_LOAD16_BYTE( "mca-u86e", 0x400000, 0x080000, CRC(017bf1da) SHA1(f6446a7219275c0eff62129f59fdfa3a6a3e06c8) )
ROM_LOAD16_BYTE( "mca-u87e", 0x400001, 0x080000, CRC(bc9dc9b9) SHA1(f525c9f994d5107752aa4d3a499ee376ec75f42b) )
ROM_REGION( 0x100000, "bg0", 0 ) /* BG0 */
ROM_REGION( 0x100000, "bg0", 0 )
ROM_LOAD( "u58.bin", 0x00000, 0x100000, CRC(73c9343a) SHA1(9efdddbad6244c1ed267bd954563ab43a1017c96) )
ROM_REGION( 0x280000, "bg1", 0 ) /* BG1 */
ROM_REGION( 0x280000, "bg1", 0 )
ROM_LOAD( "mca-u60.bin", 0x000000, 0x100000, CRC(c8942614) SHA1(244fccb9abbb04e33839dd2cd0e2de430819a18c) )
ROM_LOAD( "mca-u61.bin", 0x100000, 0x100000, CRC(51af66c9) SHA1(1055cf78ea286f02003b0d1bf08c2d7829b36f90) )
ROM_LOAD( "mca-u100", 0x200000, 0x080000, CRC(b273f1b0) SHA1(39318fe2aaf2792b85426ec6791b3360ac964de3) )
ROM_REGION( 0x100000, "ymsnd:adpcma", 0 ) /* Samples */
ROM_REGION( 0x100000, "ymsnd:adpcma", 0 )
ROM_LOAD( "u53.bin", 0x00000, 0x100000, CRC(99f2a624) SHA1(799e8e40e8bdcc8fa4cd763a366cc32473038a49) )
ROM_REGION( 0x0400, "plds", 0 )
@ -575,14 +865,14 @@ ROM_START( catt )
ROM_END
ROM_START( nost )
ROM_REGION( 0x100000, "maincpu", 0 ) /* M68000 */
ROM_REGION( 0x100000, "maincpu", 0 ) // M68000
ROM_LOAD16_BYTE( "nos-pe-u.bin", 0x00000, 0x80000, CRC(4b080149) SHA1(e1dbbe5bf554c7c5731cc3079850f257417e3caa) )
ROM_LOAD16_BYTE( "nos-po-u.bin", 0x00001, 0x80000, CRC(9e3cd6d9) SHA1(db5351ff9a05f602eceae62c0051c16ae0e4ead9) )
ROM_REGION( 0x040000, "soundcpu", 0 ) /* Z80-A */
ROM_REGION( 0x040000, "soundcpu", 0 ) // Z80-A
ROM_LOAD( "nos-ps.u9", 0x00000, 0x40000, CRC(832551e9) SHA1(86fc481b1849f378c88593594129197c69ea1359) )
ROM_REGION( 0x800000, "sprdata", ROMREGION_ERASEFF ) /* Sprites */
ROM_REGION( 0x800000, "sprdata", ROMREGION_ERASEFF )
ROM_LOAD16_BYTE( "nos-se-0.u82", 0x000000, 0x100000, CRC(9d99108d) SHA1(466540989d7b1b7f6dc7acbae74f6a8201973d45) )
ROM_LOAD16_BYTE( "nos-so-0.u83", 0x000001, 0x100000, CRC(7df0fc7e) SHA1(2e064cb5367b2839d736d339c4f1a44785b4eedf) )
ROM_LOAD16_BYTE( "nos-se-1.u84", 0x200000, 0x100000, CRC(aad07607) SHA1(89c51a9cb6b8d8ed3a357f5d8ac8399ff1c7ad46) )
@ -590,27 +880,27 @@ ROM_START( nost )
ROM_LOAD16_BYTE( "nos-se-2.u86", 0x400000, 0x080000, CRC(d99e6005) SHA1(49aae72111334ff5cd0fd86500882f559ff921f9) )
ROM_LOAD16_BYTE( "nos-so-2.u87", 0x400001, 0x080000, CRC(f60e8ef3) SHA1(4f7472b5a465e6cc6a5df520ebfe6a544739dd28) )
ROM_REGION( 0x180000, "bg0", 0 ) /* BG0 */
ROM_REGION( 0x180000, "bg0", 0 )
ROM_LOAD( "nos-b0-0.u58", 0x000000, 0x100000, CRC(0214b0f2) SHA1(678fa3dc739323bda6d7bbb1c7a573c976d69356) )
ROM_LOAD( "nos-b0-1.u59", 0x100000, 0x080000, CRC(3f8b6b34) SHA1(94c48614782ce6405965bcf6029e3bcc24a6d84f) )
ROM_REGION( 0x180000, "bg1", 0 ) /* BG1 */
ROM_REGION( 0x180000, "bg1", 0 )
ROM_LOAD( "nos-b1-0.u60", 0x000000, 0x100000, CRC(ba6fd0c7) SHA1(516d6e0c4dc6fb12ec9f30877ea1c582e7440a19) )
ROM_LOAD( "nos-b1-1.u61", 0x100000, 0x080000, CRC(dabd8009) SHA1(1862645b8d6216c3ec2b8dbf74816b8e29dea14f) )
ROM_REGION( 0x100000, "ymsnd:adpcma", 0 ) /* Samples */
ROM_REGION( 0x100000, "ymsnd:adpcma", 0 )
ROM_LOAD( "nossn-00.u53", 0x00000, 0x100000, CRC(3bd1bcbc) SHA1(1bcad43792e985402db4eca122676c2c555f3313) )
ROM_END
ROM_START( nostj )
ROM_REGION( 0x100000, "maincpu", 0 ) /* M68000 */
ROM_REGION( 0x100000, "maincpu", 0 ) // M68000
ROM_LOAD16_BYTE( "nos-pe-j.u30", 0x00000, 0x80000, CRC(4b080149) SHA1(e1dbbe5bf554c7c5731cc3079850f257417e3caa) )
ROM_LOAD16_BYTE( "nos-po-j.u29", 0x00001, 0x80000, CRC(7fe241de) SHA1(aa4ffd81cb73efc59690c2038ae9375021a775a4) )
ROM_REGION( 0x040000, "soundcpu", 0 ) /* Z80-A */
ROM_REGION( 0x040000, "soundcpu", 0 ) // Z80-A
ROM_LOAD( "nos-ps.u9", 0x00000, 0x40000, CRC(832551e9) SHA1(86fc481b1849f378c88593594129197c69ea1359) )
ROM_REGION( 0x800000, "sprdata", ROMREGION_ERASEFF ) /* Sprites */
ROM_REGION( 0x800000, "sprdata", ROMREGION_ERASEFF )
ROM_LOAD16_BYTE( "nos-se-0.u82", 0x000000, 0x100000, CRC(9d99108d) SHA1(466540989d7b1b7f6dc7acbae74f6a8201973d45) )
ROM_LOAD16_BYTE( "nos-so-0.u83", 0x000001, 0x100000, CRC(7df0fc7e) SHA1(2e064cb5367b2839d736d339c4f1a44785b4eedf) )
ROM_LOAD16_BYTE( "nos-se-1.u84", 0x200000, 0x100000, CRC(aad07607) SHA1(89c51a9cb6b8d8ed3a357f5d8ac8399ff1c7ad46) )
@ -618,27 +908,27 @@ ROM_START( nostj )
ROM_LOAD16_BYTE( "nos-se-2.u86", 0x400000, 0x080000, CRC(d99e6005) SHA1(49aae72111334ff5cd0fd86500882f559ff921f9) )
ROM_LOAD16_BYTE( "nos-so-2.u87", 0x400001, 0x080000, CRC(f60e8ef3) SHA1(4f7472b5a465e6cc6a5df520ebfe6a544739dd28) )
ROM_REGION( 0x180000, "bg0", 0 ) /* BG0 */
ROM_REGION( 0x180000, "bg0", 0 )
ROM_LOAD( "nos-b0-0.u58", 0x000000, 0x100000, CRC(0214b0f2) SHA1(678fa3dc739323bda6d7bbb1c7a573c976d69356) )
ROM_LOAD( "nos-b0-1.u59", 0x100000, 0x080000, CRC(3f8b6b34) SHA1(94c48614782ce6405965bcf6029e3bcc24a6d84f) )
ROM_REGION( 0x180000, "bg1", 0 ) /* BG1 */
ROM_REGION( 0x180000, "bg1", 0 )
ROM_LOAD( "nos-b1-0.u60", 0x000000, 0x100000, CRC(ba6fd0c7) SHA1(516d6e0c4dc6fb12ec9f30877ea1c582e7440a19) )
ROM_LOAD( "nos-b1-1.u61", 0x100000, 0x080000, CRC(dabd8009) SHA1(1862645b8d6216c3ec2b8dbf74816b8e29dea14f) )
ROM_REGION( 0x100000, "ymsnd:adpcma", 0 ) /* Samples */
ROM_REGION( 0x100000, "ymsnd:adpcma", 0 )
ROM_LOAD( "nossn-00.u53", 0x00000, 0x100000, CRC(3bd1bcbc) SHA1(1bcad43792e985402db4eca122676c2c555f3313) )
ROM_END
ROM_START( nostk )
ROM_REGION( 0x100000, "maincpu", 0 ) /* M68000 */
ROM_REGION( 0x100000, "maincpu", 0 ) // M68000
ROM_LOAD16_BYTE( "nos-pe-t.u30", 0x00000, 0x80000, CRC(bee5fbc8) SHA1(a8361fa004bb31471f973ece51a9a87b9f3438ab) )
ROM_LOAD16_BYTE( "nos-po-t.u29", 0x00001, 0x80000, CRC(f4736331) SHA1(7a6db2db1a4dbf105c22e15deff6f6032e04609c) )
ROM_REGION( 0x040000, "soundcpu", 0 ) /* Z80-A */
ROM_REGION( 0x040000, "soundcpu", 0 ) // Z80-A
ROM_LOAD( "nos-ps.u9", 0x00000, 0x40000, CRC(832551e9) SHA1(86fc481b1849f378c88593594129197c69ea1359) )
ROM_REGION( 0x800000, "sprdata", ROMREGION_ERASEFF ) /* Sprites */
ROM_REGION( 0x800000, "sprdata", ROMREGION_ERASEFF )
ROM_LOAD16_BYTE( "nos-se-0.u82", 0x000000, 0x100000, CRC(9d99108d) SHA1(466540989d7b1b7f6dc7acbae74f6a8201973d45) )
ROM_LOAD16_BYTE( "nos-so-0.u83", 0x000001, 0x100000, CRC(7df0fc7e) SHA1(2e064cb5367b2839d736d339c4f1a44785b4eedf) )
ROM_LOAD16_BYTE( "nos-se-1.u84", 0x200000, 0x100000, CRC(aad07607) SHA1(89c51a9cb6b8d8ed3a357f5d8ac8399ff1c7ad46) )
@ -646,18 +936,20 @@ ROM_START( nostk )
ROM_LOAD16_BYTE( "nos-se-2.u86", 0x400000, 0x080000, CRC(d99e6005) SHA1(49aae72111334ff5cd0fd86500882f559ff921f9) )
ROM_LOAD16_BYTE( "nos-so-2.u87", 0x400001, 0x080000, CRC(f60e8ef3) SHA1(4f7472b5a465e6cc6a5df520ebfe6a544739dd28) )
ROM_REGION( 0x180000, "bg0", 0 ) /* BG0 */
ROM_REGION( 0x180000, "bg0", 0 )
ROM_LOAD( "nos-b0-0.u58", 0x000000, 0x100000, CRC(0214b0f2) SHA1(678fa3dc739323bda6d7bbb1c7a573c976d69356) )
ROM_LOAD( "nos-b0-1.u59", 0x100000, 0x080000, CRC(3f8b6b34) SHA1(94c48614782ce6405965bcf6029e3bcc24a6d84f) )
ROM_REGION( 0x180000, "bg1", 0 ) /* BG1 */
ROM_REGION( 0x180000, "bg1", 0 )
ROM_LOAD( "nos-b1-0.u60", 0x000000, 0x100000, CRC(ba6fd0c7) SHA1(516d6e0c4dc6fb12ec9f30877ea1c582e7440a19) )
ROM_LOAD( "nos-b1-1.u61", 0x100000, 0x080000, CRC(dabd8009) SHA1(1862645b8d6216c3ec2b8dbf74816b8e29dea14f) )
ROM_REGION( 0x100000, "ymsnd:adpcma", 0 ) /* Samples */
ROM_REGION( 0x100000, "ymsnd:adpcma", 0 )
ROM_LOAD( "nossn-00.u53", 0x00000, 0x100000, CRC(3bd1bcbc) SHA1(1bcad43792e985402db4eca122676c2c555f3313) )
ROM_END
} // anonymous namespace
GAME( 1993, mcatadv, 0, mcatadv, mcatadv, mcatadv_state, empty_init, ROT0, "Wintechno", "Magical Cat Adventure", MACHINE_NO_COCKTAIL | MACHINE_SUPPORTS_SAVE )
GAME( 1993, mcatadvj, mcatadv, mcatadv, mcatadv, mcatadv_state, empty_init, ROT0, "Wintechno", "Magical Cat Adventure (Japan)", MACHINE_NO_COCKTAIL | MACHINE_SUPPORTS_SAVE )

View File

@ -1,70 +0,0 @@
// license:BSD-3-Clause
// copyright-holders:Paul Priest, David Haywood
#ifndef MAME_MISC_MCATADV_H
#define MAME_MISC_MCATADV_H
#pragma once
#include "machine/watchdog.h"
#include "video/tmap038.h"
#include "emupal.h"
class mcatadv_state : public driver_device
{
public:
mcatadv_state(const machine_config &mconfig, device_type type, const char *tag)
: driver_device(mconfig, type, tag)
, m_spriteram(*this, "spriteram")
, m_vidregs(*this, "vidregs")
, m_sprdata(*this, "sprdata")
, m_soundbank(*this, "soundbank")
, m_maincpu(*this, "maincpu")
, m_soundcpu(*this, "soundcpu")
, m_watchdog(*this, "watchdog")
, m_gfxdecode(*this, "gfxdecode")
, m_palette(*this, "palette")
, m_tilemap(*this, "tilemap_%u", 0U)
{ }
void nost(machine_config &config);
void mcatadv(machine_config &config);
private:
/* memory pointers */
required_shared_ptr<u16> m_spriteram;
std::unique_ptr<u16[]> m_spriteram_old;
required_shared_ptr<u16> m_vidregs;
std::unique_ptr<u16[]> m_vidregs_old;
required_region_ptr<u8> m_sprdata;
required_memory_bank m_soundbank;
/* video-related */
int m_palette_bank[2] = {};
/* devices */
required_device<cpu_device> m_maincpu;
required_device<cpu_device> m_soundcpu;
required_device<watchdog_timer_device> m_watchdog;
required_device<gfxdecode_device> m_gfxdecode;
required_device<palette_device> m_palette;
optional_device_array<tilemap038_device, 2> m_tilemap;
u16 mcat_wd_r();
void mcatadv_sound_bw_w(u8 data);
template<int Chip> void get_banked_color(bool tiledim, u32 &color, u32 &pri, u32 &code);
virtual void machine_start() override;
virtual void video_start() override;
u32 screen_update_mcatadv(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect);
DECLARE_WRITE_LINE_MEMBER(screen_vblank_mcatadv);
void draw_sprites( screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect );
void mcatadv_draw_tilemap_part( screen_device &screen, int layer, int i, bitmap_ind16 &bitmap, const rectangle &cliprect );
void mcatadv_map(address_map &map);
void mcatadv_sound_io_map(address_map &map);
void mcatadv_sound_map(address_map &map);
void nost_sound_io_map(address_map &map);
void nost_sound_map(address_map &map);
};
#endif // MAME_MISC_MCATADV_H

View File

@ -1,236 +0,0 @@
// license:BSD-3-Clause
// copyright-holders:Paul Priest, David Haywood
/* Magical Cat Adventure / Nostradamus Video Hardware */
/*
Notes:
Tilemap drawing is a killer on the first level of Nost due to the whole tilemap being dirty every frame.
Sprite drawing is quite fast (See USER1 in the profiler)
ToDo: Fix Sprites & Rowscroll/Select for Cocktail
*/
#include "emu.h"
#include "mcatadv.h"
#include "screen.h"
#include <algorithm>
void mcatadv_state::draw_sprites( screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect )
{
u16 *source = (m_spriteram_old.get() + (m_spriteram.bytes() / 2) /2);
source -= 4;
u16 *finish = m_spriteram_old.get();
int const global_x = m_vidregs[0] - 0x184;
int const global_y = m_vidregs[1] - 0x1f1;
u32 const sprmask = m_sprdata.bytes()-1;
int xstart, xend, xinc;
int ystart, yend, yinc;
if (m_vidregs_old[2] == 0x0001) /* Double Buffered */
{
source += (m_spriteram.bytes() / 2) / 2;
finish += (m_spriteram.bytes() / 2) / 2;
}
else if (m_vidregs_old[2]) /* I suppose it's possible that there is 4 banks, haven't seen it used though */
{
logerror("Spritebank != 0/1\n");
}
while (source >= finish)
{
u32 const pen = (source[0] & 0x3f00) >> 8;
u32 const tileno = source[1] & 0xffff;
u8 pri = (source[0] & 0xc000) >> 14;
pri |= 0x8;
int x = source[2] & 0x3ff;
int y = source[3] & 0x3ff;
int flipy = source[0] & 0x0040;
int flipx = source[0] & 0x0080;
int const height = ((source[3] & 0xf000) >> 12) * 16;
int const width = ((source[2] & 0xf000) >> 12) * 16;
u32 offset = tileno * 256;
if (x & 0x200) x-=0x400;
if (y & 0x200) y-=0x400;
#if 0 // For Flipscreen/Cocktail
if(m_vidregs[0] & 0x8000)
{
flipx = !flipx;
}
if(m_vidregs[1] & 0x8000)
{
flipy = !flipy;
}
#endif
if (source[3] != source[0]) // 'hack' don't draw sprites while its testing the ram!
{
if(!flipx) { xstart = 0; xend = width; xinc = 1; }
else { xstart = width-1; xend = -1; xinc = -1; }
if(!flipy) { ystart = 0; yend = height; yinc = 1; }
else { ystart = height-1; yend = -1; yinc = -1; }
for (int ycnt = ystart; ycnt != yend; ycnt += yinc)
{
const int drawypos = y + ycnt - global_y;
if ((drawypos >= cliprect.min_y) && (drawypos <= cliprect.max_y))
{
u16 *const destline = &bitmap.pix(drawypos);
u8 *const priline = &screen.priority().pix(drawypos);
for (int xcnt = xstart; xcnt != xend; xcnt += xinc)
{
const int drawxpos = x + xcnt - global_x;
if ((drawxpos >= cliprect.min_x) && (drawxpos <= cliprect.max_x))
{
const int pridata = priline[drawxpos];
if (!(pridata & 0x10)) // if we haven't already drawn a sprite pixel here (sprite masking)
{
u8 pix = m_sprdata[(offset / 2)&sprmask];
if (offset & 1)
pix = pix >> 4;
pix &= 0x0f;
if (pix)
{
if ((priline[drawxpos] < pri))
destline[drawxpos] = (pix + (pen << 4));
priline[drawxpos] |= 0x10;
}
}
}
offset++;
}
}
else
{
offset += width;
}
}
}
source -= 4;
}
}
void mcatadv_state::mcatadv_draw_tilemap_part( screen_device &screen, int layer, int i, bitmap_ind16 &bitmap, const rectangle &cliprect )
{
if (!m_tilemap[layer]->enable())
return;
rectangle clip;
clip.min_x = cliprect.min_x;
clip.max_x = cliprect.max_x;
for (u32 drawline = cliprect.min_y; drawline <= cliprect.max_y; drawline++)
{
clip.min_y = drawline;
clip.max_y = drawline;
int scrollx = (m_tilemap[layer]->scrollx() & 0x1ff) - 0x194;
int scrolly = (m_tilemap[layer]->scrolly() & 0x1ff) - 0x1df;
if (m_tilemap[layer]->rowselect_en())
{
const int rowselect = m_tilemap[layer]->rowselect(drawline + scrolly);
scrolly = rowselect - drawline;
}
if (m_tilemap[layer]->rowscroll_en())
{
const int rowscroll = m_tilemap[layer]->rowscroll(drawline + scrolly);
scrollx += rowscroll;
}
/* Global Flip */
if (m_tilemap[layer]->flipx()) scrollx -= 0x19;
if (m_tilemap[layer]->flipy()) scrolly -= 0x141;
int flip = (m_tilemap[layer]->flipx() ? TILEMAP_FLIPX : 0) | (m_tilemap[layer]->flipy() ? TILEMAP_FLIPY : 0);
m_tilemap[layer]->set_scrollx(0, scrollx);
m_tilemap[layer]->set_scrolly(0, scrolly);
m_tilemap[layer]->set_flip(flip);
m_tilemap[layer]->draw(screen, bitmap, clip, i, i);
}
}
u32 mcatadv_state::screen_update_mcatadv(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
{
bitmap.fill(0x3f0, cliprect);
screen.priority().fill(0, cliprect);
for (int i = 0; i < 2; i++)
{
m_tilemap[i]->prepare();
if (m_tilemap[i]->external() != m_palette_bank[i])
{
m_palette_bank[i] = m_tilemap[i]->external()&0xf;
m_tilemap[i]->mark_all_dirty();
}
}
/*
popmessage("%02x %02x %02x %02x",
m_tilemap[0]->rowscroll_en(),
m_tilemap[0]->rowselect_en(),
m_tilemap[1]->rowscroll_en(),
m_tilemap[1]->rowselect_en());
*/
for (int i = 0; i <= 3; i++)
{
#ifdef MAME_DEBUG
if (!machine().input().code_pressed(KEYCODE_Q))
#endif
mcatadv_draw_tilemap_part(screen, 0, i|0x8, bitmap, cliprect);
#ifdef MAME_DEBUG
if (!machine().input().code_pressed(KEYCODE_W))
#endif
mcatadv_draw_tilemap_part(screen, 1, i|0x8, bitmap, cliprect);
}
g_profiler.start(PROFILER_USER1);
#ifdef MAME_DEBUG
if (!machine().input().code_pressed(KEYCODE_E))
#endif
draw_sprites (screen, bitmap, cliprect);
g_profiler.stop();
return 0;
}
void mcatadv_state::video_start()
{
m_spriteram_old = make_unique_clear<u16[]>(m_spriteram.bytes() / 2);
m_vidregs_old = std::make_unique<u16[]>(m_vidregs.bytes() / 2);
m_palette_bank[0] = m_palette_bank[1] = 0;
save_pointer(NAME(m_spriteram_old), m_spriteram.bytes() / 2);
save_pointer(NAME(m_vidregs_old), m_vidregs.bytes() / 2);
}
WRITE_LINE_MEMBER(mcatadv_state::screen_vblank_mcatadv)
{
// rising edge
if (state)
{
std::copy(&m_spriteram[0], &m_spriteram[m_spriteram.bytes() / 2], &m_spriteram_old[0]);
std::copy(&m_vidregs[0], &m_vidregs[m_vidregs.bytes() / 2], &m_vidregs_old[0]);
}
}

View File

@ -1,5 +1,6 @@
// license:BSD-3-Clause
// copyright-holders:David Haywood, Paul Priest
// copyright-holders: David Haywood, Paul Priest
/* One Shot One Kill & Maddonna
Driver by David Haywood and Paul Priest
Dip Switches and Inputs by stephh
@ -10,7 +11,7 @@ Notes :
- The YM3812 is used only for timing. All sound is played with ADPCM samples.
- It doesn't seem possible to make 2 consecutive shots at the same place !
Ingame bug or is there something missing in the emulation ?
In-game bug or is there something missing in the emulation ?
* several gun games are like this, changed the driver so it doesn't try
- Gun X range is 0x0000-0x01ff and gun Y range is 0x0000-0x00ff, so you
@ -28,7 +29,7 @@ TO DO :
- verify the parameters for the guns (analog ports)
- figure out year and manufacturer
(NOTHING is displayed in "demo mode", nor when you complete ALL levels !)
- sound too fast in Maddonna?
- sound too fast in Mad Donna?
- layer order register?
NOTE: An eBay auction of the PCB shows "1996.9.16 PROMAT" on the JAMMA+ adapter for
@ -126,7 +127,6 @@ Clock measurements:
*/
#include "emu.h"
#include "oneshot.h"
#include "cpu/m68000/m68000.h"
#include "cpu/z80/z80.h"
@ -134,11 +134,316 @@ Clock measurements:
#include "sound/okim6295.h"
#include "sound/ymopl.h"
#include "emupal.h"
#include "screen.h"
#include "speaker.h"
#include "tilemap.h"
u16 oneshot_state::oneshot_in0_word_r()
// configurable logging
#define LOG_SCROLL (1U << 1)
//#define VERBOSE (LOG_GENERAL | LOG_SCROLL)
#include "logmacro.h"
#define LOGSCROLL(...) LOGMASKED(LOG_SCROLL, __VA_ARGS__)
namespace {
class maddonna_state : public driver_device
{
public:
maddonna_state(const machine_config &mconfig, device_type type, const char *tag) :
driver_device(mconfig, type, tag),
m_maincpu(*this, "maincpu"),
m_palette(*this, "palette"),
m_scroll(*this, "scroll"),
m_oki(*this, "oki"),
m_gfxdecode(*this, "gfxdecode"),
m_spriteram(*this, "spriteram"),
m_bg_videoram(*this, "bg_videoram"),
m_mid_videoram(*this, "mid_videoram"),
m_fg_videoram(*this, "fg_videoram")
{ }
void maddonna(machine_config &config);
void komocomo(machine_config &config);
protected:
virtual void video_start() override;
required_device<cpu_device> m_maincpu;
required_device<palette_device> m_palette;
required_shared_ptr<u16> m_scroll;
// video-related
tilemap_t *m_bg_tilemap = nullptr;
tilemap_t *m_mid_tilemap = nullptr;
tilemap_t *m_fg_tilemap = nullptr;
void draw_sprites(bitmap_ind16 &bitmap, const rectangle &cliprect);
void main_map(address_map &map);
private:
// devices
required_device<okim6295_device> m_oki;
required_device<gfxdecode_device> m_gfxdecode;
// memory pointers
required_shared_ptr<u16> m_spriteram;
required_shared_ptr<u16> m_bg_videoram;
required_shared_ptr<u16> m_mid_videoram;
required_shared_ptr<u16> m_fg_videoram;
void bg_videoram_w(offs_t offset, u16 data, u16 mem_mask = ~0);
void mid_videoram_w(offs_t offset, u16 data, u16 mem_mask = ~0);
void fg_videoram_w(offs_t offset, u16 data, u16 mem_mask = ~0);
void soundbank_w(u8 data);
TILE_GET_INFO_MEMBER(get_bg_tile_info);
TILE_GET_INFO_MEMBER(get_mid_tile_info);
TILE_GET_INFO_MEMBER(get_fg_tile_info);
u32 screen_update_maddonna(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect);
u32 screen_update_komocomo(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect);
void sound_map(address_map &map);
};
class oneshot_state : public maddonna_state
{
public:
oneshot_state(const machine_config &mconfig, device_type type, const char *tag) :
maddonna_state(mconfig, type, tag),
m_io_dsw1(*this, "DSW1"),
m_io_lightgun_x(*this, "LIGHT%u_X", 0U),
m_io_lightgun_y(*this, "LIGHT%u_Y", 0U)
{ }
void oneshot(machine_config &config);
protected:
virtual void machine_start() override;
virtual void machine_reset() override;
private:
required_ioport m_io_dsw1;
required_ioport_array<2> m_io_lightgun_x;
required_ioport_array<2> m_io_lightgun_y;
// gun
u16 m_gun_x[2]{};
u16 m_gun_y[2]{};
u8 m_gun_x_shift = 0;
u8 m_wobble[2]{};
u16 in0_word_r();
template <u8 Which> u16 gun_x_r();
template <u8 Which> u16 gun_y_r();
u32 screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect);
void draw_crosshairs();
void main_map(address_map &map);
};
// video
// bg tilemap
TILE_GET_INFO_MEMBER(maddonna_state::get_bg_tile_info)
{
const u32 tileno = m_bg_videoram[tile_index * 2 + 1];
tileinfo.set(0, tileno, 0, 0);
}
void maddonna_state::bg_videoram_w(offs_t offset, u16 data, u16 mem_mask)
{
COMBINE_DATA(&m_bg_videoram[offset]);
m_bg_tilemap->mark_tile_dirty(offset / 2);
}
// mid tilemap
TILE_GET_INFO_MEMBER(maddonna_state::get_mid_tile_info)
{
const u32 tileno = m_mid_videoram[tile_index * 2 + 1];
tileinfo.set(0, tileno, 2, 0);
}
void maddonna_state::mid_videoram_w(offs_t offset, u16 data, u16 mem_mask)
{
COMBINE_DATA(&m_mid_videoram[offset]);
m_mid_tilemap->mark_tile_dirty(offset / 2);
}
// fg tilemap
TILE_GET_INFO_MEMBER(maddonna_state::get_fg_tile_info)
{
const u32 tileno = m_fg_videoram[tile_index * 2 + 1];
tileinfo.set(0, tileno, 3, 0);
}
void maddonna_state::fg_videoram_w(offs_t offset, u16 data, u16 mem_mask)
{
COMBINE_DATA(&m_fg_videoram[offset]);
m_fg_tilemap->mark_tile_dirty(offset / 2);
}
void maddonna_state::video_start()
{
m_bg_tilemap = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(*this, FUNC(maddonna_state::get_bg_tile_info)), TILEMAP_SCAN_ROWS, 16, 16, 32, 32);
m_mid_tilemap = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(*this, FUNC(maddonna_state::get_mid_tile_info)), TILEMAP_SCAN_ROWS, 16, 16, 32, 32);
m_fg_tilemap = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(*this, FUNC(maddonna_state::get_fg_tile_info)), TILEMAP_SCAN_ROWS, 16, 16, 32, 32);
m_bg_tilemap->set_transparent_pen(0);
m_mid_tilemap->set_transparent_pen(0);
m_fg_tilemap->set_transparent_pen(0);
}
void oneshot_state::draw_crosshairs()
{
//int xpos,ypos;
// get gun raw coordinates (player 1)
m_gun_x[0] = (m_io_lightgun_x[0]->read() & 0xff) * 320 / 256;
m_gun_y[0] = (m_io_lightgun_y[0]->read() & 0xff) * 240 / 256;
// compute the coordinates for drawing (from routine at 0x009ab0)
//xpos = m_gun_x[0];
//ypos = m_gun_y[0];
m_gun_x[0] += m_gun_x_shift;
m_gun_y[0] -= 0x0a;
if (m_gun_y[0] < 0)
m_gun_y[0] = 0;
// get gun raw coordinates (player 2)
m_gun_x[1] = (m_io_lightgun_x[1]->read() & 0xff) * 320 / 256;
m_gun_y[1] = (m_io_lightgun_y[1]->read() & 0xff) * 240 / 256;
// compute the coordinates for drawing (from routine at 0x009b6e)
//xpos = m_gun_x[1];
//ypos = m_gun_y[1];
m_gun_x[1] += m_gun_x_shift - 0x0a;
if (m_gun_x[1] < 0)
m_gun_x[1] = 0;
}
void maddonna_state::draw_sprites(bitmap_ind16 &bitmap, const rectangle &cliprect)
{
const u16 *source = m_spriteram;
const u16 *finish = source + (0x1000 / 2);
gfx_element *gfx = m_gfxdecode->gfx(1);
while (source < finish)
{
const u16 attr = source[0];
if (attr & 0x0001) // end of sprites
break;
if (!(attr & 0x8000)) // visible bit
{
source += 0x4;
continue;
}
const u32 num = source[1] & 0xffff;
const int xsize = (source[2] & 0x000f) + 1;
const int ysize = (source[3] & 0x000f) + 1;
int ypos = source[3] & 0xff80;
int xpos = source[2] & 0xff80;
ypos = ypos >> 7;
xpos = xpos >> 7;
xpos -= 8;
ypos -= 6;
for (int blockx = 0; blockx < xsize; blockx++)
{
for (int blocky = 0; blocky < ysize; blocky++)
{
gfx->transpen(
bitmap,
cliprect,
num + (blocky * xsize) + blockx,
1,
0, 0,
xpos + blockx * 8, ypos + blocky * 8, 0);
gfx->transpen(
bitmap,
cliprect,
num + (blocky * xsize) + blockx,
1,
0, 0,
xpos + blockx * 8 - 0x200, ypos + blocky * 8, 0);
}
}
source += 0x4;
}
}
u32 oneshot_state::screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
{
bitmap.fill(m_palette->black_pen(), cliprect);
m_mid_tilemap->set_scrollx(0, m_scroll[0] - 0x1f5);
m_mid_tilemap->set_scrolly(0, m_scroll[1]);
m_bg_tilemap->draw(screen, bitmap, cliprect, 0, 0);
m_mid_tilemap->draw(screen, bitmap, cliprect, 0, 0);
draw_sprites(bitmap, cliprect);
m_fg_tilemap->draw(screen, bitmap, cliprect, 0, 0);
draw_crosshairs();
return 0;
}
u32 maddonna_state::screen_update_maddonna(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
{
bitmap.fill(m_palette->black_pen(), cliprect);
m_mid_tilemap->set_scrolly(0, m_scroll[1]); // other registers aren't used so we don't know which layers they relate to
m_mid_tilemap->draw(screen, bitmap, cliprect, 0, 0);
m_fg_tilemap->draw(screen, bitmap, cliprect, 0, 0);
m_bg_tilemap->draw(screen, bitmap, cliprect, 0, 0);
draw_sprites(bitmap, cliprect);
LOGSCROLL("%04x %04x %04x %04x %04x %04x %04x %04x", m_scroll[0], m_scroll[1], m_scroll[2], m_scroll[3], m_scroll[4], m_scroll[5], m_scroll[6], m_scroll[7]);
return 0;
}
// why are the layers in a different order?
u32 maddonna_state::screen_update_komocomo(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
{
bitmap.fill(m_palette->black_pen(), cliprect);
m_mid_tilemap->set_scrolly(0, m_scroll[1]); // other registers aren't used so we don't know which layers they relate to
m_bg_tilemap->draw(screen, bitmap, cliprect, 0, 0);
m_mid_tilemap->draw(screen, bitmap, cliprect, 0, 0);
m_fg_tilemap->draw(screen, bitmap, cliprect, 0, 0);
draw_sprites(bitmap, cliprect);
LOGSCROLL("%04x %04x %04x %04x %04x %04x %04x %04x", m_scroll[0], m_scroll[1], m_scroll[2], m_scroll[3], m_scroll[4], m_scroll[5], m_scroll[6], m_scroll[7]);
return 0;
}
// machine
u16 oneshot_state::in0_word_r()
{
const u16 data = m_io_dsw1->read();
@ -161,65 +466,61 @@ u16 oneshot_state::oneshot_in0_word_r()
return data;
}
u16 oneshot_state::oneshot_gun_x_p1_r()
template <u8 Which>
u16 oneshot_state::gun_x_r()
{
/* shots must be in a different location to register */
m_p1_wobble ^= 1;
// shots must be in a different location to register
m_wobble[Which] ^= 1;
return m_gun_x_p1 ^ m_p1_wobble;
return m_gun_x[Which] ^ m_wobble[Which];
}
u16 oneshot_state::oneshot_gun_y_p1_r()
template <u8 Which>
u16 oneshot_state::gun_y_r()
{
return m_gun_y_p1;
return m_gun_y[Which];
}
u16 oneshot_state::oneshot_gun_x_p2_r()
{
/* shots must be in a different location to register */
m_p2_wobble ^= 1;
return m_gun_x_p2 ^ m_p2_wobble;
}
u16 oneshot_state::oneshot_gun_y_p2_r()
{
return m_gun_y_p2;
}
void oneshot_state::soundbank_w(u8 data)
void maddonna_state::soundbank_w(u8 data)
{
m_oki->set_rom_bank((data & 0x03) ^ 0x03);
}
void oneshot_state::mem_map(address_map &map)
void maddonna_state::main_map(address_map &map)
{
map(0x000000, 0x03ffff).rom();
map(0x080000, 0x087fff).ram();
map(0x0c0000, 0x0c07ff).ram().w(m_palette, FUNC(palette_device::write16)).share("palette");
map(0x120000, 0x120fff).ram().share("spriteram");
map(0x120000, 0x120fff).ram().share(m_spriteram);
//map(0x13f000, 0x13f000).noprw(); // Unknown read / writes
map(0x180000, 0x180fff).ram().w(FUNC(oneshot_state::mid_videoram_w)).share("mid_videoram"); // some people , girl etc.
map(0x181000, 0x181fff).ram().w(FUNC(oneshot_state::fg_videoram_w)).share("fg_videoram"); // credits etc.
map(0x182000, 0x182fff).ram().w(FUNC(oneshot_state::bg_videoram_w)).share("bg_videoram"); // credits etc.
map(0x188000, 0x18800f).writeonly().share("scroll"); // scroll registers
map(0x180000, 0x180fff).ram().w(FUNC(maddonna_state::mid_videoram_w)).share(m_mid_videoram); // some people , girl etc.
map(0x181000, 0x181fff).ram().w(FUNC(maddonna_state::fg_videoram_w)).share(m_fg_videoram); // credits etc.
map(0x182000, 0x182fff).ram().w(FUNC(maddonna_state::bg_videoram_w)).share(m_bg_videoram); // credits etc.
map(0x188000, 0x18800f).writeonly().share(m_scroll);
map(0x190003, 0x190003).r("soundlatch", FUNC(generic_latch_8_device::read));
map(0x190011, 0x190011).w("soundlatch", FUNC(generic_latch_8_device::write));
map(0x190019, 0x190019).w(FUNC(oneshot_state::soundbank_w));
map(0x190026, 0x190027).r(FUNC(oneshot_state::oneshot_gun_x_p1_r));
map(0x19002e, 0x19002f).r(FUNC(oneshot_state::oneshot_gun_x_p2_r));
map(0x190036, 0x190037).r(FUNC(oneshot_state::oneshot_gun_y_p1_r));
map(0x19003e, 0x19003f).r(FUNC(oneshot_state::oneshot_gun_y_p2_r));
map(0x19c020, 0x19c021).r(FUNC(oneshot_state::oneshot_in0_word_r));
map(0x190019, 0x190019).w(FUNC(maddonna_state::soundbank_w));
map(0x19c020, 0x19c021).portr("DSW1");
map(0x19c024, 0x19c025).portr("DSW2");
map(0x19c02c, 0x19c02d).portr("CREDITS");
map(0x19c030, 0x19c031).portr("P1");
map(0x19c034, 0x19c035).portr("P2");
}
void oneshot_state::sound_map(address_map &map)
void oneshot_state::main_map(address_map &map)
{
maddonna_state::main_map(map);
map(0x190026, 0x190027).r(FUNC(oneshot_state::gun_x_r<0>));
map(0x19002e, 0x19002f).r(FUNC(oneshot_state::gun_x_r<1>));
map(0x190036, 0x190037).r(FUNC(oneshot_state::gun_y_r<0>));
map(0x19003e, 0x19003f).r(FUNC(oneshot_state::gun_y_r<1>));
map(0x19c020, 0x19c021).r(FUNC(oneshot_state::in0_word_r));
}
void maddonna_state::sound_map(address_map &map)
{
map(0x0000, 0x7fff).rom();
map(0x8000, 0x8000).rw("soundlatch", FUNC(generic_latch_8_device::read), FUNC(generic_latch_8_device::write));
@ -230,7 +531,7 @@ void oneshot_state::sound_map(address_map &map)
static INPUT_PORTS_START( oneshot )
PORT_START("DSW1") /* 0x19c020.l -> 0x08006c.l */
PORT_START("DSW1") // 0x19c020.l -> 0x08006c.l
PORT_DIPNAME( 0x03, 0x00, DEF_STR( Coinage ) ) // 0x080084.l : credits (00-09)
PORT_DIPSETTING( 0x03, DEF_STR( 3C_1C ) )
PORT_DIPSETTING( 0x02, DEF_STR( 2C_1C ) )
@ -252,7 +553,7 @@ static INPUT_PORTS_START( oneshot )
PORT_DIPSETTING( 0x00, DEF_STR( Off ) )
PORT_DIPSETTING( 0x80, DEF_STR( On ) )
PORT_START("DSW2") /* 0x19c024.l -> 0x08006e.l */
PORT_START("DSW2") // 0x19c024.l -> 0x08006e.l
PORT_DIPNAME( 0x03, 0x00, DEF_STR( Lives ) ) // 0x082500.l
PORT_DIPSETTING( 0x01, "1" )
PORT_DIPSETTING( 0x02, "2" )
@ -272,7 +573,7 @@ static INPUT_PORTS_START( oneshot )
PORT_DIPSETTING( 0x00, DEF_STR( Off ) )
PORT_DIPSETTING( 0x80, DEF_STR( On ) )
PORT_START("CREDITS") /* 0x19c02c.l -> 0x08007a.l */
PORT_START("CREDITS") // 0x19c02c.l -> 0x08007a.l
PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_UNKNOWN )
PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_UNKNOWN )
PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_UNKNOWN )
@ -282,7 +583,7 @@ static INPUT_PORTS_START( oneshot )
PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_START2 )
PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_UNKNOWN )
PORT_START("P1") /* Player 1 Gun Trigger (0x19c030.l) */
PORT_START("P1") // Player 1 Gun Trigger (0x19c030.l)
PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_UNKNOWN )
PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_UNKNOWN )
PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_UNKNOWN )
@ -292,7 +593,7 @@ static INPUT_PORTS_START( oneshot )
PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_UNKNOWN )
PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_UNKNOWN )
PORT_START("P2") /* Player 2 Gun Trigger (0x19c034.l) */
PORT_START("P2") // Player 2 Gun Trigger (0x19c034.l)
PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_UNKNOWN )
PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_UNKNOWN )
PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_UNKNOWN )
@ -302,16 +603,16 @@ static INPUT_PORTS_START( oneshot )
PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_UNKNOWN )
PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_UNKNOWN )
PORT_START("LIGHT0_X") /* Player 1 Gun X ($190026.l) */
PORT_START("LIGHT0_X") // Player 1 Gun X ($190026.l)
PORT_BIT( 0xff, 0x80, IPT_LIGHTGUN_X ) PORT_CROSSHAIR(X, 1.0, 0.0, 0) PORT_SENSITIVITY(35) PORT_KEYDELTA(15) PORT_PLAYER(1)
PORT_START("LIGHT0_Y") /* Player 1 Gun Y ($190036.l) */
PORT_START("LIGHT0_Y") // Player 1 Gun Y ($190036.l)
PORT_BIT( 0xff, 0x80, IPT_LIGHTGUN_Y ) PORT_CROSSHAIR(Y, 1.0, 0.0, 0) PORT_SENSITIVITY(35) PORT_KEYDELTA(15) PORT_PLAYER(1)
PORT_START("LIGHT1_X") /* Player 2 Gun X ($19002e.l) */
PORT_START("LIGHT1_X") // Player 2 Gun X ($19002e.l)
PORT_BIT( 0xff, 0x80, IPT_LIGHTGUN_X ) PORT_CROSSHAIR(X, 1.0, 0.0, 0) PORT_SENSITIVITY(35) PORT_KEYDELTA(15) PORT_PLAYER(2)
PORT_START("LIGHT1_Y") /* Player 2 Gun Y ($19003e.l) */
PORT_START("LIGHT1_Y") // Player 2 Gun Y ($19003e.l)
PORT_BIT( 0xff, 0x80, IPT_LIGHTGUN_Y ) PORT_CROSSHAIR(Y, 1.0, 0.0, 0) PORT_SENSITIVITY(35) PORT_KEYDELTA(15) PORT_PLAYER(2)
INPUT_PORTS_END
@ -350,7 +651,7 @@ static INPUT_PORTS_START( maddonna )
PORT_DIPSETTING( 0x08, "80 Seconds" )
PORT_DIPSETTING( 0x04, "90 Seconds" )
PORT_DIPSETTING( 0x00, "100 Seconds" )
// PORT_DIPSETTING( 0x0c, "?? Seconds" ) // Not Defined for On+On
PORT_DIPSETTING( 0x0c, "?? Seconds" ) // Not Defined for On+On
PORT_DIPNAME( 0x10, 0x10, DEF_STR( Lives ) )
PORT_DIPSETTING( 0x10, "3" )
PORT_DIPSETTING( 0x00, "5" )
@ -420,48 +721,45 @@ static const gfx_layout oneshot8x8_layout =
static GFXDECODE_START( gfx_oneshot )
GFXDECODE_ENTRY( "gfx1", 0, oneshot16x16_layout, 0, 4 ) /* sprites */
GFXDECODE_ENTRY( "gfx1", 0, oneshot8x8_layout, 0, 4 ) /* sprites */
GFXDECODE_ENTRY( "sprites", 0, oneshot16x16_layout, 0, 4 )
GFXDECODE_ENTRY( "sprites", 0, oneshot8x8_layout, 0, 4 )
GFXDECODE_END
void oneshot_state::machine_start()
{
save_item(NAME(m_gun_x_p1));
save_item(NAME(m_gun_y_p1));
save_item(NAME(m_gun_x_p2));
save_item(NAME(m_gun_y_p2));
save_item(NAME(m_gun_x));
save_item(NAME(m_gun_y));
save_item(NAME(m_gun_x_shift));
save_item(NAME(m_p1_wobble));
save_item(NAME(m_p2_wobble));
save_item(NAME(m_wobble));
}
void oneshot_state::machine_reset()
{
m_gun_x_p1 = 0;
m_gun_y_p1 = 0;
m_gun_x_p2 = 0;
m_gun_y_p2 = 0;
m_gun_x[0] = 0;
m_gun_y[0] = 0;
m_gun_x[1] = 0;
m_gun_y[1] = 0;
m_gun_x_shift = 0;
m_p1_wobble = 0;
m_p2_wobble = 0;
m_wobble[0] = 0;
m_wobble[1] = 0;
}
void oneshot_state::oneshot(machine_config &config)
void maddonna_state::maddonna(machine_config &config)
{
/* basic machine hardware */
// basic machine hardware
M68000(config, m_maincpu, 12_MHz_XTAL); // 12MHz - verified
m_maincpu->set_addrmap(AS_PROGRAM, &oneshot_state::mem_map);
m_maincpu->set_vblank_int("screen", FUNC(oneshot_state::irq4_line_hold));
m_maincpu->set_addrmap(AS_PROGRAM, &maddonna_state::main_map);
m_maincpu->set_vblank_int("screen", FUNC(maddonna_state::irq4_line_hold));
Z80(config, "audiocpu", 27_MHz_XTAL/8).set_addrmap(AS_PROGRAM, &oneshot_state::sound_map); // 3.375MHz - verified
Z80(config, "audiocpu", 27_MHz_XTAL / 8).set_addrmap(AS_PROGRAM, &maddonna_state::sound_map); // 3.375MHz - verified
/* video hardware */
// video hardware
screen_device &screen(SCREEN(config, "screen", SCREEN_TYPE_RASTER));
screen.set_refresh_hz(56);
screen.set_vblank_time(ATTOSECONDS_IN_USEC(0));
screen.set_size(32*16, 32*16);
screen.set_visarea(0*16, 20*16-1, 0*16, 15*16-1);
screen.set_screen_update(FUNC(oneshot_state::screen_update_oneshot));
screen.set_screen_update(FUNC(maddonna_state::screen_update_maddonna));
screen.set_palette(m_palette);
GFXDECODE(config, m_gfxdecode, m_palette, gfx_oneshot);
@ -471,37 +769,39 @@ void oneshot_state::oneshot(machine_config &config)
GENERIC_LATCH_8(config, "soundlatch");
ym3812_device &ymsnd(YM3812(config, "ymsnd", 27_MHz_XTAL/8)); // 3.375MHz - verified
ym3812_device &ymsnd(YM3812(config, "ymsnd", 27_MHz_XTAL / 8)); // 3.375MHz - verified
ymsnd.irq_handler().set_inputline("audiocpu", 0);
ymsnd.add_route(ALL_OUTPUTS, "mono", 1.0);
OKIM6295(config, m_oki, 5_MHz_XTAL/4, okim6295_device::PIN7_LOW); // 1.25MHz - verified, pin 7 is hard-wired to GROUND
OKIM6295(config, m_oki, 5_MHz_XTAL / 4, okim6295_device::PIN7_LOW); // 1.25MHz - verified, pin 7 is hard-wired to GROUND
m_oki->add_route(ALL_OUTPUTS, "mono", 1.0);
}
void oneshot_state::maddonna(machine_config &config)
void maddonna_state::komocomo(machine_config &config)
{
oneshot(config);
subdevice<screen_device>("screen")->set_screen_update(FUNC(oneshot_state::screen_update_maddonna));
maddonna(config);
subdevice<screen_device>("screen")->set_screen_update(FUNC(maddonna_state::screen_update_komocomo));
}
void oneshot_state::komocomo(machine_config &config)
void oneshot_state::oneshot(machine_config &config)
{
oneshot(config);
subdevice<screen_device>("screen")->set_screen_update(FUNC(oneshot_state::screen_update_komocomo));
}
maddonna(config);
m_maincpu->set_addrmap(AS_PROGRAM, &oneshot_state::main_map);
subdevice<screen_device>("screen")->set_screen_update(FUNC(oneshot_state::screen_update));
}
ROM_START( oneshot )
ROM_REGION( 0x40000, "maincpu", 0 ) /* 68000 Code */
ROM_REGION( 0x40000, "maincpu", 0 ) // 68000 Code
ROM_LOAD16_BYTE( "1shot-u.a24", 0x00000, 0x20000, CRC(0ecd33da) SHA1(d050e9a1900cd9f629818034b1445e034b6cf81c) )
ROM_LOAD16_BYTE( "1shot-u.a22", 0x00001, 0x20000, CRC(26c3ae2d) SHA1(47e479abe06d508a9d9fe677d34d6a485bde5533) )
ROM_REGION( 0x10000, "audiocpu", 0 ) /* Z80 Code */
ROM_REGION( 0x10000, "audiocpu", 0 ) // Z80 Code
ROM_LOAD( "1shot.ua2", 0x00000, 0x010000, CRC(f655b80e) SHA1(2574a812c35801755c187a47f46ccdb0983c5feb) )
ROM_REGION( 0x400000, "gfx1", 0 ) /* Sprites */
ROM_REGION( 0x400000, "sprites", 0 )
ROM_LOAD( "1shot-ui.16a", 0x000000, 0x080000, CRC(f765f9a2) SHA1(f6c386e0421fcb0e420585dd27d9dad951bb2556) )
ROM_LOAD( "1shot-ui.13a", 0x080000, 0x080000, CRC(3361b5d8) SHA1(f7db674d479765d4e58fb663aa5e13dde2abcce7) )
ROM_LOAD( "1shot-ui.11a", 0x100000, 0x080000, CRC(8f8bd027) SHA1(fbec952ab5604c8e20c5e7cfd2844f4fe5441186) )
@ -511,12 +811,12 @@ ROM_START( oneshot )
ROM_LOAD( "1shot-ui.11", 0x300000, 0x080000, CRC(b8938345) SHA1(318cf0d070db786680a45811bbd765fa37caaf62) )
ROM_LOAD( "1shot-ui.08", 0x380000, 0x080000, CRC(c9953bef) SHA1(21917a9dcc0afaeec20672ad863d0c9d583369e3) )
ROM_REGION( 0x100000, "oki", 0 ) /* Samples */
ROM_REGION( 0x100000, "oki", 0 )
ROM_LOAD( "1shot.u15", 0x000000, 0x080000, CRC(e3759a47) SHA1(1159335924a6d68a0a24bfbe0c9182107f3f05f8) )
ROM_LOAD( "1shot.u14", 0x080000, 0x080000, CRC(222e33f8) SHA1(2665afdf4cb1a29325df62efc1843a4b2cf34a4e) )
ROM_REGION( 0x10000, "user1", 0 )
ROM_LOAD( "1shot.mb", 0x00000, 0x10000, CRC(6b213183) SHA1(599c59d155d11edb151bfaed1d24ef964462a447) ) // motherboard rom, unknown purpose
ROM_LOAD( "1shot.mb", 0x00000, 0x10000, CRC(6b213183) SHA1(599c59d155d11edb151bfaed1d24ef964462a447) ) // motherboard ROM, unknown purpose
ROM_END
/*
@ -526,15 +826,14 @@ For this set of Mad Donna, original ROM labels follow this format:
160595 (Date, IE: May 16th, 1995)
*/
ROM_START( maddonna )
ROM_REGION( 0x40000, "maincpu", 0 ) /* 68000 Code */
ROM_REGION( 0x40000, "maincpu", 0 ) // 68000 Code
ROM_LOAD16_BYTE( "maddonna_tmad_b16_160595.ua24", 0x00000, 0x20000, CRC(643f9054) SHA1(77907ecdb02a525f9beed7fee203431eda16c831) )
ROM_LOAD16_BYTE( "maddonna_tmad_b15_160595.ua22", 0x00001, 0x20000, CRC(e36c0e26) SHA1(f261b2c74eeca05df302aa4956f5d02121d42054) )
ROM_REGION( 0x10000, "audiocpu", 0 ) /* Z80 Code */
ROM_REGION( 0x10000, "audiocpu", 0 ) // Z80 Code
ROM_LOAD( "maddonna_tmad_b13_160595.ua2", 0x00000, 0x010000, CRC(f2080071) SHA1(68cbae9559879b2dc19c41a7efbd13ab4a569d3f) )
ROM_REGION( 0x400000, "gfx1", 0 ) /* Sprites */
ROM_REGION( 0x400000, "sprites", 0 )
ROM_LOAD( "maddonna_tmad_b5_160595.ui16a", 0x000000, 0x080000, CRC(838d3244) SHA1(7339143481ec043219825f282450ff53bb718f8c) )
ROM_LOAD( "maddonna_tmad_b7_160595.ui13a", 0x080000, 0x080000, CRC(4920d2ec) SHA1(e72a374bca81ffa4f925326455e007df7227ae08) )
ROM_LOAD( "maddonna_tmad_b9_160595.ui11a", 0x100000, 0x080000, CRC(3a8a3feb) SHA1(832654902963c163644134431fd1221e1895cfec) )
@ -544,22 +843,22 @@ ROM_START( maddonna )
ROM_LOAD( "maddonna_tmad_b10_160595.ui11", 0x300000, 0x080000, CRC(87936423) SHA1(dda42f3685427edad7686d9712ff07d2fd9bf57e) )
ROM_LOAD( "maddonna_tmad_b12_160595.ui8", 0x380000, 0x080000, CRC(879ab23c) SHA1(5288016542a10e60ccb28a930d8dfe4db41c6fc6) )
ROM_REGION( 0x100000, "oki", ROMREGION_ERASE00 ) /* Samples */
/* no samples for this game */
ROM_REGION( 0x100000, "oki", ROMREGION_ERASE00 )
// no samples for this game
ROM_REGION( 0x10000, "user1", 0 )
ROM_LOAD( "x1", 0x00000, 0x10000, CRC(6b213183) SHA1(599c59d155d11edb151bfaed1d24ef964462a447) ) // motherboard rom, unknown purpose
ROM_LOAD( "x1", 0x00000, 0x10000, CRC(6b213183) SHA1(599c59d155d11edb151bfaed1d24ef964462a447) ) // motherboard ROM, unknown purpose
ROM_END
ROM_START( komocomo ) // ROM PCB marked : GAME B/D TOPnew1 002
ROM_REGION( 0x40000, "maincpu", 0 ) /* 68000 Code */
ROM_REGION( 0x40000, "maincpu", 0 ) // 68000 Code
ROM_LOAD16_BYTE( "11.ua24", 0x00000, 0x10000, CRC(31c18579) SHA1(da97207afced0cf844b111752e9f634a49bc7115) )
ROM_LOAD16_BYTE( "10.ua22", 0x00001, 0x10000, CRC(fa839c0f) SHA1(53aee489e694e5777bd5ac20aa2b51c2c9e5493a) )
ROM_REGION( 0x10000, "audiocpu", 0 ) /* Z80 Code */
ROM_REGION( 0x10000, "audiocpu", 0 ) // Z80 Code
ROM_LOAD( "9.ua2", 0x00000, 0x010000, CRC(f2080071) SHA1(68cbae9559879b2dc19c41a7efbd13ab4a569d3f) ) // 1ST AND 2ND HALF IDENTICAL
ROM_REGION( 0x400000, "gfx1", 0 ) /* Sprites */
ROM_REGION( 0x400000, "sprites", 0 )
ROM_LOAD( "8.ui16a", 0x000000, 0x080000, CRC(11ac04ab) SHA1(321a7af3bdf47fa0ec1f7bbd758dd1023b409a06) )
ROM_LOAD( "6.ui13a", 0x080000, 0x080000, CRC(bb498592) SHA1(f7946a40d35ae0726860dd65f1aaf1c145d51afd) )
ROM_LOAD( "4.ui11a", 0x100000, 0x080000, CRC(d22dd6d8) SHA1(f466167d088275cdc973535401895272d48c8079) )
@ -569,11 +868,11 @@ ROM_START( komocomo ) // ROM PCB marked : GAME B/D TOPnew1 002
ROM_LOAD( "3.ui11", 0x300000, 0x080000, CRC(646073d1) SHA1(87593ccbe9419da2ea70763784acc12221b5bed8) )
ROM_LOAD( "1.ui8", 0x380000, 0x080000, CRC(58ba6622) SHA1(ee5a759ab22a663da5bba1db5fec23958bfee771) )
ROM_REGION( 0x100000, "oki", ROMREGION_ERASE00 ) /* Samples */
/* no samples for this game */
ROM_REGION( 0x100000, "oki", ROMREGION_ERASE00 )
// no samples for this game
ROM_REGION( 0x10000, "user1", 0 )
ROM_LOAD( "12.bin", 0x00000, 0x10000, CRC(6b213183) SHA1(599c59d155d11edb151bfaed1d24ef964462a447) ) // motherboard rom, unknown purpose
ROM_LOAD( "12.bin", 0x00000, 0x10000, CRC(6b213183) SHA1(599c59d155d11edb151bfaed1d24ef964462a447) ) // motherboard ROM, unknown purpose
ROM_END
@ -583,19 +882,19 @@ ROM_END
on the title screen.
The lack of these tiles in this set causes all subsequent tiles to be shifted. It is
likely that the correct program roms for this set either don't show '(c)Copyright 1995'
likely that the correct program ROMs for this set either don't show '(c)Copyright 1995'
or display it using the regular font instead. */
ROM_START( maddonnab )
ROM_REGION( 0x40000, "maincpu", 0 ) /* 68000 Code */
/* program roms missing in this dump, gfx don't seem 100% correct for other ones */
ROM_REGION( 0x40000, "maincpu", 0 ) // 68000 Code
// program ROMs missing in this dump, gfx don't seem 100% correct for other ones
ROM_LOAD16_BYTE( "maddonnb.b16", 0x00000, 0x20000, NO_DUMP )
ROM_LOAD16_BYTE( "maddonnb.b15", 0x00001, 0x20000, NO_DUMP )
ROM_REGION( 0x10000, "audiocpu", 0 ) /* Z80 Code */
ROM_REGION( 0x10000, "audiocpu", 0 ) // Z80 Code
ROM_LOAD( "x13.ua2", 0x00000, 0x010000, CRC(f2080071) SHA1(68cbae9559879b2dc19c41a7efbd13ab4a569d3f) )
ROM_REGION( 0x400000, "gfx1", 0 ) /* Sprites */
ROM_REGION( 0x400000, "sprites", 0 )
ROM_LOAD( "x5.16a", 0x000000, 0x080000, CRC(1aae0ad3) SHA1(a5afe699c66dcc5e7928807ae1c8be7ffdda798c) )
ROM_LOAD( "x7.13a", 0x080000, 0x080000, CRC(39d13e25) SHA1(bfe8b187c7fc9dc1ac2cc3f840a686a25ec55340) )
ROM_LOAD( "x9.11a", 0x100000, 0x080000, CRC(2027faeb) SHA1(cb8c697705ac70ec3cf74901a2becf6abd8be63d) )
@ -605,17 +904,19 @@ ROM_START( maddonnab )
ROM_LOAD( "x10.11", 0x300000, 0x080000, CRC(479d718c) SHA1(4fbc2568744cf78b15c6e0f3caba4d7109743cdd) )
ROM_LOAD( "x12.08", 0x380000, 0x080000, CRC(d56ca9f8) SHA1(49bca5dbc048e7b7efa34e1c08ee1b76767ffe38) )
ROM_REGION( 0x100000, "oki", ROMREGION_ERASE00 ) /* Samples */
/* no samples for this game */
ROM_REGION( 0x100000, "oki", ROMREGION_ERASE00 )
// no samples for this game
ROM_REGION( 0x10000, "user1", 0 )
ROM_LOAD( "x1", 0x00000, 0x10000, CRC(6b213183) SHA1(599c59d155d11edb151bfaed1d24ef964462a447) ) // motherboard rom, unknown purpose
ROM_LOAD( "x1", 0x00000, 0x10000, CRC(6b213183) SHA1(599c59d155d11edb151bfaed1d24ef964462a447) ) // motherboard ROM, unknown purpose
ROM_END
} // anonymous namespace
// all sets have a large (unused) PROMAT logo in them
GAME( 1995, maddonna, 0, maddonna, maddonna, oneshot_state, empty_init, ROT0, "Promat (Tuning license)", "Mad Donna (Tuning, set 1)", MACHINE_SUPPORTS_SAVE )
GAME( 1995, maddonnab,maddonna, maddonna, maddonna, oneshot_state, empty_init, ROT0, "Promat (Tuning license)", "Mad Donna (Tuning, set 2)", MACHINE_NOT_WORKING | MACHINE_SUPPORTS_SAVE )
GAME( 1995, komocomo, maddonna, komocomo, maddonna, oneshot_state, empty_init, ROT0, "bootleg", "Komo Como (Topmar, bootleg?)", MACHINE_SUPPORTS_SAVE ) // shows TOPMAR (an anagram of PROMAT) on the side, possibly a hack of the original PROMAT version
GAME( 1995, maddonna, 0, maddonna, maddonna, maddonna_state, empty_init, ROT0, "Promat (Tuning license)", "Mad Donna (Tuning, set 1)", MACHINE_SUPPORTS_SAVE )
GAME( 1995, maddonnab, maddonna, maddonna, maddonna, maddonna_state, empty_init, ROT0, "Promat (Tuning license)", "Mad Donna (Tuning, set 2)", MACHINE_NOT_WORKING | MACHINE_SUPPORTS_SAVE )
GAME( 1995, komocomo, maddonna, komocomo, maddonna, maddonna_state, empty_init, ROT0, "bootleg", "Komo Como (Topmar, bootleg?)", MACHINE_SUPPORTS_SAVE ) // shows TOPMAR (an anagram of PROMAT) on the side, possibly a hack of the original PROMAT version
GAME( 1996, oneshot, 0, oneshot, oneshot , oneshot_state, empty_init, ROT0, "Promat", "One Shot One Kill", MACHINE_IMPERFECT_GRAPHICS | MACHINE_SUPPORTS_SAVE )
GAME( 1996, oneshot, 0, oneshot, oneshot , oneshot_state, empty_init, ROT0, "Promat", "One Shot One Kill", MACHINE_IMPERFECT_GRAPHICS | MACHINE_SUPPORTS_SAVE )

View File

@ -1,93 +0,0 @@
// license:BSD-3-Clause
// copyright-holders:David Haywood, Paul Priest
#ifndef MAME_INCLUDES_ONESHOT_H
#define MAME_INCLUDES_ONESHOT_H
#pragma once
#include "sound/okim6295.h"
#include "emupal.h"
#include "tilemap.h"
class oneshot_state : public driver_device
{
public:
oneshot_state(const machine_config &mconfig, device_type type, const char *tag) :
driver_device(mconfig, type, tag),
m_spriteram(*this, "spriteram"),
m_bg_videoram(*this, "bg_videoram"),
m_mid_videoram(*this, "mid_videoram"),
m_fg_videoram(*this, "fg_videoram"),
m_scroll(*this, "scroll"),
m_io_dsw1(*this, "DSW1"),
m_io_lightgun_x(*this, "LIGHT%u_X", 0U),
m_io_lightgun_y(*this, "LIGHT%u_Y", 0U),
m_maincpu(*this, "maincpu"),
m_oki(*this, "oki"),
m_gfxdecode(*this, "gfxdecode"),
m_palette(*this, "palette")
{ }
void maddonna(machine_config &config);
void komocomo(machine_config &config);
void oneshot(machine_config &config);
protected:
virtual void machine_start() override;
virtual void machine_reset() override;
virtual void video_start() override;
private:
/* memory pointers */
required_shared_ptr<u16> m_spriteram;
required_shared_ptr<u16> m_bg_videoram;
required_shared_ptr<u16> m_mid_videoram;
required_shared_ptr<u16> m_fg_videoram;
required_shared_ptr<u16> m_scroll;
optional_ioport m_io_dsw1;
optional_ioport_array<2> m_io_lightgun_x;
optional_ioport_array<2> m_io_lightgun_y;
/* video-related */
tilemap_t *m_bg_tilemap = nullptr;
tilemap_t *m_mid_tilemap = nullptr;
tilemap_t *m_fg_tilemap = nullptr;
/* misc */
int m_gun_x_p1 = 0;
int m_gun_y_p1 = 0;
int m_gun_x_p2 = 0;
int m_gun_y_p2 = 0;
int m_gun_x_shift = 0;
int m_p1_wobble = 0;
int m_p2_wobble = 0;
/* devices */
required_device<cpu_device> m_maincpu;
required_device<okim6295_device> m_oki;
required_device<gfxdecode_device> m_gfxdecode;
required_device<palette_device> m_palette;
u16 oneshot_in0_word_r();
u16 oneshot_gun_x_p1_r();
u16 oneshot_gun_y_p1_r();
u16 oneshot_gun_x_p2_r();
u16 oneshot_gun_y_p2_r();
void bg_videoram_w(offs_t offset, u16 data, u16 mem_mask = ~0);
void mid_videoram_w(offs_t offset, u16 data, u16 mem_mask = ~0);
void fg_videoram_w(offs_t offset, u16 data, u16 mem_mask = ~0);
void soundbank_w(u8 data);
TILE_GET_INFO_MEMBER(get_bg_tile_info);
TILE_GET_INFO_MEMBER(get_mid_tile_info);
TILE_GET_INFO_MEMBER(get_fg_tile_info);
u32 screen_update_oneshot(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect);
u32 screen_update_maddonna(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect);
u32 screen_update_komocomo(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect);
void draw_crosshairs();
void draw_sprites(bitmap_ind16 &bitmap, const rectangle &cliprect);
void mem_map(address_map &map);
void sound_map(address_map &map);
};
#endif // MAME_INCLUDES_ONESHOT_H

View File

@ -1,196 +0,0 @@
// license:BSD-3-Clause
// copyright-holders:David Haywood, Paul Priest
/* One Shot One Kill Video Hardware */
#include "emu.h"
#include "oneshot.h"
/* bg tilemap */
TILE_GET_INFO_MEMBER(oneshot_state::get_bg_tile_info)
{
const u32 tileno = m_bg_videoram[tile_index * 2 + 1];
tileinfo.set(0, tileno, 0, 0);
}
void oneshot_state::bg_videoram_w(offs_t offset, u16 data, u16 mem_mask)
{
COMBINE_DATA(&m_bg_videoram[offset]);
m_bg_tilemap->mark_tile_dirty(offset / 2);
}
/* mid tilemap */
TILE_GET_INFO_MEMBER(oneshot_state::get_mid_tile_info)
{
const u32 tileno = m_mid_videoram[tile_index * 2 + 1];
tileinfo.set(0, tileno, 2, 0);
}
void oneshot_state::mid_videoram_w(offs_t offset, u16 data, u16 mem_mask)
{
COMBINE_DATA(&m_mid_videoram[offset]);
m_mid_tilemap->mark_tile_dirty(offset / 2);
}
/* fg tilemap */
TILE_GET_INFO_MEMBER(oneshot_state::get_fg_tile_info)
{
const u32 tileno = m_fg_videoram[tile_index * 2 + 1];
tileinfo.set(0, tileno, 3, 0);
}
void oneshot_state::fg_videoram_w(offs_t offset, u16 data, u16 mem_mask)
{
COMBINE_DATA(&m_fg_videoram[offset]);
m_fg_tilemap->mark_tile_dirty(offset / 2);
}
void oneshot_state::video_start()
{
m_bg_tilemap = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(*this, FUNC(oneshot_state::get_bg_tile_info)), TILEMAP_SCAN_ROWS, 16, 16, 32, 32);
m_mid_tilemap = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(*this, FUNC(oneshot_state::get_mid_tile_info)), TILEMAP_SCAN_ROWS, 16, 16, 32, 32);
m_fg_tilemap = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(*this, FUNC(oneshot_state::get_fg_tile_info)), TILEMAP_SCAN_ROWS, 16, 16, 32, 32);
m_bg_tilemap->set_transparent_pen(0);
m_mid_tilemap->set_transparent_pen(0);
m_fg_tilemap->set_transparent_pen(0);
}
void oneshot_state::draw_crosshairs()
{
//int xpos,ypos;
/* get gun raw coordinates (player 1) */
m_gun_x_p1 = (m_io_lightgun_x[0]->read() & 0xff) * 320 / 256;
m_gun_y_p1 = (m_io_lightgun_y[0]->read() & 0xff) * 240 / 256;
/* compute the coordinates for drawing (from routine at 0x009ab0) */
//xpos = m_gun_x_p1;
//ypos = m_gun_y_p1;
m_gun_x_p1 += m_gun_x_shift;
m_gun_y_p1 -= 0x0a;
if (m_gun_y_p1 < 0)
m_gun_y_p1 = 0;
/* get gun raw coordinates (player 2) */
m_gun_x_p2 = (m_io_lightgun_x[1]->read() & 0xff) * 320 / 256;
m_gun_y_p2 = (m_io_lightgun_y[1]->read() & 0xff) * 240 / 256;
/* compute the coordinates for drawing (from routine at 0x009b6e) */
//xpos = m_gun_x_p2;
//ypos = m_gun_y_p2;
m_gun_x_p2 += m_gun_x_shift - 0x0a;
if (m_gun_x_p2 < 0)
m_gun_x_p2 = 0;
}
void oneshot_state::draw_sprites(bitmap_ind16 &bitmap, const rectangle &cliprect)
{
const u16 *source = m_spriteram;
const u16 *finish = source + (0x1000 / 2);
gfx_element *gfx = m_gfxdecode->gfx(1);
while (source < finish)
{
const u16 attr = source[0];
if (attr & 0x0001) // end of sprites
break;
if (!(attr & 0x8000)) // visible bit
{
source += 0x4;
continue;
}
const u32 num = source[1] & 0xffff;
const int xsize = (source[2] & 0x000f) + 1;
const int ysize = (source[3] & 0x000f) + 1;
int ypos = source[3] & 0xff80;
int xpos = source[2] & 0xff80;
ypos = ypos >> 7;
xpos = xpos >> 7;
xpos -= 8;
ypos -= 6;
for (int blockx = 0; blockx < xsize; blockx++)
{
for (int blocky = 0; blocky < ysize; blocky++)
{
gfx->transpen(
bitmap,
cliprect,
num + (blocky * xsize) + blockx,
1,
0,0,
xpos + blockx * 8, ypos + blocky * 8, 0);
gfx->transpen(
bitmap,
cliprect,
num + (blocky * xsize) + blockx,
1,
0,0,
xpos + blockx * 8 - 0x200, ypos + blocky * 8, 0);
}
}
source += 0x4;
}
}
u32 oneshot_state::screen_update_oneshot(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
{
bitmap.fill(m_palette->black_pen(), cliprect);
m_mid_tilemap->set_scrollx(0, m_scroll[0] - 0x1f5);
m_mid_tilemap->set_scrolly(0, m_scroll[1]);
m_bg_tilemap->draw(screen, bitmap, cliprect, 0, 0);
m_mid_tilemap->draw(screen, bitmap, cliprect, 0, 0);
draw_sprites(bitmap, cliprect);
m_fg_tilemap->draw(screen, bitmap, cliprect, 0, 0);
draw_crosshairs();
return 0;
}
u32 oneshot_state::screen_update_maddonna(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
{
bitmap.fill(m_palette->black_pen(), cliprect);
m_mid_tilemap->set_scrolly(0, m_scroll[1]); // other registers aren't used so we don't know which layers they relate to
m_mid_tilemap->draw(screen, bitmap, cliprect, 0, 0);
m_fg_tilemap->draw(screen, bitmap, cliprect, 0, 0);
m_bg_tilemap->draw(screen, bitmap, cliprect, 0, 0);
draw_sprites(bitmap, cliprect);
// popmessage ("%04x %04x %04x %04x %04x %04x %04x %04x", m_scroll[0], m_scroll[1], m_scroll[2], m_scroll[3], m_scroll[4], m_scroll[5], m_scroll[6], m_scroll[7]);
return 0;
}
// why are the layers in a different order?
u32 oneshot_state::screen_update_komocomo(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
{
bitmap.fill(m_palette->black_pen(), cliprect);
m_mid_tilemap->set_scrolly(0, m_scroll[1]); // other registers aren't used so we don't know which layers they relate to
m_bg_tilemap->draw(screen, bitmap, cliprect, 0, 0);
m_mid_tilemap->draw(screen, bitmap, cliprect, 0, 0);
m_fg_tilemap->draw(screen, bitmap, cliprect, 0, 0);
draw_sprites(bitmap, cliprect);
// popmessage ("%04x %04x %04x %04x %04x %04x %04x %04x", m_scroll[0], m_scroll[1], m_scroll[2], m_scroll[3], m_scroll[4], m_scroll[5], m_scroll[6], m_scroll[7]);
return 0;
}

View File

@ -0,0 +1,160 @@
// license:BSD-3-Clause
// copyright-holders:
/*
Bootleg PCB with 2 sub PCBs.
Main PCB components:
1x Z80 (timer CPU?)
1x ROM
1x RP2A03E (NTSC NES main CPU)
1x RP2C02E-0 (NES PPU)
3x GM76C28-10 RAMs
1x 8-dip bank
various TTL
ROM PCB components:
6x ROMs
1x UM6264 RAM
1x PAL
various TTL
NTSC PCB components:
1x NEC uPC1352C chrominance and luminance processor for NTSC color TV
1x 3'579'545 XTAL
The Z80 ROM is really strange:
* 1st half is 0xff filled;
* 2nd half contains 8x 0x800 programs
* 6 of them are identical
* 2 others (0x4000 - 0x47ff and 0x6000 - 0x67ff) differ but are identical between themselves
*/
#include "emu.h"
#include "cpu/m6502/n2a03.h"
#include "cpu/z80/z80.h"
#include "video/ppu2c0x.h"
#include "emupal.h"
#include "screen.h"
#include "speaker.h"
namespace {
class nes_arcade_bl_state : public driver_device
{
public:
nes_arcade_bl_state(const machine_config &mconfig, device_type type, const char *tag) :
driver_device(mconfig, type, tag),
m_maincpu(*this, "maincpu"),
m_ppu(*this, "ppu")
{ }
void smb3bl(machine_config &config);
private:
required_device<n2a03_device> m_maincpu;
required_device<ppu2c0x_device> m_ppu;
void nes_cpu_map(address_map &map);
void timer_prg_map(address_map &map);
void timer_io_map(address_map &map);
};
void nes_arcade_bl_state::nes_cpu_map(address_map &map)
{
map(0x8000, 0xffff).rom().region("maincpu", 0);
}
void nes_arcade_bl_state::timer_prg_map(address_map &map)
{
map(0x0000, 0x07ff).rom();
map(0x8000, 0x87ff).ram();
}
void nes_arcade_bl_state::timer_io_map(address_map &map)
{
}
static INPUT_PORTS_START( smb3bl )
PORT_START("IN0")
PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_UNKNOWN )
PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_UNKNOWN )
PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_UNKNOWN )
PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_UNKNOWN )
PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_UNKNOWN )
PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_UNKNOWN )
PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_UNKNOWN )
PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_UNKNOWN )
PORT_START("IN1")
PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_UNKNOWN )
PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_UNKNOWN )
PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_UNKNOWN )
PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_UNKNOWN )
PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_UNKNOWN )
PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_UNKNOWN )
PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_UNKNOWN )
PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_UNKNOWN )
PORT_START("DSW")
PORT_DIPUNKNOWN_DIPLOC(0x01, 0x01, "SW1:1")
PORT_DIPUNKNOWN_DIPLOC(0x02, 0x02, "SW1:2")
PORT_DIPUNKNOWN_DIPLOC(0x04, 0x04, "SW1:3")
PORT_DIPUNKNOWN_DIPLOC(0x08, 0x08, "SW1:4")
PORT_DIPUNKNOWN_DIPLOC(0x10, 0x10, "SW1:5")
PORT_DIPUNKNOWN_DIPLOC(0x20, 0x20, "SW1:6")
PORT_DIPUNKNOWN_DIPLOC(0x40, 0x40, "SW1:7")
PORT_DIPUNKNOWN_DIPLOC(0x80, 0x80, "SW1:8")
INPUT_PORTS_END
void nes_arcade_bl_state::smb3bl(machine_config &config)
{
N2A03(config, m_maincpu, 3.579545_MHz_XTAL / 2); // TODO: verify divider
m_maincpu->set_addrmap(AS_PROGRAM, &nes_arcade_bl_state::nes_cpu_map);
z80_device &timercpu(Z80(config, "timercpu", 3.579545_MHz_XTAL));
timercpu.set_addrmap(AS_PROGRAM, &nes_arcade_bl_state::timer_prg_map);
timercpu.set_addrmap(AS_IO, &nes_arcade_bl_state::timer_io_map);
screen_device &screen(SCREEN(config, "screen", SCREEN_TYPE_RASTER));
screen.set_refresh_hz(60);
screen.set_size(32*8, 262);
screen.set_visarea(0*8, 32*8-1, 0*8, 30*8-1);
screen.set_screen_update("ppu", FUNC(ppu2c0x_device::screen_update));
PPU_2C02(config, m_ppu);
m_ppu->set_cpu_tag("maincpu");
m_ppu->int_callback().set_inputline(m_maincpu, INPUT_LINE_NMI);
SPEAKER(config, "mono").front_center();
m_maincpu->add_route(ALL_OUTPUTS, "mono", 0.50);
}
ROM_START( smb3bl )
ROM_REGION( 0x40000, "maincpu", 0 ) // extremely similar to smb3h in nes.xml once split
ROM_LOAD( "mario_3-1.bin", 0x00000, 0x10000, CRC(d28e54ee) SHA1(25b842aa091dd3e497b1ff34ef8cf4cda5025dc5) ) // 5601.rom-2 [1/2] IDENTICAL
ROM_LOAD( "mario_3-2.bin", 0x10000, 0x10000, CRC(1ed05c8d) SHA1(f78cfc827b5cde86f2aa4f9a9df82b923835a7a6) ) // 5601.rom-2 [2/2] IDENTICAL
ROM_LOAD( "mario_3-3.bin", 0x20000, 0x10000, CRC(0b2f4356) SHA1(bffb329b9d7387ededf779cf40c84906fc26cf05) ) // 5602.rom-1 [1/2] IDENTICAL
ROM_LOAD( "mario_3-4.bin", 0x30000, 0x10000, CRC(2abda7cc) SHA1(6e6c9b1f28a0d6eb7dc43dfeca1da458b7ddb89e) ) // 5602.rom-1 [2/2] 99.929810% (changes seem legit / not a result of a bad dump)
ROM_REGION( 0x20000, "gfx", 0 ) // matches smb3j in nes.xml once split
ROM_LOAD( "mario_3-5.bin", 0x00000, 0x10000, CRC(48d6ddce) SHA1(686793fcb9c3ba9d7280b40c9afdbd75860a290a) ) // hvc-um-0 chr [1/2] IDENTICAL
ROM_LOAD( "mario_3-6.bin", 0x10000, 0x10000, CRC(a88664e0) SHA1(327d246f198713f20adc7764ee539d18eb0b82ad) ) // hvc-um-0 chr [2/2] IDENTICAL
ROM_REGION( 0x8000, "timercpu", 0 )
ROM_LOAD( "nes_jamma_base.bin", 0x0000, 0x4000, CRC(ea276bdd) SHA1(1cd5916e9a6ea9e40526a4fe55b846ca1818fd5f) ) // BADADDR x-xxxxxxxxxxxxx
ROM_CONTINUE( 0x0000, 0x4000 )
ROM_END
} // anonymous namespace
GAME( 1987, smb3bl, 0, smb3bl, smb3bl, nes_arcade_bl_state, empty_init, ROT0, "Sang Ho Soft", "Super Mario Bros. 3 (NES bootleg)", 0 ) // 1987.10.01 in Z80 ROM

View File

@ -1,5 +1,6 @@
// license:BSD-3-Clause
// copyright-holders:Jarek Parchanski, Andrea Mazzoleni
// copyright-holders: Jarek Parchanski, Andrea Mazzoleni
/***************************************************************************
Return of the Invaders
@ -18,7 +19,7 @@ in the ROMs reveals the following strings:
COMIX LTD. 1985.
Notes:
- The rom names and locations are derived from PCB pictures.
- The ROM names and locations are derived from PCB pictures.
- The video hardware (especially the sprite system) is quite obviously derived
from a Namco design.
@ -29,7 +30,7 @@ Notes:
- In addition to a dump of the original MCU, we have a dump from a bootleg MCU.
The game does work with it, but only when the flip screen dip switch is turned
off. If it is set to on, the game hangs when starting a game because the
mcu doesn't answer a command.
MCU doesn't answer a command.
See bootleg MCU code at $206 and $435: when the dip switch is on, the
"lda #$00" should be replaced by "lda #$01".
@ -104,16 +105,363 @@ Notes:
***************************************************************************/
#include "emu.h"
#include "retofinv.h"
#include "taito68705.h"
#include "cpu/z80/z80.h"
#include "machine/74259.h"
#include "machine/gen_latch.h"
#include "machine/watchdog.h"
#include "sound/sn76496.h"
#include "emupal.h"
#include "screen.h"
#include "speaker.h"
#include "tilemap.h"
namespace {
class retofinv_state : public driver_device
{
public:
retofinv_state(const machine_config &mconfig, device_type type, const char *tag)
: driver_device(mconfig, type, tag)
, m_maincpu(*this, "maincpu")
, m_palette(*this, "palette")
, m_mainlatch(*this, "mainlatch")
, m_audiocpu(*this, "audiocpu")
, m_subcpu(*this, "sub")
, m_gfxdecode(*this, "gfxdecode")
, m_fg_videoram(*this, "fg_videoram")
, m_sharedram(*this, "sharedram")
, m_bg_videoram(*this, "bg_videoram")
{
}
void retofinvb1_nomcu(machine_config &config);
void retofinvb_nomcu(machine_config &config);
protected:
virtual void machine_start() override;
virtual void video_start() override;
void retofinv_base(machine_config &config);
void bl_palette(palette_device &palette) const;
void bootleg_map(address_map &map);
required_device<cpu_device> m_maincpu;
required_device<palette_device> m_palette;
required_device<ls259_device> m_mainlatch;
private:
void cpu2_m6000_w(uint8_t data);
uint8_t cpu0_mf800_r();
DECLARE_WRITE_LINE_MEMBER(irq0_ack_w);
DECLARE_WRITE_LINE_MEMBER(irq1_ack_w);
void coincounter_w(uint8_t data);
DECLARE_WRITE_LINE_MEMBER(coinlockout_w);
void bg_videoram_w(offs_t offset, uint8_t data);
void fg_videoram_w(offs_t offset, uint8_t data);
void gfx_ctrl_w(offs_t offset, uint8_t data);
TILEMAP_MAPPER_MEMBER(tilemap_scan);
TILE_GET_INFO_MEMBER(bg_get_tile_info);
TILE_GET_INFO_MEMBER(fg_get_tile_info);
void palette(palette_device &palette) const;
uint32_t screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect);
INTERRUPT_GEN_MEMBER(main_vblank_irq);
INTERRUPT_GEN_MEMBER(sub_vblank_irq);
void sound_map(address_map &map);
void sub_map(address_map &map);
void draw_sprites(bitmap_ind16 &bitmap);
required_device<cpu_device> m_audiocpu;
required_device<cpu_device> m_subcpu;
required_device<gfxdecode_device> m_gfxdecode;
required_shared_ptr<uint8_t> m_fg_videoram;
required_shared_ptr<uint8_t> m_sharedram;
required_shared_ptr<uint8_t> m_bg_videoram;
uint8_t m_main_irq_mask = 0;
uint8_t m_sub_irq_mask = 0;
uint8_t m_cpu2_m6000 = 0;
uint8_t m_fg_bank = 0;
uint8_t m_bg_bank = 0;
tilemap_t *m_bg_tilemap = nullptr;
tilemap_t *m_fg_tilemap = nullptr;
};
class retofinv_mcu_state : public retofinv_state
{
public:
retofinv_mcu_state(const machine_config &mconfig, device_type type, const char *tag)
: retofinv_state(mconfig, type, tag)
, m_68705(*this, "68705")
{
}
void retofinv(machine_config &config);
void retofinvb1(machine_config &config);
private:
uint8_t mcu_status_r();
void main_map(address_map &map);
required_device<taito68705_mcu_device> m_68705;
};
// video
void retofinv_state::palette(palette_device &palette) const
{
uint8_t const *const palette_prom = memregion("palette")->base();
uint8_t const *const clut_prom = memregion("clut")->base();
// create a lookup table for the palette
for (int i = 0; i < 0x100; i++)
{
int const r = pal4bit(palette_prom[i | 0x000]);
int const g = pal4bit(palette_prom[i | 0x100]);
int const b = pal4bit(palette_prom[i | 0x200]);
palette.set_indirect_color(i, rgb_t(r, g, b));
}
// fg chars (1bpp)
for (int i = 0; i < 0x200; i++)
{
uint8_t const ctabentry = (i & 0x01) ? (i >> 1) : 0;
palette.set_pen_indirect(i, ctabentry);
}
// sprites and bg tiles clut
for (int i = 0; i < 0x800; i++)
{
// descramble the address
int const j = bitswap<16>(i, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 0, 1, 2);
palette.set_pen_indirect(i + 0x200, clut_prom[j]);
}
}
void retofinv_state::bl_palette(palette_device &palette) const
{
uint8_t const *const palette_prom = memregion("palette")->base();
uint8_t const *const clut_prom = memregion("clut")->base();
// create a lookup table for the palette
for (int i = 0; i < 0x100; i++)
{
int const r = pal4bit(palette_prom[i | 0x000]);
int const g = pal4bit(palette_prom[i | 0x100]);
int const b = pal4bit(palette_prom[i | 0x200]);
palette.set_indirect_color(i, rgb_t(r, g, b));
}
// fg chars (1bpp)
for (int i = 0; i < 0x200; i++)
{
uint8_t const ctabentry = (i & 0x01) ? (i >> 1) : 0;
palette.set_pen_indirect(i, ctabentry);
}
// sprites and bg tiles clut
for (int i = 0; i < 0x800; i++)
{
// descramble the data
palette.set_pen_indirect(i + 0x200, bitswap<8>(clut_prom[i], 4, 5, 6, 7, 3, 2, 1, 0));
}
}
/***************************************************************************
Callbacks for the TileMap code
***************************************************************************/
// convert from 32x32 to 36x28
TILEMAP_MAPPER_MEMBER(retofinv_state::tilemap_scan)
{
row += 2;
col -= 2;
if (col & 0x20)
return ((col & 0x1f) << 5) + row;
else
return (row << 5) + col;
}
TILE_GET_INFO_MEMBER(retofinv_state::bg_get_tile_info)
{
tileinfo.set(2,
m_bg_videoram[tile_index] + 256 * m_bg_bank,
m_bg_videoram[0x400 + tile_index] & 0x3f,
0);
}
TILE_GET_INFO_MEMBER(retofinv_state::fg_get_tile_info)
{
int const color = m_fg_videoram[0x400 + tile_index];
tileinfo.group = color;
tileinfo.set(0,
m_fg_videoram[tile_index] + 256 * m_fg_bank,
color,
0);
}
/***************************************************************************
Start the video hardware emulation.
***************************************************************************/
void retofinv_state::video_start()
{
m_bg_tilemap = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(*this, FUNC(retofinv_state::bg_get_tile_info)), tilemap_mapper_delegate(*this, FUNC(retofinv_state::tilemap_scan)), 8, 8, 36, 28);
m_fg_tilemap = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(*this, FUNC(retofinv_state::fg_get_tile_info)), tilemap_mapper_delegate(*this, FUNC(retofinv_state::tilemap_scan)), 8, 8, 36, 28);
m_fg_tilemap->configure_groups(*m_gfxdecode->gfx(0), 0);
save_item(NAME(m_fg_bank));
save_item(NAME(m_bg_bank));
}
/***************************************************************************
Memory handlers
***************************************************************************/
void retofinv_state::bg_videoram_w(offs_t offset, uint8_t data)
{
m_bg_videoram[offset] = data;
m_bg_tilemap->mark_tile_dirty(offset & 0x3ff);
}
void retofinv_state::fg_videoram_w(offs_t offset, uint8_t data)
{
m_fg_videoram[offset] = data;
m_fg_tilemap->mark_tile_dirty(offset & 0x3ff);
}
void retofinv_state::gfx_ctrl_w(offs_t offset, uint8_t data)
{
switch (offset)
{
case 0:
flip_screen_set(data & 1);
break;
case 1:
if (m_fg_bank != (data & 1))
{
m_fg_bank = data & 1;
m_fg_tilemap->mark_all_dirty();
}
break;
case 2:
if (m_bg_bank != (data & 1))
{
m_bg_bank = data & 1;
m_bg_tilemap->mark_all_dirty();
}
break;
}
}
/***************************************************************************
Display refresh
***************************************************************************/
void retofinv_state::draw_sprites(bitmap_ind16 &bitmap)
{
uint8_t const *spriteram = m_sharedram + 0x0780;
uint8_t const *spriteram_2 = m_sharedram + 0x0f80;
uint8_t const *spriteram_3 = m_sharedram + 0x1780;
const rectangle spritevisiblearea(2*8, 34*8-1, 0*8, 28*8-1);
for (int offs = 0; offs < 0x80; offs += 2)
{
static const int gfx_offs[2][2] =
{
{ 0, 1 },
{ 2, 3 }
};
int sprite = spriteram[offs];
int const color = spriteram[offs + 1] & 0x3f;
int const sx = ((spriteram_2[offs + 1] << 1) + ((spriteram_3[offs + 1] & 0x80) >> 7)) - 39;
int sy = 256 - ((spriteram_2[offs] << 1) + ((spriteram_3[offs] & 0x80) >> 7)) + 1;
// not sure about the flipping, it's hardly ever used (mostly for shots)
int flipx = (spriteram_3[offs] & 0x01);
int flipy = (spriteram_3[offs] & 0x02) >> 1;
int const sizey = (spriteram_3[offs] & 0x04) >> 2;
int const sizex = (spriteram_3[offs] & 0x08) >> 3;
sprite &= ~sizex;
sprite &= ~(sizey << 1);
if (flip_screen())
{
flipx ^= 1;
flipy ^= 1;
}
sy -= 16 * sizey;
sy = (sy & 0xff) - 32; // fix wraparound
for (int y = 0; y <= sizey; y++)
{
for (int x = 0; x <= sizex; x++)
{
m_gfxdecode->gfx(1)->transmask(bitmap, spritevisiblearea,
sprite + gfx_offs[y ^ (sizey * flipy)][x ^ (sizex * flipx)],
color,
flipx, flipy,
sx + 16 * x, sy + 16 * y,
m_palette->transpen_mask(*m_gfxdecode->gfx(1), color, 0xff));
}
}
}
}
uint32_t retofinv_state::screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
{
m_bg_tilemap->draw(screen, bitmap, cliprect, 0, 0);
draw_sprites(bitmap);
m_fg_tilemap->draw(screen, bitmap, cliprect, 0, 0);
return 0;
}
// machine
void retofinv_state::machine_start()
{
save_item(NAME(m_main_irq_mask));
@ -155,19 +503,19 @@ WRITE_LINE_MEMBER(retofinv_state::coinlockout_w)
machine().bookkeeping().coin_lockout_w(0, !state);
}
uint8_t retofinv_state::mcu_status_r()
uint8_t retofinv_mcu_state::mcu_status_r()
{
/* bit 4 = when 1, mcu is ready to receive data from main cpu */
/* bit 5 = when 1, mcu has sent data to the main cpu */
// bit 4 = when 1, MCU is ready to receive data from main CPU
// bit 5 = when 1, MCU has sent data to the main CPU
return
((CLEAR_LINE == m_68705->host_semaphore_r()) ? 0x10 : 0x00) |
((CLEAR_LINE != m_68705->mcu_semaphore_r()) ? 0x20 : 0x00);
}
/* It is very likely that the main cpu and the sub cpu share the entire
/* It is very likely that the main CPU and the sub CPU share the entire
8000-ffff address space, each perhaps holding the other in waitstate
while accessing it. */
/* the main cpu code looks for a string at 7b00 (in the space for the
/* the main CPU code looks for a string at 7b00 (in the space for the
empty socket at IC73 from 6000-7fff) and if it finds a particular
string there, it jumps to that area, presumably for diagnostic use */
@ -175,13 +523,13 @@ void retofinv_state::bootleg_map(address_map &map)
{
map(0x0000, 0x7fff).rom();
map(0x7fff, 0x7fff).w(FUNC(retofinv_state::coincounter_w));
map(0x8000, 0x87ff).ram().w(FUNC(retofinv_state::fg_videoram_w)).share("fg_videoram");
map(0x8800, 0x9fff).ram().share("sharedram");
map(0xa000, 0xa7ff).ram().w(FUNC(retofinv_state::bg_videoram_w)).share("bg_videoram");
map(0x8000, 0x87ff).ram().w(FUNC(retofinv_state::fg_videoram_w)).share(m_fg_videoram);
map(0x8800, 0x9fff).ram().share(m_sharedram);
map(0xa000, 0xa7ff).ram().w(FUNC(retofinv_state::bg_videoram_w)).share(m_bg_videoram);
map(0xb800, 0xb802).w(FUNC(retofinv_state::gfx_ctrl_w));
map(0xc000, 0xc000).portr("P1");
map(0xc001, 0xc001).portr("P2");
map(0xc002, 0xc002).nopr(); /* bit 7 must be 0, otherwise game resets */
map(0xc002, 0xc002).nopr(); // bit 7 must be 0, otherwise game resets
map(0xc004, 0xc004).portr("SYSTEM");
map(0xc005, 0xc005).portr("DSW1");
map(0xc006, 0xc006).portr("DSW2");
@ -192,10 +540,10 @@ void retofinv_state::bootleg_map(address_map &map)
map(0xf800, 0xf800).r(FUNC(retofinv_state::cpu0_mf800_r));
}
void retofinv_state::main_map(address_map &map)
void retofinv_mcu_state::main_map(address_map &map)
{
bootleg_map(map);
map(0xc003, 0xc003).r(FUNC(retofinv_state::mcu_status_r));
map(0xc003, 0xc003).r(FUNC(retofinv_mcu_state::mcu_status_r));
map(0xe000, 0xe000).r(m_68705, FUNC(taito68705_mcu_device::data_r));
map(0xe800, 0xe800).w(m_68705, FUNC(taito68705_mcu_device::data_w));
}
@ -203,21 +551,21 @@ void retofinv_state::main_map(address_map &map)
void retofinv_state::sub_map(address_map &map)
{
map(0x0000, 0x7fff).rom();
map(0x8000, 0x87ff).ram().w(FUNC(retofinv_state::fg_videoram_w)).share("fg_videoram");
map(0x8800, 0x9fff).ram().share("sharedram");
map(0xa000, 0xa7ff).ram().w(FUNC(retofinv_state::bg_videoram_w)).share("bg_videoram");
map(0x8000, 0x87ff).ram().w(FUNC(retofinv_state::fg_videoram_w)).share(m_fg_videoram);
map(0x8800, 0x9fff).ram().share(m_sharedram);
map(0xa000, 0xa7ff).ram().w(FUNC(retofinv_state::bg_videoram_w)).share(m_bg_videoram);
map(0xc800, 0xc807).w("mainlatch", FUNC(ls259_device::write_d0));
}
void retofinv_state::sound_map(address_map &map)
{
map(0x0000, 0x1fff).rom();
map(0x2000, 0x27ff).ram(); /* 6116 sram at IC28 */
map(0x2000, 0x27ff).ram(); // 6116 SRAM at IC28
map(0x4000, 0x4000).r("soundlatch", FUNC(generic_latch_8_device::read));
map(0x6000, 0x6000).w(FUNC(retofinv_state::cpu2_m6000_w));
map(0x8000, 0x8000).w("sn1", FUNC(sn76489a_device::write));
map(0xa000, 0xa000).w("sn2", FUNC(sn76489a_device::write));
map(0xe000, 0xffff).rom(); /* space for diagnostic ROM */
map(0xe000, 0xffff).rom(); // space for diagnostic ROM
}
@ -356,7 +704,7 @@ INPUT_PORTS_END
static const gfx_layout charlayout =
{
8,8,
RGN_FRAC(1,2), /* bottom half of ROM is empty */
RGN_FRAC(1,2), // bottom half of ROM is empty
1,
{ 0 },
{ 7, 6, 5, 4, 3, 2, 1, 0 },
@ -389,54 +737,50 @@ static const gfx_layout spritelayout =
};
static GFXDECODE_START( gfx_retofinv )
GFXDECODE_ENTRY( "gfx1", 0, charlayout, 0, 256 )
GFXDECODE_ENTRY( "gfx2", 0, spritelayout, 256*2, 64 )
GFXDECODE_ENTRY( "gfx3", 0, bglayout, 64*16+256*2, 64 )
GFXDECODE_ENTRY( "fgtiles", 0, charlayout, 0, 256 )
GFXDECODE_ENTRY( "sprites", 0, spritelayout, 256*2, 64 )
GFXDECODE_ENTRY( "bgtiles", 0, bglayout, 64*16+256*2, 64 )
GFXDECODE_END
INTERRUPT_GEN_MEMBER(retofinv_state::main_vblank_irq)
{
if(m_main_irq_mask)
if (m_main_irq_mask)
device.execute().set_input_line(0, ASSERT_LINE);
}
INTERRUPT_GEN_MEMBER(retofinv_state::sub_vblank_irq)
{
if(m_sub_irq_mask)
if (m_sub_irq_mask)
device.execute().set_input_line(0, ASSERT_LINE);
}
void retofinv_state::retofinv(machine_config &config)
void retofinv_state::retofinv_base(machine_config &config)
{
/* basic machine hardware */
Z80(config, m_maincpu, XTAL(18'432'000)/6); /* XTAL and divider verified, 3.072 MHz */
m_maincpu->set_addrmap(AS_PROGRAM, &retofinv_state::main_map);
// basic machine hardware
Z80(config, m_maincpu, XTAL(18'432'000) / 6); // XTAL and divider verified, 3.072 MHz
m_maincpu->set_vblank_int("screen", FUNC(retofinv_state::main_vblank_irq));
Z80(config, m_subcpu, XTAL(18'432'000)/6); /* XTAL and divider verified, 3.072 MHz */
Z80(config, m_subcpu, XTAL(18'432'000) / 6); // XTAL and divider verified, 3.072 MHz
m_subcpu->set_addrmap(AS_PROGRAM, &retofinv_state::sub_map);
m_subcpu->set_vblank_int("screen", FUNC(retofinv_state::sub_vblank_irq));
Z80(config, m_audiocpu, XTAL(18'432'000)/6); /* XTAL and divider verified, 3.072 MHz */
Z80(config, m_audiocpu, XTAL(18'432'000) / 6); // XTAL and divider verified, 3.072 MHz
m_audiocpu->set_addrmap(AS_PROGRAM, &retofinv_state::sound_map);
m_audiocpu->set_periodic_int(FUNC(retofinv_state::nmi_line_pulse), attotime::from_hz(2*60)); // wrong, should be ~128-132 per frame, not 120.
TAITO68705_MCU(config, m_68705, XTAL(18'432'000)/6); /* XTAL and divider verified, 3.072 MHz */
config.set_maximum_quantum(attotime::from_hz(6000)); /* 100 CPU slices per frame - enough for the sound CPU to read all commands */
config.set_maximum_quantum(attotime::from_hz(6000)); // 100 CPU slices per frame - enough for the sound CPU to read all commands
LS259(config, m_mainlatch); // IC72 - probably shared between CPUs
m_mainlatch->q_out_cb<0>().set(FUNC(retofinv_state::irq0_ack_w));
m_mainlatch->q_out_cb<1>().set(FUNC(retofinv_state::coinlockout_w));
m_mainlatch->q_out_cb<2>().set_inputline(m_audiocpu, INPUT_LINE_RESET).invert();
m_mainlatch->q_out_cb<3>().set(m_68705, FUNC(taito68705_mcu_device::reset_w)).invert();
m_mainlatch->q_out_cb<4>().set(FUNC(retofinv_state::irq1_ack_w));
m_mainlatch->q_out_cb<5>().set_inputline(m_subcpu, INPUT_LINE_RESET).invert();
WATCHDOG_TIMER(config, "watchdog");
/* video hardware */
// video hardware
screen_device &screen(SCREEN(config, "screen", SCREEN_TYPE_RASTER));
screen.set_refresh_hz(60.58); // vsync measured at 60.58hz
screen.set_vblank_time(ATTOSECONDS_IN_USEC(0)); // not accurate
@ -446,48 +790,55 @@ void retofinv_state::retofinv(machine_config &config)
screen.set_palette(m_palette);
GFXDECODE(config, m_gfxdecode, m_palette, gfx_retofinv);
PALETTE(config, m_palette, FUNC(retofinv_state::retofinv_palette), 256*2 + 64*16 + 64*16, 256);
PALETTE(config, m_palette, FUNC(retofinv_state::palette), 256*2 + 64*16 + 64*16, 256);
/* sound hardware */
// sound hardware
SPEAKER(config, "mono").front_center();
generic_latch_8_device &soundlatch(GENERIC_LATCH_8(config, "soundlatch"));
soundlatch.data_pending_callback().set_inputline(m_audiocpu, INPUT_LINE_IRQ0);
SN76489A(config, "sn1", XTAL(18'432'000)/6).add_route(ALL_OUTPUTS, "mono", 0.80); /* @IC5?; XTAL, chip type, and divider verified, 3.072 MHz */
SN76489A(config, "sn1", XTAL(18'432'000) / 6).add_route(ALL_OUTPUTS, "mono", 0.80); // @IC5?; XTAL, chip type, and divider verified, 3.072 MHz
SN76489A(config, "sn2", XTAL(18'432'000)/6).add_route(ALL_OUTPUTS, "mono", 0.80); /* @IC6?; XTAL, chip type, and divider verified, 3.072 MHz */
SN76489A(config, "sn2", XTAL(18'432'000) / 6).add_route(ALL_OUTPUTS, "mono", 0.80); // @IC6?; XTAL, chip type, and divider verified, 3.072 MHz
}
/* bootleg which has different palette clut */
void retofinv_state::retofinvb1(machine_config &config)
// original with MCU
void retofinv_mcu_state::retofinv(machine_config &config)
{
retofinv_base(config);
m_maincpu->set_addrmap(AS_PROGRAM, &retofinv_mcu_state::main_map);
m_mainlatch->q_out_cb<3>().set(m_68705, FUNC(taito68705_mcu_device::reset_w)).invert();
TAITO68705_MCU(config, m_68705, XTAL(18'432'000) / 6); // XTAL and divider verified, 3.072 MHz
}
// bootleg which has different palette CLUT
void retofinv_mcu_state::retofinvb1(machine_config &config)
{
retofinv(config);
m_palette->set_init(FUNC(retofinv_state::retofinv_bl_palette));
m_palette->set_init(FUNC(retofinv_mcu_state::bl_palette));
}
/* bootleg which has no mcu */
// bootleg which has no MCU
void retofinv_state::retofinvb_nomcu(machine_config &config)
{
retofinv(config);
retofinv_base(config);
m_maincpu->set_addrmap(AS_PROGRAM, &retofinv_state::bootleg_map);
m_mainlatch->q_out_cb<3>().set_nop();
config.device_remove("68705");
}
/* bootleg which has different palette clut and also has no mcu */
// bootleg which has different palette CLUT and also has no MCU
void retofinv_state::retofinvb1_nomcu(machine_config &config)
{
retofinvb1(config);
m_maincpu->set_addrmap(AS_PROGRAM, &retofinv_state::bootleg_map);
retofinvb_nomcu(config);
m_mainlatch->q_out_cb<3>().set_nop();
config.device_remove("68705");
m_palette->set_init(FUNC(retofinv_state::bl_palette));
}
/***************************************************************************
@ -512,10 +863,10 @@ ROM_START( retofinv )
ROM_REGION( 0x10000, "audiocpu", 0 )
ROM_LOAD( "a37__05.ic17", 0x0000, 0x2000, CRC(9025abea) SHA1(2f03e8572f23624d7cd1215a55109e97fd66e271) )
ROM_REGION( 0x0800, "68705:mcu", 0 ) /* 2k for the microcontroller */
ROM_LOAD( "a37__09.ic37", 0x00000, 0x0800, CRC(6a6d008d) SHA1(dce55b65db22ba97cb7b3d6d545575e7945d42ad) ) /* original mc68705p5 from Taito board */
ROM_REGION( 0x0800, "68705:mcu", 0 )
ROM_LOAD( "a37__09.ic37", 0x00000, 0x0800, CRC(6a6d008d) SHA1(dce55b65db22ba97cb7b3d6d545575e7945d42ad) ) // original mc68705p5 from Taito board
/* Interestingly enough, the security bit is NOT set on this MCU, but the
part is definitely a 68705P5 from an original Taito pcb running original
part is definitely a 68705P5 from an original Taito PCB running original
Taito code! Compare the MCU code to Taito games A17, A22, A23, A24, A30,
A34, A45, A47, A50, A54(and A51), A52, A64, A67, A68, probably others too,
MCU code between 0x420 and 0x73f is identical, and boot vector is 0x570.
@ -523,24 +874,24 @@ ROM_START( retofinv )
lookup table at 0x350-0x41f, and the "custom command code area" from
0x80-0x34F */
ROM_REGION( 0x02000, "gfx1", 0 )
ROM_REGION( 0x02000, "fgtiles", 0 )
ROM_LOAD( "a37__16.gfxboard.ic61", 0x0000, 0x2000, CRC(4e3f501c) SHA1(2d832f4038ae65bfdeedfab870f6f1176ec6b676) )
ROM_REGION( 0x08000, "gfx2", 0 )
ROM_REGION( 0x08000, "sprites", 0 )
ROM_LOAD( "a37__10.gfxboard.ic8", 0x0000, 0x2000, CRC(6afdeec8) SHA1(782fe0a8aea48c3c270318b7ba011fc6fce0db7a) )
ROM_LOAD( "a37__11.gfxboard.ic9", 0x2000, 0x2000, CRC(d3dc9da3) SHA1(0d98d6e993b5a4845a23802751023b7a593dce29) )
ROM_LOAD( "a37__12.gfxboard.ic10", 0x4000, 0x2000, CRC(d10b2eed) SHA1(3809a0adf935a119f9ee0d4c24f1456c35d2a6fa) )
ROM_LOAD( "a37__13.gfxboard.ic11", 0x6000, 0x2000, CRC(00ca6b3d) SHA1(08ce5b13d5ebc79cc803949f4ba9e630e6cd92b8) )
ROM_REGION( 0x04000, "gfx3", 0 )
ROM_REGION( 0x04000, "bgtiles", 0 )
ROM_LOAD( "a37__14.gfxboard.ic55", 0x0000, 0x2000, CRC(ef7f8651) SHA1(2d91057501e5e9c4255e0d55fff0d99c2a5be7e8) )
ROM_LOAD( "a37__15.gfxboard.ic56", 0x2000, 0x2000, CRC(03b40905) SHA1(c10d87796e8a6e6a2a37c6fb713821cc87299cc8) )
ROM_REGION( 0x0300, "palette", 0 )
// these three are Fujitsu 7052 PROMS, == 82S129 256x4bit TS proms
ROM_LOAD( "a37-06.ic13", 0x0000, 0x0100, CRC(e9643b8b) SHA1(7bbb92a42e7c3effb701fc7b2c24f2470f31b063) ) /* palette red bits */
ROM_LOAD( "a37-07.ic4", 0x0100, 0x0100, CRC(e8f34e11) SHA1(8f438561b8d46ffff00747ed8baf0ebb6a081615) ) /* palette green bits */
ROM_LOAD( "a37-08.ic3", 0x0200, 0x0100, CRC(50030af0) SHA1(e748ae0b8702b7d20fb65c254dceee23246b3d13) ) /* palette blue bits */
ROM_LOAD( "a37-06.ic13", 0x0000, 0x0100, CRC(e9643b8b) SHA1(7bbb92a42e7c3effb701fc7b2c24f2470f31b063) ) // palette red bits
ROM_LOAD( "a37-07.ic4", 0x0100, 0x0100, CRC(e8f34e11) SHA1(8f438561b8d46ffff00747ed8baf0ebb6a081615) ) // palette green bits
ROM_LOAD( "a37-08.ic3", 0x0200, 0x0100, CRC(50030af0) SHA1(e748ae0b8702b7d20fb65c254dceee23246b3d13) ) // palette blue bits
ROM_REGION( 0x0800, "clut", 0 )
// these four are Harris 7643 PROMS, == 82S137 1kx4 TS proms and form the tile color lookup tables; address is scrambled slightly.
@ -550,7 +901,7 @@ ROM_START( retofinv )
ROM_LOAD_NIB_LOW ( "a37-20.gfxboard.ic84", 0x0400, 0x0400, CRC(77a7aaf6) SHA1(61a474f1ad09b89ff8302f2d903b86a90823116c) )
ROM_END
ROM_START( retofinvb ) // bootleg with black-box reverse-engineered mcu. Unclear what the 'correct' rom labels are for this set.
ROM_START( retofinvb ) // bootleg with black-box reverse-engineered MCU. Unclear what the 'correct' ROM labels are for this set.
ROM_REGION( 0x10000, "maincpu", 0 )
ROM_LOAD( "a37-03.70", 0x0000, 0x2000, CRC(eae7459d) SHA1(c105f6adbd4c09decaad68ed13163d8f9b55e646) )
ROM_LOAD( "a37-02.71", 0x2000, 0x2000, CRC(72895e37) SHA1(42fb904338e9f92a79d587eac401d456e7fb6e55) )
@ -562,34 +913,34 @@ ROM_START( retofinvb ) // bootleg with black-box reverse-engineered mcu. Unclear
ROM_REGION( 0x10000, "audiocpu", 0 )
ROM_LOAD( "a37-05.17", 0x0000, 0x2000, CRC(9025abea) SHA1(2f03e8572f23624d7cd1215a55109e97fd66e271) )
ROM_REGION( 0x0800, "68705:mcu", 0 ) /* 2k for the microcontroller */
/* this MCU is from a bootleg board and is a 'clean room' reimplementation by bootleggers, and is not 100% functional (flip screen does not work, see notes at top of driver) */
ROM_REGION( 0x0800, "68705:mcu", 0 )
// this MCU is from a bootleg board and is a 'clean room' reimplementation by bootleggers, and is not 100% functional (flip screen does not work, see notes at top of driver)
ROM_LOAD( "a37-09_bootleg.37", 0x00000, 0x0800, CRC(79bd6ded) SHA1(4967e95b4461c1bfb4e933d1804677799014f77b) )
ROM_REGION( 0x02000, "gfx1", 0 )
ROM_REGION( 0x02000, "fgtiles", 0 )
ROM_LOAD( "a37-16.61", 0x0000, 0x2000, CRC(4e3f501c) SHA1(2d832f4038ae65bfdeedfab870f6f1176ec6b676) )
ROM_REGION( 0x08000, "gfx2", 0 )
ROM_REGION( 0x08000, "sprites", 0 )
ROM_LOAD( "a37-10.8", 0x0000, 0x2000, CRC(6afdeec8) SHA1(782fe0a8aea48c3c270318b7ba011fc6fce0db7a) )
ROM_LOAD( "a37-11.9", 0x2000, 0x2000, CRC(d3dc9da3) SHA1(0d98d6e993b5a4845a23802751023b7a593dce29) )
ROM_LOAD( "a37-12.10", 0x4000, 0x2000, CRC(d10b2eed) SHA1(3809a0adf935a119f9ee0d4c24f1456c35d2a6fa) )
ROM_LOAD( "a37-13.11", 0x6000, 0x2000, CRC(00ca6b3d) SHA1(08ce5b13d5ebc79cc803949f4ba9e630e6cd92b8) )
ROM_REGION( 0x04000, "gfx3", 0 )
ROM_REGION( 0x04000, "bgtiles", 0 )
ROM_LOAD( "a37-14.55", 0x0000, 0x2000, CRC(ef7f8651) SHA1(2d91057501e5e9c4255e0d55fff0d99c2a5be7e8) )
ROM_LOAD( "a37-15.56", 0x2000, 0x2000, CRC(03b40905) SHA1(c10d87796e8a6e6a2a37c6fb713821cc87299cc8) )
ROM_REGION( 0x0300, "palette", 0 )
ROM_LOAD( "a37-06.13", 0x0000, 0x0100, CRC(e9643b8b) SHA1(7bbb92a42e7c3effb701fc7b2c24f2470f31b063) ) /* palette red bits */
ROM_LOAD( "a37-07.4", 0x0100, 0x0100, CRC(e8f34e11) SHA1(8f438561b8d46ffff00747ed8baf0ebb6a081615) ) /* palette green bits */
ROM_LOAD( "a37-08.3", 0x0200, 0x0100, CRC(50030af0) SHA1(e748ae0b8702b7d20fb65c254dceee23246b3d13) ) /* palette blue bits */
ROM_LOAD( "a37-06.13", 0x0000, 0x0100, CRC(e9643b8b) SHA1(7bbb92a42e7c3effb701fc7b2c24f2470f31b063) ) // palette red bits
ROM_LOAD( "a37-07.4", 0x0100, 0x0100, CRC(e8f34e11) SHA1(8f438561b8d46ffff00747ed8baf0ebb6a081615) ) // palette green bits
ROM_LOAD( "a37-08.3", 0x0200, 0x0100, CRC(50030af0) SHA1(e748ae0b8702b7d20fb65c254dceee23246b3d13) ) // palette blue bits
// below may be incorrect; this bootleg may be supposed to use the same 4 proms as the main set above does.
ROM_REGION( 0x0800, "clut", 0 ) // bootleg uses a single 82s191 2kx8 TS prom for the tile color lookup tables; data is scrambled slightly.
// below may be incorrect; this bootleg may be supposed to use the same 4 PROMs as the main set above does.
ROM_REGION( 0x0800, "clut", 0 ) // bootleg uses a single 82s191 2kx8 TS PROM for the tile color lookup tables; data is scrambled slightly.
ROM_LOAD( "82s191n", 0x0000, 0x0800, CRC(93c891e3) SHA1(643a0107717b6a434432dda73a0102e6e8adbca7) )
ROM_END
ROM_START( retofinvb1 ) // bootleg with mcu hacked out. Unclear what the 'correct' rom labels are for this set other than the 3 main roms.
ROM_START( retofinvb1 ) // bootleg with MCU hacked out. Unclear what the 'correct' ROM labels are for this set other than the 3 main ROMs.
ROM_REGION( 0x10000, "maincpu", 0 )
ROM_LOAD( "roi.02", 0x0000, 0x2000, CRC(d98fd462) SHA1(fd35e13b7dee58639a01b040b8f84d42bb40b633) )
ROM_LOAD( "roi.01b", 0x2000, 0x2000, CRC(3379f930) SHA1(c67d687a10b6240bd6e2fbdb15e1b7d276e6fc07) )
@ -601,29 +952,29 @@ ROM_START( retofinvb1 ) // bootleg with mcu hacked out. Unclear what the 'correc
ROM_REGION( 0x10000, "audiocpu", 0 )
ROM_LOAD( "a37-05.17", 0x0000, 0x2000, CRC(9025abea) SHA1(2f03e8572f23624d7cd1215a55109e97fd66e271) )
ROM_REGION( 0x02000, "gfx1", 0 )
ROM_REGION( 0x02000, "fgtiles", 0 )
ROM_LOAD( "a37-16.61", 0x0000, 0x2000, CRC(4e3f501c) SHA1(2d832f4038ae65bfdeedfab870f6f1176ec6b676) )
ROM_REGION( 0x08000, "gfx2", 0 )
ROM_REGION( 0x08000, "sprites", 0 )
ROM_LOAD( "a37-10.8", 0x0000, 0x2000, CRC(6afdeec8) SHA1(782fe0a8aea48c3c270318b7ba011fc6fce0db7a) )
ROM_LOAD( "a37-11.9", 0x2000, 0x2000, CRC(d3dc9da3) SHA1(0d98d6e993b5a4845a23802751023b7a593dce29) )
ROM_LOAD( "a37-12.10", 0x4000, 0x2000, CRC(d10b2eed) SHA1(3809a0adf935a119f9ee0d4c24f1456c35d2a6fa) )
ROM_LOAD( "a37-13.11", 0x6000, 0x2000, CRC(00ca6b3d) SHA1(08ce5b13d5ebc79cc803949f4ba9e630e6cd92b8) )
ROM_REGION( 0x04000, "gfx3", 0 )
ROM_REGION( 0x04000, "bgtiles", 0 )
ROM_LOAD( "a37-14.55", 0x0000, 0x2000, CRC(ef7f8651) SHA1(2d91057501e5e9c4255e0d55fff0d99c2a5be7e8) )
ROM_LOAD( "a37-15.56", 0x2000, 0x2000, CRC(03b40905) SHA1(c10d87796e8a6e6a2a37c6fb713821cc87299cc8) )
ROM_REGION( 0x0300, "palette", 0 )
ROM_LOAD( "a37-06.13", 0x0000, 0x0100, CRC(e9643b8b) SHA1(7bbb92a42e7c3effb701fc7b2c24f2470f31b063) ) /* palette red bits */
ROM_LOAD( "a37-07.4", 0x0100, 0x0100, CRC(e8f34e11) SHA1(8f438561b8d46ffff00747ed8baf0ebb6a081615) ) /* palette green bits */
ROM_LOAD( "a37-08.3", 0x0200, 0x0100, CRC(50030af0) SHA1(e748ae0b8702b7d20fb65c254dceee23246b3d13) ) /* palette blue bits */
ROM_LOAD( "a37-06.13", 0x0000, 0x0100, CRC(e9643b8b) SHA1(7bbb92a42e7c3effb701fc7b2c24f2470f31b063) ) // palette red bits
ROM_LOAD( "a37-07.4", 0x0100, 0x0100, CRC(e8f34e11) SHA1(8f438561b8d46ffff00747ed8baf0ebb6a081615) ) // palette green bits
ROM_LOAD( "a37-08.3", 0x0200, 0x0100, CRC(50030af0) SHA1(e748ae0b8702b7d20fb65c254dceee23246b3d13) ) // palette blue bits
ROM_REGION( 0x0800, "clut", 0 ) // bootleg uses a single 82s191 2kx8 TS prom for the tile color lookup tables; data is scrambled slightly.
ROM_REGION( 0x0800, "clut", 0 ) // bootleg uses a single 82s191 2kx8 TS PROM for the tile color lookup tables; data is scrambled slightly.
ROM_LOAD( "82s191n", 0x0000, 0x0800, CRC(93c891e3) SHA1(643a0107717b6a434432dda73a0102e6e8adbca7) )
ROM_END
ROM_START( retofinvb2 ) // bootleg with mcu hacked out. Unclear what the 'correct' rom labels are for this set other than 2 of the 3 main roms.
ROM_START( retofinvb2 ) // bootleg with MCU hacked out. Unclear what the 'correct' ROM labels are for this set other than 2 of the 3 main ROMs.
ROM_REGION( 0x10000, "maincpu", 0 )
ROM_LOAD( "ri-c.1e", 0x0000, 0x2000, CRC(e3c31260) SHA1(cc8774251c567da2e4a54091223927c95f497fe8) )
ROM_LOAD( "roi.01b", 0x2000, 0x2000, CRC(3379f930) SHA1(c67d687a10b6240bd6e2fbdb15e1b7d276e6fc07) ) // likely should be "ri-b.1d"
@ -635,25 +986,25 @@ ROM_START( retofinvb2 ) // bootleg with mcu hacked out. Unclear what the 'correc
ROM_REGION( 0x10000, "audiocpu", 0 )
ROM_LOAD( "a37-05.17", 0x0000, 0x2000, CRC(9025abea) SHA1(2f03e8572f23624d7cd1215a55109e97fd66e271) )
ROM_REGION( 0x02000, "gfx1", 0 )
ROM_REGION( 0x02000, "fgtiles", 0 )
ROM_LOAD( "a37-16.61", 0x0000, 0x2000, CRC(4e3f501c) SHA1(2d832f4038ae65bfdeedfab870f6f1176ec6b676) )
ROM_REGION( 0x08000, "gfx2", 0 )
ROM_REGION( 0x08000, "sprites", 0 )
ROM_LOAD( "a37-10.8", 0x0000, 0x2000, CRC(6afdeec8) SHA1(782fe0a8aea48c3c270318b7ba011fc6fce0db7a) )
ROM_LOAD( "a37-11.9", 0x2000, 0x2000, CRC(d3dc9da3) SHA1(0d98d6e993b5a4845a23802751023b7a593dce29) )
ROM_LOAD( "a37-12.10", 0x4000, 0x2000, CRC(d10b2eed) SHA1(3809a0adf935a119f9ee0d4c24f1456c35d2a6fa) )
ROM_LOAD( "a37-13.11", 0x6000, 0x2000, CRC(00ca6b3d) SHA1(08ce5b13d5ebc79cc803949f4ba9e630e6cd92b8) )
ROM_REGION( 0x04000, "gfx3", 0 )
ROM_REGION( 0x04000, "bgtiles", 0 )
ROM_LOAD( "a37-14.55", 0x0000, 0x2000, CRC(ef7f8651) SHA1(2d91057501e5e9c4255e0d55fff0d99c2a5be7e8) )
ROM_LOAD( "a37-15.56", 0x2000, 0x2000, CRC(03b40905) SHA1(c10d87796e8a6e6a2a37c6fb713821cc87299cc8) )
ROM_REGION( 0x0300, "palette", 0 )
ROM_LOAD( "a37-06.13", 0x0000, 0x0100, CRC(e9643b8b) SHA1(7bbb92a42e7c3effb701fc7b2c24f2470f31b063) ) /* palette red bits */
ROM_LOAD( "a37-07.4", 0x0100, 0x0100, CRC(e8f34e11) SHA1(8f438561b8d46ffff00747ed8baf0ebb6a081615) ) /* palette green bits */
ROM_LOAD( "a37-08.3", 0x0200, 0x0100, CRC(50030af0) SHA1(e748ae0b8702b7d20fb65c254dceee23246b3d13) ) /* palette blue bits */
ROM_LOAD( "a37-06.13", 0x0000, 0x0100, CRC(e9643b8b) SHA1(7bbb92a42e7c3effb701fc7b2c24f2470f31b063) ) // palette red bits
ROM_LOAD( "a37-07.4", 0x0100, 0x0100, CRC(e8f34e11) SHA1(8f438561b8d46ffff00747ed8baf0ebb6a081615) ) // palette green bits
ROM_LOAD( "a37-08.3", 0x0200, 0x0100, CRC(50030af0) SHA1(e748ae0b8702b7d20fb65c254dceee23246b3d13) ) // palette blue bits
ROM_REGION( 0x0800, "clut", 0 ) // bootleg uses a single 82s191 2kx8 TS prom for the tile color lookup tables; data is scrambled slightly.
ROM_REGION( 0x0800, "clut", 0 ) // bootleg uses a single 82s191 2kx8 TS PROM for the tile color lookup tables; data is scrambled slightly.
ROM_LOAD( "82s191n", 0x0000, 0x0800, CRC(93c891e3) SHA1(643a0107717b6a434432dda73a0102e6e8adbca7) )
ROM_END
@ -669,23 +1020,23 @@ ROM_START( retofinvb3 ) // Italian bootleg PCB. Only maincpu ROMs differ from pa
ROM_REGION( 0x10000, "audiocpu", 0 )
ROM_LOAD( "5.bin", 0x0000, 0x2000, CRC(9025abea) SHA1(2f03e8572f23624d7cd1215a55109e97fd66e271) )
ROM_REGION( 0x02000, "gfx1", 0 )
ROM_REGION( 0x02000, "fgtiles", 0 )
ROM_LOAD( "16.7", 0x0000, 0x2000, CRC(4e3f501c) SHA1(2d832f4038ae65bfdeedfab870f6f1176ec6b676) )
ROM_REGION( 0x08000, "gfx2", 0 )
ROM_REGION( 0x08000, "sprites", 0 )
ROM_LOAD( "10.1", 0x0000, 0x2000, CRC(6afdeec8) SHA1(782fe0a8aea48c3c270318b7ba011fc6fce0db7a) )
ROM_LOAD( "11.2", 0x2000, 0x2000, CRC(d3dc9da3) SHA1(0d98d6e993b5a4845a23802751023b7a593dce29) )
ROM_LOAD( "12.3", 0x4000, 0x2000, CRC(d10b2eed) SHA1(3809a0adf935a119f9ee0d4c24f1456c35d2a6fa) )
ROM_LOAD( "13.4", 0x6000, 0x2000, CRC(00ca6b3d) SHA1(08ce5b13d5ebc79cc803949f4ba9e630e6cd92b8) )
ROM_REGION( 0x04000, "gfx3", 0 )
ROM_REGION( 0x04000, "bgtiles", 0 )
ROM_LOAD( "14.5", 0x0000, 0x2000, CRC(ef7f8651) SHA1(2d91057501e5e9c4255e0d55fff0d99c2a5be7e8) )
ROM_LOAD( "15.6", 0x2000, 0x2000, CRC(03b40905) SHA1(c10d87796e8a6e6a2a37c6fb713821cc87299cc8) )
ROM_REGION( 0x0300, "palette", 0 )
ROM_LOAD( "74s287.b", 0x0000, 0x0100, CRC(e9643b8b) SHA1(7bbb92a42e7c3effb701fc7b2c24f2470f31b063) ) /* palette red bits */
ROM_LOAD( "74s287.c", 0x0100, 0x0100, CRC(e8f34e11) SHA1(8f438561b8d46ffff00747ed8baf0ebb6a081615) ) /* palette green bits */
ROM_LOAD( "74s287.a", 0x0200, 0x0100, CRC(50030af0) SHA1(e748ae0b8702b7d20fb65c254dceee23246b3d13) ) /* palette blue bits */
ROM_LOAD( "74s287.b", 0x0000, 0x0100, CRC(e9643b8b) SHA1(7bbb92a42e7c3effb701fc7b2c24f2470f31b063) ) // palette red bits
ROM_LOAD( "74s287.c", 0x0100, 0x0100, CRC(e8f34e11) SHA1(8f438561b8d46ffff00747ed8baf0ebb6a081615) ) // palette green bits
ROM_LOAD( "74s287.a", 0x0200, 0x0100, CRC(50030af0) SHA1(e748ae0b8702b7d20fb65c254dceee23246b3d13) ) // palette blue bits
ROM_REGION( 0x0800, "clut", 0 )
ROM_LOAD_NIB_HIGH( "6353-1.a", 0x0000, 0x0400, CRC(c63cf10e) SHA1(bca8823aef31ab8f4c22201c4efd51f9a4124c8f) )
@ -694,8 +1045,11 @@ ROM_START( retofinvb3 ) // Italian bootleg PCB. Only maincpu ROMs differ from pa
ROM_LOAD_NIB_LOW ( "6353-1.c", 0x0400, 0x0400, CRC(77a7aaf6) SHA1(61a474f1ad09b89ff8302f2d903b86a90823116c) )
ROM_END
GAME( 1985, retofinv, 0, retofinv, retofinv, retofinv_state, empty_init, ROT90, "Taito Corporation", "Return of the Invaders", MACHINE_SUPPORTS_SAVE )
GAME( 1985, retofinvb, retofinv, retofinvb1, retofinv, retofinv_state, empty_init, ROT90, "bootleg", "Return of the Invaders (bootleg w/MCU)", MACHINE_SUPPORTS_SAVE )
GAME( 1985, retofinvb1, retofinv, retofinvb1_nomcu, retofinv, retofinv_state, empty_init, ROT90, "bootleg", "Return of the Invaders (bootleg no MCU set 1)", MACHINE_SUPPORTS_SAVE )
GAME( 1985, retofinvb2, retofinv, retofinvb1_nomcu, retofin2, retofinv_state, empty_init, ROT90, "bootleg", "Return of the Invaders (bootleg no MCU set 2)", MACHINE_SUPPORTS_SAVE )
GAME( 1985, retofinvb3, retofinv, retofinvb_nomcu, retofinv, retofinv_state, empty_init, ROT90, "bootleg", "Return of the Invaders (bootleg no MCU set 3)", MACHINE_SUPPORTS_SAVE )
} // anonymous namespace
GAME( 1985, retofinv, 0, retofinv, retofinv, retofinv_mcu_state, empty_init, ROT90, "Taito Corporation", "Return of the Invaders", MACHINE_SUPPORTS_SAVE )
GAME( 1985, retofinvb, retofinv, retofinvb1, retofinv, retofinv_mcu_state, empty_init, ROT90, "bootleg", "Return of the Invaders (bootleg w/MCU)", MACHINE_SUPPORTS_SAVE )
GAME( 1985, retofinvb1, retofinv, retofinvb1_nomcu, retofinv, retofinv_state, empty_init, ROT90, "bootleg", "Return of the Invaders (bootleg no MCU set 1)", MACHINE_SUPPORTS_SAVE )
GAME( 1985, retofinvb2, retofinv, retofinvb1_nomcu, retofin2, retofinv_state, empty_init, ROT90, "bootleg", "Return of the Invaders (bootleg no MCU set 2)", MACHINE_SUPPORTS_SAVE )
GAME( 1985, retofinvb3, retofinv, retofinvb_nomcu, retofinv, retofinv_state, empty_init, ROT90, "bootleg", "Return of the Invaders (bootleg no MCU set 3)", MACHINE_SUPPORTS_SAVE )

View File

@ -1,95 +0,0 @@
// license:BSD-3-Clause
// copyright-holders:Jarek Parchanski, Andrea Mazzoleni
#ifndef MAME_TAITO_RETOFINV_H
#define MAME_TAITO_RETOFINV_H
#pragma once
#include "taito68705.h"
#include "machine/74259.h"
#include "emupal.h"
#include "tilemap.h"
class retofinv_state : public driver_device
{
public:
retofinv_state(const machine_config &mconfig, device_type type, const char *tag)
: driver_device(mconfig, type, tag)
, m_maincpu(*this, "maincpu")
, m_audiocpu(*this, "audiocpu")
, m_subcpu(*this, "sub")
, m_68705(*this, "68705")
, m_gfxdecode(*this, "gfxdecode")
, m_palette(*this, "palette")
, m_mainlatch(*this, "mainlatch")
, m_fg_videoram(*this, "fg_videoram")
, m_sharedram(*this, "sharedram")
, m_bg_videoram(*this, "bg_videoram")
{
}
void retofinvb1_nomcu(machine_config &config);
void retofinvb_nomcu(machine_config &config);
void retofinv(machine_config &config);
void retofinvb1(machine_config &config);
protected:
virtual void machine_start() override;
virtual void video_start() override;
private:
void cpu2_m6000_w(uint8_t data);
uint8_t cpu0_mf800_r();
DECLARE_WRITE_LINE_MEMBER(irq0_ack_w);
DECLARE_WRITE_LINE_MEMBER(irq1_ack_w);
void coincounter_w(uint8_t data);
DECLARE_WRITE_LINE_MEMBER(coinlockout_w);
uint8_t mcu_status_r();
void bg_videoram_w(offs_t offset, uint8_t data);
void fg_videoram_w(offs_t offset, uint8_t data);
void gfx_ctrl_w(offs_t offset, uint8_t data);
TILEMAP_MAPPER_MEMBER(tilemap_scan);
TILE_GET_INFO_MEMBER(bg_get_tile_info);
TILE_GET_INFO_MEMBER(fg_get_tile_info);
void retofinv_palette(palette_device &palette) const;
void retofinv_bl_palette(palette_device &palette) const;
uint32_t screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect);
INTERRUPT_GEN_MEMBER(main_vblank_irq);
INTERRUPT_GEN_MEMBER(sub_vblank_irq);
void bootleg_map(address_map &map);
void main_map(address_map &map);
void sound_map(address_map &map);
void sub_map(address_map &map);
void draw_sprites(bitmap_ind16 &bitmap);
required_device<cpu_device> m_maincpu;
required_device<cpu_device> m_audiocpu;
required_device<cpu_device> m_subcpu;
optional_device<taito68705_mcu_device> m_68705;
required_device<gfxdecode_device> m_gfxdecode;
required_device<palette_device> m_palette;
required_device<ls259_device> m_mainlatch;
required_shared_ptr<uint8_t> m_fg_videoram;
required_shared_ptr<uint8_t> m_sharedram;
required_shared_ptr<uint8_t> m_bg_videoram;
uint8_t m_main_irq_mask = 0;
uint8_t m_sub_irq_mask = 0;
uint8_t m_cpu2_m6000 = 0;
int m_fg_bank = 0;
int m_bg_bank = 0;
tilemap_t *m_bg_tilemap = nullptr;
tilemap_t *m_fg_tilemap = nullptr;
};
#endif // MAME_TAITO_RETOFINV_H

View File

@ -1,251 +0,0 @@
// license:BSD-3-Clause
// copyright-holders:Jarek Parchanski, Andrea Mazzoleni
/***************************************************************************
video.c
Functions to emulate the video hardware of the machine.
***************************************************************************/
#include "emu.h"
#include "retofinv.h"
void retofinv_state::retofinv_palette(palette_device &palette) const
{
uint8_t const *const palette_prom = memregion("palette")->base();
uint8_t const *const clut_prom = memregion("clut")->base();
// create a lookup table for the palette
for (int i = 0; i < 0x100; i++)
{
int const r = pal4bit(palette_prom[i | 0x000]);
int const g = pal4bit(palette_prom[i | 0x100]);
int const b = pal4bit(palette_prom[i | 0x200]);
palette.set_indirect_color(i, rgb_t(r, g, b));
}
// fg chars (1bpp)
for (int i = 0; i < 0x200; i++)
{
uint8_t const ctabentry = (i & 0x01) ? (i >> 1) : 0;
palette.set_pen_indirect(i, ctabentry);
}
// sprites and bg tiles clut
for (int i = 0; i < 0x800; i++)
{
// descramble the address
int const j = bitswap<16>(i, 15,14,13,12,11,10,9,8,7,6,5,4,3,0,1,2);
palette.set_pen_indirect(i + 0x200, clut_prom[j]);
}
}
void retofinv_state::retofinv_bl_palette(palette_device &palette) const
{
uint8_t const *const palette_prom = memregion("palette")->base();
uint8_t const *const clut_prom = memregion("clut")->base();
// create a lookup table for the palette
for (int i = 0; i < 0x100; i++)
{
int const r = pal4bit(palette_prom[i | 0x000]);
int const g = pal4bit(palette_prom[i | 0x100]);
int const b = pal4bit(palette_prom[i | 0x200]);
palette.set_indirect_color(i, rgb_t(r, g, b));
}
// fg chars (1bpp)
for (int i = 0; i < 0x200; i++)
{
uint8_t const ctabentry = (i & 0x01) ? (i >> 1) : 0;
palette.set_pen_indirect(i, ctabentry);
}
// sprites and bg tiles clut
for (int i = 0; i < 0x800; i++)
{
// descramble the data
palette.set_pen_indirect(i + 0x200, bitswap<8>(clut_prom[i], 4,5,6,7,3,2,1,0));
}
}
/***************************************************************************
Callbacks for the TileMap code
***************************************************************************/
/* convert from 32x32 to 36x28 */
TILEMAP_MAPPER_MEMBER(retofinv_state::tilemap_scan)
{
row += 2;
col -= 2;
if (col & 0x20)
return ((col & 0x1f) << 5) + row;
else
return (row << 5) + col;
}
TILE_GET_INFO_MEMBER(retofinv_state::bg_get_tile_info)
{
tileinfo.set(2,
m_bg_videoram[tile_index] + 256 * m_bg_bank,
m_bg_videoram[0x400 + tile_index] & 0x3f,
0);
}
TILE_GET_INFO_MEMBER(retofinv_state::fg_get_tile_info)
{
int color = m_fg_videoram[0x400 + tile_index];
tileinfo.group = color;
tileinfo.set(0,
m_fg_videoram[tile_index] + 256 * m_fg_bank,
color,
0);
}
/***************************************************************************
Start the video hardware emulation.
***************************************************************************/
void retofinv_state::video_start()
{
m_bg_tilemap = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(*this, FUNC(retofinv_state::bg_get_tile_info)), tilemap_mapper_delegate(*this, FUNC(retofinv_state::tilemap_scan)), 8, 8, 36, 28);
m_fg_tilemap = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(*this, FUNC(retofinv_state::fg_get_tile_info)), tilemap_mapper_delegate(*this, FUNC(retofinv_state::tilemap_scan)), 8, 8, 36, 28);
m_fg_tilemap->configure_groups(*m_gfxdecode->gfx(0), 0);
save_item(NAME(m_fg_bank));
save_item(NAME(m_bg_bank));
}
/***************************************************************************
Memory handlers
***************************************************************************/
void retofinv_state::bg_videoram_w(offs_t offset, uint8_t data)
{
m_bg_videoram[offset] = data;
m_bg_tilemap->mark_tile_dirty(offset & 0x3ff);
}
void retofinv_state::fg_videoram_w(offs_t offset, uint8_t data)
{
m_fg_videoram[offset] = data;
m_fg_tilemap->mark_tile_dirty(offset & 0x3ff);
}
void retofinv_state::gfx_ctrl_w(offs_t offset, uint8_t data)
{
switch (offset)
{
case 0:
flip_screen_set(data & 1);
break;
case 1:
if (m_fg_bank != (data & 1))
{
m_fg_bank = data & 1;
m_fg_tilemap->mark_all_dirty();
}
break;
case 2:
if (m_bg_bank != (data & 1))
{
m_bg_bank = data & 1;
m_bg_tilemap->mark_all_dirty();
}
break;
}
}
/***************************************************************************
Display refresh
***************************************************************************/
void retofinv_state::draw_sprites(bitmap_ind16 &bitmap)
{
uint8_t *spriteram = m_sharedram + 0x0780;
uint8_t *spriteram_2 = m_sharedram + 0x0f80;
uint8_t *spriteram_3 = m_sharedram + 0x1780;
int offs;
const rectangle spritevisiblearea(2*8, 34*8-1, 0*8, 28*8-1);
for (offs = 0;offs < 0x80;offs += 2)
{
static const int gfx_offs[2][2] =
{
{ 0, 1 },
{ 2, 3 }
};
int sprite = spriteram[offs];
int color = spriteram[offs+1] & 0x3f;
int sx = ((spriteram_2[offs+1] << 1) + ((spriteram_3[offs+1] & 0x80) >> 7)) - 39;
int sy = 256 - ((spriteram_2[offs] << 1) + ((spriteram_3[offs] & 0x80) >> 7)) + 1;
/* not sure about the flipping, it's hardly ever used (mostly for shots) */
int flipx = (spriteram_3[offs] & 0x01);
int flipy = (spriteram_3[offs] & 0x02) >> 1;
int sizey = (spriteram_3[offs] & 0x04) >> 2;
int sizex = (spriteram_3[offs] & 0x08) >> 3;
int x,y;
sprite &= ~sizex;
sprite &= ~(sizey << 1);
if (flip_screen())
{
flipx ^= 1;
flipy ^= 1;
}
sy -= 16 * sizey;
sy = (sy & 0xff) - 32; // fix wraparound
for (y = 0;y <= sizey;y++)
{
for (x = 0;x <= sizex;x++)
{
m_gfxdecode->gfx(1)->transmask(bitmap,spritevisiblearea,
sprite + gfx_offs[y ^ (sizey * flipy)][x ^ (sizex * flipx)],
color,
flipx,flipy,
sx + 16*x,sy + 16*y,
m_palette->transpen_mask(*m_gfxdecode->gfx(1), color, 0xff));
}
}
}
}
uint32_t retofinv_state::screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
{
m_bg_tilemap->draw(screen, bitmap, cliprect, 0,0);
draw_sprites(bitmap);
m_fg_tilemap->draw(screen, bitmap, cliprect, 0,0);
return 0;
}