summaryrefslogtreecommitdiffstatshomepage
path: root/src/mame/video/n8080.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/mame/video/n8080.c')
-rw-r--r--src/mame/video/n8080.c405
1 files changed, 405 insertions, 0 deletions
diff --git a/src/mame/video/n8080.c b/src/mame/video/n8080.c
new file mode 100644
index 00000000000..8c42fc4b518
--- /dev/null
+++ b/src/mame/video/n8080.c
@@ -0,0 +1,405 @@
+/***************************************************************************
+
+ Nintendo 8080 video emulation
+
+***************************************************************************/
+
+#include "driver.h"
+#include "includes/n8080.h"
+#include <math.h>
+
+int spacefev_red_screen;
+int spacefev_red_cannon;
+
+int helifire_flash;
+
+static emu_timer* cannon_timer;
+
+static int sheriff_color_mode;
+static int sheriff_color_data;
+
+static UINT8 helifire_LSFR[63];
+
+static unsigned helifire_mv;
+static unsigned helifire_sc; /* IC56 */
+
+
+WRITE8_HANDLER( n8080_video_control_w )
+{
+ sheriff_color_mode = (data >> 3) & 3;
+ sheriff_color_data = (data >> 0) & 7;
+
+ flip_screen = data & 0x20;
+}
+
+
+PALETTE_INIT( n8080 )
+{
+ int i;
+
+ for (i = 0; i < 8; i++)
+ palette_set_color_rgb(machine,i,pal1bit(i >> 0),pal1bit(i >> 1),pal1bit(i >> 2));
+}
+
+
+PALETTE_INIT( helifire )
+{
+ int i;
+
+ palette_init_n8080(machine, NULL, NULL);
+
+ for (i = 0; i < 0x100; i++)
+ {
+ int level = 0xff * exp(-3 * i / 255.); /* capacitor discharge */
+
+ palette_set_color(machine,0x000 + 8 + i, MAKE_RGB(0x00, 0x00, level)); /* shades of blue */
+ palette_set_color(machine,0x100 + 8 + i, MAKE_RGB(0x00, 0xC0, level)); /* shades of blue w/ green star */
+
+ palette_set_color(machine,0x200 + 8 + i, MAKE_RGB(level, 0x00, 0x00)); /* shades of red */
+ palette_set_color(machine,0x300 + 8 + i, MAKE_RGB(level, 0xC0, 0x00)); /* shades of red w/ green star */
+ }
+}
+
+
+void spacefev_start_red_cannon(void)
+{
+ spacefev_red_cannon = 1;
+
+ timer_adjust(cannon_timer, ATTOTIME_IN_USEC(550 * 68 * 10), 0, attotime_zero);
+}
+
+
+static TIMER_CALLBACK( spacefev_stop_red_cannon )
+{
+ spacefev_red_cannon = 0;
+
+ timer_adjust(cannon_timer, attotime_never, 0, attotime_never);
+}
+
+
+static void helifire_next_line(void)
+{
+ helifire_mv++;
+
+ if (helifire_sc % 4 == 2)
+ {
+ helifire_mv %= 256;
+ }
+ else
+ {
+ if (flip_screen)
+ {
+ helifire_mv %= 255;
+ }
+ else
+ {
+ helifire_mv %= 257;
+ }
+ }
+
+ if (helifire_mv == 128)
+ {
+ helifire_sc++;
+ }
+}
+
+
+VIDEO_START( spacefev )
+{
+ cannon_timer = timer_alloc(spacefev_stop_red_cannon);
+
+ flip_screen = 0;
+
+ spacefev_red_screen = 0;
+ spacefev_red_cannon = 0;
+}
+
+
+VIDEO_START( sheriff )
+{
+ flip_screen = 0;
+
+ sheriff_color_mode = 0;
+ sheriff_color_data = 0;
+}
+
+
+VIDEO_START( helifire )
+{
+ UINT8 data = 0;
+
+ int i;
+
+ helifire_mv = 0;
+ helifire_sc = 0;
+
+ for (i = 0; i < 63; i++)
+ {
+ int bit =
+ (data >> 6) ^
+ (data >> 7) ^ 1;
+
+ data = (data << 1) | (bit & 1);
+
+ helifire_LSFR[i] = data;
+ }
+
+ flip_screen = 0;
+
+ helifire_flash = 0;
+}
+
+
+VIDEO_UPDATE( spacefev )
+{
+ UINT8 mask = flip_screen ? 0xff : 0x00;
+
+ int x;
+ int y;
+
+ const UINT8* pRAM = videoram;
+
+ for (y = 0; y < 256; y++)
+ {
+ UINT16* pLine = BITMAP_ADDR16(bitmap, y ^ mask, 0);
+
+ for (x = 0; x < 256; x += 8)
+ {
+ int n;
+
+ UINT8 color = 0;
+
+ if (spacefev_red_screen)
+ {
+ color = 1;
+ }
+ else
+ {
+ UINT8 val = memory_region(REGION_PROMS)[x >> 3];
+
+ if ((x >> 3) == 0x06)
+ {
+ color = spacefev_red_cannon ? 1 : 7;
+ }
+
+ if ((x >> 3) == 0x1b)
+ {
+ static const UINT8 ufo_color[] =
+ {
+ 1, /* red */
+ 2, /* green */
+ 7, /* white */
+ 3, /* yellow */
+ 5, /* magenta */
+ 6, /* cyan */
+ };
+
+ int cycle = cpu_getcurrentframe() / 32;
+
+ color = ufo_color[cycle % 6];
+ }
+
+ for (n = color + 1; n < 8; n++)
+ {
+ if (~val & (1 << n))
+ {
+ color = n;
+ }
+ }
+ }
+
+ for (n = 0; n < 8; n++)
+ {
+ pLine[(x + n) ^ mask] = (pRAM[x >> 3] & (1 << n)) ? color : 0;
+ }
+ }
+
+ pRAM += 32;
+ }
+ return 0;
+}
+
+
+VIDEO_UPDATE( sheriff )
+{
+ UINT8 mask = flip_screen ? 0xff : 0x00;
+
+ const UINT8* pPROM = memory_region(REGION_PROMS);
+
+ int x;
+ int y;
+
+ const UINT8* pRAM = videoram;
+
+ for (y = 0; y < 256; y++)
+ {
+ UINT16* pLine = BITMAP_ADDR16(bitmap, y ^ mask, 0);
+
+ for (x = 0; x < 256; x += 8)
+ {
+ int n;
+
+ UINT8 color = pPROM[32 * (y >> 3) + (x >> 3)];
+
+ if (sheriff_color_mode == 1 && !(color & 8))
+ {
+ color = sheriff_color_data ^ 7;
+ }
+
+ if (sheriff_color_mode == 2)
+ {
+ color = sheriff_color_data ^ 7;
+ }
+
+ if (sheriff_color_mode == 3)
+ {
+ color = 7;
+ }
+
+ for (n = 0; n < 8; n++)
+ {
+ pLine[(x + n) ^ mask] = ((pRAM[x >> 3] >> n) & 1) ? (color & 7) : 0;
+ }
+ }
+
+ pRAM += 32;
+ }
+ return 0;
+}
+
+
+VIDEO_UPDATE( helifire )
+{
+ int SUN_BRIGHTNESS = readinputport(4);
+ int SEA_BRIGHTNESS = readinputport(5);
+
+ static const int wave[8] = { 0, 1, 2, 2, 2, 1, 0, 0 };
+
+ unsigned saved_mv = helifire_mv;
+ unsigned saved_sc = helifire_sc;
+
+ int x;
+ int y;
+
+ for (y = 0; y < 256; y++)
+ {
+ UINT16* pLine = BITMAP_ADDR16(bitmap, y, 0);
+
+ int level = 120 + wave[helifire_mv & 7];
+
+ /* draw sky */
+
+ for (x = level; x < 256; x++)
+ {
+ pLine[x] = 0x200 + 8 + SUN_BRIGHTNESS + x - level;
+ }
+
+ /* draw stars */
+
+ if (helifire_mv % 8 == 4) /* upper half */
+ {
+ int step = (320 * (helifire_mv - 0)) % sizeof helifire_LSFR;
+
+ int data =
+ ((helifire_LSFR[step] & 1) << 6) |
+ ((helifire_LSFR[step] & 2) << 4) |
+ ((helifire_LSFR[step] & 4) << 2) |
+ ((helifire_LSFR[step] & 8) << 0);
+
+ pLine[0x80 + data] |= 0x100;
+ }
+
+ if (helifire_mv % 8 == 5) /* lower half */
+ {
+ int step = (320 * (helifire_mv - 1)) % sizeof helifire_LSFR;
+
+ int data =
+ ((helifire_LSFR[step] & 1) << 6) |
+ ((helifire_LSFR[step] & 2) << 4) |
+ ((helifire_LSFR[step] & 4) << 2) |
+ ((helifire_LSFR[step] & 8) << 0);
+
+ pLine[0x00 + data] |= 0x100;
+ }
+
+ /* draw sea */
+
+ for (x = 0; x < level; x++)
+ {
+ pLine[x] = 8 + SEA_BRIGHTNESS + x;
+ }
+
+ /* draw foreground */
+
+ for (x = 0; x < 256; x += 8)
+ {
+ int offset = 32 * y + (x >> 3);
+
+ int n;
+
+ for (n = 0; n < 8; n++)
+ {
+ if (flip_screen)
+ {
+ if ((videoram[offset ^ 0x1fff] << n) & 0x80)
+ {
+ pLine[x + n] = colorram[offset ^ 0x1fff] & 7;
+ }
+ }
+ else
+ {
+ if ((videoram[offset] >> n) & 1)
+ {
+ pLine[x + n] = colorram[offset] & 7;
+ }
+ }
+ }
+ }
+
+ /* next line */
+
+ helifire_next_line();
+ }
+
+ helifire_mv = saved_mv;
+ helifire_sc = saved_sc;
+ return 0;
+}
+
+
+VIDEO_EOF( helifire )
+{
+ int n = (cpu_getcurrentframe() >> 1) % sizeof helifire_LSFR;
+
+ int i;
+
+ for (i = 0; i < 8; i++)
+ {
+ int R = (i & 1);
+ int G = (i & 2);
+ int B = (i & 4);
+
+ if (helifire_flash)
+ {
+ if (helifire_LSFR[n] & 0x20)
+ {
+ G |= B;
+ }
+
+ if (cpu_getcurrentframe() & 0x04)
+ {
+ R |= G;
+ }
+ }
+
+ palette_set_color_rgb(machine,i,
+ R ? 255 : 0,
+ G ? 255 : 0,
+ B ? 255 : 0);
+ }
+
+ for (i = 0; i < 256; i++)
+ {
+ helifire_next_line();
+ }
+}