diff options
Diffstat (limited to 'src/mame/video/m72.c')
-rw-r--r-- | src/mame/video/m72.c | 597 |
1 files changed, 597 insertions, 0 deletions
diff --git a/src/mame/video/m72.c b/src/mame/video/m72.c new file mode 100644 index 00000000000..a0d85fb21aa --- /dev/null +++ b/src/mame/video/m72.c @@ -0,0 +1,597 @@ +#include "driver.h" +#include "audio/m72.h" +#include "m72.h" + + + +UINT16 *m72_videoram1,*m72_videoram2,*majtitle_rowscrollram; +static UINT16 *m72_spriteram; +static INT32 splitline; +static tilemap *fg_tilemap,*bg_tilemap; +static int xadjust; +static int bgadjust; +static INT32 scrollx1,scrolly1,scrollx2,scrolly2; +static INT32 video_off; + +static int irqbase; + +MACHINE_RESET( m72 ) +{ + irqbase = 0x20; + machine_reset_m72_sound(machine); +} + +MACHINE_RESET( xmultipl ) +{ + irqbase = 0x08; + machine_reset_m72_sound(machine); +} + +MACHINE_RESET( kengo ) +{ + irqbase = 0x18; + machine_reset_m72_sound(machine); +} + +INTERRUPT_GEN( m72_interrupt ) +{ + int line = 255 - cpu_getiloops(); + + if (line == 255) /* vblank */ + { + cpunum_set_input_line_and_vector(0, 0, HOLD_LINE, irqbase+0); + } + else + { + if (line != splitline - 128) + return; + + video_screen_update_partial(0, line + 128); + + /* this is used to do a raster effect and show the score display at + the bottom of the screen or other things. The line where the + interrupt happens is programmable (and the interrupt can be triggered + multiple times, by changing the interrupt line register in the + interrupt handler). + */ + cpunum_set_input_line_and_vector(0, 0, HOLD_LINE, irqbase+2); + } +} + + + +/*************************************************************************** + + Callbacks for the TileMap code + +***************************************************************************/ + +INLINE void m72_get_tile_info(running_machine *machine,tile_data *tileinfo,int tile_index,const UINT16 *vram,int gfxnum) +{ + int code,attr,color,pri; + + tile_index *= 2; + + code = vram[tile_index] & 0xff; + attr = vram[tile_index] >> 8; + color = vram[tile_index+1] & 0xff; + + if (color & 0x80) pri = 2; + else if (color & 0x40) pri = 1; + else pri = 0; +/* color & 0x10 is used in bchopper and hharry, more priority? */ + + SET_TILE_INFO( + gfxnum, + code + ((attr & 0x3f) << 8), + color & 0x0f, + TILE_FLIPYX((attr & 0xc0) >> 6)); + tileinfo->group = pri; +} + +INLINE void rtype2_get_tile_info(running_machine *machine,tile_data *tileinfo,int tile_index,const UINT16 *vram,int gfxnum) +{ + int code,attr,color,pri; + + tile_index *= 2; + + code = vram[tile_index]; + color = vram[tile_index+1] & 0xff; + attr = vram[tile_index+1] >> 8; + + if (attr & 0x01) pri = 2; + else if (color & 0x80) pri = 1; + else pri = 0; + +/* (vram[tile_index+2] & 0x10) is used by majtitle on the green, but it's not clear for what */ +/* (vram[tile_index+3] & 0xfe) are used as well */ + + SET_TILE_INFO( + gfxnum, + code, + color & 0x0f, + TILE_FLIPYX((color & 0x60) >> 5)); + tileinfo->group = pri; +} + + +static TILE_GET_INFO( m72_get_bg_tile_info ) +{ + m72_get_tile_info(machine,tileinfo,tile_index,m72_videoram2,2); +} + +static TILE_GET_INFO( m72_get_fg_tile_info ) +{ + m72_get_tile_info(machine,tileinfo,tile_index,m72_videoram1,1); +} + +static TILE_GET_INFO( hharry_get_bg_tile_info ) +{ + m72_get_tile_info(machine,tileinfo,tile_index,m72_videoram2,1); +} + +static TILE_GET_INFO( rtype2_get_bg_tile_info ) +{ + rtype2_get_tile_info(machine,tileinfo,tile_index,m72_videoram2,1); +} + +static TILE_GET_INFO( rtype2_get_fg_tile_info ) +{ + rtype2_get_tile_info(machine,tileinfo,tile_index,m72_videoram1,1); +} + + +static TILEMAP_MAPPER( majtitle_scan_rows ) +{ + /* logical (col,row) -> memory offset */ + return row*256 + col; +} + + +/*************************************************************************** + + Start the video hardware emulation. + +***************************************************************************/ + +static void register_savestate(void) +{ + state_save_register_global(splitline); + state_save_register_global(video_off); + state_save_register_global(scrollx1); + state_save_register_global(scrolly1); + state_save_register_global(scrollx2); + state_save_register_global(scrolly2); + state_save_register_global_pointer(m72_spriteram, spriteram_size); +} + + +VIDEO_START( m72 ) +{ + bg_tilemap = tilemap_create(m72_get_bg_tile_info,tilemap_scan_rows,TILEMAP_TYPE_PEN,8,8,64,64); + fg_tilemap = tilemap_create(m72_get_fg_tile_info,tilemap_scan_rows,TILEMAP_TYPE_PEN,8,8,64,64); + + m72_spriteram = auto_malloc(spriteram_size); + + tilemap_set_transmask(fg_tilemap,0,0xffff,0x0001); + tilemap_set_transmask(fg_tilemap,1,0x00ff,0xff01); + tilemap_set_transmask(fg_tilemap,2,0x0001,0xffff); + + tilemap_set_transmask(bg_tilemap,0,0xffff,0x0000); + tilemap_set_transmask(bg_tilemap,1,0x00ff,0xff00); + tilemap_set_transmask(bg_tilemap,2,0x0001,0xfffe); + + memset(m72_spriteram,0,spriteram_size); + + xadjust = 0; + bgadjust = 0; + + register_savestate(); +} + +VIDEO_START( rtype2 ) +{ + bg_tilemap = tilemap_create(rtype2_get_bg_tile_info,tilemap_scan_rows,TILEMAP_TYPE_PEN,8,8,64,64); + fg_tilemap = tilemap_create(rtype2_get_fg_tile_info,tilemap_scan_rows,TILEMAP_TYPE_PEN,8,8,64,64); + + m72_spriteram = auto_malloc(spriteram_size); + + tilemap_set_transmask(fg_tilemap,0,0xffff,0x0001); + tilemap_set_transmask(fg_tilemap,1,0x00ff,0xff01); + tilemap_set_transmask(fg_tilemap,2,0x0001,0xffff); + + tilemap_set_transmask(bg_tilemap,0,0xffff,0x0000); + tilemap_set_transmask(bg_tilemap,1,0x00ff,0xff00); + tilemap_set_transmask(bg_tilemap,2,0x0001,0xfffe); + + memset(m72_spriteram,0,spriteram_size); + + xadjust = -4; + bgadjust = 0; + + register_savestate(); +} + +VIDEO_START( poundfor ) +{ + video_start_rtype2(machine); + + xadjust = -6; +} + + +/* Major Title has a larger background RAM, and rowscroll */ +VIDEO_START( majtitle ) +{ +// The tilemap can be 256x64, but seems to be used at 128x64 (scroll wraparound). +// The layout ramains 256x64, the right half is just not displayed. +// bg_tilemap = tilemap_create(rtype2_get_bg_tile_info,tilemap_scan_rows,TILEMAP_TYPE_PEN,8,8,256,64); + bg_tilemap = tilemap_create(rtype2_get_bg_tile_info,majtitle_scan_rows,TILEMAP_TYPE_PEN,8,8,128,64); + fg_tilemap = tilemap_create(rtype2_get_fg_tile_info,tilemap_scan_rows,TILEMAP_TYPE_PEN,8,8,64,64); + + m72_spriteram = auto_malloc(spriteram_size); + + tilemap_set_transmask(fg_tilemap,0,0xffff,0x0001); + tilemap_set_transmask(fg_tilemap,1,0x00ff,0xff01); + tilemap_set_transmask(fg_tilemap,2,0x0001,0xffff); + + tilemap_set_transmask(bg_tilemap,0,0xffff,0x0000); + tilemap_set_transmask(bg_tilemap,1,0x00ff,0xff00); + tilemap_set_transmask(bg_tilemap,2,0x0001,0xfffe); + + memset(m72_spriteram,0,spriteram_size); + + xadjust = -4; + bgadjust = 0; + + register_savestate(); +} + +VIDEO_START( hharry ) +{ + bg_tilemap = tilemap_create(hharry_get_bg_tile_info,tilemap_scan_rows,TILEMAP_TYPE_PEN,8,8,64,64); + fg_tilemap = tilemap_create(m72_get_fg_tile_info, tilemap_scan_rows,TILEMAP_TYPE_PEN,8,8,64,64); + + m72_spriteram = auto_malloc(spriteram_size); + + tilemap_set_transmask(fg_tilemap,0,0xffff,0x0001); + tilemap_set_transmask(fg_tilemap,1,0x00ff,0xff01); + tilemap_set_transmask(fg_tilemap,2,0x0001,0xffff); + + tilemap_set_transmask(bg_tilemap,0,0xffff,0x0000); + tilemap_set_transmask(bg_tilemap,1,0x00ff,0xff00); + tilemap_set_transmask(bg_tilemap,2,0x0001,0xfffe); + + memset(m72_spriteram,0,spriteram_size); + + xadjust = -4; + bgadjust = -2; + + register_savestate(); +} + + +/*************************************************************************** + + Memory handlers + +***************************************************************************/ + +READ16_HANDLER( m72_palette1_r ) +{ + /* A9 isn't connected, so 0x200-0x3ff mirrors 0x000-0x1ff etc. */ + offset &= ~0x100; + + return paletteram16[offset] | 0xffe0; /* only D0-D4 are connected */ +} + +READ16_HANDLER( m72_palette2_r ) +{ + /* A9 isn't connected, so 0x200-0x3ff mirrors 0x000-0x1ff etc. */ + offset &= ~0x100; + + return paletteram16_2[offset] | 0xffe0; /* only D0-D4 are connected */ +} + +INLINE void changecolor(int color,int r,int g,int b) +{ + palette_set_color_rgb(Machine,color,pal5bit(r),pal5bit(g),pal5bit(b)); +} + +WRITE16_HANDLER( m72_palette1_w ) +{ + /* A9 isn't connected, so 0x200-0x3ff mirrors 0x000-0x1ff etc. */ + offset &= ~0x100; + + COMBINE_DATA(&paletteram16[offset]); + offset &= 0x0ff; + changecolor(offset, + paletteram16[offset + 0x000], + paletteram16[offset + 0x200], + paletteram16[offset + 0x400]); +} + +WRITE16_HANDLER( m72_palette2_w ) +{ + /* A9 isn't connected, so 0x200-0x3ff mirrors 0x000-0x1ff etc. */ + offset &= ~0x100; + + COMBINE_DATA(&paletteram16_2[offset]); + offset &= 0x0ff; + changecolor(offset + 256, + paletteram16_2[offset + 0x000], + paletteram16_2[offset + 0x200], + paletteram16_2[offset + 0x400]); +} + +WRITE16_HANDLER( m72_videoram1_w ) +{ + COMBINE_DATA(&m72_videoram1[offset]); + tilemap_mark_tile_dirty(fg_tilemap,offset/2); +} + +WRITE16_HANDLER( m72_videoram2_w ) +{ + COMBINE_DATA(&m72_videoram2[offset]); + tilemap_mark_tile_dirty(bg_tilemap,offset/2); +} + +WRITE16_HANDLER( m72_irq_line_w ) +{ + COMBINE_DATA(&splitline); +} + +WRITE16_HANDLER( m72_scrollx1_w ) +{ + COMBINE_DATA(&scrollx1); +} + +WRITE16_HANDLER( m72_scrollx2_w ) +{ + COMBINE_DATA(&scrollx2); +} + +WRITE16_HANDLER( m72_scrolly1_w ) +{ + COMBINE_DATA(&scrolly1); +} + +WRITE16_HANDLER( m72_scrolly2_w ) +{ + COMBINE_DATA(&scrolly2); +} + +WRITE16_HANDLER( m72_dmaon_w ) +{ + if (ACCESSING_LSB) + memcpy(m72_spriteram,spriteram16,spriteram_size); +} + + +WRITE16_HANDLER( m72_port02_w ) +{ + if (ACCESSING_LSB) + { + if (data & 0xe0) logerror("write %02x to port 02\n",data); + + /* bits 0/1 are coin counters */ + coin_counter_w(0,data & 0x01); + coin_counter_w(1,data & 0x02); + + /* bit 2 is flip screen (handled both by software and hardware) */ + flip_screen_set(((data & 0x04) >> 2) ^ ((~readinputport(2) >> 8) & 1)); + + /* bit 3 is display disable */ + video_off = data & 0x08; + + /* bit 4 resets sound CPU (active low) */ + if (data & 0x10) + cpunum_set_input_line(1, INPUT_LINE_RESET, CLEAR_LINE); + else + cpunum_set_input_line(1, INPUT_LINE_RESET, ASSERT_LINE); + + /* bit 5 = "bank"? */ + } +} + +WRITE16_HANDLER( rtype2_port02_w ) +{ + if (ACCESSING_LSB) + { + if (data & 0xe0) logerror("write %02x to port 02\n",data); + + /* bits 0/1 are coin counters */ + coin_counter_w(0,data & 0x01); + coin_counter_w(1,data & 0x02); + + /* bit 2 is flip screen (handled both by software and hardware) */ + flip_screen_set(((data & 0x04) >> 2) ^ ((~readinputport(2) >> 8) & 1)); + + /* bit 3 is display disable */ + video_off = data & 0x08; + + /* other bits unknown */ + } +} + + +static int majtitle_rowscroll; + +/* the following is mostly a kludge. This register seems to be used for something else */ +WRITE16_HANDLER( majtitle_gfx_ctrl_w ) +{ + if (ACCESSING_MSB) + { + if (data & 0xff00) majtitle_rowscroll = 1; + else majtitle_rowscroll = 0; + } +} + + +/*************************************************************************** + + Display refresh + +***************************************************************************/ + +static void m72_draw_sprites(running_machine *machine, mame_bitmap *bitmap,const rectangle *cliprect) +{ + int offs; + + offs = 0; + while (offs < spriteram_size/2) + { + int code,color,sx,sy,flipx,flipy,w,h,x,y; + + + code = m72_spriteram[offs+1]; + color = m72_spriteram[offs+2] & 0x0f; + sx = -256+(m72_spriteram[offs+3] & 0x3ff); + sy = 512-(m72_spriteram[offs+0] & 0x1ff); + flipx = m72_spriteram[offs+2] & 0x0800; + flipy = m72_spriteram[offs+2] & 0x0400; + + w = 1 << ((m72_spriteram[offs+2] & 0xc000) >> 14); + h = 1 << ((m72_spriteram[offs+2] & 0x3000) >> 12); + sy -= 16 * h; + + if (flip_screen) + { + sx = 512 - 16*w - sx; + sy = 512 - 16*h - sy; + flipx = !flipx; + flipy = !flipy; + } + + for (x = 0;x < w;x++) + { + for (y = 0;y < h;y++) + { + int c = code; + + if (flipx) c += 8*(w-1-x); + else c += 8*x; + if (flipy) c += h-1-y; + else c += y; + + drawgfx(bitmap,machine->gfx[0], + c, + color, + flipx,flipy, + sx + 16*x,sy + 16*y, + cliprect,TRANSPARENCY_PEN,0); + } + } + + offs += w*4; + } +} + +static void majtitle_draw_sprites(running_machine *machine, mame_bitmap *bitmap,const rectangle *cliprect) +{ + int offs; + + for (offs = 0;offs < spriteram_size;offs += 4) + { + int code,color,sx,sy,flipx,flipy,w,h,x,y; + + + code = spriteram16_2[offs+1]; + color = spriteram16_2[offs+2] & 0x0f; + sx = -256+(spriteram16_2[offs+3] & 0x3ff); + sy = 512-(spriteram16_2[offs+0] & 0x1ff); + flipx = spriteram16_2[offs+2] & 0x0800; + flipy = spriteram16_2[offs+2] & 0x0400; + + w = 1;// << ((spriteram16_2[offs+2] & 0xc000) >> 14); + h = 1 << ((spriteram16_2[offs+2] & 0x3000) >> 12); + sy -= 16 * h; + + if (flip_screen) + { + sx = 512 - 16*w - sx; + sy = 512 - 16*h - sy; + flipx = !flipx; + flipy = !flipy; + } + + for (x = 0;x < w;x++) + { + for (y = 0;y < h;y++) + { + int c = code; + + if (flipx) c += 8*(w-1-x); + else c += 8*x; + if (flipy) c += h-1-y; + else c += y; + + drawgfx(bitmap,machine->gfx[2], + c, + color, + flipx,flipy, + sx + 16*x,sy + 16*y, + cliprect,TRANSPARENCY_PEN,0); + } + } + } +} + +VIDEO_UPDATE( m72 ) +{ + if (video_off) + { + fillbitmap(bitmap,get_black_pen(machine),cliprect); + return 0; + } + + tilemap_set_scrollx(fg_tilemap,0,scrollx1 + xadjust); + tilemap_set_scrolly(fg_tilemap,0,scrolly1); + + tilemap_set_scrollx(bg_tilemap,0,scrollx2 + xadjust + bgadjust); + tilemap_set_scrolly(bg_tilemap,0,scrolly2); + + tilemap_draw(bitmap,cliprect,bg_tilemap,TILEMAP_DRAW_LAYER1,0); + tilemap_draw(bitmap,cliprect,fg_tilemap,TILEMAP_DRAW_LAYER1,0); + m72_draw_sprites(machine, bitmap,cliprect); + tilemap_draw(bitmap,cliprect,bg_tilemap,TILEMAP_DRAW_LAYER0,0); + tilemap_draw(bitmap,cliprect,fg_tilemap,TILEMAP_DRAW_LAYER0,0); + return 0; +} + +VIDEO_UPDATE( majtitle ) +{ + int i; + + + if (video_off) + { + fillbitmap(bitmap,get_black_pen(machine),cliprect); + return 0; + } + + tilemap_set_scrollx(fg_tilemap,0,scrollx1 + xadjust); + tilemap_set_scrolly(fg_tilemap,0,scrolly1); + + if (majtitle_rowscroll) + { + tilemap_set_scroll_rows(bg_tilemap,512); + for (i = 0;i < 512;i++) + tilemap_set_scrollx(bg_tilemap,(i+scrolly2)&0x1ff, + 256 + majtitle_rowscrollram[i] + xadjust); + } + else + { + tilemap_set_scroll_rows(bg_tilemap,1); + tilemap_set_scrollx(bg_tilemap,0,256 + scrollx2 + xadjust); + } + tilemap_set_scrolly(bg_tilemap,0,scrolly2); + + tilemap_draw(bitmap,cliprect,bg_tilemap,TILEMAP_DRAW_LAYER1,0); + tilemap_draw(bitmap,cliprect,fg_tilemap,TILEMAP_DRAW_LAYER1,0); + majtitle_draw_sprites(machine, bitmap,cliprect); + m72_draw_sprites(machine, bitmap,cliprect); + tilemap_draw(bitmap,cliprect,bg_tilemap,TILEMAP_DRAW_LAYER0,0); + tilemap_draw(bitmap,cliprect,fg_tilemap,TILEMAP_DRAW_LAYER0,0); + return 0; +} |