diff options
Diffstat (limited to 'src/mame/video/midvunit.cpp')
-rw-r--r-- | src/mame/video/midvunit.cpp | 585 |
1 files changed, 0 insertions, 585 deletions
diff --git a/src/mame/video/midvunit.cpp b/src/mame/video/midvunit.cpp deleted file mode 100644 index 2cc60de8c5e..00000000000 --- a/src/mame/video/midvunit.cpp +++ /dev/null @@ -1,585 +0,0 @@ -// license:BSD-3-Clause -// copyright-holders:Aaron Giles -/************************************************************************* - - Driver for Midway V-Unit games - -**************************************************************************/ - -#include "emu.h" -#include "cpu/tms34010/tms34010.h" -#include "cpu/adsp2100/adsp2100.h" -#include "audio/williams.h" -#include "includes/midvunit.h" - - -#define WATCH_RENDER (0) -#define LOG_DMA (0) - - -#define DMA_CLOCK 40000000 - - -/* for when we implement DMA timing */ -#define DMA_QUEUE_SIZE 273 -#define TIME_PER_PIXEL 41e-9 - - -midvunit_renderer::midvunit_renderer(midvunit_state &state) - : poly_manager<float, midvunit_object_data, 2, 4000>(state.machine()), - m_state(state) { } - - -/************************************* - * - * Video system start - * - *************************************/ - -void midvunit_state::device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr) -{ - switch (id) - { - case TIMER_SCANLINE: - scanline_timer_cb(ptr, param); - break; - default: - throw emu_fatalerror("Unknown id in midvunit_state::device_timer"); - } -} - -TIMER_CALLBACK_MEMBER(midvunit_state::scanline_timer_cb) -{ - int scanline = param; - - if (scanline != -1) - { - m_maincpu->set_input_line(0, ASSERT_LINE); - m_scanline_timer->adjust(m_screen->time_until_pos(scanline + 1), scanline); - timer_set(attotime::from_hz(25000000), TIMER_SCANLINE, -1); - } - else - m_maincpu->set_input_line(0, CLEAR_LINE); -} - - -void midvunit_state::video_start() -{ - m_scanline_timer = timer_alloc(TIMER_SCANLINE); - - m_poly = std::make_unique<midvunit_renderer>(*this); - - save_item(NAME(m_video_regs)); - save_item(NAME(m_dma_data)); - save_item(NAME(m_dma_data_index)); - save_item(NAME(m_page_control)); - - m_video_changed = true; - machine().save().register_postload(save_prepost_delegate(FUNC(midvunit_state::postload), this)); -} - -void midvunit_state::postload() -{ - m_video_changed = true; -} - -/************************************* - * - * Generic flat quad renderer - * - *************************************/ - -void midvunit_renderer::render_flat(int32_t scanline, const extent_t &extent, const midvunit_object_data &objectdata, int threadid) -{ - uint16_t pixdata = objectdata.pixdata; - int xstep = objectdata.dither + 1; - uint16_t *dest = objectdata.destbase + scanline * 512; - int startx = extent.startx; - int x; - - /* if dithering, ensure that we start on an appropriate pixel */ - startx += (scanline ^ startx) & objectdata.dither; - - /* non-dithered 0 pixels can use a memset */ - if (pixdata == 0 && xstep == 1) - memset(&dest[startx], 0, 2 * (extent.stopx - startx + 1)); - - /* otherwise, we fill manually */ - else - { - for (x = startx; x < extent.stopx; x += xstep) - dest[x] = pixdata; - } -} - - - -/************************************* - * - * Generic textured quad renderers - * - *************************************/ - -void midvunit_renderer::render_tex(int32_t scanline, const extent_t &extent, const midvunit_object_data &objectdata, int threadid) -{ - uint16_t pixdata = objectdata.pixdata; - const uint8_t *texbase = objectdata.texbase; - int xstep = objectdata.dither + 1; - uint16_t *dest = objectdata.destbase + scanline * 512; - int startx = extent.startx; - int stopx = extent.stopx; - int32_t u = extent.param[0].start; - int32_t v = extent.param[1].start; - int32_t dudx = extent.param[0].dpdx; - int32_t dvdx = extent.param[1].dpdx; - int x; - - /* if dithering, we advance by 2x; also ensure that we start on an appropriate pixel */ - if (xstep == 2) - { - if ((scanline ^ startx) & 1) - { - startx++; - u += dudx; - v += dvdx; - } - dudx *= 2; - dvdx *= 2; - } - - /* general case; render every pixel */ - for (x = startx; x < stopx; x += xstep) - { - dest[x] = pixdata + texbase[((v >> 8) & 0xff00) + (u >> 16)]; - u += dudx; - v += dvdx; - } -} - - -void midvunit_renderer::render_textrans(int32_t scanline, const extent_t &extent, const midvunit_object_data &objectdata, int threadid) -{ - uint16_t pixdata = objectdata.pixdata; - const uint8_t *texbase = objectdata.texbase; - int xstep = objectdata.dither + 1; - uint16_t *dest = objectdata.destbase + scanline * 512; - int startx = extent.startx; - int stopx = extent.stopx; - int32_t u = extent.param[0].start; - int32_t v = extent.param[1].start; - int32_t dudx = extent.param[0].dpdx; - int32_t dvdx = extent.param[1].dpdx; - int x; - - /* if dithering, we advance by 2x; also ensure that we start on an appropriate pixel */ - if (xstep == 2) - { - if ((scanline ^ startx) & 1) - { - startx++; - u += dudx; - v += dvdx; - } - dudx *= 2; - dvdx *= 2; - } - - /* general case; render every non-zero texel */ - for (x = startx; x < stopx; x += xstep) - { - uint8_t pix = texbase[((v >> 8) & 0xff00) + (u >> 16)]; - if (pix != 0) - dest[x] = pixdata + pix; - u += dudx; - v += dvdx; - } -} - - -void midvunit_renderer::render_textransmask(int32_t scanline, const extent_t &extent, const midvunit_object_data &objectdata, int threadid) -{ - uint16_t pixdata = objectdata.pixdata; - const uint8_t *texbase = objectdata.texbase; - int xstep = objectdata.dither + 1; - uint16_t *dest = objectdata.destbase + scanline * 512; - int startx = extent.startx; - int stopx = extent.stopx; - int32_t u = extent.param[0].start; - int32_t v = extent.param[1].start; - int32_t dudx = extent.param[0].dpdx; - int32_t dvdx = extent.param[1].dpdx; - int x; - - /* if dithering, we advance by 2x; also ensure that we start on an appropriate pixel */ - if (xstep == 2) - { - if ((scanline ^ startx) & 1) - { - startx++; - u += dudx; - v += dvdx; - } - dudx *= 2; - dvdx *= 2; - } - - /* general case; every non-zero texel renders pixdata */ - for (x = startx; x < stopx; x += xstep) - { - uint8_t pix = texbase[((v >> 8) & 0xff00) + (u >> 16)]; - if (pix != 0) - dest[x] = pixdata; - u += dudx; - v += dvdx; - } -} - - - -/************************************* - * - * DMA queue processor - * - *************************************/ - -void midvunit_renderer::make_vertices_inclusive(vertex_t *vert) -{ - /* build up a mask of right and bottom points */ - /* note we assume clockwise orientation here */ - uint8_t rmask = 0, bmask = 0, eqmask = 0; - for (int vnum = 0; vnum < 4; vnum++) - { - vertex_t *currv = &vert[vnum]; - vertex_t *nextv = &vert[(vnum + 1) & 3]; - - /* if this vertex equals the next one, tag it */ - if (nextv->y == currv->y && nextv->x == currv->x) - eqmask |= 1 << vnum; - - /* if the next vertex is down from us, we are a right coordinate */ - if (nextv->y > currv->y || (nextv->y == currv->y && nextv->x < currv->x)) - rmask |= 1 << vnum; - - /* if the next vertex is left from us, we are a bottom coordinate */ - if (nextv->x < currv->x || (nextv->x == currv->x && nextv->y < currv->y)) - bmask |= 1 << vnum; - } - - /* bail on the edge case */ - if (eqmask == 0x0f) - return; - - /* adjust the right/bottom points so that they get included */ - for (int vnum = 0; vnum < 4; vnum++) - { - vertex_t *currv = &vert[vnum]; - int effvnum = vnum; - - /* if we're equal to the next vertex, use that instead */ - while (eqmask & (1 << effvnum)) - effvnum = (effvnum + 1) & 3; - - /* adjust the points */ - if (rmask & (1 << effvnum)) - currv->x += 0.001f; - if (bmask & (1 << effvnum)) - currv->y += 0.001f; - } -} - - -void midvunit_renderer::process_dma_queue() -{ - /* if we're rendering to the same page we're viewing, it has changed */ - if ((((m_state.m_page_control >> 2) ^ m_state.m_page_control) & 1) == 0 || WATCH_RENDER) - m_state.m_video_changed = true; - - /* fill in the vertex data */ - vertex_t vert[4]; - vert[0].x = (float)(int16_t)m_state.m_dma_data[2] + 0.5f; - vert[0].y = (float)(int16_t)m_state.m_dma_data[3] + 0.5f; - vert[1].x = (float)(int16_t)m_state.m_dma_data[4] + 0.5f; - vert[1].y = (float)(int16_t)m_state.m_dma_data[5] + 0.5f; - vert[2].x = (float)(int16_t)m_state.m_dma_data[6] + 0.5f; - vert[2].y = (float)(int16_t)m_state.m_dma_data[7] + 0.5f; - vert[3].x = (float)(int16_t)m_state.m_dma_data[8] + 0.5f; - vert[3].y = (float)(int16_t)m_state.m_dma_data[9] + 0.5f; - - /* make the vertices inclusive of right/bottom points */ - make_vertices_inclusive(vert); - - /* set the palette base */ - uint16_t pixdata = m_state.m_dma_data[1]; - - render_delegate callback; - bool textured = ((m_state.m_dma_data[0] & 0x300) == 0x100); - - /* handle flat-shaded quads here */ - if (!textured) - { - callback = render_delegate(&midvunit_renderer::render_flat, this); - pixdata += (m_state.m_dma_data[0] & 0x00ff); - } - /* handle textured quads here */ - else - { - /* add the texture info */ - vert[0].p[0] = (float)(m_state.m_dma_data[10] & 0xff) * 65536.0f + 32768.0f; - vert[0].p[1] = (float)(m_state.m_dma_data[10] >> 8) * 65536.0f + 32768.0f; - vert[1].p[0] = (float)(m_state.m_dma_data[11] & 0xff) * 65536.0f + 32768.0f; - vert[1].p[1] = (float)(m_state.m_dma_data[11] >> 8) * 65536.0f + 32768.0f; - vert[2].p[0] = (float)(m_state.m_dma_data[12] & 0xff) * 65536.0f + 32768.0f; - vert[2].p[1] = (float)(m_state.m_dma_data[12] >> 8) * 65536.0f + 32768.0f; - vert[3].p[0] = (float)(m_state.m_dma_data[13] & 0xff) * 65536.0f + 32768.0f; - vert[3].p[1] = (float)(m_state.m_dma_data[13] >> 8) * 65536.0f + 32768.0f; - - /* handle non-masked, non-transparent quads */ - if ((m_state.m_dma_data[0] & 0xc00) == 0x000) - { - callback = render_delegate(&midvunit_renderer::render_tex, this); - } - /* handle non-masked, transparent quads */ - else if ((m_state.m_dma_data[0] & 0xc00) == 0x800) - { - callback = render_delegate(&midvunit_renderer::render_textrans, this); - } - /* handle masked, transparent quads */ - else if ((m_state.m_dma_data[0] & 0xc00) == 0xc00) - { - callback = render_delegate(&midvunit_renderer::render_textransmask, this); - pixdata += (m_state.m_dma_data[0] & 0x00ff); - } - /* handle masked, non-transparent quads (invalid?) */ - else - { - callback = render_delegate(&midvunit_renderer::render_flat, this); - pixdata += (m_state.m_dma_data[0] & 0x00ff); - } - } - - /* set up the object data for this triangle */ - midvunit_object_data &objectdata = object_data_alloc(); - objectdata.destbase = &m_state.m_videoram[(m_state.m_page_control & 4) ? 0x40000 : 0x00000]; - objectdata.texbase = (uint8_t *)m_state.m_textureram.target() + (m_state.m_dma_data[14] * 256); - objectdata.pixdata = pixdata; - objectdata.dither = ((m_state.m_dma_data[0] & 0x2000) != 0); - - /* render as a quad */ - render_polygon<4>(m_state.m_screen->visible_area(), callback, textured ? 2 : 0, vert); -} - - - -/************************************* - * - * DMA pipe control control - * - *************************************/ - -WRITE32_MEMBER(midvunit_state::midvunit_dma_queue_w) -{ - if (LOG_DMA && machine().input().code_pressed(KEYCODE_L)) - logerror("%06X:queue(%X) = %08X\n", m_maincpu->pc(), m_dma_data_index, data); - if (m_dma_data_index < 16) - m_dma_data[m_dma_data_index++] = data; -} - - -READ32_MEMBER(midvunit_state::midvunit_dma_queue_entries_r) -{ - /* always return 0 entries */ - return 0; -} - - -READ32_MEMBER(midvunit_state::midvunit_dma_trigger_r) -{ - if (offset) - { - if (LOG_DMA && machine().input().code_pressed(KEYCODE_L)) - logerror("%06X:trigger\n", m_maincpu->pc()); - m_poly->process_dma_queue(); - m_dma_data_index = 0; - } - return 0; -} - - - -/************************************* - * - * Paging control - * - *************************************/ - -WRITE32_MEMBER(midvunit_state::midvunit_page_control_w) -{ - /* watch for the display page to change */ - if ((m_page_control ^ data) & 1) - { - m_video_changed = true; - if (LOG_DMA && machine().input().code_pressed(KEYCODE_L)) - logerror("##########################################################\n"); - m_screen->update_partial(m_screen->vpos() - 1); - } - m_page_control = data; -} - - -READ32_MEMBER(midvunit_state::midvunit_page_control_r) -{ - return m_page_control; -} - - - -/************************************* - * - * Video control - * - *************************************/ - -WRITE32_MEMBER(midvunit_state::midvunit_video_control_w) -{ - uint16_t old = m_video_regs[offset]; - - /* update the data */ - COMBINE_DATA(&m_video_regs[offset]); - - /* update the scanline timer */ - if (offset == 0) - m_scanline_timer->adjust(m_screen->time_until_pos((data & 0x1ff) + 1, 0), data & 0x1ff); - - /* if something changed, update our parameters */ - if (old != m_video_regs[offset] && m_video_regs[6] != 0 && m_video_regs[11] != 0) - { - rectangle visarea; - - /* derive visible area from blanking */ - visarea.min_x = 0; - visarea.max_x = (m_video_regs[6] + m_video_regs[2] - m_video_regs[5]) % m_video_regs[6]; - visarea.min_y = 0; - visarea.max_y = (m_video_regs[11] + m_video_regs[7] - m_video_regs[10]) % m_video_regs[11]; - m_screen->configure(m_video_regs[6], m_video_regs[11], visarea, HZ_TO_ATTOSECONDS(MIDVUNIT_VIDEO_CLOCK / 2) * m_video_regs[6] * m_video_regs[11]); - } -} - - -READ32_MEMBER(midvunit_state::midvunit_scanline_r) -{ - return m_screen->vpos(); -} - - - -/************************************* - * - * Video RAM access - * - *************************************/ - -WRITE32_MEMBER(midvunit_state::midvunit_videoram_w) -{ - m_poly->wait("Video RAM write"); - if (!m_video_changed) - { - int visbase = (m_page_control & 1) ? 0x40000 : 0x00000; - if ((offset & 0x40000) == visbase) - m_video_changed = true; - } - COMBINE_DATA(&m_videoram[offset]); -} - - -READ32_MEMBER(midvunit_state::midvunit_videoram_r) -{ - m_poly->wait("Video RAM read"); - return m_videoram[offset]; -} - - - -/************************************* - * - * Palette RAM access - * - *************************************/ - -WRITE32_MEMBER(midvunit_state::midvunit_paletteram_w) -{ - int newword; - - COMBINE_DATA(&m_generic_paletteram_32[offset]); - newword = m_generic_paletteram_32[offset]; - m_palette->set_pen_color(offset, pal5bit(newword >> 10), pal5bit(newword >> 5), pal5bit(newword >> 0)); -} - - - -/************************************* - * - * Texture RAM access - * - *************************************/ - -WRITE32_MEMBER(midvunit_state::midvunit_textureram_w) -{ - uint8_t *base = (uint8_t *)m_textureram.target(); - m_poly->wait("Texture RAM write"); - base[offset * 2] = data; - base[offset * 2 + 1] = data >> 8; -} - - -READ32_MEMBER(midvunit_state::midvunit_textureram_r) -{ - uint8_t *base = (uint8_t *)m_textureram.target(); - return (base[offset * 2 + 1] << 8) | base[offset * 2]; -} - - - - -/************************************* - * - * Video system update - * - *************************************/ - -uint32_t midvunit_state::screen_update_midvunit(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect) -{ - int x, y, width, xoffs; - uint32_t offset; - - m_poly->wait("Refresh Time"); - - /* if the video didn't change, indicate as much */ - if (!m_video_changed) - return UPDATE_HAS_NOT_CHANGED; - m_video_changed = false; - - /* determine the base of the videoram */ -#if WATCH_RENDER - offset = (m_page_control & 4) ? 0x40000 : 0x00000; -#else - offset = (m_page_control & 1) ? 0x40000 : 0x00000; -#endif - - /* determine how many pixels to copy */ - xoffs = cliprect.min_x; - width = cliprect.max_x - xoffs + 1; - - /* adjust the offset */ - offset += xoffs; - offset += 512 * (cliprect.min_y - screen.visible_area().min_y); - - /* loop over rows */ - for (y = cliprect.min_y; y <= cliprect.max_y; y++) - { - uint16_t *dest = &bitmap.pix16(y, cliprect.min_x); - for (x = 0; x < width; x++) - *dest++ = m_videoram[offset + x] & 0x7fff; - offset += 512; - } - return 0; -} |