mirror of
https://github.com/holub/mame
synced 2025-06-01 18:41:47 +03:00
st0020 (seta blitter + zooming sprites) is now a device. [David Haywood]
This commit is contained in:
parent
67c37ad05c
commit
62ac08faba
2
.gitattributes
vendored
2
.gitattributes
vendored
@ -5066,6 +5066,8 @@ src/mame/video/sspeedr.c svneol=native#text/plain
|
||||
src/mame/video/ssrj.c svneol=native#text/plain
|
||||
src/mame/video/ssv.c svneol=native#text/plain
|
||||
src/mame/video/st0016.c svneol=native#text/plain
|
||||
src/mame/video/st0020.c svneol=native#text/plain
|
||||
src/mame/video/st0020.h svneol=native#text/plain
|
||||
src/mame/video/stactics.c svneol=native#text/plain
|
||||
src/mame/video/stadhero.c svneol=native#text/plain
|
||||
src/mame/video/starcrus.c svneol=native#text/plain
|
||||
|
@ -492,92 +492,6 @@ WRITE16_MEMBER(ssv_state::gdfs_eeprom_w)
|
||||
}
|
||||
|
||||
|
||||
READ16_MEMBER(ssv_state::gdfs_gfxram_r)
|
||||
{
|
||||
|
||||
return m_eaglshot_gfxram[offset + m_gdfs_gfxram_bank * 0x100000/2];
|
||||
}
|
||||
|
||||
WRITE16_MEMBER(ssv_state::gdfs_gfxram_w)
|
||||
{
|
||||
offset += m_gdfs_gfxram_bank * 0x100000/2;
|
||||
COMBINE_DATA(&m_eaglshot_gfxram[offset]);
|
||||
gfx_element_mark_dirty(machine().gfx[2], offset / (16*8/2));
|
||||
}
|
||||
|
||||
READ16_MEMBER(ssv_state::gdfs_blitram_r)
|
||||
{
|
||||
switch (offset)
|
||||
{
|
||||
case 0x00/2:
|
||||
// blitter status? (bit C, bit A)
|
||||
return 0;
|
||||
}
|
||||
|
||||
logerror("CPU #0 PC: %06X - Blit reg read: %02X\n",cpu_get_pc(&space.device()),offset*2);
|
||||
return 0;
|
||||
}
|
||||
|
||||
WRITE16_MEMBER(ssv_state::gdfs_blitram_w)
|
||||
{
|
||||
UINT16 *gdfs_blitram = m_gdfs_blitram;
|
||||
|
||||
COMBINE_DATA(&gdfs_blitram[offset]);
|
||||
|
||||
switch (offset)
|
||||
{
|
||||
case 0x8a/2:
|
||||
{
|
||||
if (data & ~0x43)
|
||||
logerror("CPU #0 PC: %06X - Unknown gdfs_gfxram_bank bit written %04X\n",cpu_get_pc(&space.device()),data);
|
||||
|
||||
if (ACCESSING_BITS_0_7)
|
||||
m_gdfs_gfxram_bank = data & 3;
|
||||
}
|
||||
break;
|
||||
|
||||
case 0xc0/2:
|
||||
case 0xc2/2:
|
||||
case 0xc4/2:
|
||||
case 0xc6/2:
|
||||
case 0xc8/2:
|
||||
break;
|
||||
|
||||
case 0xca/2:
|
||||
{
|
||||
UINT32 src = (gdfs_blitram[0xc0/2] + (gdfs_blitram[0xc2/2] << 16)) << 1;
|
||||
UINT32 dst = (gdfs_blitram[0xc4/2] + (gdfs_blitram[0xc6/2] << 16)) << 4;
|
||||
UINT32 len = (gdfs_blitram[0xc8/2]) << 4;
|
||||
|
||||
UINT8 *rom = memregion("gfx2")->base();
|
||||
size_t size = memregion("gfx2")->bytes();
|
||||
|
||||
if ( (src+len <= size) && (dst+len <= 4 * 0x100000) )
|
||||
{
|
||||
memcpy( &m_eaglshot_gfxram[dst/2], &rom[src], len );
|
||||
|
||||
if (len % (16*8)) len = len / (16*8) + 1;
|
||||
else len = len / (16*8);
|
||||
|
||||
dst /= 16*8;
|
||||
while (len--)
|
||||
{
|
||||
gfx_element_mark_dirty(machine().gfx[2], dst);
|
||||
dst++;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
logerror("CPU #0 PC: %06X - Blit out of range: src %x, dst %x, len %x\n",cpu_get_pc(&space.device()),src,dst,len);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
logerror("CPU #0 PC: %06X - Blit reg written: %02X <- %04X\n",cpu_get_pc(&space.device()),offset*2,data);
|
||||
}
|
||||
}
|
||||
|
||||
static ADDRESS_MAP_START( gdfs_map, AS_PROGRAM, 16, ssv_state )
|
||||
AM_RANGE(0x400000, 0x41ffff) AM_RAM_WRITE(gdfs_tmapram_w) AM_SHARE("gdfs_tmapram")
|
||||
AM_RANGE(0x420000, 0x43ffff) AM_RAM
|
||||
@ -585,9 +499,9 @@ static ADDRESS_MAP_START( gdfs_map, AS_PROGRAM, 16, ssv_state )
|
||||
AM_RANGE(0x500000, 0x500001) AM_WRITE(gdfs_eeprom_w)
|
||||
AM_RANGE(0x540000, 0x540001) AM_READ(gdfs_eeprom_r)
|
||||
AM_RANGE(0x600000, 0x600fff) AM_RAM
|
||||
AM_RANGE(0x800000, 0x87ffff) AM_RAM AM_SHARE("spriteram2")
|
||||
AM_RANGE(0x8c0000, 0x8c00ff) AM_READWRITE(gdfs_blitram_r, gdfs_blitram_w) AM_SHARE("gdfs_blitram")
|
||||
AM_RANGE(0x900000, 0x9fffff) AM_READWRITE(gdfs_gfxram_r, gdfs_gfxram_w)
|
||||
AM_RANGE(0x800000, 0x87ffff) AM_DEVREADWRITE( "st0020_spr", st0020_device, st0020_sprram_r, st0020_sprram_w );
|
||||
AM_RANGE(0x8c0000, 0x8c00ff) AM_DEVREADWRITE( "st0020_spr", st0020_device, st0020_blitram_r, st0020_blitram_w );
|
||||
AM_RANGE(0x900000, 0x9fffff) AM_DEVREADWRITE( "st0020_spr", st0020_device, st0020_gfxram_r, st0020_gfxram_w );
|
||||
SSV_MAP( 0xc00000 )
|
||||
ADDRESS_MAP_END
|
||||
|
||||
@ -2586,7 +2500,6 @@ static const gfx_layout layout_16x16x8 =
|
||||
static GFXDECODE_START( gdfs )
|
||||
GFXDECODE_ENTRY( "gfx1", 0, layout_16x8x8, 0, 0x8000/64 ) // [0] Sprites (256 colors)
|
||||
GFXDECODE_ENTRY( "gfx1", 0, layout_16x8x6, 0, 0x8000/64 ) // [1] Sprites (64 colors)
|
||||
GFXDECODE_ENTRY( "gfx2", 0, layout_16x8x8_2, 0, 0x8000/64 ) // [2] Zooming Sprites (256 colors, decoded from ram)
|
||||
GFXDECODE_ENTRY( "gfx3", 0, layout_16x16x8, 0, 0x8000/256 ) // [3] Tilemap
|
||||
GFXDECODE_END
|
||||
|
||||
@ -2750,6 +2663,8 @@ static MACHINE_CONFIG_DERIVED( gdfs, ssv )
|
||||
MCFG_SCREEN_VISIBLE_AREA(0, (0xd5-0x2c)*2-1, 0, (0x102-0x12)-1)
|
||||
MCFG_SCREEN_UPDATE_STATIC(gdfs)
|
||||
|
||||
MCFG_DEVICE_ADD("st0020_spr", ST0020_SPRITES, 0)
|
||||
|
||||
MCFG_GFXDECODE(gdfs)
|
||||
MCFG_VIDEO_START(gdfs)
|
||||
MACHINE_CONFIG_END
|
||||
@ -4629,7 +4544,7 @@ ROM_START( gdfs )
|
||||
ROM_LOAD( "vg004-10.u45", 0x200000, 0x200000, CRC(b3c6b1cb) SHA1(c601213e35d8dfd1244921da5c093f82145706d2) )
|
||||
ROM_LOAD( "vg004-11.u48", 0x400000, 0x200000, CRC(1491def1) SHA1(344043302c81b4118cac4f692375b8af7ea68570) )
|
||||
|
||||
ROM_REGION( 0x1000000, "gfx2", /*0*/0 ) // Zooming Sprites, read by a blitter
|
||||
ROM_REGION( 0x1000000, "st0020", /*0*/0 ) // Zooming Sprites, read by a blitter
|
||||
ROM_LOAD( "vg004-01.u33", 0x0000000, 0x200000, CRC(aa9a81c2) SHA1(a7d005f9be199e317aa4c6aed8a2ab322fe82119) )
|
||||
ROM_LOAD( "vg004-02.u34", 0x0200000, 0x200000, CRC(fa40ecb4) SHA1(0513f3b6879dc7d207646d949d6ddb7251f77bcc) )
|
||||
ROM_LOAD( "vg004-03.u35", 0x0400000, 0x200000, CRC(90004023) SHA1(041edb77b34e6677ac5b85ce542d87a9bb1baf31) )
|
||||
|
@ -1,4 +1,5 @@
|
||||
#include "cpu/upd7725/upd7725.h"
|
||||
#include "video/st0020.h"
|
||||
|
||||
class ssv_state : public driver_device
|
||||
{
|
||||
@ -13,8 +14,7 @@ public:
|
||||
m_irq_vectors(*this, "irq_vectors"),
|
||||
m_gdfs_tmapram(*this, "gdfs_tmapram"),
|
||||
m_gdfs_tmapscroll(*this, "gdfs_tmapscroll"),
|
||||
m_spriteram2(*this, "spriteram2"),
|
||||
m_gdfs_blitram(*this, "gdfs_blitram"),
|
||||
m_gdfs_st0020(*this, "st0020_spr"),
|
||||
m_input_sel(*this, "input_sel"){ }
|
||||
|
||||
optional_device<upd96050_device> m_dsp;
|
||||
@ -26,8 +26,7 @@ public:
|
||||
required_shared_ptr<UINT16> m_irq_vectors;
|
||||
optional_shared_ptr<UINT16> m_gdfs_tmapram;
|
||||
optional_shared_ptr<UINT16> m_gdfs_tmapscroll;
|
||||
optional_shared_ptr<UINT16> m_spriteram2;
|
||||
optional_shared_ptr<UINT16> m_gdfs_blitram;
|
||||
optional_device<st0020_device> m_gdfs_st0020;
|
||||
optional_shared_ptr<UINT16> m_input_sel;
|
||||
|
||||
int m_tile_code[16];
|
||||
|
@ -1313,6 +1313,7 @@ $(MAMEOBJ)/seta.a: \
|
||||
$(DRIVERS)/srmp5.o \
|
||||
$(DRIVERS)/srmp6.o \
|
||||
$(DRIVERS)/ssv.o $(VIDEO)/ssv.o \
|
||||
$(VIDEO)/st0020.o \
|
||||
$(DRIVERS)/st0016.o $(VIDEO)/st0016.o \
|
||||
$(VIDEO)/seta001.o \
|
||||
|
||||
|
@ -213,7 +213,7 @@ static TILE_GET_INFO( get_tile_info_0 )
|
||||
ssv_state *state = machine.driver_data<ssv_state>();
|
||||
UINT16 tile = state->m_gdfs_tmapram[tile_index];
|
||||
|
||||
SET_TILE_INFO(3, tile, 0, TILE_FLIPXY( tile >> 14 ));
|
||||
SET_TILE_INFO(2, tile, 0, TILE_FLIPXY( tile >> 14 ));
|
||||
}
|
||||
|
||||
WRITE16_MEMBER(ssv_state::gdfs_tmapram_w)
|
||||
@ -229,10 +229,6 @@ VIDEO_START( gdfs )
|
||||
|
||||
VIDEO_START_CALL(ssv);
|
||||
|
||||
state->m_eaglshot_gfxram = auto_alloc_array(machine, UINT16, 4 * 0x100000 / 2);
|
||||
|
||||
machine.gfx[2]->color_granularity = 64; /* 256 colour sprites with palette selectable on 64 colour boundaries */
|
||||
gfx_element_set_source(machine.gfx[2], (UINT8 *)state->m_eaglshot_gfxram);
|
||||
|
||||
state->m_gdfs_tmap = tilemap_create( machine, get_tile_info_0, tilemap_scan_rows,
|
||||
16,16, 0x100,0x100 );
|
||||
@ -983,191 +979,14 @@ SCREEN_UPDATE_IND16( eaglshot )
|
||||
return SCREEN_UPDATE16_CALL(ssv);
|
||||
}
|
||||
|
||||
/*
|
||||
Sprites RAM is 0x80000 bytes long. The first 0x2000? bytes hold a list
|
||||
of sprites to display (the list can be made shorter using an end-of-list
|
||||
marker).
|
||||
|
||||
Each entry in the list (16 bytes) is a multi-sprite (e.g it tells the
|
||||
hardware to display several single-sprites).
|
||||
|
||||
The list looks like this:
|
||||
|
||||
Offset: Bits: Value:
|
||||
|
||||
0.h fedc ba-- ---- ----
|
||||
---- --98 7654 3210 X displacement
|
||||
|
||||
2.h fedc ba-- ---- ----
|
||||
---- --98 7654 3210 Y displacement
|
||||
|
||||
4.h f--- ---- ---- ---- List end
|
||||
-edc ba98 7654 3210 Offset of the single-sprite(s) data
|
||||
|
||||
0.h Number of single-sprites (how many bits?)
|
||||
|
||||
A single-sprite is:
|
||||
|
||||
Offset: Bits: Value:
|
||||
|
||||
0.h Code
|
||||
|
||||
2.h f--- ---- ---- ---- Flip X
|
||||
-e-- ---- ---- ---- Flip Y
|
||||
---- -a-- ---- ---- 0 = 256 color steps, 1 = 64 color steps
|
||||
---- --98 7654 3210 Color code
|
||||
|
||||
4.h fedc ba-- ---- ----
|
||||
---- --98 7654 3210 X displacement
|
||||
|
||||
6.h fedc ba-- ---- ----
|
||||
---- --98 7654 3210 Y displacement
|
||||
|
||||
8.h fedc ba98 ---- ---- Y Size
|
||||
---- ---- 7654 3210 X Size
|
||||
|
||||
A.h fedc ba98 ---- ----
|
||||
---- ---- 7654 ---- Priority
|
||||
---- ---- ---- 32-- Y Tiles (1,2,4,8)
|
||||
---- ---- ---- --10 X Tiles (1,2,4,8)
|
||||
|
||||
C.h Unused
|
||||
|
||||
E.h Unused
|
||||
|
||||
*/
|
||||
static void gdfs_draw_zooming_sprites(running_machine &machine, bitmap_ind16 &bitmap, const rectangle &cliprect, int priority)
|
||||
{
|
||||
/* Sprites list */
|
||||
|
||||
ssv_state *state = machine.driver_data<ssv_state>();
|
||||
UINT16 *spriteram16_2 = state->m_spriteram2;
|
||||
UINT16 *s1 = spriteram16_2;
|
||||
UINT16 *end1 = spriteram16_2 + 0x02000/2;
|
||||
UINT16 *s2;
|
||||
|
||||
priority <<= 4;
|
||||
|
||||
for ( ; s1 < end1; s1+=8/2 )
|
||||
{
|
||||
int attr, code, color, num, sprite, zoom, size;
|
||||
int sx, x, xoffs, flipx, xnum, xstart, xend, xinc, xdim, xscale;
|
||||
int sy, y, yoffs, flipy, ynum, ystart, yend, yinc, ydim, yscale;
|
||||
|
||||
xoffs = s1[ 0 ];
|
||||
yoffs = s1[ 1 ];
|
||||
sprite = s1[ 2 ];
|
||||
num = s1[ 3 ] % 0x101;
|
||||
|
||||
/* Last sprite */
|
||||
if (sprite & 0x8000) break;
|
||||
|
||||
/* Single-sprite address */
|
||||
s2 = &spriteram16_2[ (sprite & 0x7fff) * 16/2 ];
|
||||
|
||||
for( ; num > 0; num--,s2+=16/2 )
|
||||
{
|
||||
code = s2[ 0 ];
|
||||
attr = s2[ 1 ];
|
||||
sx = s2[ 2 ];
|
||||
sy = s2[ 3 ];
|
||||
zoom = s2[ 4 ];
|
||||
size = s2[ 5 ];
|
||||
|
||||
if (priority != (size & 0xf0))
|
||||
break;
|
||||
|
||||
flipx = (attr & 0x8000);
|
||||
flipy = (attr & 0x4000);
|
||||
|
||||
/*
|
||||
if ((ssv_scroll[0x74/2] & 0x1000) && ((ssv_scroll[0x74/2] & 0x2000) == 0))
|
||||
{
|
||||
if (flipx == 0) flipx = 1; else flipx = 0;
|
||||
}
|
||||
if ((ssv_scroll[0x74/2] & 0x4000) && ((ssv_scroll[0x74/2] & 0x2000) == 0))
|
||||
{
|
||||
if (flipy == 0) flipy = 1; else flipy = 0;
|
||||
}
|
||||
*/
|
||||
|
||||
color = (attr & 0x0400) ? attr : attr * 4;
|
||||
|
||||
/* Single-sprite tile size */
|
||||
xnum = 1 << ((size >> 0) & 3);
|
||||
ynum = 1 << ((size >> 2) & 3);
|
||||
|
||||
xnum = (xnum + 1) / 2;
|
||||
|
||||
if (flipx) { xstart = xnum-1; xend = -1; xinc = -1; }
|
||||
else { xstart = 0; xend = xnum; xinc = +1; }
|
||||
|
||||
if (flipy) { ystart = ynum-1; yend = -1; yinc = -1; }
|
||||
else { ystart = 0; yend = ynum; yinc = +1; }
|
||||
|
||||
/* Apply global offsets */
|
||||
sx += xoffs;
|
||||
sy += yoffs;
|
||||
|
||||
/* Sign extend the position */
|
||||
sx = (sx & 0x1ff) - (sx & 0x200);
|
||||
sy = (sy & 0x1ff) - (sy & 0x200);
|
||||
|
||||
sy = -sy;
|
||||
|
||||
/* Use fixed point values (16.16), for accuracy */
|
||||
sx <<= 16;
|
||||
sy <<= 16;
|
||||
|
||||
xdim = ( ( ((zoom >> 0) & 0xff) + 1) << 16 ) / xnum;
|
||||
ydim = ( ( ((zoom >> 8) & 0xff) + 1) << 16 ) / ynum;
|
||||
|
||||
xscale = xdim / 16;
|
||||
yscale = ydim / 8;
|
||||
|
||||
/* Let's approximate to the nearest greater integer value
|
||||
to avoid holes in between tiles */
|
||||
if (xscale & 0xffff) xscale += (1<<16) / 16;
|
||||
if (yscale & 0xffff) yscale += (1<<16) / 8;
|
||||
|
||||
/* Draw the tiles */
|
||||
|
||||
for (x = xstart; x != xend; x += xinc)
|
||||
{
|
||||
for (y = ystart; y != yend; y += yinc)
|
||||
{
|
||||
drawgfxzoom_transpen( bitmap, cliprect, machine.gfx[2],
|
||||
code++,
|
||||
color,
|
||||
flipx, flipy,
|
||||
(sx + x * xdim) / 0x10000, (sy + y * ydim) / 0x10000,
|
||||
xscale, yscale, 0
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef MAME_DEBUG
|
||||
if (machine.input().code_pressed(KEYCODE_Z)) /* Display some info on each sprite */
|
||||
{
|
||||
char buf[10];
|
||||
sprintf(buf, "%X",size);
|
||||
ui_draw_text(&machine.render().ui_container(), buf, sx / 0x10000, sy / 0x10000);
|
||||
}
|
||||
#endif
|
||||
} /* single-sprites */
|
||||
|
||||
} /* sprites list */
|
||||
}
|
||||
|
||||
SCREEN_UPDATE_IND16( gdfs )
|
||||
{
|
||||
ssv_state *state = screen.machine().driver_data<ssv_state>();
|
||||
int pri;
|
||||
|
||||
SCREEN_UPDATE16_CALL(ssv);
|
||||
|
||||
for (pri = 0; pri <= 0xf; pri++)
|
||||
gdfs_draw_zooming_sprites(screen.machine(), bitmap, cliprect, pri);
|
||||
// draw zooming sprites
|
||||
state->m_gdfs_st0020->st0020_draw_all(screen.machine(), bitmap, cliprect);
|
||||
|
||||
state->m_gdfs_tmap->set_scrollx(0, state->m_gdfs_tmapscroll[0x0c/2]);
|
||||
state->m_gdfs_tmap->set_scrolly(0, state->m_gdfs_tmapscroll[0x10/2]);
|
||||
|
343
src/mame/video/st0020.c
Normal file
343
src/mame/video/st0020.c
Normal file
@ -0,0 +1,343 @@
|
||||
/* ST0020 - Seta Zooming Sprites + Blitter
|
||||
|
||||
(gdfs also has a tilemap, I don't know if this chip supplies that)
|
||||
|
||||
*/
|
||||
|
||||
|
||||
#include "emu.h"
|
||||
#include "st0020.h"
|
||||
|
||||
const device_type ST0020_SPRITES = &device_creator<st0020_device>;
|
||||
|
||||
st0020_device::st0020_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
|
||||
: device_t(mconfig, ST0020_SPRITES, "st0020_device", tag, owner, clock)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
static const gfx_layout layout_16x8x8_2 =
|
||||
{
|
||||
16,8,
|
||||
0x400000/(16*8),
|
||||
8,
|
||||
{ STEP8(0,1) },
|
||||
{ STEP16(0,8) },
|
||||
{ STEP8(0,16*8) },
|
||||
16*8*8
|
||||
};
|
||||
|
||||
|
||||
|
||||
void st0020_device::device_start()
|
||||
{
|
||||
m_st0020_gfxram = auto_alloc_array_clear(machine(), UINT16, 4 * 0x100000 / 2);
|
||||
m_st0020_spriteram = auto_alloc_array_clear(machine(), UINT16, 0x80000 / 2);
|
||||
m_st0020_blitram = auto_alloc_array_clear(machine(), UINT16, 0x100 / 2);
|
||||
|
||||
for (m_gfx_index = 0; m_gfx_index < MAX_GFX_ELEMENTS; m_gfx_index++)
|
||||
if (machine().gfx[m_gfx_index] == 0)
|
||||
break;
|
||||
|
||||
machine().gfx[m_gfx_index] = gfx_element_alloc(machine(), &layout_16x8x8_2, (UINT8 *)m_st0020_gfxram, machine().total_colors() / 64, 0);
|
||||
|
||||
machine().gfx[m_gfx_index]->color_granularity = 64; /* 256 colour sprites with palette selectable on 64 colour boundaries */
|
||||
|
||||
}
|
||||
|
||||
void st0020_device::device_reset()
|
||||
{
|
||||
m_st0020_gfxram_bank = 0;
|
||||
}
|
||||
|
||||
|
||||
READ16_MEMBER(st0020_device::st0020_gfxram_r)
|
||||
{
|
||||
return m_st0020_gfxram[offset + m_st0020_gfxram_bank * 0x100000/2];
|
||||
}
|
||||
|
||||
WRITE16_MEMBER(st0020_device::st0020_gfxram_w)
|
||||
{
|
||||
offset += m_st0020_gfxram_bank * 0x100000/2;
|
||||
COMBINE_DATA(&m_st0020_gfxram[offset]);
|
||||
gfx_element_mark_dirty(machine().gfx[m_gfx_index], offset / (16*8/2));
|
||||
}
|
||||
|
||||
READ16_MEMBER(st0020_device::st0020_sprram_r)
|
||||
{
|
||||
return m_st0020_spriteram[offset];
|
||||
}
|
||||
|
||||
WRITE16_MEMBER(st0020_device::st0020_sprram_w)
|
||||
{
|
||||
COMBINE_DATA(&m_st0020_spriteram[offset]);
|
||||
}
|
||||
|
||||
READ16_MEMBER(st0020_device::st0020_blitram_r)
|
||||
{
|
||||
switch (offset)
|
||||
{
|
||||
case 0x00/2:
|
||||
// blitter status? (bit C, bit A)
|
||||
return 0;
|
||||
}
|
||||
|
||||
logerror("CPU #0 PC: %06X - Blit reg read: %02X\n",cpu_get_pc(&space.device()),offset*2);
|
||||
return 0;
|
||||
}
|
||||
|
||||
WRITE16_MEMBER(st0020_device::st0020_blitram_w)
|
||||
{
|
||||
UINT16 *st0020_blitram = m_st0020_blitram;
|
||||
|
||||
COMBINE_DATA(&st0020_blitram[offset]);
|
||||
|
||||
switch (offset)
|
||||
{
|
||||
case 0x8a/2:
|
||||
{
|
||||
if (data & ~0x43)
|
||||
logerror("CPU #0 PC: %06X - Unknown st0020_gfxram_bank bit written %04X\n",cpu_get_pc(&space.device()),data);
|
||||
|
||||
if (ACCESSING_BITS_0_7)
|
||||
m_st0020_gfxram_bank = data & 3;
|
||||
}
|
||||
break;
|
||||
|
||||
case 0xc0/2:
|
||||
case 0xc2/2:
|
||||
case 0xc4/2:
|
||||
case 0xc6/2:
|
||||
case 0xc8/2:
|
||||
break;
|
||||
|
||||
case 0xca/2:
|
||||
{
|
||||
UINT32 src = (st0020_blitram[0xc0/2] + (st0020_blitram[0xc2/2] << 16)) << 1;
|
||||
UINT32 dst = (st0020_blitram[0xc4/2] + (st0020_blitram[0xc6/2] << 16)) << 4;
|
||||
UINT32 len = (st0020_blitram[0xc8/2]) << 4;
|
||||
|
||||
UINT8 *rom = memregion(":st0020")->base();
|
||||
|
||||
|
||||
if (!rom)
|
||||
{
|
||||
logerror("CPU #0 PC: %06X - Blit out of range: src %x, dst %x, len %x\n",cpu_get_pc(&space.device()),src,dst,len);
|
||||
return;
|
||||
}
|
||||
|
||||
size_t size = memregion(":st0020")->bytes();
|
||||
|
||||
if ( (src+len <= size) && (dst+len <= 4 * 0x100000) )
|
||||
{
|
||||
memcpy( &m_st0020_gfxram[dst/2], &rom[src], len );
|
||||
|
||||
if (len % (16*8)) len = len / (16*8) + 1;
|
||||
else len = len / (16*8);
|
||||
|
||||
dst /= 16*8;
|
||||
while (len--)
|
||||
{
|
||||
gfx_element_mark_dirty(machine().gfx[m_gfx_index], dst);
|
||||
dst++;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
logerror("CPU #0 PC: %06X - Blit out of range: src %x, dst %x, len %x\n",cpu_get_pc(&space.device()),src,dst,len);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
logerror("CPU #0 PC: %06X - Blit reg written: %02X <- %04X\n",cpu_get_pc(&space.device()),offset*2,data);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/*
|
||||
Sprites RAM is 0x80000 bytes long. The first 0x2000? bytes hold a list
|
||||
of sprites to display (the list can be made shorter using an end-of-list
|
||||
marker).
|
||||
|
||||
Each entry in the list (16 bytes) is a multi-sprite (e.g it tells the
|
||||
hardware to display several single-sprites).
|
||||
|
||||
The list looks like this:
|
||||
|
||||
Offset: Bits: Value:
|
||||
|
||||
0.h fedc ba-- ---- ----
|
||||
---- --98 7654 3210 X displacement
|
||||
|
||||
2.h fedc ba-- ---- ----
|
||||
---- --98 7654 3210 Y displacement
|
||||
|
||||
4.h f--- ---- ---- ---- List end
|
||||
-edc ba98 7654 3210 Offset of the single-sprite(s) data
|
||||
|
||||
0.h Number of single-sprites (how many bits?)
|
||||
|
||||
A single-sprite is:
|
||||
|
||||
Offset: Bits: Value:
|
||||
|
||||
0.h Code
|
||||
|
||||
2.h f--- ---- ---- ---- Flip X
|
||||
-e-- ---- ---- ---- Flip Y
|
||||
---- -a-- ---- ---- 0 = 256 color steps, 1 = 64 color steps
|
||||
---- --98 7654 3210 Color code
|
||||
|
||||
4.h fedc ba-- ---- ----
|
||||
---- --98 7654 3210 X displacement
|
||||
|
||||
6.h fedc ba-- ---- ----
|
||||
---- --98 7654 3210 Y displacement
|
||||
|
||||
8.h fedc ba98 ---- ---- Y Size
|
||||
---- ---- 7654 3210 X Size
|
||||
|
||||
A.h fedc ba98 ---- ----
|
||||
---- ---- 7654 ---- Priority
|
||||
---- ---- ---- 32-- Y Tiles (1,2,4,8)
|
||||
---- ---- ---- --10 X Tiles (1,2,4,8)
|
||||
|
||||
C.h Unused
|
||||
|
||||
E.h Unused
|
||||
|
||||
*/
|
||||
void st0020_device::st0020_draw_zooming_sprites(running_machine &machine, bitmap_ind16 &bitmap, const rectangle &cliprect, int priority)
|
||||
{
|
||||
/* Sprites list */
|
||||
UINT16 *spriteram16_2 = m_st0020_spriteram;
|
||||
UINT16 *s1 = spriteram16_2;
|
||||
UINT16 *end1 = spriteram16_2 + 0x02000/2;
|
||||
UINT16 *s2;
|
||||
|
||||
priority <<= 4;
|
||||
|
||||
for ( ; s1 < end1; s1+=8/2 )
|
||||
{
|
||||
int attr, code, color, num, sprite, zoom, size;
|
||||
int sx, x, xoffs, flipx, xnum, xstart, xend, xinc, xdim, xscale;
|
||||
int sy, y, yoffs, flipy, ynum, ystart, yend, yinc, ydim, yscale;
|
||||
|
||||
xoffs = s1[ 0 ];
|
||||
yoffs = s1[ 1 ];
|
||||
sprite = s1[ 2 ];
|
||||
num = s1[ 3 ] % 0x101;
|
||||
|
||||
/* Last sprite */
|
||||
if (sprite & 0x8000) break;
|
||||
|
||||
/* Single-sprite address */
|
||||
s2 = &spriteram16_2[ (sprite & 0x7fff) * 16/2 ];
|
||||
|
||||
for( ; num > 0; num--,s2+=16/2 )
|
||||
{
|
||||
code = s2[ 0 ];
|
||||
attr = s2[ 1 ];
|
||||
sx = s2[ 2 ];
|
||||
sy = s2[ 3 ];
|
||||
zoom = s2[ 4 ];
|
||||
size = s2[ 5 ];
|
||||
|
||||
if (priority != (size & 0xf0))
|
||||
break;
|
||||
|
||||
flipx = (attr & 0x8000);
|
||||
flipy = (attr & 0x4000);
|
||||
|
||||
/*
|
||||
if ((ssv_scroll[0x74/2] & 0x1000) && ((ssv_scroll[0x74/2] & 0x2000) == 0))
|
||||
{
|
||||
if (flipx == 0) flipx = 1; else flipx = 0;
|
||||
}
|
||||
if ((ssv_scroll[0x74/2] & 0x4000) && ((ssv_scroll[0x74/2] & 0x2000) == 0))
|
||||
{
|
||||
if (flipy == 0) flipy = 1; else flipy = 0;
|
||||
}
|
||||
*/
|
||||
|
||||
color = (attr & 0x0400) ? attr : attr * 4;
|
||||
|
||||
/* Single-sprite tile size */
|
||||
xnum = 1 << ((size >> 0) & 3);
|
||||
ynum = 1 << ((size >> 2) & 3);
|
||||
|
||||
xnum = (xnum + 1) / 2;
|
||||
|
||||
if (flipx) { xstart = xnum-1; xend = -1; xinc = -1; }
|
||||
else { xstart = 0; xend = xnum; xinc = +1; }
|
||||
|
||||
if (flipy) { ystart = ynum-1; yend = -1; yinc = -1; }
|
||||
else { ystart = 0; yend = ynum; yinc = +1; }
|
||||
|
||||
/* Apply global offsets */
|
||||
sx += xoffs;
|
||||
sy += yoffs;
|
||||
|
||||
/* Sign extend the position */
|
||||
sx = (sx & 0x1ff) - (sx & 0x200);
|
||||
sy = (sy & 0x1ff) - (sy & 0x200);
|
||||
|
||||
sy = -sy;
|
||||
|
||||
/* Use fixed point values (16.16), for accuracy */
|
||||
sx <<= 16;
|
||||
sy <<= 16;
|
||||
|
||||
xdim = ( ( ((zoom >> 0) & 0xff) + 1) << 16 ) / xnum;
|
||||
ydim = ( ( ((zoom >> 8) & 0xff) + 1) << 16 ) / ynum;
|
||||
|
||||
xscale = xdim / 16;
|
||||
yscale = ydim / 8;
|
||||
|
||||
/* Let's approximate to the nearest greater integer value
|
||||
to avoid holes in between tiles */
|
||||
if (xscale & 0xffff) xscale += (1<<16) / 16;
|
||||
if (yscale & 0xffff) yscale += (1<<16) / 8;
|
||||
|
||||
/* Draw the tiles */
|
||||
|
||||
for (x = xstart; x != xend; x += xinc)
|
||||
{
|
||||
for (y = ystart; y != yend; y += yinc)
|
||||
{
|
||||
drawgfxzoom_transpen( bitmap, cliprect, machine.gfx[m_gfx_index],
|
||||
code++,
|
||||
color,
|
||||
flipx, flipy,
|
||||
(sx + x * xdim) / 0x10000, (sy + y * ydim) / 0x10000,
|
||||
xscale, yscale, 0
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#if 0 /* doesn't compile in a device context (can't use ui_draw_text? */
|
||||
if (machine.input().code_pressed(KEYCODE_Z)) /* Display some info on each sprite */
|
||||
{
|
||||
char buf[10];
|
||||
sprintf(buf, "%X",size);
|
||||
ui_draw_text(&machine.render().ui_container(), buf, sx / 0x10000, sy / 0x10000);
|
||||
}
|
||||
#endif
|
||||
} /* single-sprites */
|
||||
|
||||
} /* sprites list */
|
||||
}
|
||||
|
||||
|
||||
|
||||
void st0020_device::st0020_draw_all(running_machine &machine, bitmap_ind16 &bitmap, const rectangle &cliprect)
|
||||
{
|
||||
for (int pri = 0; pri <= 0xf; pri++)
|
||||
st0020_draw_zooming_sprites(machine, bitmap, cliprect, pri);
|
||||
}
|
||||
|
37
src/mame/video/st0020.h
Normal file
37
src/mame/video/st0020.h
Normal file
@ -0,0 +1,37 @@
|
||||
|
||||
|
||||
|
||||
class st0020_device : public device_t
|
||||
{
|
||||
public:
|
||||
st0020_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
|
||||
|
||||
int m_gfx_index;
|
||||
int m_st0020_gfxram_bank;
|
||||
UINT16* m_st0020_gfxram;
|
||||
UINT16* m_st0020_spriteram;
|
||||
UINT16* m_st0020_blitram;
|
||||
|
||||
void st0020_draw_zooming_sprites(running_machine &machine, bitmap_ind16 &bitmap, const rectangle &cliprect, int priority);
|
||||
void st0020_draw_all(running_machine &machine, bitmap_ind16 &bitmap, const rectangle &cliprect);
|
||||
|
||||
DECLARE_READ16_MEMBER(st0020_gfxram_r);
|
||||
DECLARE_WRITE16_MEMBER(st0020_gfxram_w);
|
||||
DECLARE_READ16_MEMBER(st0020_blitram_r);
|
||||
DECLARE_WRITE16_MEMBER(st0020_blitram_w);
|
||||
DECLARE_READ16_MEMBER(st0020_sprram_r);
|
||||
DECLARE_WRITE16_MEMBER(st0020_sprram_w);
|
||||
|
||||
protected:
|
||||
virtual void device_start();
|
||||
virtual void device_reset();
|
||||
|
||||
private:
|
||||
|
||||
|
||||
|
||||
};
|
||||
|
||||
|
||||
extern const device_type ST0020_SPRITES;
|
||||
|
Loading…
Reference in New Issue
Block a user