diff --git a/doc/nvidia_notes/NV128.xlsx b/doc/nvidia_notes/NV128.xlsx index 1cb14fdcc..919297d56 100644 Binary files a/doc/nvidia_notes/NV128.xlsx and b/doc/nvidia_notes/NV128.xlsx differ diff --git a/src/include/86box/nv/vid_nv3.h b/src/include/86box/nv/vid_nv3.h index 957714799..9c1a5628e 100644 --- a/src/include/86box/nv/vid_nv3.h +++ b/src/include/86box/nv/vid_nv3.h @@ -845,6 +845,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 @@ -906,6 +908,7 @@ typedef struct nv3_pfb_s // // DMA & Notifier Engine +// All singing all dancing all happy happy bullshit to send dma transfers literally anywhere in your computer // // Not a notification status, because it's a 16-bit enum @@ -914,6 +917,21 @@ typedef struct nv3_pfb_s #define NV3_NOTIFICATION_STATUS_IN_PROGRESS 0xFF #define NV3_NOTIFICATION_STATUS_ERROR 0x100 +#define NV3_NOTIFICATION_INFO_ADJUST 0 // Wut +#define NV3_NOTIFICATION_PT_PRESENT 16 // Determines if the pagetable exists. +#define NV3_NOTIFICATION_TARGET 24 // Determines where this notification goes +#define NV3_NOTIFICATION_TARGET_NVM 0 // VRAM target for DMA +#define NV3_NOTIFICATION_TARGET_CART 1 // "Cartridge" target for dma, only mentioned in a few places, !!! NV2 LEFTOVER !!! +#define NV3_NOTIFICATION_TARGET_PCI 2 // Send the data to the host system over PCI +#define NV3_NOTIFICATION_TARGET_AGP 3 // Send the data to the host system over AGP + +#define NV3_NOTIFICATION_PAGE_IS_PRESENT 0 // Determines if the page really exists +#define NV3_NOTIFICATION_PAGE_ACCESS 1 // Determines the page access type +#define NV3_NOTIFICATION_PAGE_ACCESS_READ 0x0 // If this is set, the page is read only +#define NV3_NOTIFICATION_PAGE_ACCESS_READ_WRITE 0x1 // If this is set, the page is read/write +#define NV3_NOTIFICATION_PAGE_FRAME_ADDRESS 12 // The pageframe to use + + // Core notification structure typedef struct nv3_notification_s { @@ -1170,6 +1188,7 @@ typedef struct nv3_pgraph_s // CLIP nv3_pgraph_clip_misc_settings_t clip_misc_settings; nv3_notifier_t notifier; + bool notify_pending; // Determines if a notification is pending. nv3_position_16_bigy_t clip0_min; nv3_position_16_bigy_t clip0_max; nv3_position_16_bigy_t clip1_min; @@ -1550,7 +1569,7 @@ void nv3_class_018_method(uint32_t name, uint32_t method_id, nv3_ramin_co void nv3_class_01c_method(uint32_t name, uint32_t method_id, nv3_ramin_context_t context, nv3_grobj_t grobj); // Notification Engine -void nv3_notify_if_needed(nv3_grobj_t grobj); +void nv3_notify_if_needed(uint32_t name, uint32_t method_id, nv3_ramin_context_t context,nv3_grobj_t grobj); // NV3 PFIFO void nv3_pfifo_init(); @@ -1595,4 +1614,4 @@ void nv3_ptimer_tick(double real_time); void nv3_pvideo_init(); // NV3 PMEDIA (Mediaport) -void nv3_pmedia_init(); +void nv3_pmedia_init(); \ No newline at end of file diff --git a/src/video/nv/nv3/classes/nv3_class_017_d3d5_tri_zeta_buffer.c b/src/video/nv/nv3/classes/nv3_class_017_d3d5_tri_zeta_buffer.c index 2acb22a08..951ba862d 100644 --- a/src/video/nv/nv3/classes/nv3_class_017_d3d5_tri_zeta_buffer.c +++ b/src/video/nv/nv3/classes/nv3_class_017_d3d5_tri_zeta_buffer.c @@ -1,19 +1,19 @@ /* - * 86Box A hypervisor and IBM PC system emulator that specializes in - * running old operating systems and software designed for IBM - * PC systems and compatibles from 1981 through fairly recent - * system designs based on the PCI bus. - * - * This file is part of the 86Box distribution. - * - * NV3: Methods for class 0x17 (Direct3D 5.0 accelerated triangle with zeta buffer) - * - * - * - * Authors: Connor Hyde, I need a better email address ;^) - * - * Copyright 2024-2025 Connor Hyde - */ +* 86Box A hypervisor and IBM PC system emulator that specializes in +* running old operating systems and software designed for IBM +* PC systems and compatibles from 1981 through fairly recent +* system designs based on the PCI bus. +* +* This file is part of the 86Box distribution. +* +* NV3: Methods for class 0x17 (Direct3D 5.0 accelerated triangle with zeta buffer) +* +* +* +* Authors: Connor Hyde, I need a better email address ;^) +* +* Copyright 2024-2025 Connor Hyde +*/ #include #include diff --git a/src/video/nv/nv3/classes/nv3_class_names.c b/src/video/nv/nv3/classes/nv3_class_names.c index ded63ece2..64e35d9b3 100644 --- a/src/video/nv/nv3/classes/nv3_class_names.c +++ b/src/video/nv/nv3/classes/nv3_class_names.c @@ -64,4 +64,4 @@ const char* nv3_class_names[] = "NV3 INVALID class 0x1D", "NV3 INVALID class 0x1E", "NV3 INVALID class 0x1F", -}; +}; \ No newline at end of file diff --git a/src/video/nv/nv3/classes/nv3_class_shared_methods.c b/src/video/nv/nv3/classes/nv3_class_shared_methods.c index 663214cec..abeb0571b 100644 --- a/src/video/nv/nv3/classes/nv3_class_shared_methods.c +++ b/src/video/nv/nv3/classes/nv3_class_shared_methods.c @@ -21,6 +21,7 @@ #include #include <86box/86box.h> #include <86box/device.h> +#include <86box/dma.h> #include <86box/mem.h> #include <86box/pci.h> #include <86box/rom.h> @@ -39,7 +40,78 @@ void nv3_generic_method(uint32_t name, uint32_t method_id, nv3_ramin_context_t c } } -void nv3_notify_if_needed(nv3_grobj_t grobj) + +/* Sees if any notification is required after an object method is executed. If so, executes it... */ +void nv3_notify_if_needed(uint32_t name, uint32_t method_id, nv3_ramin_context_t context, nv3_grobj_t grobj) { + if (nv3->pgraph.notify_pending) + { + nv_log("Called nv3_notify_if_needed with nv3->pgraph.notify_pending already set. name=0x%08x, method=0x%04x, grobj=0x%08x 0x%08x 0x%08x 0x%08x\n"); + nv_log("IF THIS IS A DEBUG BUILD, YOU SHOULD SEE A CONTEXT BELOW"); + nv3_debug_ramin_print_context_info(name, context); + nv3_pgraph_interrupt_invalid(NV3_PGRAPH_INTR_1_DOUBLE_NOTIFY); + + // disable + nv3->pgraph.notify_pending = false; + return; + } + + // set up the NvNotification structure + nv3_notification_t notify = {0}; + notify.nanoseconds = nv3->ptimer.time; + notify.status = NV3_NOTIFICATION_STATUS_DONE_OK; // it should be fine to just signal that it's ok -} \ No newline at end of file + // this is completely speculative and i have no idea + notify.info32 = grobj.grobj_0; + + // notify object base=grobj_1 >> 12 + uint32_t notify_obj_base = grobj.grobj_1 >> 12; + + uint32_t notify_obj_info = nv3_ramin_read32(notify_obj_base, nv3); + uint32_t notify_obj_limit = nv3_ramin_read32(notify_obj_base + 0x04, nv3); + uint32_t notify_obj_page = nv3_ramin_read32(notify_obj_base + 0x08, nv3); + + /* extract some important information*/ + uint32_t info_adjust = notify_obj_info & 0xFFF; + bool info_pt_present = (notify_obj_info >> NV3_NOTIFICATION_PT_PRESENT) & 0x01; + uint8_t info_notification_target = (notify_obj_info >> NV3_NOTIFICATION_TARGET) & 0x03; + + /* paging information */ + bool page_is_present = notify_obj_page & 0x01; + bool page_is_readwrite = (notify_obj_page >> NV3_NOTIFICATION_PAGE_ACCESS); + uint32_t frame_value = (notify_obj_page >> NV3_NOTIFICATION_PAGE_FRAME_ADDRESS) & 0xFFFFF; + + // This code is temporary and will probably be moved somewhere else + // Print torns of debug info + #ifdef DEBUG + nv_log("******* WARNING: IF THIS OPERATION FUCKS UP, RANDOM MEMORY WILL BE CORRUPTED, YOUR ENTIRE SYSTEM MAY BE HOSED *******\n"); + + nv_log("Notification Information:\n"); + nv_log("Adjust Value: 0x%08x\n", info_adjust); + (info_pt_present) ? nv_log("Pagetable Present: True\n") : nv_log("Pagetable Present: False\n"); + + switch (info_notification_target) + { + case NV3_NOTIFICATION_TARGET_NVM: + nv_log("Notification Target: VRAM\n"); + break; + case NV3_NOTIFICATION_TARGET_CART: + nv_log("VERY BAD WARNING: Notification detected with Notification Target: Cartridge. THIS SHOULD NEVER HAPPEN!!!!!\n"); + break; + case NV3_NOTIFICATION_TARGET_PCI: + (nv3->nvbase.bus_generation == nv_bus_pci) ? nv_log("Notification Target: PCI Bus\n") : nv_log("Notification Target: PCI Bus (On AGP card???)\n"); + break; + case NV3_NOTIFICATION_TARGET_AGP: + (nv3->nvbase.bus_generation == nv_bus_agp_1x + || nv3->nvbase.bus_generation == nv_bus_agp_2x) ? nv_log("Notification Target: AGP Bus\n") : nv_log("Notification Target: AGP Bus (On PCI card???)\n"); + break; + } + + nv_log("Limit: 0x%08x", notify_obj_limit); + (page_is_present) ? nv_log("Page is present\n") : nv_log("Page is not present\n"); + (page_is_readwrite) ? nv_log("Page is read-write\n") : nv_log("Page is read-only\n"); + nv_log("Pageframe Address: 0x%08x", frame_value); + #endif + + // set up the dma transfer. we need to translate to a physical address. +} diff --git a/src/video/nv/nv3/nv3_core_arbiter.c b/src/video/nv/nv3/nv3_core_arbiter.c index 17cca15df..e5e7ced6b 100644 --- a/src/video/nv/nv3/nv3_core_arbiter.c +++ b/src/video/nv/nv3/nv3_core_arbiter.c @@ -194,5 +194,4 @@ uint32_t nv3_prmcio_read(uint32_t address) { return 0; }; void nv3_prmcio_write(uint32_t address, uint32_t value) {}; uint32_t nv3_vram_read(uint32_t address) { return 0; }; -void nv3_vram_write(uint32_t address, uint32_t value) {}; - +void nv3_vram_write(uint32_t address, uint32_t value) {}; \ No newline at end of file diff --git a/src/video/nv/nv3/subsystems/nv3_pbus_dma.c b/src/video/nv/nv3/subsystems/nv3_pbus_dma.c index d5d17fe2d..4ce686335 100644 --- a/src/video/nv/nv3/subsystems/nv3_pbus_dma.c +++ b/src/video/nv/nv3/subsystems/nv3_pbus_dma.c @@ -28,4 +28,9 @@ #include <86box/nv/vid_nv.h> #include <86box/nv/vid_nv3.h> -/* Nvidia DMA Engine */ \ No newline at end of file +/* Nvidia DMA Engine */ + +void nv3_dma_translate_address() +{ + +} \ No newline at end of file diff --git a/src/video/nv/nv3/subsystems/nv3_pfb.c b/src/video/nv/nv3/subsystems/nv3_pfb.c index 435225bc2..92a643502 100644 --- a/src/video/nv/nv3/subsystems/nv3_pfb.c +++ b/src/video/nv/nv3/subsystems/nv3_pfb.c @@ -168,13 +168,12 @@ void nv3_pfb_config0_write(uint32_t val) uint32_t new_pfb_htotal = (nv3->pfb.config_0 & 0x3F) << 5; // i don't think 16:9 is supported - uint32_t new_pfb_vtotal = new_pfb_htotal * (4.0/3.0); - + uint32_t new_pfb_vtotal = new_pfb_htotal * (4.0/3.0); uint32_t new_bit_depth = (nv3->pfb.config_0 >> 8) & 0x03; + nv_log("Framebuffer Config Change\n"); nv_log("Horizontal Size=%d pixels\n", new_pfb_htotal); nv_log("Vertical Size @ 4:3=%d pixels\n", new_pfb_vtotal); - if (new_bit_depth == NV3_PFB_CONFIG_0_DEPTH_8BPP) nv_log("Bit Depth=8bpp\n"); diff --git a/src/video/nv/nv3/subsystems/nv3_pgraph.c b/src/video/nv/nv3/subsystems/nv3_pgraph.c index 117a88733..5851d9301 100644 --- a/src/video/nv/nv3/subsystems/nv3_pgraph.c +++ b/src/video/nv/nv3/subsystems/nv3_pgraph.c @@ -589,7 +589,7 @@ void nv3_pgraph_arbitrate_method(uint32_t param, uint16_t method, uint8_t channe return; } - nv3_notify_if_needed(grobj); + nv3_notify_if_needed(param, method, context, grobj); } /* Arbitrates graphics object submission to the right object types */ diff --git a/src/video/nv/nv3/subsystems/nv3_pramin.c b/src/video/nv/nv3/subsystems/nv3_pramin.c index 226f4d8ee..f85ae3f8e 100644 --- a/src/video/nv/nv3/subsystems/nv3_pramin.c +++ b/src/video/nv/nv3/subsystems/nv3_pramin.c @@ -498,10 +498,11 @@ bool nv3_ramin_find_object(uint32_t name, uint32_t cache_num, uint8_t channel, u } -#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) { + #ifndef RELEASE_BUILD nv_log("Found object:\n"); nv_log("Name: 0x%04x\n", name); @@ -511,6 +512,5 @@ void nv3_debug_ramin_print_context_info(uint32_t name, nv3_ramin_context_t conte context.class_id & 0x1F, nv3_class_names[context.class_id & 0x1F]); 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 } - -#endif \ No newline at end of file