mirror of
https://github.com/86Box/86Box.git
synced 2026-02-24 02:18:20 -07:00
Implement put/get registers. Also, bit numbering is hard.
This commit is contained in:
@@ -14,7 +14,7 @@
|
||||
* Also check the doc folder for some more notres
|
||||
*
|
||||
* vid_nv3.h: NV3 Architecture Hardware Reference (open-source)
|
||||
* Last updated: 26 February 2025 (STILL WORKING ON IT!!!)
|
||||
* Last updated: 11 March 2025 (STILL WORKING ON IT!!!)
|
||||
*
|
||||
* Authors: Connor Hyde <mario64crashed@gmail.com>
|
||||
*
|
||||
@@ -977,7 +977,7 @@ typedef struct nv3_pfifo_s
|
||||
uint32_t runout_get; // 8:3 if RAMRO=512b, otherwise 12:3
|
||||
|
||||
// Cache stuff
|
||||
uint32_t cache_reassignment; // Enable automatic reassignment into CACHE0?
|
||||
uint32_t cache_reassignment; // Allow context switching
|
||||
nv3_pfifo_cache_t cache0_settings;
|
||||
nv3_pfifo_cache_t cache1_settings;
|
||||
|
||||
@@ -1213,13 +1213,12 @@ typedef struct nv3_ramin_context_s
|
||||
|
||||
struct
|
||||
{
|
||||
bool reserved : 1;
|
||||
uint8_t channel : 7;
|
||||
bool is_rendering : 1;
|
||||
uint8_t class_id : 7;
|
||||
uint16_t ramin_offset;
|
||||
uint8_t class_id : 7;
|
||||
bool is_rendering : 1;
|
||||
uint8_t channel : 7;
|
||||
bool reserved : 1;
|
||||
};
|
||||
|
||||
};
|
||||
} nv3_ramin_context_t;
|
||||
|
||||
|
||||
@@ -201,8 +201,17 @@ uint32_t nv3_pfifo_read(uint32_t address)
|
||||
ret = ((nv3->pfifo.cache1_settings.method_subchannel << 13) & 0x07)
|
||||
| ((nv3->pfifo.cache1_settings.method_address << 2) & 0x7FF);
|
||||
break;
|
||||
case NV3_PFIFO_CACHE0_PUT:
|
||||
ret = nv3->pfifo.cache0_settings.put_address;
|
||||
break;
|
||||
case NV3_PFIFO_CACHE0_GET:
|
||||
//wa
|
||||
ret = nv3->pfifo.cache0_settings.get_address;
|
||||
break;
|
||||
case NV3_PFIFO_CACHE1_PUT:
|
||||
ret = nv3->pfifo.cache1_settings.put_address;
|
||||
break;
|
||||
case NV3_PFIFO_CACHE1_GET:
|
||||
ret = nv3->pfifo.cache1_settings.get_address;
|
||||
break;
|
||||
// Reassignment
|
||||
case NV3_PFIFO_CACHE_REASSIGNMENT:
|
||||
@@ -324,7 +333,7 @@ void nv3_pfifo_trigger_dma_if_required()
|
||||
}
|
||||
}
|
||||
|
||||
void nv3_pfifo_write(uint32_t address, uint32_t value)
|
||||
void nv3_pfifo_write(uint32_t address, uint32_t val)
|
||||
{
|
||||
// before doing anything, check the subsystem enablement
|
||||
|
||||
@@ -337,14 +346,14 @@ void nv3_pfifo_write(uint32_t address, uint32_t value)
|
||||
|
||||
nv_register_t* reg = nv_get_register(address, pfifo_registers, sizeof(pfifo_registers)/sizeof(pfifo_registers[0]));
|
||||
|
||||
nv_log("PFIFO Write 0x%08x -> 0x%08x", value, address);
|
||||
nv_log("PFIFO Write 0x%08x -> 0x%08x", val, address);
|
||||
|
||||
// if the register actually exists
|
||||
if (reg)
|
||||
{
|
||||
// on-read function
|
||||
if (reg->on_write)
|
||||
reg->on_write(value);
|
||||
reg->on_write(val);
|
||||
else
|
||||
{
|
||||
switch (reg->address)
|
||||
@@ -356,7 +365,7 @@ void nv3_pfifo_write(uint32_t address, uint32_t value)
|
||||
// Bit 12 - DMA Pusher
|
||||
// Bit 16 - DMA Page Table Entry (pagefault?)
|
||||
case NV3_PFIFO_INTR:
|
||||
nv3->pfifo.interrupt_status &= ~value;
|
||||
nv3->pfifo.interrupt_status &= ~val;
|
||||
nv3_pmc_clear_interrupts();
|
||||
|
||||
// update the internal cache error state
|
||||
@@ -364,21 +373,21 @@ void nv3_pfifo_write(uint32_t address, uint32_t value)
|
||||
nv3->pfifo.debug_0 &= ~NV3_PFIFO_INTR_CACHE_ERROR;
|
||||
break;
|
||||
case NV3_PFIFO_INTR_EN:
|
||||
nv3->pfifo.interrupt_enable = value & 0x00011111;
|
||||
nv3->pfifo.interrupt_enable = val & 0x00011111;
|
||||
nv3_pmc_handle_interrupts(true);
|
||||
break;
|
||||
case NV3_PFIFO_DELAY_0:
|
||||
nv3->pfifo.dma_delay_retry = value;
|
||||
nv3->pfifo.dma_delay_retry = val;
|
||||
break;
|
||||
case NV3_PFIFO_CONFIG_0:
|
||||
nv3->pfifo.config_0 = value;
|
||||
nv3->pfifo.config_0 = val;
|
||||
break;
|
||||
|
||||
case NV3_PFIFO_CONFIG_RAMHT:
|
||||
nv3->pfifo.ramht_config = value;
|
||||
nv3->pfifo.ramht_config = val;
|
||||
// This code sucks a bit fix it later
|
||||
#ifdef ENABLE_NV_LOG
|
||||
uint32_t new_size_ramht = ((value >> 16) & 0x03);
|
||||
uint32_t new_size_ramht = ((val >> 16) & 0x03);
|
||||
|
||||
if (new_size_ramht == 0)
|
||||
new_size_ramht = 0x1000;
|
||||
@@ -395,15 +404,15 @@ void nv3_pfifo_write(uint32_t address, uint32_t value)
|
||||
#endif
|
||||
break;
|
||||
case NV3_PFIFO_CONFIG_RAMFC:
|
||||
nv3->pfifo.ramfc_config = value;
|
||||
nv3->pfifo.ramfc_config = val;
|
||||
|
||||
nv_log("RAMFC Reconfiguration\n"
|
||||
"Base Address in RAMIN: %d\n", ((nv3->pfifo.ramfc_config >> NV3_PFIFO_CONFIG_RAMFC_BASE_ADDRESS) & 0x7F) << 9);
|
||||
break;
|
||||
case NV3_PFIFO_CONFIG_RAMRO:
|
||||
nv3->pfifo.ramro_config = value;
|
||||
nv3->pfifo.ramro_config = val;
|
||||
|
||||
uint32_t new_size_ramro = ((value >> NV3_PFIFO_CONFIG_RAMRO_SIZE) & 0x01);
|
||||
uint32_t new_size_ramro = ((val >> NV3_PFIFO_CONFIG_RAMRO_SIZE) & 0x01);
|
||||
|
||||
if (new_size_ramro == 0)
|
||||
new_size_ramro = 0x200;
|
||||
@@ -415,86 +424,99 @@ void nv3_pfifo_write(uint32_t address, uint32_t value)
|
||||
"Size: 0x%08x bytes\n", ((nv3->pfifo.ramro_config >> NV3_PFIFO_CONFIG_RAMRO_BASE_ADDRESS) & 0x7F) << 9, new_size_ramro);
|
||||
break;
|
||||
case NV3_PFIFO_DEBUG_0:
|
||||
nv3->pfifo.debug_0 = value;
|
||||
nv3->pfifo.debug_0 = val;
|
||||
break;
|
||||
// Reassignment
|
||||
case NV3_PFIFO_CACHE_REASSIGNMENT:
|
||||
nv3->pfifo.cache_reassignment = value & 0x01; //1bit meaningful
|
||||
nv3->pfifo.cache_reassignment = val & 0x01; //1bit meaningful
|
||||
break;
|
||||
// Control
|
||||
case NV3_PFIFO_CACHE0_PULLER_CONTROL:
|
||||
nv3->pfifo.cache0_settings.puller_control = value; // 8bits meaningful
|
||||
nv3->pfifo.cache0_settings.puller_control = val; // 8bits meaningful
|
||||
break;
|
||||
case NV3_PFIFO_CACHE1_PULL0:
|
||||
nv3->pfifo.cache1_settings.puller_control = value; // 8bits meaningful
|
||||
nv3->pfifo.cache1_settings.puller_control = val; // 8bits meaningful
|
||||
break;
|
||||
case NV3_PFIFO_CACHE0_PULLER_CTX_STATE:
|
||||
nv3->pfifo.cache0_settings.context_is_dirty = (value >> NV3_PFIFO_CACHE0_PULLER_CTX_STATE_DIRTY) & 0x01;
|
||||
nv3->pfifo.cache0_settings.context_is_dirty = (val >> NV3_PFIFO_CACHE0_PULLER_CTX_STATE_DIRTY) & 0x01;
|
||||
break;
|
||||
case NV3_PFIFO_CACHE1_PULLER_CTX_STATE:
|
||||
nv3->pfifo.cache1_settings.context_is_dirty = (value >> NV3_PFIFO_CACHE0_PULLER_CTX_STATE_DIRTY) & 0x01;
|
||||
nv3->pfifo.cache1_settings.context_is_dirty = (val >> NV3_PFIFO_CACHE0_PULLER_CTX_STATE_DIRTY) & 0x01;
|
||||
break;
|
||||
case NV3_PFIFO_CACHE0_DMA_PUSH0:
|
||||
nv3->pfifo.cache0_settings.dma_push0 = value;
|
||||
nv3->pfifo.cache0_settings.dma_push0 = val;
|
||||
break;
|
||||
case NV3_PFIFO_CACHE1_DMA_PUSH0:
|
||||
nv3->pfifo.cache1_settings.dma_push0 = value;
|
||||
nv3->pfifo.cache1_settings.dma_push0 = val;
|
||||
break;
|
||||
case NV3_PFIFO_CACHE0_PUSH_CHANNEL_ID:
|
||||
nv3->pfifo.cache0_settings.channel = value;
|
||||
nv3->pfifo.cache0_settings.channel = val;
|
||||
break;
|
||||
case NV3_PFIFO_CACHE1_PUSH_CHANNEL_ID:
|
||||
nv3->pfifo.cache1_settings.channel = value;
|
||||
nv3->pfifo.cache1_settings.channel = val;
|
||||
break;
|
||||
// CACHE0_STATUS and CACHE1_STATUS are not writable
|
||||
case NV3_PFIFO_CACHE0_METHOD:
|
||||
nv3->pfifo.cache0_settings.method_subchannel = (value >> 13) & 0x07;
|
||||
nv3->pfifo.cache0_settings.method_address = (value >> 2) & 0x7FF;
|
||||
nv3->pfifo.cache0_settings.method_subchannel = (val >> 13) & 0x07;
|
||||
nv3->pfifo.cache0_settings.method_address = (val >> 2) & 0x7FF;
|
||||
break;
|
||||
case NV3_PFIFO_CACHE1_METHOD:
|
||||
nv3->pfifo.cache1_settings.method_subchannel = (value >> 13) & 0x07;
|
||||
nv3->pfifo.cache1_settings.method_address = (value >> 2) & 0x7FF;
|
||||
nv3->pfifo.cache1_settings.method_subchannel = (val >> 13) & 0x07;
|
||||
nv3->pfifo.cache1_settings.method_address = (val >> 2) & 0x7FF;
|
||||
break;
|
||||
case NV3_PFIFO_CACHE1_DMA_CONFIG_0:
|
||||
nv3->pfifo.cache1_settings.dma_state = value;
|
||||
nv3->pfifo.cache1_settings.dma_state = val;
|
||||
break;
|
||||
case NV3_PFIFO_CACHE1_DMA_CONFIG_1:
|
||||
nv3->pfifo.cache1_settings.dma_length = value;
|
||||
nv3->pfifo.cache1_settings.dma_length = val;
|
||||
break;
|
||||
case NV3_PFIFO_CACHE1_DMA_CONFIG_2:
|
||||
nv3->pfifo.cache1_settings.dma_address = value;
|
||||
nv3->pfifo.cache1_settings.dma_address = val;
|
||||
break;
|
||||
case NV3_PFIFO_CACHE1_DMA_STATUS:
|
||||
nv3->pfifo.cache1_settings.dma_status = value;
|
||||
nv3->pfifo.cache1_settings.dma_status = val;
|
||||
break;
|
||||
case NV3_PFIFO_CACHE1_DMA_TLB_PT_BASE:
|
||||
nv3->pfifo.cache1_settings.dma_tlb_pt_base = value;
|
||||
nv3->pfifo.cache1_settings.dma_tlb_pt_base = val;
|
||||
break;
|
||||
case NV3_PFIFO_CACHE1_DMA_TLB_PTE:
|
||||
nv3->pfifo.cache1_settings.dma_tlb_pte = value;
|
||||
nv3->pfifo.cache1_settings.dma_tlb_pte = val;
|
||||
break;
|
||||
case NV3_PFIFO_CACHE1_DMA_TLB_TAG:
|
||||
nv3->pfifo.cache1_settings.dma_tlb_tag = value;
|
||||
nv3->pfifo.cache1_settings.dma_tlb_tag = val;
|
||||
break;
|
||||
/* Put and Get addresses */
|
||||
case NV3_PFIFO_CACHE0_PUT:
|
||||
nv3->pfifo.cache0_settings.put_address = val;
|
||||
break;
|
||||
case NV3_PFIFO_CACHE0_GET:
|
||||
nv3->pfifo.cache0_settings.get_address = val;
|
||||
break;
|
||||
case NV3_PFIFO_CACHE1_PUT:
|
||||
nv3->pfifo.cache1_settings.put_address = val;
|
||||
break;
|
||||
case NV3_PFIFO_CACHE1_GET:
|
||||
nv3->pfifo.cache1_settings.get_address = val;
|
||||
break;
|
||||
case NV3_PFIFO_RUNOUT_GET:
|
||||
uint32_t size_get = ((nv3->pfifo.ramro_config >> NV3_PFIFO_CONFIG_RAMRO_SIZE) & 0x01);
|
||||
|
||||
if (size_get == 0) //512b
|
||||
nv3->pfifo.runout_get = ((value & 0x3F) << 3);
|
||||
nv3->pfifo.runout_get = ((val & 0x3F) << 3);
|
||||
else
|
||||
nv3->pfifo.runout_get = ((value & 0x3FF) << 3);
|
||||
nv3->pfifo.runout_get = ((val & 0x3FF) << 3);
|
||||
break;
|
||||
case NV3_PFIFO_RUNOUT_PUT:
|
||||
uint32_t size_put = ((nv3->pfifo.ramro_config >> NV3_PFIFO_CONFIG_RAMRO_SIZE) & 0x01);
|
||||
|
||||
if (size_put == 0) //512b
|
||||
nv3->pfifo.runout_put = ((value & 0x3F) << 3);
|
||||
nv3->pfifo.runout_put = ((val & 0x3F) << 3);
|
||||
else
|
||||
nv3->pfifo.runout_put = ((value & 0x3FF) << 3);
|
||||
nv3->pfifo.runout_put = ((val & 0x3FF) << 3);
|
||||
break;
|
||||
/* Cache1 is handled below */
|
||||
case NV3_PFIFO_CACHE0_CTX:
|
||||
nv3->pfifo.cache0_settings.context[0] = value;
|
||||
nv3->pfifo.cache0_settings.context[0] = val;
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -508,9 +530,9 @@ void nv3_pfifo_write(uint32_t address, uint32_t value)
|
||||
else if (address >= NV3_PFIFO_CACHE1_CTX_START && address <= NV3_PFIFO_CACHE1_CTX_END)
|
||||
{
|
||||
uint32_t ctx_entry_id = ((address - NV3_PFIFO_CACHE1_CTX_START) / 16) % 8;
|
||||
nv3->pfifo.cache1_settings.context[ctx_entry_id] = value;
|
||||
nv3->pfifo.cache1_settings.context[ctx_entry_id] = val;
|
||||
|
||||
nv_log("PFIFO Cache1 CTX Write Entry=%d value=0x%04x\n", ctx_entry_id, value);
|
||||
nv_log("PFIFO Cache1 CTX Write Entry=%d value=0x%04x\n", ctx_entry_id, val);
|
||||
}
|
||||
|
||||
/* Trigger DMA for notifications if we need to */
|
||||
|
||||
@@ -502,15 +502,15 @@ bool nv3_ramin_find_object(uint32_t name, uint32_t cache_num, uint8_t channel, u
|
||||
// Prints out some informaiton about the object
|
||||
void nv3_debug_ramin_print_context_info(uint32_t name, nv3_ramin_context_t context)
|
||||
{
|
||||
nv_log("Found object:");
|
||||
nv_log("Name: 0x%04x", name);
|
||||
nv_log("Found object:\n");
|
||||
nv_log("Name: 0x%04x\n", name);
|
||||
|
||||
nv_log("Context:");
|
||||
nv_log("DMA Channel %d (0-7 valid)", context.channel);
|
||||
nv_log("Class ID: as repreesnted in ramin=%04x, Stupid 5 bit version (the actual id)=0x%04x (%s)", context.class_id,
|
||||
nv_log("Context:\n");
|
||||
nv_log("DMA Channel %d (0-7 valid)\n", context.channel);
|
||||
nv_log("Class ID: as repreesnted in ramin=%04x, Stupid 5 bit version (the actual id)=0x%04x (%s)\n", 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);
|
||||
nv_log("Render Engine %d (0=Software, also DMA? 1=Accelerated Renderer)\n", context.is_rendering);
|
||||
nv_log("PRAMIN Offset 0x%08x\n", context.ramin_offset << 4);
|
||||
}
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user