Implement RAMIN lookup and start the pullers. I hate nvidia

This commit is contained in:
starfrost013
2025-01-31 01:21:28 +00:00
parent ce27b51ff5
commit 1e8c804cfd
6 changed files with 254 additions and 70 deletions

View File

@@ -14,8 +14,8 @@
* Also check the doc folder for some more notres
*
* vid_nv3.h: NV3 Architecture Hardware Reference (open-source)
* Last updated: 28 January 2025 (STILL WORKING ON IT!!!)
*
* Last updated: 30 January 2025 (STILL WORKING ON IT!!!)
*
* Authors: Connor Hyde <mario64crashed@gmail.com>
*
* Copyright 2024-2025 Connor Hyde
@@ -43,9 +43,16 @@ extern const device_config_t nv3_config[];
#define NV3_86BOX_TIMER_SYSTEM_FIX_QUOTIENT 10 // The amount by which we have to ration out the memory clock because it's not fast enough...
// Multiply by this value to get the real clock speed.
#define NV3_LAST_VALID_GRAPHICS_OBJECT_ID 0x1F
// The class ids are represented with 5 bits in PGRAPH, but 7 bits in PFIFO!
// What...
#define NV3_PFIFO_FIRST_VALID_GRAPHICS_OBJECT_ID 0x40
#define NV3_PFIFO_LAST_VALID_GRAPHICS_OBJECT_ID 0x5F
// Default value for the boot information register.
// Depends on the chip
#define NV3_BOOT_REG_REV_A00 0x00030100
#define NV3_BOOT_REG_REV_A00 0x00030100 // todo: format is wrong(?) for nv3a, fix it later
#define NV3_BOOT_REG_REV_B00 0x00030110
#define NV3_BOOT_REG_REV_C00 0x00030120
@@ -72,7 +79,7 @@ extern const device_config_t nv3_config[];
#define VRAM_SIZE_2MB 0x200000 // 2MB
#define VRAM_SIZE_4MB 0x400000 // 4MB
#define VRAM_SIZE_8MB 0x800000 // NV3T only
// There is also 1mb supported by the card but it was never used
// PCI config
#define NV3_PCI_CFG_VENDOR_ID 0x0
@@ -194,6 +201,7 @@ extern const device_config_t nv3_config[];
#define NV3_CIO_END 0x3df
#define NV3_PBUS_START 0x1000 // Bus Control Subsystem
#define NV3_PBUS_INTR 0x1100 // Bus Control - Interrupt Status
#define NV3_PBUS_INTR_EN 0x1140 // Bus Control - Interrupt Enable
#define NV3_PBUS_PCI_START 0x1800 // PCI mirror start
#define NV3_PBUS_PCI_END 0x18FF // PCI mirror end
@@ -202,18 +210,25 @@ extern const device_config_t nv3_config[];
#define NV3_PFIFO_DEBUG_0 0x2080 // PFIFO Debug Register
#define NV3_PFIFO_CACHE0_ERROR_PENDING 0
#define NV3_PFIFO_CACHE1_ERROR_PENDING 1
#define NV3_PFIFO_CACHE1_ERROR_PENDING 4
#define NV3_PFIFO_INTR 0x2100 // FIFO - Interrupt Status
#define NV3_PFIFO_INTR_EN 0x2140 // FIFO - Interrupt Enable
// PFIFO interrupts
#define NV3_PFIFO_INTR_CACHE_ERROR 0
#define NV3_PFIFO_INTR_RUNOUT 4
#define NV3_PFIFO_INTR_RUNOUT_OVERFLOW 8
#define NV3_PFIFO_INTR_DMA_PUSHER 12
#define NV3_PFIFO_INTR_DMA_PTE 16
#define NV3_PFIFO_CONFIG_0 0x2200
#define NV3_PFIFO_CONFIG_0_DMA_FETCH 8
#define NV3_PFIFO_CONFIG_RAMHT 0x2210 // Hashtable for graphics objects config
#define NV3_PFIFO_CONFIG_RAMHT_BASE_ADDRESS 12
#define NV3_PFIFO_CONFIG_RAMHT_BASE_ADDRESS 12 // 15:12
#define NV3_PFIFO_CONFIG_RAMHT_BASE_ADDRESS_DEFAULT 0x0
#define NV3_PFIFO_CONFIG_RAMHT_SIZE 16
#define NV3_PFIFO_CONFIG_RAMHT_SIZE 16 // 17:16
#define NV3_PFIFO_CONFIG_RAMHT_SIZE_4K 0x0
#define NV3_PFIFO_CONFIG_RAMHT_SIZE_8K 0x1
#define NV3_PFIFO_CONFIG_RAMHT_SIZE_16K 0x2
@@ -231,8 +246,8 @@ extern const device_config_t nv3_config[];
#define NV3_PFIFO_RUNOUT_STATUS 0x2400
#define NV3_PFIFO_RUNOUT_STATUS_RANOUT 0 // 1 if we fucked up
#define NV3_PFIFO_RUNOUT_STATUS_EMPTY 4 // 1 if ramro is empty
#define NV3_PFIFO_RUNOUT_STATUS_FULL 8
#define NV3_PFIFO_RUNOUT_STATUS_EMPTY 4 // 1 if ramro is empty
#define NV3_PFIFO_RUNOUT_STATUS_FULL 8
#define NV3_PFIFO_RUNOUT_PUT 0x2410
#define NV3_PFIFO_RUNOUT_PUT_ADDRESS 3 // 9:3 if small ramfc(?) otherwise 12:3
#define NV3_PFIFO_RUNOUT_GET 0x2420
@@ -243,17 +258,18 @@ extern const device_config_t nv3_config[];
#define NV3_PFIFO_CACHE1_SIZE_REV_C 64
#define NV3_PFIFO_CACHE1_SIZE_MAX NV3_PFIFO_CACHE1_SIZE_REV_C
#define NV3_PFIFO_CACHE_REASSIGNMENT 0x2500
#define NV3_PFIFO_CACHE0_PUSH_ACCESS 0x3000
#define NV3_PFIFO_CACHE0_PUSH_CHANNEL_ID 0x3004
#define NV3_PFIFO_CACHE0_PUT 0x3010
#define NV3_PFIFO_CACHE0_STATUS 0x3014
#define NV3_PFIFO_CACHE0_STATUS_EMPTY 4 // 1 if ramro is empty
#define NV3_PFIFO_CACHE0_STATUS_FULL 8
#define NV3_PFIFO_CACHE0_STATUS_EMPTY 4 // 1 if ramro is empty
#define NV3_PFIFO_CACHE0_STATUS_FULL 8
#define NV3_PFIFO_CACHE0_PUT_ADDRESS 2 // 1 bit
#define NV3_PFIFO_CACHE0_PULLER_CONTROL 0x3040
#define NV3_PFIFO_CACHE0_PULLER_CONTROL_ENABLED 0
#define NV3_PFIFO_CACHE0_PULLER_CONTROL_HASH_SUCCESS 4
#define NV3_PFIFO_CACHE0_PULLER_CONTROL_DEVICE 8
#define NV3_PFIFO_CACHE0_PULLER_CONTROL_HASH_FAILURE 4
#define NV3_PFIFO_CACHE0_PULLER_CONTROL_SOFTWARE_METHOD 8
#define NV3_PFIFO_CACHE0_PULLER_CTX_IS_DIRTY 0x3050
#define NV3_PFIFO_CACHE0_PULLER_CTX_IS_DIRTY_BOOL 4 // 1=dirty 0=clean
#define NV3_PFIFO_CACHE0_GET 0x3070
@@ -267,8 +283,8 @@ extern const device_config_t nv3_config[];
#define NV3_PFIFO_CACHE1_PUT_ADDRESS 2 // 6:2
#define NV3_PFIFO_CACHE1_STATUS 0x3214
#define NV3_PFIFO_CACHE1_STATUS_RANOUT 0 // 1 if we fucked up
#define NV3_PFIFO_CACHE1_STATUS_EMPTY 4 // 1 if ramro is empty
#define NV3_PFIFO_CACHE1_STATUS_FULL 8
#define NV3_PFIFO_CACHE1_STATUS_EMPTY 4 // 1 if ramro is empty
#define NV3_PFIFO_CACHE1_STATUS_FULL 8
#define NV3_PFIFO_CACHE1_DMA_STATUS 0x3218
#define NV3_PFIFO_CACHE1_DMA_CONFIG_0 0x3220
#define NV3_PFIFO_CACHE1_DMA_CONFIG_1 0x3224
@@ -279,9 +295,10 @@ extern const device_config_t nv3_config[];
#define NV3_PFIFO_CACHE1_DMA_TLB_PTE 0x3234 // Base of pagetableor DMA
#define NV3_PFIFO_CACHE1_DMA_TLB_PT_BASE 0x3238 // Base of pagetable for DMA
#define NV3_PFIFO_CACHE1_PULLER_CONTROL 0x3240
//todo: merge stuff
#define NV3_PFIFO_CACHE1_PULLER_CONTROL_ENABLED 0
#define NV3_PFIFO_CACHE1_PULLER_CONTROL_HASH_SUCCESS 4
#define NV3_PFIFO_CACHE1_PULLER_CONTROL_DEVICE 8
#define NV3_PFIFO_CACHE1_PULLER_CONTROL_HASH_FAILURE 4
#define NV3_PFIFO_CACHE1_PULLER_CONTROL_SOFTWARE_METHOD 8 // 0=software, 1=hardware
#define NV3_PFIFO_CACHE1_PULLER_STATE1 0x3250
#define NV3_PFIFO_CACHE1_PULLER_CTX_IS_DIRTY 4
#define NV3_PFIFO_CACHE1_GET 0x3270
@@ -289,6 +306,7 @@ extern const device_config_t nv3_config[];
#define NV3_PFIFO_CACHE1_METHOD 0x3300
#define NV3_PFIFO_CACHE1_METHOD_ADDRESS 2 // 12:2
#define NV3_PFIFO_CACHE1_METHOD_SUBCHANNEL 13 // 15:13
#define NV3_PFIFO_END 0x3FFF
#define NV3_PRM_START 0x4000 // Real-Mode Device Support Subsystem
#define NV3_PRM_INTR 0x4100
@@ -684,9 +702,8 @@ extern const device_config_t nv3_config[];
#define NV3_CRTC_BANKED_32K_B0000 0x08
#define NV3_CRTC_BANKED_32K_B8000 0x0C
#define NV3_CRTC_REGISTER_NVIDIA_END 0x3F
// for 86box 8bit addressing
// get rid of this asap, replace with 32->8 macros
#define NV3_RMA_SIGNATURE_MSB 0x65
@@ -696,13 +713,11 @@ extern const device_config_t nv3_config[];
#define NV3_CRTC_REGISTER_RMA_MODE_MAX 0x0F
/*
STRUCTURES FOR THE GPU START HERE
OBJECT CLASS & RENDERING RELATED STUFF IS IN VID_NV3_CLASSES.H
*/
//todo: pixel format
// Master Control
@@ -712,12 +727,15 @@ typedef struct nv3_pmc_s
Holds chip manufacturing information at bootup.
Current specification (may change later): pre-packed for convenience
FIB Revision 1, Mask Revision B0, Implementation 1 [NV3], Architecture 3 [NV3], Manufacturer Nvidia, Foundry SGS (seems to have been the most common?)
31:28=0000, 27:24=0000, 23:16=0003, 15:8=0001, 7:4=0001, 3:0=0001
little endian 00000000 00000011 00000001 00010001 = 0x00300111
Revision A:
FIB Revision 1, Mask Revision B0, Implementation 1 [NV3], Architecture 3 [NV3], Manufacturer Nvidia, Foundry SGS (seems to have been the most common?)
31:28=0000, 27:24=0000, 23:16=0003, 15:8=0001, 7:4=0001, 3:0=0001
little endian 00000000 00000011 00000001 00010001 = 0x00300111#
Revision B/c:
write this later
*/
int32_t boot;
int32_t interrupt_status; // Determines if interrupts are pending for specific subsystems.
int32_t interrupt_status; // Determines if interrupts are pending for specific subsystems.
int32_t interrupt_enable; // Determines if interrupts are actually enabled.
int32_t enable; // Determines which subsystems are enabled.
@@ -776,9 +794,9 @@ typedef struct nv3_pfifo_cache_s
uint8_t get_address; // Trigger a DMA from the value you put here into where you were going.
uint8_t channel_id; // The DMA channel ID of this cache.
uint32_t status;
uint32_t status_puller;
uint32_t puller_control;
uint32_t control;
uint32_t context[8];
uint32_t context[NV3_DMA_SUBCHANNELS_PER_CHANNEL];
/* cache1 only
do we even need to emulate this?
@@ -1050,23 +1068,9 @@ typedef struct nv3_ptimer_s
uint32_t alarm; // The value of time when there should be an alarm
} nv3_ptimer_t;
typedef struct nv3_ramin_name_s
{
union
{
uint32_t name;
struct
{
uint8_t byte_high;
uint8_t byte_mid2;
uint8_t byte_mid1;
uint8_t byte_low;
};
};
} nv3_ramin_name_t;
// Object name is just a uint32_t identifier it doesn't need a struct
// This is howt he cotnext is represented in ramin
// IN PGRAPH IT IS DIFFERENT! ONLY 5 BITS FOR THE CLASS ID! WHY?
typedef struct nv3_ramin_context_s
{
union
@@ -1075,11 +1079,11 @@ typedef struct nv3_ramin_context_s
struct
{
uint8_t dma_channel;
uint8_t render_object; //0=sw, 1=hw accelerated render
uint8_t class_id;
uint8_t ramin_offset; //find
bool reserved : 1;
uint8_t channel_id : 7;
bool is_rendering : 1;
uint8_t class_id : 7;
uint16_t ramin_offset;
};
};
@@ -1088,7 +1092,7 @@ typedef struct nv3_ramin_context_s
// Graphics object hashtable for specific DMA [channel, subchannel] pair
typedef struct nv3_ramin_ramht_subchannel_s
{
nv3_ramin_name_t name; // must be >4096
uint32_t name; // must be >4096
// Contextual information.
// See the above union.
@@ -1193,10 +1197,13 @@ typedef struct nv3_s
} nv3_t;
// device objects
// device object
extern nv3_t* nv3;
// NV3 stuff
/*
*FUNCTIONS* for the GPU core start here
Functions for PGRAPH objects are in vid_nv3_classes.h
*/
// Device Core
void* nv3_init(const device_t *info);
@@ -1229,8 +1236,8 @@ bool nv3_ramin_arbitrate_read(uint32_t address, uint32_t* value); /
bool nv3_ramin_arbitrate_write(uint32_t address, uint32_t value); // Write arbitration so we can read/write to the structures in the first 64k of ramin
// RAMIN functions
uint32_t nv3_ramht_hash(nv3_ramin_name_t name, uint32_t channel);
void nv3_ramin_find_object(uint32_t name, uint32_t cache_id, uint32_t channel_id, uint32_t subchannel_id);
uint32_t nv3_ramht_hash(uint32_t name, uint32_t channel);
bool nv3_ramin_find_object(uint32_t name, uint32_t cache_num, uint32_t channel_id, uint32_t subchannel_id);
uint32_t nv3_ramfc_read(uint32_t address);
void nv3_ramfc_write(uint32_t address, uint32_t value);
@@ -1310,6 +1317,7 @@ void nv3_pgraph_vblank_start(svga_t* svga);
void nv3_pfifo_init();
uint32_t nv3_pfifo_read(uint32_t address);
void nv3_pfifo_write(uint32_t address, uint32_t value);
void nv3_pfifo_interrupt(uint32_t id, bool fire_now);
// NV3 PFIFO - Caches
void nv3_pfifo_cache0_push();

