- Added tilemaps and sprites 4bpp mode

- Added preliminary ROZ implementation (disabled until the enable / disable register is found)
- Changed background pen to fix emeralda demo
This commit is contained in:
Pierpaolo Prazzoli 2008-04-01 21:29:29 +00:00
parent f4b7ad20e2
commit f95ec93c7c
2 changed files with 142 additions and 95 deletions

View File

@ -726,7 +726,7 @@ static READ16_HANDLER( custom_key_r )
old_count = count;
do
{
count = mame_rand(Machine);
count = mame_rand(machine);
} while( old_count == count );
switch( namcona1_gametype )
@ -797,7 +797,7 @@ static READ16_HANDLER( custom_key_r )
default:
return 0;
}
return mame_rand(Machine)&0xffff;
return mame_rand(machine)&0xffff;
} /* custom_key_r */
static WRITE16_HANDLER( custom_key_w )
@ -1053,16 +1053,6 @@ static WRITE16_HANDLER( namcona1_vreg_w )
/***************************************************************/
static WRITE16_HANDLER( bogus_w )
{
// DEBUGGER_BREAK;
}
static READ16_HANDLER( bogus_r )
{
// DEBUGGER_BREAK;
return 0;
}
// MCU "mailslot" handler - has 8 16-bit slots mirrored
static UINT16 mcu_mailbox[8];
@ -1075,7 +1065,7 @@ static WRITE16_HANDLER( mcu_mailbox_w_68k )
{
// logerror("mailbox_w_68k: %x @ %x\n", data, offset);
if (offset == 4) cpunum_set_input_line(Machine, 1, M37710_LINE_IRQ0, HOLD_LINE);
if (offset == 4) cpunum_set_input_line(machine, 1, M37710_LINE_IRQ0, HOLD_LINE);
COMBINE_DATA(&mcu_mailbox[offset%8]);
}
@ -1085,44 +1075,20 @@ static WRITE16_HANDLER( mcu_mailbox_w_mcu )
COMBINE_DATA(&mcu_mailbox[offset%8]);
}
static ADDRESS_MAP_START( namcona1_mcu_readmem, ADDRESS_SPACE_PROGRAM, 16 )
static ADDRESS_MAP_START( namcona1_main_map, ADDRESS_SPACE_PROGRAM, 16 )
AM_RANGE(0x000000, 0x07ffff) AM_RAM AM_BASE(&namcona1_workram)
AM_RANGE(0x080000, 0x3f7fff) AM_READ(bogus_r)
AM_RANGE(0x3f8000, 0x3fffff) AM_READ(mcu_mailbox_r)
AM_RANGE(0x3f8000, 0x3fffff) AM_READWRITE(mcu_mailbox_r, mcu_mailbox_w_68k)
AM_RANGE(0x400000, 0xbfffff) AM_ROM AM_REGION(REGION_CPU1, 0x280000) /* data */
AM_RANGE(0xc00000, 0xdfffff) AM_ROM AM_REGION(REGION_CPU1, 0x080000) /* code */
AM_RANGE(0xe00000, 0xe00fff) AM_READ(namcona1_nvram_r)
AM_RANGE(0xe40000, 0xe4000f) AM_READ(custom_key_r)
AM_RANGE(0xe40010, 0xeffeff) AM_READ(bogus_r)
AM_RANGE(0xefff00, 0xefffff) AM_READ(namcona1_vreg_r)
AM_RANGE(0xf00000, 0xf01fff) AM_READ(namcona1_paletteram_r)
AM_RANGE(0xf02000, 0xf3ffff) AM_READ(bogus_r)
AM_RANGE(0xf40000, 0xf7ffff) AM_READ(namcona1_gfxram_r)
AM_RANGE(0xf80000, 0xfeffff) AM_READ(bogus_r)
AM_RANGE(0xff0000, 0xff7fff) AM_READ(namcona1_videoram_r)
AM_RANGE(0xff8000, 0xffdfff) AM_READ(SMH_RAM) /* spare videoram */
AM_RANGE(0xffe000, 0xffefff) AM_READ(SMH_RAM) /* scroll registers */
AM_RANGE(0xfff000, 0xffffff) AM_READ(SMH_RAM) /* spriteram */
ADDRESS_MAP_END
static ADDRESS_MAP_START( namcona1_mcu_writemem, ADDRESS_SPACE_PROGRAM, 16 )
AM_RANGE(0x000000, 0x07ffff) AM_RAM
AM_RANGE(0x080000, 0x3f7fff) AM_WRITE(bogus_w)
AM_RANGE(0x3f8000, 0x3fffff) AM_WRITE(mcu_mailbox_w_68k)
AM_RANGE(0x400000, 0xdfffff) AM_WRITE(SMH_ROM) /* data + code */
AM_RANGE(0xe00000, 0xe00fff) AM_WRITE(namcona1_nvram_w)
AM_RANGE(0xe01000, 0xe3ffff) AM_WRITE(bogus_w)
AM_RANGE(0xe40000, 0xe4000f) AM_WRITE(custom_key_w)
AM_RANGE(0xe40010, 0xeffeff) AM_WRITE(bogus_w)
AM_RANGE(0xefff00, 0xefffff) AM_WRITE(namcona1_vreg_w) AM_BASE(&namcona1_vreg)
AM_RANGE(0xf00000, 0xf01fff) AM_WRITE(namcona1_paletteram_w) AM_BASE(&paletteram16)
AM_RANGE(0xf02000, 0xf3ffff) AM_WRITE(bogus_w)
AM_RANGE(0xf40000, 0xf7ffff) AM_WRITE(namcona1_gfxram_w)
AM_RANGE(0xf80000, 0xfeffff) AM_WRITE(bogus_w)
AM_RANGE(0xff0000, 0xff7fff) AM_WRITE(namcona1_videoram_w) AM_BASE(&videoram16)
AM_RANGE(0xff8000, 0xffdfff) AM_WRITE(SMH_RAM) AM_BASE(&namcona1_sparevram)
AM_RANGE(0xffe000, 0xffefff) AM_WRITE(SMH_RAM) AM_BASE(&namcona1_scroll)
AM_RANGE(0xfff000, 0xffffff) AM_WRITE(SMH_RAM) AM_BASE(&spriteram16)
AM_RANGE(0xe00000, 0xe00fff) AM_READWRITE(namcona1_nvram_r, namcona1_nvram_w)
AM_RANGE(0xe40000, 0xe4000f) AM_READWRITE(custom_key_r, custom_key_w)
AM_RANGE(0xefff00, 0xefffff) AM_READWRITE(namcona1_vreg_r, namcona1_vreg_w) AM_BASE(&namcona1_vreg)
AM_RANGE(0xf00000, 0xf01fff) AM_READWRITE(namcona1_paletteram_r, namcona1_paletteram_w) AM_BASE(&paletteram16)
AM_RANGE(0xf40000, 0xf7ffff) AM_READWRITE(namcona1_gfxram_r, namcona1_gfxram_w)
AM_RANGE(0xff0000, 0xff7fff) AM_READWRITE(namcona1_videoram_r, namcona1_videoram_w) AM_BASE(&videoram16)
AM_RANGE(0xff8000, 0xffdfff) AM_RAM AM_BASE(&namcona1_sparevram) /* spare videoram */
AM_RANGE(0xffe000, 0xffefff) AM_RAM AM_BASE(&namcona1_scroll) /* scroll registers */
AM_RANGE(0xfff000, 0xffffff) AM_RAM AM_BASE(&spriteram16) /* spriteram */
ADDRESS_MAP_END
/* ----- NA-1 MCU handling ----------------------------------- */
@ -1193,7 +1159,7 @@ static WRITE8_HANDLER( port4_w )
logerror("launching 68k, PC=%x\n", activecpu_get_pc());
// reset and launch the 68k
cpunum_set_input_line(Machine, 0, INPUT_LINE_RESET, CLEAR_LINE);
cpunum_set_input_line(machine, 0, INPUT_LINE_RESET, CLEAR_LINE);
}
mcu_port4 = data;
@ -1311,7 +1277,7 @@ static INTERRUPT_GEN( namcona1_interrupt )
{
simulate_mcu();
}
if( mEnableInterrupts )
if(1)// mEnableInterrupts )
{
if( (namcona1_vreg[0x1a/2]&(1<<level))==0 )
{
@ -1344,7 +1310,7 @@ static const struct C140interface C140_interface_typeA =
static MACHINE_DRIVER_START( namcona1 )
/* basic machine hardware */
MDRV_CPU_ADD(M68000, 50113000/4)
MDRV_CPU_PROGRAM_MAP(namcona1_mcu_readmem,namcona1_mcu_writemem)
MDRV_CPU_PROGRAM_MAP(namcona1_main_map,0)
MDRV_CPU_VBLANK_INT_HACK(namcona1_interrupt,5)
MDRV_CPU_ADD(M37710, 50113000/4)
@ -1395,17 +1361,13 @@ MACHINE_DRIVER_END
static ADDRESS_MAP_START( namcona2_readmem, ADDRESS_SPACE_PROGRAM, 16 )
AM_RANGE(0x000000, 0x07ffff) AM_READ(SMH_RAM) /* work RAM */
AM_RANGE(0x080000, 0x3fffff) AM_READ(bogus_r)
AM_RANGE(0x400000, 0xbfffff) AM_ROM AM_REGION(REGION_CPU1, 0x280000) /* data */
AM_RANGE(0xc00000, 0xdfffff) AM_ROM AM_REGION(REGION_CPU1, 0x080000) /* code */
AM_RANGE(0xe00000, 0xe00fff) AM_READ(namcona1_nvram_r)
AM_RANGE(0xe40000, 0xe4000f) AM_READ(custom_key_r)
AM_RANGE(0xe40010, 0xeffeff) AM_READ(bogus_r)
AM_RANGE(0xefff00, 0xefffff) AM_READ(namcona1_vreg_r)
AM_RANGE(0xf00000, 0xf01fff) AM_READ(namcona1_paletteram_r)
AM_RANGE(0xf02000, 0xf3ffff) AM_READ(bogus_r)
AM_RANGE(0xf40000, 0xf7ffff) AM_READ(namcona1_gfxram_r)
AM_RANGE(0xf80000, 0xfeffff) AM_READ(bogus_r)
AM_RANGE(0xff0000, 0xff7fff) AM_READ(namcona1_videoram_r)
AM_RANGE(0xff8000, 0xffdfff) AM_READ(SMH_RAM) /* spare videoram */
AM_RANGE(0xffe000, 0xffefff) AM_READ(SMH_RAM) /* scroll registers */
@ -1415,19 +1377,13 @@ ADDRESS_MAP_END
static ADDRESS_MAP_START( namcona2_writemem, ADDRESS_SPACE_PROGRAM, 16 )
AM_RANGE(0x000000, 0x000fff) AM_WRITE(namcona1_mcu_w) AM_BASE(&mcu_ram)
AM_RANGE(0x000000, 0x07ffff) AM_WRITE(SMH_RAM) AM_BASE(&namcona1_workram)
AM_RANGE(0x080000, 0x3f8007) AM_WRITE(bogus_w)
AM_RANGE(0x3f8008, 0x3f8009) AM_WRITE(mcu_command_w)
AM_RANGE(0x3f800a, 0x3fffff) AM_WRITE(bogus_w)
AM_RANGE(0x400000, 0xdfffff) AM_WRITE(SMH_ROM) /* data + code */
AM_RANGE(0xe00000, 0xe00fff) AM_WRITE(namcona1_nvram_w)
AM_RANGE(0xe01000, 0xe3ffff) AM_WRITE(bogus_w)
AM_RANGE(0xe40000, 0xe4000f) AM_WRITE(custom_key_w)
AM_RANGE(0xe40010, 0xeffeff) AM_WRITE(bogus_w)
AM_RANGE(0xefff00, 0xefffff) AM_WRITE(namcona1_vreg_w) AM_BASE(&namcona1_vreg)
AM_RANGE(0xf00000, 0xf01fff) AM_WRITE(namcona1_paletteram_w) AM_BASE(&paletteram16)
AM_RANGE(0xf02000, 0xf3ffff) AM_WRITE(bogus_w)
AM_RANGE(0xf40000, 0xf7ffff) AM_WRITE(namcona1_gfxram_w)
AM_RANGE(0xf80000, 0xfeffff) AM_WRITE(bogus_w)
AM_RANGE(0xff0000, 0xff7fff) AM_WRITE(namcona1_videoram_w) AM_BASE(&videoram16)
AM_RANGE(0xff8000, 0xffdfff) AM_WRITE(SMH_RAM) AM_BASE(&namcona1_sparevram)
AM_RANGE(0xffe000, 0xffefff) AM_WRITE(SMH_RAM) AM_BASE(&namcona1_scroll)

View File

@ -1,5 +1,16 @@
/* Namco System NA1/2 Video Hardware */
/*
TODO:
- dynamic screen resolution
- bg pen (or the pen of the lower tilemap?)
- hook up roz tilemaps with roz enable / disable and tweak it (mainly missing offsets)
- sprites with shadow bit have bad colors
- check if the data&0x8000 condition in tilemaps is valid even when 4bpp mode it's used
- namco logo in emeralda demo is missing (it's used with a roz effect)
- invisible dolphin sprite in emeralda instruction screen
*/
#include "driver.h"
#include "namcona1.h"
@ -21,7 +32,7 @@ static int tilemap_palette_bank[NAMCONA1_NUM_TILEMAPS];
static int palette_is_dirty;
static void tilemap_get_info(
running_machine *machine,tile_data *tileinfo,int tile_index,const UINT16 *tilemap_videoram,int tilemap_color )
running_machine *machine,tile_data *tileinfo,int tile_index,const UINT16 *tilemap_videoram,int tilemap_color,int use_4bpp_gfx )
{
#ifdef LSB_FIRST
UINT16 *source;
@ -30,14 +41,26 @@ static void tilemap_get_info(
int data = tilemap_videoram[tile_index];
int tile = data&0xfff;
int gfx;
if( data&0x8000 )
if( use_4bpp_gfx )
{
SET_TILE_INFO( 0,tile,tilemap_color,TILE_FORCE_LAYER0 );
gfx = 1;
tilemap_color *= 0x10;
tilemap_color += (data & 0x7000)>>12;
}
else
{
SET_TILE_INFO( 0,tile,tilemap_color,0 );
gfx = 0;
}
if( data & 0x8000 )
{
SET_TILE_INFO( gfx,tile,tilemap_color,TILE_FORCE_LAYER0 );
}
else
{
SET_TILE_INFO( gfx,tile,tilemap_color,0 );
#ifdef LSB_FIRST
source = shaperam+4*tile;
mask_data[0] = source[0]>>8;
@ -55,10 +78,10 @@ static void tilemap_get_info(
}
} /* tilemap_get_info */
static TILE_GET_INFO( tilemap_get_info0 ){ tilemap_get_info(machine,tileinfo,tile_index,0*0x1000+videoram16,tilemap_palette_bank[0]); }
static TILE_GET_INFO( tilemap_get_info1 ){ tilemap_get_info(machine,tileinfo,tile_index,1*0x1000+videoram16,tilemap_palette_bank[1]); }
static TILE_GET_INFO( tilemap_get_info2 ){ tilemap_get_info(machine,tileinfo,tile_index,2*0x1000+videoram16,tilemap_palette_bank[2]); }
static TILE_GET_INFO( tilemap_get_info3 ){ tilemap_get_info(machine,tileinfo,tile_index,3*0x1000+videoram16,tilemap_palette_bank[3]); }
static TILE_GET_INFO( tilemap_get_info0 ){ tilemap_get_info(machine,tileinfo,tile_index,0*0x1000+videoram16,tilemap_palette_bank[0],namcona1_vreg[0x58+6]&1); }
static TILE_GET_INFO( tilemap_get_info1 ){ tilemap_get_info(machine,tileinfo,tile_index,1*0x1000+videoram16,tilemap_palette_bank[1],namcona1_vreg[0x58+6]&2); }
static TILE_GET_INFO( tilemap_get_info2 ){ tilemap_get_info(machine,tileinfo,tile_index,2*0x1000+videoram16,tilemap_palette_bank[2],namcona1_vreg[0x58+6]&4); }
static TILE_GET_INFO( tilemap_get_info3 ){ tilemap_get_info(machine,tileinfo,tile_index,3*0x1000+videoram16,tilemap_palette_bank[3],namcona1_vreg[0x58+6]&8); }
/*************************************************************************/
@ -122,7 +145,7 @@ static const gfx_layout shape_layout =
8*8
}; /* shape_layout */
static const gfx_layout cg_layout =
static const gfx_layout cg_layout_8bpp =
{
8,8,
0x1000,
@ -135,7 +158,22 @@ static const gfx_layout cg_layout =
#endif
{ 64*0,64*1,64*2,64*3,64*4,64*5,64*6,64*7 },
64*8
}; /* cg_layout */
}; /* cg_layout_8bpp */
static const gfx_layout cg_layout_4bpp =
{
8,8,
0x1000,
4, /* 4BPP */
{ 4,5,6,7 },
#ifdef LSB_FIRST
{ 8*1,8*0,8*3,8*2,8*5,8*4,8*7,8*6 },
#else
{ 8*0,8*1,8*2,8*3,8*4,8*5,8*6,8*7 },
#endif
{ 64*0,64*1,64*2,64*3,64*4,64*5,64*6,64*7 },
64*8
}; /* cg_layout_4bpp */
READ16_HANDLER( namcona1_gfxram_r )
{
@ -208,7 +246,8 @@ static void update_gfx(running_machine *machine)
{
dirtychar[i] = 0;
decodechar(machine->gfx[0],i,(UINT8 *)cgram);
decodechar(machine->gfx[1],i,(UINT8 *)shaperam);
decodechar(machine->gfx[1],i,(UINT8 *)cgram);
decodechar(machine->gfx[2],i,(UINT8 *)shaperam);
}
}
dirtygfx = 0;
@ -218,7 +257,7 @@ static void update_gfx(running_machine *machine)
VIDEO_START( namcona1 )
{
int i;
gfx_element *gfx0,*gfx1;
gfx_element *gfx0,*gfx1,*gfx2;
static const tile_get_info_func get_info[4] =
{ tilemap_get_info0, tilemap_get_info1, tilemap_get_info2, tilemap_get_info3 };
@ -236,13 +275,17 @@ VIDEO_START( namcona1 )
cgram = auto_malloc( 0x1000*0x20*2 );
dirtychar = auto_malloc( 0x1000 );
gfx0 = allocgfx( &cg_layout );
gfx1 = allocgfx( &shape_layout );
gfx0 = allocgfx( &cg_layout_8bpp );
gfx1 = allocgfx( &cg_layout_4bpp );
gfx2 = allocgfx( &shape_layout );
gfx0->total_colors = machine->config->total_colors/256;
machine->gfx[0] = gfx0;
gfx1->total_colors = machine->config->total_colors/2;
gfx1->total_colors = machine->config->total_colors/16;
machine->gfx[1] = gfx1;
gfx2->total_colors = machine->config->total_colors/2;
machine->gfx[2] = gfx2;
} /* namcona1_vh_start */
/*************************************************************************/
@ -256,10 +299,11 @@ static void pdraw_tile(running_machine *machine,
int flipx, int flipy,
int priority,
int bShadow,
int bOpaque )
int bOpaque,
int gfx_region )
{
const gfx_element *gfx = machine->gfx[0];
const gfx_element *mask = machine->gfx[1];
const gfx_element *gfx = machine->gfx[gfx_region];
const gfx_element *mask = machine->gfx[2];
int pal_base = gfx->color_base + gfx->color_granularity * (color % gfx->total_colors);
UINT8 *source_base = gfx->gfxdata + (code % gfx->total_elements) * gfx->char_modulo;
@ -360,8 +404,8 @@ static void pdraw_tile(running_machine *machine,
{
int c = source[x_index>>16];
/* render a shadow only if the sprites color is $F */
if( bShadow && color == 0x0f )
/* render a shadow only if the sprites color is $F (8bpp) or $FF (4bpp) */
if( bShadow && /*((gfx_region == 0 && color == 0x0f) || */(gfx_region == 1 && color == 0xff)/*)*/)
{
pen_t *palette_shadow_table = machine->shadow_table;
dest[x] = palette_shadow_table[dest[x]];
@ -404,7 +448,7 @@ static void draw_sprites(running_machine *machine, bitmap_t *bitmap, const recta
{ /* max 256 sprites */
ypos = source[0]; /* FHHH---Y YYYYYYYY flipy, height, ypos */
tile = source[1]; /* O???TTTT TTTTTTTT opaque tile */
color = source[2]; /* FSWW???B CCCC?PPP flipx, shadow, width, color, pri*/
color = source[2]; /* FSWWOOOO CCCCBPPP flipx, shadow, width, color offset for 4bpp, color, 4bbp - 8bpp mode, pri*/
xpos = source[3]; /* -------X XXXXXXXX xpos */
priority = color&0x7;
@ -436,17 +480,36 @@ static void draw_sprites(running_machine *machine, bitmap_t *bitmap, const recta
sx+=col*8;
}
pdraw_tile(machine,
bitmap,
cliprect,
(tile & 0xfff) + row*64+col,
(color>>4)&0xf,
((sx+16)&0x1ff)-8,
((sy+8)&0x1ff)-8,
flipx,flipy,
priority,
color & 0x4000, /* shadow */
tile & 0x8000 /* opaque */ );
if(color & 8)
{
pdraw_tile(machine,
bitmap,
cliprect,
(tile & 0xfff) + row*64+col,
((color>>4)&0xf) * 0x10 + ((color & 0xf00) >> 8),
((sx+16)&0x1ff)-8,
((sy+8)&0x1ff)-8,
flipx,flipy,
priority,
color & 0x4000, /* shadow */
tile & 0x8000, /* opaque */
1 /* 4bpp gfx */ );
}
else
{
pdraw_tile(machine,
bitmap,
cliprect,
(tile & 0xfff) + row*64+col,
(color>>4)&0xf,
((sx+16)&0x1ff)-8,
((sy+8)&0x1ff)-8,
flipx,flipy,
priority,
color & 0x4000, /* shadow */
tile & 0x8000, /* opaque */
0 /* 8bpp gfx */ );
}
} /* next col */
} /* next row */
@ -528,6 +591,31 @@ static void draw_background(running_machine *machine, bitmap_t *bitmap, const re
tilemap_set_scrollx( bg_tilemap[which], 0, scrollx );
tilemap_set_scrolly( bg_tilemap[which], 0, scrolly );
tilemap_draw_primask( bitmap, &clip, bg_tilemap[which], 0, primask, 0 );
#if 0
INT16 incxy, incyx, incxx, incyy;
INT16 xoffset, yoffset;
UINT32 startx,starty;
incxx = (INT16)namcona1_vreg[0xc0/2]; // or incyy ?
incxy = (INT16)namcona1_vreg[0xc2/2];
incyx = (INT16)namcona1_vreg[0xc4/2];
incyy = (INT16)namcona1_vreg[0xc6/2]; // or incxx ?
xoffset = namcona1_vreg[0xc8/2];
yoffset = namcona1_vreg[0xca/2];
//namcona1_vreg[0xcc/2]; // ?
startx = ((xoffset + a) << 12);
starty = ((yoffset + b) << 12);
popmessage("scrollx = %x - scrolly = %x - xo = %d - yo = %d",scrollx,scrolly,xoffset,yoffset);
tilemap_draw_roz_primask(bitmap, &clip, bg_tilemap[which],
startx , starty ,
incxx << 8, incxy << 8, incyx << 8, incyy << 8,
0, 0, primask, 0);
#endif
}
}
}
@ -562,14 +650,17 @@ VIDEO_UPDATE( namcona1 )
}
} /* next tilemap */
fillbitmap( priority_bitmap,0,cliprect );
fillbitmap( bitmap,0,cliprect );
// It fixes bg in emeralda
fillbitmap( bitmap,/* 0 */ 0xff,cliprect );
for( priority = 0; priority<8; priority++ )
{
for( which=NAMCONA1_NUM_TILEMAPS-1; which>=0; which-- )
{
if( (namcona1_vreg[0x50+which]&0x7) == priority )
{
draw_background(screen->machine,bitmap,cliprect,which,priority );
draw_background(screen->machine,bitmap,cliprect,which,priority);
}
} /* next tilemap */
} /* next priority level */