comparison cd_graphics.c @ 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 8e51c0c3f2e3
children c3241eff3c3a
comparison
equal deleted inserted replaced
2070:afc54649ebed 2071:598017ef4b0d
54 } 54 }
55 uint32_t address = (cd->gate_array[GA_STAMP_MAP_BASE] & base_mask) << 1; 55 uint32_t address = (cd->gate_array[GA_STAMP_MAP_BASE] & base_mask) << 1;
56 address += (stamp_y << row_shift) + stamp_x; 56 address += (stamp_y << row_shift) + stamp_x;
57 uint16_t stamp_def = cd->word_ram[address]; 57 uint16_t stamp_def = cd->word_ram[address];
58 uint16_t stamp_num = stamp_def & stamp_num_mask; 58 uint16_t stamp_num = stamp_def & stamp_num_mask;
59 if (!stamp_num) {
60 //manual says stamp 0 can't be used, I assume that means it's treated as transparent
61 return 0;
62 }
59 uint16_t pixel_x = x & pixel_mask; 63 uint16_t pixel_x = x & pixel_mask;
60 uint16_t pixel_y = y & pixel_mask; 64 uint16_t pixel_y = y & pixel_mask;
61 if (stamp_def & BIT_HFLIP) { 65 if (stamp_def & BIT_HFLIP) {
62 pixel_x = pixel_mask - pixel_x; 66 pixel_x = pixel_mask - pixel_x;
63 } 67 }
80 tmp = pixel_y; 84 tmp = pixel_y;
81 pixel_y = pixel_mask - pixel_x; 85 pixel_y = pixel_mask - pixel_x;
82 pixel_x = tmp; 86 pixel_x = tmp;
83 break; 87 break;
84 } 88 }
85 uint16_t cell_x = pixel_x >> 4; 89 uint16_t cell_x = pixel_x >> 3;
86 uint32_t pixel_address = stamp_num << 6; 90 uint32_t pixel_address = stamp_num << 6;
87 pixel_address += (pixel_y << 1) + (cell_x << (stamp_shift + 2)) + (pixel_x >> 2 & 1); 91 pixel_address += (pixel_y << 1) + (cell_x << (stamp_shift + 1)) + (pixel_x >> 2 & 1);
88 uint16_t word = cd->word_ram[pixel_address]; 92 uint16_t word = cd->word_ram[pixel_address];
89 switch (pixel_x & 3) 93 switch (pixel_x & 3)
90 { 94 {
91 default: 95 default:
92 case 0: 96 case 0:
121 to_draw = cd->gate_array[GA_IMAGE_BUFFER_HDOTS] + (cd->gate_array[GA_IMAGE_BUFFER_OFFSET] & 3) - cd->graphics_dst_x; 125 to_draw = cd->gate_array[GA_IMAGE_BUFFER_HDOTS] + (cd->gate_array[GA_IMAGE_BUFFER_OFFSET] & 3) - cd->graphics_dst_x;
122 } 126 }
123 for(uint16_t i = 0; i < to_draw; i++) 127 for(uint16_t i = 0; i < to_draw; i++)
124 { 128 {
125 uint32_t dst_address = cd->gate_array[GA_IMAGE_BUFFER_START] << 1; 129 uint32_t dst_address = cd->gate_array[GA_IMAGE_BUFFER_START] << 1;
126 dst_address += cd->graphics_dst_y << 4; 130 dst_address += cd->graphics_dst_y << 1;
127 dst_address += cd->graphics_dst_x >> 2 & 1; 131 dst_address += cd->graphics_dst_x >> 2 & 1;
128 dst_address += ((cd->graphics_dst_x >> 3) * cd->gate_array[GA_IMAGE_BUFFER_VCELLS]) << 4; 132 dst_address += ((cd->graphics_dst_x >> 3) * cd->gate_array[GA_IMAGE_BUFFER_VCELLS]) << 4;
129 uint16_t pixel_shift = 12 - 4 * (cd->graphics_dst_x & 3); 133 uint16_t pixel_shift = 12 - 4 * (cd->graphics_dst_x & 3);
130 uint16_t pixel = cd->graphics_pixels[i] << pixel_shift; 134 uint16_t pixel = cd->graphics_pixels[i] << pixel_shift;
131 uint16_t src_mask_check = 0xFF << pixel_shift; 135 uint16_t src_mask_check = 0xF << pixel_shift;
132 uint16_t src_mask_keep = ~src_mask_check; 136 uint16_t src_mask_keep = ~src_mask_check;
137 pixel &= src_mask_check;
133 switch (cd->gate_array[1] >> 3 & 3) 138 switch (cd->gate_array[1] >> 3 & 3)
134 { 139 {
135 case 0: 140 case 0:
136 //priority mode off 141 //priority mode off
137 cd->word_ram[dst_address] &= src_mask_keep; 142 cd->word_ram[dst_address] &= src_mask_keep;
150 cd->word_ram[dst_address] &= src_mask_keep; 155 cd->word_ram[dst_address] &= src_mask_keep;
151 cd->word_ram[dst_address] |= pixel; 156 cd->word_ram[dst_address] |= pixel;
152 } 157 }
153 break; 158 break;
154 } 159 }
155 } 160 cd->graphics_dst_x++;
156 cd->graphics_dst_x += to_draw; 161 }
157 if (cd->graphics_dst_x == x_end) { 162 if (cd->graphics_dst_x == x_end) {
158 cd->graphics_dst_y++; 163 cd->graphics_dst_y++;
159 --cd->gate_array[GA_IMAGE_BUFFER_LINES]; 164 --cd->gate_array[GA_IMAGE_BUFFER_LINES];
165 cd->gate_array[GA_TRACE_VECTOR_BASE] += 2;
160 cd->graphics_step = FETCH_X; 166 cd->graphics_step = FETCH_X;
161 } else { 167 } else {
162 cd->graphics_step = PIXEL0; 168 cd->graphics_step = PIXEL0;
163 } 169 }
164 } 170 }
179 cd->graphics_x = cd->word_ram[cd->gate_array[GA_TRACE_VECTOR_BASE] << 1] << 8; 185 cd->graphics_x = cd->word_ram[cd->gate_array[GA_TRACE_VECTOR_BASE] << 1] << 8;
180 cd->graphics_cycle += 3*4; 186 cd->graphics_cycle += 3*4;
181 cd->graphics_dst_x = cd->gate_array[GA_IMAGE_BUFFER_OFFSET] & 3; 187 cd->graphics_dst_x = cd->gate_array[GA_IMAGE_BUFFER_OFFSET] & 3;
182 CHECK_CYCLES; 188 CHECK_CYCLES;
183 case FETCH_Y: 189 case FETCH_Y:
184 cd->graphics_y = cd->word_ram[cd->gate_array[GA_TRACE_VECTOR_BASE] << 1 + 1] << 8; 190 cd->graphics_y = cd->word_ram[(cd->gate_array[GA_TRACE_VECTOR_BASE] << 1) + 1] << 8;
185 cd->graphics_cycle += 2*4; 191 cd->graphics_cycle += 2*4;
186 CHECK_CYCLES; 192 CHECK_CYCLES;
187 case FETCH_DX: 193 case FETCH_DX:
188 cd->graphics_dx = cd->word_ram[cd->gate_array[GA_TRACE_VECTOR_BASE] << 1 + 2]; 194 cd->graphics_dx = cd->word_ram[(cd->gate_array[GA_TRACE_VECTOR_BASE] << 1) + 2];
189 if (cd->graphics_dx & 0x8000) { 195 if (cd->graphics_dx & 0x8000) {
190 cd->graphics_dx |= 0xFF0000; 196 cd->graphics_dx |= 0xFF0000;
191 } 197 }
192 cd->graphics_cycle += 2*4; 198 cd->graphics_cycle += 2*4;
193 CHECK_CYCLES; 199 CHECK_CYCLES;
194 case FETCH_DY: 200 case FETCH_DY:
195 cd->graphics_dy = cd->word_ram[cd->gate_array[GA_TRACE_VECTOR_BASE] << 1 + 3]; 201 cd->graphics_dy = cd->word_ram[(cd->gate_array[GA_TRACE_VECTOR_BASE] << 1) + 3];
196 if (cd->graphics_dy & 0x8000) { 202 if (cd->graphics_dy & 0x8000) {
197 cd->graphics_dy |= 0xFF0000; 203 cd->graphics_dy |= 0xFF0000;
198 } 204 }
199 cd->graphics_cycle += 2*4; 205 cd->graphics_cycle += 2*4;
200 CHECK_CYCLES; 206 CHECK_CYCLES;