diff cd_graphics.c @ 2271:3ef80963c2a7

Fix stamp address mask and add WIP CD graphics debug view
author Michael Pavone <pavone@retrodev.com>
date Thu, 29 Dec 2022 15:47:19 -0800
parents da326c32ad8f
children a1afe26a8ef0
line wrap: on
line diff
--- a/cd_graphics.c	Mon Dec 26 12:42:12 2022 -0800
+++ b/cd_graphics.c	Thu Dec 29 15:47:19 2022 -0800
@@ -1,5 +1,6 @@
 #include "cd_graphics.h"
 #include "backend.h"
+#include "render.h"
 
 void cd_graphics_init(segacd_context *cd)
 {
@@ -22,12 +23,12 @@
 		//32x32 stamps
 		stamp_shift = 5;
 		pixel_mask = 0x1F;
-		stamp_num_mask = 0x3FC;
+		stamp_num_mask = 0x7FC;
 	} else {
 		//16x16 stamps
 		stamp_shift = 4;
 		pixel_mask = 0xF;
-		stamp_num_mask = 0x3FF;
+		stamp_num_mask = 0x7FF;
 	}
 	uint16_t stamp_x = x >> stamp_shift;
 	uint16_t stamp_y = y >> stamp_shift;
@@ -249,6 +250,64 @@
 	}
 }
 
+void scd_toggle_graphics_debug(segacd_context *cd)
+{
+	if (cd->graphics_debug_window) {
+		render_destroy_window(cd->graphics_debug_window);
+		cd->graphics_debug_window = 0;
+	} else {
+		cd->graphics_debug_window = render_create_window("CD ASIC", 1024, 1024, NULL);
+	}
+}
+
+static void render_graphics_debug(segacd_context *cd)
+{
+	int pitch;
+	uint32_t *fb = render_get_framebuffer(cd->graphics_debug_window, &pitch);
+	uint32_t pixels = (cd->gate_array[GA_STAMP_SIZE] & BIT_SMS) ? 4096 : 256;
+	uint32_t stamp_size = (cd->gate_array[GA_STAMP_SIZE] & BIT_STS) ? 32 : 16;
+	uint32_t num_stamps = pixels / stamp_size;
+	//TODO: fix mask based on SMS and STS
+	uint32_t address = (cd->gate_array[GA_STAMP_MAP_BASE] & 0xFFE0) << 1;
+	genesis_context *gen = cd->genesis;
+	for (uint32_t stamp_y = 0; stamp_y < num_stamps; stamp_y++)
+	{
+		uint32_t start_y = stamp_y * stamp_size;
+		for (uint32_t stamp_x = 0; stamp_x < num_stamps; stamp_x++)
+		{
+			uint16_t entry = cd->word_ram[address++];
+			uint32_t tile_address = (entry & 0x7FF) << 6;
+			//TODO: flip and rotation
+			uint32_t start_x = stamp_x * stamp_size;
+			if (start_x < 1024 && start_y < 1024) {
+				for (uint32_t tile_x = start_x; tile_x < start_x + stamp_size; tile_x+=8)
+				{
+					for (uint32_t y = start_y; y < start_y + stamp_size; y++)
+					{
+						uint32_t *line = fb + y * pitch / sizeof(uint32_t);
+						for (uint32_t x = tile_x; x < tile_x + 8; x += 4)
+						{
+						
+							uint16_t word = cd->word_ram[tile_address++];
+							uint16_t pixels[4] = {
+								word >> 12,
+								word >> 8 & 0xF,
+								word >> 4 & 0xF,
+								word & 0xF
+							};
+							for (uint32_t i = 0; i < 4; i++)
+							{
+								line[x + i] = gen->vdp->colors[pixels[i]];
+							}
+						}
+					}
+				}
+			}
+		}
+	}
+	render_framebuffer_updated(cd->graphics_debug_window, 1024);
+}
+
 void cd_graphics_run(segacd_context *cd, uint32_t cycle)
 {
 	while (cd->graphics_cycle < cycle)
@@ -263,6 +322,10 @@
 			if (cd->graphics_cycle >= cd->graphics_int_cycle) {
 				printf("graphics end %u\n", cd->graphics_cycle);
 				cd->gate_array[GA_STAMP_SIZE] &= ~BIT_GRON;
+				
+				if (cd->graphics_debug_window) {
+					render_graphics_debug(cd);
+				}
 				break;
 			}
 		} else {