Mercurial > repos > blastem
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 |