Bug fixes for NamcoNA Hardware:

- support for scanline effect (fixes invisible dolphin in Emeralda attract mode)
- ROZ implementation no longer breaks Numan Athletics pixmap layer
- blitter fixes; xday graphics are now correct
- identified extra communications RAM used by xday (probably to control printer)
This commit is contained in:
Phil Stroffolino 2008-05-14 12:50:42 +00:00
parent 4bdc8dd7b5
commit 1394652ab0
3 changed files with 85 additions and 138 deletions

View File

@ -19,24 +19,9 @@ NA-2 Games:
To Do:
- Pressing "F3" (reset) crashes MAME
- Emeralda:
After selecting the game type, tilemap scrolling is briefly incorrect
The demo sprites are incorrect, you should see a dolphin speaking
the instructions and the playfield is wrong.
Byte 0x25 of the NVRAM controls the FBI logo. 0x00 is on, 0x01 is off
- Hook up ROZ registers
Example: In Emeralda the game logo rotates and zooms in against a black
background with bubbles during the intro. Then at the second green screen
when flashing Please Insert Coin, the word NAMCO rotates past the viewer.
- Is view area controlled by registers?
- view area / screen resolution controlled by registers?
- Xday 2:
has some graphics glitches (wrong sprite tiles); probably blitter-related
Rom board M112
Rom board custom Key chip i.d. C394
Game uses a small cash-register type printer (connects to rom board)
@ -75,6 +60,8 @@ Notes:
button1 to up, button 2 to down, button 3 to left, button 4 to right.
But Taito F2 quiz games assign button 3 to right and button 4 to left.
- Emeralda: Byte 0x25 of the NVRAM, when zero, enables the FBI logo.
Namco NA2 hardware
------------------
@ -833,11 +820,11 @@ transfer_dword( running_machine *machine, UINT32 dest, UINT32 source )
logerror( "bad blt src %08x\n", source );
return -1;
}
if( dest>=0xf00000 && dest<=0xf02000 )
if( dest>=0xf00000 && dest<0xf02000 )
{
namcona1_paletteram_w( machine, (dest-0xf00000)/2, data, 0xffff );
}
else if( dest>=0xf40000 && dest<=0xf80000 )
else if( dest>=0xf40000 && dest<0xf80000 )
{
namcona1_gfxram_w( machine, (dest-0xf40000)/2, data, 0xffff );
}
@ -845,17 +832,17 @@ transfer_dword( running_machine *machine, UINT32 dest, UINT32 source )
{
namcona1_videoram_w( machine, (dest-0xff0000)/2, data, 0xffff );
}
else if( dest>=0xff8000 && dest<=0xffdfff )
else if( dest>=0xff8000 && dest<0xffc000 )
{
namcona1_sparevram[(dest-0xff8000)/2] = data;
namcona1_rozvideoram_w( machine, (dest-0xff8000)/2, data, 0xffff );
}
else if( dest>=0xfff000 && dest<=0xffffff )
else if( dest>=0xfff000 && dest<0x1000000 )
{
spriteram16[(dest-0xfff000)/2] = data;
}
else
{
logerror( "bad blt dst %08x\n", dest );
logerror( "bad blit dest %08x\n", dest );
return -1;
}
return 0;
@ -865,7 +852,7 @@ static void
blit_setup( int format, int *bytes_per_row, int *pitch, int mode )
{
if( mode == 3 )
{
{ /* TILE DATA */
switch( format )
{
case 0x0001:
@ -888,7 +875,7 @@ blit_setup( int format, int *bytes_per_row, int *pitch, int mode )
}
}
else
{
{ /* SHAPE DATA */
switch( format )
{
case 0x00bd: /* Numan Athletics */
@ -933,29 +920,6 @@ blit_setup( int format, int *bytes_per_row, int *pitch, int mode )
}
} /* blit_setup */
/*
$efff20: sprite control: 0x3a,0x3e,0x3f
bit 0x01 selects spriteram bank
0 2 4 6 8 a c e
$efff00: src0 src1 src2 dst0 dst1 dst2 BANK [src
$efff10: src] [dst dst] #BYT BLIT eINT 001f 0001
$efff20: 003f 003f IACK ---- ---- ---- ---- ----
$efff30: ---- ---- ---- ---- ---- ---- ---- ----
$efff40: ---- ---- ---- ---- ---- ---- ---- ----
$efff50: ---- ---- ---- ---- ---- ---- ---- ----
$efff60: ---- ---- ---- ---- ---- ---- ---- ----
$efff70: ---- ---- ---- ---- ---- ---- ---- ----
$efff80: 0050 0170 0020 0100 0000 0000 0000 GFXE
$efff90: 0000 0001 0002 0003 FLIP ---- ---- ----
$efffa0: PRI PRI PRI PRI ---- ---- 00c0 ---- priority (0..7)
$efffb0: COLR COLR COLR COLR 0001 0004 0000 ---- color (0..f)
$efffc0: ???? ???? ???? ???? ???? ???? ???? ---- ROZ
Emeralda:
$efff80: 0048 0177 0020 0100 0000 00fd 0000 GFXE
*/
static void namcona1_blit( running_machine *machine )
{
int src0 = namcona1_vreg[0x0];
@ -969,8 +933,8 @@ static void namcona1_blit( running_machine *machine )
int gfxbank = namcona1_vreg[0x6];
/* dest and source are provided as dword offsets */
UINT32 src_baseaddr = 2*((namcona1_vreg[0x7]<<16)|namcona1_vreg[0x8]);
UINT32 dst_baseaddr = 2*((namcona1_vreg[0x9]<<16)|namcona1_vreg[0xa]);
UINT32 src_baseaddr = 2*(0xffffff&((namcona1_vreg[0x7]<<16)|namcona1_vreg[0x8]));
UINT32 dst_baseaddr = 2*(0xffffff&((namcona1_vreg[0x9]<<16)|namcona1_vreg[0xa]));
int num_bytes = namcona1_vreg[0xb];
@ -982,14 +946,14 @@ static void namcona1_blit( running_machine *machine )
(void)dst0;
(void)src2;
(void)src0;
/* logerror( "0x%08x: blt(%08x,%08x,%08x);%04x %04x %04x; %04x %04x %04x; gfx=%04x\n",
/*
logerror( "0x%08x: blt(%08x,%08x,numBytes=%04x);src=%04x %04x %04x; dst=%04x %04x %04x; gfx=%04x\n",
activecpu_get_pc(),
dst_baseaddr,src_baseaddr,num_bytes,
src0,src1,src2,
dst0,dst1,dst2,
gfxbank );*/
gfxbank );
*/
blit_setup( dst1, &dst_bytes_per_row, &dst_pitch, gfxbank);
blit_setup( src1, &src_bytes_per_row, &src_pitch, gfxbank );
@ -1002,11 +966,6 @@ static void namcona1_blit( running_machine *machine )
{
dst_baseaddr += 0xf40000;
}
if( input_code_pressed(KEYCODE_N) )
{
printf( "src format=%04x baseaddr=%x width=%x pitch=%x\n", src1, src_baseaddr, src_bytes_per_row, src_pitch );
printf( "dst format=%04x baseaddr=%x width=%x pitch=%x\n", dst1, dst_baseaddr, dst_bytes_per_row, dst_pitch );
}
dst_offset = 0;
src_offset = 0;
@ -1091,8 +1050,8 @@ static ADDRESS_MAP_START( namcona1_main_map, ADDRESS_SPACE_PROGRAM, 16 )
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, 0xff8fff) AM_READWRITE(namcona1_rozvideoram_r, namcona1_rozvideoram_w) AM_BASE(&namcona1_rozvideoram)
AM_RANGE(0xff9000, 0xffdfff) AM_RAM AM_BASE(&namcona1_sparevram) /* spare videoram */
AM_RANGE(0xff8000, 0xffbfff) AM_READWRITE(namcona1_rozvideoram_r, namcona1_rozvideoram_w) AM_BASE(&namcona1_rozvideoram)
AM_RANGE(0xffd000, 0xffdfff) AM_RAM /* unknown */
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
@ -1276,38 +1235,26 @@ static ADDRESS_MAP_START( namcona1_mcu_io_map, ADDRESS_SPACE_IO, 8 )
AM_RANGE(0x10, 0x1f) AM_READ( portana_r )
ADDRESS_MAP_END
static TIMER_CALLBACK( namcona1_posirq )
{
video_screen_update_partial(machine->primary_screen, param);
cpunum_set_input_line(machine, 0/*CPU*/, 2+1, HOLD_LINE);
}
static INTERRUPT_GEN( namcona1_interrupt )
{
int level = cpu_getiloops(); /* 0,1,2,3,4 */
int posirq = input_code_pressed(KEYCODE_M);
if( level==0 )
{
simulate_mcu(machine);
if( mEnableInterrupts && posirq )
{
if( level==2 && namcona1_vreg[0x1a/2]&(1<<2) )
{
int scanline = 192;//namcona1_vreg[0xac/2];
timer_set(video_screen_get_time_until_pos(machine->primary_screen, scanline, 0), NULL, scanline, namcona1_posirq );
}
if( level==3 && namcona1_vreg[0x1a/2]&(1<<3) )
{
cpunum_set_input_line(machine, 0, 3+1, HOLD_LINE);
}
}
simulate_mcu( machine );
}
if( mEnableInterrupts && !posirq )
if( mEnableInterrupts )
{
if( (namcona1_vreg[0x1a/2]&(1<<level))==0 )
{
if( level!=2 && level!=3 ) printf( "level = %d\n", level );
if( level==2 )
{ // posirq used with dolphin in Emeraldia's "how to play" attract mode
int scanline = namcona1_vreg[0x8a/2]&0xff;
if( scanline )
{
video_screen_update_partial(machine->primary_screen, scanline );
}
}
cpunum_set_input_line(machine, 0, level+1, HOLD_LINE);
}
}
@ -1320,7 +1267,9 @@ static INTERRUPT_GEN( namcona1_interrupt )
static INTERRUPT_GEN( mcu_interrupt )
{
if (cpu_getiloops() == 0)
{
cpunum_set_input_line(machine, 1, M37710_LINE_IRQ1, HOLD_LINE);
}
else if (cpu_getiloops() == 1)
{
cpunum_set_input_line(machine, 1, M37710_LINE_ADC, HOLD_LINE);
@ -1387,25 +1336,30 @@ static MACHINE_DRIVER_START( namcona1w )
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(0x000000, 0x07ffff) AM_READ(SMH_RAM) /* work RAM */
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)
/* xday: additional battery-backed ram at 00E024FA? */
AM_RANGE(0xe40000, 0xe4000f) AM_READ(custom_key_r)
AM_RANGE(0xefff00, 0xefffff) AM_READ(namcona1_vreg_r)
AM_RANGE(0xf00000, 0xf01fff) AM_READ(namcona1_paletteram_r)
AM_RANGE(0xf40000, 0xf7ffff) AM_READ(namcona1_gfxram_r)
AM_RANGE(0xff0000, 0xff7fff) AM_READ(namcona1_videoram_r)
AM_RANGE(0xff8000, 0xff8fff) AM_READ(namcona1_rozvideoram_r )
AM_RANGE(0xff9000, 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 */
AM_RANGE(0xff8000, 0xffbfff) AM_READ(namcona1_rozvideoram_r )
AM_RANGE(0xffd000, 0xffdfff) AM_READ(SMH_RAM) /* unknown */
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( 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(0x3f8008, 0x3f8009) AM_WRITE(mcu_command_w)
AM_RANGE(0xd00000, 0xd00001) AM_WRITE(SMH_NOP) /* xday: serial out? */
AM_RANGE(0xd40000, 0xd40001) AM_WRITE(SMH_NOP) /* xday: serial out? */
AM_RANGE(0xd80000, 0xd80001) AM_WRITE(SMH_NOP) /* xday: serial out? */
AM_RANGE(0xdc0000, 0xdc001f) AM_WRITE(SMH_NOP) /* xday: serial config? */
AM_RANGE(0x400000, 0xdfffff) AM_WRITE(SMH_ROM) /* data + code */
AM_RANGE(0xe00000, 0xe00fff) AM_WRITE(namcona1_nvram_w)
AM_RANGE(0xe40000, 0xe4000f) AM_WRITE(custom_key_w)
@ -1413,8 +1367,8 @@ static ADDRESS_MAP_START( namcona2_writemem, ADDRESS_SPACE_PROGRAM, 16 )
AM_RANGE(0xf00000, 0xf01fff) AM_WRITE(namcona1_paletteram_w) AM_BASE(&paletteram16)
AM_RANGE(0xf40000, 0xf7ffff) AM_WRITE(namcona1_gfxram_w)
AM_RANGE(0xff0000, 0xff7fff) AM_WRITE(namcona1_videoram_w) AM_BASE(&videoram16)
AM_RANGE(0xff8000, 0xff8fff) AM_WRITE(namcona1_rozvideoram_w) AM_BASE(&namcona1_rozvideoram)
AM_RANGE(0xff9000, 0xffdfff) AM_WRITE(SMH_RAM) AM_BASE(&namcona1_sparevram)
AM_RANGE(0xff8000, 0xffbfff) AM_WRITE(namcona1_rozvideoram_w) AM_BASE(&namcona1_rozvideoram)
AM_RANGE(0xffd000, 0xffdfff) AM_WRITE(SMH_RAM) /* unknown */
AM_RANGE(0xffe000, 0xffefff) AM_WRITE(SMH_RAM) AM_BASE(&namcona1_scroll)
AM_RANGE(0xfff000, 0xffffff) AM_WRITE(SMH_RAM) AM_BASE(&spriteram16)
ADDRESS_MAP_END

View File

@ -26,7 +26,6 @@ extern UINT16 *namcona1_rozvideoram;
extern UINT16 *namcona1_workram;
extern UINT16 *namcona1_vreg;
extern UINT16 *namcona1_scroll;
extern UINT16 *namcona1_sparevram;
extern WRITE16_HANDLER( namcona1_rozvideoram_w );
extern READ16_HANDLER( namcona1_rozvideoram_r );

View File

@ -2,10 +2,8 @@
/*
TODO:
- dynamic screen resolution
- is background pen configurable?
- dynamic screen resolution (changes between emeralda test mode and normal game)
- non-shadow pixels for sprites flagged to enable shadows have bad colors
- dolphin sprite in emeralda instruction screen is missing because of an incorrectly emulated scanline irq
*/
#include "driver.h"
@ -19,6 +17,7 @@ UINT16 *namcona1_scroll;
UINT16 *namcona1_workram;
UINT16 *namcona1_sparevram;
UINT16 *namcona1_rozvideoram;
UINT16 *namcona1_pixmap;
/* private variables */
static char *dirtychar;
@ -158,11 +157,7 @@ READ16_HANDLER( namcona1_videoram_r )
static void
UpdatePalette(running_machine *machine, int offset )
{
UINT16 color;
color = paletteram16[offset];
/* -RRRRRGGGGGBBBBB */
UINT16 color = paletteram16[offset]; /* -RRRRRGGGGGBBBBB */
palette_set_color_rgb( machine, offset, pal5bit(color >> 10), pal5bit(color >> 5), pal5bit(color >> 0));
} /* namcona1_paletteram_w */
@ -279,7 +274,7 @@ WRITE16_HANDLER( namcona1_gfxram_w )
}
} /* namcona1_gfxram_w */
static void update_gfx(running_machine *machine)
static void UpdateGfx(running_machine *machine)
{
const UINT16 *pSource = videoram16;
int page;
@ -302,7 +297,7 @@ static void update_gfx(running_machine *machine)
for( i=0; i<0x800; i++ )
{
if( dirtychar[*pSource++ & 0xfff] )
{ // todo: this checks only if top-left tile has changed
{
roz_dirty = 1;
break;
}
@ -320,7 +315,7 @@ static void update_gfx(running_machine *machine)
}
dirtygfx = 0;
}
} /* update_gfx */
} /* UpdateGfx */
VIDEO_START( namcona1 )
{
@ -337,10 +332,10 @@ VIDEO_START( namcona1 )
tilemap_palette_bank[i] = -1;
}
shaperam = auto_malloc( 0x1000*4*2 );
shaperam = auto_malloc( 0x2000*4 );
cgram = auto_malloc( 0x1000*0x20*2 );
dirtychar = auto_malloc( 0x1000 );
namcona1_rozvideoram = auto_malloc( 0x1000 );
namcona1_rozvideoram = auto_malloc( 0x4000 );
gfx0 = allocgfx( &cg_layout_8bpp );
gfx0->total_colors = machine->config->total_colors/256;
@ -481,8 +476,8 @@ static void pdraw_tile(running_machine *machine,
dest[x] = palette_shadow_table[dest[x]];
}
else
{
dest[x] = pal_base + c;
{ // bad?
dest[x] = pal_base+c;
}
}
else
@ -520,6 +515,7 @@ static void draw_sprites(running_machine *machine, bitmap_t *bitmap, const recta
for( which=0; which<0x100; which++ )
{ /* max 256 sprites */
int bpp4,palbase;
ypos = source[0]; /* FHHH---Y YYYYYYYY flipy, height, ypos */
tile = source[1]; /* O???TTTT TTTTTTTT opaque tile */
color = source[2]; /* FSWWOOOO CCCCBPPP flipx, shadow, width, color offset for 4bpp, color, 4bbp - 8bpp mode, pri*/
@ -531,6 +527,17 @@ static void draw_sprites(running_machine *machine, bitmap_t *bitmap, const recta
flipy = ypos&0x8000;
flipx = color&0x8000;
if( color&8 )
{
palbase = ((color>>4)&0xf) * 0x10 + ((color & 0xf00) >> 8);
bpp4 = 1;
}
else
{
palbase = (color>>4)&0xf;
bpp4 = 0;
}
for( row=0; row<height; row++ )
{
sy = (ypos&0x1ff)-30+32;
@ -542,6 +549,8 @@ static void draw_sprites(running_machine *machine, bitmap_t *bitmap, const recta
{
sy += row*8;
}
sy = ((sy+8)&0x1ff)-8;
for( col=0; col<width; col++ )
{
sx = (xpos&0x1ff)-10;
@ -554,34 +563,17 @@ static void draw_sprites(running_machine *machine, bitmap_t *bitmap, const recta
sx+=col*8;
}
sx = ((sx+16)&0x1ff)-8;
sy = ((sy+8)&0x1ff)-8;
if(color & 8)
{
pdraw_tile(machine,
bitmap,
cliprect,
(tile & 0xfff) + row*64+col,
((color>>4)&0xf) * 0x10 + ((color & 0xf00) >> 8),
sx,sy,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,sy,flipx,flipy,
priority,
color & 0x4000, /* shadow */
tile & 0x8000, /* opaque */
0 /* 8bpp gfx */ );
}
pdraw_tile(machine,
bitmap,
cliprect,
(tile & 0xfff) + row*64+col,
palbase,
sx,sy,flipx,flipy,
priority,
color & 0x4000, /* shadow */
tile & 0x8000, /* opaque */
bpp4 );
} /* next col */
} /* next row */
@ -655,7 +647,7 @@ static void draw_background(running_machine *machine, bitmap_t *bitmap, const re
draw_pixel_line(
BITMAP_ADDR16(bitmap, line, 0),
BITMAP_ADDR8(priority_bitmap, line, 0),
namcona1_sparevram + (ydata-0x4000) + 25,
namcona1_rozvideoram + (ydata-0x4000) + 25,
paldata );
}
else
@ -697,6 +689,7 @@ VIDEO_UPDATE( namcona1 )
{
int which;
int priority;
/* int flipscreen = namcona1_vreg[0x98/2]; (TBA) */
if( namcona1_vreg[0x8e/2] )
@ -710,7 +703,7 @@ VIDEO_UPDATE( namcona1 )
}
palette_is_dirty = 0;
}
update_gfx(screen->machine);
UpdateGfx(screen->machine);
for( which=0; which<NAMCONA1_NUM_TILEMAPS; which++ )
{
int tilemap_color = namcona1_vreg[0xb0/2+(which&3)]&0xf;
@ -721,14 +714,15 @@ VIDEO_UPDATE( namcona1 )
}
} /* next tilemap */
{
int color = namcona1_vreg[0xb0/2+5]&0xf;
{ /* ROZ tilemap */
int color = namcona1_vreg[0xba/2]&0xf;
if( color != roz_palette )
{
roz_dirty = 1;
roz_palette = color;
}
}
if( roz_dirty )
{
tilemap_mark_all_tiles_dirty( roz_tilemap );
@ -764,9 +758,9 @@ $efff20: sprite control: 0x3a,0x3e,0x3f
$efff00: src0 src1 src2 dst0 dst1 dst2 BANK [src
$efff10: src] [dst dst] #BYT BLIT eINT 001f 0001
$efff20: 003f 003f IACK ---- ---- ---- ---- ----
$efff80: 0050 0170 0020 0100 0000 00?? 0000 GFXE
$efff80: 0050 0170 0020 0100 0000 POSI 0000 GFXE POSI: scanline for POSIRQ
$efff90: 0000 0001 0002 0003 FLIP ---- ---- ----
$efffa0: PRI PRI PRI PRI ---- PRI? POSI ---- priority (0..7) + scanline interrupt?
$efffa0: PRI PRI PRI PRI ---- PRI? --?? ---- priority (0..7)
$efffb0: CLR CLR CLR CLR 0001 CLR? BPP ---- color (0..f), bpp flag per layer
$efffc0: RZXX RZXY RZYX RZYY RZX0 RZY0 ???? ---- ROZ
*/