summaryrefslogtreecommitdiffstatshomepage
path: root/src/mame/video/m72.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/mame/video/m72.c')
-rw-r--r--src/mame/video/m72.c597
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;
+}