Mercurial > repos > blastem
comparison vdp.c @ 417:acdd6c5240fe
Fix window layer in double res interlace mode
author | Mike Pavone <pavone@retrodev.com> |
---|---|
date | Sun, 23 Jun 2013 12:27:11 -0700 |
parents | 8c60c8c09a0f |
children | 7e8e179116af |
comparison
equal
deleted
inserted
replaced
416:29c1a0dcf683 | 417:acdd6c5240fe |
---|---|
438 #define WINDOW_RIGHT 0x80 | 438 #define WINDOW_RIGHT 0x80 |
439 #define WINDOW_DOWN 0x80 | 439 #define WINDOW_DOWN 0x80 |
440 | 440 |
441 void read_map_scroll(uint16_t column, uint16_t vsram_off, uint32_t line, uint16_t address, uint16_t hscroll_val, vdp_context * context) | 441 void read_map_scroll(uint16_t column, uint16_t vsram_off, uint32_t line, uint16_t address, uint16_t hscroll_val, vdp_context * context) |
442 { | 442 { |
443 uint16_t window_line_shift, v_offset_mask, vscroll_shift; | |
443 if (context->double_res) { | 444 if (context->double_res) { |
444 line *= 2; | 445 line *= 2; |
445 if (context->framebuf != context->oddbuf) { | 446 if (context->framebuf != context->oddbuf) { |
446 line++; | 447 line++; |
447 } | 448 } |
449 window_line_shift = 4; | |
450 v_offset_mask = 0xF; | |
451 vscroll_shift = 4; | |
452 } else { | |
453 window_line_shift = 3; | |
454 v_offset_mask = 0x7; | |
455 vscroll_shift = 3; | |
448 } | 456 } |
449 if (!vsram_off) { | 457 if (!vsram_off) { |
450 uint16_t left_col, right_col; | 458 uint16_t left_col, right_col; |
451 if (context->regs[REG_WINDOW_H] & WINDOW_RIGHT) { | 459 if (context->regs[REG_WINDOW_H] & WINDOW_RIGHT) { |
452 left_col = (context->regs[REG_WINDOW_H] & 0x1F) * 2; | 460 left_col = (context->regs[REG_WINDOW_H] & 0x1F) * 2; |
458 right_col += 2; | 466 right_col += 2; |
459 } | 467 } |
460 } | 468 } |
461 uint16_t top_line, bottom_line; | 469 uint16_t top_line, bottom_line; |
462 if (context->regs[REG_WINDOW_V] & WINDOW_DOWN) { | 470 if (context->regs[REG_WINDOW_V] & WINDOW_DOWN) { |
463 top_line = (context->regs[REG_WINDOW_V] & 0x1F) * 8; | 471 top_line = (context->regs[REG_WINDOW_V] & 0x1F) << window_line_shift; |
464 bottom_line = 241; | 472 bottom_line = context->double_res ? 481 : 241; |
465 } else { | 473 } else { |
466 top_line = 0; | 474 top_line = 0; |
467 bottom_line = (context->regs[REG_WINDOW_V] & 0x1F) * 8; | 475 bottom_line = (context->regs[REG_WINDOW_V] & 0x1F) << window_line_shift; |
468 } | 476 } |
469 if ((column >= left_col && column < right_col) || (line >= top_line && line < bottom_line)) { | 477 if ((column >= left_col && column < right_col) || (line >= top_line && line < bottom_line)) { |
470 uint16_t address = context->regs[REG_WINDOW] << 10; | 478 uint16_t address = context->regs[REG_WINDOW] << 10; |
471 uint16_t line_offset, offset, mask; | 479 uint16_t line_offset, offset, mask; |
472 if (context->latched_mode & BIT_H40) { | 480 if (context->latched_mode & BIT_H40) { |
473 address &= 0xF000; | 481 address &= 0xF000; |
474 line_offset = (((line) / 8) * 64 * 2) & 0xFFF; | 482 line_offset = (((line) >> vscroll_shift) * 64 * 2) & 0xFFF; |
475 mask = 0x7F; | 483 mask = 0x7F; |
476 | 484 |
477 } else { | 485 } else { |
478 address &= 0xF800; | 486 address &= 0xF800; |
479 line_offset = (((line) / 8) * 32 * 2) & 0xFFF; | 487 line_offset = (((line) >> vscroll_shift) * 32 * 2) & 0xFFF; |
480 mask = 0x3F; | 488 mask = 0x3F; |
489 } | |
490 if (context->double_res) { | |
491 mask <<= 1; | |
492 mask |= 1; | |
481 } | 493 } |
482 offset = address + line_offset + (((column - 2) * 2) & mask); | 494 offset = address + line_offset + (((column - 2) * 2) & mask); |
483 context->col_1 = (context->vdpmem[offset] << 8) | context->vdpmem[offset+1]; | 495 context->col_1 = (context->vdpmem[offset] << 8) | context->vdpmem[offset+1]; |
484 //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]); | 496 //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]); |
485 offset = address + line_offset + (((column - 1) * 2) & mask); | 497 offset = address + line_offset + (((column - 1) * 2) & mask); |
486 context->col_2 = (context->vdpmem[offset] << 8) | context->vdpmem[offset+1]; | 498 context->col_2 = (context->vdpmem[offset] << 8) | context->vdpmem[offset+1]; |
487 context->v_offset = (line) & 0x7; | 499 context->v_offset = (line) & v_offset_mask; |
488 context->flags |= FLAG_WINDOW; | 500 context->flags |= FLAG_WINDOW; |
489 return; | 501 return; |
490 } | 502 } |
491 context->flags &= ~FLAG_WINDOW; | 503 context->flags &= ~FLAG_WINDOW; |
492 } | 504 } |
505 break; | 517 break; |
506 case 0x30: | 518 case 0x30: |
507 vscroll = 0x3FF; | 519 vscroll = 0x3FF; |
508 break; | 520 break; |
509 } | 521 } |
510 uint16_t v_offset_mask, vscroll_shift; | |
511 if (context->double_res) { | 522 if (context->double_res) { |
512 vscroll <<= 1; | 523 vscroll <<= 1; |
513 vscroll |= 1; | 524 vscroll |= 1; |
514 v_offset_mask = 0xF; | |
515 vscroll_shift = 4; | |
516 } else { | |
517 v_offset_mask = 0x7; | |
518 vscroll_shift = 3; | |
519 } | 525 } |
520 vscroll &= (context->vsram[(context->regs[REG_MODE_3] & BIT_VSCROLL ? column : 0) + vsram_off] + line); | 526 vscroll &= (context->vsram[(context->regs[REG_MODE_3] & BIT_VSCROLL ? column : 0) + vsram_off] + line); |
521 context->v_offset = vscroll & v_offset_mask; | 527 context->v_offset = vscroll & v_offset_mask; |
522 //printf("%s | line %d, vsram: %d, vscroll: %d, v_offset: %d\n",(vsram_off ? "B" : "A"), line, context->vsram[context->regs[REG_MODE_3] & 0x4 ? column : 0], vscroll, context->v_offset); | 528 //printf("%s | line %d, vsram: %d, vscroll: %d, v_offset: %d\n",(vsram_off ? "B" : "A"), line, context->vsram[context->regs[REG_MODE_3] & 0x4 ? column : 0], vscroll, context->v_offset); |
523 vscroll >>= vscroll_shift; | 529 vscroll >>= vscroll_shift; |