diff --git a/src/include/86box/nv/vid_nv3.h b/src/include/86box/nv/vid_nv3.h index 9c1a5628e..3756a47ed 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: 17 March 2025 (STILL WORKING ON IT!!!) + * Last updated: 20 March 2025 (STILL WORKING ON IT!!!) * * Authors: Connor Hyde * @@ -521,9 +521,11 @@ extern const device_config_t nv3_config[]; #define NV3_PGRAPH_DEBUG_3_FORMAT_CHECK 22 #define NV3_PGRAPH_DEBUG_3_ALPHA_CHECK 24 +// Interrupt stuff #define NV3_PGRAPH_INTR_0 0x400100 #define NV3_PGRAPH_INTR_0_VBLANK 8 // Fired every frame #define NV3_PGRAPH_INTR_0_VBLANK_ENABLED 0x1 // Is the vblank interrupt enabled? +#define NV3_PGRAPH_INTR_0_SOFTWARE_NOTIFY 28 // Fired on software notification #define NV3_PGRAPH_INTR_1 0x400104 #define NV3_PGRAPH_INTR_1_INVALID_METHOD 0 // Invalid method @@ -578,7 +580,14 @@ extern const device_config_t nv3_config[]; #define NV3_PGRAPH_CHROMA_KEY 0x40062C #define NV3_PGRAPH_BETA 0x400640 // Beta factor (30:23 fractional, 22:0 before fraction) #define NV3_PGRAPH_DMA 0x400680 -#define NV3_PGRAPH_NOTIFY 0x400684 // Notifier for PGRAPH + +// Current notification object for pgraph +#define NV3_PGRAPH_NOTIFY 0x400684 // Notifier for PGRAPH +#define NV3_PGRAPH_NOTIFY_INSTANCE 0 +#define NV3_PGRAPH_NOTIFY_REQUEST_PENDING 16 +#define NV3_PGRAPH_NOTIFY_REQUEST_TYPE 20 +#define NV3_PGRAPH_NOTIFY_REQUEST_TYPE_HARDWARE 0x0 // anything else is software + #define NV3_PGRAPH_CLIP0_MIN 0x400690 // Clip for Blitting 0 Min #define NV3_PGRAPH_CLIP0_MAX 0x400694 // Clip for Blitting 0 Max #define NV3_PGRAPH_CLIP1_MIN 0x400698 // Clip for Blitting 1 Min @@ -882,11 +891,6 @@ typedef struct nv3_pci_config_s uint8_t int_line; } nv3_pci_config_t; -/* Notifier Engine */ -typedef struct nv3_notifier_s -{ - /* TODO */ -} nv3_notifier_t; // add enums for eac // Chip configuration @@ -1187,7 +1191,7 @@ typedef struct nv3_pgraph_s uint32_t bpixel[NV3_PGRAPH_MAX_BUFFERS]; // Pixel format for each possible surfaces. // CLIP nv3_pgraph_clip_misc_settings_t clip_misc_settings; - nv3_notifier_t notifier; + uint32_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; diff --git a/src/sound/snd_emu8k.c b/src/sound/snd_emu8k.c index 822abeeaa..c32c16be1 100644 --- a/src/sound/snd_emu8k.c +++ b/src/sound/snd_emu8k.c @@ -1525,7 +1525,7 @@ emu8k_outw(uint16_t addr, uint16_t val, void *priv) default: break; } - emu8k_log("EMU8K WRITE: Unknown register write: %04X-%02X(%d/%d): %04X \n", addr, (emu8k->cur_reg) << 5 | emu8k->cur_voice, + emu8k_log("EMU8K WRITE: : Unknown register write: %04X-%02X(%d/%d): %04X \n", addr, (emu8k->cur_reg) << 5 | emu8k->cur_voice, emu8k->cur_reg, emu8k->cur_voice, val); } diff --git a/src/sound/snd_sb.c b/src/sound/snd_sb.c index e89946486..160e79881 100644 --- a/src/sound/snd_sb.c +++ b/src/sound/snd_sb.c @@ -798,7 +798,7 @@ sb_ct1335_mixer_write(uint16_t addr, uint8_t val, void *priv) break; default: - sb_log("sb_ct1335: Unknown register WRITE: %02X\t%02X\n", mixer->index, mixer->regs[mixer->index]); + sb_log("sb_ct1335: : Unknown register write: %02X\t%02X\n", mixer->index, mixer->regs[mixer->index]); break; } } @@ -899,7 +899,7 @@ sb_ct1345_mixer_write(uint16_t addr, uint8_t val, void *priv) break; default: - sb_log("sb_ct1345: Unknown register WRITE: %02X\t%02X\n", mixer->index, mixer->regs[mixer->index]); + sb_log("sb_ct1345: : Unknown register write: %02X\t%02X\n", mixer->index, mixer->regs[mixer->index]); break; } } 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 abeb0571b..fcfe1e7c4 100644 --- a/src/video/nv/nv3/classes/nv3_class_shared_methods.c +++ b/src/video/nv/nv3/classes/nv3_class_shared_methods.c @@ -29,10 +29,31 @@ #include <86box/nv/vid_nv.h> #include <86box/nv/vid_nv3.h> -void nv3_generic_method(uint32_t name, uint32_t method_id, nv3_ramin_context_t context, nv3_grobj_t grobj) +void nv3_generic_method(uint32_t param, uint32_t method_id, nv3_ramin_context_t context, nv3_grobj_t grobj) { switch (method_id) { + // set up the current notification request/object] + // check for double notifiers. + case NV3_SET_NOTIFY: + if (nv3->pgraph.notify_pending) + { + nv_log("Executed method NV3_SET_NOTIFY with nv3->pgraph.notify_pending already set. param=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(param, context); + nv3_pgraph_interrupt_invalid(NV3_PGRAPH_INTR_1_DOUBLE_NOTIFY); + + // disable + nv3->pgraph.notify_pending = false; + nv3_pgraph_interrupt_invalid(NV3_PGRAPH_INTR_1_DOUBLE_NOTIFY); + /* may need to disable fifo in this state */ + return; + } + + // set a notify as pending. + nv3->pgraph.notifier = param; + nv3->pgraph.notify_pending = true; + break; default: nv_log("Shared Generic Methods: Invalid or Unimplemented method 0x%04x", method_id); nv3_pgraph_interrupt_invalid(NV3_PGRAPH_INTR_1_INVALID_METHOD); @@ -44,18 +65,19 @@ void nv3_generic_method(uint32_t name, uint32_t method_id, nv3_ramin_context_t c /* 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; + if (!nv3->pgraph.notify_pending) return; - } + uint32_t current_notification_object = nv3->pgraph.notifier; + + // check for a software method (0 = hardware, 1 = software) + if (((current_notification_object >> NV3_PGRAPH_NOTIFY_REQUEST_TYPE) & 0x07) != 0) + { + nv_log("Software Notification, firing interrupt"); + nv3_pgraph_interrupt_valid(NV3_PGRAPH_INTR_0_SOFTWARE_NOTIFY); + return; + } + // set up the NvNotification structure nv3_notification_t notify = {0}; notify.nanoseconds = nv3->ptimer.time; @@ -79,7 +101,8 @@ void nv3_notify_if_needed(uint32_t name, uint32_t method_id, nv3_ramin_context_t /* 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; + //uint32_t frame_value = (notify_obj_page >> NV3_NOTIFICATION_PAGE_FRAME_ADDRESS) & 0xFFFFF; + uint32_t frame_value = (notify_obj_page >> NV3_NOTIFICATION_PAGE_FRAME_ADDRESS) & 0xFFFFF000; // This code is temporary and will probably be moved somewhere else // Print torns of debug info @@ -99,18 +122,18 @@ void nv3_notify_if_needed(uint32_t name, uint32_t method_id, nv3_ramin_context_t 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"); + (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"); + || 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); + nv_log("Limit: 0x%08x\n", 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); + nv_log("Pageframe Address: 0x%08x\n", frame_value); #endif // set up the dma transfer. we need to translate to a physical address. diff --git a/src/video/nv/nv3/subsystems/nv3_pbus.c b/src/video/nv/nv3/subsystems/nv3_pbus.c index 2594e0739..ca631edfc 100644 --- a/src/video/nv/nv3/subsystems/nv3_pbus.c +++ b/src/video/nv/nv3/subsystems/nv3_pbus.c @@ -122,6 +122,10 @@ void nv3_pbus_write(uint32_t address, uint32_t value) } } + else /* Completely unknown */ + { + nv_log(": Unknown register write (address=0x%08x)\n", address); + } } uint8_t nv3_pbus_rma_read(uint16_t addr) diff --git a/src/video/nv/nv3/subsystems/nv3_pextdev.c b/src/video/nv/nv3/subsystems/nv3_pextdev.c index 6d8cadbf0..c26266a00 100644 --- a/src/video/nv/nv3/subsystems/nv3_pextdev.c +++ b/src/video/nv/nv3/subsystems/nv3_pextdev.c @@ -150,4 +150,8 @@ void nv3_pextdev_write(uint32_t address, uint32_t value) if (reg->on_write) reg->on_write(value); } + else /* Completely unknown */ + { + nv_log(": Unknown register write (address=0x%08x)\n", 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 92a643502..f7d80a41a 100644 --- a/src/video/nv/nv3/subsystems/nv3_pfb.c +++ b/src/video/nv/nv3/subsystems/nv3_pfb.c @@ -152,6 +152,10 @@ void nv3_pfb_write(uint32_t address, uint32_t value) } } } + else /* Completely unknown */ + { + nv_log(": Unknown register write (address=0x%08x)\n", address); + } } uint32_t nv3_pfb_config0_read() diff --git a/src/video/nv/nv3/subsystems/nv3_pfifo.c b/src/video/nv/nv3/subsystems/nv3_pfifo.c index a836fdd21..073599577 100644 --- a/src/video/nv/nv3/subsystems/nv3_pfifo.c +++ b/src/video/nv/nv3/subsystems/nv3_pfifo.c @@ -599,7 +599,6 @@ void nv3_pfifo_write(uint32_t address, uint32_t val) 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) @@ -609,6 +608,10 @@ void nv3_pfifo_write(uint32_t address, uint32_t val) nv_log("PFIFO Cache1 CTX Write Entry=%d value=0x%04x\n", ctx_entry_id, val); } + else /* Completely unknown */ + { + nv_log(": Unknown register write (address=0x%08x)\n", address); + } /* Trigger DMA for notifications if we need to */ nv3_pfifo_trigger_dma_if_required(); @@ -620,6 +623,7 @@ 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 +(Possibly it just makes it easier to implement in logic) I decided to use a lookup table to save everyone's time, also the numbers generated from the function that existed here before didn't make any sense diff --git a/src/video/nv/nv3/subsystems/nv3_pgraph.c b/src/video/nv/nv3/subsystems/nv3_pgraph.c index 5851d9301..93fe8c32f 100644 --- a/src/video/nv/nv3/subsystems/nv3_pgraph.c +++ b/src/video/nv/nv3/subsystems/nv3_pgraph.c @@ -472,6 +472,10 @@ void nv3_pgraph_write(uint32_t address, uint32_t value) nv_log("PGRAPH Context Cache Write (Entry=%04x Value=0x%08x)\n", entry, value); nv3->pgraph.context_cache[entry] = value; } + else /* Completely unknown */ + { + nv_log(": Unknown register write (address=0x%08x)\n", address); + } } } @@ -506,6 +510,7 @@ void nv3_pgraph_arbitrate_method(uint32_t param, uint16_t method, uint8_t channe // we need to shift left by 4 to get the real address, something to do with the 16 byte unit of reversal uint32_t real_ramin_base = context.ramin_offset << 4; + // readin our grobj grobj.grobj_0 = nv3_ramin_read32(real_ramin_base, nv3); grobj.grobj_1 = nv3_ramin_read32(real_ramin_base + 4, nv3); grobj.grobj_2 = nv3_ramin_read32(real_ramin_base + 8, nv3); @@ -514,80 +519,90 @@ void nv3_pgraph_arbitrate_method(uint32_t param, uint16_t method, uint8_t channe nv_log("**** About to execute method **** method=0x%04x param=0x%08x, channel=%d.%d, class=%s, grobj=0x%08x 0x%08x 0x%08x 0x%08x\n", method, param, channel, subchannel, nv3_class_names[class_id], grobj.grobj_0, grobj.grobj_1, grobj.grobj_2, grobj.grobj_3); - // By this point, we already ANDed the class ID to 0x1F. - // Send the grobj, the context, the method and the name off to actually be acted upon. - switch (class_id) + /* Methods below 0x104 are shared across all classids, so call generic_method for that*/ + if (method <= NV3_SET_NOTIFY) { - case nv3_pgraph_class01_beta_factor: - nv3_class_001_method(param, method, context, grobj); - break; - case nv3_pgraph_class02_rop: - nv3_class_002_method(param, method, context, grobj); - break; - case nv3_pgraph_class03_chroma_key: - nv3_class_003_method(param, method, context, grobj); - break; - case nv3_pgraph_class04_plane_mask: - nv3_class_004_method(param, method, context, grobj); - break; - case nv3_pgraph_class05_clipping_rectangle: - nv3_class_005_method(param, method, context, grobj); - break; - case nv3_pgraph_class06_pattern: - nv3_class_006_method(param, method, context, grobj); - break; - case nv3_pgraph_class07_rectangle: - nv3_class_007_method(param, method, context, grobj); - break; - case nv3_pgraph_class08_point: - nv3_class_008_method(param, method, context, grobj); - break; - case nv3_pgraph_class09_line: - nv3_class_009_method(param, method, context, grobj); - break; - case nv3_pgraph_class0a_lin: - nv3_class_00a_method(param, method, context, grobj); - break; - case nv3_pgraph_class0b_triangle: - nv3_class_00b_method(param, method, context, grobj); - break; - case nv3_pgraph_class0c_w95txt: - nv3_class_00c_method(param, method, context, grobj); - break; - case nv3_pgraph_class0d_m2mf: - nv3_class_00d_method(param, method, context, grobj); - break; - case nv3_pgraph_class0e_scaled_image_from_memory: - nv3_class_00e_method(param, method, context, grobj); - break; - case nv3_pgraph_class10_blit: - nv3_class_010_method(param, method, context, grobj); - break; - case nv3_pgraph_class11_image: - nv3_class_011_method(param, method, context, grobj); - break; - case nv3_pgraph_class12_bitmap: - nv3_class_012_method(param, method, context, grobj); - break; - case nv3_pgraph_class14_transfer2memory: - nv3_class_014_method(param, method, context, grobj); - break; - case nv3_pgraph_class15_stretched_image_from_cpu: - nv3_class_015_method(param, method, context, grobj); - break; - case nv3_pgraph_class17_d3d5tri_zeta_buffer: - nv3_class_017_method(param, method, context, grobj); - break; - case nv3_pgraph_class18_point_zeta_buffer: - nv3_class_018_method(param, method, context, grobj); - break; - case nv3_pgraph_class1c_image_in_memory: - nv3_class_01c_method(param, method, context, grobj); - break; - default: - fatal("NV3 (nv3_pgraph_arbitrate_method): Attempted to execute method on invalid, or unimplemented, class ID %s", nv3_class_names[class_id]); - return; + nv3_generic_method(param, method, context, grobj); } + else + { + // By this point, we already ANDed the class ID to 0x1F. + // Send the grobj, the context, the method and the name off to actually be acted upon. + switch (class_id) + { + case nv3_pgraph_class01_beta_factor: + nv3_class_001_method(param, method, context, grobj); + break; + case nv3_pgraph_class02_rop: + nv3_class_002_method(param, method, context, grobj); + break; + case nv3_pgraph_class03_chroma_key: + nv3_class_003_method(param, method, context, grobj); + break; + case nv3_pgraph_class04_plane_mask: + nv3_class_004_method(param, method, context, grobj); + break; + case nv3_pgraph_class05_clipping_rectangle: + nv3_class_005_method(param, method, context, grobj); + break; + case nv3_pgraph_class06_pattern: + nv3_class_006_method(param, method, context, grobj); + break; + case nv3_pgraph_class07_rectangle: + nv3_class_007_method(param, method, context, grobj); + break; + case nv3_pgraph_class08_point: + nv3_class_008_method(param, method, context, grobj); + break; + case nv3_pgraph_class09_line: + nv3_class_009_method(param, method, context, grobj); + break; + case nv3_pgraph_class0a_lin: + nv3_class_00a_method(param, method, context, grobj); + break; + case nv3_pgraph_class0b_triangle: + nv3_class_00b_method(param, method, context, grobj); + break; + case nv3_pgraph_class0c_w95txt: + nv3_class_00c_method(param, method, context, grobj); + break; + case nv3_pgraph_class0d_m2mf: + nv3_class_00d_method(param, method, context, grobj); + break; + case nv3_pgraph_class0e_scaled_image_from_memory: + nv3_class_00e_method(param, method, context, grobj); + break; + case nv3_pgraph_class10_blit: + nv3_class_010_method(param, method, context, grobj); + break; + case nv3_pgraph_class11_image: + nv3_class_011_method(param, method, context, grobj); + break; + case nv3_pgraph_class12_bitmap: + nv3_class_012_method(param, method, context, grobj); + break; + case nv3_pgraph_class14_transfer2memory: + nv3_class_014_method(param, method, context, grobj); + break; + case nv3_pgraph_class15_stretched_image_from_cpu: + nv3_class_015_method(param, method, context, grobj); + break; + case nv3_pgraph_class17_d3d5tri_zeta_buffer: + nv3_class_017_method(param, method, context, grobj); + break; + case nv3_pgraph_class18_point_zeta_buffer: + nv3_class_018_method(param, method, context, grobj); + break; + case nv3_pgraph_class1c_image_in_memory: + nv3_class_01c_method(param, method, context, grobj); + break; + default: + fatal("NV3 (nv3_pgraph_arbitrate_method): Attempted to execute method on invalid, or unimplemented, class ID %s", nv3_class_names[class_id]); + return; + } + } + + nv3_notify_if_needed(param, method, context, grobj); } diff --git a/src/video/nv/nv3/subsystems/nv3_pmc.c b/src/video/nv/nv3/subsystems/nv3_pmc.c index f67eb707b..24f0ad44a 100644 --- a/src/video/nv/nv3/subsystems/nv3_pmc.c +++ b/src/video/nv/nv3/subsystems/nv3_pmc.c @@ -269,4 +269,8 @@ void nv3_pmc_write(uint32_t address, uint32_t value) nv_log("\n"); } + else /* Completely unknown */ + { + nv_log(": Unknown register write (address=0x%08x)\n", address); + } } \ No newline at end of file diff --git a/src/video/nv/nv3/subsystems/nv3_pme.c b/src/video/nv/nv3/subsystems/nv3_pme.c index e555c9752..d7f6f0cf9 100644 --- a/src/video/nv/nv3/subsystems/nv3_pme.c +++ b/src/video/nv/nv3/subsystems/nv3_pme.c @@ -128,4 +128,9 @@ void nv3_pme_write(uint32_t address, uint32_t value) } } + else /* Completely unknown */ + { + nv_log(": Unknown register write (address=0x%08x)\n", address); + } + } \ No newline at end of file diff --git a/src/video/nv/nv3/subsystems/nv3_pramdac.c b/src/video/nv/nv3/subsystems/nv3_pramdac.c index 6ff090716..c9430018f 100644 --- a/src/video/nv/nv3/subsystems/nv3_pramdac.c +++ b/src/video/nv/nv3/subsystems/nv3_pramdac.c @@ -377,4 +377,9 @@ void nv3_pramdac_write(uint32_t address, uint32_t value) } } } + else /* Completely unknown */ + { + nv_log(": Unknown register write (address=0x%08x)\n", address); + } + } \ No newline at end of file diff --git a/src/video/nv/nv3/subsystems/nv3_ptimer.c b/src/video/nv/nv3/subsystems/nv3_ptimer.c index aa5942ad8..b5c278387 100644 --- a/src/video/nv/nv3/subsystems/nv3_ptimer.c +++ b/src/video/nv/nv3/subsystems/nv3_ptimer.c @@ -222,4 +222,8 @@ void nv3_ptimer_write(uint32_t address, uint32_t value) } } } + else /* Completely unknown */ + { + nv_log(": Unknown register write (address=0x%08x)\n", address); + } } \ No newline at end of file diff --git a/src/video/nv/nv3/subsystems/nv3_pvideo.c b/src/video/nv/nv3/subsystems/nv3_pvideo.c index db6e78a59..6f72da719 100644 --- a/src/video/nv/nv3/subsystems/nv3_pvideo.c +++ b/src/video/nv/nv3/subsystems/nv3_pvideo.c @@ -152,5 +152,8 @@ void nv3_pvideo_write(uint32_t address, uint32_t value) } } } - + else /* Completely unknown */ + { + nv_log(": Unknown register write (address=0x%08x)\n", address); + } } \ No newline at end of file diff --git a/src/video/vid_voodoo.c b/src/video/vid_voodoo.c index e45f112ed..8f6e8bf26 100644 --- a/src/video/vid_voodoo.c +++ b/src/video/vid_voodoo.c @@ -676,7 +676,7 @@ voodoo_writel(uint32_t addr, uint32_t val, void *priv) default: if (voodoo->fbiInit7 & FBIINIT7_CMDFIFO_ENABLE) { - voodoo_log("Unknown register write in CMDFIFO mode %08x %08x\n", addr, val); + voodoo_log(": Unknown register write in CMDFIFO mode %08x %08x\n", addr, val); } else { voodoo_queue_command(voodoo, addr | FIFO_WRITEL_REG, val); }