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