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