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;