diff --git a/src/include/86box/nv/classes/vid_nv3_classes.h b/src/include/86box/nv/classes/vid_nv3_classes.h index 5ccd067a9..099c0bdc6 100644 --- a/src/include/86box/nv/classes/vid_nv3_classes.h +++ b/src/include/86box/nv/classes/vid_nv3_classes.h @@ -1043,9 +1043,12 @@ typedef struct nv3_object_class_017 /* No placeholder needed, it really is that long. */ } nv3_d3d5_accelerated_triangle_with_zeta_buffer_t; -/* 0x18, 0x19, 0x1A, 0x1B don't exist */ +/* 0x19, 0x1A, 0x1B don't exist */ +typedef struct nv3_object_class_018 +{ +} nv3_point_with_zeta_buffer_t; /* WHY IS THE FORMAT DIFFERENT TO THE REST OF THE GPU? They are making it look like a bitfield but it's hex? diff --git a/src/include/86box/nv/vid_nv3.h b/src/include/86box/nv/vid_nv3.h index 7845f132b..a2c54748e 100644 --- a/src/include/86box/nv/vid_nv3.h +++ b/src/include/86box/nv/vid_nv3.h @@ -14,7 +14,7 @@ * Also check the doc folder for some more notres * * vid_nv3.h: NV3 Architecture Hardware Reference (open-source) - * Last updated: 12 January 2025 (STILL WORKING ON IT!!!) + * Last updated: 20 January 2025 (STILL WORKING ON IT!!!) * * Authors: Connor Hyde * @@ -218,7 +218,6 @@ extern const device_config_t nv3_config[]; #define NV3_PFIFO_CONFIG_RAMFC 0x2214 #define NV3_PFIFO_CONFIG_RAMFC_BASE_ADDRESS 9 #define NV3_PFIFO_CONFIG_RAMFC_BASE_ADDRESS_DEFAULT 0x1C00 // Hardcoded in silicon? - #define NV3_PFIFO_CONFIG_RAMRO 0x2218 #define NV3_PFIFO_CONFIG_RAMRO_BASE_ADDRESS 9 #define NV3_PFIFO_CONFIG_RAMRO_BASE_ADDRESS_DEFAULT 0x1E00 // Hardcoded in silicon? @@ -226,6 +225,44 @@ extern const device_config_t nv3_config[]; #define NV3_PFIFO_CONFIG_RAMRO_SIZE_512B 0x0 #define NV3_PFIFO_CONFIG_RAMRO_SIZE_8K 0x1 +#define NV3_PFIFO_RUNOUT_STATUS 0x2400 +#define NV3_PFIFO_RUNOUT_STATUS_RANOUT 0 // 1 if we fucked up +#define NV3_PFIFO_RUNOUT_STATUS_LOW_MARK 4 // 1 if ramro is empty +#define NV3_PFIFO_RUNOUT_STATUS_HIGH_MARK 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 +#define NV3_PFIFO_RUNOUT_GET_ADDRESS 3 // 13:3 + +#define NV3_PFIFO_CACHE0_SIZE 1 // This is for software-injected notified only! +#define NV3_PFIFO_CACHE1_SIZE_REV_AB 32 +#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_ACCESS 0x3000 +#define NV3_PFIFO_CACHE0_DMA_CHANNEL_ID 0x3004 +#define NV3_PFIFO_CACHE0_PUT 0x3010 +#define NV3_PFIFO_CACHE0_PUT_ADDRESS 2 // 1 bit +#define NV3_PFIFO_CACHE0_PULLER 0x3040 +#define NV3_PFIFO_CACHE0_GET 0x3070 +#define NV3_PFIFO_CACHE0_GET_ADDRESS 2 // 1 bit +#define NV3_PFIFO_CACHE1_ACCESS 0x3200 +#define NV3_PFIFO_CACHE1_DMA_CHANNEL_ID 0x3204 +#define NV3_PFIFO_CACHE1_PUT 0x3210 +#define NV3_PFIFO_CACHE1_PUT_ADDRESS 2 // 6:2 +#define NV3_PFIFO_CACHE1_DMA_STATUS 0x3218 +#define NV3_PFIFO_CACHE1_DMA_CONFIG_0 0x3220 +#define NV3_PFIFO_CACHE1_DMA_CONFIG_1 0x3224 +#define NV3_PFIFO_CACHE1_DMA_CONFIG_2 0x3228 +#define NV3_PFIFO_CACHE1_DMA_CONFIG_3 0x322C +// Why does a gpu need its own translation lookaside buffer and pagetable format. Are they crazy +#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_PULLER 0x3240 +#define NV3_PFIFO_CACHE1_PULLER_CONTEXT_IS_CLEAN 0x3250 +#define NV3_PFIFO_CACHE1_GET 0x3270 +#define NV3_PFIFO_CACHE1_GET_ADDRESS 2 // 6:2 #define NV3_PFIFO_END 0x3FFF #define NV3_PRM_START 0x4000 // Real-Mode Device Support Subsystem #define NV3_PRM_INTR 0x4100 @@ -750,7 +787,7 @@ typedef struct nv3_pramdac_s uint32_t hserr_width; // horizontal sync error width } nv3_pramdac_t; -/* Holds DMA context channel information */ +/* Holds DMA channel context information */ typedef struct nv3_pgraph_context_switch_s { /* TODO */ @@ -766,12 +803,20 @@ typedef struct nv3_pgraph_context_control_s */ typedef struct nv3_pgraph_context_user_s { - bool reserved3 : 1; - uint8_t channel : 7; - uint8_t reserved2 : 4; - uint8_t class : 5; - uint8_t subchannel : 3; - uint16_t reserved : 12; + union + { + uint32_t value; + + struct + { + bool reserved3 : 1; + uint8_t channel : 7; + uint8_t reserved2 : 3; + uint8_t class : 5; + uint8_t subchannel : 3; + uint16_t reserved : 13; + }; + }; } nv3_pgraph_context_user_t; typedef struct nv3_pgraph_dma_settings_s @@ -819,6 +864,7 @@ typedef struct nv3_pgraph_s uint32_t interrupt_status_1; // Interrupt status 1 uint32_t interrupt_enable_1; // Interrupt enable 1 + uint32_t context_switch; // TODO: Make this a struct, it's just going to be enormous lol. nv3_pgraph_context_control_t context_control; nv3_pgraph_context_switch_t context_user_submit; nv3_pgraph_context_user_t context_user; @@ -923,16 +969,21 @@ typedef struct nv3_ptimer_s uint32_t alarm; // The value of time when there should be an alarm } nv3_ptimer_t; -typedef struct nv3_pramin_name_sd +typedef struct nv3_pramin_name_s { union { uint32_t name; - uint8_t byte_high; - uint8_t byte_mid2; - uint8_t byte_mid1; - uint8_t byte_low; + + struct + { + uint8_t byte_high; + uint8_t byte_mid2; + uint8_t byte_mid1; + uint8_t byte_low; + }; }; + } nv3_pramin_name_t; typedef struct nv3_pramin_context_s @@ -940,10 +991,16 @@ typedef struct nv3_pramin_context_s union { uint32_t context; - uint8_t dma_channel; - uint8_t render_object; //0=sw, 1=hw accelerated render - uint8_t class_id; - uint8_t ramin_offset; //find + + struct + { + + uint8_t dma_channel; + uint8_t render_object; //0=sw, 1=hw accelerated render + uint8_t class_id; + uint8_t ramin_offset; //find + }; + }; } nv3_pramin_context_t; @@ -1110,8 +1167,6 @@ uint32_t nv3_cio_read(uint32_t address); void nv3_cio_write(uint32_t address, uint32_t value); uint32_t nv3_pbus_read(uint32_t address); void nv3_pbus_write(uint32_t address, uint32_t value); -uint32_t nv3_pfifo_read(uint32_t address); -void nv3_pfifo_write(uint32_t address, uint32_t value); uint32_t nv3_prm_read(uint32_t address); void nv3_prm_write(uint32_t address, uint32_t value); uint32_t nv3_prmio_read(uint32_t address); @@ -1133,8 +1188,6 @@ uint32_t nv3_palt_read(uint32_t address); void nv3_palt_write(uint32_t address, uint32_t value); uint32_t nv3_pme_read(uint32_t address); void nv3_pme_write(uint32_t address, uint32_t value); -uint32_t nv3_pgraph_read(uint32_t address); -void nv3_pgraph_write(uint32_t address, uint32_t value); // TODO: PGRAPH class registers @@ -1163,11 +1216,18 @@ uint32_t nv3_pmc_handle_interrupts(bool send_now); // NV3 PGRAPH void nv3_pgraph_init(); +uint32_t nv3_pgraph_read(uint32_t address); +void nv3_pgraph_write(uint32_t address, uint32_t value); void nv3_pgraph_vblank_start(svga_t* svga); // NV3 PFIFO void nv3_pfifo_init(); +uint32_t nv3_pfifo_read(uint32_t address); +void nv3_pfifo_write(uint32_t address, uint32_t value); +// NV3 PFIFO - Caches +uint32_t nv3_pfifo_cache1_normal2gray(uint32_t val); +uint32_t nv3_pfifo_cache1_gray2normal(uint32_t val); // NV3 PFB void nv3_pfb_init(); diff --git a/src/video/nv/nv3/classes/nv3_class_names.c b/src/video/nv/nv3/classes/nv3_class_names.c index 2b38afbb4..0ee56443b 100644 --- a/src/video/nv/nv3/classes/nv3_class_names.c +++ b/src/video/nv/nv3/classes/nv3_class_names.c @@ -56,7 +56,7 @@ const char* nv3_class_names[] = "NV3 class 0x15: Stretched image from CPU", "NV3 INVALID class 0x16", "NV3 class 0x17: Direct3D 5.0 accelerated textured triangle w/zeta buffer", - "NV3 INVALID class 0x18", + "NV3 class 0x18: Point with zeta buffer", "NV3 INVALID class 0x19", "NV3 INVALID class 0x1A", "NV3 INVALID class 0x1B", diff --git a/src/video/nv/nv3/subsystems/nv3_pfifo.c b/src/video/nv/nv3/subsystems/nv3_pfifo.c index 1838faef5..b770116f3 100644 --- a/src/video/nv/nv3/subsystems/nv3_pfifo.c +++ b/src/video/nv/nv3/subsystems/nv3_pfifo.c @@ -28,8 +28,6 @@ #include <86Box/nv/vid_nv.h> #include <86Box/nv/vid_nv3.h> - - // // ****** pfifo register list START ****** // @@ -206,4 +204,32 @@ void nv3_pfifo_write(uint32_t address, uint32_t value) } } +} + +/* +https://en.wikipedia.org/wiki/Gray_code +WHY?????? IT'S NOT A TELEGRAPH IT'S A GPU????? + +Convert from a normal number to a total insanity number which is only used in PFIFO CACHE1 for ungodly and totally unknowable reasons +*/ +uint32_t nv3_pfifo_cache1_normal2gray(uint32_t val) +{ + return (val) ^ (val >> 1); +} + +/* +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) + { + val ^= mask; + mask >>= 1; + } + + return val; } \ No newline at end of file diff --git a/src/video/nv/nv3/subsystems/nv3_pgraph.c b/src/video/nv/nv3/subsystems/nv3_pgraph.c index 32f87ee30..fbdf058ec 100644 --- a/src/video/nv/nv3/subsystems/nv3_pgraph.c +++ b/src/video/nv/nv3/subsystems/nv3_pgraph.c @@ -120,6 +120,17 @@ uint32_t nv3_pgraph_read(uint32_t address) { switch (reg->address) { + case NV3_PGRAPH_DEBUG_0: + ret = nv3->pgraph.debug_0; + break; + case NV3_PGRAPH_DEBUG_1: + ret = nv3->pgraph.debug_1; + break; + case NV3_PGRAPH_DEBUG_2: + ret = nv3->pgraph.debug_2; + break; + case NV3_PGRAPH_DEBUG_3: + ret = nv3->pgraph.debug_3; //interrupt status and enable regs case NV3_PGRAPH_INTR_0: ret = nv3->pgraph.interrupt_status_0; @@ -133,6 +144,101 @@ uint32_t nv3_pgraph_read(uint32_t address) case NV3_PGRAPH_INTR_EN_1: ret = nv3->pgraph.interrupt_enable_1; break; + // A lot of this is currently a temporary implementation so that we can just debug what the current state looks like + // during the driver initialisation process + + // In the future, these will most likely have their own functions... + + // Context Swithcing (THIS IS CONTROLLED BY PFIFO!) + case NV3_PGRAPH_CONTEXT_SWITCH: + ret = nv3->pgraph.context_switch; + break; + case NV3_PGRAPH_CONTEXT_CONTROL: + ret = *(uint32_t*)&nv3->pgraph.context_control; + break; + case NV3_PGRAPH_CONTEXT_USER: + ret = *(uint32_t*)&nv3->pgraph.context_user; + break; + // Clip + case NV3_PGRAPH_ABS_UCLIP_XMIN: + ret = nv3->pgraph.abs_uclip_xmin; + break; + case NV3_PGRAPH_ABS_UCLIP_XMAX: + ret = nv3->pgraph.abs_uclip_xmax; + break; + case NV3_PGRAPH_ABS_UCLIP_YMIN: + ret = nv3->pgraph.abs_uclip_ymin; + break; + case NV3_PGRAPH_ABS_UCLIP_YMAX: + ret = nv3->pgraph.abs_uclip_ymax; + break; + // Canvas + case NV3_PGRAPH_SRC_CANVAS_MIN: + ret = *(uint32_t*)&nv3->pgraph.src_canvas_min; + break; + case NV3_PGRAPH_SRC_CANVAS_MAX: + ret = *(uint32_t*)&nv3->pgraph.src_canvas_max; + break; + // Pattern + case NV3_PGRAPH_PATTERN_COLOR_0_0: + ret = *(uint32_t*)&nv3->pgraph.pattern_color_0_0; + break; + case NV3_PGRAPH_PATTERN_COLOR_0_1: + ret = *(uint32_t*)&nv3->pgraph.pattern_color_0_1; + break; + case NV3_PGRAPH_PATTERN_COLOR_1_0: + ret = *(uint32_t*)&nv3->pgraph.pattern_color_1_0; + break; + case NV3_PGRAPH_PATTERN_COLOR_1_1: + ret = *(uint32_t*)&nv3->pgraph.pattern_color_1_1; + break; + case NV3_PGRAPH_PATTERN_BITMAP_HIGH: + ret = nv3->pgraph.pattern_bitmap_high; + break; + case NV3_PGRAPH_PATTERN_BITMAP_LOW: + ret = nv3->pgraph.pattern_bitmap_low; + break; + // Beta factor + case NV3_PGRAPH_BETA: + ret = nv3->pgraph.beta_factor; + break; + // DMA + case NV3_PGRAPH_DMA: + ret = *(uint32_t*)&nv3->pgraph.dma_settings; + break; + case NV3_PGRAPH_NOTIFY: + ret = *(uint32_t*)&nv3->pgraph.notifier; + break; + // More clip + case NV3_PGRAPH_CLIP0_MIN: + ret = *(uint32_t*)&nv3->pgraph.clip0_min; + break; + case NV3_PGRAPH_CLIP0_MAX: + ret = *(uint32_t*)&nv3->pgraph.clip0_max; + break; + case NV3_PGRAPH_CLIP1_MIN: + ret = *(uint32_t*)&nv3->pgraph.clip1_min; + break; + case NV3_PGRAPH_CLIP1_MAX: + ret = *(uint32_t*)&nv3->pgraph.clip1_max; + break; + case NV3_PGRAPH_CLIP_MISC: + ret = *(uint32_t*)&nv3->pgraph.clip_misc_settings; + break; + // Overall Status + case NV3_PGRAPH_STATUS: + ret = *(uint32_t*)&nv3->pgraph.status; + break; + // Trapped Address + case NV3_PGRAPH_TRAPPED_ADDRESS: + ret = nv3->pgraph.trapped_address; + break; + case NV3_PGRAPH_TRAPPED_DATA: + ret = nv3->pgraph.trapped_data; + break; + case NV3_PGRAPH_TRAPPED_INSTANCE: + ret = nv3->pgraph.trapped_instance; + break; } } @@ -189,6 +295,18 @@ void nv3_pgraph_write(uint32_t address, uint32_t value) { switch (reg->address) { + case NV3_PGRAPH_DEBUG_0: + nv3->pgraph.debug_0 = value; + break; + case NV3_PGRAPH_DEBUG_1: + nv3->pgraph.debug_1 = value; + break; + case NV3_PGRAPH_DEBUG_2: + nv3->pgraph.debug_2 = value; + break; + case NV3_PGRAPH_DEBUG_3: + nv3->pgraph.debug_3 = value; + break; //interrupt status and enable regs case NV3_PGRAPH_INTR_0: nv3->pgraph.interrupt_status_0 &= ~value; @@ -210,6 +328,101 @@ void nv3_pgraph_write(uint32_t address, uint32_t value) nv3->pgraph.interrupt_enable_1 = value & 0x00011111; nv3_pmc_handle_interrupts(true); + break; + // A lot of this is currently a temporary implementation so that we can just debug what the current state looks like + // during the driver initialisation process + + // In the future, these will most likely have their own functions... + + // Context Swithcing (THIS IS CONTROLLED BY PFIFO!) + case NV3_PGRAPH_CONTEXT_SWITCH: + nv3->pgraph.context_switch = value; + break; + case NV3_PGRAPH_CONTEXT_CONTROL: + *(uint32_t*)&nv3->pgraph.context_control = value; + break; + case NV3_PGRAPH_CONTEXT_USER: + *(uint32_t*)&nv3->pgraph.context_user = value; + break; + // Clip + case NV3_PGRAPH_ABS_UCLIP_XMIN: + nv3->pgraph.abs_uclip_xmin = value; + break; + case NV3_PGRAPH_ABS_UCLIP_XMAX: + nv3->pgraph.abs_uclip_xmax = value; + break; + case NV3_PGRAPH_ABS_UCLIP_YMIN: + nv3->pgraph.abs_uclip_ymin = value; + break; + case NV3_PGRAPH_ABS_UCLIP_YMAX: + nv3->pgraph.abs_uclip_ymax = value; + break; + // Canvas + case NV3_PGRAPH_SRC_CANVAS_MIN: + *(uint32_t*)&nv3->pgraph.src_canvas_min = value; + break; + case NV3_PGRAPH_SRC_CANVAS_MAX: + *(uint32_t*)&nv3->pgraph.src_canvas_max = value; + break; + // Pattern + case NV3_PGRAPH_PATTERN_COLOR_0_0: + *(uint32_t*)&nv3->pgraph.pattern_color_0_0 = value; + break; + case NV3_PGRAPH_PATTERN_COLOR_0_1: + *(uint32_t*)&nv3->pgraph.pattern_color_0_1 = value; + break; + case NV3_PGRAPH_PATTERN_COLOR_1_0: + *(uint32_t*)&nv3->pgraph.pattern_color_1_0 = value; + break; + case NV3_PGRAPH_PATTERN_COLOR_1_1: + *(uint32_t*)&nv3->pgraph.pattern_color_1_1 = value; + break; + case NV3_PGRAPH_PATTERN_BITMAP_HIGH: + nv3->pgraph.pattern_bitmap_high = value; + break; + case NV3_PGRAPH_PATTERN_BITMAP_LOW: + nv3->pgraph.pattern_bitmap_low = value; + break; + // Beta factor + case NV3_PGRAPH_BETA: + nv3->pgraph.beta_factor = value; + break; + // DMA + case NV3_PGRAPH_DMA: + *(uint32_t*)&nv3->pgraph.dma_settings = value; + break; + case NV3_PGRAPH_NOTIFY: + *(uint32_t*)&nv3->pgraph.notifier = value; + break; + // More clip + case NV3_PGRAPH_CLIP0_MIN: + *(uint32_t*)&nv3->pgraph.clip0_min = value; + break; + case NV3_PGRAPH_CLIP0_MAX: + *(uint32_t*)&nv3->pgraph.clip0_max = value; + break; + case NV3_PGRAPH_CLIP1_MIN: + *(uint32_t*)&nv3->pgraph.clip1_min = value; + break; + case NV3_PGRAPH_CLIP1_MAX: + *(uint32_t*)&nv3->pgraph.clip1_max = value; + break; + case NV3_PGRAPH_CLIP_MISC: + *(uint32_t*)&nv3->pgraph.clip_misc_settings = value; + break; + // Overall Status + case NV3_PGRAPH_STATUS: + *(uint32_t*)&nv3->pgraph.status = value; + break; + // Trapped Address + case NV3_PGRAPH_TRAPPED_ADDRESS: + nv3->pgraph.trapped_address = value; + break; + case NV3_PGRAPH_TRAPPED_DATA: + nv3->pgraph.trapped_data = value; + break; + case NV3_PGRAPH_TRAPPED_INSTANCE: + nv3->pgraph.trapped_instance = value; break; } } diff --git a/src/video/nv/nv3/subsystems/nv3_pramin_ramfc.c b/src/video/nv/nv3/subsystems/nv3_pramin_ramfc.c index e06445755..a3872c40a 100644 --- a/src/video/nv/nv3/subsystems/nv3_pramin_ramfc.c +++ b/src/video/nv/nv3/subsystems/nv3_pramin_ramfc.c @@ -6,7 +6,7 @@ * * This file is part of the 86Box distribution. * - * NV3 PFIFO RAMFC area: Stores context unused DMA channels + * NV3 PFIFO RAMFC area: Stores context for unused DMA channels * * * @@ -30,10 +30,10 @@ uint32_t nv3_ramfc_read(uint32_t address) { - nv_log("NV3: RAMFC (Unused DMA channel context) Read (0x%04x), UNIMPLEMENTED - RETURNING 0x00", address); + nv_log("NV3: RAMFC (Unused DMA channel context) Read (0x%04x), UNIMPLEMENTED - RETURNING 0x00\n", address); } void nv3_ramfc_write(uint32_t address, uint32_t value) { - nv_log("NV3: RAMFC (Unused DMA channel context) Write (0x%04x -> 0x%04x), UNIMPLEMENTED", value, address); + nv_log("NV3: RAMFC (Unused DMA channel context) Write (0x%04x -> 0x%04x), UNIMPLEMENTED\n", value, address); } \ No newline at end of file diff --git a/src/video/nv/nv3/subsystems/nv3_pramin_ramht.c b/src/video/nv/nv3/subsystems/nv3_pramin_ramht.c index ff72e811c..7df99d697 100644 --- a/src/video/nv/nv3/subsystems/nv3_pramin_ramht.c +++ b/src/video/nv/nv3/subsystems/nv3_pramin_ramht.c @@ -35,17 +35,17 @@ It is used to get the offset within RAMHT of a graphics object. uint32_t nv3_ramht_hash(nv3_pramin_name_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)", name, channel); + nv_log("NV3: Generating RAMHT hash (RAMHT slot=0x%04x (from name 0x%08x for DMA channel 0x%04x)\n)\n", name, channel); return hash; } uint32_t nv3_ramht_read(uint32_t address) { - nv_log("NV3: RAMHT (Graphics object storage hashtable) Read (0x%04x), UNIMPLEMENTED - RETURNING 0x00", address); + nv_log("NV3: RAMHT (Graphics object storage hashtable) Read (0x%04x), UNIMPLEMENTED - RETURNING 0x00\n", address); } void nv3_ramht_write(uint32_t address, uint32_t value) { - nv_log("NV3: RAMHT (Graphics object storage hashtable) Write (0x%04x -> 0x%04x), UNIMPLEMENTED", value, address); + nv_log("NV3: RAMHT (Graphics object storage hashtable) Write (0x%04x -> 0x%04x), UNIMPLEMENTED\n", value, address); } diff --git a/src/video/nv/nv3/subsystems/nv3_pramin_ramro.c b/src/video/nv/nv3/subsystems/nv3_pramin_ramro.c index 6176e191a..b7d8f4f57 100644 --- a/src/video/nv/nv3/subsystems/nv3_pramin_ramro.c +++ b/src/video/nv/nv3/subsystems/nv3_pramin_ramro.c @@ -30,10 +30,10 @@ uint32_t nv3_ramro_read(uint32_t address) { - nv_log("NV3: RAM Runout (invalid dma object submission) Read (0x%04x), UNIMPLEMENTED - RETURNING 0x00", address); + nv_log("NV3: RAM Runout (invalid dma object submission) Read (0x%04x), UNIMPLEMENTED - RETURNING 0x00\n", address); } void nv3_ramro_write(uint32_t address, uint32_t value) { - nv_log("NV3: RAM Runout WRITE, OH CRAP!!!! (0x%04x -> 0x%04x), UNIMPLEMENTED\n (Todo: Read the entries...)", value, address); + nv_log("NV3: RAM Runout WRITE, OH CRAP!!!! (0x%04x -> 0x%04x), UNIMPLEMENTED\n (Todo: Read the entries...)\n", value, address); } \ No newline at end of file