Black Touch '96 hardware is a Korean clone of 'SNK68' hardware so start to refactor, and share code

This commit is contained in:
David Haywood 2016-03-01 19:35:32 +00:00
parent 7d28d39b8c
commit 3b3c516a3d
7 changed files with 306 additions and 401 deletions

View File

@ -3327,6 +3327,8 @@ files {
MAME_DIR .. "src/mame/drivers/snk68.cpp",
MAME_DIR .. "src/mame/includes/snk68.h",
MAME_DIR .. "src/mame/video/snk68.cpp",
MAME_DIR .. "src/mame/video/snk68_spr.cpp",
}
createMAMEProjects(_target, _subtarget, "sony")

View File

@ -44,31 +44,8 @@ Notes:
2008-07
Added Dip Locations based on Service Mode
The video system is a little weird, and looks like it was overdesigned for
what the hardware is capable of.
The video RAM can be viewed as 8 'banks', the first bank is the sprite 'list'
The other video banks contain 1x32 tile strips which are the sprites.
For every tile strip the first bank contains an x/y position, entries
which would coincide with strips in the first bank are left blank, presumably
due to this bank being the actual list.
This would suggest the hardware is capable of drawing 31x32 (992) sprites,
each made of 1x32 tile strips, however the game only ever appears to use 3
banks of tile strips (96 sprites)
In practice it seems like the hardware can probably only draw these 3 banks
as separate layers with seemingly hardcoded priority levels, despite the odd
design.
Furthermore there are two sets of graphics, background tiles and 'sprite'
tiles which are of different bitdepths, but are addressed in the same way.
Tilemap hookup is just to make viewing easier, it's not used for rendering
There is also an additional 8x8 text layer..
The hardware is cloned from 'snk68' with some extra capabilities
the drivers can probably be merged.
Bugs:
@ -88,7 +65,7 @@ There are some unmapped writes past the end of text ram too
#include "cpu/pic16c5x/pic16c5x.h"
#include "cpu/m68000/m68000.h"
#include "sound/okim6295.h"
#include "video/snk68_spr.h"
class blackt96_state : public driver_device
{
@ -96,27 +73,13 @@ public:
blackt96_state(const machine_config &mconfig, device_type type, const char *tag)
: driver_device(mconfig, type, tag),
m_tilemapram(*this, "tilemapram"),
m_spriteram0(*this, "spriteram0"),
m_spriteram1(*this, "spriteram1"),
m_spriteram2(*this, "spriteram2"),
m_spriteram3(*this, "spriteram3"),
m_spriteram4(*this, "spriteram4"),
m_spriteram5(*this, "spriteram5"),
m_spriteram6(*this, "spriteram6"),
m_spriteram7(*this, "spriteram7"),
m_maincpu(*this, "maincpu"),
m_gfxdecode(*this, "gfxdecode"),
m_palette(*this, "palette") { }
m_palette(*this, "palette"),
m_sprites(*this, "sprites")
{ }
required_shared_ptr<UINT16> m_tilemapram;
required_shared_ptr<UINT16> m_spriteram0;
required_shared_ptr<UINT16> m_spriteram1;
required_shared_ptr<UINT16> m_spriteram2;
required_shared_ptr<UINT16> m_spriteram3;
required_shared_ptr<UINT16> m_spriteram4;
required_shared_ptr<UINT16> m_spriteram5;
required_shared_ptr<UINT16> m_spriteram6;
required_shared_ptr<UINT16> m_spriteram7;
DECLARE_WRITE16_MEMBER(blackt96_c0000_w);
DECLARE_WRITE16_MEMBER(blackt96_80000_w);
DECLARE_READ_LINE_MEMBER(PIC16C5X_T0_clk_r);
@ -126,147 +89,35 @@ public:
DECLARE_READ8_MEMBER(blackt96_soundio_port02_r);
DECLARE_WRITE8_MEMBER(blackt96_soundio_port02_w);
void tile_callback(int &tile, int& fx, int& fy, int& region);
DECLARE_READ16_MEMBER( random_r )
{
return machine().rand();
}
DECLARE_WRITE16_MEMBER(bg_videoram0_w);
DECLARE_WRITE16_MEMBER(bg_videoram1_w);
DECLARE_WRITE16_MEMBER(bg_videoram2_w);
DECLARE_WRITE16_MEMBER(bg_videoram3_w);
DECLARE_WRITE16_MEMBER(bg_videoram4_w);
DECLARE_WRITE16_MEMBER(bg_videoram5_w);
DECLARE_WRITE16_MEMBER(bg_videoram6_w);
DECLARE_WRITE16_MEMBER(bg_videoram7_w);
UINT16* m_spriteram[8];
tilemap_t *m_bg_tilemap[8];
UINT8 m_txt_bank;
TILE_GET_INFO_MEMBER(get_bg0_tile_info);
TILE_GET_INFO_MEMBER(get_bg1_tile_info);
TILE_GET_INFO_MEMBER(get_bg2_tile_info);
TILE_GET_INFO_MEMBER(get_bg3_tile_info);
TILE_GET_INFO_MEMBER(get_bg4_tile_info);
TILE_GET_INFO_MEMBER(get_bg5_tile_info);
TILE_GET_INFO_MEMBER(get_bg6_tile_info);
TILE_GET_INFO_MEMBER(get_bg7_tile_info);
virtual void video_start() override;
UINT32 screen_update_blackt96(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect);
void draw_strip(bitmap_ind16 &bitmap, const rectangle &cliprect, int page, int column);
void draw_page(bitmap_ind16 &bitmap, const rectangle &cliprect, int page);
required_device<cpu_device> m_maincpu;
required_device<gfxdecode_device> m_gfxdecode;
required_device<palette_device> m_palette;
required_device<snk68_spr_device> m_sprites;
};
#define GET_INFO( ram ) \
int tileno = (ram[tile_index*2+1] & 0x1fff); \
int rgn = (ram[tile_index*2+1] & 0x2000) >> 13; \
int flipyx = (ram[tile_index*2+1] & 0xc000)>>14; \
int col = (ram[tile_index*2] & 0x00ff); \
if (rgn==1) col >>=4; \
SET_TILE_INFO_MEMBER(1-rgn, tileno, col, TILE_FLIPYX(flipyx));
TILE_GET_INFO_MEMBER(blackt96_state::get_bg0_tile_info){ GET_INFO(m_spriteram0); }
TILE_GET_INFO_MEMBER(blackt96_state::get_bg1_tile_info){ GET_INFO(m_spriteram1); }
TILE_GET_INFO_MEMBER(blackt96_state::get_bg2_tile_info){ GET_INFO(m_spriteram2); }
TILE_GET_INFO_MEMBER(blackt96_state::get_bg3_tile_info){ GET_INFO(m_spriteram3); }
TILE_GET_INFO_MEMBER(blackt96_state::get_bg4_tile_info){ GET_INFO(m_spriteram4); }
TILE_GET_INFO_MEMBER(blackt96_state::get_bg5_tile_info){ GET_INFO(m_spriteram5); }
TILE_GET_INFO_MEMBER(blackt96_state::get_bg6_tile_info){ GET_INFO(m_spriteram6); }
TILE_GET_INFO_MEMBER(blackt96_state::get_bg7_tile_info){ GET_INFO(m_spriteram7); }
WRITE16_MEMBER(blackt96_state::bg_videoram0_w) { COMBINE_DATA(&m_spriteram0[offset]); m_bg_tilemap[0]->mark_tile_dirty(offset/2); }
WRITE16_MEMBER(blackt96_state::bg_videoram1_w) { COMBINE_DATA(&m_spriteram1[offset]); m_bg_tilemap[1]->mark_tile_dirty(offset/2); }
WRITE16_MEMBER(blackt96_state::bg_videoram2_w) { COMBINE_DATA(&m_spriteram2[offset]); m_bg_tilemap[2]->mark_tile_dirty(offset/2); }
WRITE16_MEMBER(blackt96_state::bg_videoram3_w) { COMBINE_DATA(&m_spriteram3[offset]); m_bg_tilemap[3]->mark_tile_dirty(offset/2); }
WRITE16_MEMBER(blackt96_state::bg_videoram4_w) { COMBINE_DATA(&m_spriteram4[offset]); m_bg_tilemap[4]->mark_tile_dirty(offset/2); }
WRITE16_MEMBER(blackt96_state::bg_videoram5_w) { COMBINE_DATA(&m_spriteram5[offset]); m_bg_tilemap[5]->mark_tile_dirty(offset/2); }
WRITE16_MEMBER(blackt96_state::bg_videoram6_w) { COMBINE_DATA(&m_spriteram6[offset]); m_bg_tilemap[6]->mark_tile_dirty(offset/2); }
WRITE16_MEMBER(blackt96_state::bg_videoram7_w) { COMBINE_DATA(&m_spriteram7[offset]); m_bg_tilemap[7]->mark_tile_dirty(offset/2); }
void blackt96_state::video_start()
{
m_bg_tilemap[0] = &machine().tilemap().create(m_gfxdecode, tilemap_get_info_delegate(FUNC(blackt96_state::get_bg0_tile_info),this), TILEMAP_SCAN_COLS, 16, 16, 32, 32);
m_bg_tilemap[1] = &machine().tilemap().create(m_gfxdecode, tilemap_get_info_delegate(FUNC(blackt96_state::get_bg1_tile_info),this), TILEMAP_SCAN_COLS, 16, 16, 32, 32);
m_bg_tilemap[2] = &machine().tilemap().create(m_gfxdecode, tilemap_get_info_delegate(FUNC(blackt96_state::get_bg2_tile_info),this), TILEMAP_SCAN_COLS, 16, 16, 32, 32);
m_bg_tilemap[3] = &machine().tilemap().create(m_gfxdecode, tilemap_get_info_delegate(FUNC(blackt96_state::get_bg3_tile_info),this), TILEMAP_SCAN_COLS, 16, 16, 32, 32);
m_bg_tilemap[4] = &machine().tilemap().create(m_gfxdecode, tilemap_get_info_delegate(FUNC(blackt96_state::get_bg4_tile_info),this), TILEMAP_SCAN_COLS, 16, 16, 32, 32);
m_bg_tilemap[5] = &machine().tilemap().create(m_gfxdecode, tilemap_get_info_delegate(FUNC(blackt96_state::get_bg5_tile_info),this), TILEMAP_SCAN_COLS, 16, 16, 32, 32);
m_bg_tilemap[6] = &machine().tilemap().create(m_gfxdecode, tilemap_get_info_delegate(FUNC(blackt96_state::get_bg6_tile_info),this), TILEMAP_SCAN_COLS, 16, 16, 32, 32);
m_bg_tilemap[7] = &machine().tilemap().create(m_gfxdecode, tilemap_get_info_delegate(FUNC(blackt96_state::get_bg7_tile_info),this), TILEMAP_SCAN_COLS, 16, 16, 32, 32);
m_spriteram[0] = m_spriteram0;
m_spriteram[1] = m_spriteram1;
m_spriteram[2] = m_spriteram2;
m_spriteram[3] = m_spriteram3;
m_spriteram[4] = m_spriteram4;
m_spriteram[5] = m_spriteram5;
m_spriteram[6] = m_spriteram6;
m_spriteram[7] = m_spriteram7;
}
void blackt96_state::draw_strip(bitmap_ind16 &bitmap, const rectangle &cliprect, int page, int column)
{
/* the very first 'page' in the spriteram contains the x/y positions for each tile strip */
gfx_element *gfxbg = m_gfxdecode->gfx(0);
gfx_element *gfxspr = m_gfxdecode->gfx(1);
int base = column * (0x80/2);
base += page * 2;
/* ---- ---- ---x xxxx
xxxx ---y yyyy yyyy */
int xx= ((m_spriteram[0][base+0]&0x001f)<<4) | (m_spriteram[0][base+1]&0xf000)>>12;
int yy = ((m_spriteram[0][base+1]&0x1ff));
if (xx&0x100) xx-=0x200;
yy = 0x1ff-yy;
if (yy&0x100) yy-=0x200;
yy -= 15;
UINT16* base2 = m_spriteram[page]+column * (0x80/2);
for (int y=0;y<32;y++)
{
/* -Xtt tttt tttt tttt
---- ---- cccc cccc */
UINT16 tile = (base2[y*2+1]&0x3fff);
UINT16 flipx = (base2[y*2+1]&0x4000);
UINT16 colour = (base2[y*2]&0x00ff);
if (tile&0x2000)
{
gfxbg->transpen(bitmap,cliprect,tile&0x1fff,colour>>4,flipx,0,xx,yy+y*16,0);
}
else
{
gfxspr->transpen(bitmap,cliprect,tile&0x1fff,colour,flipx,0,xx,yy+y*16,0);
}
}
}
void blackt96_state::draw_page(bitmap_ind16 &bitmap, const rectangle &cliprect, int page)
{
for (int strip=0;strip<32;strip++)
{
draw_strip(bitmap, cliprect, page, strip);
}
}
UINT32 blackt96_state::screen_update_blackt96(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
{
bitmap.fill(m_palette->black_pen(), cliprect);
draw_page(bitmap, cliprect, 2); // bg
draw_page(bitmap, cliprect, 3); // lower pri sprites
draw_page(bitmap, cliprect, 1); // higher pri sprites
m_sprites->draw_sprites_all(bitmap, cliprect);
/* Text Layer */
int count = 0;
@ -279,7 +130,7 @@ UINT32 blackt96_state::screen_update_blackt96(screen_device &screen, bitmap_ind1
{
UINT16 tile = (m_tilemapram[count*2]&0xff);
tile += m_txt_bank * 0x100;
gfx->transpen(bitmap,cliprect,tile,0,0,0,x*8,-16+y*8,0);
gfx->transpen(bitmap,cliprect,tile,0,0,0,x*8,y*8,0);
count++;
}
}
@ -319,17 +170,7 @@ static ADDRESS_MAP_START( blackt96_map, AS_PROGRAM, 16, blackt96_state )
AM_RANGE(0x0f0008, 0x0f0009) AM_READ_PORT("DSW2")
AM_RANGE(0x100000, 0x100fff) AM_RAM AM_SHARE("tilemapram") // text tilemap
AM_RANGE(0x200000, 0x200fff) AM_RAM_WRITE(bg_videoram0_w) AM_SHARE("spriteram0") // this is the 'list'
AM_RANGE(0x201000, 0x201fff) AM_RAM_WRITE(bg_videoram1_w) AM_SHARE("spriteram1") // sprites layer 0
AM_RANGE(0x202000, 0x202fff) AM_RAM_WRITE(bg_videoram2_w) AM_SHARE("spriteram2") // bg layer?
AM_RANGE(0x203000, 0x203fff) AM_RAM_WRITE(bg_videoram3_w) AM_SHARE("spriteram3") // sprites layer 1
// the following potentially exist (the ram is cleared, there is room for entries in the 'spriteram0' region
// but they never get used..)
AM_RANGE(0x204000, 0x204fff) AM_RAM_WRITE(bg_videoram4_w) AM_SHARE("spriteram4")
AM_RANGE(0x205000, 0x205fff) AM_RAM_WRITE(bg_videoram5_w) AM_SHARE("spriteram5")
AM_RANGE(0x206000, 0x206fff) AM_RAM_WRITE(bg_videoram6_w) AM_SHARE("spriteram6")
AM_RANGE(0x207000, 0x207fff) AM_RAM_WRITE(bg_videoram7_w) AM_SHARE("spriteram7")
AM_RANGE(0x200000, 0x207fff) AM_DEVREADWRITE("sprites", snk68_spr_device, spriteram_r, spriteram_w) AM_SHARE("spriteram") // only partially populated
AM_RANGE(0x400000, 0x400fff) AM_RAM_DEVWRITE("palette", palette_device, write) AM_SHARE("palette")
AM_RANGE(0xc00000, 0xc03fff) AM_RAM // main ram
@ -368,108 +209,6 @@ static INPUT_PORTS_START( blackt96 )
PORT_BIT( 0x0080, IP_ACTIVE_HIGH, IPT_UNKNOWN )
PORT_BIT( 0xff00, IP_ACTIVE_HIGH, IPT_UNKNOWN )
#if 0
PORT_START("IN2")
PORT_DIPNAME( 0x0001, 0x0001, "2" )
PORT_DIPSETTING( 0x0001, DEF_STR( Off ) )
PORT_DIPSETTING( 0x0000, DEF_STR( On ) )
PORT_DIPNAME( 0x0002, 0x0002, DEF_STR( Unknown ) )
PORT_DIPSETTING( 0x0002, DEF_STR( Off ) )
PORT_DIPSETTING( 0x0000, DEF_STR( On ) )
PORT_DIPNAME( 0x0004, 0x0004, DEF_STR( Unknown ) )
PORT_DIPSETTING( 0x0004, DEF_STR( Off ) )
PORT_DIPSETTING( 0x0000, DEF_STR( On ) )
PORT_DIPNAME( 0x0008, 0x0008, DEF_STR( Unknown ) )
PORT_DIPSETTING( 0x0008, DEF_STR( Off ) )
PORT_DIPSETTING( 0x0000, DEF_STR( On ) )
PORT_DIPNAME( 0x0010, 0x0010, DEF_STR( Unknown ) )
PORT_DIPSETTING( 0x0010, DEF_STR( Off ) )
PORT_DIPSETTING( 0x0000, DEF_STR( On ) )
PORT_DIPNAME( 0x0020, 0x0020, DEF_STR( Unknown ) )
PORT_DIPSETTING( 0x0020, DEF_STR( Off ) )
PORT_DIPSETTING( 0x0000, DEF_STR( On ) )
PORT_DIPNAME( 0x0040, 0x0040, DEF_STR( Unknown ) )
PORT_DIPSETTING( 0x0040, DEF_STR( Off ) )
PORT_DIPSETTING( 0x0000, DEF_STR( On ) )
PORT_DIPNAME( 0x0080, 0x0080, DEF_STR( Unknown ) )
PORT_DIPSETTING( 0x0080, DEF_STR( Off ) )
PORT_DIPSETTING( 0x0000, DEF_STR( On ) )
PORT_DIPNAME( 0x0100, 0x0100, DEF_STR( Unknown ) )
PORT_DIPSETTING( 0x0100, DEF_STR( Off ) )
PORT_DIPSETTING( 0x0000, DEF_STR( On ) )
PORT_DIPNAME( 0x0200, 0x0200, DEF_STR( Unknown ) )
PORT_DIPSETTING( 0x0200, DEF_STR( Off ) )
PORT_DIPSETTING( 0x0000, DEF_STR( On ) )
PORT_DIPNAME( 0x0400, 0x0400, DEF_STR( Unknown ) )
PORT_DIPSETTING( 0x0400, DEF_STR( Off ) )
PORT_DIPSETTING( 0x0000, DEF_STR( On ) )
PORT_DIPNAME( 0x0800, 0x0800, DEF_STR( Unknown ) )
PORT_DIPSETTING( 0x0800, DEF_STR( Off ) )
PORT_DIPSETTING( 0x0000, DEF_STR( On ) )
PORT_DIPNAME( 0x1000, 0x1000, DEF_STR( Unknown ) )
PORT_DIPSETTING( 0x1000, DEF_STR( Off ) )
PORT_DIPSETTING( 0x0000, DEF_STR( On ) )
PORT_DIPNAME( 0x2000, 0x2000, DEF_STR( Unknown ) )
PORT_DIPSETTING( 0x2000, DEF_STR( Off ) )
PORT_DIPSETTING( 0x0000, DEF_STR( On ) )
PORT_DIPNAME( 0x4000, 0x4000, DEF_STR( Unknown ) )
PORT_DIPSETTING( 0x4000, DEF_STR( Off ) )
PORT_DIPSETTING( 0x0000, DEF_STR( On ) )
PORT_DIPNAME( 0x8000, 0x8000, DEF_STR( Unknown ) )
PORT_DIPSETTING( 0x8000, DEF_STR( Off ) )
PORT_DIPSETTING( 0x0000, DEF_STR( On ) )
PORT_START("IN3")
PORT_DIPNAME( 0x0001, 0x0001, "3" )
PORT_DIPSETTING( 0x0001, DEF_STR( Off ) )
PORT_DIPSETTING( 0x0000, DEF_STR( On ) )
PORT_DIPNAME( 0x0002, 0x0002, DEF_STR( Unknown ) )
PORT_DIPSETTING( 0x0002, DEF_STR( Off ) )
PORT_DIPSETTING( 0x0000, DEF_STR( On ) )
PORT_DIPNAME( 0x0004, 0x0004, DEF_STR( Unknown ) )
PORT_DIPSETTING( 0x0004, DEF_STR( Off ) )
PORT_DIPSETTING( 0x0000, DEF_STR( On ) )
PORT_DIPNAME( 0x0008, 0x0008, DEF_STR( Unknown ) )
PORT_DIPSETTING( 0x0008, DEF_STR( Off ) )
PORT_DIPSETTING( 0x0000, DEF_STR( On ) )
PORT_DIPNAME( 0x0010, 0x0010, DEF_STR( Unknown ) )
PORT_DIPSETTING( 0x0010, DEF_STR( Off ) )
PORT_DIPSETTING( 0x0000, DEF_STR( On ) )
PORT_DIPNAME( 0x0020, 0x0020, DEF_STR( Unknown ) )
PORT_DIPSETTING( 0x0020, DEF_STR( Off ) )
PORT_DIPSETTING( 0x0000, DEF_STR( On ) )
PORT_DIPNAME( 0x0040, 0x0040, DEF_STR( Unknown ) )
PORT_DIPSETTING( 0x0040, DEF_STR( Off ) )
PORT_DIPSETTING( 0x0000, DEF_STR( On ) )
PORT_DIPNAME( 0x0080, 0x0080, DEF_STR( Unknown ) )
PORT_DIPSETTING( 0x0080, DEF_STR( Off ) )
PORT_DIPSETTING( 0x0000, DEF_STR( On ) )
PORT_DIPNAME( 0x0100, 0x0100, DEF_STR( Unknown ) )
PORT_DIPSETTING( 0x0100, DEF_STR( Off ) )
PORT_DIPSETTING( 0x0000, DEF_STR( On ) )
PORT_DIPNAME( 0x0200, 0x0200, DEF_STR( Unknown ) )
PORT_DIPSETTING( 0x0200, DEF_STR( Off ) )
PORT_DIPSETTING( 0x0000, DEF_STR( On ) )
PORT_DIPNAME( 0x0400, 0x0400, DEF_STR( Unknown ) )
PORT_DIPSETTING( 0x0400, DEF_STR( Off ) )
PORT_DIPSETTING( 0x0000, DEF_STR( On ) )
PORT_DIPNAME( 0x0800, 0x0800, DEF_STR( Unknown ) )
PORT_DIPSETTING( 0x0800, DEF_STR( Off ) )
PORT_DIPSETTING( 0x0000, DEF_STR( On ) )
PORT_DIPNAME( 0x1000, 0x1000, DEF_STR( Unknown ) )
PORT_DIPSETTING( 0x1000, DEF_STR( Off ) )
PORT_DIPSETTING( 0x0000, DEF_STR( On ) )
PORT_DIPNAME( 0x2000, 0x2000, DEF_STR( Unknown ) )
PORT_DIPSETTING( 0x2000, DEF_STR( Off ) )
PORT_DIPSETTING( 0x0000, DEF_STR( On ) )
PORT_DIPNAME( 0x4000, 0x4000, DEF_STR( Unknown ) )
PORT_DIPSETTING( 0x4000, DEF_STR( Off ) )
PORT_DIPSETTING( 0x0000, DEF_STR( On ) )
PORT_DIPNAME( 0x8000, 0x8000, DEF_STR( Unknown ) )
PORT_DIPSETTING( 0x8000, DEF_STR( Off ) )
PORT_DIPSETTING( 0x0000, DEF_STR( On ) )
#endif
/* Dipswitch Port A */
PORT_START("DSW1")
PORT_DIPNAME( 0x0300, 0x0000, DEF_STR( Coin_B ) ) PORT_DIPLOCATION("SW1:!7,!8")
@ -589,6 +328,21 @@ WRITE8_MEMBER(blackt96_state::blackt96_soundio_port02_w)
{
}
void blackt96_state::tile_callback(int &tile, int& fx, int& fy, int& region)
{
fx = tile & 0x4000;
fy = tile & 0x8000;
tile &= 0x3fff;
if (tile & 0x2000)
{
region = 0;
}
else
{
region = 1;
}
}
static MACHINE_CONFIG_START( blackt96, blackt96_state )
@ -611,13 +365,18 @@ static MACHINE_CONFIG_START( blackt96, blackt96_state )
MCFG_SCREEN_VBLANK_TIME(ATTOSECONDS_IN_USEC(0))
MCFG_SCREEN_SIZE(256, 256)
// MCFG_SCREEN_VISIBLE_AREA(0*8, 16*32-1, 0*8, 16*32-1)
MCFG_SCREEN_VISIBLE_AREA(0*8, 256-1, 0*8, 224-1)
MCFG_SCREEN_VISIBLE_AREA(0*8, 256-1, 2*8, 240-1)
MCFG_SCREEN_UPDATE_DRIVER(blackt96_state, screen_update_blackt96)
MCFG_SCREEN_PALETTE("palette")
MCFG_PALETTE_ADD("palette", 0x800)
MCFG_PALETTE_FORMAT(xxxxRRRRGGGGBBBB)
MCFG_DEVICE_ADD("sprites", SNK68_SPR, 0)
MCFG_SNK68_SPR_GFXDECODE("gfxdecode")
MCFG_SNK68_SPR_PALETTE("palette")
MCFG_SNK68_SPR_SET_TILE_INDIRECT( blackt96_state, tile_callback )
MCFG_SPEAKER_STANDARD_STEREO("lspeaker", "rspeaker")

View File

@ -117,7 +117,7 @@ static ADDRESS_MAP_START( pow_map, AS_PROGRAM, 16, snk68_state )
AM_RANGE(0x0f0008, 0x0f0009) AM_READ_PORT("DSW2")
// AM_RANGE(0x0f0008, 0x0f0009) AM_WRITENOP /* ?? */
AM_RANGE(0x100000, 0x100fff) AM_READWRITE(pow_fg_videoram_r, pow_fg_videoram_w) AM_MIRROR(0x1000) AM_SHARE("pow_fg_videoram") // 8-bit
AM_RANGE(0x200000, 0x207fff) AM_READWRITE(spriteram_r, spriteram_w) AM_SHARE("spriteram") // only partially populated
AM_RANGE(0x200000, 0x207fff) AM_DEVREADWRITE("sprites", snk68_spr_device, spriteram_r, spriteram_w) AM_SHARE("spriteram") // only partially populated
AM_RANGE(0x400000, 0x400fff) AM_RAM_DEVWRITE("palette", palette_device, write) AM_SHARE("palette")
ADDRESS_MAP_END
@ -137,7 +137,7 @@ static ADDRESS_MAP_START( searchar_map, AS_PROGRAM, 16, snk68_state )
AM_RANGE(0x0f0000, 0x0f0001) AM_READ_PORT("DSW1")
AM_RANGE(0x0f0008, 0x0f0009) AM_READ_PORT("DSW2")
AM_RANGE(0x0f8000, 0x0f8001) AM_READ8(soundlatch2_byte_r, 0xff00)
AM_RANGE(0x100000, 0x107fff) AM_READWRITE(spriteram_r, spriteram_w) AM_SHARE("spriteram") // only partially populated
AM_RANGE(0x100000, 0x107fff) AM_DEVREADWRITE("sprites", snk68_spr_device, spriteram_r, spriteram_w) AM_SHARE("spriteram") // only partially populated
AM_RANGE(0x200000, 0x200fff) AM_RAM_WRITE(searchar_fg_videoram_w) AM_MIRROR(0x1000) AM_SHARE("pow_fg_videoram") /* Mirror is used by Ikari 3 */
AM_RANGE(0x300000, 0x33ffff) AM_ROM AM_REGION("user1", 0) /* Extra code bank */
AM_RANGE(0x400000, 0x400fff) AM_RAM_DEVWRITE("palette", palette_device, write) AM_SHARE("palette")
@ -561,6 +561,33 @@ GFXDECODE_END
/******************************************************************************/
// pow has 0x4000 tiles and independent x/y flipping
// the other games have > 0x4000 tiles and flipping in only one direction
// (globally selected)
void snk68_state::tile_callback_pow(int &tile, int& fx, int& fy, int& region)
{
fx = tile & 0x4000;
fy = tile & 0x8000;
tile &= 0x3fff;
region = 1;
}
void snk68_state::tile_callback_notpow(int &tile, int& fx, int& fy, int& region)
{
if (m_sprite_flip_axis)
{
fx = 0;
fy = tile & 0x8000;
}
else
{
fx = tile & 0x8000;
fy = 0;
}
tile &= 0x7fff;
region = 1;
}
static MACHINE_CONFIG_START( pow, snk68_state )
/* basic machine hardware */
@ -588,6 +615,11 @@ static MACHINE_CONFIG_START( pow, snk68_state )
/* sound hardware */
MCFG_SPEAKER_STANDARD_MONO("mono")
MCFG_DEVICE_ADD("sprites", SNK68_SPR, 0)
MCFG_SNK68_SPR_GFXDECODE("gfxdecode")
MCFG_SNK68_SPR_PALETTE("palette")
MCFG_SNK68_SPR_SET_TILE_INDIRECT( snk68_state, tile_callback_pow )
MCFG_SOUND_ADD("ymsnd", YM3812, XTAL_8MHz/2) /* verified on pcb */
MCFG_YM3812_IRQ_HANDLER(INPUTLINE("soundcpu", 0))
MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 1.0)
@ -603,6 +635,9 @@ static MACHINE_CONFIG_DERIVED( searchar, pow )
MCFG_CPU_PROGRAM_MAP(searchar_map)
MCFG_VIDEO_START_OVERRIDE(snk68_state,searchar)
MCFG_DEVICE_MODIFY("sprites")
MCFG_SNK68_SPR_SET_TILE_INDIRECT( snk68_state, tile_callback_notpow )
MACHINE_CONFIG_END

View File

@ -1,7 +1,7 @@
// license:BSD-3-Clause
// copyright-holders:Bryan McPhail, Acho A. Tang, Nicola Salmoria
#include "sound/upd7759.h"
#include "video/snk68_spr.h"
class snk68_state : public driver_device
{
public:
@ -13,7 +13,9 @@ public:
m_gfxdecode(*this, "gfxdecode"),
m_screen(*this, "screen"),
m_pow_fg_videoram(*this, "pow_fg_videoram"),
m_spriteram(*this, "spriteram") { }
m_spriteram(*this, "spriteram"),
m_sprites(*this, "sprites")
{ }
required_device<cpu_device> m_maincpu;
required_device<cpu_device> m_soundcpu;
@ -24,6 +26,8 @@ public:
required_shared_ptr<UINT16> m_pow_fg_videoram;
required_shared_ptr<UINT16> m_spriteram;
required_device<snk68_spr_device> m_sprites;
UINT8 m_invert_controls;
bool m_sprite_flip_axis;
tilemap_t *m_fg_tilemap;
@ -31,8 +35,6 @@ public:
// common
DECLARE_WRITE16_MEMBER(sound_w);
DECLARE_READ16_MEMBER(spriteram_r);
DECLARE_WRITE16_MEMBER(spriteram_w);
DECLARE_WRITE8_MEMBER(D7759_write_port_0_w);
DECLARE_WRITE8_MEMBER(D7759_upd_reset_w);
@ -60,5 +62,8 @@ public:
void common_video_start();
UINT32 screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect);
void draw_sprites(bitmap_ind16 &bitmap, const rectangle &cliprect, int group);
void tile_callback_pow(int &tile, int& fx, int& fy, int& region);
void tile_callback_notpow(int &tile, int& fx, int& fy, int& region);
};

