changeset 2071:598017ef4b0d segacd

Fix a few sega cd graphics processor bugs
author Michael Pavone <pavone@retrodev.com>
date Sun, 30 Jan 2022 22:29:04 -0800
parents afc54649ebed
children cc13c100b027
files cd_graphics.c
diffstat 1 files changed, 14 insertions(+), 8 deletions(-) [+]
line wrap: on
line diff
--- a/cd_graphics.c	Sun Jan 30 19:56:09 2022 -0800
+++ b/cd_graphics.c	Sun Jan 30 22:29:04 2022 -0800
@@ -56,6 +56,10 @@
 	address += (stamp_y << row_shift) + stamp_x;
 	uint16_t stamp_def = cd->word_ram[address];
 	uint16_t stamp_num = stamp_def & stamp_num_mask;
+	if (!stamp_num) {
+		//manual says stamp 0 can't be used, I assume that means it's treated as transparent
+		return 0;
+	}
 	uint16_t pixel_x = x & pixel_mask;
 	uint16_t pixel_y = y & pixel_mask;
 	if (stamp_def & BIT_HFLIP) {
@@ -82,9 +86,9 @@
 		pixel_x = tmp;
 		break;
 	}
-	uint16_t cell_x = pixel_x >> 4;
+	uint16_t cell_x = pixel_x >> 3;
 	uint32_t pixel_address = stamp_num << 6;
-	pixel_address += (pixel_y << 1) + (cell_x << (stamp_shift + 2)) + (pixel_x >> 2 & 1);
+	pixel_address += (pixel_y << 1) + (cell_x << (stamp_shift + 1)) + (pixel_x >> 2 & 1);
 	uint16_t word = cd->word_ram[pixel_address];
 	switch (pixel_x & 3)
 	{
@@ -123,13 +127,14 @@
 	for(uint16_t i = 0; i < to_draw; i++)
 	{
 		uint32_t dst_address = cd->gate_array[GA_IMAGE_BUFFER_START] << 1;
-		dst_address += cd->graphics_dst_y << 4;
+		dst_address += cd->graphics_dst_y << 1;
 		dst_address += cd->graphics_dst_x >> 2 & 1;
 		dst_address += ((cd->graphics_dst_x >> 3) * cd->gate_array[GA_IMAGE_BUFFER_VCELLS]) << 4;
 		uint16_t pixel_shift = 12 - 4 * (cd->graphics_dst_x & 3);
 		uint16_t pixel = cd->graphics_pixels[i] << pixel_shift;
-		uint16_t src_mask_check = 0xFF << pixel_shift;
+		uint16_t src_mask_check = 0xF << pixel_shift;
 		uint16_t src_mask_keep = ~src_mask_check;
+		pixel &= src_mask_check;
 		switch (cd->gate_array[1] >> 3 & 3)
 		{
 		case 0:
@@ -152,11 +157,12 @@
 			}
 			break;
 		}
+		cd->graphics_dst_x++;
 	}
-	cd->graphics_dst_x += to_draw;
 	if (cd->graphics_dst_x == x_end) {
 		cd->graphics_dst_y++;
 		--cd->gate_array[GA_IMAGE_BUFFER_LINES];
+		cd->gate_array[GA_TRACE_VECTOR_BASE] += 2;
 		cd->graphics_step = FETCH_X;
 	} else {
 		cd->graphics_step = PIXEL0;
@@ -181,18 +187,18 @@
 			cd->graphics_dst_x = cd->gate_array[GA_IMAGE_BUFFER_OFFSET] & 3;
 			CHECK_CYCLES;
 		case FETCH_Y:
-			cd->graphics_y = cd->word_ram[cd->gate_array[GA_TRACE_VECTOR_BASE] << 1 + 1] << 8;
+			cd->graphics_y = cd->word_ram[(cd->gate_array[GA_TRACE_VECTOR_BASE] << 1) + 1] << 8;
 			cd->graphics_cycle += 2*4;
 			CHECK_CYCLES;
 		case FETCH_DX:
-			cd->graphics_dx = cd->word_ram[cd->gate_array[GA_TRACE_VECTOR_BASE] << 1 + 2];
+			cd->graphics_dx = cd->word_ram[(cd->gate_array[GA_TRACE_VECTOR_BASE] << 1) + 2];
 			if (cd->graphics_dx & 0x8000) {
 				cd->graphics_dx |= 0xFF0000;
 			}
 			cd->graphics_cycle += 2*4;
 			CHECK_CYCLES;
 		case FETCH_DY:
-			cd->graphics_dy = cd->word_ram[cd->gate_array[GA_TRACE_VECTOR_BASE] << 1 + 3];
+			cd->graphics_dy = cd->word_ram[(cd->gate_array[GA_TRACE_VECTOR_BASE] << 1) + 3];
 			if (cd->graphics_dy & 0x8000) {
 				cd->graphics_dy |= 0xFF0000;
 			}