View File

@@ -36,14 +36,15 @@
#include <86box/log.h>
typedef struct log_t {
char buff[1024];
char *dev_name;
int seen;
int suppr_seen;
char** cyclic_buff;
int32_t cyclic_last_line;
int32_t log_cycles;
int32_t last_repeat_order;
char buff[1024];
char dev_name[1024];
int seen;
int suppr_seen;
/* Cyclical log buffer. */
char **cyclic_buff;
int32_t cyclic_last_line;
int32_t log_cycles;
int32_t last_repeat_order;
} log_t;
/* File to log output to. */

View File

@@ -6,7 +6,7 @@
*
* This file is part of the 86Box distribution.
*
* NV3 PBUS DMA: DMA Engine
* NV3 PBUS DMA: DMA & Notifier Engine
*
*
*

View File

@@ -433,7 +433,15 @@ void nv3_pfifo_cache0_push()
void nv3_pfifo_cache0_pull()
{
// Do nothing if PFIFO CACHE0 is disabled
if (!nv3->pfifo.cache0_settings.puller_control & (1 >> NV3_PFIFO_CACHE0_PULLER_CONTROL_ENABLED))
return;
// Do nothing if there is nothing in cache0 to pull
if (nv3->pfifo.cache0_settings.put_address == nv3->pfifo.cache0_settings.get_address)
return;
// There is only one entry
}
void nv3_pfifo_cache1_push()
@@ -443,7 +451,13 @@ void nv3_pfifo_cache1_push()
void nv3_pfifo_cache1_pull()
{
// Do nothing if PFIFO CACHE1 is disabled
if (!nv3->pfifo.cache1_settings.puller_control & (1 >> NV3_PFIFO_CACHE1_PULLER_CONTROL_ENABLED))
return;
// Do nothing if there is nothing in cache1 to pull
if (nv3->pfifo.cache1_settings.put_address == nv3->pfifo.cache1_settings.get_address)
return;
}
bool nv3_pfifo_cache1_is_free()

