diff options
Diffstat (limited to 'src/mame/video/arabian.c')
-rw-r--r-- | src/mame/video/arabian.c | 394 |
1 files changed, 394 insertions, 0 deletions
diff --git a/src/mame/video/arabian.c b/src/mame/video/arabian.c new file mode 100644 index 00000000000..c0197fa672d --- /dev/null +++ b/src/mame/video/arabian.c @@ -0,0 +1,394 @@ +/*************************************************************************** + + video.c + + Functions to emulate the video hardware of the machine. + +***************************************************************************/ + +#include "driver.h" +#include "arabian.h" + + +/* Constants */ +#define BITMAP_WIDTH 256 +#define BITMAP_HEIGHT 256 + + +/* Local variables */ +static UINT8 *main_bitmap; +static UINT8 *converted_gfx; + + +/* Globals */ +UINT8 arabian_video_control; +UINT8 arabian_flip_screen; + + + +/************************************* + * + * Color PROM conversion + * + *************************************/ + +PALETTE_INIT( arabian ) +{ + int i; + + /* there are effectively 6 bits of color: 2 red, 2 green, 2 blue */ + for (i = 0; i < 64; i++) + { + palette_set_color_rgb(machine, i, + ((i >> 5) & 1) * (153*192/255) + ((i >> 4) & 1) * (102*192/255) + ((i & 0x30) ? 63 : 0), + ((i >> 3) & 1) * (156*192/255) + ((i >> 2) & 1) * (99*192/255) + ((i & 0x0c) ? 63 : 0), + ((i >> 1) & 1) * 192 + ((i >> 0) & 1) * 63); + } + + /* there are 13 color table bits */ + for (i = 0; i < (1 << 13); i++) + { + int ena = (i >> 12) & 1; + int enb = (i >> 11) & 1; + int abhf = (~i >> 10) & 1; + int aghf = (~i >> 9) & 1; + int arhf = (~i >> 8) & 1; + int az = (i >> 7) & 1; + int ar = (i >> 6) & 1; + int ag = (i >> 5) & 1; + int ab = (i >> 4) & 1; + int bz = (i >> 3) & 1; + int br = (i >> 2) & 1; + int bg = (i >> 1) & 1; + int bb = (i >> 0) & 1; + + int planea = (az | ar | ag | ab) & ena; + + /*------------------------------------------------------------------------- + red derivation: + + ROUT.1200 = !IC192.11 + = !(!(!IC117.11 | !IC118.12)) + = !IC117.11 | !IC118.12 + = !(IC99.8 ^ IC119.6) | !(!(!BLNK & IC119.11 & BR)) + = !((!ARHF & !BLNK & AR & AZ) ^ !(AR & !BLNK)) | (!BLNK & IC119.11 & BR) + = !BLNK & (!((!ARHF & AR & AZ) ^ !AR) | (IC119.11 & BR)) + = !BLNK & ((!(!ARHF & AR & AZ) ^ AR) | (BR & !(AZ | AR | AG | AB))) + + ROUT.1800 = !IC192.3 + = !(!(!IC119.6 | !IC118.12)) + = !IC119.6 | !IC118.12 + = !(!(AR & !BLNK) | !(!(!BLNK & IC119.11 & BZ))) + = (AR & !BLNK) | (!BLNK & IC119.11 & BZ) + = !BLNK & (AR | (BZ & !(AZ | AR | AG | AB))) + + RENA = IC116.6 + = !IC192.11 | !IC192.3 + = ROUT.1200 | ROUT.1800 + + red.hi = planea ? ar : bz; + red.lo = planea ? ((!arhf & az) ? 0 : ar) : br; + red.base = (red.hi | red.lo) + -------------------------------------------------------------------------*/ + + int rhi = planea ? ar : enb ? bz : 0; + int rlo = planea ? ((!arhf & az) ? 0 : ar) : enb ? br : 0; + + /*------------------------------------------------------------------------- + green derivation: + + GOUT.750 = !IC192.8 + = !(!(!IC119.8 | !IC120.8)) + = !IC119.8 | !IC120.8 + = !(!(AG & !BLNK)) | !(!(!BLNK & IC119.11 & BB)) + = (AG & !BLNK) | (!BLNK & IC119.11 & BB) + = !BLNK & (AG | (IC119.11 & BB)) + = !BLNK & (AG | (BB & !(AZ | AR | AG | AB))) + + GOUT.1200 = !IC192.6 + = !(!(!IC117.3 | !IC118.6)) + = !IC117.3 | !IC118.6 + = !(IC99.6 ^ IC119.8) | !(!(!BLNK & IC119.11 & BG)) + = !((!AGHF & !BLNK & AG & AZ) ^ !(AG & !BLNK)) | (!BLNK & IC119.11 & BG) + = !BLNK & (!((!AGHF & AG & AZ) ^ !AG) | (IC119.11 & BG)) + = !BLNK & ((!(!AGHF & AG & AZ) ^ AG) | (BG & !(AZ | AR | AG | AB))) + + GENA = IC116.8 + = !IC192.8 | !IC192.6 + = GOUT.750 | GOUT.1200 + + grn.hi = planea ? ag : bb; + grn.lo = planea ? ((!aghf & az) ? 0 : ag) : bg; + grn.base = (grn.hi | grn.lo) + -------------------------------------------------------------------------*/ + + int ghi = planea ? ag : enb ? bb : 0; + int glo = planea ? ((!aghf & az) ? 0 : ag) : enb ? bg : 0; + + /*------------------------------------------------------------------------- + blue derivation: + + BOUT.1200 = !IC117.6 + = !IC119.3 + = !(!(AB & !BLNK)) + = !BLNK & AB + + BENA = !IC117.8 + = !(IC189.6 ^ IC119.3) + = !((!ABHF & !BLNK & AB & AZ) ^ !(AB & !BLNK)) + = (!(!ABHF & !BLNK & AB & AZ) ^ (AB & !BLNK)) + = !BLNK & (!(!ABHF & AB & AZ) ^ AB) + + blu.hi = ab; + blu.base = ((!abhf & az) ? 0 : ab); + -------------------------------------------------------------------------*/ + + int bhi = ab; + int bbase = (!abhf & az) ? 0 : ab; + + *colortable++ = (rhi << 5) | (rlo << 4) | + (ghi << 3) | (glo << 2) | + (bhi << 1) | bbase; + } +} + + + +/************************************* + * + * Video startup + * + *************************************/ + +VIDEO_START( arabian ) +{ + UINT8 *gfxbase = memory_region(REGION_GFX1); + int offs; + + /* allocate a common bitmap to use for both planes */ + /* plane A (top plane with motion objects) is in the upper 4 bits */ + /* plane B (bottom plane with playfield) is in the lower 4 bits */ + main_bitmap = auto_malloc(BITMAP_WIDTH * BITMAP_HEIGHT); + + /* allocate memory for the converted graphics data */ + converted_gfx = auto_malloc(0x8000 * 2); + + /*-------------------------------------------------- + transform graphics data into more usable format + which is coded like this: + + byte adr+0x4000 byte adr + DCBA DCBA DCBA DCBA + + D-bits of pixel 4 + C-bits of pixel 3 + B-bits of pixel 2 + A-bits of pixel 1 + + after conversion : + + byte adr+0x4000 byte adr + DDDD CCCC BBBB AAAA + --------------------------------------------------*/ + + for (offs = 0; offs < 0x4000; offs++) + { + int v1 = gfxbase[offs + 0x0000]; + int v2 = gfxbase[offs + 0x4000]; + int p1, p2, p3, p4; + + p1 = (v1 & 0x01) | ((v1 & 0x10) >> 3) | ((v2 & 0x01) << 2) | ((v2 & 0x10) >> 1); + v1 >>= 1; + v2 >>= 1; + p2 = (v1 & 0x01) | ((v1 & 0x10) >> 3) | ((v2 & 0x01) << 2) | ((v2 & 0x10) >> 1); + v1 >>= 1; + v2 >>= 1; + p3 = (v1 & 0x01) | ((v1 & 0x10) >> 3) | ((v2 & 0x01) << 2) | ((v2 & 0x10) >> 1); + v1 >>= 1; + v2 >>= 1; + p4 = (v1 & 0x01) | ((v1 & 0x10) >> 3) | ((v2 & 0x01) << 2) | ((v2 & 0x10) >> 1); + + converted_gfx[offs * 4 + 3] = p1; + converted_gfx[offs * 4 + 2] = p2; + converted_gfx[offs * 4 + 1] = p3; + converted_gfx[offs * 4 + 0] = p4; + } +} + + + +/************************************* + * + * DMA blitter simulation + * + *************************************/ + +static void blit_area(UINT8 plane, UINT16 src, UINT8 x, UINT8 y, UINT8 sx, UINT8 sy) +{ + UINT8 *srcdata = &converted_gfx[src * 4]; + int i,j; + + /* loop over X, then Y */ + for (i = 0; i <= sx; i++, x += 4) + for (j = 0; j <= sy; j++) + { + UINT8 p1 = *srcdata++; + UINT8 p2 = *srcdata++; + UINT8 p3 = *srcdata++; + UINT8 p4 = *srcdata++; + UINT8 *base; + + /* get a pointer to the bitmap */ + base = &main_bitmap[((y + j) & 0xff) * BITMAP_WIDTH + (x & 0xff)]; + + /* bit 0 means write to upper plane (upper 4 bits of our bitmap) */ + if (plane & 0x01) + { + if (p4 != 8) base[0] = (base[0] & ~0xf0) | (p4 << 4); + if (p3 != 8) base[1] = (base[1] & ~0xf0) | (p3 << 4); + if (p2 != 8) base[2] = (base[2] & ~0xf0) | (p2 << 4); + if (p1 != 8) base[3] = (base[3] & ~0xf0) | (p1 << 4); + } + + /* bit 2 means write to lower plane (lower 4 bits of our bitmap) */ + if (plane & 0x04) + { + if (p4 != 8) base[0] = (base[0] & ~0x0f) | p4; + if (p3 != 8) base[1] = (base[1] & ~0x0f) | p3; + if (p2 != 8) base[2] = (base[2] & ~0x0f) | p2; + if (p1 != 8) base[3] = (base[3] & ~0x0f) | p1; + } + } +} + + + +/************************************* + * + * DMA blitter parameters + * + *************************************/ + +WRITE8_HANDLER( arabian_blitter_w ) +{ + /* write the data */ + offset &= 7; + spriteram[offset] = data; + + /* watch for a write to offset 6 -- that triggers the blit */ + if ((offset & 0x07) == 6) + { + /* extract the data */ + int plane = spriteram[offset - 6]; + int src = spriteram[offset - 5] | (spriteram[offset - 4] << 8); + int x = spriteram[offset - 2] << 2; + int y = spriteram[offset - 3]; + int sx = spriteram[offset - 0]; + int sy = spriteram[offset - 1]; + + /* blit it */ + blit_area(plane, src, x, y, sx, sy); + } +} + + + +/************************************* + * + * VRAM direct I/O + * + *************************************/ + +WRITE8_HANDLER( arabian_videoram_w ) +{ + UINT8 *base; + UINT8 x, y; + + /* determine X/Y and mark the area dirty */ + x = (offset >> 8) << 2; + y = offset & 0xff; + + /* get a pointer to the pixels */ + base = &main_bitmap[y * BITMAP_WIDTH + x]; + + /* the data is written as 4 2-bit values, as follows: + + bit 7 = pixel 3, upper bit + bit 6 = pixel 2, upper bit + bit 5 = pixel 1, upper bit + bit 4 = pixel 0, upper bit + bit 3 = pixel 3, lower bit + bit 2 = pixel 2, lower bit + bit 1 = pixel 1, lower bit + bit 0 = pixel 0, lower bit + */ + + /* enable writes to AZ/AR */ + if (spriteram[0] & 0x08) + { + base[0] = (base[0] & ~0x03) | ((data & 0x10) >> 3) | ((data & 0x01) >> 0); + base[1] = (base[1] & ~0x03) | ((data & 0x20) >> 4) | ((data & 0x02) >> 1); + base[2] = (base[2] & ~0x03) | ((data & 0x40) >> 5) | ((data & 0x04) >> 2); + base[3] = (base[3] & ~0x03) | ((data & 0x80) >> 6) | ((data & 0x08) >> 3); + } + + /* enable writes to AG/AB */ + if (spriteram[0] & 0x04) + { + base[0] = (base[0] & ~0x0c) | ((data & 0x10) >> 1) | ((data & 0x01) << 2); + base[1] = (base[1] & ~0x0c) | ((data & 0x20) >> 2) | ((data & 0x02) << 1); + base[2] = (base[2] & ~0x0c) | ((data & 0x40) >> 3) | ((data & 0x04) << 0); + base[3] = (base[3] & ~0x0c) | ((data & 0x80) >> 4) | ((data & 0x08) >> 1); + } + + /* enable writes to BZ/BR */ + if (spriteram[0] & 0x02) + { + base[0] = (base[0] & ~0x30) | ((data & 0x10) << 1) | ((data & 0x01) << 4); + base[1] = (base[1] & ~0x30) | ((data & 0x20) << 0) | ((data & 0x02) << 3); + base[2] = (base[2] & ~0x30) | ((data & 0x40) >> 1) | ((data & 0x04) << 2); + base[3] = (base[3] & ~0x30) | ((data & 0x80) >> 2) | ((data & 0x08) << 1); + } + + /* enable writes to BG/BB */ + if (spriteram[0] & 0x01) + { + base[0] = (base[0] & ~0xc0) | ((data & 0x10) << 3) | ((data & 0x01) << 6); + base[1] = (base[1] & ~0xc0) | ((data & 0x20) << 2) | ((data & 0x02) << 5); + base[2] = (base[2] & ~0xc0) | ((data & 0x40) << 1) | ((data & 0x04) << 4); + base[3] = (base[3] & ~0xc0) | ((data & 0x80) << 0) | ((data & 0x08) << 3); + } +} + + + +/************************************* + * + * Core video refresh + * + *************************************/ + +VIDEO_UPDATE( arabian ) +{ + const pen_t *colortable = &machine->remapped_colortable[(arabian_video_control >> 3) << 8]; + int y; + + /* render the screen from the bitmap */ + for (y = 0; y < BITMAP_HEIGHT; y++) + { + /* non-flipped case */ + if (!arabian_flip_screen) + draw_scanline8(bitmap, 0, y, BITMAP_WIDTH, &main_bitmap[y * BITMAP_WIDTH], colortable, -1); + + /* flipped case */ + else + { + UINT8 scanline[BITMAP_WIDTH]; + int x; + for (x = 0; x < BITMAP_WIDTH; x++) + scanline[BITMAP_WIDTH - 1 - x] = main_bitmap[y * BITMAP_WIDTH + x]; + draw_scanline8(bitmap, 0, BITMAP_HEIGHT - 1 - y, BITMAP_WIDTH, scanline, colortable, -1); + } + } + return 0; +} |