8-bit texture upload byte selection (thanks to Ville; but not tested yet); code cleanup

This commit is contained in:
Bart Trzynadlowski 2016-04-04 03:42:26 +00:00
parent d155fbd6e4
commit d8aefa421d
2 changed files with 1222 additions and 1232 deletions

View file

@ -41,8 +41,8 @@
* The render currently cannot cope with this. * The render currently cannot cope with this.
*/ */
#include <cstring>
#include "Supermodel.h" #include "Supermodel.h"
#include <cstring>
// Macros that divide memory regions into pages and mark them as dirty when they are written to // Macros that divide memory regions into pages and mark them as dirty when they are written to
#define PAGE_WIDTH 12 #define PAGE_WIDTH 12
@ -150,7 +150,7 @@ void CReal3D::EndVBlank(void)
error = false; // clear error (just needs to be done once per frame) error = false; // clear error (just needs to be done once per frame)
} }
UINT32 CReal3D::SyncSnapshots(void) uint32_t CReal3D::SyncSnapshots(void)
{ {
// Update read-only copy of command port flag // Update read-only copy of command port flag
commandPortWrittenRO = commandPortWritten; commandPortWrittenRO = commandPortWritten;
@ -167,7 +167,7 @@ UINT32 CReal3D::SyncSnapshots(void)
return UpdateSnapshots(false); return UpdateSnapshots(false);
} }
UINT32 CReal3D::UpdateSnapshot(bool copyWhole, UINT8 *src, UINT8 *dst, unsigned size, UINT8 *dirty) uint32_t CReal3D::UpdateSnapshot(bool copyWhole, uint8_t *src, uint8_t *dst, unsigned size, uint8_t *dirty)
{ {
unsigned dirtySize = DIRTY_SIZE(size); unsigned dirtySize = DIRTY_SIZE(size);
if (copyWhole) if (copyWhole)
@ -180,12 +180,12 @@ UINT32 CReal3D::UpdateSnapshot(bool copyWhole, UINT8 *src, UINT8 *dst, unsigned
else else
{ {
// Otherwise, loop through dirty pages array to find out what needs to be updated and copy only those parts // Otherwise, loop through dirty pages array to find out what needs to be updated and copy only those parts
UINT32 copied = 0; uint32_t copied = 0;
UINT8 *pSrc = src; uint8_t *pSrc = src;
UINT8 *pDst = dst; uint8_t *pDst = dst;
for (unsigned i = 0; i < dirtySize; i++) for (unsigned i = 0; i < dirtySize; i++)
{ {
UINT8 d = dirty[i]; uint8_t d = dirty[i];
if (d) if (d)
{ {
for (unsigned j = 0; j < 8; j++) for (unsigned j = 0; j < 8; j++)
@ -193,7 +193,7 @@ UINT32 CReal3D::UpdateSnapshot(bool copyWhole, UINT8 *src, UINT8 *dst, unsigned
if (d&1) if (d&1)
{ {
// If not at very end of region, then copy an extra 4 bytes to allow for a possible 32-bit overlap // If not at very end of region, then copy an extra 4 bytes to allow for a possible 32-bit overlap
UINT32 toCopy = (i < dirtySize - 1 || j < 7 ? PAGE_SIZE + 4 : PAGE_SIZE); uint32_t toCopy = (i < dirtySize - 1 || j < 7 ? PAGE_SIZE + 4 : PAGE_SIZE);
memcpy(pDst, pSrc, toCopy); memcpy(pDst, pSrc, toCopy);
copied += toCopy; copied += toCopy;
} }
@ -213,13 +213,13 @@ UINT32 CReal3D::UpdateSnapshot(bool copyWhole, UINT8 *src, UINT8 *dst, unsigned
} }
} }
UINT32 CReal3D::UpdateSnapshots(bool copyWhole) uint32_t CReal3D::UpdateSnapshots(bool copyWhole)
{ {
// Update all memory region snapshots // Update all memory region snapshots
UINT32 cullLoCopied = UpdateSnapshot(copyWhole, (UINT8*)cullingRAMLo, (UINT8*)cullingRAMLoRO, 0x400000, cullingRAMLoDirty); uint32_t cullLoCopied = UpdateSnapshot(copyWhole, (uint8_t*)cullingRAMLo, (uint8_t*)cullingRAMLoRO, 0x400000, cullingRAMLoDirty);
UINT32 cullHiCopied = UpdateSnapshot(copyWhole, (UINT8*)cullingRAMHi, (UINT8*)cullingRAMHiRO, 0x100000, cullingRAMHiDirty); uint32_t cullHiCopied = UpdateSnapshot(copyWhole, (uint8_t*)cullingRAMHi, (uint8_t*)cullingRAMHiRO, 0x100000, cullingRAMHiDirty);
UINT32 polyCopied = UpdateSnapshot(copyWhole, (UINT8*)polyRAM, (UINT8*)polyRAMRO, 0x400000, polyRAMDirty); uint32_t polyCopied = UpdateSnapshot(copyWhole, (uint8_t*)polyRAM, (uint8_t*)polyRAMRO, 0x400000, polyRAMDirty);
UINT32 textureCopied = UpdateSnapshot(copyWhole, (UINT8*)textureRAM, (UINT8*)textureRAMRO, 0x800000, textureRAMDirty); uint32_t textureCopied = UpdateSnapshot(copyWhole, (uint8_t*)textureRAM, (uint8_t*)textureRAMRO, 0x800000, textureRAMDirty);
//printf("Read3D copied - cullLo:%4uK, cullHi:%4uK, poly:%4uK, texture:%4uK\n", cullLoCopied / 1024, cullHiCopied / 1024, polyCopied / 1024, textureCopied / 1024); //printf("Read3D copied - cullLo:%4uK, cullHi:%4uK, poly:%4uK, texture:%4uK\n", cullLoCopied / 1024, cullHiCopied / 1024, polyCopied / 1024, textureCopied / 1024);
return cullLoCopied + cullHiCopied + polyCopied + textureCopied; return cullLoCopied + cullHiCopied + polyCopied + textureCopied;
} }
@ -267,7 +267,7 @@ void CReal3D::DMACopy(void)
{ {
while (dmaLength != 0) while (dmaLength != 0)
{ {
UINT32 data = Bus->Read32(dmaSrc); uint32_t data = Bus->Read32(dmaSrc);
Bus->Write32(dmaDest, FLIPENDIAN32(data)); Bus->Write32(dmaDest, FLIPENDIAN32(data));
dmaSrc += 4; dmaSrc += 4;
dmaDest += 4; dmaDest += 4;
@ -286,7 +286,7 @@ void CReal3D::DMACopy(void)
} }
} }
UINT8 CReal3D::ReadDMARegister8(unsigned reg) uint8_t CReal3D::ReadDMARegister8(unsigned reg)
{ {
switch (reg) switch (reg)
{ {
@ -302,7 +302,7 @@ UINT8 CReal3D::ReadDMARegister8(unsigned reg)
return 0; return 0;
} }
void CReal3D::WriteDMARegister8(unsigned reg, UINT8 data) void CReal3D::WriteDMARegister8(unsigned reg, uint8_t data)
{ {
switch (reg) switch (reg)
{ {
@ -323,7 +323,7 @@ void CReal3D::WriteDMARegister8(unsigned reg, UINT8 data)
//DebugLog("Real3D: WriteDMARegister8: reg=%X, data=%02X\n", reg, data); //DebugLog("Real3D: WriteDMARegister8: reg=%X, data=%02X\n", reg, data);
} }
UINT32 CReal3D::ReadDMARegister32(unsigned reg) uint32_t CReal3D::ReadDMARegister32(unsigned reg)
{ {
switch (reg) switch (reg)
{ {
@ -337,7 +337,7 @@ UINT32 CReal3D::ReadDMARegister32(unsigned reg)
return 0; return 0;
} }
void CReal3D::WriteDMARegister32(unsigned reg, UINT32 data) void CReal3D::WriteDMARegister32(unsigned reg, uint32_t data)
{ {
switch (reg) switch (reg)
{ {
@ -408,12 +408,9 @@ static const int tapFSM[][2] = // finite state machine, each state can lead to
* Inserts a bit into an arbitrarily long bit field. Bit 0 is assumed to be * Inserts a bit into an arbitrarily long bit field. Bit 0 is assumed to be
* the MSB of the first byte in the buffer. * the MSB of the first byte in the buffer.
*/ */
void CReal3D::InsertBit(UINT8 *buf, unsigned bitNum, unsigned bit) void CReal3D::InsertBit(uint8_t *buf, unsigned bitNum, unsigned bit)
{ {
unsigned bitInByte; unsigned bitInByte = 7 - (bitNum & 7);
bitInByte = 7 - (bitNum & 7);
buf[bitNum / 8] &= ~(1 << bitInByte); buf[bitNum / 8] &= ~(1 << bitInByte);
buf[bitNum / 8] |= (bit << bitInByte); buf[bitNum / 8] |= (bit << bitInByte);
} }
@ -423,11 +420,9 @@ void CReal3D::InsertBit(UINT8 *buf, unsigned bitNum, unsigned bit)
* *
* Inserts a 32-bit ID code into the ID bit field. * Inserts a 32-bit ID code into the ID bit field.
*/ */
void CReal3D::InsertID(UINT32 id, unsigned startBit) void CReal3D::InsertID(uint32_t id, unsigned startBit)
{ {
int i; for (int i = 31; i >= 0; i--)
for (i = 31; i >= 0; i--)
InsertBit(tapID, startBit++, (id >> i) & 1); InsertBit(tapID, startBit++, (id >> i) & 1);
} }
@ -438,14 +433,12 @@ void CReal3D::InsertID(UINT32 id, unsigned startBit)
* the number of bits must be specified. The bit shifted out of the LSB is * the number of bits must be specified. The bit shifted out of the LSB is
* returned. * returned.
*/ */
unsigned CReal3D::Shift(UINT8 *data, unsigned numBits) unsigned CReal3D::Shift(uint8_t *data, unsigned numBits)
{ {
unsigned i;
unsigned shiftOut, shiftIn;
// This loop takes care of all the fully-filled bytes // This loop takes care of all the fully-filled bytes
shiftIn = 0; unsigned shiftIn = 0;
shiftOut = 0; unsigned shiftOut = 0;
size_t i;
for (i = 0; i < numBits / 8; i++) for (i = 0; i < numBits / 8; i++)
{ {
shiftOut = data[i] & 1; shiftOut = data[i] & 1;
@ -477,13 +470,9 @@ void CReal3D::WriteTAP(unsigned tck, unsigned tms, unsigned tdi, unsigned trst)
// Go to next state // Go to next state
tapState = tapFSM[tapState][tms]; tapState = tapFSM[tapState][tms];
switch (tapState) switch (tapState)
{ {
case 3: // Capture-DR case 3: // Capture-DR
//printf("TAP: Capture-DR\n");
//bit = 0;
/* /*
* Read ASIC IDs. * Read ASIC IDs.
* *
@ -532,31 +521,22 @@ void CReal3D::WriteTAP(unsigned tck, unsigned tms, unsigned tdi, unsigned trst)
InsertID(0x316C6057, 1 + 4 * 32 + 1); InsertID(0x316C6057, 1 + 4 * 32 + 1);
InsertID(0x316C6057, 1 + 5 * 32 + 1); InsertID(0x316C6057, 1 + 5 * 32 + 1);
} }
break; break;
case 4: // Shift-DR case 4: // Shift-DR
tapTDO = Shift(tapID, tapIDSize); tapTDO = Shift(tapID, tapIDSize);
//printf("TAP: Shift-DR Bit %d\n", bit++); //printf("TAP: Shift-DR Bit %d\n", bit++);
break; break;
case 10: // Capture-IR case 10: // Capture-IR
// Load lower 2 bits with 01 as per IEEE 1149.1-1990 // Load lower 2 bits with 01 as per IEEE 1149.1-1990
tapIR = 1; tapIR = 1;
break; break;
case 11: // Shift-IR case 11: // Shift-IR
// Shift IR towards output and load in new data from TDI // Shift IR towards output and load in new data from TDI
tapTDO = tapIR & 1; // shift LSB to output tapTDO = tapIR & 1; // shift LSB to output
tapIR >>= 1; tapIR >>= 1;
tapIR |= ((UINT64) tdi << 45); tapIR |= ((uint64_t) tdi << 45);
break; break;
case 15: // Update-IR case 15: // Update-IR
/* /*
* Latch IR (technically, this should occur on the falling edge of * Latch IR (technically, this should occur on the falling edge of
* TCK) * TCK)
@ -565,7 +545,6 @@ void CReal3D::WriteTAP(unsigned tck, unsigned tms, unsigned tdi, unsigned trst)
tapCurrentInstruction = tapIR; tapCurrentInstruction = tapIR;
//printf("TAP: Update-IR %XLL\n", tapCurrentInstruction); //printf("TAP: Update-IR %XLL\n", tapCurrentInstruction);
break; break;
default: default:
break; break;
} }
@ -623,22 +602,28 @@ static const unsigned decode[64] =
50,51,54,55,58,59,62,63 50,51,54,55,58,59,62,63
}; };
void CReal3D::StoreTexture(unsigned xPos, unsigned yPos, unsigned width, unsigned height, UINT16 *texData, unsigned bytesPerTexel) static void StoreTexelByte(uint16_t *texel, size_t byteSelect, uint8_t byte)
{ {
unsigned x, y, xx, yy, destOffset; if ((byteSelect & 1)) // write to LSB
*texel = (*texel & 0xFF00) | byte;
if ((byteSelect & 2)) // write to MSB
*texel = (*texel & 0x00FF) | (uint16_t(byte) << 8);
}
if (bytesPerTexel == 2) // 16-bit textures void CReal3D::StoreTexture(unsigned xPos, unsigned yPos, unsigned width, unsigned height, uint16_t *texData, uint32_t header)
{
if ((header & 0x00800000)) // 16-bit textures
{ {
// Outer 2 loops: 8x8 tiles // Outer 2 loops: 8x8 tiles
for (y = yPos; y < (yPos+height); y += 8) for (size_t y = yPos; y < (yPos+height); y += 8)
{ {
for (x = xPos; x < (xPos+width); x += 8) for (size_t x = xPos; x < (xPos+width); x += 8)
{ {
// Inner 2 loops: 8x8 texels for the current tile // Inner 2 loops: 8x8 texels for the current tile
destOffset = y*2048+x; size_t destOffset = y*2048+x;
for (yy = 0; yy < 8; yy++) for (size_t yy = 0; yy < 8; yy++)
{ {
for (xx = 0; xx < 8; xx++) for (size_t xx = 0; xx < 8; xx++)
{ {
if (g_Config.gpuMultiThreaded) if (g_Config.gpuMultiThreaded)
MARK_DIRTY(textureRAMDirty, destOffset * 2); MARK_DIRTY(textureRAMDirty, destOffset * 2);
@ -659,24 +644,31 @@ void CReal3D::StoreTexture(unsigned xPos, unsigned yPos, unsigned width, unsigne
* swapped. * swapped.
*/ */
size_t byteSelect = (header>>21)&3; // which byte to unpack to
if (byteSelect == 3) // write to both?
DebugLog("Observed 8-bit texture with byte_select=3!");
// Outer 2 loops: 8x8 tiles // Outer 2 loops: 8x8 tiles
for (y = yPos; y < (yPos+height); y += 8) for (size_t y = yPos; y < (yPos+height); y += 8)
{ {
for (x = xPos; x < (xPos+width); x += 8) for (size_t x = xPos; x < (xPos+width); x += 8)
{ {
// Inner 2 loops: 8x8 texels for the current tile // Inner 2 loops: 8x8 texels for the current tile
destOffset = y*2048+x; size_t destOffset = y*2048+x;
for (yy = 0; yy < 8; yy++) for (size_t yy = 0; yy < 8; yy++)
{ {
for (xx = 0; xx < 8; xx += 2) for (size_t xx = 0; xx < 8; xx += 2)
{ {
uint8_t byte1 = texData[decode[(yy^1)*8+((xx+0)^1)]/2]>>8;
uint8_t byte2 = texData[decode[(yy^1)*8+((xx+1)^1)]/2]&0xFF;
if (g_Config.gpuMultiThreaded) if (g_Config.gpuMultiThreaded)
MARK_DIRTY(textureRAMDirty, destOffset * 2); MARK_DIRTY(textureRAMDirty, destOffset * 2);
textureRAM[destOffset++] = texData[decode[(yy^1)*8+((xx+0)^1)]/2]>>8; StoreTexelByte(&textureRAM[destOffset], byteSelect, byte1);
++destOffset;
if (g_Config.gpuMultiThreaded) if (g_Config.gpuMultiThreaded)
MARK_DIRTY(textureRAMDirty, destOffset * 2); MARK_DIRTY(textureRAMDirty, destOffset * 2);
textureRAM[destOffset++] = texData[decode[(yy^1)*8+((xx+1)^1)]/2]&0xFF; StoreTexelByte(&textureRAM[destOffset], byteSelect, byte2);
++destOffset;
} }
destOffset += 2048-8; destOffset += 2048-8;
} }
@ -702,20 +694,18 @@ void CReal3D::StoreTexture(unsigned xPos, unsigned yPos, unsigned width, unsigne
} }
// Texture data will be in little endian format // Texture data will be in little endian format
void CReal3D::UploadTexture(UINT32 header, UINT16 *texData) void CReal3D::UploadTexture(uint32_t header, uint16_t *texData)
{ {
unsigned x, y, page, width, height, bytesPerTexel,
mipYPos, mipWidth, mipHeight, mipNum, mipX, mipY;
// Position: texture RAM is arranged as 2 2048x1024 texel sheets // Position: texture RAM is arranged as 2 2048x1024 texel sheets
x = 32*(header&0x3F); size_t x = 32*(header&0x3F);
y = 32*((header>>7)&0x1F); size_t y = 32*((header>>7)&0x1F);
page = (header>>20)&1; size_t page = (header>>20)&1;
y += page*1024; // treat page as additional Y bit (one 2048x2048 sheet) y += page*1024; // treat page as additional Y bit (one 2048x2048 sheet)
// Texture size and bit depth // Texture size and bit depth
width = 32<<((header>>14)&7); size_t width = 32<<((header>>14)&7);
height = 32<<((header>>17)&7); size_t height = 32<<((header>>17)&7);
size_t bytesPerTexel;
if ((header&0x00800000)) // 16 bits per texel if ((header&0x00800000)) // 16 bits per texel
bytesPerTexel = 2; bytesPerTexel = 2;
else // 8 bits else // 8 bits
@ -725,7 +715,7 @@ void CReal3D::UploadTexture(UINT32 header, UINT16 *texData)
} }
// Mipmaps // Mipmaps
mipYPos = 32*((header>>7)&0x1F); size_t mipYPos = 32*((header>>7)&0x1F);
// Process texture data // Process texture data
DebugLog("Real3D: Texture upload: pos=(%d,%d) size=(%d,%d), %d-bit\n", x, y, width, height, bytesPerTexel*8); DebugLog("Real3D: Texture upload: pos=(%d,%d) size=(%d,%d), %d-bit\n", x, y, width, height, bytesPerTexel*8);
@ -733,10 +723,11 @@ void CReal3D::UploadTexture(UINT32 header, UINT16 *texData)
switch ((header>>24)&0x0F) switch ((header>>24)&0x0F)
{ {
case 0x00: // texture w/ mipmaps case 0x00: // texture w/ mipmaps
StoreTexture(x, y, width, height, texData, bytesPerTexel); {
mipWidth = width; StoreTexture(x, y, width, height, texData, header);
mipHeight = height; size_t mipWidth = width;
mipNum = 0; size_t mipHeight = height;
size_t mipNum = 0;
while((mipHeight>8) && (mipWidth>8)) while((mipHeight>8) && (mipWidth>8))
{ {
@ -746,38 +737,40 @@ void CReal3D::UploadTexture(UINT32 header, UINT16 *texData)
texData += (mipWidth*mipHeight); texData += (mipWidth*mipHeight);
mipWidth /= 2; mipWidth /= 2;
mipHeight /= 2; mipHeight /= 2;
mipX = mipXBase[mipNum] + (x / mipDivisor[mipNum]); size_t mipX = mipXBase[mipNum] + (x / mipDivisor[mipNum]);
mipY = mipYBase[mipNum] + (mipYPos / mipDivisor[mipNum]); size_t mipY = mipYBase[mipNum] + (mipYPos / mipDivisor[mipNum]);
if(page) if(page)
mipY += 1024; mipY += 1024;
mipNum++; mipNum++;
StoreTexture(mipX, mipY, mipWidth, mipHeight, (UINT16 *) texData, bytesPerTexel); StoreTexture(mipX, mipY, mipWidth, mipHeight, (uint16_t *) texData, header);
} }
break; break;
}
case 0x01: // texture w/out mipmaps case 0x01: // texture w/out mipmaps
StoreTexture(x, y, width, height, texData, bytesPerTexel); StoreTexture(x, y, width, height, texData, header);
break; break;
case 0x02: // mipmaps only case 0x02: // mipmaps only
mipWidth = width; {
mipHeight = height; size_t mipWidth = width;
mipNum = 0; size_t mipHeight = height;
size_t mipNum = 0;
while((mipHeight>8) && (mipWidth>8)) while((mipHeight>8) && (mipWidth>8))
{ {
mipWidth /= 2; mipWidth /= 2;
mipHeight /= 2; mipHeight /= 2;
mipX = mipXBase[mipNum] + (x / mipDivisor[mipNum]); size_t mipX = mipXBase[mipNum] + (x / mipDivisor[mipNum]);
mipY = mipYBase[mipNum] + (mipYPos / mipDivisor[mipNum]); size_t mipY = mipYBase[mipNum] + (mipYPos / mipDivisor[mipNum]);
if(page) if(page)
mipY += 1024; mipY += 1024;
mipNum++; mipNum++;
StoreTexture(mipX, mipY, mipWidth, mipHeight, texData, bytesPerTexel); StoreTexture(mipX, mipY, mipWidth, mipHeight, texData, header);
if (bytesPerTexel == 1) if (bytesPerTexel == 1)
texData += (mipWidth*mipHeight)/2; texData += (mipWidth*mipHeight)/2;
else else
texData += (mipWidth*mipHeight); texData += (mipWidth*mipHeight);
} }
break; break;
}
case 0x80: // MAME thinks these might be a gamma table case 0x80: // MAME thinks these might be a gamma table
//break; //break;
default: // unknown default: // unknown
@ -794,21 +787,17 @@ void CReal3D::UploadTexture(UINT32 header, UINT16 *texData)
void CReal3D::Flush(void) void CReal3D::Flush(void)
{ {
unsigned i, size;
UINT32 header;
commandPortWritten = true; commandPortWritten = true;
DebugLog("Real3D 88000000 written @ PC=%08X\n", ppc_get_pc()); DebugLog("Real3D 88000000 written @ PC=%08X\n", ppc_get_pc());
// Upload textures (if any) // Upload textures (if any)
if (fifoIdx > 0) if (fifoIdx > 0)
{ {
for (i = 0; i < fifoIdx; ) for (size_t i = 0; i < fifoIdx; )
{ {
size = 2+textureFIFO[i+0]/2; size_t size = 2+textureFIFO[i+0]/2;
size /= 4; size /= 4;
header = textureFIFO[i+1]; // texture information header uint32_t header = textureFIFO[i+1]; // texture information header
// Spikeout seems to be uploading 0 length textures // Spikeout seems to be uploading 0 length textures
if (0 == size) if (0 == size)
@ -817,7 +806,7 @@ void CReal3D::Flush(void)
break; break;
} }
UploadTexture(header,(UINT16 *)&textureFIFO[i+2]); UploadTexture(header,(uint16_t *)&textureFIFO[i+2]);
DebugLog("Real3D: Texture upload completed: %X bytes (%X)\n", size*4, textureFIFO[i+0]); DebugLog("Real3D: Texture upload completed: %X bytes (%X)\n", size*4, textureFIFO[i+0]);
i += size; i += size;
} }
@ -827,7 +816,7 @@ void CReal3D::Flush(void)
fifoIdx = 0; fifoIdx = 0;
} }
void CReal3D::WriteTextureFIFO(UINT32 data) void CReal3D::WriteTextureFIFO(uint32_t data)
{ {
if (fifoIdx >= (0x100000/4)) if (fifoIdx >= (0x100000/4))
{ {
@ -839,7 +828,7 @@ void CReal3D::WriteTextureFIFO(UINT32 data)
textureFIFO[fifoIdx++] = data; textureFIFO[fifoIdx++] = data;
} }
void CReal3D::WriteTexturePort(unsigned reg, UINT32 data) void CReal3D::WriteTexturePort(unsigned reg, uint32_t data)
{ {
//printf("Texture Port: %X=%08X\n", reg, data); //printf("Texture Port: %X=%08X\n", reg, data);
switch (reg) switch (reg)
@ -854,7 +843,7 @@ void CReal3D::WriteTexturePort(unsigned reg, UINT32 data)
break; break;
case 0x8: // VROM texture length (also used to trigger uploads) case 0x8: // VROM texture length (also used to trigger uploads)
case 0x14: case 0x14:
UploadTexture(vromTextureHeader,(UINT16 *)&vrom[vromTextureAddr&0xFFFFFF]); UploadTexture(vromTextureHeader,(uint16_t *)&vrom[vromTextureAddr&0xFFFFFF]);
//printf("texture upload: addr=%08X\n", vromTextureAddr); //printf("texture upload: addr=%08X\n", vromTextureAddr);
break; break;
default: default:
@ -863,21 +852,21 @@ void CReal3D::WriteTexturePort(unsigned reg, UINT32 data)
} }
} }
void CReal3D::WriteLowCullingRAM(UINT32 addr, UINT32 data) void CReal3D::WriteLowCullingRAM(uint32_t addr, uint32_t data)
{ {
if (g_Config.gpuMultiThreaded) if (g_Config.gpuMultiThreaded)
MARK_DIRTY(cullingRAMLoDirty, addr); MARK_DIRTY(cullingRAMLoDirty, addr);
cullingRAMLo[addr/4] = data; cullingRAMLo[addr/4] = data;
} }
void CReal3D::WriteHighCullingRAM(UINT32 addr, UINT32 data) void CReal3D::WriteHighCullingRAM(uint32_t addr, uint32_t data)
{ {
if (g_Config.gpuMultiThreaded) if (g_Config.gpuMultiThreaded)
MARK_DIRTY(cullingRAMHiDirty, addr); MARK_DIRTY(cullingRAMHiDirty, addr);
cullingRAMHi[addr/4] = data; cullingRAMHi[addr/4] = data;
} }
void CReal3D::WritePolygonRAM(UINT32 addr, UINT32 data) void CReal3D::WritePolygonRAM(uint32_t addr, uint32_t data)
{ {
if (g_Config.gpuMultiThreaded) if (g_Config.gpuMultiThreaded)
MARK_DIRTY(polyRAMDirty, addr); MARK_DIRTY(polyRAMDirty, addr);
@ -885,21 +874,21 @@ void CReal3D::WritePolygonRAM(UINT32 addr, UINT32 data)
} }
// Registers seem to range from 0x00 to around 0x3C but they are not understood // Registers seem to range from 0x00 to around 0x3C but they are not understood
UINT32 CReal3D::ReadRegister(unsigned reg) uint32_t CReal3D::ReadRegister(unsigned reg)
{ {
DebugLog("Real3D: Read reg %X\n", reg); DebugLog("Real3D: Read reg %X\n", reg);
if (reg == 0) if (reg == 0)
{ {
UINT32 status = (ppc_total_cycles() >= statusChange ? 0x0 : 0x2); uint32_t status = (ppc_total_cycles() >= statusChange ? 0x0 : 0x2);
return 0xFFFFFFFD|status; return 0xFFFFFFFD|status;
} }
else else
return 0xFFFFFFFF; return 0xFFFFFFFF;
} }
UINT32 CReal3D::ReadPCIConfigSpace(unsigned device, unsigned reg, unsigned bits, unsigned offset) uint32_t CReal3D::ReadPCIConfigSpace(unsigned device, unsigned reg, unsigned bits, unsigned offset)
{ {
UINT32 d; uint32_t d;
if ((bits==8)) if ((bits==8))
{ {
@ -935,7 +924,7 @@ UINT32 CReal3D::ReadPCIConfigSpace(unsigned device, unsigned reg, unsigned bits,
return 0; return 0;
} }
void CReal3D::WritePCIConfigSpace(unsigned device, unsigned reg, unsigned bits, unsigned offset, UINT32 data) void CReal3D::WritePCIConfigSpace(unsigned device, unsigned reg, unsigned bits, unsigned offset, uint32_t data)
{ {
DebugLog("Real3D: PCI %d-bit write request for reg=%02X, data=%08X\n", bits, reg, data); DebugLog("Real3D: PCI %d-bit write request for reg=%02X, data=%08X\n", bits, reg, data);
} }
@ -1006,9 +995,9 @@ void CReal3D::SetStep(int stepID)
DebugLog("Real3D set to Step %d.%d\n", (step>>4)&0xF, step&0xF); DebugLog("Real3D set to Step %d.%d\n", (step>>4)&0xF, step&0xF);
} }
bool CReal3D::Init(const UINT8 *vromPtr, CBus *BusObjectPtr, CIRQ *IRQObjectPtr, unsigned dmaIRQBit) bool CReal3D::Init(const uint8_t *vromPtr, CBus *BusObjectPtr, CIRQ *IRQObjectPtr, unsigned dmaIRQBit)
{ {
unsigned memSize = (g_Config.gpuMultiThreaded ? MEMORY_POOL_SIZE : MEM_POOL_SIZE_RW); size_t memSize = (g_Config.gpuMultiThreaded ? MEMORY_POOL_SIZE : MEM_POOL_SIZE_RW);
float memSizeMB = (float)memSize/(float)0x100000; float memSizeMB = (float)memSize/(float)0x100000;
// IRQ and bus objects // IRQ and bus objects
@ -1017,32 +1006,32 @@ bool CReal3D::Init(const UINT8 *vromPtr, CBus *BusObjectPtr, CIRQ *IRQObjectPtr,
dmaIRQ = dmaIRQBit; dmaIRQ = dmaIRQBit;
// Allocate all Real3D RAM regions // Allocate all Real3D RAM regions
memoryPool = new(std::nothrow) UINT8[memSize]; memoryPool = new(std::nothrow) uint8_t[memSize];
if (NULL == memoryPool) if (NULL == memoryPool)
return ErrorLog("Insufficient memory for Real3D object (needs %1.1f MB).", memSizeMB); return ErrorLog("Insufficient memory for Real3D object (needs %1.1f MB).", memSizeMB);
// Set up main pointers // Set up main pointers
cullingRAMLo = (UINT32 *) &memoryPool[OFFSET_8C]; cullingRAMLo = (uint32_t *) &memoryPool[OFFSET_8C];
cullingRAMHi = (UINT32 *) &memoryPool[OFFSET_8E]; cullingRAMHi = (uint32_t *) &memoryPool[OFFSET_8E];
polyRAM = (UINT32 *) &memoryPool[OFFSET_98]; polyRAM = (uint32_t *) &memoryPool[OFFSET_98];
textureRAM = (UINT16 *) &memoryPool[OFFSET_TEXRAM]; textureRAM = (uint16_t *) &memoryPool[OFFSET_TEXRAM];
textureFIFO = (UINT32 *) &memoryPool[OFFSET_TEXFIFO]; textureFIFO = (uint32_t *) &memoryPool[OFFSET_TEXFIFO];
// If multi-threaded, set up pointers for read-only snapshots and dirty page arrays too // If multi-threaded, set up pointers for read-only snapshots and dirty page arrays too
if (g_Config.gpuMultiThreaded) if (g_Config.gpuMultiThreaded)
{ {
cullingRAMLoRO = (UINT32 *) &memoryPool[OFFSET_8C_RO]; cullingRAMLoRO = (uint32_t *) &memoryPool[OFFSET_8C_RO];
cullingRAMHiRO = (UINT32 *) &memoryPool[OFFSET_8E_RO]; cullingRAMHiRO = (uint32_t *) &memoryPool[OFFSET_8E_RO];
polyRAMRO = (UINT32 *) &memoryPool[OFFSET_98_RO]; polyRAMRO = (uint32_t *) &memoryPool[OFFSET_98_RO];
textureRAMRO = (UINT16 *) &memoryPool[OFFSET_TEXRAM_RO]; textureRAMRO = (uint16_t *) &memoryPool[OFFSET_TEXRAM_RO];
cullingRAMLoDirty = (UINT8 *) &memoryPool[OFFSET_8C_DIRTY]; cullingRAMLoDirty = (uint8_t *) &memoryPool[OFFSET_8C_DIRTY];
cullingRAMHiDirty = (UINT8 *) &memoryPool[OFFSET_8E_DIRTY]; cullingRAMHiDirty = (uint8_t *) &memoryPool[OFFSET_8E_DIRTY];
polyRAMDirty = (UINT8 *) &memoryPool[OFFSET_98_DIRTY]; polyRAMDirty = (uint8_t *) &memoryPool[OFFSET_98_DIRTY];
textureRAMDirty = (UINT8 *) &memoryPool[OFFSET_TEXRAM_DIRTY]; textureRAMDirty = (uint8_t *) &memoryPool[OFFSET_TEXRAM_DIRTY];
} }
// VROM pointer passed to us // VROM pointer passed to us
vrom = (UINT32 *) vromPtr; vrom = (uint32_t *) vromPtr;
DebugLog("Initialized Real3D (allocated %1.1f MB)\n", memSizeMB); DebugLog("Initialized Real3D (allocated %1.1f MB)\n", memSizeMB);
return OKAY; return OKAY;
@ -1080,7 +1069,7 @@ CReal3D::~CReal3D(void)
fp = fopen("8c000000", "wb"); fp = fopen("8c000000", "wb");
if (NULL != fp) if (NULL != fp)
{ {
fwrite(cullingRAMLo, sizeof(UINT8), 0x400000, fp); fwrite(cullingRAMLo, sizeof(uint8_t), 0x400000, fp);
fclose(fp); fclose(fp);
printf("dumped %s\n", "8c000000"); printf("dumped %s\n", "8c000000");
} }
@ -1089,7 +1078,7 @@ CReal3D::~CReal3D(void)
fp = fopen("8e000000", "wb"); fp = fopen("8e000000", "wb");
if (NULL != fp) if (NULL != fp)
{ {
fwrite(cullingRAMHi, sizeof(UINT8), 0x100000, fp); fwrite(cullingRAMHi, sizeof(uint8_t), 0x100000, fp);
fclose(fp); fclose(fp);
printf("dumped %s\n", "8e000000"); printf("dumped %s\n", "8e000000");
} }
@ -1098,7 +1087,7 @@ CReal3D::~CReal3D(void)
fp = fopen("98000000", "wb"); fp = fopen("98000000", "wb");
if (NULL != fp) if (NULL != fp)
{ {
fwrite(polyRAM, sizeof(UINT8), 0x400000, fp); fwrite(polyRAM, sizeof(uint8_t), 0x400000, fp);
fclose(fp); fclose(fp);
printf("dumped %s\n", "98000000"); printf("dumped %s\n", "98000000");
} }
@ -1107,7 +1096,7 @@ CReal3D::~CReal3D(void)
fp = fopen("texram", "wb"); fp = fopen("texram", "wb");
if (NULL != fp) if (NULL != fp)
{ {
fwrite(textureRAM, sizeof(UINT8), 0x800000, fp); fwrite(textureRAM, sizeof(uint8_t), 0x800000, fp);
fclose(fp); fclose(fp);
printf("dumped %s\n", "texram"); printf("dumped %s\n", "texram");
} }

View file

@ -29,6 +29,8 @@
#ifndef INCLUDED_REAL3D_H #ifndef INCLUDED_REAL3D_H
#define INCLUDED_REAL3D_H #define INCLUDED_REAL3D_H
#include <cstdint>
/* /*
* QueuedUploadTextures: * QueuedUploadTextures:
* *
@ -98,7 +100,7 @@ public:
* their work. If multi-threaded rendering is not enabled, then this method does * their work. If multi-threaded rendering is not enabled, then this method does
* nothing. * nothing.
*/ */
UINT32 SyncSnapshots(void); uint32_t SyncSnapshots(void);
/* /*
* BeginFrame(void): * BeginFrame(void):
@ -151,8 +153,8 @@ public:
* Returns: * Returns:
* Data of the requested size, in little endian. * Data of the requested size, in little endian.
*/ */
UINT8 ReadDMARegister8(unsigned reg); uint8_t ReadDMARegister8(unsigned reg);
UINT32 ReadDMARegister32(unsigned reg); uint32_t ReadDMARegister32(unsigned reg);
/* /*
* WriteDMARegister8(reg, data): * WriteDMARegister8(reg, data):
@ -165,8 +167,8 @@ public:
* reg Register number to read from (0-0xFF only). * reg Register number to read from (0-0xFF only).
* data Data to write. * data Data to write.
*/ */
void WriteDMARegister8(unsigned reg, UINT8 data); void WriteDMARegister8(unsigned reg, uint8_t data);
void WriteDMARegister32(unsigned reg, UINT32 data); void WriteDMARegister32(unsigned reg, uint32_t data);
/* /*
* WriteLowCullingRAM(addr, data): * WriteLowCullingRAM(addr, data):
@ -180,7 +182,7 @@ public:
* User must ensure address is properly clamped. * User must ensure address is properly clamped.
* data Data to write. * data Data to write.
*/ */
void WriteLowCullingRAM(UINT32 addr, UINT32 data); void WriteLowCullingRAM(uint32_t addr, uint32_t data);
/* /*
* WriteHighCullingRAM(addr, data): * WriteHighCullingRAM(addr, data):
@ -194,7 +196,7 @@ public:
* User must ensure address is properly clamped. * User must ensure address is properly clamped.
* data Data to write. * data Data to write.
*/ */
void WriteHighCullingRAM(UINT32 addr, UINT32 data); void WriteHighCullingRAM(uint32_t addr, uint32_t data);
/* /*
* WriteTextureFIFO(data): * WriteTextureFIFO(data):
@ -206,7 +208,7 @@ public:
* Parameters: * Parameters:
* data Data to write. * data Data to write.
*/ */
void WriteTextureFIFO(UINT32 data); void WriteTextureFIFO(uint32_t data);
/* /*
* WriteTexturePort(reg, data): * WriteTexturePort(reg, data):
@ -220,7 +222,7 @@ public:
* data The 32-bit word to write to the register. A write to * data The 32-bit word to write to the register. A write to
* register 8 triggers the upload. * register 8 triggers the upload.
*/ */
void WriteTexturePort(unsigned reg, UINT32 data); void WriteTexturePort(unsigned reg, uint32_t data);
/* /*
* WritePolygonRAM(addr, data): * WritePolygonRAM(addr, data):
@ -234,7 +236,7 @@ public:
* User must ensure address is properly clamped. * User must ensure address is properly clamped.
* data Data to write. * data Data to write.
*/ */
void WritePolygonRAM(UINT32 addr, UINT32 data); void WritePolygonRAM(uint32_t addr, uint32_t data);
/* /*
* ReadTAP(void): * ReadTAP(void):
@ -272,7 +274,7 @@ public:
* Returns: * Returns:
* The 32-bit status register. * The 32-bit status register.
*/ */
UINT32 ReadRegister(unsigned reg); uint32_t ReadRegister(unsigned reg);
/* /*
* ReadPCIConfigSpace(device, reg, bits, offset): * ReadPCIConfigSpace(device, reg, bits, offset):
@ -291,7 +293,7 @@ public:
* Returns: * Returns:
* Register data. * Register data.
*/ */
UINT32 ReadPCIConfigSpace(unsigned device, unsigned reg, unsigned bits, unsigned width); uint32_t ReadPCIConfigSpace(unsigned device, unsigned reg, unsigned bits, unsigned width);
/* /*
* WritePCIConfigSpace(device, reg, bits, offset, data): * WritePCIConfigSpace(device, reg, bits, offset, data):
@ -308,7 +310,7 @@ public:
* register number. * register number.
* data Data. * data Data.
*/ */
void WritePCIConfigSpace(unsigned device, unsigned reg, unsigned bits, unsigned width, UINT32 data); void WritePCIConfigSpace(unsigned device, unsigned reg, unsigned bits, unsigned width, uint32_t data);
/* /*
* Reset(void): * Reset(void):
@ -359,13 +361,12 @@ public:
* and DMA interrupts. * and DMA interrupts.
* dmaIRQBit IRQ identifier bit to pass along to IRQ controller * dmaIRQBit IRQ identifier bit to pass along to IRQ controller
* when asserting interrupts. * when asserting interrupts.
* *
* Returns: * Returns:
* OKAY if successful otherwise FAIL (not enough memory). Prints own * OKAY if successful otherwise FAIL (not enough memory). Prints own
* errors. * errors.
*/ */
bool Init(const UINT8 *vromPtr, CBus *BusObjectPtr, CIRQ *IRQObjectPtr, unsigned dmaIRQBit); bool Init(const uint8_t *vromPtr, CBus *BusObjectPtr, CIRQ *IRQObjectPtr, unsigned dmaIRQBit);
/* /*
* CReal3D(void): * CReal3D(void):
@ -379,47 +380,47 @@ public:
private: private:
// Private member functions // Private member functions
void DMACopy(void); void DMACopy(void);
void InsertBit(UINT8 *buf, unsigned bitNum, unsigned bit); void InsertBit(uint8_t *buf, unsigned bitNum, unsigned bit);
void InsertID(UINT32 id, unsigned startBit); void InsertID(uint32_t id, unsigned startBit);
unsigned Shift(UINT8 *data, unsigned numBits); unsigned Shift(uint8_t *data, unsigned numBits);
void StoreTexture(unsigned xPos, unsigned yPos, unsigned width, unsigned height, UINT16 *texData, unsigned bytesPerTexel); void StoreTexture(unsigned xPos, unsigned yPos, unsigned width, unsigned height, uint16_t *texData, uint32_t header);
void UploadTexture(UINT32 header, UINT16 *texData); void UploadTexture(uint32_t header, uint16_t *texData);
UINT32 UpdateSnapshots(bool copyWhole); uint32_t UpdateSnapshots(bool copyWhole);
UINT32 UpdateSnapshot(bool copyWhole, UINT8 *src, UINT8 *dst, unsigned size, UINT8 *dirty); uint32_t UpdateSnapshot(bool copyWhole, uint8_t *src, uint8_t *dst, unsigned size, uint8_t *dirty);
// Renderer attached to the Real3D // Renderer attached to the Real3D
IRender3D *Render3D; IRender3D *Render3D;
// Data passed from Model 3 object // Data passed from Model 3 object
const UINT32 *vrom; // Video ROM const uint32_t *vrom; // Video ROM
int step; // hardware stepping (as in GameInfo structure) int step; // hardware stepping (as in GameInfo structure)
UINT32 pciID; // PCI vendor and device ID uint32_t pciID; // PCI vendor and device ID
// Error flag (to limit errors to once per frame) // Error flag (to limit errors to once per frame)
bool error; // true if an error occurred this frame bool error; // true if an error occurred this frame
// Real3D memory // Real3D memory
UINT8 *memoryPool; // all memory allocated here uint8_t *memoryPool; // all memory allocated here
UINT32 *cullingRAMLo; // 4MB of culling RAM at 8C000000 uint32_t *cullingRAMLo; // 4MB of culling RAM at 8C000000
UINT32 *cullingRAMHi; // 1MB of culling RAM at 8E000000 uint32_t *cullingRAMHi; // 1MB of culling RAM at 8E000000
UINT32 *polyRAM; // 4MB of polygon RAM at 98000000 uint32_t *polyRAM; // 4MB of polygon RAM at 98000000
UINT16 *textureRAM; // 8MB of internal texture RAM uint16_t *textureRAM; // 8MB of internal texture RAM
UINT32 *textureFIFO; // 1MB texture FIFO at 0x94000000 uint32_t *textureFIFO; // 1MB texture FIFO at 0x94000000
unsigned fifoIdx; // index into texture FIFO size_t fifoIdx; // index into texture FIFO
UINT32 vromTextureAddr; // VROM texture port address data uint32_t vromTextureAddr; // VROM texture port address data
UINT32 vromTextureHeader; // VROM texture port header data uint32_t vromTextureHeader; // VROM texture port header data
// Read-only snapshots // Read-only snapshots
UINT32 *cullingRAMLoRO; // 4MB of culling RAM at 8C000000 [read-only snapshot] uint32_t *cullingRAMLoRO; // 4MB of culling RAM at 8C000000 [read-only snapshot]
UINT32 *cullingRAMHiRO; // 1MB of culling RAM at 8E000000 [read-only snapshot] uint32_t *cullingRAMHiRO; // 1MB of culling RAM at 8E000000 [read-only snapshot]
UINT32 *polyRAMRO; // 4MB of polygon RAM at 98000000 [read-only snapshot] uint32_t *polyRAMRO; // 4MB of polygon RAM at 98000000 [read-only snapshot]
UINT16 *textureRAMRO; // 8MB of internal texture RAM [read-only snapshot] uint16_t *textureRAMRO; // 8MB of internal texture RAM [read-only snapshot]
// Arrays to keep track of dirty pages in memory regions // Arrays to keep track of dirty pages in memory regions
UINT8 *cullingRAMLoDirty; uint8_t *cullingRAMLoDirty;
UINT8 *cullingRAMHiDirty; uint8_t *cullingRAMHiDirty;
UINT8 *polyRAMDirty; uint8_t *polyRAMDirty;
UINT8 *textureRAMDirty; uint8_t *textureRAMDirty;
// Queued texture uploads // Queued texture uploads
vector<QueuedUploadTextures> queuedUploadTextures; vector<QueuedUploadTextures> queuedUploadTextures;
@ -430,31 +431,31 @@ private:
// IRQ handling // IRQ handling
CIRQ *IRQ; // IRQ controller CIRQ *IRQ; // IRQ controller
unsigned dmaIRQ; // IRQ bit to use when calling IRQ handler size_t dmaIRQ; // IRQ bit to use when calling IRQ handler
// DMA device // DMA device
UINT32 dmaSrc; uint32_t dmaSrc;
UINT32 dmaDest; uint32_t dmaDest;
UINT32 dmaLength; uint32_t dmaLength;
UINT32 dmaData; uint32_t dmaData;
UINT32 dmaUnknownReg; uint32_t dmaUnknownReg;
UINT8 dmaStatus; uint8_t dmaStatus;
UINT8 dmaConfig; uint8_t dmaConfig;
// Command port // Command port
bool commandPortWritten; bool commandPortWritten;
bool commandPortWrittenRO; // Read-only copy of flag bool commandPortWrittenRO; // Read-only copy of flag
// Status and command registers // Status and command registers
UINT64 statusChange; uint64_t statusChange;
// JTAG Test Access Port // JTAG Test Access Port
UINT64 tapCurrentInstruction; // latched IR (not always equal to IR) uint64_t tapCurrentInstruction; // latched IR (not always equal to IR)
UINT64 tapIR; // instruction register (46 bits) uint64_t tapIR; // instruction register (46 bits)
UINT8 tapID[32]; // ASIC ID code data buffer uint8_t tapID[32]; // ASIC ID code data buffer
unsigned tapIDSize; // size of ID data in bits unsigned tapIDSize; // size of ID data in bits
unsigned tapTDO; // bit shifted out to TDO unsigned tapTDO; // bit shifted out to TDO
int tapState; // current state unsigned tapState; // current state
}; };