Mercurial > repos > blastem
comparison cd_graphics.c @ 2077:c3241eff3c3a
Sega CD graphics processor output now looks correct for some operations
author | Michael Pavone <pavone@retrodev.com> |
---|---|
date | Mon, 31 Jan 2022 22:07:51 -0800 |
parents | 598017ef4b0d |
children | 8665d8da0e1c |
comparison
equal
deleted
inserted
replaced
2076:3f29e2726522 | 2077:c3241eff3c3a |
---|---|
42 max = 256 >> stamp_shift; | 42 max = 256 >> stamp_shift; |
43 base_mask = 0xFFE0 << ((5 - stamp_shift) << 1); | 43 base_mask = 0xFFE0 << ((5 - stamp_shift) << 1); |
44 //8 stamps in 32x32 mode, 16 stamps in 16x16 mode | 44 //8 stamps in 32x32 mode, 16 stamps in 16x16 mode |
45 row_shift = 8 - stamp_shift; | 45 row_shift = 8 - stamp_shift; |
46 } | 46 } |
47 if (stamp_x > max || stamp_y > max) { | 47 if (stamp_x >= max || stamp_y >= max) { |
48 if (cd->gate_array[GA_STAMP_SIZE] & BIT_RPT) { | 48 if (cd->gate_array[GA_STAMP_SIZE] & BIT_RPT) { |
49 stamp_x &= max - 1; | 49 stamp_x &= max - 1; |
50 stamp_y &= max - 1; | 50 stamp_y &= max - 1; |
51 } else { | 51 } else { |
52 return 0; | 52 return 0; |
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); | |
61 return 0; | 62 return 0; |
62 } | 63 } |
63 uint16_t pixel_x = x & pixel_mask; | 64 uint16_t pixel_x = x & pixel_mask; |
64 uint16_t pixel_y = y & pixel_mask; | 65 uint16_t pixel_y = y & pixel_mask; |
65 if (stamp_def & BIT_HFLIP) { | 66 if (stamp_def & BIT_HFLIP) { |
88 } | 89 } |
89 uint16_t cell_x = pixel_x >> 3; | 90 uint16_t cell_x = pixel_x >> 3; |
90 uint32_t pixel_address = stamp_num << 6; | 91 uint32_t pixel_address = stamp_num << 6; |
91 pixel_address += (pixel_y << 1) + (cell_x << (stamp_shift + 1)) + (pixel_x >> 2 & 1); | 92 pixel_address += (pixel_y << 1) + (cell_x << (stamp_shift + 1)) + (pixel_x >> 2 & 1); |
92 uint16_t word = cd->word_ram[pixel_address]; | 93 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); | |
93 switch (pixel_x & 3) | 95 switch (pixel_x & 3) |
94 { | 96 { |
95 default: | 97 default: |
96 case 0: | 98 case 0: |
97 return word >> 12; | 99 return word >> 12; |
127 for(uint16_t i = 0; i < to_draw; i++) | 129 for(uint16_t i = 0; i < to_draw; i++) |
128 { | 130 { |
129 uint32_t dst_address = cd->gate_array[GA_IMAGE_BUFFER_START] << 1; | 131 uint32_t dst_address = cd->gate_array[GA_IMAGE_BUFFER_START] << 1; |
130 dst_address += cd->graphics_dst_y << 1; | 132 dst_address += cd->graphics_dst_y << 1; |
131 dst_address += cd->graphics_dst_x >> 2 & 1; | 133 dst_address += cd->graphics_dst_x >> 2 & 1; |
132 dst_address += ((cd->graphics_dst_x >> 3) * cd->gate_array[GA_IMAGE_BUFFER_VCELLS]) << 4; | 134 dst_address += ((cd->graphics_dst_x >> 3) * (cd->gate_array[GA_IMAGE_BUFFER_VCELLS] + 1)) << 4; |
133 uint16_t pixel_shift = 12 - 4 * (cd->graphics_dst_x & 3); | 135 uint16_t pixel_shift = 12 - 4 * (cd->graphics_dst_x & 3); |
134 uint16_t pixel = cd->graphics_pixels[i] << pixel_shift; | 136 uint16_t pixel = cd->graphics_pixels[i] << pixel_shift; |
135 uint16_t src_mask_check = 0xF << pixel_shift; | 137 uint16_t src_mask_check = 0xF << pixel_shift; |
136 uint16_t src_mask_keep = ~src_mask_check; | 138 uint16_t src_mask_keep = ~src_mask_check; |
137 pixel &= src_mask_check; | 139 pixel &= src_mask_check; |
140 //printf("dst (%u, %u = %X)\n", cd->graphics_dst_x, cd->graphics_dst_y, dst_address); | |
138 switch (cd->gate_array[1] >> 3 & 3) | 141 switch (cd->gate_array[1] >> 3 & 3) |
139 { | 142 { |
140 case 0: | 143 case 0: |
141 //priority mode off | 144 //priority mode off |
142 cd->word_ram[dst_address] &= src_mask_keep; | 145 cd->word_ram[dst_address] &= src_mask_keep; |
186 cd->graphics_cycle += 3*4; | 189 cd->graphics_cycle += 3*4; |
187 cd->graphics_dst_x = cd->gate_array[GA_IMAGE_BUFFER_OFFSET] & 3; | 190 cd->graphics_dst_x = cd->gate_array[GA_IMAGE_BUFFER_OFFSET] & 3; |
188 CHECK_CYCLES; | 191 CHECK_CYCLES; |
189 case FETCH_Y: | 192 case FETCH_Y: |
190 cd->graphics_y = cd->word_ram[(cd->gate_array[GA_TRACE_VECTOR_BASE] << 1) + 1] << 8; | 193 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]); | |
191 cd->graphics_cycle += 2*4; | 195 cd->graphics_cycle += 2*4; |
192 CHECK_CYCLES; | 196 CHECK_CYCLES; |
193 case FETCH_DX: | 197 case FETCH_DX: |
194 cd->graphics_dx = cd->word_ram[(cd->gate_array[GA_TRACE_VECTOR_BASE] << 1) + 2]; | 198 cd->graphics_dx = cd->word_ram[(cd->gate_array[GA_TRACE_VECTOR_BASE] << 1) + 2]; |
195 if (cd->graphics_dx & 0x8000) { | 199 if (cd->graphics_dx & 0x8000) { |
267 } | 271 } |
268 } | 272 } |
269 void cd_graphics_start(segacd_context *cd) | 273 void cd_graphics_start(segacd_context *cd) |
270 { | 274 { |
271 if (!(cd->gate_array[GA_STAMP_SIZE] & BIT_GRON)) { | 275 if (!(cd->gate_array[GA_STAMP_SIZE] & BIT_GRON)) { |
272 printf("grahpics start @ %u\n", cd->graphics_cycle); | 276 |
273 cd->gate_array[GA_STAMP_SIZE] |= BIT_GRON; | 277 cd->gate_array[GA_STAMP_SIZE] |= BIT_GRON; |
274 //Manual scan is bad, but formula appears to be | 278 //Manual scan is bad, but formula appears to be |
275 // vsize * (13 + 2 * hoffset + 9 * (hdots + hoffset - 1)) | 279 // vsize * (13 + 2 * hoffset + 9 * (hdots + hoffset - 1)) |
276 //with an additional 13? cycle setup cost per line | 280 //with an additional 13? cycle setup cost per line |
277 uint32_t lines = cd->gate_array[GA_IMAGE_BUFFER_LINES]; | 281 uint32_t lines = cd->gate_array[GA_IMAGE_BUFFER_LINES]; |
278 uint32_t hdots = cd->gate_array[GA_IMAGE_BUFFER_HDOTS]; | 282 uint32_t hdots = cd->gate_array[GA_IMAGE_BUFFER_HDOTS]; |
279 uint32_t hoffset = cd->gate_array[GA_IMAGE_BUFFER_OFFSET] & 3; | 283 uint32_t hoffset = cd->gate_array[GA_IMAGE_BUFFER_OFFSET] & 3; |
284 printf("graphics start @ %u, %u lines, %u hdots\n", cd->graphics_cycle, lines, hdots); | |
280 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)); |
281 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 cd->graphics_step = FETCH_X; | |
282 } else { | 288 } else { |
283 printf("graphics start ignored @ %u\n", cd->graphics_cycle); | 289 printf("graphics start ignored @ %u\n", cd->graphics_cycle); |
284 } | 290 } |
285 | 291 |
286 } | 292 } |