View File

@ -79,36 +79,6 @@ VIDEO_START_MEMBER(snk68_state,searchar)
***************************************************************************/
READ16_MEMBER(snk68_state::spriteram_r)
{
// streetsj expects the MSB of every 32-bit word to be FF. Presumably RAM
// exists only for 3 bytes out of 4 and the fourth is unmapped.
if (!(offset & 1))
return m_spriteram[offset] | 0xff00;
else
return m_spriteram[offset];
}
WRITE16_MEMBER(snk68_state::spriteram_w)
{
UINT16 newword = m_spriteram[offset];
if (!(offset & 1))
data |= 0xff00;
COMBINE_DATA(&newword);
if (m_spriteram[offset] != newword)
{
int vpos = m_screen->vpos();
if (vpos > 0)
m_screen->update_partial(vpos - 1);
m_spriteram[offset] = newword;
}
}
READ16_MEMBER(snk68_state::pow_fg_videoram_r)
{
// RAM is only 8-bit
@ -134,7 +104,7 @@ WRITE16_MEMBER(snk68_state::pow_flipscreen_w)
if (ACCESSING_BITS_0_7)
{
flip_screen_set(data & 0x08);
m_sprites->set_flip(data & 0x08);
m_sprite_flip_axis = data & 0x04; // for streetsm? though might not be present on this board
if (m_fg_tile_offset != ((data & 0x70) << 4))
@ -150,6 +120,7 @@ WRITE16_MEMBER(snk68_state::searchar_flipscreen_w)
if (ACCESSING_BITS_0_7)
{
flip_screen_set(data & 0x08);
m_sprites->set_flip(data & 0x08);
m_sprite_flip_axis = data & 0x04;
}
}
@ -161,99 +132,12 @@ WRITE16_MEMBER(snk68_state::searchar_flipscreen_w)
***************************************************************************/
void snk68_state::draw_sprites(bitmap_ind16 &bitmap, const rectangle &cliprect, int group)
{
const UINT16* tiledata = &m_spriteram[0x800*group];
// pow has 0x4000 tiles and independent x/y flipping
// the other games have > 0x4000 tiles and flipping in only one direction
// (globally selected)
bool const is_pow = (m_gfxdecode->gfx(1)->elements() <= 0x4000);
bool const flip = flip_screen();
for (int offs = 0; offs < 0x800; offs += 0x40)
{
int mx = (m_spriteram[offs + 2*group] & 0xff) << 4;
int my = m_spriteram[offs + 2*group + 1];
int i;
mx = mx | (my >> 12);
mx = ((mx + 16) & 0x1ff) - 16;
my = -my;
if (flip)
{
mx = 240 - mx;
my = 240 - my;
}
// every sprite is a column 32 tiles (512 pixels) tall
for (i = 0; i < 0x20; ++i)
{
my &= 0x1ff;
if (my <= cliprect.max_y && my + 15 >= cliprect.min_y)
{
int color = *(tiledata++) & 0x7f;
int tile = *(tiledata++);
int fx,fy;
if (is_pow)
{
fx = tile & 0x4000;
fy = tile & 0x8000;
tile &= 0x3fff;
}
else
{
if (m_sprite_flip_axis)
{
fx = 0;
fy = tile & 0x8000;
}
else
{
fx = tile & 0x8000;
fy = 0;
}
tile &= 0x7fff;
}
if (flip)
{
fx = !fx;
fy = !fy;
}
m_gfxdecode->gfx(1)->transpen(bitmap,cliprect,
tile,
color,
fx, fy,
mx, my, 0);
}
else
{
tiledata += 2;
}
if (flip)
my -= 16;
else
my += 16;
}
}
}
UINT32 snk68_state::screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
{
bitmap.fill(0x7ff, cliprect);
/* This appears to be the correct priority order */
draw_sprites(bitmap, cliprect, 2);
draw_sprites(bitmap, cliprect, 3);
draw_sprites(bitmap, cliprect, 1);
m_sprites->draw_sprites_all(bitmap, cliprect);
m_fg_tilemap->draw(screen, bitmap, cliprect, 0, 0);
return 0;

View File

@ -0,0 +1,175 @@
// license:BSD-3-Clause
// copyright-holders:Bryan McPhail, Acho A. Tang, Nicola Salmoria
/* SNK68 Sprites */
#include "emu.h"
#include "snk68_spr.h"
const device_type SNK68_SPR = &device_creator<snk68_spr_device>;
snk68_spr_device::snk68_spr_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
: device_t(mconfig, SNK68_SPR, "SNK68 Sprites", tag, owner, clock, "snk68_spr", __FILE__),
m_gfxdecode(*this),
m_palette(*this),
m_spriteram(*this, "^spriteram"),
m_screen(*this, "^screen"),
m_flipscreen(0)
{
m_newtilecb = snk68_tile_indirection_delegate(FUNC(snk68_spr_device::tile_callback_noindirect), this);
}
void snk68_spr_device::tile_callback_noindirect(int &tile, int& fx, int& fy, int& region)
{
}
//-------------------------------------------------
// static_set_gfxdecode_tag: Set the tag of the
// gfx decoder
//-------------------------------------------------
void snk68_spr_device::static_set_gfxdecode_tag(device_t &device, const char *tag)
{
downcast<snk68_spr_device &>(device).m_gfxdecode.set_tag(tag);
}
//-------------------------------------------------
// static_set_palette_tag: Set the tag of the
// palette device
//-------------------------------------------------
void snk68_spr_device::static_set_palette_tag(device_t &device, const char *tag)
{
downcast<snk68_spr_device &>(device).m_palette.set_tag(tag);
}
// static
void snk68_spr_device::set_tile_indirect_cb(device_t &device,snk68_tile_indirection_delegate newtilecb)
{
snk68_spr_device &dev = downcast<snk68_spr_device &>(device);
dev.m_newtilecb = newtilecb;
}
void snk68_spr_device::device_start()
{
// bind our handler
m_newtilecb.bind_relative_to(*owner());
}
void snk68_spr_device::device_reset()
{
}
READ16_MEMBER(snk68_spr_device::spriteram_r)
{
// streetsj expects the MSB of every 32-bit word to be FF. Presumably RAM
// exists only for 3 bytes out of 4 and the fourth is unmapped.
if (!(offset & 1))
return m_spriteram[offset] | 0xff00;
else
return m_spriteram[offset];
}
WRITE16_MEMBER(snk68_spr_device::spriteram_w)
{
UINT16 newword = m_spriteram[offset];
if (!(offset & 1))
data |= 0xff00;
COMBINE_DATA(&newword);
if (m_spriteram[offset] != newword)
{
int vpos = m_screen->vpos();
if (vpos > 0)
m_screen->update_partial(vpos - 1);
m_spriteram[offset] = newword;
}
}
void snk68_spr_device::draw_sprites(bitmap_ind16 &bitmap, const rectangle &cliprect, int group)
{
const UINT16* tiledata = &m_spriteram[0x800*group];
bool const flip = m_flipscreen;
for (int offs = 0; offs < 0x800; offs += 0x40)
{
int mx = (m_spriteram[offs + 2*group] & 0xff) << 4;
int my = m_spriteram[offs + 2*group + 1];
int i;
mx = mx | (my >> 12);
mx = ((mx + 16) & 0x1ff) - 16;
my = -my;
if (flip)
{
mx = 240 - mx;
my = 240 - my;
}
// every sprite is a column 32 tiles (512 pixels) tall
for (i = 0; i < 0x20; ++i)
{
my &= 0x1ff;
if (my <= cliprect.max_y && my + 15 >= cliprect.min_y)
{
int color = *(tiledata++) & 0x7f;
int tile = *(tiledata++);
int fx = 0,fy = 0;
int region = 0;
m_newtilecb(tile, fx, fy, region);
// the black touch '96 cloned hardware has some tiles
// as 8bpp, we need to shift the colour bits in those cases
int depth = m_gfxdecode->gfx(region)->depth();
if (depth == 256) color >>= 4;
if (flip)
{
fx = !fx;
fy = !fy;
}
m_gfxdecode->gfx(region)->transpen(bitmap,cliprect,
tile,
color,
fx, fy,
mx, my, 0);
}
else
{
tiledata += 2;
}
if (flip)
my -= 16;
else
my += 16;
}
}
}
void snk68_spr_device::draw_sprites_all(bitmap_ind16 &bitmap, const rectangle &cliprect)
{
/* This appears to be the correct priority order */
draw_sprites(bitmap, cliprect, 2);
draw_sprites(bitmap, cliprect, 3);
draw_sprites(bitmap, cliprect, 1);
}
void snk68_spr_device::set_flip(int flip)
{
if (flip) m_flipscreen = 1;
else m_flipscreen = 0;
}

View File

@ -0,0 +1,45 @@
typedef device_delegate<void (int&, int&, int&, int&)> snk68_tile_indirection_delegate;
#define MCFG_SNK68_SPR_GFXDECODE(_gfxtag) \
snk68_spr_device::static_set_gfxdecode_tag(*device, "^" _gfxtag);
#define MCFG_SNK68_SPR_PALETTE(_palette_tag) \
snk68_spr_device::static_set_palette_tag(*device, "^" _palette_tag);
#define MCFG_SNK68_SPR_SET_TILE_INDIRECT( _class, _method) \
snk68_spr_device::set_tile_indirect_cb(*device, snk68_tile_indirection_delegate(&_class::_method, #_class "::" #_method, NULL, (_class *)0));
class snk68_spr_device : public device_t
{
public:
snk68_spr_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
// static configuration
static void static_set_gfxdecode_tag(device_t &device, const char *tag);
static void static_set_palette_tag(device_t &device, const char *tag);
static void set_tile_indirect_cb(device_t &device,snk68_tile_indirection_delegate newtilecb);
DECLARE_READ16_MEMBER(spriteram_r);
DECLARE_WRITE16_MEMBER(spriteram_w);
void draw_sprites(bitmap_ind16 &bitmap, const rectangle &cliprect, int group);
void draw_sprites_all(bitmap_ind16 &bitmap, const rectangle &cliprect);
snk68_tile_indirection_delegate m_newtilecb;
void tile_callback_noindirect(int& tile, int& fx, int& ft, int& region);
void set_flip(int flip);
protected:
virtual void device_start() override;
virtual void device_reset() override;
private:
optional_device<gfxdecode_device> m_gfxdecode;
optional_device<palette_device> m_palette;
required_shared_ptr<UINT16> m_spriteram;
required_device<screen_device> m_screen;
int m_flipscreen;
};
extern const device_type SNK68_SPR;