Simplified Y-unit DMA rendering.

Fixes term20103u4gre and term20104u2gre
This commit is contained in:
Aaron Giles 2008-01-08 10:29:22 +00:00
parent ecfd14305e
commit 1b378f7136

View file

@ -277,139 +277,107 @@ WRITE16_HANDLER( midyunit_paletteram_w )
* *
*************************************/ *************************************/
/*** constant definitions ***/ static void dma_draw(UINT16 command)
#define PIXEL_SKIP 0
#define PIXEL_COLOR 1
#define PIXEL_COPY 2
#define XFLIP_NO 0
#define XFLIP_YES 1
typedef void (*dma_draw_func)(void);
/*** core blitter routine macro ***/
#define DMA_DRAW_FUNC_BODY(name, xflip, zero, nonzero) \
{ \
int height = dma_state.height; \
int width = dma_state.width; \
UINT8 *base = midyunit_gfx_rom; \
UINT32 offset = dma_state.offset >> 3; \
UINT16 pal = dma_state.palette; \
UINT16 color = pal | dma_state.color; \
int x, y; \
\
/* loop over the height */ \
for (y = 0; y < height; y++) \
{ \
int tx = dma_state.xpos; \
int ty = dma_state.ypos; \
UINT32 o = offset; \
UINT16 *dest; \
\
/* determine Y position */ \
ty = (ty + y) & 0x1ff; \
offset += dma_state.rowbytes; \
\
/* check for over/underrun */ \
if (o >= 0x06000000) \
continue; \
\
/* determine destination pointer */ \
dest = &local_videoram[ty * 512]; \
\
/* loop until we draw the entire width */ \
for (x = 0; x < width; x++, o++) \
{ \
/* special case similar handling of zero/non-zero */ \
if (zero == nonzero) \
{ \
if (zero == PIXEL_COLOR) \
dest[tx] = color; \
else if (zero == PIXEL_COPY) \
dest[tx] = base[o] | pal; \
} \
\
/* otherwise, read the pixel and look */ \
else \
{ \
int pixel = base[o]; \
\
/* non-zero pixel case */ \
if (pixel) \
{ \
if (nonzero == PIXEL_COLOR) \
dest[tx] = color; \
else if (nonzero == PIXEL_COPY) \
dest[tx] = pixel | pal; \
} \
\
/* zero pixel case */ \
else \
{ \
if (zero == PIXEL_COLOR) \
dest[tx] = color; \
else if (zero == PIXEL_COPY) \
dest[tx] = pal; \
} \
} \
\
/* update pointers */ \
if (xflip) tx--; \
else tx++; \
} \
} \
}
/*** slightly simplified one for most blitters ***/
#define DMA_DRAW_FUNC(name, xflip, zero, nonzero) \
static void name(void) \
{ \
DMA_DRAW_FUNC_BODY(name, xflip, zero, nonzero) \
}
/*** empty blitter ***/
static void dma_draw_none(void)
{ {
int dx = (command & 0x10) ? -1 : 1;
int height = dma_state.height;
int width = dma_state.width;
UINT8 *base = midyunit_gfx_rom;
UINT32 offset = dma_state.offset >> 3;
UINT16 pal = dma_state.palette;
UINT16 color = pal | dma_state.color;
int x, y;
/* we only need the low 4 bits of the command */
command &= 0x0f;
/* loop over the height */
for (y = 0; y < height; y++)
{
int tx = dma_state.xpos;
int ty = dma_state.ypos;
UINT32 o = offset;
UINT16 *dest;
/* determine Y position */
ty = (ty + y) & 0x1ff;
offset += dma_state.rowbytes;
/* determine destination pointer */
dest = &local_videoram[ty * 512];
/* check for overruns if they are relevant */
if (o >= 0x06000000 && command < 0x0c)
continue;
/* switch off the zero/non-zero options */
switch (command)
{
case 0x00: /* draw nothing */
break;
case 0x01: /* draw only 0 pixels */
for (x = 0; x < width; x++, tx += dx)
if (base[o++] == 0)
dest[tx] = pal;
break;
case 0x02: /* draw only non-0 pixels */
for (x = 0; x < width; x++, tx += dx)
{
int pixel = base[o++];
if (pixel != 0)
dest[tx] = pal | pixel;
} }
break;
/*** super macro for declaring an entire blitter family ***/ case 0x03: /* draw all pixels */
#define DECLARE_BLITTER_SET(prefix) \ for (x = 0; x < width; x++, tx += dx)
DMA_DRAW_FUNC(prefix##_p0, XFLIP_NO, PIXEL_COPY, PIXEL_SKIP) \ dest[tx] = pal | base[o++];
DMA_DRAW_FUNC(prefix##_p1, XFLIP_NO, PIXEL_SKIP, PIXEL_COPY) \ break;
DMA_DRAW_FUNC(prefix##_c0, XFLIP_NO, PIXEL_COLOR, PIXEL_SKIP) \
DMA_DRAW_FUNC(prefix##_c1, XFLIP_NO, PIXEL_SKIP, PIXEL_COLOR) \
DMA_DRAW_FUNC(prefix##_p0p1, XFLIP_NO, PIXEL_COPY, PIXEL_COPY) \
DMA_DRAW_FUNC(prefix##_c0c1, XFLIP_NO, PIXEL_COLOR, PIXEL_COLOR) \
DMA_DRAW_FUNC(prefix##_c0p1, XFLIP_NO, PIXEL_COLOR, PIXEL_COPY) \
DMA_DRAW_FUNC(prefix##_p0c1, XFLIP_NO, PIXEL_COPY, PIXEL_COLOR) \
\
DMA_DRAW_FUNC(prefix##_p0_xf, XFLIP_YES, PIXEL_COPY, PIXEL_SKIP) \
DMA_DRAW_FUNC(prefix##_p1_xf, XFLIP_YES, PIXEL_SKIP, PIXEL_COPY) \
DMA_DRAW_FUNC(prefix##_c0_xf, XFLIP_YES, PIXEL_COLOR, PIXEL_SKIP) \
DMA_DRAW_FUNC(prefix##_c1_xf, XFLIP_YES, PIXEL_SKIP, PIXEL_COLOR) \
DMA_DRAW_FUNC(prefix##_p0p1_xf, XFLIP_YES, PIXEL_COPY, PIXEL_COPY) \
DMA_DRAW_FUNC(prefix##_c0c1_xf, XFLIP_YES, PIXEL_COLOR, PIXEL_COLOR) \
DMA_DRAW_FUNC(prefix##_c0p1_xf, XFLIP_YES, PIXEL_COLOR, PIXEL_COPY) \
DMA_DRAW_FUNC(prefix##_p0c1_xf, XFLIP_YES, PIXEL_COPY, PIXEL_COLOR) \
\
static const dma_draw_func prefix[32] = \
{ \
/* B0:N / B1:N B0:Y / B1:N B0:N / B1:Y B0:Y / B1:Y */ \
dma_draw_none, prefix##_p0, prefix##_p1, prefix##_p0p1, /* no color */ \
prefix##_c0, prefix##_c0, prefix##_c0p1, prefix##_c0p1, /* color 0 pixels */ \
prefix##_c1, prefix##_p0c1, prefix##_c1, prefix##_p0c1, /* color non-0 pixels */ \
prefix##_c0c1, prefix##_c0c1, prefix##_c0c1, prefix##_c0c1, /* fill */ \
\
dma_draw_none, prefix##_p0_xf, prefix##_p1_xf, prefix##_p0p1_xf, /* no color */ \
prefix##_c0_xf, prefix##_c0_xf, prefix##_c0p1_xf, prefix##_c0p1_xf, /* color 0 pixels */ \
prefix##_c1_xf, prefix##_p0c1_xf, prefix##_c1_xf, prefix##_p0c1_xf, /* color non-0 pixels */ \
prefix##_c0c1_xf, prefix##_c0c1_xf, prefix##_c0c1_xf, prefix##_c0c1_xf /* fill */ \
};
/*** blitter family declarations ***/ case 0x04: /* color only 0 pixels */
DECLARE_BLITTER_SET(dma_draw) case 0x05: /* color only 0 pixels */
for (x = 0; x < width; x++, tx += dx)
if (base[o++] == 0)
dest[tx] = color;
break;
case 0x06: /* color only 0 pixels, copy the rest */
case 0x07: /* color only 0 pixels, copy the rest */
for (x = 0; x < width; x++, tx += dx)
{
int pixel = base[o++];
dest[tx] = (pixel == 0) ? color : (pal | pixel);
}
break;
case 0x08: /* color only non-0 pixels */
case 0x0a: /* color only non-0 pixels */
for (x = 0; x < width; x++, tx += dx)
if (base[o++] != 0)
dest[tx] = color;
break;
case 0x09: /* color only non-0 pixels, copy the rest */
case 0x0b: /* color only non-0 pixels, copy the rest */
for (x = 0; x < width; x++, tx += dx)
{
int pixel = base[o++];
dest[tx] = (pixel != 0) ? color : (pal | pixel);
}
break;
case 0x0c: /* color all pixels */
case 0x0d: /* color all pixels */
case 0x0e: /* color all pixels */
case 0x0f: /* color all pixels */
for (x = 0; x < width; x++, tx += dx)
dest[tx] = color;
break;
}
}
}
@ -565,18 +533,12 @@ WRITE16_HANDLER( midyunit_dma_w )
dma_state.width = dma_state.xpos; dma_state.width = dma_state.xpos;
} }
/* special case: drawing mode C doesn't need to know about any pixel data */
/* shimpact relies on this behavior */
if ((command & 0x0f) == 0x0c)
gfxoffset = 0;
/* determine the location and draw */ /* determine the location and draw */
if (gfxoffset < 0x02000000) if (gfxoffset < 0x02000000)
gfxoffset += 0x02000000; gfxoffset += 0x02000000;
if (gfxoffset < 0x06000000)
{ {
dma_state.offset = gfxoffset - 0x02000000; dma_state.offset = gfxoffset - 0x02000000;
(*dma_draw[command & 0x1f])(); dma_draw(command);
} }
/* signal we're done */ /* signal we're done */