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