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