diff --git a/src/include/86box/nv/vid_nv3.h b/src/include/86box/nv/vid_nv3.h index d9d0a6ad3..852c368b5 100644 --- a/src/include/86box/nv/vid_nv3.h +++ b/src/include/86box/nv/vid_nv3.h @@ -264,17 +264,17 @@ extern const device_config_t nv3_config[]; #define NV3_PFIFO_CACHE1_SIZE_MAX NV3_PFIFO_CACHE1_SIZE_REV_C #define NV3_PFIFO_CACHE_REASSIGNMENT 0x2500 -#define NV3_PFIFO_CACHE0_DMA_PUSH0 0x3000 +#define NV3_PFIFO_CACHE0_PUSH0 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_PUT_ADDRESS 2 // 1 bit -#define NV3_PFIFO_CACHE0_DMA_PULL0 0x3040 -#define NV3_PFIFO_CACHE0_DMA_PULL0_ENABLED 0 -#define NV3_PFIFO_CACHE0_DMA_PULL0_HASH_FAILURE 4 -#define NV3_PFIFO_CACHE0_DMA_PULL0_SOFTWARE_METHOD 8 +#define NV3_PFIFO_CACHE0_PULL0 0x3040 +#define NV3_PFIFO_CACHE0_PULL0_ENABLED 0 +#define NV3_PFIFO_CACHE0_PULL0_HASH_FAILURE 4 +#define NV3_PFIFO_CACHE0_PULL0_SOFTWARE_METHOD 8 #define NV3_PFIFO_CACHE0_PULLER_CTX_STATE 0x3050 #define NV3_PFIFO_CACHE0_PULLER_CTX_STATE_DIRTY 4 // 1=dirty 0=clean #define NV3_PFIFO_CACHE0_GET 0x3070 @@ -286,7 +286,7 @@ extern const device_config_t nv3_config[]; #define NV3_PFIFO_CACHE0_METHOD_END 0x3200 #define NV3_PFIFO_CACHE0_METHOD_ADDRESS 2 // 12:2 #define NV3_PFIFO_CACHE0_METHOD_SUBCHANNEL 13 // 15:13 -#define NV3_PFIFO_CACHE1_DMA_PUSH0 0x3200 +#define NV3_PFIFO_CACHE1_PUSH0 0x3200 #define NV3_PFIFO_CACHE1_PUSH_CHANNEL_ID 0x3204 #define NV3_PFIFO_CACHE1_PUT 0x3210 #define NV3_PFIFO_CACHE1_PUT_ADDRESS 2 // 6:2 @@ -307,11 +307,11 @@ extern const device_config_t nv3_config[]; #define NV3_PFIFO_CACHE1_DMA_TLB_TAG 0x3230 #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_DMA_PULL0 0x3240 +#define NV3_PFIFO_CACHE1_PULL0 0x3240 //todo: merge stuff -#define NV3_PFIFO_CACHE1_DMA_PULL0_ENABLED 0 -#define NV3_PFIFO_CACHE1_DMA_PULL0_HASH_FAILURE 4 -#define NV3_PFIFO_CACHE1_DMA_PULL0_SOFTWARE_METHOD 8 // 0=software, 1=hardware +#define NV3_PFIFO_CACHE1_PULL0_ENABLED 0 +#define NV3_PFIFO_CACHE1_PULL0_HASH_FAILURE 4 +#define NV3_PFIFO_CACHE1_PULL0_SOFTWARE_METHOD 8 // 0=software, 1=hardware #define NV3_PFIFO_CACHE1_PULLER_CTX_STATE 0x3250 #define NV3_PFIFO_CACHE1_PULLER_CTX_STATE_DIRTY 4 #define NV3_PFIFO_CACHE1_GET 0x3270 @@ -927,12 +927,12 @@ typedef struct nv3_pbus_s typedef struct nv3_pfifo_cache_s { - bool dma_push0; // Can we even access this cache? + bool push0; // Can we even access this cache? uint8_t put_address; // Trigger a DMA into the value you put here. uint8_t get_address; // Trigger a DMA from the value you put here into where you were going. uint8_t channel; // The DMA channel ID of this cache. uint32_t status; - uint32_t dma_pull0; + uint32_t pull0; uint32_t context[NV3_DMA_SUBCHANNELS_PER_CHANNEL]; // Only one of these exists for cache0 /* cache1 only diff --git a/src/video/nv/nv3/subsystems/nv3_pfifo.c b/src/video/nv/nv3/subsystems/nv3_pfifo.c index a9ae7dc61..c3deac24e 100644 --- a/src/video/nv/nv3/subsystems/nv3_pfifo.c +++ b/src/video/nv/nv3/subsystems/nv3_pfifo.c @@ -43,13 +43,13 @@ nv_register_t pfifo_registers[] = { { NV3_PFIFO_CONFIG_RAMHT, "PFIFO - RAMIN RAMHT Config", NULL, NULL }, { NV3_PFIFO_CONFIG_RAMRO, "PFIFO - RAMIN RAMRO Config", NULL, NULL }, { NV3_PFIFO_CACHE_REASSIGNMENT, "PFIFO - Allow Cache Channel Reassignment", NULL, NULL }, - { NV3_PFIFO_CACHE0_DMA_PULL0, "PFIFO - Cache0 Puller Control", NULL, NULL}, - { NV3_PFIFO_CACHE1_DMA_PULL0, "PFIFO - Cache1 Puller Control"}, + { NV3_PFIFO_CACHE0_PULL0, "PFIFO - Cache0 Puller Control", NULL, NULL}, + { NV3_PFIFO_CACHE1_PULL0, "PFIFO - Cache1 Puller Control"}, { NV3_PFIFO_CACHE0_PULLER_CTX_STATE, "PFIFO - Cache0 Puller State1 (Is context clean?)", NULL, NULL}, - { NV3_PFIFO_CACHE1_DMA_PULL0, "PFIFO - Cache1 Puller State0", NULL, NULL}, + { NV3_PFIFO_CACHE1_PULL0, "PFIFO - Cache1 Puller State0", NULL, NULL}, { NV3_PFIFO_CACHE1_PULLER_CTX_STATE, "PFIFO - Cache1 Puller State1 (Is context clean?)", NULL, NULL}, - { NV3_PFIFO_CACHE0_DMA_PUSH0, "PFIFO - Cache0 Access", NULL, NULL, }, - { NV3_PFIFO_CACHE1_DMA_PUSH0, "PFIFO - Cache1 Access", NULL, NULL, }, + { NV3_PFIFO_CACHE0_PUSH0, "PFIFO - Cache0 Access", NULL, NULL, }, + { NV3_PFIFO_CACHE1_PUSH0, "PFIFO - Cache1 Access", NULL, NULL, }, { NV3_PFIFO_CACHE0_PUSH_CHANNEL_ID, "PFIFO - Cache0 Push Channel ID", NULL, NULL, }, { NV3_PFIFO_CACHE1_PUSH_CHANNEL_ID, "PFIFO - Cache1 Push Channel ID", NULL, NULL, }, { NV3_PFIFO_CACHE0_ERROR_PENDING, "PFIFO - Cache0 DMA Error Pending?", NULL, NULL, }, @@ -146,11 +146,12 @@ uint32_t nv3_pfifo_read(uint32_t address) case NV3_PFIFO_CONFIG_RAMRO: ret = nv3->pfifo.ramro_config; break; - case NV3_PFIFO_CACHE0_DMA_PULL0: - ret = nv3->pfifo.cache0_settings.dma_pull0; + /* These automatically trigger pulls when 1 is written */ + case NV3_PFIFO_CACHE0_PULL0: + ret = nv3->pfifo.cache0_settings.pull0; break; - case NV3_PFIFO_CACHE1_DMA_PULL0: - ret = nv3->pfifo.cache1_settings.dma_pull0; + case NV3_PFIFO_CACHE1_PULL0: + ret = nv3->pfifo.cache1_settings.pull0; break; case NV3_PFIFO_CACHE0_PULLER_CTX_STATE: ret = (nv3->pfifo.cache0_settings.context_is_dirty) ? (1 << NV3_PFIFO_CACHE0_PULLER_CTX_STATE_DIRTY) : 0; @@ -158,11 +159,12 @@ uint32_t nv3_pfifo_read(uint32_t address) case NV3_PFIFO_CACHE1_PULLER_CTX_STATE: ret = (nv3->pfifo.cache0_settings.context_is_dirty) ? (1 << NV3_PFIFO_CACHE0_PULLER_CTX_STATE_DIRTY) : 0; break; - case NV3_PFIFO_CACHE0_DMA_PUSH0: - ret = nv3->pfifo.cache0_settings.dma_push0; + /* Does this automatically push? */ + case NV3_PFIFO_CACHE0_PUSH0: + ret = nv3->pfifo.cache0_settings.push0; break; - case NV3_PFIFO_CACHE1_DMA_PUSH0: - ret = nv3->pfifo.cache1_settings.dma_push0; + case NV3_PFIFO_CACHE1_PUSH0: + ret = nv3->pfifo.cache1_settings.push0; break; case NV3_PFIFO_CACHE0_PUSH_CHANNEL_ID: ret = nv3->pfifo.cache0_settings.channel; @@ -344,12 +346,12 @@ void nv3_pfifo_trigger_dma_if_required() uint32_t tlb_pt_tag = nv3->pfifo.cache1_settings.dma_tlb_tag; // 0xFFFFFFFF usually? /* PUSH - System to GPU (?) */ - if (nv3->pfifo.cache1_settings.dma_push0) + if (nv3->pfifo.cache1_settings.push0) { /* PULL - GPU to System */ nv_log("Initiating System to NV DMA - Probably we are trying to notify\n"); } - else if (nv3->pfifo.cache1_settings.dma_pull0) + else if (nv3->pfifo.cache1_settings.pull0) { /* PULL - GPU to System */ nv_log("Initiating NV to System DMA - Probably we are trying to notify\n"); @@ -455,12 +457,20 @@ void nv3_pfifo_write(uint32_t address, uint32_t val) case NV3_PFIFO_CACHE_REASSIGNMENT: nv3->pfifo.cache_reassignment = val & 0x01; //1bit meaningful break; - // Control - case NV3_PFIFO_CACHE0_DMA_PULL0: - nv3->pfifo.cache0_settings.dma_pull0 = val; // 8bits meaningful + // Control - these can trigger pulls + case NV3_PFIFO_CACHE0_PULL0: + nv3->pfifo.cache0_settings.pull0 = val; // 8bits meaningful + + if (nv3->pfifo.cache0_settings.pull0 & (1 >> NV3_PFIFO_CACHE0_PULL0_ENABLED)) + nv3_pfifo_cache0_pull(); + break; - case NV3_PFIFO_CACHE1_DMA_PULL0: - nv3->pfifo.cache1_settings.dma_pull0 = val; // 8bits meaningful + case NV3_PFIFO_CACHE1_PULL0: + nv3->pfifo.cache1_settings.pull0 = val; // 8bits meaningful + + if (nv3->pfifo.cache1_settings.pull0 & (1 >> NV3_PFIFO_CACHE1_PULL0_ENABLED)) + nv3_pfifo_cache1_pull(); + break; case NV3_PFIFO_CACHE0_PULLER_CTX_STATE: nv3->pfifo.cache0_settings.context_is_dirty = (val >> NV3_PFIFO_CACHE0_PULLER_CTX_STATE_DIRTY) & 0x01; @@ -468,11 +478,11 @@ void nv3_pfifo_write(uint32_t address, uint32_t val) case NV3_PFIFO_CACHE1_PULLER_CTX_STATE: 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 = val; + case NV3_PFIFO_CACHE0_PUSH0: + nv3->pfifo.cache0_settings.push0 = val; break; - case NV3_PFIFO_CACHE1_DMA_PUSH0: - nv3->pfifo.cache1_settings.dma_push0 = val; + case NV3_PFIFO_CACHE1_PUSH0: + nv3->pfifo.cache1_settings.push0 = val; break; case NV3_PFIFO_CACHE0_PUSH_CHANNEL_ID: nv3->pfifo.cache0_settings.channel = val; @@ -545,15 +555,22 @@ void nv3_pfifo_write(uint32_t address, uint32_t val) } else if (address >= NV3_PFIFO_CACHE0_METHOD_START && address <= NV3_PFIFO_CACHE0_METHOD_END) { + nv_log("PFIFO Cache0 Write"); + // 3104 always written after 3100 if (address & 4) { + nv_log("Name = 0x%08x\n", val); nv3->pfifo.cache0_entry.data = val; nv3_pfifo_cache0_pull(); // immediately pull out } else + { nv3->pfifo.cache0_entry.method = (val & 0x1FFC); nv3->pfifo.cache0_entry.subchannel = (val >> NV3_PFIFO_CACHE1_METHOD_SUBCHANNEL) & 0x07; + nv_log("Subchannel = 0x%08x, method = 0x%04x\n", nv3->pfifo.cache0_entry.subchannel, nv3->pfifo.cache0_entry.method); + } + } else if (address >= NV3_PFIFO_CACHE1_METHOD_START && address <= NV3_PFIFO_CACHE1_METHOD_END) { @@ -567,12 +584,21 @@ void nv3_pfifo_write(uint32_t address, uint32_t val) uint32_t real_entry = nv3_pfifo_cache1_normal2gray(slot); + nv_log("Cache1 Write Slot %d (Gray code)", real_entry); + // See if we want the object name or the channel/subchannel information. if (address & 4) + { + nv_log("Name = 0x%08x\n", val); nv3->pfifo.cache1_entries[real_entry].data = val; + } else + { nv3->pfifo.cache1_entries[real_entry].method = (val & 0x1FFC); nv3->pfifo.cache1_entries[real_entry].subchannel = (val >> NV3_PFIFO_CACHE1_METHOD_SUBCHANNEL) & 0x07; + nv_log("Subchannel = 0x%08x, method = 0x%04x\n", nv3->pfifo.cache1_entries[real_entry].subchannel, nv3->pfifo.cache1_entries[real_entry].method); + } + } /* Handle some special memory areas */ else if (address >= NV3_PFIFO_CACHE1_CTX_START && address <= NV3_PFIFO_CACHE1_CTX_END) @@ -641,7 +667,7 @@ void nv3_pfifo_cache0_push() void nv3_pfifo_cache0_pull() { // Do nothing if PFIFO CACHE0 is disabled - if (!nv3->pfifo.cache0_settings.dma_pull0 & (1 >> NV3_PFIFO_CACHE0_DMA_PULL0_ENABLED)) + if (!nv3->pfifo.cache0_settings.pull0 & (1 >> NV3_PFIFO_CACHE0_PULL0_ENABLED)) return; // Do nothing if there is nothing in cache0 to pull @@ -668,10 +694,12 @@ void nv3_pfifo_cache0_pull() 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) + if (!(current_context & 0x800000)) { - nv3->pfifo.cache0_settings.dma_pull0 |= NV3_PFIFO_CACHE0_DMA_PULL0_SOFTWARE_METHOD; - nv3->pfifo.cache0_settings.dma_pull0 &= ~NV3_PFIFO_CACHE0_DMA_PULL0_ENABLED; + nv_log("The object in CACHE0 is a software object\n"); + + nv3->pfifo.cache0_settings.pull0 |= NV3_PFIFO_CACHE0_PULL0_SOFTWARE_METHOD; + nv3->pfifo.cache0_settings.pull0 &= ~NV3_PFIFO_CACHE0_PULL0_ENABLED; nv3_pfifo_interrupt(NV3_PFIFO_INTR_CACHE_ERROR, true); } @@ -713,7 +741,7 @@ void nv3_pfifo_cache1_push(uint32_t addr, uint32_t object_name) uint32_t subchannel = (addr >> NV3_OBJECT_SUBMIT_SUBCHANNEL) & (NV3_DMA_CHANNELS - 1); // first make sure there is even any cache available - if (!nv3->pfifo.cache1_settings.dma_push0) + if (!nv3->pfifo.cache1_settings.push0) { oh_shit = true; oh_shit_reason = nv3_runout_reason_no_cache_available; @@ -796,7 +824,7 @@ void nv3_pfifo_cache1_push(uint32_t addr, uint32_t object_name) void nv3_pfifo_cache1_pull() { // Do nothing if PFIFO CACHE1 is disabled - if (!nv3->pfifo.cache1_settings.dma_pull0 & (1 >> NV3_PFIFO_CACHE1_DMA_PULL0_ENABLED)) + if (!nv3->pfifo.cache1_settings.pull0 & (1 >> NV3_PFIFO_CACHE1_PULL0_ENABLED)) return; // Do nothing if there is nothing in cache1 to pull @@ -822,10 +850,14 @@ void nv3_pfifo_cache1_pull() 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) + //bit23 unset=software + //bit23 set=hardware + if (!(current_context & 0x800000)) { - nv3->pfifo.cache1_settings.dma_pull0 |= NV3_PFIFO_CACHE0_DMA_PULL0_SOFTWARE_METHOD; - nv3->pfifo.cache1_settings.dma_pull0 &= ~NV3_PFIFO_CACHE0_DMA_PULL0_ENABLED; + nv_log("The object in CACHE1 is a software object\n"); + + nv3->pfifo.cache1_settings.pull0 |= NV3_PFIFO_CACHE0_PULL0_SOFTWARE_METHOD; + nv3->pfifo.cache1_settings.pull0 &= ~NV3_PFIFO_CACHE0_PULL0_ENABLED; nv3_pfifo_interrupt(NV3_PFIFO_INTR_CACHE_ERROR, true); } diff --git a/src/video/nv/nv3/subsystems/nv3_pramin.c b/src/video/nv/nv3/subsystems/nv3_pramin.c index 55de2616b..a591f69b1 100644 --- a/src/video/nv/nv3/subsystems/nv3_pramin.c +++ b/src/video/nv/nv3/subsystems/nv3_pramin.c @@ -409,16 +409,16 @@ bool nv3_ramin_find_object(uint32_t name, uint32_t cache_num, uint8_t channel, u if (!cache_num) { nv3->pfifo.debug_0 |= NV3_PFIFO_CACHE0_ERROR_PENDING; - nv3->pfifo.cache0_settings.dma_pull0 |= NV3_PFIFO_CACHE0_DMA_PULL0_HASH_FAILURE; + nv3->pfifo.cache0_settings.pull0 |= NV3_PFIFO_CACHE0_PULL0_HASH_FAILURE; //It turns itself off on failure, the drivers turn it back on - nv3->pfifo.cache0_settings.dma_pull0 &= ~NV3_PFIFO_CACHE0_DMA_PULL0_ENABLED; + nv3->pfifo.cache0_settings.pull0 &= ~NV3_PFIFO_CACHE0_PULL0_ENABLED; } else { nv3->pfifo.debug_0 |= NV3_PFIFO_CACHE1_ERROR_PENDING; - nv3->pfifo.cache1_settings.dma_pull0 |= NV3_PFIFO_CACHE1_DMA_PULL0_HASH_FAILURE; + nv3->pfifo.cache1_settings.pull0 |= NV3_PFIFO_CACHE1_PULL0_HASH_FAILURE; //It turns itself off on failure, the drivers turn it back on - nv3->pfifo.cache1_settings.dma_pull0 &= ~NV3_PFIFO_CACHE1_DMA_PULL0_ENABLED; + nv3->pfifo.cache1_settings.pull0 &= ~NV3_PFIFO_CACHE1_PULL0_ENABLED; } nv3_pfifo_interrupt(NV3_PFIFO_INTR_CACHE_ERROR, true); @@ -452,9 +452,9 @@ bool nv3_ramin_find_object(uint32_t name, uint32_t cache_num, uint8_t channel, u // By definition we can't have a cache error by here so take it off if (!cache_num) - nv3->pfifo.cache0_settings.dma_pull0 &= ~NV3_PFIFO_CACHE0_DMA_PULL0_HASH_FAILURE; + nv3->pfifo.cache0_settings.pull0 &= ~NV3_PFIFO_CACHE0_PULL0_HASH_FAILURE; else - nv3->pfifo.cache1_settings.dma_pull0 &= ~NV3_PFIFO_CACHE1_DMA_PULL0_HASH_FAILURE; + nv3->pfifo.cache1_settings.pull0 &= ~NV3_PFIFO_CACHE1_PULL0_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... @@ -471,13 +471,13 @@ bool nv3_ramin_find_object(uint32_t name, uint32_t cache_num, uint8_t channel, u // handle it as an error if (!cache_num) { - nv3->pfifo.cache0_settings.dma_pull0 |= NV3_PFIFO_CACHE0_DMA_PULL0_SOFTWARE_METHOD; - nv3->pfifo.cache0_settings.dma_pull0 &= ~NV3_PFIFO_CACHE0_DMA_PULL0_ENABLED; + nv3->pfifo.cache0_settings.pull0 |= NV3_PFIFO_CACHE0_PULL0_SOFTWARE_METHOD; + nv3->pfifo.cache0_settings.pull0 &= ~NV3_PFIFO_CACHE0_PULL0_ENABLED; } else { - nv3->pfifo.cache1_settings.dma_pull0 |= NV3_PFIFO_CACHE1_DMA_PULL0_SOFTWARE_METHOD; - nv3->pfifo.cache0_settings.dma_pull0 &= ~NV3_PFIFO_CACHE1_DMA_PULL0_ENABLED; + nv3->pfifo.cache1_settings.pull0 |= NV3_PFIFO_CACHE1_PULL0_SOFTWARE_METHOD; + nv3->pfifo.cache0_settings.pull0 &= ~NV3_PFIFO_CACHE1_PULL0_ENABLED; } // It's an error but it isn't lol @@ -488,9 +488,9 @@ bool nv3_ramin_find_object(uint32_t name, uint32_t cache_num, uint8_t channel, u { // obviously turn off the "is software" if it's not if (!cache_num) - nv3->pfifo.cache0_settings.dma_pull0 &= ~NV3_PFIFO_CACHE0_DMA_PULL0_SOFTWARE_METHOD; + nv3->pfifo.cache0_settings.pull0 &= ~NV3_PFIFO_CACHE0_PULL0_SOFTWARE_METHOD; else - nv3->pfifo.cache1_settings.dma_pull0 &= ~NV3_PFIFO_CACHE1_DMA_PULL0_SOFTWARE_METHOD; + nv3->pfifo.cache1_settings.pull0 &= ~NV3_PFIFO_CACHE1_PULL0_SOFTWARE_METHOD; } // Ok we found it. Lol