mirror of
https://github.com/86Box/86Box.git
synced 2026-02-24 02:18:20 -07:00
Fix put addresses
This commit is contained in:
@@ -618,6 +618,17 @@ extern const device_config_t nv3_config[];
|
||||
#define NV3_PGRAPH_CLASS1C_MEM2IMAGE_START 0x5C0000 // class 55, 56, 62, 63?
|
||||
#define NV3_PGRAPH_CLASS1C_MEM2IMAGE_END 0x5C1FFF
|
||||
|
||||
/*
|
||||
OBJECT METHODS
|
||||
*/
|
||||
|
||||
// Global stuff
|
||||
#define NV3_ROOT_HI_IM_OBJECT_MCOBJECTYFACE 0x0 // I'm going insane at 00:48 14/02/2025
|
||||
#define NV3_SET_NOTIFY_CONTEXT_FOR_DMA 0x100 // Set object ctx for dma...see nv3_dma_context_t structure
|
||||
#define NV3_SET_NOTIFY 0x104
|
||||
|
||||
#define NV3_W95TXT_COLORA 0x3FC // It's the colour of the text. This is used to submit a dummy object so the notifier can be used to sync in Win2000 DDraw6 drivers.
|
||||
|
||||
#define NV3_PGRAPH_REGISTER_END 0x401FFF // end of pgraph registers
|
||||
#define NV3_PGRAPH_REAL_END 0x5C1FFF
|
||||
|
||||
@@ -724,9 +735,6 @@ extern const device_config_t nv3_config[];
|
||||
|
||||
// not done
|
||||
|
||||
// Master Control
|
||||
|
||||
|
||||
// CRTC/CIO (0x3b0-0x3df)
|
||||
|
||||
#define NV3_CRTC_DATA_OUT 0x3C0
|
||||
@@ -810,6 +818,8 @@ 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
|
||||
@@ -1358,9 +1368,9 @@ bool nv3_ramin_arbitrate_write(uint32_t address, uint32_t value); /
|
||||
|
||||
// RAMIN functions
|
||||
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);
|
||||
bool nv3_ramin_find_object(uint32_t name, uint32_t cache_num, uint8_t channel_id, uint8_t subchannel_id);
|
||||
#ifndef RELEASE_BUILD
|
||||
void nv3_debug_ramin_print_context_info(uint32_t name, nv3_ramin_context_t context);
|
||||
void nv3_debug_ramin_print_context_info(uint32_t name, nv3_ramin_context_t context);
|
||||
#endif
|
||||
|
||||
uint32_t nv3_ramfc_read(uint32_t address);
|
||||
|
||||
@@ -32,4 +32,9 @@
|
||||
void nv3_generic_method(uint32_t method_id, nv3_grobj_t grobj)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void nv3_notify()
|
||||
{
|
||||
|
||||
}
|
||||
@@ -500,13 +500,13 @@ Back to sanity
|
||||
uint32_t nv3_pfifo_cache1_gray2normal(uint32_t val)
|
||||
{
|
||||
uint32_t mask = val >> 1;
|
||||
|
||||
|
||||
// shift right until we have our normla number again
|
||||
while (mask)
|
||||
{
|
||||
// NT4 drivers v1.29 do this the other way around??
|
||||
val ^= mask;
|
||||
// Algorithm from NT4 drivers, version 1.29
|
||||
mask >>= 1;
|
||||
val ^= mask;
|
||||
}
|
||||
|
||||
return val;
|
||||
@@ -530,11 +530,11 @@ void nv3_pfifo_cache0_pull()
|
||||
return;
|
||||
|
||||
// There is only one entry for cache0
|
||||
uint16_t current_channel = nv3->pfifo.cache0_settings.channel;
|
||||
uint32_t current_subchannel = nv3->pfifo.cache0_entry.subchannel;
|
||||
uint8_t current_channel = nv3->pfifo.cache0_settings.channel;
|
||||
uint8_t current_subchannel = nv3->pfifo.cache0_entry.subchannel;
|
||||
uint32_t current_name = nv3->pfifo.cache0_entry.data;
|
||||
uint32_t current_method = nv3->pfifo.cache0_entry.method;
|
||||
|
||||
uint16_t current_method = nv3->pfifo.cache0_entry.method;
|
||||
|
||||
// i.e. there is no method in cache0, so we have to find the object.
|
||||
if (!current_method)
|
||||
{
|
||||
@@ -543,6 +543,7 @@ void nv3_pfifo_cache0_pull()
|
||||
}
|
||||
|
||||
uint32_t current_context = nv3->pfifo.cache0_settings.context[0]; // only 1 entry for CACHE0 so basically ignore the other context entries?
|
||||
uint8_t class_id = ((nv3_ramin_context_t*)¤t_context)->class_id;
|
||||
|
||||
// Tell the CPU if we found a software method
|
||||
if (current_context & 0x800000)
|
||||
@@ -594,6 +595,8 @@ void nv3_pfifo_cache1_push(uint32_t addr, uint32_t val)
|
||||
{
|
||||
oh_shit = true;
|
||||
oh_shit_reason = nv3_runout_reason_no_cache_available;
|
||||
new_address |= (nv3_runout_reason_no_cache_available << NV3_PFIFO_RUNOUT_RAMIN_ERR);
|
||||
|
||||
}
|
||||
|
||||
// Check if runout is full
|
||||
@@ -627,7 +630,7 @@ void nv3_pfifo_cache1_push(uint32_t addr, uint32_t val)
|
||||
{
|
||||
// Cache reassignment required
|
||||
if (!nv3->pfifo.cache_reassignment
|
||||
|| (nv3->pfifo.cache0_settings.get_address != nv3->pfifo.cache0_settings.get_address))
|
||||
|| (nv3->pfifo.cache1_settings.get_address != nv3->pfifo.cache1_settings.get_address))
|
||||
{
|
||||
oh_shit = true;
|
||||
oh_shit_reason = nv3_runout_reason_no_cache_available;
|
||||
@@ -654,13 +657,13 @@ void nv3_pfifo_cache1_push(uint32_t addr, uint32_t val)
|
||||
uint32_t next_put_address = nv3_pfifo_cache1_gray2normal(current_put_address) + 1;
|
||||
|
||||
if (nv3->nvbase.gpu_revision >= NV3_BOOT_REG_REV_C00) // RIVA 128ZX#
|
||||
next_put_address &= NV3_PFIFO_CACHE1_SIZE_REV_C;
|
||||
next_put_address &= (NV3_PFIFO_CACHE1_SIZE_REV_C - 1);
|
||||
else
|
||||
next_put_address &= NV3_PFIFO_CACHE1_SIZE_REV_AB;
|
||||
next_put_address &= (NV3_PFIFO_CACHE1_SIZE_REV_AB - 1);
|
||||
|
||||
nv3->pfifo.cache1_settings.put_address = nv3_pfifo_cache1_normal2gray(next_put_address);
|
||||
nv3->pfifo.cache1_settings.put_address = nv3_pfifo_cache1_normal2gray(next_put_address) << 2;
|
||||
|
||||
nv_log("Submitted object [PIO]: Channel %d, Subchannel %d, Method ID 0x%04x (Put Address is now %d)\n",
|
||||
nv_log("Submitted object [PIO]: Channel %d.%d, Method ID 0x%04x (Put Address is now %d)\n",
|
||||
channel, subchannel, method_offset, nv3->pfifo.cache1_settings.put_address);
|
||||
|
||||
// Now we're done. Phew!
|
||||
@@ -679,25 +682,27 @@ void nv3_pfifo_cache1_pull()
|
||||
|
||||
uint32_t get_address = nv3->pfifo.cache1_settings.get_address >> 2; // 32 bit aligned probably
|
||||
|
||||
uint16_t current_channel = nv3->pfifo.cache1_settings.channel;
|
||||
uint32_t current_subchannel = nv3->pfifo.cache1_entries[get_address].subchannel;
|
||||
uint8_t current_channel = nv3->pfifo.cache1_settings.channel;
|
||||
uint8_t current_subchannel = nv3->pfifo.cache1_entries[get_address].subchannel;
|
||||
uint32_t current_name = nv3->pfifo.cache1_entries[get_address].data;
|
||||
uint32_t current_method = nv3->pfifo.cache1_entries[get_address].method;
|
||||
uint16_t current_method = nv3->pfifo.cache1_entries[get_address].method;
|
||||
|
||||
// i.e. there is no method in cache0, so we have to find the object.
|
||||
// i.e. there is no method in cache1, so we have to find the object.
|
||||
if (!current_method)
|
||||
{
|
||||
if (!nv3_ramin_find_object(current_name, 0, current_channel, current_subchannel))
|
||||
return; // interrupt was fired, and we went to ramro
|
||||
}
|
||||
|
||||
uint32_t current_context = nv3->pfifo.cache0_settings.context[current_subchannel]; // only 1 entry for CACHE0 so basically ignore the other context entries?
|
||||
uint32_t current_context = nv3->pfifo.cache1_settings.context[current_subchannel]; // get the current subchannel
|
||||
|
||||
uint8_t class_id = ((nv3_ramin_context_t*)¤t_context)->class_id;
|
||||
|
||||
// Tell the CPU if we found a software method
|
||||
if (current_context & 0x800000)
|
||||
{
|
||||
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;
|
||||
nv3->pfifo.cache1_settings.puller_control |= NV3_PFIFO_CACHE0_PULLER_CONTROL_SOFTWARE_METHOD;
|
||||
nv3->pfifo.cache1_settings.puller_control &= ~NV3_PFIFO_CACHE0_PULLER_CONTROL_ENABLED;
|
||||
nv3_pfifo_interrupt(NV3_PFIFO_INTR_CACHE_ERROR, true);
|
||||
}
|
||||
|
||||
@@ -705,12 +710,12 @@ void nv3_pfifo_cache1_pull()
|
||||
uint32_t next_get_address = nv3_pfifo_cache1_gray2normal(get_address) + 1;
|
||||
|
||||
if (nv3->nvbase.gpu_revision >= NV3_BOOT_REG_REV_C00) // RIVA 128ZX#
|
||||
next_get_address &= NV3_PFIFO_CACHE1_SIZE_REV_C;
|
||||
next_get_address &= (NV3_PFIFO_CACHE1_SIZE_REV_C - 1);
|
||||
else
|
||||
next_get_address &= NV3_PFIFO_CACHE1_SIZE_REV_AB;
|
||||
next_get_address &= (NV3_PFIFO_CACHE1_SIZE_REV_AB - 1);
|
||||
|
||||
// Is this needed?
|
||||
nv3->pfifo.cache0_settings.get_address = nv3_pfifo_cache1_normal2gray(next_get_address) << 2;
|
||||
nv3->pfifo.cache1_settings.get_address = nv3_pfifo_cache1_normal2gray(next_get_address) << 2;
|
||||
|
||||
#ifndef RELEASE_BUILD
|
||||
nv_log("***** OBJECT PULLED, SUBMITTING GRAPHICS COMMANDS CURRENTLY UNIMPLEMENTED - ****** Contextual information below\n");
|
||||
|
||||
@@ -468,7 +468,16 @@ void nv3_pgraph_vblank_start(svga_t* svga)
|
||||
nv3_pgraph_interrupt_valid(NV3_PGRAPH_INTR_EN_0_VBLANK);
|
||||
}
|
||||
|
||||
void nv3_pgraph_submit()
|
||||
/* Arbitrates graphics object submission to the right object types */
|
||||
void nv3_pgraph_submit(uint8_t name, uint16_t method, uint8_t channel, uint8_t subchannel, uint8_t class_id, uint32_t context)
|
||||
{
|
||||
// class id can be derived from the context but we debug log it before we get here
|
||||
|
||||
switch (method)
|
||||
{
|
||||
// This method is how we figure out which methods exist.
|
||||
case NV3_ROOT_HI_IM_OBJECT_MCOBJECTYFACE:
|
||||
nv_log("Hi, I'm an NV []");
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -347,7 +347,7 @@ bool nv3_ramin_arbitrate_write(uint32_t address, uint32_t value)
|
||||
}
|
||||
|
||||
// THIS IS THE MOST IMPORTANT FUNCTION!
|
||||
bool nv3_ramin_find_object(uint32_t name, uint32_t cache_num, uint32_t channel, uint32_t subchannel)
|
||||
bool nv3_ramin_find_object(uint32_t name, uint32_t cache_num, uint8_t channel, uint8_t subchannel)
|
||||
{
|
||||
// TODO: WRITE IT!!!
|
||||
// Set the number of entries to search based on the ramht size (2*(size+1))
|
||||
|
||||
Reference in New Issue
Block a user