zeus2: Re-organize frame buffer ram and add IEEE754 floating point conversion (nw)

This commit is contained in:
Ted Green 2016-06-21 08:38:28 -06:00
parent 200fc9859a
commit a96049fb14
3 changed files with 214 additions and 161 deletions

View File

@ -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::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<UINT32[]>(WAVERAM1_WIDTH * WAVERAM1_HEIGHT * 2);
m_frameDepth = std::make_unique<UINT16[]>(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;
}
}

View File

@ -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<zeus2_device *>(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<UINT32[]> m_frameColor;
std::unique_ptr<UINT16[]> 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<float&>(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)

View File

@ -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))