View File

@@ -23,11 +23,17 @@
#include <86Box/86box.h>
#include <86Box/device.h>
#include <86Box/mem.h>
#include <86box/pci.h>
#include <86Box/pci.h>
#include <86Box/rom.h> // DEPENDENT!!!
#include <86Box/video.h>
#include <86Box/nv/vid_nv.h>
#include <86Box/nv/vid_nv3.h>
#include <86box/nv/classes/vid_nv3_classes.h>
// Functions only used in this translation unit
#ifndef RELEASE_BUILD
void nv3_debug_ramin_print_context_info(uint32_t name, nv3_ramin_context_t context);
#endif
// i believe the main loop is to walk the hashtable in RAMIN (last 0.5 MB of VRAM),
// find the objects that were submitted from DMA
@@ -190,6 +196,12 @@ void nv3_ramin_write32(uint32_t addr, uint32_t val, void* priv)
}
void nv3_pfifo_interrupt(uint32_t id, bool fire_now)
{
nv3->pfifo.interrupt_status |= (1 << id);
nv3_pmc_handle_interrupts(fire_now);
}
/*
RAMIN access arbitration functions
Arbitrates reads and writes to RAMFC (unused dma context storage), RAMRO (invalid object submission location), RAMHT (hashtable for graphics objectstorage) (RAMAU?)
@@ -311,6 +323,7 @@ bool nv3_ramin_arbitrate_write(uint32_t address, uint32_t value)
break;
}
// send the addresses to the right part
if (address >= ramht_start
&& address <= ramht_end)
{
@@ -334,7 +347,151 @@ bool nv3_ramin_arbitrate_write(uint32_t address, uint32_t value)
}
// THIS IS THE MOST IMPORTANT FUNCTION!
void nv3_ramin_find_object(uint32_t name, uint32_t cache_id, uint32_t channel_id, uint32_t subchannel_id)
bool nv3_ramin_find_object(uint32_t name, uint32_t cache_num, uint32_t channel_id, uint32_t subchannel_id)
{
// TODO: WRITE IT!!!
}
// Set the number of entries to search based on the ramht size (2*(size+1))
// Not a switch statement in case newer gpus have larger ramins
uint32_t bucket_entries = 2 * (((nv3->pfifo.ramht_config >> NV3_PFIFO_CONFIG_RAMHT_SIZE) & 0x03) + 1);
// Calculate the address in the hashtable
uint32_t ramht_base = ((nv3->pfifo.ramht_config >> NV3_PFIFO_CONFIG_RAMHT_BASE_ADDRESS) & 0x0F) << NV3_PFIFO_CONFIG_RAMHT_BASE_ADDRESS;
uint32_t ramht_cur_address = ramht_base;
nv_log("NV3: Beginning search for graphics object at RAMHT base=0x%04x, Cache%d, channel=%d, subchannel=%d)", name, cache_num, channel_id, subchannel_id);
bool found_object = false;
// set up some variables
uint32_t found_obj_name;
nv3_ramin_context_t obj_context_struct;
for (uint32_t bucket_entry = 0; bucket_entry < bucket_entries; bucket_entry++)
{
found_obj_name = nv3_ramin_read32(ramht_cur_address, NULL);
ramht_cur_address += 0x04;
uint32_t obj_context = nv3_ramin_read32(ramht_cur_address, NULL);
ramht_cur_address += 0x04;
obj_context_struct = *(nv3_ramin_context_t*)&obj_context;
// see if the object is in the right channel
if (found_obj_name == name
&& obj_context_struct.channel_id == channel_id)
{
found_object = true;
break;
}
}
if (!found_object)
{
if (!cache_num)
{
nv3->pfifo.debug_0 |= NV3_PFIFO_CACHE0_ERROR_PENDING;
nv3->pfifo.cache0_settings.puller_control |= NV3_PFIFO_CACHE0_PULLER_CONTROL_HASH_FAILURE;
//It turns itself off on failure, the drivers turn it back on
nv3->pfifo.cache0_settings.puller_control &= ~NV3_PFIFO_CACHE0_PULLER_CONTROL_ENABLED;
}
else
{
nv3->pfifo.debug_0 |= NV3_PFIFO_CACHE1_ERROR_PENDING;
nv3->pfifo.cache1_settings.puller_control |= NV3_PFIFO_CACHE1_PULLER_CONTROL_HASH_FAILURE;
//It turns itself off on failure, the drivers turn it back on
nv3->pfifo.cache1_settings.puller_control &= ~NV3_PFIFO_CACHE1_PULLER_CONTROL_ENABLED;
}
nv3_pfifo_interrupt(NV3_PFIFO_INTR_CACHE_ERROR, true);
return false;
}
// So we did find an object.
// Now try to read some of this...
// Class ID is 5 bits in all other parts of the gpu but 7 bits here. A move in a direction that didn't pan out?
// Represented as 0x40-0x5f? Some other meaning
// Perform more validation
if (obj_context_struct.class_id > NV3_PFIFO_FIRST_VALID_GRAPHICS_OBJECT_ID
|| obj_context_struct.class_id < NV3_PFIFO_LAST_VALID_GRAPHICS_OBJECT_ID)
{
fatal("NV3: Invalid graphics object class ID name=0x%04x type=%04x, interpreted by pgraph as: %04x (Contact starfrost)",
name, obj_context_struct.class_id, obj_context_struct.class_id & 0x1F);
}
else if (obj_context_struct.channel_id > NV3_DMA_CHANNELS)
fatal("NV3: Super fucked up graphics object. Contact starfrost with the error string: DMA Channel ID=%d, it should be 0-8", obj_context_struct.channel_id);
// Illegal accesses sent to RAMRO, so ignore here
// TODO: SEND THESE TO RAMRO!!!!!
#ifndef RELEASE_BUILD
nv3_debug_ramin_print_context_info(name, obj_context_struct);
#endif
// By definition we can't have a cache error by here so take it off
if (!cache_num)
nv3->pfifo.cache0_settings.puller_control &= ~NV3_PFIFO_CACHE0_PULLER_CONTROL_HASH_FAILURE;
else
nv3->pfifo.cache1_settings.puller_control &= ~NV3_PFIFO_CACHE1_PULLER_CONTROL_HASH_FAILURE;
// Caches store all the subchannels for our current dma channel and basically get stale every context switch
// Also we have to check that a osftware object didn't end up in here...
bool is_software = false;
if (!cache_num)
is_software = (nv3->pfifo.cache0_settings.context[subchannel_id] & 0x800000);
else
is_software = (nv3->pfifo.cache1_settings.context[subchannel_id] & 0x800000);
// This isn't an error but it's sent as an interrupt so the drivers can sync
if (is_software)
{
// handle it as an error
if (!cache_num)
{
nv3->pfifo.cache0_settings.puller_control |= NV3_PFIFO_CACHE0_PULLER_CONTROL_SOFTWARE_METHOD;
nv3->pfifo.cache0_settings.puller_control &= ~NV3_PFIFO_CACHE0_PULLER_CONTROL_ENABLED;
}
else
{
nv3->pfifo.cache1_settings.puller_control |= NV3_PFIFO_CACHE1_PULLER_CONTROL_SOFTWARE_METHOD;
nv3->pfifo.cache0_settings.puller_control &= ~NV3_PFIFO_CACHE1_PULLER_CONTROL_ENABLED;
}
// It's an error but it isn't lol
nv3_pfifo_interrupt(NV3_PFIFO_INTR_CACHE_ERROR, true);
}
else
{
// obviously turn off the "is software" if it's not
if (!cache_num)
nv3->pfifo.cache0_settings.puller_control &= ~NV3_PFIFO_CACHE0_PULLER_CONTROL_SOFTWARE_METHOD;
else
nv3->pfifo.cache1_settings.puller_control &= ~NV3_PFIFO_CACHE1_PULLER_CONTROL_SOFTWARE_METHOD;
}
// Ok we found it. Lol
return true;
}
#ifndef RELEASE_BUILD
// Prints out some informaiton about the object
void nv3_debug_ramin_print_context_info(uint32_t name, nv3_ramin_context_t context)
{
nv_log("NV3: Found object:");
nv_log("Name: 0x%04x", name);
nv_log("Context:");
nv_log("DMA Channel %d (0-7 valid)", context.channel_id);
nv_log("Class ID: as repreesnted in ramin=%04x, Stupid 5 bit version (the actual id)=0x%04x (%s)", context.class_id,
context.class_id & 0x1F, nv3_class_names[context.class_id & 0x1F]);
nv_log("Render Engine %d (0=Software, also DMA? 1=Accelerated Renderer)", context.is_rendering);
nv_log("PRAMIN Offset 0x%08x", context.ramin_offset << 4);
}
#endif

View File

@@ -22,7 +22,7 @@
#include <86Box/86box.h>
#include <86Box/device.h>
#include <86Box/mem.h>
#include <86box/pci.h>
#include <86Box/pci.h>
#include <86Box/rom.h> // DEPENDENT!!!
#include <86Box/video.h>
#include <86Box/nv/vid_nv.h>
@@ -32,10 +32,14 @@
It is used to get the offset within RAMHT of a graphics object.
*/
uint32_t nv3_ramht_hash(nv3_ramin_name_t name, uint32_t channel)
uint32_t nv3_ramht_hash(uint32_t name, uint32_t channel)
{
uint32_t hash = (name.byte_high ^ name.byte_mid2 ^ name.byte_mid1 ^ name.byte_low ^ (uint8_t)channel);
nv_log("NV3: Generating RAMHT hash (RAMHT slot=0x%04x (from name 0x%08x for DMA channel 0x%04x)\n)\n", name, channel);
// convert the name to an array of bytes
uint8_t* hash_bytes = (uint8_t*)name;
// is this the right endianness?
uint32_t hash = (hash_bytes[0] ^ hash_bytes[1] ^ hash_bytes[2] ^ hash_bytes[3] ^ (uint8_t)channel);
nv_log("NV3: Generated RAMHT hash 0x%04x (RAMHT slot=0x%04x (from name 0x%08x for DMA channel 0x%04x)\n)\n", hash, name, channel);
return hash;
}