summaryrefslogtreecommitdiffstatshomepage
path: root/src/mame/video/midtunit.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/mame/video/midtunit.cpp')
-rw-r--r--src/mame/video/midtunit.cpp756
1 files changed, 327 insertions, 429 deletions
diff --git a/src/mame/video/midtunit.cpp b/src/mame/video/midtunit.cpp
index 6e91baff868..71112f2e32b 100644
--- a/src/mame/video/midtunit.cpp
+++ b/src/mame/video/midtunit.cpp
@@ -3,84 +3,43 @@
// thanks-to:Kurt Mahan
/*************************************************************************
- Driver for Midway T-unit games.
+ Video Emulation for Midway T-unit, W-unit, and X-unit games.
**************************************************************************/
#include "emu.h"
-#include "cpu/tms34010/tms34010.h"
-#include "includes/midtunit.h"
-#include "includes/midwunit.h"
-#include "includes/midxunit.h"
+#include "midtunit.h"
+#include "midtunit.hxx"
+DEFINE_DEVICE_TYPE(MIDTUNIT_VIDEO, midtunit_video_device, "tunitvid", "Midway T-Unit Video")
+DEFINE_DEVICE_TYPE(MIDWUNIT_VIDEO, midwunit_video_device, "wunitvid", "Midway W-Unit Video")
+DEFINE_DEVICE_TYPE(MIDXUNIT_VIDEO, midxunit_video_device, "xunitvid", "Midway X-Unit Video")
/* compile-time options */
#define LOG_DMA 0 /* DMAs are logged if the 'L' key is pressed */
-
-/* constants for the DMA chip */
-enum
+midtunit_video_device::midtunit_video_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock)
+ : device_t(mconfig, type, tag, owner, clock)
+ , m_maincpu(*this, finder_base::DUMMY_TAG)
+ , m_palette(*this, finder_base::DUMMY_TAG)
+ , m_gfxrom(*this, finder_base::DUMMY_TAG)
{
- DMA_LRSKIP = 0,
- DMA_COMMAND,
- DMA_OFFSETLO,
- DMA_OFFSETHI,
- DMA_XSTART,
- DMA_YSTART,
- DMA_WIDTH,
- DMA_HEIGHT,
- DMA_PALETTE,
- DMA_COLOR,
- DMA_SCALE_X,
- DMA_SCALE_Y,
- DMA_TOPCLIP,
- DMA_BOTCLIP,
- DMA_UNKNOWN_E, /* MK1/2 never write here; NBA only writes 0 */
- DMA_CONFIG,
- DMA_LEFTCLIP, /* pseudo-register */
- DMA_RIGHTCLIP /* pseudo-register */
-};
-
-
-
-/* graphics-related variables */
-static uint16_t midtunit_control;
-
-/* videoram-related variables */
-static uint32_t gfxbank_offset[2];
-static std::unique_ptr<uint16_t[]> local_videoram;
-static uint8_t videobank_select;
-
-/* DMA-related variables */
-static uint16_t dma_register[18];
-static struct
+}
+
+midtunit_video_device::midtunit_video_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
+ : midtunit_video_device(mconfig, MIDTUNIT_VIDEO, tag, owner, clock)
{
- uint8_t * gfxrom;
-
- uint32_t offset; /* source offset, in bits */
- int32_t rowbits; /* source bits to skip each row */
- int32_t xpos; /* x position, clipped */
- int32_t ypos; /* y position, clipped */
- int32_t width; /* horizontal pixel count */
- int32_t height; /* vertical pixel count */
- uint16_t palette; /* palette base */
- uint16_t color; /* current foreground color with palette */
-
- uint8_t yflip; /* yflip? */
- uint8_t bpp; /* bits per pixel */
- uint8_t preskip; /* preskip scale */
- uint8_t postskip; /* postskip scale */
- int32_t topclip; /* top clipping scanline */
- int32_t botclip; /* bottom clipping scanline */
- int32_t leftclip; /* left clipping column */
- int32_t rightclip; /* right clipping column */
- int32_t startskip; /* pixels to skip at start */
- int32_t endskip; /* pixels to skip at end */
- uint16_t xstep; /* 8.8 fixed number scale x factor */
- uint16_t ystep; /* 8.8 fixed number scale y factor */
-} dma_state;
+}
+midwunit_video_device::midwunit_video_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
+ : midtunit_video_device(mconfig, MIDWUNIT_VIDEO, tag, owner, clock)
+{
+}
+midxunit_video_device::midxunit_video_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
+ : midtunit_video_device(mconfig, MIDXUNIT_VIDEO, tag, owner, clock)
+{
+}
/*************************************
*
@@ -88,42 +47,48 @@ static struct
*
*************************************/
-VIDEO_START_MEMBER(midtunit_state,midtunit)
+void midtunit_video_device::device_start()
{
/* allocate memory */
- local_videoram = std::make_unique<uint16_t[]>(0x100000/2);
+ m_local_videoram = std::make_unique<uint16_t[]>(0x100000/2);
m_dma_timer = timer_alloc(TIMER_DMA);
/* reset all the globals */
- gfxbank_offset[0] = 0x000000;
- gfxbank_offset[1] = 0x400000;
+ m_gfxbank_offset[0] = 0x000000;
+ m_gfxbank_offset[1] = 0x400000;
- memset(dma_register, 0, sizeof(dma_register));
- memset(&dma_state, 0, sizeof(dma_state));
- dma_state.gfxrom = m_gfxrom->base();
+ memset(m_dma_register, 0, sizeof(m_dma_register));
+ memset(&m_dma_state, 0, sizeof(dma_state));
+ m_dma_state.gfxrom = m_gfxrom->base();
/* register for state saving */
- save_item(NAME(midtunit_control));
- save_item(NAME(gfxbank_offset));
- save_pointer(NAME(local_videoram), 0x100000/sizeof(local_videoram[0]));
- save_item(NAME(videobank_select));
- save_item(NAME(dma_register));
+ save_item(NAME(m_midtunit_control));
+ save_item(NAME(m_gfxbank_offset));
+ save_pointer(NAME(m_local_videoram), 0x100000/sizeof(m_local_videoram[0]));
+ save_item(NAME(m_videobank_select));
+ save_item(NAME(m_dma_register));
+
+ INIT_TEMPLATED_DMA_DRAW_GROUP(m_dma_draw_skip_scale, true, true);
+ INIT_TEMPLATED_DMA_DRAW_GROUP(m_dma_draw_noskip_scale, false, true);
+ INIT_TEMPLATED_DMA_DRAW_GROUP(m_dma_draw_skip_noscale, true, false);
+ INIT_TEMPLATED_DMA_DRAW_GROUP(m_dma_draw_noskip_noscale, false, false);
+
+ m_gfx_rom_large = false;
}
-
-VIDEO_START_MEMBER(midwunit_state,midwunit)
+void midwunit_video_device::device_start()
{
- VIDEO_START_CALL_MEMBER(midtunit);
- m_gfx_rom_large = 1;
+ midtunit_video_device::device_start();
+ m_gfx_rom_large = true;
}
-VIDEO_START_MEMBER(midxunit_state,midxunit)
+void midxunit_video_device::device_start()
{
- VIDEO_START_CALL_MEMBER(midtunit);
- m_gfx_rom_large = 1;
- videobank_select = 1;
+ midtunit_video_device::device_start();
+ m_gfx_rom_large = true;
+ m_videobank_select = 1;
}
@@ -134,17 +99,17 @@ VIDEO_START_MEMBER(midxunit_state,midxunit)
*
*************************************/
-READ16_MEMBER(midtunit_state::midtunit_gfxrom_r)
+READ16_MEMBER(midtunit_video_device::midtunit_gfxrom_r)
{
- uint8_t *base = m_gfxrom->base() + gfxbank_offset[(offset >> 21) & 1];
+ uint8_t *base = m_gfxrom->base() + m_gfxbank_offset[(offset >> 21) & 1];
offset = (offset & 0x01fffff) * 2;
return base[offset] | (base[offset + 1] << 8);
}
-READ16_MEMBER(midtunit_state::midwunit_gfxrom_r)
+READ16_MEMBER(midwunit_video_device::midwunit_gfxrom_r)
{
- uint8_t *base = m_gfxrom->base() + gfxbank_offset[0];
+ uint8_t *base = m_gfxrom->base() + m_gfxbank_offset[0];
offset *= 2;
return base[offset] | (base[offset + 1] << 8);
}
@@ -157,67 +122,67 @@ READ16_MEMBER(midtunit_state::midwunit_gfxrom_r)
*
*************************************/
-WRITE16_MEMBER(midtunit_state::midtunit_vram_w)
+WRITE16_MEMBER(midtunit_video_device::midtunit_vram_w)
{
offset *= 2;
- if (videobank_select)
+ if (m_videobank_select)
{
- if (ACCESSING_BITS_0_7)
- local_videoram[offset] = (data & 0xff) | ((dma_register[DMA_PALETTE] & 0xff) << 8);
+ if (ACCESSING_BITS_0_7)
+ m_local_videoram[offset] = 0;// (data & 0xff) | ((m_dma_register[DMA_PALETTE] & 0xff) << 8);
if (ACCESSING_BITS_8_15)
- local_videoram[offset + 1] = ((data >> 8) & 0xff) | (dma_register[DMA_PALETTE] & 0xff00);
+ m_local_videoram[offset + 1] = ((data >> 8) & 0xff) | (m_dma_register[DMA_PALETTE] & 0xff00);
}
else
{
if (ACCESSING_BITS_0_7)
- local_videoram[offset] = (local_videoram[offset] & 0xff) | ((data & 0xff) << 8);
+ m_local_videoram[offset] = (m_local_videoram[offset] & 0xff) | ((data & 0xff) << 8);
if (ACCESSING_BITS_8_15)
- local_videoram[offset + 1] = (local_videoram[offset + 1] & 0xff) | (data & 0xff00);
+ m_local_videoram[offset + 1] = (m_local_videoram[offset + 1] & 0xff) | (data & 0xff00);
}
}
-WRITE16_MEMBER(midtunit_state::midtunit_vram_data_w)
+WRITE16_MEMBER(midtunit_video_device::midtunit_vram_data_w)
{
offset *= 2;
if (ACCESSING_BITS_0_7)
- local_videoram[offset] = (data & 0xff) | ((dma_register[DMA_PALETTE] & 0xff) << 8);
+ m_local_videoram[offset] = (data & 0xff) | ((m_dma_register[DMA_PALETTE] & 0xff) << 8);
if (ACCESSING_BITS_8_15)
- local_videoram[offset + 1] = ((data >> 8) & 0xff) | (dma_register[DMA_PALETTE] & 0xff00);
+ m_local_videoram[offset + 1] = ((data >> 8) & 0xff) | (m_dma_register[DMA_PALETTE] & 0xff00);
}
-WRITE16_MEMBER(midtunit_state::midtunit_vram_color_w)
+WRITE16_MEMBER(midtunit_video_device::midtunit_vram_color_w)
{
offset *= 2;
if (ACCESSING_BITS_0_7)
- local_videoram[offset] = (local_videoram[offset] & 0xff) | ((data & 0xff) << 8);
+ m_local_videoram[offset] = (m_local_videoram[offset] & 0xff) | ((data & 0xff) << 8);
if (ACCESSING_BITS_8_15)
- local_videoram[offset + 1] = (local_videoram[offset + 1] & 0xff) | (data & 0xff00);
+ m_local_videoram[offset + 1] = (m_local_videoram[offset + 1] & 0xff) | (data & 0xff00);
}
-READ16_MEMBER(midtunit_state::midtunit_vram_r)
+READ16_MEMBER(midtunit_video_device::midtunit_vram_r)
{
offset *= 2;
- if (videobank_select)
- return (local_videoram[offset] & 0x00ff) | (local_videoram[offset + 1] << 8);
+ if (m_videobank_select)
+ return (m_local_videoram[offset] & 0x00ff) | (m_local_videoram[offset + 1] << 8);
else
- return (local_videoram[offset] >> 8) | (local_videoram[offset + 1] & 0xff00);
+ return (m_local_videoram[offset] >> 8) | (m_local_videoram[offset + 1] & 0xff00);
}
-READ16_MEMBER(midtunit_state::midtunit_vram_data_r)
+READ16_MEMBER(midtunit_video_device::midtunit_vram_data_r)
{
offset *= 2;
- return (local_videoram[offset] & 0x00ff) | (local_videoram[offset + 1] << 8);
+ return (m_local_videoram[offset] & 0x00ff) | (m_local_videoram[offset + 1] << 8);
}
-READ16_MEMBER(midtunit_state::midtunit_vram_color_r)
+READ16_MEMBER(midtunit_video_device::midtunit_vram_color_r)
{
offset *= 2;
- return (local_videoram[offset] >> 8) | (local_videoram[offset + 1] & 0xff00);
+ return (m_local_videoram[offset] >> 8) | (m_local_videoram[offset + 1] & 0xff00);
}
@@ -228,15 +193,15 @@ READ16_MEMBER(midtunit_state::midtunit_vram_color_r)
*
*************************************/
-TMS340X0_TO_SHIFTREG_CB_MEMBER(midtunit_state::to_shiftreg)
+TMS340X0_TO_SHIFTREG_CB_MEMBER(midtunit_video_device::to_shiftreg)
{
- memcpy(shiftreg, &local_videoram[address >> 3], 2 * 512 * sizeof(uint16_t));
+ memcpy(shiftreg, &m_local_videoram[address >> 3], 2 * 512 * sizeof(uint16_t));
}
-TMS340X0_FROM_SHIFTREG_CB_MEMBER(midtunit_state::from_shiftreg)
+TMS340X0_FROM_SHIFTREG_CB_MEMBER(midtunit_video_device::from_shiftreg)
{
- memcpy(&local_videoram[address >> 3], shiftreg, 2 * 512 * sizeof(uint16_t));
+ memcpy(&m_local_videoram[address >> 3], shiftreg, 2 * 512 * sizeof(uint16_t));
}
@@ -247,7 +212,7 @@ TMS340X0_FROM_SHIFTREG_CB_MEMBER(midtunit_state::from_shiftreg)
*
*************************************/
-WRITE16_MEMBER(midtunit_state::midtunit_control_w)
+WRITE16_MEMBER(midtunit_video_device::midtunit_control_w)
{
/*
other important bits:
@@ -255,20 +220,20 @@ WRITE16_MEMBER(midtunit_state::midtunit_control_w)
*/
logerror("T-unit control = %04X\n", data);
- COMBINE_DATA(&midtunit_control);
+ COMBINE_DATA(&m_midtunit_control);
/* gfx bank select is bit 7 */
- if (!(midtunit_control & 0x0080) || !m_gfx_rom_large)
- gfxbank_offset[0] = 0x000000;
+ if (!(m_midtunit_control & 0x0080) || !m_gfx_rom_large)
+ m_gfxbank_offset[0] = 0x000000;
else
- gfxbank_offset[0] = 0x800000;
+ m_gfxbank_offset[0] = 0x800000;
/* video bank select is bit 5 */
- videobank_select = (midtunit_control >> 5) & 1;
+ m_videobank_select = (m_midtunit_control >> 5) & 1;
}
-WRITE16_MEMBER(midtunit_state::midwunit_control_w)
+WRITE16_MEMBER(midwunit_video_device::midwunit_control_w)
{
/*
other important bits:
@@ -276,19 +241,19 @@ WRITE16_MEMBER(midtunit_state::midwunit_control_w)
*/
logerror("Wolf-unit control = %04X\n", data);
- COMBINE_DATA(&midtunit_control);
+ COMBINE_DATA(&m_midtunit_control);
/* gfx bank select is bits 8-9 */
- gfxbank_offset[0] = 0x800000 * ((midtunit_control >> 8) & 3);
+ m_gfxbank_offset[0] = 0x800000 * ((m_midtunit_control >> 8) & 3);
/* video bank select is unknown */
- videobank_select = (midtunit_control >> 11) & 1;
+ m_videobank_select = (m_midtunit_control >> 11) & 1;
}
-READ16_MEMBER(midtunit_state::midwunit_control_r)
+READ16_MEMBER(midwunit_video_device::midwunit_control_r)
{
- return midtunit_control;
+ return m_midtunit_control;
}
@@ -299,14 +264,14 @@ READ16_MEMBER(midtunit_state::midwunit_control_r)
*
*************************************/
-WRITE16_MEMBER(midtunit_state::midxunit_paletteram_w)
+WRITE16_MEMBER(midxunit_video_device::midxunit_paletteram_w)
{
if (!(offset & 1))
m_palette->write16(space, offset / 2, data, mem_mask);
}
-READ16_MEMBER(midtunit_state::midxunit_paletteram_r)
+READ16_MEMBER(midxunit_video_device::midxunit_paletteram_r)
{
return m_palette->read16(space, offset / 2, mem_mask);
}
@@ -319,27 +284,6 @@ READ16_MEMBER(midtunit_state::midxunit_paletteram_r)
*
*************************************/
-/*** constant definitions ***/
-#define PIXEL_SKIP 0
-#define PIXEL_COLOR 1
-#define PIXEL_COPY 2
-
-#define XFLIP_NO 0
-#define XFLIP_YES 1
-
-#define SKIP_NO 0
-#define SKIP_YES 1
-
-#define SCALE_NO 0
-#define SCALE_YES 1
-
-#define XPOSMASK 0x3ff
-#define YPOSMASK 0x1ff
-
-
-typedef void (*dma_draw_func)(void);
-
-
/*** fast pixel extractors ***/
#if !defined(ALIGN_SHORTS) && defined(LSB_FIRST)
#define EXTRACTGEN(m) ((*(uint16_t *)&base[o >> 3] >> (o & 7)) & (m))
@@ -350,230 +294,188 @@ typedef void (*dma_draw_func)(void);
#endif
/*** core blitter routine macro ***/
-#define DMA_DRAW_FUNC_BODY(name, bitsperpixel, extractor, xflip, skip, scale, zero, nonzero) \
-{ \
- int height = dma_state.height << 8; \
- uint8_t *base = dma_state.gfxrom; \
- uint32_t offset = dma_state.offset; \
- uint16_t pal = dma_state.palette; \
- uint16_t color = pal | dma_state.color; \
- int sy = dma_state.ypos, iy = 0, ty; \
- int bpp = bitsperpixel; \
- int mask = (1 << bpp) - 1; \
- int xstep = scale ? dma_state.xstep : 0x100; \
- \
- /* loop over the height */ \
- while (iy < height) \
- { \
- int startskip = dma_state.startskip << 8; \
- int endskip = dma_state.endskip << 8; \
- int width = dma_state.width << 8; \
- int sx = dma_state.xpos, ix = 0, tx; \
- uint32_t o = offset; \
- int pre, post; \
- uint16_t *d; \
- \
- /* handle skipping */ \
- if (skip) \
- { \
- uint8_t value = EXTRACTGEN(0xff); \
- o += 8; \
- \
- /* adjust for preskip */ \
- pre = (value & 0x0f) << (dma_state.preskip + 8); \
- tx = pre / xstep; \
- if (xflip) \
- sx = (sx - tx) & XPOSMASK; \
- else \
- sx = (sx + tx) & XPOSMASK; \
- ix += tx * xstep; \
- \
- /* adjust for postskip */ \
- post = ((value >> 4) & 0x0f) << (dma_state.postskip + 8); \
- width -= post; \
- endskip -= post; \
- } \
- \
- /* handle Y clipping */ \
- if (sy < dma_state.topclip || sy > dma_state.botclip) \
- goto clipy; \
- \
- /* handle start skip */ \
- if (ix < startskip) \
- { \
- tx = ((startskip - ix) / xstep) * xstep; \
- ix += tx; \
- o += (tx >> 8) * bpp; \
- } \
- \
- /* handle end skip */ \
- if ((width >> 8) > dma_state.width - dma_state.endskip) \
- width = (dma_state.width - dma_state.endskip) << 8; \
- \
- /* determine destination pointer */ \
- d = &local_videoram[sy * 512]; \
- \
- /* loop until we draw the entire width */ \
- while (ix < width) \
- { \
- /* only process if not clipped */ \
- if (sx >= dma_state.leftclip && sx <= dma_state.rightclip) \
- { \
- /* special case similar handling of zero/non-zero */ \
- if (zero == nonzero) \
- { \
- if (zero == PIXEL_COLOR) \
- d[sx] = color; \
- else if (zero == PIXEL_COPY) \
- d[sx] = (extractor(mask)) | pal; \
- } \
- \
- /* otherwise, read the pixel and look */ \
- else \
- { \
- int pixel = (extractor(mask)); \
- \
- /* non-zero pixel case */ \
- if (pixel) \
- { \
- if (nonzero == PIXEL_COLOR) \
- d[sx] = color; \
- else if (nonzero == PIXEL_COPY) \
- d[sx] = pixel | pal; \
- } \
- \
- /* zero pixel case */ \
- else \
- { \
- if (zero == PIXEL_COLOR) \
- d[sx] = color; \
- else if (zero == PIXEL_COPY) \
- d[sx] = pal; \
- } \
- } \
- } \
- \
- /* update pointers */ \
- if (xflip) \
- sx = (sx - 1) & XPOSMASK; \
- else \
- sx = (sx + 1) & XPOSMASK; \
- \
- /* advance to the next pixel */ \
- if (!scale) \
- { \
- ix += 0x100; \
- o += bpp; \
- } \
- else \
- { \
- tx = ix >> 8; \
- ix += xstep; \
- tx = (ix >> 8) - tx; \
- o += bpp * tx; \
- } \
- } \
- \
- clipy: \
- /* advance to the next row */ \
- if (dma_state.yflip) \
- sy = (sy - 1) & YPOSMASK; \
- else \
- sy = (sy + 1) & YPOSMASK; \
- if (!scale) \
- { \
- iy += 0x100; \
- width = dma_state.width; \
- if (skip) \
- { \
- offset += 8; \
- width -= (pre + post) >> 8; \
- if (width > 0) offset += width * bpp; \
- } \
- else \
- offset += width * bpp; \
- } \
- else \
- { \
- ty = iy >> 8; \
- iy += dma_state.ystep; \
- ty = (iy >> 8) - ty; \
- if (!skip) \
- offset += ty * dma_state.width * bpp; \
- else if (ty--) \
- { \
- o = offset + 8; \
- width = dma_state.width - ((pre + post) >> 8); \
- if (width > 0) o += width * bpp; \
- while (ty--) \
- { \
- uint8_t value = EXTRACTGEN(0xff); \
- o += 8; \
- pre = (value & 0x0f) << dma_state.preskip; \
- post = ((value >> 4) & 0x0f) << dma_state.postskip; \
- width = dma_state.width - pre - post; \
- if (width > 0) o += width * bpp; \
- } \
- offset = o; \
- } \
- } \
- } \
-}
-
-
-/*** slightly simplified one for most blitters ***/
-#define DMA_DRAW_FUNC(name, bpp, extract, xflip, skip, scale, zero, nonzero) \
-static void name(void) \
-{ \
- DMA_DRAW_FUNC_BODY(name, bpp, extract, xflip, skip, scale, zero, nonzero) \
-}
-
-/*** empty blitter ***/
-static void dma_draw_none(void)
+template <int BitsPerPixel, bool XFlip, bool Skip, bool Scale, midtunit_video_device::op_type_t Zero, midtunit_video_device::op_type_t NonZero>
+void midtunit_video_device::dma_draw()
{
+ int height = m_dma_state.height << 8;
+ uint8_t *base = m_dma_state.gfxrom;
+ uint32_t offset = m_dma_state.offset;
+ uint16_t pal = m_dma_state.palette;
+ uint16_t color = pal | m_dma_state.color;
+ int sy = m_dma_state.ypos;
+ int iy = 0;
+ int ty;
+ int mask = (1 << BitsPerPixel) - 1;
+ int xstep = Scale ? m_dma_state.xstep : 0x100;
+
+ /* loop over the height */
+ while (iy < height)
+ {
+ int startskip = m_dma_state.startskip << 8;
+ int endskip = m_dma_state.endskip << 8;
+ int width = m_dma_state.width << 8;
+ int sx = m_dma_state.xpos;
+ int ix = 0;
+ int tx;
+ uint32_t o = offset;
+ int pre, post;
+ uint16_t *d;
+
+ /* handle skipping */
+ if (Skip)
+ {
+ uint8_t value = EXTRACTGEN(0xff);
+ o += 8;
+
+ /* adjust for preskip */
+ pre = (value & 0x0f) << (m_dma_state.preskip + 8);
+ tx = pre / xstep;
+ if (XFlip)
+ sx = (sx - tx) & XPOSMASK;
+ else
+ sx = (sx + tx) & XPOSMASK;
+ ix += tx * xstep;
+
+ /* adjust for postskip */
+ post = ((value >> 4) & 0x0f) << (m_dma_state.postskip + 8);
+ width -= post;
+ endskip -= post;
+ }
+
+ /* handle Y clipping */
+ if (sy < m_dma_state.topclip || sy > m_dma_state.botclip)
+ goto clipy;
+
+ /* handle start skip */
+ if (ix < startskip)
+ {
+ tx = ((startskip - ix) / xstep) * xstep;
+ ix += tx;
+ o += (tx >> 8) * BitsPerPixel;
+ }
+
+ /* handle end skip */
+ if ((width >> 8) > m_dma_state.width - m_dma_state.endskip)
+ width = (m_dma_state.width - m_dma_state.endskip) << 8;
+
+ /* determine destination pointer */
+ d = &m_local_videoram[sy * 512];
+
+ /* loop until we draw the entire width */
+ while (ix < width)
+ {
+ /* only process if not clipped */
+ if (sx >= m_dma_state.leftclip && sx <= m_dma_state.rightclip)
+ {
+ /* special case similar handling of zero/non-zero */
+ if (Zero == NonZero)
+ {
+ if (Zero == PIXEL_COLOR)
+ d[sx] = color;
+ else if (Zero == PIXEL_COPY)
+ d[sx] = (EXTRACTGEN(mask)) | pal;
+ }
+
+ /* otherwise, read the pixel and look */
+ else
+ {
+ int pixel = (EXTRACTGEN(mask));
+
+ /* non-zero pixel case */
+ if (pixel)
+ {
+ if (NonZero == PIXEL_COLOR)
+ d[sx] = color;
+ else if (NonZero == PIXEL_COPY)
+ d[sx] = pixel | pal;
+ }
+
+ /* zero pixel case */
+ else
+ {
+ if (Zero == PIXEL_COLOR)
+ d[sx] = color;
+ else if (Zero == PIXEL_COPY)
+ d[sx] = pal;
+ }
+ }
+ }
+
+ /* update pointers */
+ if (XFlip)
+ sx = (sx - 1) & XPOSMASK;
+ else
+ sx = (sx + 1) & XPOSMASK;
+
+ /* advance to the next pixel */
+ if (!Scale)
+ {
+ ix += 0x100;
+ o += BitsPerPixel;
+ }
+ else
+ {
+ tx = ix >> 8;
+ ix += xstep;
+ tx = (ix >> 8) - tx;
+ o += BitsPerPixel * tx;
+ }
+ }
+
+ clipy:
+ /* advance to the next row */
+ if (m_dma_state.yflip)
+ sy = (sy - 1) & YPOSMASK;
+ else
+ sy = (sy + 1) & YPOSMASK;
+ if (!Scale)
+ {
+ iy += 0x100;
+ width = m_dma_state.width;
+ if (Skip)
+ {
+ offset += 8;
+ width -= (pre + post) >> 8;
+ if (width > 0) offset += width * BitsPerPixel;
+ }
+ else
+ {
+ offset += width * BitsPerPixel;
+ }
+ }
+ else
+ {
+ ty = iy >> 8;
+ iy += m_dma_state.ystep;
+ ty = (iy >> 8) - ty;
+ if (!Skip)
+ {
+ offset += ty * m_dma_state.width * BitsPerPixel;
+ }
+ else if (ty--)
+ {
+ o = offset + 8;
+ width = m_dma_state.width - ((pre + post) >> 8);
+ if (width > 0) o += width * BitsPerPixel;
+ while (ty--)
+ {
+ uint8_t value = EXTRACTGEN(0xff);
+ o += 8;
+ pre = (value & 0x0f) << m_dma_state.preskip;
+ post = ((value >> 4) & 0x0f) << m_dma_state.postskip;
+ width = m_dma_state.width - pre - post;
+ if (width > 0) o += width * BitsPerPixel;
+ }
+ offset = o;
+ }
+ }
+ }
}
-/*** super macro for declaring an entire blitter family ***/
-#define DECLARE_BLITTER_SET(prefix, bpp, extract, skip, scale) \
-DMA_DRAW_FUNC(prefix##_p0, bpp, extract, XFLIP_NO, skip, scale, PIXEL_COPY, PIXEL_SKIP) \
-DMA_DRAW_FUNC(prefix##_p1, bpp, extract, XFLIP_NO, skip, scale, PIXEL_SKIP, PIXEL_COPY) \
-DMA_DRAW_FUNC(prefix##_c0, bpp, extract, XFLIP_NO, skip, scale, PIXEL_COLOR, PIXEL_SKIP) \
-DMA_DRAW_FUNC(prefix##_c1, bpp, extract, XFLIP_NO, skip, scale, PIXEL_SKIP, PIXEL_COLOR) \
-DMA_DRAW_FUNC(prefix##_p0p1, bpp, extract, XFLIP_NO, skip, scale, PIXEL_COPY, PIXEL_COPY) \
-DMA_DRAW_FUNC(prefix##_c0c1, bpp, extract, XFLIP_NO, skip, scale, PIXEL_COLOR, PIXEL_COLOR) \
-DMA_DRAW_FUNC(prefix##_c0p1, bpp, extract, XFLIP_NO, skip, scale, PIXEL_COLOR, PIXEL_COPY) \
-DMA_DRAW_FUNC(prefix##_p0c1, bpp, extract, XFLIP_NO, skip, scale, PIXEL_COPY, PIXEL_COLOR) \
- \
-DMA_DRAW_FUNC(prefix##_p0_xf, bpp, extract, XFLIP_YES, skip, scale, PIXEL_COPY, PIXEL_SKIP) \
-DMA_DRAW_FUNC(prefix##_p1_xf, bpp, extract, XFLIP_YES, skip, scale, PIXEL_SKIP, PIXEL_COPY) \
-DMA_DRAW_FUNC(prefix##_c0_xf, bpp, extract, XFLIP_YES, skip, scale, PIXEL_COLOR, PIXEL_SKIP) \
-DMA_DRAW_FUNC(prefix##_c1_xf, bpp, extract, XFLIP_YES, skip, scale, PIXEL_SKIP, PIXEL_COLOR) \
-DMA_DRAW_FUNC(prefix##_p0p1_xf, bpp, extract, XFLIP_YES, skip, scale, PIXEL_COPY, PIXEL_COPY) \
-DMA_DRAW_FUNC(prefix##_c0c1_xf, bpp, extract, XFLIP_YES, skip, scale, PIXEL_COLOR, PIXEL_COLOR) \
-DMA_DRAW_FUNC(prefix##_c0p1_xf, bpp, extract, XFLIP_YES, skip, scale, PIXEL_COLOR, PIXEL_COPY) \
-DMA_DRAW_FUNC(prefix##_p0c1_xf, bpp, extract, XFLIP_YES, skip, scale, 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 ***/
-DECLARE_BLITTER_SET(dma_draw_skip_scale, dma_state.bpp, EXTRACTGEN, SKIP_YES, SCALE_YES)
-DECLARE_BLITTER_SET(dma_draw_noskip_scale, dma_state.bpp, EXTRACTGEN, SKIP_NO, SCALE_YES)
-DECLARE_BLITTER_SET(dma_draw_skip_noscale, dma_state.bpp, EXTRACTGEN, SKIP_YES, SCALE_NO)
-DECLARE_BLITTER_SET(dma_draw_noskip_noscale, dma_state.bpp, EXTRACTGEN, SKIP_NO, SCALE_NO)
-
+DEFINE_TEMPLATED_DMA_DRAW_GROUP(true, true);
+DEFINE_TEMPLATED_DMA_DRAW_GROUP(false, true);
+DEFINE_TEMPLATED_DMA_DRAW_GROUP(true, false);
+DEFINE_TEMPLATED_DMA_DRAW_GROUP(false, false);
/*************************************
@@ -582,16 +484,16 @@ DECLARE_BLITTER_SET(dma_draw_noskip_noscale, dma_state.bpp, EXTRACTGEN, SKIP
*
*************************************/
-void midtunit_state::device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr)
+void midtunit_video_device::device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr)
{
switch (id)
{
case TIMER_DMA:
- dma_register[DMA_COMMAND] &= ~0x8000; /* tell the cpu we're done */
+ m_dma_register[DMA_COMMAND] &= ~0x8000; /* tell the cpu we're done */
m_maincpu->set_input_line(0, ASSERT_LINE);
break;
default:
- assert_always(false, "Unknown id in midtunit_state::device_timer");
+ assert_always(false, "Unknown id in midtunit_video_device::device_timer");
}
}
@@ -603,14 +505,14 @@ void midtunit_state::device_timer(emu_timer &timer, device_timer_id id, int para
*
*************************************/
-READ16_MEMBER(midtunit_state::midtunit_dma_r)
+READ16_MEMBER(midtunit_video_device::midtunit_dma_r)
{
/* rmpgwt sometimes reads register 0, expecting it to return the */
/* current DMA status; thus we map register 0 to register 1 */
/* openice does it as well */
if (offset == 0)
offset = 1;
- return dma_register[offset];
+ return m_dma_register[offset];
}
@@ -660,28 +562,26 @@ READ16_MEMBER(midtunit_state::midtunit_dma_r)
* | ----------2----- | select top/bottom or left/right for reg 12/13
*/
-WRITE16_MEMBER(midtunit_state::midtunit_dma_w)
+WRITE16_MEMBER(midtunit_video_device::midtunit_dma_w)
{
static const uint8_t register_map[2][16] =
{
{ 0,1,2,3,4,5,6,7,8,9,10,11,16,17,14,15 },
{ 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15 }
};
- int regbank = (dma_register[DMA_CONFIG] >> 5) & 1;
- int command, bpp, regnum;
- uint32_t gfxoffset;
+ int regbank = (m_dma_register[DMA_CONFIG] >> 5) & 1;
int pixels = 0;
/* blend with the current register contents */
- regnum = register_map[regbank][offset];
- COMBINE_DATA(&dma_register[regnum]);
+ int regnum = register_map[regbank][offset];
+ COMBINE_DATA(&m_dma_register[regnum]);
/* only writes to DMA_COMMAND actually cause actions */
if (regnum != DMA_COMMAND)
return;
/* high bit triggers action */
- command = dma_register[DMA_COMMAND];
+ int command = m_dma_register[DMA_COMMAND];
m_maincpu->set_input_line(0, CLEAR_LINE);
if (!(command & 0x8000))
return;
@@ -689,32 +589,32 @@ WRITE16_MEMBER(midtunit_state::midtunit_dma_w)
g_profiler.start(PROFILER_USER1);
/* determine bpp */
- bpp = (command >> 12) & 7;
+ int bpp = (command >> 12) & 7;
/* fill in the basic data */
- dma_state.xpos = dma_register[DMA_XSTART] & XPOSMASK;
- dma_state.ypos = dma_register[DMA_YSTART] & YPOSMASK;
- dma_state.width = dma_register[DMA_WIDTH] & 0x3ff;
- dma_state.height = dma_register[DMA_HEIGHT] & 0x3ff;
- dma_state.palette = dma_register[DMA_PALETTE] & 0x7f00;
- dma_state.color = dma_register[DMA_COLOR] & 0xff;
+ m_dma_state.xpos = m_dma_register[DMA_XSTART] & XPOSMASK;
+ m_dma_state.ypos = m_dma_register[DMA_YSTART] & YPOSMASK;
+ m_dma_state.width = m_dma_register[DMA_WIDTH] & 0x3ff;
+ m_dma_state.height = m_dma_register[DMA_HEIGHT] & 0x3ff;
+ m_dma_state.palette = m_dma_register[DMA_PALETTE] & 0x7f00;
+ m_dma_state.color = m_dma_register[DMA_COLOR] & 0xff;
/* fill in the rev 2 data */
- dma_state.yflip = (command & 0x20) >> 5;
- dma_state.bpp = bpp ? bpp : 8;
- dma_state.preskip = (command >> 8) & 3;
- dma_state.postskip = (command >> 10) & 3;
- dma_state.xstep = dma_register[DMA_SCALE_X] ? dma_register[DMA_SCALE_X] : 0x100;
- dma_state.ystep = dma_register[DMA_SCALE_Y] ? dma_register[DMA_SCALE_Y] : 0x100;
+ m_dma_state.yflip = (command & 0x20) >> 5;
+ m_dma_state.bpp = bpp;
+ m_dma_state.preskip = (command >> 8) & 3;
+ m_dma_state.postskip = (command >> 10) & 3;
+ m_dma_state.xstep = m_dma_register[DMA_SCALE_X] ? m_dma_register[DMA_SCALE_X] : 0x100;
+ m_dma_state.ystep = m_dma_register[DMA_SCALE_Y] ? m_dma_register[DMA_SCALE_Y] : 0x100;
/* clip the clippers */
- dma_state.topclip = dma_register[DMA_TOPCLIP] & 0x1ff;
- dma_state.botclip = dma_register[DMA_BOTCLIP] & 0x1ff;
- dma_state.leftclip = dma_register[DMA_LEFTCLIP] & 0x3ff;
- dma_state.rightclip = dma_register[DMA_RIGHTCLIP] & 0x3ff;
+ m_dma_state.topclip = m_dma_register[DMA_TOPCLIP] & 0x1ff;
+ m_dma_state.botclip = m_dma_register[DMA_BOTCLIP] & 0x1ff;
+ m_dma_state.leftclip = m_dma_register[DMA_LEFTCLIP] & 0x3ff;
+ m_dma_state.rightclip = m_dma_register[DMA_RIGHTCLIP] & 0x3ff;
/* determine the offset */
- gfxoffset = dma_register[DMA_OFFSETLO] | (dma_register[DMA_OFFSETHI] << 16);
+ uint32_t gfxoffset = m_dma_register[DMA_OFFSETLO] | (m_dma_register[DMA_OFFSETHI] << 16);
if (LOG_DMA)
{
@@ -722,15 +622,15 @@ if (LOG_DMA)
{
logerror("DMA command %04X: (bpp=%d skip=%d xflip=%d yflip=%d preskip=%d postskip=%d)\n",
command, (command >> 12) & 7, (command >> 7) & 1, (command >> 4) & 1, (command >> 5) & 1, (command >> 8) & 3, (command >> 10) & 3);
- logerror(" offset=%08X pos=(%d,%d) w=%d h=%d clip=(%d,%d)-(%d,%d)\n", gfxoffset, dma_register[DMA_XSTART], dma_register[DMA_YSTART],
- dma_register[DMA_WIDTH], dma_register[DMA_HEIGHT], dma_register[DMA_LEFTCLIP], dma_register[DMA_TOPCLIP], dma_register[DMA_RIGHTCLIP], dma_register[DMA_BOTCLIP]);
- logerror(" offset=%08X pos=(%d,%d) w=%d h=%d clip=(%d,%d)-(%d,%d)\n", gfxoffset, dma_state.xpos, dma_state.ypos,
- dma_state.width, dma_state.height, dma_state.leftclip, dma_state.topclip, dma_state.rightclip, dma_state.botclip);
+ logerror(" offset=%08X pos=(%d,%d) w=%d h=%d clip=(%d,%d)-(%d,%d)\n", gfxoffset, m_dma_register[DMA_XSTART], m_dma_register[DMA_YSTART],
+ m_dma_register[DMA_WIDTH], m_dma_register[DMA_HEIGHT], m_dma_register[DMA_LEFTCLIP], m_dma_register[DMA_TOPCLIP], m_dma_register[DMA_RIGHTCLIP], m_dma_register[DMA_BOTCLIP]);
+ logerror(" offset=%08X pos=(%d,%d) w=%d h=%d clip=(%d,%d)-(%d,%d)\n", gfxoffset, m_dma_state.xpos, m_dma_state.ypos,
+ m_dma_state.width, m_dma_state.height, m_dma_state.leftclip, m_dma_state.topclip, m_dma_state.rightclip, m_dma_state.botclip);
logerror(" palette=%04X color=%04X lskip=%02X rskip=%02X xstep=%04X ystep=%04X test=%04X config=%04X\n",
- dma_register[DMA_PALETTE], dma_register[DMA_COLOR],
- dma_register[DMA_LRSKIP] >> 8, dma_register[DMA_LRSKIP] & 0xff,
- dma_register[DMA_SCALE_X], dma_register[DMA_SCALE_Y], dma_register[DMA_UNKNOWN_E],
- dma_register[DMA_CONFIG]);
+ m_dma_register[DMA_PALETTE], m_dma_register[DMA_COLOR],
+ m_dma_register[DMA_LRSKIP] >> 8, m_dma_register[DMA_LRSKIP] & 0xff,
+ m_dma_register[DMA_SCALE_X], m_dma_register[DMA_SCALE_Y], m_dma_register[DMA_UNKNOWN_E],
+ m_dma_register[DMA_CONFIG]);
logerror("----\n");
}
}
@@ -744,7 +644,7 @@ if (LOG_DMA)
if (gfxoffset >= 0xf8000000)
gfxoffset -= 0xf8000000;
if (gfxoffset < 0x10000000)
- dma_state.offset = gfxoffset;
+ m_dma_state.offset = gfxoffset;
else
{
logerror("DMA source out of range: %08X\n", gfxoffset);
@@ -758,34 +658,34 @@ if (LOG_DMA)
/* full word seems to be the starting skip value. */
if (command & 0x40)
{
- dma_state.startskip = dma_register[DMA_LRSKIP] & 0xff;
- dma_state.endskip = dma_register[DMA_LRSKIP] >> 8;
+ m_dma_state.startskip = m_dma_register[DMA_LRSKIP] & 0xff;
+ m_dma_state.endskip = m_dma_register[DMA_LRSKIP] >> 8;
}
else
{
- dma_state.startskip = 0;
- dma_state.endskip = dma_register[DMA_LRSKIP];
+ m_dma_state.startskip = 0;
+ m_dma_state.endskip = m_dma_register[DMA_LRSKIP];
}
/* then draw */
- if (dma_state.xstep == 0x100 && dma_state.ystep == 0x100)
+ if (m_dma_state.xstep == 0x100 && m_dma_state.ystep == 0x100)
{
if (command & 0x80)
- (*dma_draw_skip_noscale[command & 0x1f])();
+ ((this)->*(m_dma_draw_skip_noscale[(command & 0x1f)*8 + bpp]))();
else
- (*dma_draw_noskip_noscale[command & 0x1f])();
+ ((this)->*(m_dma_draw_noskip_noscale[(command & 0x1f)*8 + bpp]))();
- pixels = dma_state.width * dma_state.height;
+ pixels = m_dma_state.width * m_dma_state.height;
}
else
{
if (command & 0x80)
- (*dma_draw_skip_scale[command & 0x1f])();
+ ((this)->*(m_dma_draw_skip_scale[(command & 0x1f)*8 + bpp]))();
else
- (*dma_draw_noskip_scale[command & 0x1f])();
+ ((this)->*(m_dma_draw_noskip_scale[(command & 0x1f)*8 + bpp]))();
- if (dma_state.xstep && dma_state.ystep)
- pixels = ((dma_state.width << 8) / dma_state.xstep) * ((dma_state.height << 8) / dma_state.ystep);
+ if (m_dma_state.xstep && m_dma_state.ystep)
+ pixels = ((m_dma_state.width << 8) / m_dma_state.xstep) * ((m_dma_state.height << 8) / m_dma_state.ystep);
else
pixels = 0;
}
@@ -805,26 +705,24 @@ skipdma:
*
*************************************/
-TMS340X0_SCANLINE_IND16_CB_MEMBER(midtunit_state::scanline_update)
+TMS340X0_SCANLINE_IND16_CB_MEMBER(midtunit_video_device::scanline_update)
{
- uint16_t *src = &local_videoram[(params->rowaddr << 9) & 0x3fe00];
+ uint16_t *src = &m_local_videoram[(params->rowaddr << 9) & 0x3fe00];
uint16_t *dest = &bitmap.pix16(scanline);
int coladdr = params->coladdr << 1;
- int x;
/* copy the non-blanked portions of this scanline */
- for (x = params->heblnk; x < params->hsblnk; x++)
+ for (int x = params->heblnk; x < params->hsblnk; x++)
dest[x] = src[coladdr++ & 0x1ff] & 0x7fff;
}
-TMS340X0_SCANLINE_IND16_CB_MEMBER(midxunit_state::scanline_update)
+TMS340X0_SCANLINE_IND16_CB_MEMBER(midxunit_video_device::scanline_update)
{
uint32_t fulladdr = ((params->rowaddr << 16) | params->coladdr) >> 3;
- uint16_t *src = &local_videoram[fulladdr & 0x3fe00];
+ uint16_t *src = &m_local_videoram[fulladdr & 0x3fe00];
uint16_t *dest = &bitmap.pix16(scanline);
- int x;
/* copy the non-blanked portions of this scanline */
- for (x = params->heblnk; x < params->hsblnk; x++)
+ for (int x = params->heblnk; x < params->hsblnk; x++)
dest[x] = src[fulladdr++ & 0x1ff] & 0x7fff;
}