mirror of
https://github.com/holub/mame
synced 2025-04-26 02:07:14 +03:00
zeus2: Re-organize frame buffer ram and add IEEE754 floating point conversion (nw)
This commit is contained in:
parent
200fc9859a
commit
a96049fb14
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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)
|
||||
|
@ -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))
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user