changeset 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 827ab6dd534a
children 777900eb8e15
files bindings.c cd_graphics.c genesis.c segacd.h system.h
diffstat 5 files changed, 74 insertions(+), 2 deletions(-) [+]
line wrap: on
line diff
--- a/bindings.c	Mon Dec 26 12:42:12 2022 -0800
+++ b/bindings.c	Thu Dec 29 15:47:19 2022 -0800
@@ -44,6 +44,7 @@
 	UI_CRAM_DEBUG,
 	UI_COMPOSITE_DEBUG,
 	UI_OSCILLOSCOPE_DEBUG,
+	UI_CD_GRAPHICS_DEBUG
 } ui_action;
 
 typedef struct {
@@ -434,6 +435,7 @@
 		case UI_CRAM_DEBUG:
 		case UI_COMPOSITE_DEBUG:
 		case UI_OSCILLOSCOPE_DEBUG:
+		case UI_CD_GRAPHICS_DEBUG:
 			if (allow_content_binds && current_system->toggle_debug_view) {
 				current_system->toggle_debug_view(current_system, binding->subtype_a - UI_PLANE_DEBUG + DEBUG_PLANE);
 				/*
@@ -677,6 +679,8 @@
 			*subtype_a = UI_COMPOSITE_DEBUG;
 		} else if (!strcmp(target + 3, "oscilloscope")) {
 			*subtype_a = UI_OSCILLOSCOPE_DEBUG;
+		} else if (!strcmp(target + 3, "cd_graphics_debug")) {
+			*subtype_a = UI_CD_GRAPHICS_DEBUG;
 		} else {
 			warning("Unreconized UI binding type %s\n", target);
 			return 0;
--- 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 {
--- a/genesis.c	Mon Dec 26 12:42:12 2022 -0800
+++ b/genesis.c	Thu Dec 29 15:47:19 2022 -0800
@@ -1740,6 +1740,8 @@
 				rf5c164_enable_scope(&cd->pcm, scope);
 			}
 		}
+	} else if (debug_view == DEBUG_CD_GRAPHICS && gen->expansion) {
+		scd_toggle_graphics_debug(gen->expansion);
 	}
 }
 
--- a/segacd.h	Mon Dec 26 12:42:12 2022 -0800
+++ b/segacd.h	Thu Dec 29 15:47:19 2022 -0800
@@ -29,6 +29,7 @@
 	uint32_t        graphics_dy;
 	uint16_t        graphics_dst_x;
 	uint8_t         graphics_pixels[4];
+	uint8_t         graphics_debug_window;
 	uint8_t         timer_pending;
 	uint8_t         timer_value;
 	uint8_t         busreq;
@@ -57,5 +58,6 @@
 uint32_t gen_cycle_to_scd(uint32_t cycle, genesis_context *gen);
 void scd_run(segacd_context *cd, uint32_t cycle);
 void scd_adjust_cycle(segacd_context *cd, uint32_t deduction);
+void scd_toggle_graphics_debug(segacd_context *cd);
 
 #endif //SEGACD_H_
--- a/system.h	Mon Dec 26 12:42:12 2022 -0800
+++ b/system.h	Thu Dec 29 15:47:19 2022 -0800
@@ -28,6 +28,7 @@
 	DEBUG_CRAM,
 	DEBUG_COMPOSITE,
 	DEBUG_OSCILLOSCOPE,
+	DEBUG_CD_GRAPHICS,
 	NUM_DEBUG_TYPES
 };