diff options
Diffstat (limited to 'src/mame/video/starfire.c')
-rw-r--r-- | src/mame/video/starfire.c | 276 |
1 files changed, 276 insertions, 0 deletions
diff --git a/src/mame/video/starfire.c b/src/mame/video/starfire.c new file mode 100644 index 00000000000..4341a6ff0b8 --- /dev/null +++ b/src/mame/video/starfire.c @@ -0,0 +1,276 @@ +/*************************************************************************** + + Star Fire video system + +***************************************************************************/ + +#include "driver.h" +#include "includes/starfire.h" + +/* local allocated storage */ +static UINT8 *scanline_dirty; + +static UINT8 starfire_vidctrl; +static UINT8 starfire_vidctrl1; +static UINT8 starfire_color; + + + +/************************************* + * + * Initialize the video system + * + *************************************/ + +VIDEO_START( starfire ) +{ + /* make a temporary bitmap */ + tmpbitmap = auto_bitmap_alloc(machine->screen[0].width, machine->screen[0].height, machine->screen[0].format); + + /* make a dirty array */ + scanline_dirty = auto_malloc(STARFIRE_VTOTAL); + + /* reset videoram */ + memset(starfire_videoram, 0, 0x2000); + memset(starfire_colorram, 0, 0x2000); + memset(scanline_dirty, 1, 256); +} + + + +/************************************* + * + * Video control writes + * + *************************************/ + +WRITE8_HANDLER( starfire_vidctrl_w ) +{ + starfire_vidctrl = data; +} + +WRITE8_HANDLER( starfire_vidctrl1_w ) +{ + starfire_vidctrl1 = data; +} + + + +/************************************* + * + * Color RAM read/writes + * + *************************************/ + +WRITE8_HANDLER( starfire_colorram_w ) +{ + /* handle writes to the pseudo-color RAM */ + if ((offset & 0xe0) == 0) + { + int palette_index = (offset & 0x1f) | ((offset & 0x200) >> 4); + + /* set RAM regardless */ + starfire_colorram[offset & ~0x100] = data; + starfire_colorram[offset | 0x100] = data; + + /* don't modify the palette unless the TRANS bit is set */ + starfire_color = data & 0x1f; + if (!(starfire_vidctrl1 & 0x40)) + return; + + palette_set_color_rgb(Machine, palette_index, pal3bit((data << 1) & 0x06) | ((offset >> 8) & 0x01), pal3bit(data >> 5), pal3bit(data >> 2)); + } + + /* handle writes to the rest of color RAM */ + else + { + /* set RAM based on CDRM */ + starfire_colorram[offset] = (starfire_vidctrl1 & 0x80) ? starfire_color : (data & 0x1f); + scanline_dirty[offset & 0xff] = 1; + starfire_color = data & 0x1f; + } +} + +READ8_HANDLER( starfire_colorram_r ) +{ + return starfire_colorram[offset]; +} + + + +/************************************* + * + * Video RAM read/writes + * + *************************************/ + +WRITE8_HANDLER( starfire_videoram_w ) +{ + int sh, lr, dm, ds, mask, d0, dalu; + int offset1 = offset & 0x1fff; + int offset2 = (offset + 0x100) & 0x1fff; + + /* PROT */ + if (!(offset & 0xe0) && !(starfire_vidctrl1 & 0x20)) + return; + + /* selector 6A */ + if (offset & 0x2000) + { + sh = (starfire_vidctrl >> 1) & 0x07; + lr = starfire_vidctrl & 0x01; + } + else + { + sh = (starfire_vidctrl >> 5) & 0x07; + lr = (starfire_vidctrl >> 4) & 0x01; + } + + /* mirror bits 5B/5C/5D/5E */ + dm = data; + if (lr) + dm = ((dm & 0x01) << 7) | ((dm & 0x02) << 5) | ((dm & 0x04) << 3) | ((dm & 0x08) << 1) | + ((dm & 0x10) >> 1) | ((dm & 0x20) >> 3) | ((dm & 0x40) >> 5) | ((dm & 0x80) >> 7); + + /* shifters 6D/6E */ + ds = (dm << 8) >> sh; + mask = 0xff00 >> sh; + + /* ROLL */ + if ((offset & 0x1f00) == 0x1f00) + { + if (starfire_vidctrl1 & 0x10) + mask &= 0x00ff; + else + mask &= 0xff00; + } + + /* ALU 8B/8D */ + d0 = (starfire_videoram[offset1] << 8) | starfire_videoram[offset2]; + dalu = d0 & ~mask; + d0 &= mask; + ds &= mask; + switch (~starfire_vidctrl1 & 15) + { + case 0: dalu |= ds ^ mask; break; + case 1: dalu |= (ds | d0) ^ mask; break; + case 2: dalu |= (ds ^ mask) & d0; break; + case 3: dalu |= 0; break; + case 4: dalu |= (ds & d0) ^ mask; break; + case 5: dalu |= d0 ^ mask; break; + case 6: dalu |= ds ^ d0; break; + case 7: dalu |= ds & (d0 ^ mask); break; + case 8: dalu |= (ds ^ mask) | d0; break; + case 9: dalu |= (ds ^ d0) ^ mask; break; + case 10: dalu |= d0; break; + case 11: dalu |= ds & d0; break; + case 12: dalu |= mask; break; + case 13: dalu |= ds | (d0 ^ mask); break; + case 14: dalu |= ds | d0; break; + case 15: dalu |= ds; break; + } + + /* final output */ + starfire_videoram[offset1] = dalu >> 8; + starfire_videoram[offset2] = dalu; + scanline_dirty[offset1 & 0xff] = 1; + + /* color output */ + if (!(offset & 0x2000) && !(starfire_vidctrl1 & 0x80)) + { + if (mask & 0xff00) + starfire_colorram[offset1] = starfire_color; + if (mask & 0x00ff) + starfire_colorram[offset2] = starfire_color; + } +} + +READ8_HANDLER( starfire_videoram_r ) +{ + int sh, mask, d0; + int offset1 = offset & 0x1fff; + int offset2 = (offset + 0x100) & 0x1fff; + + /* selector 6A */ + if (offset & 0x2000) + sh = (starfire_vidctrl >> 1) & 0x07; + else + sh = (starfire_vidctrl >> 5) & 0x07; + + /* shifters 6D/6E */ + mask = 0xff00 >> sh; + + /* ROLL */ + if ((offset & 0x1f00) == 0x1f00) + { + if (starfire_vidctrl1 & 0x10) + mask &= 0x00ff; + else + mask &= 0xff00; + } + + /* munge the results */ + d0 = (starfire_videoram[offset1] & (mask >> 8)) | (starfire_videoram[offset2] & mask); + d0 = (d0 << sh) | (d0 >> (8 - sh)); + return d0 & 0xff; +} + + + +/************************************* + * + * Periodic screen refresh callback + * + *************************************/ + +void starfire_video_update(int scanline, int count) +{ + UINT8 *pix = &starfire_videoram[scanline]; + UINT8 *col = &starfire_colorram[scanline]; + int x, y; + + /* update any dirty scanlines in this range */ + for (x = 0; x < 256; x += 8) + { + for (y = 0; y < count; y++) + if ((scanline + y) < STARFIRE_VTOTAL && scanline_dirty[scanline + y]) + { + int data = pix[y]; + int color = col[y]; + + *BITMAP_ADDR16(tmpbitmap, scanline + y, x + 0) = color | ((data >> 2) & 0x20); + *BITMAP_ADDR16(tmpbitmap, scanline + y, x + 1) = color | ((data >> 1) & 0x20); + *BITMAP_ADDR16(tmpbitmap, scanline + y, x + 2) = color | ((data >> 0) & 0x20); + *BITMAP_ADDR16(tmpbitmap, scanline + y, x + 3) = color | ((data << 1) & 0x20); + *BITMAP_ADDR16(tmpbitmap, scanline + y, x + 4) = color | ((data << 2) & 0x20); + *BITMAP_ADDR16(tmpbitmap, scanline + y, x + 5) = color | ((data << 3) & 0x20); + *BITMAP_ADDR16(tmpbitmap, scanline + y, x + 6) = color | ((data << 4) & 0x20); + *BITMAP_ADDR16(tmpbitmap, scanline + y, x + 7) = color | ((data << 5) & 0x20); + } + + pix += 256; + col += 256; + } + + /* mark them not dirty anymore */ + for (y = 0; y < count; y++) + if ((scanline + y) < STARFIRE_VTOTAL) + scanline_dirty[scanline + y] = 0; +} + + + +/************************************* + * + * Standard screen refresh callback + * + *************************************/ + +VIDEO_UPDATE( starfire ) +{ + /* copy the bitmap, remapping the colors */ + copybitmap_remap(bitmap, tmpbitmap, 0, 0, 0, 0, &machine->screen[0].visarea, TRANSPARENCY_NONE, 0); + return 0; +} + + |