#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;
}