diff options
Diffstat (limited to 'src/mame/video/deniam.c')
-rw-r--r-- | src/mame/video/deniam.c | 401 |
1 files changed, 401 insertions, 0 deletions
diff --git a/src/mame/video/deniam.c b/src/mame/video/deniam.c new file mode 100644 index 00000000000..28225ed5212 --- /dev/null +++ b/src/mame/video/deniam.c @@ -0,0 +1,401 @@ +#include "driver.h" + + +UINT16 *deniam_videoram,*deniam_textram; +static int display_enable; +static int bg_scrollx_offs,bg_scrolly_offs,fg_scrollx_offs,fg_scrolly_offs; +static int bg_scrollx_reg,bg_scrolly_reg,bg_page_reg; +static int fg_scrollx_reg,fg_scrolly_reg,fg_page_reg; +static int bg_page[4],fg_page[4]; + +static tilemap *bg_tilemap,*fg_tilemap,*tx_tilemap; + + + +DRIVER_INIT( logicpro ) +{ + bg_scrollx_reg = 0x00a4/2; + bg_scrolly_reg = 0x00a8/2; + bg_page_reg = 0x00ac/2; + fg_scrollx_reg = 0x00a2/2; + fg_scrolly_reg = 0x00a6/2; + fg_page_reg = 0x00aa/2; + + bg_scrollx_offs = 0x00d; + bg_scrolly_offs = 0x000; + fg_scrollx_offs = 0x009; + fg_scrolly_offs = 0x000; +} +DRIVER_INIT( karianx ) +{ + bg_scrollx_reg = 0x00a4/2; + bg_scrolly_reg = 0x00a8/2; + bg_page_reg = 0x00ac/2; + fg_scrollx_reg = 0x00a2/2; + fg_scrolly_reg = 0x00a6/2; + fg_page_reg = 0x00aa/2; + + bg_scrollx_offs = 0x10d; + bg_scrolly_offs = 0x080; + fg_scrollx_offs = 0x109; + fg_scrolly_offs = 0x080; +} + + + +/*************************************************************************** + + Callbacks for the TileMap code + +***************************************************************************/ + +static TILEMAP_MAPPER( scan_pages ) +{ + /* logical (col,row) -> memory offset */ + return (col & 0x3f) + ((row & 0x1f) << 6) + ((col & 0x40) << 5) + ((row & 0x20) << 7); +} + +static TILE_GET_INFO( get_bg_tile_info ) +{ + int page = tile_index >> 11; + UINT16 attr = deniam_videoram[bg_page[page] * 0x0800 + (tile_index & 0x7ff)]; + SET_TILE_INFO( + 0, + attr, + (attr & 0x1fc0) >> 6, + 0); +} + +static TILE_GET_INFO( get_fg_tile_info ) +{ + int page = tile_index >> 11; + UINT16 attr = deniam_videoram[fg_page[page] * 0x0800 + (tile_index & 0x7ff)]; + SET_TILE_INFO( + 0, + attr, + (attr & 0x1fc0) >> 6, + 0); +} + +static TILE_GET_INFO( get_tx_tile_info ) +{ + UINT16 attr = deniam_textram[tile_index]; + SET_TILE_INFO( + 0, + attr & 0xf1ff, + (attr & 0x0e00) >> 9, + 0); +} + + + +/*************************************************************************** + + Start the video hardware emulation. + +***************************************************************************/ + +VIDEO_START( deniam ) +{ + bg_tilemap = tilemap_create(get_bg_tile_info,scan_pages, TILEMAP_TYPE_PEN, 8,8,128,64); + fg_tilemap = tilemap_create(get_fg_tile_info,scan_pages, TILEMAP_TYPE_PEN,8,8,128,64); + tx_tilemap = tilemap_create(get_tx_tile_info,tilemap_scan_rows,TILEMAP_TYPE_PEN,8,8, 64,32); + + tilemap_set_transparent_pen(fg_tilemap,0); + tilemap_set_transparent_pen(tx_tilemap,0); +} + + + +/*************************************************************************** + + Memory handlers + +***************************************************************************/ + +WRITE16_HANDLER( deniam_videoram_w ) +{ + int page,i; + COMBINE_DATA(&deniam_videoram[offset]); + + page = offset >> 11; + for (i = 0;i < 4;i++) + { + if (bg_page[i] == page) + tilemap_mark_tile_dirty(bg_tilemap,i * 0x800 + (offset & 0x7ff)); + if (fg_page[i] == page) + tilemap_mark_tile_dirty(fg_tilemap,i * 0x800 + (offset & 0x7ff)); + } +} + + +WRITE16_HANDLER( deniam_textram_w ) +{ + COMBINE_DATA(&deniam_textram[offset]); + tilemap_mark_tile_dirty(tx_tilemap,offset); +} + + +WRITE16_HANDLER( deniam_palette_w ) +{ + int r,g,b; + + data = COMBINE_DATA(&paletteram16[offset]); + + r = ((data << 1) & 0x1e) | ((data >> 12) & 0x01); + g = ((data >> 3) & 0x1e) | ((data >> 13) & 0x01); + b = ((data >> 7) & 0x1e) | ((data >> 14) & 0x01); + palette_set_color_rgb(Machine,offset,pal5bit(r),pal5bit(g),pal5bit(b)); +} + + +static UINT16 coinctrl; + +READ16_HANDLER( deniam_coinctrl_r ) +{ + return coinctrl; +} + +WRITE16_HANDLER( deniam_coinctrl_w ) +{ + COMBINE_DATA(&coinctrl); + + /* bit 0 is coin counter */ + coin_counter_w(0,coinctrl & 0x01); + + /* bit 6 is display enable (0 freezes screen) */ + display_enable = coinctrl & 0x20; + + /* other bits unknown (unused?) */ +} + + + +/*************************************************************************** + + Display refresh + +***************************************************************************/ + +/* + * Sprite Format + * ------------------ + * + * Word | Bit(s) | Use + * -----+-fedcba9876543210-+---------------- + * 0 | --------xxxxxxxx | display y start + * 0 | xxxxxxxx-------- | display y end + * 2 | -------xxxxxxxxx | x position + * 2 | ------x--------- | unknown (used in logicpr2, maybe just a bug?) + * 2 | xxxxxx---------- | unused? + * 4 | ---------xxxxxxx | width + * 4 | --------x------- | is this flip y like in System 16? + * 4 | -------x-------- | flip x + * 4 | xxxxxxx--------- | unused? + * 6 | xxxxxxxxxxxxxxxx | ROM address low bits + * 8 | ----------xxxxxx | color + * 8 | --------xx------ | priority + * 8 | ---xxxxx-------- | ROM address high bits + * 8 | xxx------------- | unused? (extra address bits for larger ROMs?) + * a | ---------------- | zoomx like in System 16? + * c | ---------------- | zoomy like in System 16? + * e | ---------------- | + */ +static void draw_sprites(running_machine* machine, mame_bitmap *bitmap, const rectangle *cliprect) +{ + int offs; + + for (offs = spriteram_size/2-8;offs >= 0;offs -= 8) + { + int sx,starty,endy,x,y,start,color,width,flipx,primask; + UINT8 *rom = memory_region(REGION_GFX2); + + + sx = (spriteram16[offs+1] & 0x01ff) + 16*8 - 1; + if (sx >= 512) sx -= 512; + starty = spriteram16[offs+0] & 0xff; + endy = spriteram16[offs+0] >> 8; + + width = spriteram16[offs+2] & 0x007f; + flipx = spriteram16[offs+2] & 0x0100; + if (flipx) sx++; + + color = 0x40 + (spriteram16[offs+4] & 0x3f); + + primask = 8; + switch (spriteram16[offs+4] & 0xc0) + { + case 0x00: primask |= 4|2|1; break; /* below everything */ + case 0x40: primask |= 4|2; break; /* below fg and tx */ + case 0x80: primask |= 4; break; /* below tx */ + case 0xc0: break; /* above everything */ + } + + + start = spriteram16[offs+3] + ((spriteram16[offs+4] & 0x1f00) << 8); + rom += 2*start; + + for (y = starty+1;y <= endy;y++) + { + int drawing = 0; + int i=0; + + rom += 2*width; /* note that the first line is skipped */ + x = 0; + while (i < 512) /* safety check */ + { + if (flipx) + { + if ((rom[i] & 0x0f) == 0x0f) + { + if (!drawing) drawing = 1; + else break; + } + else + { + if (rom[i] & 0x0f) + { + if (sx+x >= cliprect->min_x && sx+x <= cliprect->max_x && + y >= cliprect->min_y && y <= cliprect->max_y) + { + if ((*BITMAP_ADDR8(priority_bitmap, y, sx+x) & primask) == 0) + *BITMAP_ADDR16(bitmap, y, sx+x) = machine->pens[color*16+(rom[i]&0x0f)]; + *BITMAP_ADDR8(priority_bitmap, y, sx+x) = 8; + } + } + x++; + } + + if ((rom[i] & 0xf0) == 0xf0) + { + if (!drawing) drawing = 1; + else break; + } + else + { + if (rom[i] & 0xf0) + { + if (sx+x >= cliprect->min_x && sx+x <= cliprect->max_x && + y >= cliprect->min_y && y <= cliprect->max_y) + { + if ((*BITMAP_ADDR8(priority_bitmap, y, sx+x) & primask) == 0) + *BITMAP_ADDR16(bitmap, y, sx+x) = machine->pens[color*16+(rom[i]>>4)]; + *BITMAP_ADDR8(priority_bitmap, y, sx+x) = 8; + } + } + x++; + } + + i--; + } + else + { + if ((rom[i] & 0xf0) == 0xf0) + { + if (!drawing) drawing = 1; + else break; + } + else + { + if (rom[i] & 0xf0) + { + if (sx+x >= cliprect->min_x && sx+x <= cliprect->max_x && + y >= cliprect->min_y && y <= cliprect->max_y) + { + if ((*BITMAP_ADDR8(priority_bitmap, y, sx+x) & primask) == 0) + *BITMAP_ADDR16(bitmap, y, sx+x) = machine->pens[color*16+(rom[i]>>4)]; + *BITMAP_ADDR8(priority_bitmap, y, sx+x) = 8; + } + } + x++; + } + + if ((rom[i] & 0x0f) == 0x0f) + { + if (!drawing) drawing = 1; + else break; + } + else + { + if (rom[i] & 0x0f) + { + if (sx+x >= cliprect->min_x && sx+x <= cliprect->max_x && + y >= cliprect->min_y && y <= cliprect->max_y) + { + if ((*BITMAP_ADDR8(priority_bitmap, y, sx+x) & primask) == 0) + *BITMAP_ADDR16(bitmap, y, sx+x) = machine->pens[color*16+(rom[i]&0x0f)]; + *BITMAP_ADDR8(priority_bitmap, y, sx+x) = 8; + } + } + x++; + } + + i++; + } + } + } + } +} + +static void set_bg_page(int page,int value) +{ + int tile_index; + + if (bg_page[page] != value) + { + bg_page[page] = value; + for (tile_index = page * 0x800;tile_index < (page+1)*0x800;tile_index++) + tilemap_mark_tile_dirty(bg_tilemap,tile_index); + } +} + +static void set_fg_page(int page,int value) +{ + int tile_index; + + if (fg_page[page] != value) + { + fg_page[page] = value; + for (tile_index = page * 0x800;tile_index < (page+1)*0x800;tile_index++) + tilemap_mark_tile_dirty(fg_tilemap,tile_index); + } +} + +VIDEO_UPDATE( deniam ) +{ + int bg_scrollx,bg_scrolly,fg_scrollx,fg_scrolly; + int page; + + + if (!display_enable) return 0; /* don't update (freeze display) */ + + bg_scrollx = deniam_textram[bg_scrollx_reg] - bg_scrollx_offs; + bg_scrolly = (deniam_textram[bg_scrolly_reg] & 0xff) - bg_scrolly_offs; + page = deniam_textram[bg_page_reg]; + set_bg_page(3,(page >>12) & 0x0f); + set_bg_page(2,(page >> 8) & 0x0f); + set_bg_page(1,(page >> 4) & 0x0f); + set_bg_page(0,(page >> 0) & 0x0f); + + fg_scrollx = deniam_textram[fg_scrollx_reg] - fg_scrollx_offs; + fg_scrolly = (deniam_textram[fg_scrolly_reg] & 0xff) - fg_scrolly_offs; + page = deniam_textram[fg_page_reg]; + set_fg_page(3,(page >>12) & 0x0f); + set_fg_page(2,(page >> 8) & 0x0f); + set_fg_page(1,(page >> 4) & 0x0f); + set_fg_page(0,(page >> 0) & 0x0f); + + tilemap_set_scrollx(bg_tilemap,0,bg_scrollx & 0x1ff); + tilemap_set_scrolly(bg_tilemap,0,bg_scrolly & 0x0ff); + tilemap_set_scrollx(fg_tilemap,0,fg_scrollx & 0x1ff); + tilemap_set_scrolly(fg_tilemap,0,fg_scrolly & 0x0ff); + + fillbitmap(priority_bitmap,0,cliprect); + + tilemap_draw(bitmap,cliprect,bg_tilemap,0,1); + tilemap_draw(bitmap,cliprect,fg_tilemap,0,2); + tilemap_draw(bitmap,cliprect,tx_tilemap,0,4); + + draw_sprites(machine,bitmap,cliprect); + return 0; +} |