comparison cd_graphics.c @ 2098:da326c32ad8f

Fix some bugs in the Sega CD graphics coprocessor
author Michael Pavone <pavone@retrodev.com>
date Wed, 09 Feb 2022 00:46:54 -0800
parents 8665d8da0e1c
children 3ef80963c2a7
comparison
equal deleted inserted replaced
2097:0407d812cb4a 2098:da326c32ad8f
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) { 59 if (!stamp_num) {
60 //manual says stamp 0 can't be used, I assume that means it's treated as transparent 60 //manual says stamp 0 can't be used, I assume that means it's treated as transparent
61 //printf("src pixel (%u, %u = BLANK) stamp (%u, %u = %X), def %X\n", x, y, stamp_x, stamp_y, address, stamp_def);
62 return 0; 61 return 0;
63 } 62 }
64 uint16_t pixel_x = x & pixel_mask; 63 uint16_t pixel_x = x & pixel_mask;
65 uint16_t pixel_y = y & pixel_mask; 64 uint16_t pixel_y = y & pixel_mask;
66 if (stamp_def & BIT_HFLIP) { 65 if (stamp_def & BIT_HFLIP) {
75 tmp = pixel_y; 74 tmp = pixel_y;
76 pixel_y = pixel_x; 75 pixel_y = pixel_x;
77 pixel_x = pixel_mask - tmp; 76 pixel_x = pixel_mask - tmp;
78 break; 77 break;
79 case 2: 78 case 2:
80 tmp = pixel_y; 79 pixel_y = pixel_mask - pixel_y;
81 pixel_y = pixel_mask - pixel_x; 80 pixel_x = pixel_mask - pixel_x;
82 pixel_x = pixel_mask - tmp;
83 break; 81 break;
84 case 3: 82 case 3:
85 tmp = pixel_y; 83 tmp = pixel_y;
86 pixel_y = pixel_mask - pixel_x; 84 pixel_y = pixel_mask - pixel_x;
87 pixel_x = tmp; 85 pixel_x = tmp;
89 } 87 }
90 uint16_t cell_x = pixel_x >> 3; 88 uint16_t cell_x = pixel_x >> 3;
91 uint32_t pixel_address = stamp_num << 6; 89 uint32_t pixel_address = stamp_num << 6;
92 pixel_address += (pixel_y << 1) + (cell_x << (stamp_shift + 1)) + (pixel_x >> 2 & 1); 90 pixel_address += (pixel_y << 1) + (cell_x << (stamp_shift + 1)) + (pixel_x >> 2 & 1);
93 uint16_t word = cd->word_ram[pixel_address]; 91 uint16_t word = cd->word_ram[pixel_address];
94 //printf("src pixel (%u, %u = %X) stamp (%u, %u = %X), def %X\n", x, y, pixel_address, stamp_x, stamp_y, address, stamp_def);
95 switch (pixel_x & 3) 92 switch (pixel_x & 3)
96 { 93 {
97 default: 94 default:
98 case 0: 95 case 0:
99 return word >> 12; 96 return word >> 12;
135 uint16_t pixel_shift = 12 - 4 * (cd->graphics_dst_x & 3); 132 uint16_t pixel_shift = 12 - 4 * (cd->graphics_dst_x & 3);
136 uint16_t pixel = cd->graphics_pixels[i] << pixel_shift; 133 uint16_t pixel = cd->graphics_pixels[i] << pixel_shift;
137 uint16_t src_mask_check = 0xF << pixel_shift; 134 uint16_t src_mask_check = 0xF << pixel_shift;
138 uint16_t src_mask_keep = ~src_mask_check; 135 uint16_t src_mask_keep = ~src_mask_check;
139 pixel &= src_mask_check; 136 pixel &= src_mask_check;
140 //printf("dst (%u, %u = %X)\n", cd->graphics_dst_x, cd->graphics_dst_y, dst_address);
141 switch (cd->gate_array[1] >> 3 & 3) 137 switch (cd->gate_array[1] >> 3 & 3)
142 { 138 {
143 case 0: 139 case 0:
144 //priority mode off 140 //priority mode off
145 cd->word_ram[dst_address] &= src_mask_keep; 141 cd->word_ram[dst_address] &= src_mask_keep;
150 if (pixel && ! (cd->word_ram[dst_address] & src_mask_check)) { 146 if (pixel && ! (cd->word_ram[dst_address] & src_mask_check)) {
151 cd->word_ram[dst_address] &= src_mask_keep; 147 cd->word_ram[dst_address] &= src_mask_keep;
152 cd->word_ram[dst_address] |= pixel; 148 cd->word_ram[dst_address] |= pixel;
153 } 149 }
154 break; 150 break;
155 case 3: 151 case 2:
156 //overwrite 152 //overwrite
157 if (pixel) { 153 if (pixel) {
158 cd->word_ram[dst_address] &= src_mask_keep; 154 cd->word_ram[dst_address] &= src_mask_keep;
159 cd->word_ram[dst_address] |= pixel; 155 cd->word_ram[dst_address] |= pixel;
160 } 156 }
189 cd->graphics_cycle += 3*4; 185 cd->graphics_cycle += 3*4;
190 cd->graphics_dst_x = cd->gate_array[GA_IMAGE_BUFFER_OFFSET] & 3; 186 cd->graphics_dst_x = cd->gate_array[GA_IMAGE_BUFFER_OFFSET] & 3;
191 CHECK_CYCLES; 187 CHECK_CYCLES;
192 case FETCH_Y: 188 case FETCH_Y:
193 cd->graphics_y = cd->word_ram[(cd->gate_array[GA_TRACE_VECTOR_BASE] << 1) + 1] << 8; 189 cd->graphics_y = cd->word_ram[(cd->gate_array[GA_TRACE_VECTOR_BASE] << 1) + 1] << 8;
194 //printf("Fetching line start (%u, %u) from %X for dst y %u, %u lines remain\n", cd->graphics_x, cd->graphics_y, cd->gate_array[GA_TRACE_VECTOR_BASE] << 1, cd->graphics_dst_y, cd->gate_array[GA_IMAGE_BUFFER_LINES]);
195 cd->graphics_cycle += 2*4; 190 cd->graphics_cycle += 2*4;
196 CHECK_CYCLES; 191 CHECK_CYCLES;
197 case FETCH_DX: 192 case FETCH_DX:
198 cd->graphics_dx = cd->word_ram[(cd->gate_array[GA_TRACE_VECTOR_BASE] << 1) + 2]; 193 cd->graphics_dx = cd->word_ram[(cd->gate_array[GA_TRACE_VECTOR_BASE] << 1) + 2];
199 if (cd->graphics_dx & 0x8000) { 194 if (cd->graphics_dx & 0x8000) {
245 draw: 240 draw:
246 case DRAW: 241 case DRAW:
247 draw_pixels(cd); 242 draw_pixels(cd);
248 cd->graphics_cycle += 1*4; 243 cd->graphics_cycle += 1*4;
249 if (!cd->gate_array[GA_IMAGE_BUFFER_LINES]) { 244 if (!cd->gate_array[GA_IMAGE_BUFFER_LINES]) {
250 break; 245 return;
251 } 246 }
252 CHECK_ONLY; 247 CHECK_ONLY;
253 } 248 }
254 } 249 }
255 } 250 }
264 //deal with that here for now 259 //deal with that here for now
265 for(; cd->graphics_cycle < cycle; cd->graphics_cycle += 4) 260 for(; cd->graphics_cycle < cycle; cd->graphics_cycle += 4)
266 { 261 {
267 } 262 }
268 if (cd->graphics_cycle >= cd->graphics_int_cycle) { 263 if (cd->graphics_cycle >= cd->graphics_int_cycle) {
264 printf("graphics end %u\n", cd->graphics_cycle);
269 cd->gate_array[GA_STAMP_SIZE] &= ~BIT_GRON; 265 cd->gate_array[GA_STAMP_SIZE] &= ~BIT_GRON;
270 break; 266 break;
271 } 267 }
272 } else { 268 } else {
273 cd->graphics_cycle = cycle; 269 cd->graphics_cycle = cycle;
283 // vsize * (13 + 2 * hoffset + 9 * (hdots + hoffset - 1)) 279 // vsize * (13 + 2 * hoffset + 9 * (hdots + hoffset - 1))
284 //with an additional 13? cycle setup cost per line 280 //with an additional 13? cycle setup cost per line
285 uint32_t lines = cd->gate_array[GA_IMAGE_BUFFER_LINES]; 281 uint32_t lines = cd->gate_array[GA_IMAGE_BUFFER_LINES];
286 uint32_t hdots = cd->gate_array[GA_IMAGE_BUFFER_HDOTS]; 282 uint32_t hdots = cd->gate_array[GA_IMAGE_BUFFER_HDOTS];
287 uint32_t hoffset = cd->gate_array[GA_IMAGE_BUFFER_OFFSET] & 3; 283 uint32_t hoffset = cd->gate_array[GA_IMAGE_BUFFER_OFFSET] & 3;
288 printf("graphics start @ %u, %u lines, %u hdots\n", cd->graphics_cycle, lines, hdots); 284 uint16_t pm = cd->gate_array[1] >> 3 & 3;
289 cd->graphics_int_cycle = cd->graphics_cycle + 4 * lines * (13 + 2 * hoffset + 9 * (hdots + hoffset - 1)); 285 cd->graphics_int_cycle = cd->graphics_cycle + 4 * lines * (13 + 2 * hoffset + 9 * (hdots + hoffset - 1));
290 cd->graphics_dst_y = cd->gate_array[GA_IMAGE_BUFFER_OFFSET] >> 3; 286 cd->graphics_dst_y = cd->gate_array[GA_IMAGE_BUFFER_OFFSET] >> 3;
287 printf("graphics start @ %u, %u lines, %u hdots, pm = %u, hoff = %u, voff = %u, addr = %X\n", cd->graphics_cycle, lines, hdots, pm, hoffset, cd->graphics_dst_y, cd->gate_array[GA_IMAGE_BUFFER_START]);
291 cd->graphics_step = FETCH_X; 288 cd->graphics_step = FETCH_X;
292 } else { 289 } else {
293 printf("graphics start ignored @ %u\n", cd->graphics_cycle); 290 printf("graphics start ignored @ %u\n", cd->graphics_cycle);
294 } 291 }
295 292