comparison vdp.c @ 436:e341fd5aa996

Implement the scroll ring buffer properly without memcpy
author Mike Pavone <pavone@retrodev.com>
date Fri, 12 Jul 2013 19:11:55 -0700
parents 2802318c14e1
children afbea09d7fb4
comparison
equal deleted inserted replaced
435:e68efe35d147 436:e341fd5aa996
10 #define MAP_BIT_PRIORITY 0x8000 10 #define MAP_BIT_PRIORITY 0x8000
11 #define MAP_BIT_H_FLIP 0x800 11 #define MAP_BIT_H_FLIP 0x800
12 #define MAP_BIT_V_FLIP 0x1000 12 #define MAP_BIT_V_FLIP 0x1000
13 13
14 #define SCROLL_BUFFER_SIZE 32 14 #define SCROLL_BUFFER_SIZE 32
15 #define SCROLL_BUFFER_DRAW 16 15 #define SCROLL_BUFFER_MASK (SCROLL_BUFFER_SIZE-1)
16 #define SCROLL_BUFFER_DRAW (SCROLL_BUFFER_SIZE/2)
16 17
17 #define FIFO_SIZE 4 18 #define FIFO_SIZE 4
18 19
19 #define MCLKS_SLOT_H40 16 20 #define MCLKS_SLOT_H40 16
20 #define MCLKS_SLOT_H32 20 21 #define MCLKS_SLOT_H32 20
610 void read_map_scroll_b(uint16_t column, uint32_t line, vdp_context * context) 611 void read_map_scroll_b(uint16_t column, uint32_t line, vdp_context * context)
611 { 612 {
612 read_map_scroll(column, 1, line, (context->regs[REG_SCROLL_B] & 0x7) << 13, context->hscroll_b, context); 613 read_map_scroll(column, 1, line, (context->regs[REG_SCROLL_B] & 0x7) << 13, context->hscroll_b, context);
613 } 614 }
614 615
615 void render_map(uint16_t col, uint8_t * tmp_buf, vdp_context * context) 616 void render_map(uint16_t col, uint8_t * tmp_buf, uint8_t offset, vdp_context * context)
616 { 617 {
617 uint16_t address; 618 uint16_t address;
618 uint8_t shift, add; 619 uint8_t shift, add;
619 if (context->double_res) { 620 if (context->double_res) {
620 address = ((col & 0x3FF) << 6); 621 address = ((col & 0x3FF) << 6);
631 address += 4 * context->v_offset/*((context->v_offset << shift) + add)*/; 632 address += 4 * context->v_offset/*((context->v_offset << shift) + add)*/;
632 } 633 }
633 uint16_t pal_priority = (col >> 9) & 0x70; 634 uint16_t pal_priority = (col >> 9) & 0x70;
634 int32_t dir; 635 int32_t dir;
635 if (col & MAP_BIT_H_FLIP) { 636 if (col & MAP_BIT_H_FLIP) {
636 tmp_buf += 7; 637 offset += 7;
638 offset &= SCROLL_BUFFER_MASK;
637 dir = -1; 639 dir = -1;
638 } else { 640 } else {
639 dir = 1; 641 dir = 1;
640 } 642 }
641 for (uint32_t i=0; i < 4; i++, address++) 643 for (uint32_t i=0; i < 4; i++, address++)
642 { 644 {
643 *tmp_buf = pal_priority | (context->vdpmem[address] >> 4); 645 tmp_buf[offset] = pal_priority | (context->vdpmem[address] >> 4);
644 tmp_buf += dir; 646 offset += dir;
645 *tmp_buf = pal_priority | (context->vdpmem[address] & 0xF); 647 offset &= SCROLL_BUFFER_MASK;
646 tmp_buf += dir; 648 tmp_buf[offset] = pal_priority | (context->vdpmem[address] & 0xF);
649 offset += dir;
650 offset &= SCROLL_BUFFER_MASK;
647 } 651 }
648 } 652 }
649 653
650 void render_map_1(vdp_context * context) 654 void render_map_1(vdp_context * context)
651 { 655 {
652 render_map(context->col_1, context->tmp_buf_a+SCROLL_BUFFER_DRAW, context); 656 render_map(context->col_1, context->tmp_buf_a, context->buf_a_off, context);
653 } 657 }
654 658
655 void render_map_2(vdp_context * context) 659 void render_map_2(vdp_context * context)
656 { 660 {
657 render_map(context->col_2, context->tmp_buf_a+SCROLL_BUFFER_DRAW+8, context); 661 render_map(context->col_2, context->tmp_buf_a, context->buf_a_off+8, context);
658 } 662 }
659 663
660 void render_map_3(vdp_context * context) 664 void render_map_3(vdp_context * context)
661 { 665 {
662 render_map(context->col_1, context->tmp_buf_b+SCROLL_BUFFER_DRAW, context); 666 render_map(context->col_1, context->tmp_buf_b, context->buf_b_off, context);
663 } 667 }
664 668
665 void render_map_output(uint32_t line, int32_t col, vdp_context * context) 669 void render_map_output(uint32_t line, int32_t col, vdp_context * context)
666 { 670 {
667 if (line >= 240) { 671 if (line >= 240) {
668 return; 672 return;
669 } 673 }
670 render_map(context->col_2, context->tmp_buf_b+SCROLL_BUFFER_DRAW+8, context); 674 render_map(context->col_2, context->tmp_buf_b, context->buf_b_off+8, context);
671 uint16_t *dst; 675 uint16_t *dst;
672 uint32_t *dst32; 676 uint32_t *dst32;
673 uint8_t *sprite_buf, *plane_a, *plane_b; 677 uint8_t *sprite_buf, *plane_a, *plane_b;
678 int plane_a_off, plane_b_off;
674 if (col) 679 if (col)
675 { 680 {
676 col-=2; 681 col-=2;
677 if (context->b32) { 682 if (context->b32) {
678 dst32 = context->framebuf; 683 dst32 = context->framebuf;
682 dst += line * 320 + col * 8; 687 dst += line * 320 + col * 8;
683 } 688 }
684 sprite_buf = context->linebuf + col * 8; 689 sprite_buf = context->linebuf + col * 8;
685 uint16_t a_src; 690 uint16_t a_src;
686 if (context->flags & FLAG_WINDOW) { 691 if (context->flags & FLAG_WINDOW) {
687 plane_a = context->tmp_buf_a + SCROLL_BUFFER_DRAW; 692 plane_a_off = context->buf_a_off;
688 //a_src = FBUF_SRC_W; 693 //a_src = FBUF_SRC_W;
689 } else { 694 } else {
690 plane_a = context->tmp_buf_a + SCROLL_BUFFER_DRAW - (context->hscroll_a & 0xF); 695 plane_a_off = context->buf_a_off - (context->hscroll_a & 0xF);
691 //a_src = FBUF_SRC_A; 696 //a_src = FBUF_SRC_A;
692 } 697 }
693 plane_b = context->tmp_buf_b + SCROLL_BUFFER_DRAW - (context->hscroll_b & 0xF); 698 plane_b_off = context->buf_b_off - (context->hscroll_b & 0xF);
694 uint16_t src; 699 uint16_t src;
695 //printf("A | tmp_buf offset: %d\n", 8 - (context->hscroll_a & 0x7)); 700 //printf("A | tmp_buf offset: %d\n", 8 - (context->hscroll_a & 0x7));
696 701
697 if (context->regs[REG_MODE_4] & BIT_HILIGHT) { 702 if (context->regs[REG_MODE_4] & BIT_HILIGHT) {
698 for (int i = 0; i < 16; ++plane_a, ++plane_b, ++sprite_buf, ++i) { 703 for (int i = 0; i < 16; ++plane_a_off, ++plane_b_off, ++sprite_buf, ++i) {
699 uint8_t pixel; 704 uint8_t pixel;
700 705 plane_a = context->tmp_buf_a + (plane_a_off & SCROLL_BUFFER_MASK);
706 plane_b = context->tmp_buf_b + (plane_b_off & SCROLL_BUFFER_MASK);
701 src = 0; 707 src = 0;
702 uint8_t sprite_color = *sprite_buf & 0x3F; 708 uint8_t sprite_color = *sprite_buf & 0x3F;
703 if (sprite_color == 0x3E || sprite_color == 0x3F) { 709 if (sprite_color == 0x3E || sprite_color == 0x3F) {
704 if (sprite_color == 0x3F) { 710 if (sprite_color == 0x3F) {
705 src = CRAM_SIZE;//FBUF_SHADOW; 711 src = CRAM_SIZE;//FBUF_SHADOW;
763 *(dst++) = context->colors[pixel]; 769 *(dst++) = context->colors[pixel];
764 } 770 }
765 //*dst = (context->cram[pixel & 0x3F] & 0xEEE) | ((pixel & BUF_BIT_PRIORITY) ? FBUF_BIT_PRIORITY : 0) | src; 771 //*dst = (context->cram[pixel & 0x3F] & 0xEEE) | ((pixel & BUF_BIT_PRIORITY) ? FBUF_BIT_PRIORITY : 0) | src;
766 } 772 }
767 } else { 773 } else {
768 for (int i = 0; i < 16; ++plane_a, ++plane_b, ++sprite_buf, ++i) { 774 for (int i = 0; i < 16; ++plane_a_off, ++plane_b_off, ++sprite_buf, ++i) {
769 uint8_t pixel; 775 uint8_t pixel;
776 plane_a = context->tmp_buf_a + (plane_a_off & SCROLL_BUFFER_MASK);
777 plane_b = context->tmp_buf_b + (plane_b_off & SCROLL_BUFFER_MASK);
770 if (*sprite_buf & BUF_BIT_PRIORITY && *sprite_buf & 0xF) { 778 if (*sprite_buf & BUF_BIT_PRIORITY && *sprite_buf & 0xF) {
771 pixel = *sprite_buf; 779 pixel = *sprite_buf;
772 //src = FBUF_SRC_S; 780 //src = FBUF_SRC_S;
773 } else if (*plane_a & BUF_BIT_PRIORITY && *plane_a & 0xF) { 781 } else if (*plane_a & BUF_BIT_PRIORITY && *plane_a & 0xF) {
774 pixel = *plane_a; 782 pixel = *plane_a;
802 //sprite_buf = context->linebuf + col * 8; 810 //sprite_buf = context->linebuf + col * 8;
803 //plane_a = context->tmp_buf_a + 16 - (context->hscroll_a & 0x7); 811 //plane_a = context->tmp_buf_a + 16 - (context->hscroll_a & 0x7);
804 //plane_b = context->tmp_buf_b + 16 - (context->hscroll_b & 0x7); 812 //plane_b = context->tmp_buf_b + 16 - (context->hscroll_b & 0x7);
805 //end = dst + 8; 813 //end = dst + 8;
806 } 814 }
807 815 context->buf_a_off = (context->buf_a_off + SCROLL_BUFFER_DRAW) & SCROLL_BUFFER_MASK;
808 uint16_t remaining; 816 context->buf_b_off = (context->buf_b_off + SCROLL_BUFFER_DRAW) & SCROLL_BUFFER_MASK;
809 if (!(context->flags & FLAG_WINDOW)) {
810 remaining = context->hscroll_a & 0xF;
811 memcpy(context->tmp_buf_a + SCROLL_BUFFER_DRAW - remaining, context->tmp_buf_a + SCROLL_BUFFER_SIZE - remaining, remaining);
812 }
813 remaining = context->hscroll_b & 0xF;
814 memcpy(context->tmp_buf_b + SCROLL_BUFFER_DRAW - remaining, context->tmp_buf_b + SCROLL_BUFFER_SIZE - remaining, remaining);
815 } 817 }
816 818
817 #define COLUMN_RENDER_BLOCK(column, startcyc) \ 819 #define COLUMN_RENDER_BLOCK(column, startcyc) \
818 case startcyc:\ 820 case startcyc:\
819 read_map_scroll_a(column, line, context);\ 821 read_map_scroll_a(column, line, context);\