Mercurial > repos > blastem
comparison vdp.c @ 40:7368a7071908
Broken window support
author | Mike Pavone <pavone@retrodev.com> |
---|---|
date | Sun, 09 Dec 2012 17:05:13 -0800 |
parents | 3c69319269ef |
children | e591004487bc |
comparison
equal
deleted
inserted
replaced
39:3c69319269ef | 40:7368a7071908 |
---|---|
13 #define BIT_PAL 0x8 | 13 #define BIT_PAL 0x8 |
14 #define BIT_H40 0x1 | 14 #define BIT_H40 0x1 |
15 | 15 |
16 #define SCROLL_BUFFER_SIZE 32 | 16 #define SCROLL_BUFFER_SIZE 32 |
17 #define SCROLL_BUFFER_DRAW 16 | 17 #define SCROLL_BUFFER_DRAW 16 |
18 | |
19 #define FLAG_DOT_OFLOW 0x1 | |
20 #define FLAG_CAN_MASK 0x2 | |
21 #define FLAG_MASKED 0x4 | |
22 #define FLAG_WINDOW 0x8 | |
18 | 23 |
19 void init_vdp_context(vdp_context * context) | 24 void init_vdp_context(vdp_context * context) |
20 { | 25 { |
21 memset(context, 0, sizeof(context)); | 26 memset(context, 0, sizeof(context)); |
22 context->vdpmem = malloc(VRAM_SIZE); | 27 context->vdpmem = malloc(VRAM_SIZE); |
98 context->sprite_index = context->vdpmem[address+3] & 0x7F; | 103 context->sprite_index = context->vdpmem[address+3] & 0x7F; |
99 } | 104 } |
100 } | 105 } |
101 } | 106 } |
102 | 107 |
103 #define FLAG_DOT_OFLOW 0x1 | |
104 #define FLAG_CAN_MASK 0x2 | |
105 #define FLAG_MASKED 0x4 | |
106 void read_sprite_x(uint32_t line, vdp_context * context) | 108 void read_sprite_x(uint32_t line, vdp_context * context) |
107 { | 109 { |
108 if (context->cur_slot >= context->slot_counter) { | 110 if (context->cur_slot >= context->slot_counter) { |
109 if (context->sprite_draws) { | 111 if (context->sprite_draws) { |
110 line += 1; | 112 line += 1; |
169 void external_slot(vdp_context * context) | 171 void external_slot(vdp_context * context) |
170 { | 172 { |
171 //TODO: Implement me | 173 //TODO: Implement me |
172 } | 174 } |
173 | 175 |
176 #define WINDOW_RIGHT 0x80 | |
177 #define WINDOW_DOWN 0x80 | |
178 #define ALWAYS_WINDOW 0 | |
179 | |
174 void read_map_scroll(uint16_t column, uint16_t vsram_off, uint32_t line, uint16_t address, uint16_t hscroll_val, vdp_context * context) | 180 void read_map_scroll(uint16_t column, uint16_t vsram_off, uint32_t line, uint16_t address, uint16_t hscroll_val, vdp_context * context) |
175 { | 181 { |
182 if (!vsram_off) { | |
183 uint16_t left_col, right_col; | |
184 #if ALWAYS_WINDOW | |
185 left_col = 0; right_col = 42; | |
186 uint16_t top_line, bottom_line; | |
187 top_line = 0; bottom_line = 241; | |
188 #else | |
189 if (context->regs[REG_WINDOW_H] & WINDOW_RIGHT) { | |
190 left_col = 0; | |
191 right_col = (context->regs[REG_WINDOW_H] & 0x1F) * 2; | |
192 if (right_col) { | |
193 right_col += 2; | |
194 } | |
195 } else { | |
196 left_col = (context->regs[REG_WINDOW_H] & 0x1F) * 2; | |
197 right_col = 42; | |
198 } | |
199 if (column >= left_col && column < right_col) { | |
200 uint16_t top_line, bottom_line; | |
201 if (context->regs[REG_WINDOW_V] & WINDOW_DOWN) { | |
202 top_line = (context->regs[REG_WINDOW_V] & 0x1F) * 8; | |
203 bottom_line = 241; | |
204 } else { | |
205 top_line = 0; | |
206 bottom_line = (context->regs[REG_WINDOW_V] & 0x1F) * 8; | |
207 } | |
208 if (line >= top_line && line < bottom_line) { | |
209 #endif | |
210 uint16_t address = context->regs[REG_WINDOW] << 10; | |
211 uint16_t line_offset, offset, mask; | |
212 if (context->latched_mode & BIT_H40) { | |
213 address &= 0xF000; | |
214 line_offset = (((line/* - top_line */) / 8) * 64 * 2) & 0xFFF; | |
215 mask = 0x7F; | |
216 | |
217 } else { | |
218 address &= 0xF800; | |
219 line_offset = (((line/* - top_line*/) / 8) * 32 * 2) & 0xFFF; | |
220 mask = 0x3F; | |
221 } | |
222 offset = address + line_offset + (((column - 2/* - left_col*/) * 2) & mask); | |
223 context->col_1 = (context->vdpmem[offset] << 8) | context->vdpmem[offset+1]; | |
224 printf("Window | top: %d, bot: %d, left: %d, right: %d, base: %X, line: %X offset: %X, tile: %X, reg: %X\n", top_line, bottom_line, left_col, right_col, address, line_offset, offset, ((context->col_1 & 0x3FF) << 5), context->regs[REG_WINDOW]); | |
225 offset = address + line_offset + (((column - 1/* - left_col*/) * 2) & mask); | |
226 context->col_2 = (context->vdpmem[offset] << 8) | context->vdpmem[offset+1]; | |
227 context->v_offset = (line/* - top_line*/) & 0x7; | |
228 context->flags |= FLAG_WINDOW; | |
229 return; | |
230 #if !ALWAYS_WINDOW | |
231 } | |
232 } | |
233 context->flags &= ~FLAG_WINDOW; | |
234 #endif | |
235 | |
236 } | |
176 uint16_t vscroll; | 237 uint16_t vscroll; |
177 switch(context->regs[REG_SCROLL] & 0x30) | 238 switch(context->regs[REG_SCROLL] & 0x30) |
178 { | 239 { |
179 case 0: | 240 case 0: |
180 vscroll = 0xFF; | 241 vscroll = 0xFF; |
291 if (col) | 352 if (col) |
292 { | 353 { |
293 col-=2; | 354 col-=2; |
294 dst = context->framebuf + line * 320 + col * 8; | 355 dst = context->framebuf + line * 320 + col * 8; |
295 sprite_buf = context->linebuf + col * 8; | 356 sprite_buf = context->linebuf + col * 8; |
296 plane_a = context->tmp_buf_a + SCROLL_BUFFER_DRAW - (context->hscroll_a & 0xF); | 357 if (context->flags & FLAG_WINDOW) { |
358 plane_a = context->tmp_buf_a + SCROLL_BUFFER_DRAW; | |
359 } else { | |
360 plane_a = context->tmp_buf_a + SCROLL_BUFFER_DRAW - (context->hscroll_a & 0xF); | |
361 } | |
297 plane_b = context->tmp_buf_b + SCROLL_BUFFER_DRAW - (context->hscroll_b & 0xF); | 362 plane_b = context->tmp_buf_b + SCROLL_BUFFER_DRAW - (context->hscroll_b & 0xF); |
298 end = dst + 16; | 363 end = dst + 16; |
299 //printf("A | tmp_buf offset: %d\n", 8 - (context->hscroll_a & 0x7)); | 364 //printf("A | tmp_buf offset: %d\n", 8 - (context->hscroll_a & 0x7)); |
300 for (; dst < end; ++plane_a, ++plane_b, ++sprite_buf, ++dst) { | 365 for (; dst < end; ++plane_a, ++plane_b, ++sprite_buf, ++dst) { |
301 uint8_t pixel; | 366 uint8_t pixel; |
322 //plane_a = context->tmp_buf_a + 16 - (context->hscroll_a & 0x7); | 387 //plane_a = context->tmp_buf_a + 16 - (context->hscroll_a & 0x7); |
323 //plane_b = context->tmp_buf_b + 16 - (context->hscroll_b & 0x7); | 388 //plane_b = context->tmp_buf_b + 16 - (context->hscroll_b & 0x7); |
324 //end = dst + 8; | 389 //end = dst + 8; |
325 } | 390 } |
326 | 391 |
327 uint16_t remaining = context->hscroll_a & 0xF; | 392 uint16_t remaining; |
328 memcpy(context->tmp_buf_a + SCROLL_BUFFER_DRAW - remaining, context->tmp_buf_a + SCROLL_BUFFER_SIZE - remaining, remaining); | 393 if (!(context->flags & FLAG_WINDOW)) { |
394 remaining = context->hscroll_a & 0xF; | |
395 memcpy(context->tmp_buf_a + SCROLL_BUFFER_DRAW - remaining, context->tmp_buf_a + SCROLL_BUFFER_SIZE - remaining, remaining); | |
396 } | |
329 remaining = context->hscroll_b & 0xF; | 397 remaining = context->hscroll_b & 0xF; |
330 memcpy(context->tmp_buf_b + SCROLL_BUFFER_DRAW - remaining, context->tmp_buf_b + SCROLL_BUFFER_SIZE - remaining, remaining); | 398 memcpy(context->tmp_buf_b + SCROLL_BUFFER_DRAW - remaining, context->tmp_buf_b + SCROLL_BUFFER_SIZE - remaining, remaining); |
331 } | 399 } |
332 | 400 |
333 #define COLUMN_RENDER_BLOCK(column, startcyc) \ | 401 #define COLUMN_RENDER_BLOCK(column, startcyc) \ |