diff --git a/doc/nvidia_notes/status.xlsx b/doc/nvidia_notes/status.xlsx new file mode 100644 index 000000000..a301eba64 Binary files /dev/null and b/doc/nvidia_notes/status.xlsx differ diff --git a/src/include/86box/nv/classes/vid_nv3_classes.h b/src/include/86box/nv/classes/vid_nv3_classes.h index 96df80eb1..80e2c1437 100644 --- a/src/include/86box/nv/classes/vid_nv3_classes.h +++ b/src/include/86box/nv/classes/vid_nv3_classes.h @@ -92,7 +92,15 @@ typedef enum nv3_pgraph_class_e #define NV3_RECTANGLE_START 0x0400 #define NV3_RECTANGLE_MAX 16 -#define NV3_RECTNAGLE_END 0x0480 +#define NV3_RECTANGLE_END 0x0480 + +// image_from_cpu +#define NV3_IMAGE_START_POSITION 0x0304 // starting position of image from cpu +#define NV3_IMAGE_SIZE 0x0308 +#define NV3_IMAGE_SIZE_IN 0x030C +#define NV3_IMAGE_COLOR_START 0x0400 +#define NV3_IMAGE_COLOR_MAX 32 +#define NV3_IMAGE_COLOR_END 0x0480 #define NV3_IMAGE_IN_MEMORY_COLOR_FORMAT 0x0300 #define NV3_IMAGE_IN_MEMORY_IN_MEMORY_DMA_CTX_TYPE 0x0304 diff --git a/src/include/86box/nv/vid_nv3.h b/src/include/86box/nv/vid_nv3.h index 640a0c951..29b2f70b9 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: 20 March 2025 (STILL WORKING ON IT!!!) + * Last updated: 22 March 2025 (STILL WORKING ON IT!!!) * * Authors: Connor Hyde * @@ -1227,6 +1227,7 @@ typedef struct nv3_pgraph_s struct nv3_object_class_00E scaled_image_from_memory; struct nv3_object_class_010 blit; struct nv3_object_class_011 image; + nv3_position_16_t image_current_position; /* This is here so we can hold the current state of the image */ struct nv3_object_class_012 bitmap; struct nv3_object_class_014 transfer2memory; struct nv3_object_class_015 stretched_image_from_cpu; diff --git a/src/video/nv/nv3/classes/nv3_class_007_rectangle.c b/src/video/nv/nv3/classes/nv3_class_007_rectangle.c index a92a1f761..8f304fdac 100644 --- a/src/video/nv/nv3/classes/nv3_class_007_rectangle.c +++ b/src/video/nv/nv3/classes/nv3_class_007_rectangle.c @@ -37,7 +37,7 @@ void nv3_class_007_method(uint32_t param, uint32_t method_id, nv3_ramin_context_ break; default: /* Check for any rectangle point or size method. */ - if (method_id >= NV3_RECTANGLE_START && method_id <= NV3_RECTNAGLE_END) + if (method_id >= NV3_RECTANGLE_START && method_id <= NV3_RECTANGLE_END) { uint32_t index = (method_id - NV3_RECTANGLE_START) / 8; diff --git a/src/video/nv/nv3/classes/nv3_class_011_image.c b/src/video/nv/nv3/classes/nv3_class_011_image.c index b40b9025c..9b4446cff 100644 --- a/src/video/nv/nv3/classes/nv3_class_011_image.c +++ b/src/video/nv/nv3/classes/nv3_class_011_image.c @@ -28,13 +28,108 @@ #include <86box/nv/vid_nv.h> #include <86box/nv/vid_nv3.h> +/* Check the line bounds */ +void nv3_class_011_check_line_bounds() +{ + uint32_t relative_x = nv3->pgraph.image_current_position.x - nv3->pgraph.image.point.x; + //uint32_t relative_y = nv3->pgraph.image_current_position.y - nv3->pgraph.image.point.y; + + /* In theory, relative_y should never be exceeded...because it only submits enough pixels to render the image*/ + if (relative_x >= nv3->pgraph.image.size_in.w) + { + nv3->pgraph.image_current_position.y++; + nv3->pgraph.image_current_position.x = nv3->pgraph.image.point.x; + } +} + void nv3_class_011_method(uint32_t param, uint32_t method_id, nv3_ramin_context_t context, nv3_grobj_t grobj) { switch (method_id) { + case NV3_IMAGE_START_POSITION: + nv3->pgraph.image.point.x = (param & 0xFFFF); + nv3->pgraph.image.point.y = (param >> 16); + nv_log("Image Point=%d,%d", nv3->pgraph.image.point.x, nv3->pgraph.image.point.y); + break; + /* Seems to allow scaling of the bitblt. */ + case NV3_IMAGE_SIZE: + nv3->pgraph.image.size.w = (param & 0xFFFF); + nv3->pgraph.image.size.h = (param >> 16); + break; + case NV3_IMAGE_SIZE_IN: + nv3->pgraph.image.size_in.w = (param & 0xFFFF); + nv3->pgraph.image.size_in.h = (param >> 16); + nv3->pgraph.image_current_position = nv3->pgraph.image.point; + break; default: - nv_log("%s: Invalid or Unimplemented method 0x%04x", nv3_class_names[context.class_id & 0x1F], method_id); - nv3_pgraph_interrupt_invalid(NV3_PGRAPH_INTR_1_SOFTWARE_METHOD_PENDING); + if (method_id >= NV3_IMAGE_COLOR_START && method_id <= NV3_IMAGE_COLOR_END) + { + // shift left by 2 because it's 4 bits per si\e.. + uint32_t pixel_slot = (method_id - NV3_IMAGE_COLOR_START) >> 2; + uint32_t current_buffer = (nv3->pgraph.context_switch >> NV3_PGRAPH_CONTEXT_SWITCH_SRC_BUFFER) & 0x03; + + /* todo: a lot of stuff */ + + uint32_t pixel0 = 0, pixel1 = 0, pixel2 = 0, pixel3 = 0; + + /* we need to unpack them - IF THIS IS USED SOMEWHERE ELSE, DO SOMETHING ELSE WITH IT */ + /* the reverse order is due to the endianness */ + switch (nv3->nvbase.svga.bpp) + { + // 4pixels packed into one + case 8: + + //pixel3 + pixel3 = param & 0xFF; + nv3_render_pixel(nv3->pgraph.image_current_position, pixel3, grobj); + nv3->pgraph.image_current_position.x++; + nv3_class_011_check_line_bounds(); + + pixel2 = (param >> 8) & 0xFF; + nv3_render_pixel(nv3->pgraph.image_current_position, pixel2, grobj); + nv3->pgraph.image_current_position.x++; + nv3_class_011_check_line_bounds(); + + pixel1 = (param >> 16) & 0xFF; + nv3_render_pixel(nv3->pgraph.image_current_position, pixel1, grobj); + nv3->pgraph.image_current_position.x++; + nv3_class_011_check_line_bounds(); + + pixel0 = (param >> 24) & 0xFF; + nv3_render_pixel(nv3->pgraph.image_current_position, pixel0, grobj); + nv3->pgraph.image_current_position.x++; + nv3_class_011_check_line_bounds(); + + break; + //2pixels packed into 1 + case 16: + pixel1 = (param) & 0xFFFF; + nv3_render_pixel(nv3->pgraph.image_current_position, pixel1, grobj); + nv3->pgraph.image_current_position.x++; + nv3_class_011_check_line_bounds(); + + pixel0 = (param >> 16) & 0xFFFF; + nv3_render_pixel(nv3->pgraph.image_current_position, pixel0, grobj); + nv3->pgraph.image_current_position.x++; + nv3_class_011_check_line_bounds(); + + break; + // just one + case 32: + pixel0 = param; + nv3_render_pixel(nv3->pgraph.image_current_position, pixel0, grobj); + nv3->pgraph.image_current_position.x++; + nv3_class_011_check_line_bounds(); + + break; + } + } + else + { + nv_log("%s: Invalid or Unimplemented method 0x%04x", nv3_class_names[context.class_id & 0x1F], method_id); + nv3_pgraph_interrupt_invalid(NV3_PGRAPH_INTR_1_SOFTWARE_METHOD_PENDING); + + } return; } } \ No newline at end of file