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

File diff suppressed because it is too large Load diff

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:
* *
@ -38,10 +40,10 @@
*/ */
struct QueuedUploadTextures struct QueuedUploadTextures
{ {
unsigned x; unsigned x;
unsigned y; unsigned y;
unsigned width; unsigned width;
unsigned height; unsigned height;
}; };
/* /*
@ -55,407 +57,406 @@ struct QueuedUploadTextures
class CReal3D: public CPCIDevice class CReal3D: public CPCIDevice
{ {
public: public:
/* /*
* SaveState(SaveState): * SaveState(SaveState):
* *
* Saves an image of the current device state. * Saves an image of the current device state.
* *
* Parameters: * Parameters:
* SaveState Block file to save state information to. * SaveState Block file to save state information to.
*/ */
void SaveState(CBlockFile *SaveState); void SaveState(CBlockFile *SaveState);
/* /*
* LoadState(SaveState): * LoadState(SaveState):
* *
* Loads and a state image. * Loads and a state image.
* *
* Parameters: * Parameters:
* SaveState Block file to load state information from. * SaveState Block file to load state information from.
*/ */
void LoadState(CBlockFile *SaveState); void LoadState(CBlockFile *SaveState);
/* /*
* BeginVBlank(void): * BeginVBlank(void):
* *
* Must be called before the VBlank starts. * Must be called before the VBlank starts.
*/ */
void BeginVBlank(int statusCycles); void BeginVBlank(int statusCycles);
/* /*
* EndVBlank(void) * EndVBlank(void)
* *
* Must be called after the VBlank finishes. * Must be called after the VBlank finishes.
*/ */
void EndVBlank(void); void EndVBlank(void);
/* /*
* SyncSnapshots(void): * SyncSnapshots(void):
* *
* Syncs the read-only memory snapshots with the real ones so that rendering * Syncs the read-only memory snapshots with the real ones so that rendering
* of the current frame can begin in the render thread. Must be called at the * of the current frame can begin in the render thread. Must be called at the
* end of each frame when both the render thread and the PPC thread have finished * end of each frame when both the render thread and the PPC thread have finished
* 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):
* *
* Prepares to render a new frame. Must be called once per frame prior to * Prepares to render a new frame. Must be called once per frame prior to
* drawing anything and must only access read-only snapshots and variables * drawing anything and must only access read-only snapshots and variables
* since it may be running in a separate thread. * since it may be running in a separate thread.
*/ */
void BeginFrame(void); void BeginFrame(void);
/* /*
* RenderFrame(void): * RenderFrame(void):
* *
* Traverses the scene database and renders a frame. Must be called after * Traverses the scene database and renders a frame. Must be called after
* BeginFrame() but before EndFrame() and must only access read-only snapshots * BeginFrame() but before EndFrame() and must only access read-only snapshots
* and variables since it may be running in a separate thread. * and variables since it may be running in a separate thread.
*/ */
void RenderFrame(void); void RenderFrame(void);
/* /*
* EndFrame(void): * EndFrame(void):
* *
* Signals the end of rendering for this frame. Must be called last during * Signals the end of rendering for this frame. Must be called last during
* the frame and must only access read-only snapshots and variables since it * the frame and must only access read-only snapshots and variables since it
* may be running in a separate thread. * may be running in a separate thread.
*/ */
void EndFrame(void); void EndFrame(void);
/* /*
* Flush(void): * Flush(void):
* *
* Triggers the beginning of a new frame. All textures in the texture FIFO * Triggers the beginning of a new frame. All textures in the texture FIFO
* are uploaded and the FIFO is reset. On the real device, this seems to * are uploaded and the FIFO is reset. On the real device, this seems to
* cause a frame to be rendered as well but this is not performed here. * cause a frame to be rendered as well but this is not performed here.
* *
* This should be called when the command port is written. * This should be called when the command port is written.
*/ */
void Flush(void); void Flush(void);
/* /*
* ReadDMARegister8(reg): * ReadDMARegister8(reg):
* ReadDMARegister32(reg): * ReadDMARegister32(reg):
* *
* Reads from a DMA register. Multi-byte reads are returned as little * Reads from a DMA register. Multi-byte reads are returned as little
* endian and must be flipped if called by a big endian device. * endian and must be flipped if called by a big endian device.
* *
* Parameters: * Parameters:
* reg Register number to read from (0-0xFF only). * reg Register number to read from (0-0xFF only).
* *
* 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):
* WriteDMARegister32(reg, data); * WriteDMARegister32(reg, data);
* *
* Write to a DMA register. Multi-byte writes by big endian devices must be * Write to a DMA register. Multi-byte writes by big endian devices must be
* byte reversed (this is a little endian device). * byte reversed (this is a little endian device).
* *
* Parameters: * Parameters:
* 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):
* *
* Writes the low culling RAM region. Because this is a little endian * Writes the low culling RAM region. Because this is a little endian
* device, big endian devices/buses have to take care to manually reverse * device, big endian devices/buses have to take care to manually reverse
* the data before writing. * the data before writing.
* *
* Parameters: * Parameters:
* addr Word (32-bit) aligned address ranging from 0 to 0x3FFFFC. * addr Word (32-bit) aligned address ranging from 0 to 0x3FFFFC.
* 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):
* *
* Writes the high culling RAM region. Because this is a little endian * Writes the high culling RAM region. Because this is a little endian
* device, big endian devices/buses have to take care to manually reverse * device, big endian devices/buses have to take care to manually reverse
* the data before writing. * the data before writing.
* *
* Parameters: * Parameters:
* addr Word (32-bit) aligned address ranging from 0 to 0xFFFFC. * addr Word (32-bit) aligned address ranging from 0 to 0xFFFFC.
* 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):
* *
* Writes to the 1MB texture FIFO. Because this is a little endian device, * Writes to the 1MB texture FIFO. Because this is a little endian device,
* big endian devices/buses have to take care to manually reverse the data * big endian devices/buses have to take care to manually reverse the data
* before writing. * before writing.
* *
* 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):
* *
* Writes to the VROM texture ports. Register 0 is the word-granular VROM * Writes to the VROM texture ports. Register 0 is the word-granular VROM
* address of the texture, register 4 is the texture information header, * address of the texture, register 4 is the texture information header,
* and register 8 is the size of the texture in words. * and register 8 is the size of the texture in words.
* *
* Parameters: * Parameters:
* reg Register number: must be 0, 4, 8, 0xC, 0x10, or 0x14 only. * reg Register number: must be 0, 4, 8, 0xC, 0x10, or 0x14 only.
* 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):
* *
* Writes the polygon RAM region. Because this is a little endian device, * Writes the polygon RAM region. Because this is a little endian device,
* big endian devices/buses have to take care to manually reverse the data * big endian devices/buses have to take care to manually reverse the data
* before writing. * before writing.
* *
* Parameters: * Parameters:
* addr Word (32-bit) aligned address ranging from 0 to 0x3FFFFC. * addr Word (32-bit) aligned address ranging from 0 to 0x3FFFFC.
* 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):
* *
* Reads the JTAG Test Access Port. * Reads the JTAG Test Access Port.
* *
* Returns: * Returns:
* The TDO bit (either 1 or 0). * The TDO bit (either 1 or 0).
*/ */
unsigned ReadTAP(void); unsigned ReadTAP(void);
/* /*
* void WriteTAP(tck, tms, tdi, trst): * void WriteTAP(tck, tms, tdi, trst):
* *
* Writes to the JTAG TAP. State changes only occur on the rising edge of * Writes to the JTAG TAP. State changes only occur on the rising edge of
* the clock (tck = 1). Each of the inputs is a single bit only and must be * the clock (tck = 1). Each of the inputs is a single bit only and must be
* either 0 or 1, or the code will fail. * either 0 or 1, or the code will fail.
* *
* Parameters: * Parameters:
* tck Clock. * tck Clock.
* tms Test mode select. * tms Test mode select.
* tdi Serial data input. Must be 0 or 1 only! * tdi Serial data input. Must be 0 or 1 only!
* trst Reset. * trst Reset.
*/ */
void WriteTAP(unsigned tck, unsigned tms, unsigned tdi, unsigned trst); void WriteTAP(unsigned tck, unsigned tms, unsigned tdi, unsigned trst);
/* /*
* ReadRegister(reg): * ReadRegister(reg):
* *
* Reads one of the status registers. * Reads one of the status registers.
* *
* Parameters: * Parameters:
* reg Register offset (32-bit aligned). From 0x00 to 0x3C. * reg Register offset (32-bit aligned). From 0x00 to 0x3C.
* *
* 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):
* *
* Reads a PCI configuration space register. See CPCIDevice definition for * Reads a PCI configuration space register. See CPCIDevice definition for
* more details. * more details.
* *
* Parameters: * Parameters:
* device Device number (ignored, not needed). * device Device number (ignored, not needed).
* reg Register number. * reg Register number.
* bits Bit width of access (8, 16, or 32 only).; * bits Bit width of access (8, 16, or 32 only).;
* offset Byte offset within register, aligned to the specified bit * offset Byte offset within register, aligned to the specified bit
* width, and offset from the 32-bit aligned base of the * width, and offset from the 32-bit aligned base of the
* register number. * register number.
* *
* 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):
* *
* Writes to a PCI configuration space register. See CPCIDevice definition * Writes to a PCI configuration space register. See CPCIDevice definition
* for more details. * for more details.
* *
* Parameters: * Parameters:
* device Device number (ignored, not needed). * device Device number (ignored, not needed).
* reg Register number. * reg Register number.
* bits Bit width of access (8, 16, or 32 only). * bits Bit width of access (8, 16, or 32 only).
* offset Byte offset within register, aligned to the specified bit * offset Byte offset within register, aligned to the specified bit
* width, and offset from the 32-bit aligned base of the * width, and offset from the 32-bit aligned base of the
* 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):
* *
* Resets the Real3D device. Must be called before reading/writing the * Resets the Real3D device. Must be called before reading/writing the
* device. * device.
*/ */
void Reset(void); void Reset(void);
/* /*
* AttachRenderer(render3DPtr): * AttachRenderer(render3DPtr):
* *
* Attaches a 3D renderer for the Real3D to use. This function will * Attaches a 3D renderer for the Real3D to use. This function will
* immediately pass along the information that a CRender3D object needs to * immediately pass along the information that a CRender3D object needs to
* work with. * work with.
* *
* Parameters: * Parameters:
* Render3DPtr Pointer to a 3D renderer object. * Render3DPtr Pointer to a 3D renderer object.
*/ */
void AttachRenderer(IRender3D *Render3DPtr); void AttachRenderer(IRender3D *Render3DPtr);
/* /*
* SetStep(stepID): * SetStep(stepID):
* *
* Sets the Model 3 hardware stepping, which also determines the Real3D * Sets the Model 3 hardware stepping, which also determines the Real3D
* functionality. The default is Step 1.0. This should be called prior to * functionality. The default is Step 1.0. This should be called prior to
* any other emulation functions and after Init(). * any other emulation functions and after Init().
* *
* Parameters: * Parameters:
* stepID 0x10 for Step 1.0, 0x15 for Step 1.5, 0x20 for Step 2.0, * stepID 0x10 for Step 1.0, 0x15 for Step 1.5, 0x20 for Step 2.0,
* or 0x21 for Step 2.1. Anything else defaults to 1.0. * or 0x21 for Step 2.1. Anything else defaults to 1.0.
*/ */
void SetStep(int stepID); void SetStep(int stepID);
/* /*
* Init(vromPtr, BusObjectPtr, IRQObjectPtr, dmaIRQBit): * Init(vromPtr, BusObjectPtr, IRQObjectPtr, dmaIRQBit):
* *
* One-time initialization of the context. Must be called prior to all * One-time initialization of the context. Must be called prior to all
* other members. Connects the Real3D device to its video ROM and allocates * other members. Connects the Real3D device to its video ROM and allocates
* memory for RAM regions. * memory for RAM regions.
* *
* Parameters: * Parameters:
* vromPtr A pointer to video ROM (with each 32-bit word in * vromPtr A pointer to video ROM (with each 32-bit word in
* its native little endian format). * its native little endian format).
* BusObjectPtr Pointer to the bus that the 53C810 has control * BusObjectPtr Pointer to the bus that the 53C810 has control
* over. Used to read/write memory. * over. Used to read/write memory.
* IRQObjectPtr Pointer to the IRQ controller. Used to trigger SCSI * IRQObjectPtr Pointer to the IRQ controller. Used to trigger SCSI
* 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_t *vromPtr, CBus *BusObjectPtr, CIRQ *IRQObjectPtr, unsigned dmaIRQBit);
bool Init(const UINT8 *vromPtr, CBus *BusObjectPtr, CIRQ *IRQObjectPtr, unsigned dmaIRQBit);
/*
/* * CReal3D(void):
* CReal3D(void): * ~CReal3D(void):
* ~CReal3D(void): *
* * Constructor and destructor.
* Constructor and destructor. */
*/ CReal3D(void);
CReal3D(void); ~CReal3D(void);
~CReal3D(void);
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;
vector<QueuedUploadTextures> queuedUploadTexturesRO; // Read-only copy of queue vector<QueuedUploadTextures> queuedUploadTexturesRO; // Read-only copy of queue
// Big endian bus object for DMA memory access // Big endian bus object for DMA memory access
CBus *Bus; CBus *Bus;
// 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
}; };
#endif // INCLUDED_REAL3D_H #endif // INCLUDED_REAL3D_H