From a96049fb14b6b6633b61bff693379f90825a2af3 Mon Sep 17 00:00:00 2001 From: Ted Green Date: Tue, 21 Jun 2016 08:38:28 -0600 Subject: [PATCH] zeus2: Re-organize frame buffer ram and add IEEE754 floating point conversion (nw) --- src/devices/video/zeus2.cpp | 286 ++++++++++++++++------------------ src/devices/video/zeus2.h | 86 +++++++++- src/mame/drivers/atlantis.cpp | 3 +- 3 files changed, 214 insertions(+), 161 deletions(-) diff --git a/src/devices/video/zeus2.cpp b/src/devices/video/zeus2.cpp index 02e9b9d9e52..cb35cf501c6 100644 --- a/src/devices/video/zeus2.cpp +++ b/src/devices/video/zeus2.cpp @@ -7,7 +7,7 @@ **************************************************************************/ #include "zeus2.h" -#define LOG_REGS 0 +#define LOG_REGS 1 /************************************* * Constructor @@ -22,7 +22,7 @@ const device_type ZEUS2 = &device_creator; zeus2_device::zeus2_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) : device_t(mconfig, ZEUS2, "Midway Zeus2", tag, owner, clock, "zeus2", __FILE__), - m_vblank(*this), m_irq(*this) + m_vblank(*this), m_irq(*this), m_ieee754_float(0) { } @@ -69,7 +69,9 @@ void zeus2_device::device_start() /* allocate memory for "wave" RAM */ waveram[0] = auto_alloc_array(machine(), UINT32, WAVERAM0_WIDTH * WAVERAM0_HEIGHT * 8/4); - waveram[1] = auto_alloc_array(machine(), UINT32, WAVERAM1_WIDTH * WAVERAM1_HEIGHT * 12/4); + //waveram[1] = auto_alloc_array(machine(), UINT32, WAVERAM1_WIDTH * WAVERAM1_HEIGHT * 12/4); + m_frameColor = std::make_unique(WAVERAM1_WIDTH * WAVERAM1_HEIGHT * 2); + m_frameDepth = std::make_unique(WAVERAM1_WIDTH * WAVERAM1_HEIGHT * 2); /* initialize polygon engine */ poly = auto_alloc(machine(), zeus2_renderer(this)); @@ -87,8 +89,11 @@ void zeus2_device::device_start() /* save states */ save_pointer(NAME(waveram[0]), WAVERAM0_WIDTH * WAVERAM0_HEIGHT * 8 / sizeof(waveram[0][0])); - save_pointer(NAME(waveram[1]), WAVERAM1_WIDTH * WAVERAM1_HEIGHT * 12 / sizeof(waveram[1][0])); - save_pointer(NAME(m_zeusbase), sizeof(m_zeusbase[0])*0x80); + //save_pointer(NAME(waveram[1]), WAVERAM1_WIDTH * WAVERAM1_HEIGHT * 12 / sizeof(waveram[1][0])); + save_pointer(m_frameColor.get(), "m_frameColor", sizeof(m_frameColor[0]) * WAVERAM1_WIDTH * WAVERAM1_HEIGHT * 2); + save_pointer(m_frameDepth.get(), "m_frameDepth", sizeof(m_frameDepth[0]) * WAVERAM1_WIDTH * WAVERAM1_HEIGHT * 2); + save_pointer(NAME(m_zeusbase), sizeof(m_zeusbase[0]) * 0x80); + save_pointer(NAME(m_renderRegs), sizeof(m_renderRegs[0]) * 0x80); save_item(NAME(zeus_fifo)); save_item(NAME(zeus_fifo_words)); save_item(NAME(zeus_cliprect.min_x)); @@ -104,12 +109,13 @@ void zeus2_device::device_start() void zeus2_device::device_reset() { - memset(m_zeusbase, 0, sizeof(m_zeusbase)); + memset(m_zeusbase, 0, sizeof(m_zeusbase[0]) * 0x80); + memset(m_renderRegs, 0, sizeof(m_renderRegs[0]) * 0x80); + zbase = 2.0f; - m_yScale = 0; + m_yScale = 1; yoffs = 0; texel_width = 256; - zeus_renderbase = waveram[1]; zeus_fifo_words = 0; m_fill_color = 0; m_fill_depth = 0; @@ -177,6 +183,10 @@ void zeus2_device::device_stop() UINT32 zeus2_device::screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect) { + // Wait until configuration is completed before transfering anything + if (m_zeusbase[0x30] == 0) + return 0; + int x, y; poly->wait(); @@ -187,17 +197,15 @@ if (machine().input().code_pressed(KEYCODE_DOWN)) { zbase -= 1.0f; popmessage("Z /* normal update case */ if (!machine().input().code_pressed(KEYCODE_W)) { - const void *base = waveram1_ptr_from_expanded_addr(m_zeusbase[0x38] >> m_yScale); int xoffs = screen.visible_area().min_x; for (y = cliprect.min_y; y <= cliprect.max_y; y++) { + UINT32 *colorptr = &m_frameColor[frame_addr_from_xy(0, y, false)]; UINT32 *dest = &bitmap.pix32(y); - UINT32 bufY = y >> m_yScale; - UINT32 bufOffsX = (m_yScale && (y & 1)) ? 0x200 : 0; for (x = cliprect.min_x; x <= cliprect.max_x; x++) { - UINT32 bufX = x - xoffs + bufOffsX; - dest[x] = WAVERAM_READPIX(base, bufY, bufX); + UINT32 bufX = x - xoffs; //dest[x] = WAVERAM_READPIX(base, y, x - xoffs); + dest[x] = colorptr[bufX]; } } } @@ -205,7 +213,7 @@ if (machine().input().code_pressed(KEYCODE_DOWN)) { zbase -= 1.0f; popmessage("Z /* waveram drawing case */ else { - const UINT64 *base; + const void *base; if (machine().input().code_pressed(KEYCODE_DOWN)) yoffs += machine().input().code_pressed(KEYCODE_LSHIFT) ? 0x40 : 1; if (machine().input().code_pressed(KEYCODE_UP)) yoffs -= machine().input().code_pressed(KEYCODE_LSHIFT) ? 0x40 : 1; @@ -214,9 +222,9 @@ if (machine().input().code_pressed(KEYCODE_DOWN)) { zbase -= 1.0f; popmessage("Z if (yoffs < 0) yoffs = 0; if (0) - base = (const UINT64 *)waveram0_ptr_from_expanded_addr(yoffs << 16); + base = waveram0_ptr_from_expanded_addr(yoffs << 16); else - base = (const UINT64 *)waveram1_ptr_from_expanded_addr(yoffs << 16); + base = (void *)&m_frameColor[yoffs<<9]; int xoffs = screen.visible_area().min_x; for (y = cliprect.min_y; y <= cliprect.max_y; y++) @@ -225,15 +233,15 @@ if (machine().input().code_pressed(KEYCODE_DOWN)) { zbase -= 1.0f; popmessage("Z for (x = cliprect.min_x; x <= cliprect.max_x; x++) { if (0) { - UINT8 tex = get_texel_8bit(base, y, x, texel_width); + UINT8 tex = get_texel_8bit((UINT64 *)base, y, x, texel_width); dest[x] = (tex << 16) | (tex << 8) | tex; } else { - dest[x] = WAVERAM_READPIX(base, y, x - xoffs); + dest[x] = ((UINT32 *)(base))[((y * WAVERAM1_WIDTH)) + x - xoffs]; } } } - popmessage("offs = %06X", yoffs); + popmessage("offs = %06X base = %08X", yoffs, yoffs<<9); } return 0; @@ -303,7 +311,8 @@ WRITE32_MEMBER( zeus2_device::zeus2_w ) int logit = (offset != 0x08 && (offset != 0x20 || data != 0) && offset != 0x40 && offset != 0x41 && offset != 0x48 && offset != 0x49 && offset != 0x4e && - offset != 0x50 && offset != 0x51 && offset != 0x57 && offset != 0x58 && offset != 0x59 && offset != 0x5a && offset != 0x5e); + offset != 0x50 && offset != 0x51 && offset != 0x57 && offset != 0x58 && offset != 0x59 && offset != 0x5a && offset != 0x5e + ); logit &= LOG_REGS; if (logit) logerror("%08X:zeus2_w", machine().device("maincpu")->safe_pc()); @@ -389,6 +398,18 @@ void zeus2_device::zeus2_register_update(offs_t offset, UINT32 oldval, int logit zeus2_pointer_write(m_zeusbase[0x20] >> 24, m_zeusbase[0x20]); break; + case 0x30: + { + int horPixels = (m_zeusbase[0x34] & 0xffff) - (m_zeusbase[0x33] >> 16); + // Just a guess. Atlantis startup has two scanlines per physical ram row + if (horPixels <= 0x200) + m_yScale = 1; + else + m_yScale = 0; + popmessage("reg[30]: %08X horPixels: %d scale: %d", m_zeusbase[0x30], horPixels, m_yScale); + } + break; + case 0x33: case 0x34: case 0x35: @@ -396,15 +417,9 @@ void zeus2_device::zeus2_register_update(offs_t offset, UINT32 oldval, int logit case 0x37: m_screen->update_partial(m_screen->vpos()); { - // Just a guess. Atlantis startup has two scanlines per physical ram row - if ((m_zeusbase[0x30] & 0xfff) <= 0x100) - m_yScale = 1; - else - m_yScale = 0; - int vtotal = (m_zeusbase[0x37] & 0xffff) << m_yScale; + int vtotal = (m_zeusbase[0x37] & 0xffff); int htotal = (m_zeusbase[0x34] >> 16); - - rectangle visarea((m_zeusbase[0x33] >> 16), htotal - 1, 0, (m_zeusbase[0x35] & 0xffff)<< m_yScale); + rectangle visarea((m_zeusbase[0x33] >> 16), htotal - 1, 0, (m_zeusbase[0x35] & 0xffff)); if (htotal > 0 && vtotal > 0 && visarea.min_x < visarea.max_x && visarea.max_y < vtotal) { m_screen->configure(htotal, vtotal, visarea, HZ_TO_ATTOSECONDS((double)ZEUS2_VIDEO_CLOCK / 4.0 / (htotal * vtotal))); @@ -423,7 +438,7 @@ void zeus2_device::zeus2_register_update(offs_t offset, UINT32 oldval, int logit m_zeusbase[0x38] = oldval; m_screen->update_partial(m_screen->vpos()); log_fifo = machine().input().code_pressed(KEYCODE_L); - //log_fifo = 1; + log_fifo = 1; m_zeusbase[0x38] = temp; } break; @@ -500,39 +515,34 @@ void zeus2_device::zeus2_register_update(offs_t offset, UINT32 oldval, int logit case 0x50: if (m_zeusbase[0x50] == 0x00510000) { // SGRAM Special Mode Register Write - if (m_zeusbase[0x51] & 0x00400000) { + if (m_zeusbase[0x51] == 0x00200000) { // SGRAM Mask Register if ((m_zeusbase[0x58] & m_zeusbase[0x59] & m_zeusbase[0x5a]) != 0xffffffff) logerror("zeus2_register_update: Warning! Mask Register not equal to 0xffffffff\n"); } - if (m_zeusbase[0x51] & 0x00200000) { + if (m_zeusbase[0x51] == 0x00400000) { // SGRAM Color Register m_fill_color = m_zeusbase[0x58]; - m_fill_depth = m_zeusbase[0x5a] & 0xffff; + m_fill_depth = m_zeusbase[0x5a]; if (m_zeusbase[0x58] != m_zeusbase[0x59]) logerror("zeus2_register_update: Warning! Different fill colors are set.\n"); } } - else if (1 && (m_zeusbase[0x50] & 0x00080000) && (m_zeusbase[0x50] & 0xffff)) { + else if (1 && ((m_zeusbase[0x50] & 0x000f0000)==0x80000) && (m_zeusbase[0x50] & 0xffff)) { // Fast fill // Unknown what the exact bit fields are, this is a just a guess // Atlantis: 0x00983FFF => clear entire frame buffer, 0x00981FFF => clear one frame // crusnexo: 0x007831FF => clear one frame // thegrid: 0x008831FF => clear one frame - //UINT32 lastRow = (((m_zeusbase[0x50] >> 8) & 0xff) << 3) | 0x7; - UINT32 lastRow = (((m_zeusbase[0x50] >> 8) & 0xff) << 3) | 0x3; - UINT32 lastCol = (((m_zeusbase[0x50] >> 0) & 0xff) << 2) | 0x3; - // Not sure how to select - //void *base = waveram1_ptr_from_expanded_addr(m_zeusbase[0x51]); - void *base = (m_zeusbase[0x50] & 0x800000) ? waveram1_ptr_from_expanded_addr(m_zeusbase[0x51]) : zeus_renderbase; - for (int y = 0; y <= lastRow; y++) - for (int x = 0; x <= lastCol; x++) { - WAVERAM_WRITEPIX(base, y, x, m_fill_color); - WAVERAM_WRITEDEPTH(base, y, x, m_fill_depth); - } - //waveram_plot_depth(y, x, m_fill_color, m_fill_depth); + // thegrid: 0x0079FFFF => clear one frame at 51=0 then 51=00800000 ??? + UINT32 addr = frame_addr_from_reg51(); + UINT32 numBytes = (m_zeusbase[0x50] & 0xffff) + 1; + numBytes *= 0x40; + //printf("Clearing buffer: numPixels: %08X addr: %08X reg50: %08X\n", numBytes/4, addr, m_zeusbase[0x50]); + memset(&m_frameColor[addr], m_fill_color, numBytes); + memset(&m_frameDepth[addr], m_fill_depth, numBytes/2); } - else if ((m_zeusbase[0x5e] >> 16) != 0xF208) { + else if ((m_zeusbase[0x5e] >> 16) != 0xf208 && !(m_zeusbase[0x5e] & 0xffff)) { /* If 0x5e==0xf20a0000 (atlantis) or 0xf20d0000 (the grid) then process the read/write now */ /* m_zeusbase[0x5e]: @@ -542,39 +552,18 @@ void zeus2_device::zeus2_register_update(offs_t offset, UINT32 oldval, int logit bit 5: unknown, currently used to specify ordering, but this is suspect bit 6: enable autoincrement on write through */ - if (m_zeusbase[0x50] == 0x00890000) + //if (m_zeusbase[0x50] == 0x00890000) + if ((m_zeusbase[0x50] == 0x00890000) || (m_zeusbase[0x50] == 0x00e90000)) { - void *dest = waveram1_ptr_from_expanded_addr(m_zeusbase[0x51]); - WAVERAM_WRITE32(dest, 0, m_zeusbase[0x58]); - if (m_zeusbase[0x5e] & 0x20) - WAVERAM_WRITE32(dest, 1, m_zeusbase[0x5a]); - else - { - WAVERAM_WRITE32(dest, 1, m_zeusbase[0x59]); - WAVERAM_WRITE32(dest, 2, m_zeusbase[0x5a]); - } - - if (m_zeusbase[0x5e] & 0x40) - { - m_zeusbase[0x51]++; - m_zeusbase[0x51] += (m_zeusbase[0x51] & 0x200) << 7; - m_zeusbase[0x51] &= ~0xfe00; - } + frame_write(); } else if (m_zeusbase[0x50] == 0x00720000) { /* Do the read */ - const void *src = waveram1_ptr_from_expanded_addr(m_zeusbase[0x51]); - m_zeusbase[0x58] = WAVERAM_READ32(src, 0); - m_zeusbase[0x59] = WAVERAM_READ32(src, 1); - m_zeusbase[0x5a] = WAVERAM_READ32(src, 2); - - if (m_zeusbase[0x5e] & 0x40) - { - m_zeusbase[0x51]++; - m_zeusbase[0x51] += (m_zeusbase[0x51] & 0x200) << 7; - m_zeusbase[0x51] &= ~0xfe00; - } + frame_read(); } + /* make sure we log anything else */ + else if (1 || logit) + logerror("\t[50]=%08X [5E]=%08X\n", m_zeusbase[0x50], m_zeusbase[0x5e]); } break; case 0x51: @@ -586,36 +575,26 @@ void zeus2_device::zeus2_register_update(offs_t offset, UINT32 oldval, int logit /* this is the address, except in read mode, where it latches values */ if ((m_zeusbase[0x5e] & 0x10) || (m_zeusbase[0x50] == 0x00a20000)) - { - const void *src = waveram1_ptr_from_expanded_addr(oldval); + { m_zeusbase[0x51] = oldval; - m_zeusbase[0x58] = WAVERAM_READ32(src, 0); - m_zeusbase[0x59] = WAVERAM_READ32(src, 1); - m_zeusbase[0x5a] = WAVERAM_READ32(src, 2); - - if (m_zeusbase[0x5e] & 0x40) - { - m_zeusbase[0x51]++; - m_zeusbase[0x51] += (m_zeusbase[0x51] & 0x200) << 7; - m_zeusbase[0x51] &= ~0xfe00; - } + frame_read(); } break; case 0x57: /* thegrid uses this to write either left or right halves of pixels */ - if (m_zeusbase[0x50] == 0x00e90000) - { - void *dest = waveram1_ptr_from_expanded_addr(m_zeusbase[0x51]); - if (m_zeusbase[0x57] & 1) - WAVERAM_WRITE32(dest, 0, m_zeusbase[0x58]); - if (m_zeusbase[0x57] & 4) - WAVERAM_WRITE32(dest, 1, m_zeusbase[0x59]); - } + //if (m_zeusbase[0x50] == 0x00e90000) + //{ + // UINT32 addr = frame_addr_from_reg51(); + // if (m_zeusbase[0x57] & 1) + // m_frameColor[addr] = m_zeusbase[0x58]; + // if (m_zeusbase[0x57] & 4) + // m_frameColor[addr+1] = m_zeusbase[0x59]; + //} - /* make sure we log anything else */ - else if (logit) - logerror("\t[50]=%08X [5E]=%08X\n", m_zeusbase[0x50], m_zeusbase[0x5e]); + ///* make sure we log anything else */ + //else if (logit) + // logerror("\t[50]=%08X [5E]=%08X\n", m_zeusbase[0x50], m_zeusbase[0x5e]); break; case 0x58: @@ -633,23 +612,8 @@ void zeus2_device::zeus2_register_update(offs_t offset, UINT32 oldval, int logit bit 6: enable autoincrement on write through */ if ((m_zeusbase[0x5e] & 0x08) && (offset & 3) == (m_zeusbase[0x5e] & 3)) - { - void *dest = waveram1_ptr_from_expanded_addr(m_zeusbase[0x51]); - WAVERAM_WRITE32(dest, 0, m_zeusbase[0x58]); - if (m_zeusbase[0x5e] & 0x20) - WAVERAM_WRITE32(dest, 1, m_zeusbase[0x5a]); - else - { - WAVERAM_WRITE32(dest, 1, m_zeusbase[0x59]); - WAVERAM_WRITE32(dest, 2, m_zeusbase[0x5a]); - } - - if (m_zeusbase[0x5e] & 0x40) - { - m_zeusbase[0x51]++; - m_zeusbase[0x51] += (m_zeusbase[0x51] & 0x200) << 7; - m_zeusbase[0x51] &= ~0xfe00; - } + { + frame_write(); } } @@ -688,13 +652,10 @@ if (subregdata_count[which] < 256) } } #endif + m_renderRegs[which] = value; switch (which) { - case 0x04: - zeus_renderbase = waveram1_ptr_from_expanded_addr(value << 16); - break; - case 0x05: zeus_texbase = value % (WAVERAM0_HEIGHT * WAVERAM0_WIDTH); break; @@ -757,20 +718,20 @@ int zeus2_device::zeus2_fifo_process(const UINT32 *data, int numwords) return FALSE; /* extract the matrix from the raw data */ - zeus_matrix[0][0] = tms3203x_device::fp_to_float(data[dataoffs + 1]); - zeus_matrix[0][1] = tms3203x_device::fp_to_float(data[dataoffs + 2]); - zeus_matrix[0][2] = tms3203x_device::fp_to_float(data[dataoffs + 3]); - zeus_matrix[1][0] = tms3203x_device::fp_to_float(data[dataoffs + 4]); - zeus_matrix[1][1] = tms3203x_device::fp_to_float(data[dataoffs + 5]); - zeus_matrix[1][2] = tms3203x_device::fp_to_float(data[dataoffs + 6]); - zeus_matrix[2][0] = tms3203x_device::fp_to_float(data[dataoffs + 7]); - zeus_matrix[2][1] = tms3203x_device::fp_to_float(data[dataoffs + 8]); - zeus_matrix[2][2] = tms3203x_device::fp_to_float(data[dataoffs + 9]); + zeus_matrix[0][0] = convert_float(data[dataoffs + 1]); + zeus_matrix[0][1] = convert_float(data[dataoffs + 2]); + zeus_matrix[0][2] = convert_float(data[dataoffs + 3]); + zeus_matrix[1][0] = convert_float(data[dataoffs + 4]); + zeus_matrix[1][1] = convert_float(data[dataoffs + 5]); + zeus_matrix[1][2] = convert_float(data[dataoffs + 6]); + zeus_matrix[2][0] = convert_float(data[dataoffs + 7]); + zeus_matrix[2][1] = convert_float(data[dataoffs + 8]); + zeus_matrix[2][2] = convert_float(data[dataoffs + 9]); /* extract the translation point from the raw data */ - zeus_point[0] = tms3203x_device::fp_to_float(data[dataoffs + 10]); - zeus_point[1] = tms3203x_device::fp_to_float(data[dataoffs + 11]); - zeus_point[2] = tms3203x_device::fp_to_float(data[dataoffs + 12]); + zeus_point[0] = convert_float(data[dataoffs + 10]); + zeus_point[1] = convert_float(data[dataoffs + 11]); + zeus_point[2] = convert_float(data[dataoffs + 12]); if (log_fifo) { @@ -795,9 +756,9 @@ int zeus2_device::zeus2_fifo_process(const UINT32 *data, int numwords) return FALSE; /* extract the translation point from the raw data */ - zeus_point[0] = tms3203x_device::fp_to_float(data[1]); - zeus_point[1] = tms3203x_device::fp_to_float(data[2]); - zeus_point[2] = tms3203x_device::fp_to_float(data[3]); + zeus_point[0] = convert_float(data[1]); + zeus_point[1] = convert_float(data[2]); + zeus_point[2] = convert_float(data[3]); if (log_fifo) { @@ -817,23 +778,14 @@ int zeus2_device::zeus2_fifo_process(const UINT32 *data, int numwords) { log_fifo_command(data, numwords, " -- unknown control + hack clear screen\n"); logerror("\t\tvector %8.2f %8.2f %8.5f\n", - (double) tms3203x_device::fp_to_float(data[1]), - (double) tms3203x_device::fp_to_float(data[2]), - (double) tms3203x_device::fp_to_float(data[3])); + (double) convert_float(data[1]), + (double) convert_float(data[2]), + (double) convert_float(data[3])); /* extract the translation point from the raw data */ - zeus_point2[0] = tms3203x_device::fp_to_float(data[1]); - zeus_point2[1] = tms3203x_device::fp_to_float(data[2]); - zeus_point2[2] = tms3203x_device::fp_to_float(data[3]); - } - { - /* not right -- just a hack */ - if (0) { - int x, y; - for (y = zeus_cliprect.min_y; y <= zeus_cliprect.max_y; y++) - for (x = zeus_cliprect.min_x; x <= zeus_cliprect.max_x; x++) - waveram_plot_depth(y, x, 0, 0x7fff); - } + zeus_point2[0] = convert_float(data[1]); + zeus_point2[1] = convert_float(data[2]); + zeus_point2[2] = convert_float(data[3]); } break; @@ -851,7 +803,7 @@ int zeus2_device::zeus2_fifo_process(const UINT32 *data, int numwords) zeus2_draw_model(data[1], data[0] & 0x3fff, log_fifo); break; - // 0x2d; ??? (atlantis) + // 0x2d; direct render quad (atlantis) case 0x2d: if (numwords < 2) return FALSE; @@ -860,10 +812,15 @@ int zeus2_device::zeus2_fifo_process(const UINT32 *data, int numwords) //zeus2_draw_model(data[1], data[0] & 0xff, log_fifo); break; - /* 0x31: sync pipeline? (thegrid) */ - /* 0x32: sync pipeline? (crusnexo) */ // 0x25 ?? (atlantis) case 0x25: + if (log_fifo) + log_fifo_command(data, numwords, "\n"); + //zeus_quad_size = 10; + break; + + /* 0x31: sync pipeline? (thegrid) */ + /* 0x32: sync pipeline? (crusnexo) */ case 0x31: case 0x32: if (log_fifo) @@ -936,7 +893,7 @@ void zeus2_device::zeus2_draw_model(UINT32 baseaddr, UINT16 count, int logit) /* if this is enough, process the command */ cmd = databuffer[0] >> 24; - if (cmd == 0x38) + if ((cmd == 0x38) || (cmd == 0x2d)) countneeded = quadsize; if (databufcount == countneeded) { @@ -970,6 +927,7 @@ void zeus2_device::zeus2_draw_model(UINT32 baseaddr, UINT16 count, int logit) logerror("sync?\n"); break; + case 0x29: // atlantis case 0x35: /* thegrid */ case 0x36: /* crusnexo */ if (logit) @@ -977,6 +935,11 @@ void zeus2_device::zeus2_draw_model(UINT32 baseaddr, UINT16 count, int logit) zeus2_register32_w((databuffer[0] >> 16) & 0x7f, databuffer[1], logit); break; + case 0x2d: // atlantis + texoffs = databuffer[1]; + poly->zeus2_draw_quad(&databuffer[1], texoffs, logit); + break; + case 0x38: /* crusnexo/thegrid */ poly->zeus2_draw_quad(databuffer, texoffs, logit); break; @@ -1179,11 +1142,13 @@ void zeus2_renderer::zeus2_draw_quad(const UINT32 *databuffer, UINT32 texoffs, i case 0x05d: /* crusnexo: background, road */ case 0x0dd: /* crusnexo: license plate letters */ case 0x11d: /* crusnexo: LHS of score bar */ + case 0x14d: // atlantis case 0x15d: /* crusnexo */ case 0x85d: /* crusnexo */ case 0x95d: /* crusnexo */ case 0xc1d: /* crusnexo */ case 0xc5d: /* crusnexo */ + case 0x18e: // atlantis extra.texwidth = 256; break; @@ -1191,16 +1156,20 @@ void zeus2_renderer::zeus2_draw_quad(const UINT32 *databuffer, UINT32 texoffs, i case 0x0d9: /* crusnexo */ case 0x119: /* crusnexo: license plates */ case 0x159: /* crusnexo */ + case 0x18a: // atlantis extra.texwidth = 128; break; case 0x055: /* crusnexo */ + case 0x145: // atlantis case 0x155: /* crusnexo */ extra.texwidth = 64; break; case 0x000: // thegrid guess case 0x120: // thegrid guess + case 0x140: // atlantis + case 0x141: // atlantis extra.texwidth = 32; break; @@ -1257,13 +1226,16 @@ void zeus2_renderer::render_poly_8bit(INT32 scanline, const extent_t& extent, co int texwidth = object.texwidth; int x; + UINT32 addr = m_state->frame_addr_from_xy(0, scanline, true); + UINT16 *depthptr = &m_state->m_frameDepth[addr]; + UINT32 *colorptr = &m_state->m_frameColor[addr]; for (x = extent.startx; x < extent.stopx; x++) { - UINT16 *depthptr = WAVERAM_PTRDEPTH(m_state->zeus_renderbase, scanline, x); + //UINT16 *depthptr = WAVERAM_PTRDEPTH(m_state->zeus_renderbase, scanline, x); INT32 depth = (curz >> 16) + object.zoffset; //if (depth > 0x7fff) depth = 0x7fff; if (depth > 0xffff) depth = 0xffff; - if (depth >= 0 && depth <= *depthptr) + if (depth >= 0 && depth <= depthptr[x]) { int u0 = (curu >> 8);// & (texwidth - 1); int v0 = (curv >> 8);// & 255; @@ -1284,8 +1256,10 @@ void zeus2_renderer::render_poly_8bit(INT32 scanline, const extent_t& extent, co color2 = ((color2 & 0x7c00) << 9) | ((color2 & 0x3e0) << 6) | ((color2 & 0x1f) << 3); color3 = ((color3 & 0x7c00) << 9) | ((color3 & 0x3e0) << 6) | ((color3 & 0x1f) << 3); rgb_t filtered = rgbaint_t::bilinear_filter(color0, color1, color2, color3, curu, curv); - WAVERAM_WRITEPIX(m_state->zeus_renderbase, scanline, x, filtered); - *depthptr = depth; + //WAVERAM_WRITEPIX(m_state->zeus_renderbase, scanline, x, filtered); + //*depthptr = depth; + colorptr[x] = filtered; + depthptr[x] = depth; } } diff --git a/src/devices/video/zeus2.h b/src/devices/video/zeus2.h index cc147654e71..b89fe1f82e4 100644 --- a/src/devices/video/zeus2.h +++ b/src/devices/video/zeus2.h @@ -106,6 +106,9 @@ typedef zeus2_renderer::extent_t z2_poly_extent; #define MCFG_ZEUS2_IRQ_CB(_devcb) \ devcb = &zeus2_device::set_irq_callback(*device, DEVCB_##_devcb); +#define MCFG_ZEUS2_FLOAT_MODE(_mode) \ + downcast(device)->set_float_mode(_mode); + class zeus2_device : public device_t { public: @@ -124,11 +127,14 @@ public: devcb_write_line m_vblank; devcb_write_line m_irq; + void set_float_mode(int mode) { m_ieee754_float = mode; } + int m_ieee754_float; // Used to switch to using IEEE754 floating point format + UINT32 m_zeusbase[0x80]; + UINT32 m_renderRegs[0x100]; zeus2_renderer* poly; - void *zeus_renderbase; rectangle zeus_cliprect; float zeus_matrix[3][3]; @@ -139,6 +145,9 @@ public: int zeus_quad_size; UINT32 *waveram[2]; + std::unique_ptr m_frameColor; + std::unique_ptr m_frameDepth; + emu_timer *int_timer; emu_timer *vblank_timer; int m_yScale; @@ -164,15 +173,13 @@ private: /************************************* * Member variables *************************************/ - - UINT8 log_fifo; UINT32 zeus_fifo[20]; UINT8 zeus_fifo_words; UINT32 m_fill_color; - UINT16 m_fill_depth; + UINT32 m_fill_depth; #if TRACK_REG_USAGE struct reg_info @@ -193,6 +200,75 @@ public: /************************************* * Inlines for block addressing *************************************/ + inline float convert_float(UINT32 val) + { + if (m_ieee754_float) + return reinterpret_cast(val); + else + return tms3203x_device::fp_to_float(val); + } + + inline UINT32 frame_addr_from_xy(UINT32 x, UINT32 y, bool render) + { + UINT32 addr = render ? frame_addr_from_expanded_addr(m_renderRegs[0x4] << 16) + : frame_addr_from_expanded_addr(m_zeusbase[0x38]); + addr += ((y * WAVERAM1_WIDTH) << (1 - m_yScale)) + x; + return addr; + } + + // Convert 0xRRRRCCCC to frame buffer addresss + inline UINT32 frame_addr_from_expanded_addr(UINT32 addr) + { + return (((addr & 0x3ff0000) >> (16 - 9 + m_yScale)) | (addr & 0x1ff)) << 1; + } + + // Convert Physical 0xRRRRCCCC to frame buffer addresss + // Based on address reg 51 (no scaling) + inline UINT32 frame_addr_from_reg51() + { + UINT32 addr = (((m_zeusbase[0x51] & 0x3ff0000) >> (16 - 9)) | (m_zeusbase[0x51] & 0x1ff)) << 1; + return addr; + } + + // Read from frame buffer + inline void frame_read() + { + UINT32 addr = frame_addr_from_reg51(); + m_zeusbase[0x58] = m_frameColor[addr]; + m_zeusbase[0x59] = m_frameColor[addr + 1]; + m_zeusbase[0x5a] = *(UINT32*)&m_frameDepth[addr]; + if (m_zeusbase[0x5e] & 0x40) + { + m_zeusbase[0x51]++; + m_zeusbase[0x51] += (m_zeusbase[0x51] & 0x200) << 7; + m_zeusbase[0x51] &= ~0xfe00; + } + } + + // Write to frame buffer + inline void frame_write() + { + UINT32 addr = frame_addr_from_reg51(); + if (m_zeusbase[0x57] & 0x1) + m_frameColor[addr] = m_zeusbase[0x58]; + if (m_zeusbase[0x5e] & 0x20) { + if (m_zeusbase[0x57] & 0x4) + m_frameColor[addr + 1] = m_zeusbase[0x5a]; + } else + { + if (m_zeusbase[0x57] & 0x4) + m_frameColor[addr + 1] = m_zeusbase[0x59]; + if (m_zeusbase[0x57] & 0x10) + *(UINT32*)&m_frameDepth[addr] = m_zeusbase[0x5a]; + } + + if (m_zeusbase[0x5e] & 0x40) + { + m_zeusbase[0x51]++; + m_zeusbase[0x51] += (m_zeusbase[0x51] & 0x200) << 7; + m_zeusbase[0x51] &= ~0xfe00; + } + } inline void *waveram0_ptr_from_expanded_addr(UINT32 addr) { @@ -226,6 +302,7 @@ public: } #endif +#ifdef UNUSED_FUNCTION inline void waveram_plot_depth(int y, int x, UINT32 color, UINT16 depth) { if (zeus_cliprect.contains(x, y)) @@ -234,6 +311,7 @@ public: WAVERAM_WRITEDEPTH(zeus_renderbase, y, x, depth); } } +#endif #ifdef UNUSED_FUNCTION inline void waveram_plot_check_depth(int y, int x, UINT32 color, UINT16 depth) diff --git a/src/mame/drivers/atlantis.cpp b/src/mame/drivers/atlantis.cpp index 802704b8e43..e18abf06d1e 100644 --- a/src/mame/drivers/atlantis.cpp +++ b/src/mame/drivers/atlantis.cpp @@ -370,7 +370,7 @@ WRITE32_MEMBER(atlantis_state::status_leds_w) case 0xfe: digit = '-'; break; case 0xff: digit = 'Z'; break; } - popmessage("LED: %c", digit); + //popmessage("LED: %c", digit); osd_printf_debug("%06X: status_leds_w digit: %c %08x = %02x\n", machine().device("maincpu")->safe_pc(), digit, offset, data); logerror("%06X: status_leds_w digit: %c %08x = %02x\n", machine().device("maincpu")->safe_pc(), digit, offset, data); } @@ -818,6 +818,7 @@ static MACHINE_CONFIG_START( mwskins, atlantis_state ) /* video hardware */ MCFG_DEVICE_ADD("zeus2", ZEUS2, ZEUS2_VIDEO_CLOCK) + MCFG_ZEUS2_FLOAT_MODE(1) MCFG_ZEUS2_IRQ_CB(WRITELINE(atlantis_state, zeus_irq)) MCFG_ZEUS2_VBLANK_CB(WRITELINE(atlantis_state, vblank_irq))