/************************************************************************* Driver for Midway T-unit games. **************************************************************************/ #include "emu.h" #include "profiler.h" #include "cpu/tms34010/tms34010.h" #include "includes/midtunit.h" /* compile-time options */ #define LOG_DMA 0 /* DMAs are logged if the 'L' key is pressed */ /* constants for the DMA chip */ enum { 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 */ UINT8 * midtunit_gfx_rom; size_t midtunit_gfx_rom_size; UINT8 midtunit_gfx_rom_large; static UINT16 midtunit_control; /* videoram-related variables */ static UINT32 gfxbank_offset[2]; static UINT16 * local_videoram; static UINT8 videobank_select; /* DMA-related variables */ static UINT16 dma_register[18]; static struct { UINT32 offset; /* source offset, in bits */ INT32 rowbits; /* source bits to skip each row */ INT32 xpos; /* x position, clipped */ INT32 ypos; /* y position, clipped */ INT32 width; /* horizontal pixel count */ INT32 height; /* vertical pixel count */ UINT16 palette; /* palette base */ UINT16 color; /* current foreground color with palette */ UINT8 yflip; /* yflip? */ UINT8 bpp; /* bits per pixel */ UINT8 preskip; /* preskip scale */ UINT8 postskip; /* postskip scale */ INT32 topclip; /* top clipping scanline */ INT32 botclip; /* bottom clipping scanline */ INT32 leftclip; /* left clipping column */ INT32 rightclip; /* right clipping column */ INT32 startskip; /* pixels to skip at start */ INT32 endskip; /* pixels to skip at end */ UINT16 xstep; /* 8.8 fixed number scale x factor */ UINT16 ystep; /* 8.8 fixed number scale y factor */ } dma_state; /************************************* * * Video startup * *************************************/ VIDEO_START( midtunit ) { /* allocate memory */ local_videoram = auto_alloc_array(machine, UINT16, 0x100000/2); /* reset all the globals */ gfxbank_offset[0] = 0x000000; gfxbank_offset[1] = 0x400000; memset(dma_register, 0, sizeof(dma_register)); memset(&dma_state, 0, sizeof(dma_state)); /* register for state saving */ state_save_register_global(machine, midtunit_control); state_save_register_global_array(machine, gfxbank_offset); state_save_register_global_pointer(machine, local_videoram, 0x100000/sizeof(local_videoram[0])); state_save_register_global(machine, videobank_select); state_save_register_global_array(machine, dma_register); } VIDEO_START( midwunit ) { VIDEO_START_CALL(midtunit); midtunit_gfx_rom_large = 1; } VIDEO_START( midxunit ) { VIDEO_START_CALL(midtunit); midtunit_gfx_rom_large = 1; videobank_select = 1; } /************************************* * * Banked graphics ROM access * *************************************/ READ16_HANDLER( midtunit_gfxrom_r ) { UINT8 *base = &midtunit_gfx_rom[gfxbank_offset[(offset >> 21) & 1]]; offset = (offset & 0x01fffff) * 2; return base[offset] | (base[offset + 1] << 8); } READ16_HANDLER( midwunit_gfxrom_r ) { UINT8 *base = &midtunit_gfx_rom[gfxbank_offset[0]]; offset *= 2; return base[offset] | (base[offset + 1] << 8); } /************************************* * * Video RAM read/write * *************************************/ WRITE16_HANDLER( midtunit_vram_w ) { offset *= 2; if (videobank_select) { if (ACCESSING_BITS_0_7) local_videoram[offset] = (data & 0xff) | ((dma_register[DMA_PALETTE] & 0xff) << 8); if (ACCESSING_BITS_8_15) local_videoram[offset + 1] = ((data >> 8) & 0xff) | (dma_register[DMA_PALETTE] & 0xff00); } else { if (ACCESSING_BITS_0_7) local_videoram[offset] = (local_videoram[offset] & 0xff) | ((data & 0xff) << 8); if (ACCESSING_BITS_8_15) local_videoram[offset + 1] = (local_videoram[offset + 1] & 0xff) | (data & 0xff00); } } WRITE16_HANDLER( midtunit_vram_data_w ) { offset *= 2; if (ACCESSING_BITS_0_7) local_videoram[offset] = (data & 0xff) | ((dma_register[DMA_PALETTE] & 0xff) << 8); if (ACCESSING_BITS_8_15) local_videoram[offset + 1] = ((data >> 8) & 0xff) | (dma_register[DMA_PALETTE] & 0xff00); } WRITE16_HANDLER( midtunit_vram_color_w ) { offset *= 2; if (ACCESSING_BITS_0_7) local_videoram[offset] = (local_videoram[offset] & 0xff) | ((data & 0xff) << 8); if (ACCESSING_BITS_8_15) local_videoram[offset + 1] = (local_videoram[offset + 1] & 0xff) | (data & 0xff00); } READ16_HANDLER( midtunit_vram_r ) { offset *= 2; if (videobank_select) return (local_videoram[offset] & 0x00ff) | (local_videoram[offset + 1] << 8); else return (local_videoram[offset] >> 8) | (local_videoram[offset + 1] & 0xff00); } READ16_HANDLER( midtunit_vram_data_r ) { offset *= 2; return (local_videoram[offset] & 0x00ff) | (local_videoram[offset + 1] << 8); } READ16_HANDLER( midtunit_vram_color_r ) { offset *= 2; return (local_videoram[offset] >> 8) | (local_videoram[offset + 1] & 0xff00); } /************************************* * * Shift register read/write * *************************************/ void midtunit_to_shiftreg(address_space *space, UINT32 address, UINT16 *shiftreg) { memcpy(shiftreg, &local_videoram[address >> 3], 2 * 512 * sizeof(UINT16)); } void midtunit_from_shiftreg(address_space *space, UINT32 address, UINT16 *shiftreg) { memcpy(&local_videoram[address >> 3], shiftreg, 2 * 512 * sizeof(UINT16)); } /************************************* * * Control register * *************************************/ WRITE16_HANDLER( midtunit_control_w ) { /* other important bits: bit 2 (0x0004) is toggled periodically */ logerror("T-unit control = %04X\n", data); COMBINE_DATA(&midtunit_control); /* gfx bank select is bit 7 */ if (!(midtunit_control & 0x0080) || !midtunit_gfx_rom_large) gfxbank_offset[0] = 0x000000; else gfxbank_offset[0] = 0x800000; /* video bank select is bit 5 */ videobank_select = (midtunit_control >> 5) & 1; } WRITE16_HANDLER( midwunit_control_w ) { /* other important bits: bit 2 (0x0004) is toggled periodically */ logerror("Wolf-unit control = %04X\n", data); COMBINE_DATA(&midtunit_control); /* gfx bank select is bits 8-9 */ gfxbank_offset[0] = 0x800000 * ((midtunit_control >> 8) & 3); /* video bank select is unknown */ videobank_select = (midtunit_control >> 11) & 1; } READ16_HANDLER( midwunit_control_r ) { return midtunit_control; } /************************************* * * Palette handlers * *************************************/ WRITE16_HANDLER( midtunit_paletteram_w ) { //int newword; COMBINE_DATA(&space->machine().generic.paletteram.u16[offset]); //newword = space->machine().generic.paletteram.u16[offset]; palette_set_color_rgb(space->machine(), offset, pal5bit(data >> 10), pal5bit(data >> 5), pal5bit(data >> 0)); } WRITE16_HANDLER( midxunit_paletteram_w ) { if (!(offset & 1)) midtunit_paletteram_w(space, offset / 2, data, mem_mask); } READ16_HANDLER( midxunit_paletteram_r ) { return space->machine().generic.paletteram.u16[offset / 2]; } /************************************* * * DMA drawing routines * *************************************/ /*** 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 *)&base[o >> 3] >> (o & 7)) & (m)) #elif defined(powerc) #define EXTRACTGEN(m) ((__lhbrx(base, o >> 3) >> (o & 7)) & (m)) #else #define EXTRACTGEN(m) (((base[o >> 3] | (base[(o >> 3) + 1] << 8)) >> (o & 7)) & (m)) #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 *base = midtunit_gfx_rom; \ UINT32 offset = dma_state.offset; \ UINT16 pal = dma_state.palette; \ UINT16 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 o = offset; \ int pre, post; \ UINT16 *d; \ \ /* handle skipping */ \ if (skip) \ { \ UINT8 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 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) { } /*** 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) /************************************* * * DMA finished callback * *************************************/ static TIMER_CALLBACK( dma_callback ) { dma_register[DMA_COMMAND] &= ~0x8000; /* tell the cpu we're done */ cputag_set_input_line(machine, "maincpu", 0, ASSERT_LINE); } /************************************* * * DMA reader * *************************************/ READ16_HANDLER( 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]; } /************************************* * * DMA write handler * *************************************/ /* * DMA registers * ------------------ * * Register | Bit | Use * ----------+-FEDCBA9876543210-+------------ * 0 | xxxxxxxx-------- | pixels to drop at the start of each row * | --------xxxxxxxx | pixels to drop at the end of each row * 1 | x--------------- | trigger write (or clear if zero) * | -421------------ | image bpp (0=8) * | ----84---------- | post skip size = (1<> 5) & 1; int command, bpp, regnum; UINT32 gfxoffset; int pixels = 0; /* blend with the current register contents */ regnum = register_map[regbank][offset]; COMBINE_DATA(&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]; cputag_set_input_line(space->machine(), "maincpu", 0, CLEAR_LINE); if (!(command & 0x8000)) return; g_profiler.start(PROFILER_USER1); /* determine bpp */ 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; /* 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; /* 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; /* determine the offset */ gfxoffset = dma_register[DMA_OFFSETLO] | (dma_register[DMA_OFFSETHI] << 16); if (LOG_DMA) { if (space->machine().input().code_pressed(KEYCODE_L)) { 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(" 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]); logerror("----\n"); } } /* special case: drawing mode C doesn't need to know about any pixel data */ if ((command & 0x0f) == 0x0c) gfxoffset = 0; /* determine the location */ if (!midtunit_gfx_rom_large && gfxoffset >= 0x2000000) gfxoffset -= 0x2000000; if (gfxoffset >= 0xf8000000) gfxoffset -= 0xf8000000; if (gfxoffset < 0x10000000) dma_state.offset = gfxoffset; else { logerror("DMA source out of range: %08X\n", gfxoffset); goto skipdma; } /* there seems to be two types of behavior for the DMA chip */ /* for MK1 and MK2, the upper byte of the LRSKIP is the */ /* starting skip value, and the lower byte is the ending */ /* skip value; for the NBA Jam, Hangtime, and Open Ice, the */ /* 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; } else { dma_state.startskip = 0; dma_state.endskip = dma_register[DMA_LRSKIP]; } /* then draw */ if (dma_state.xstep == 0x100 && dma_state.ystep == 0x100) { if (command & 0x80) (*dma_draw_skip_noscale[command & 0x1f])(); else (*dma_draw_noskip_noscale[command & 0x1f])(); pixels = dma_state.width * dma_state.height; } else { if (command & 0x80) (*dma_draw_skip_scale[command & 0x1f])(); else (*dma_draw_noskip_scale[command & 0x1f])(); if (dma_state.xstep && dma_state.ystep) pixels = ((dma_state.width << 8) / dma_state.xstep) * ((dma_state.height << 8) / dma_state.ystep); else pixels = 0; } /* signal we're done */ skipdma: space->machine().scheduler().timer_set(attotime::from_nsec(41 * pixels), FUNC(dma_callback)); g_profiler.stop(); } /************************************* * * Core refresh routine * *************************************/ void midtunit_scanline_update(screen_device &screen, bitmap_t *bitmap, int scanline, const tms34010_display_params *params) { UINT16 *src = &local_videoram[(params->rowaddr << 9) & 0x3fe00]; UINT16 *dest = BITMAP_ADDR16(bitmap, scanline, 0); int coladdr = params->coladdr << 1; int x; /* copy the non-blanked portions of this scanline */ for (x = params->heblnk; x < params->hsblnk; x++) dest[x] = src[coladdr++ & 0x1ff] & 0x7fff; } void midxunit_scanline_update(screen_device &screen, bitmap_t *bitmap, int scanline, const tms34010_display_params *params) { UINT32 fulladdr = ((params->rowaddr << 16) | params->coladdr) >> 3; UINT16 *src = &local_videoram[fulladdr & 0x3fe00]; UINT16 *dest = BITMAP_ADDR16(bitmap, scanline, 0); int x; /* copy the non-blanked portions of this scanline */ for (x = params->heblnk; x < params->hsblnk; x++) dest[x] = src[fulladdr++ & 0x1ff] & 0x7fff; }