comparison vdp.c @ 426:add9e2f5c0e3

Make VDP render in native pixel format of the renderer for a modest performance gain and to make it easier to use OpenGL for rendering
author Mike Pavone <pavone@retrodev.com>
date Sun, 30 Jun 2013 11:45:58 -0700
parents 7e8e179116af
children 2802318c14e1
comparison
equal deleted inserted replaced
425:8b3ae850d1c4 426:add9e2f5c0e3
1 #include "vdp.h" 1 #include "vdp.h"
2 #include "blastem.h" 2 #include "blastem.h"
3 #include <stdlib.h> 3 #include <stdlib.h>
4 #include <string.h> 4 #include <string.h>
5 #include "render.h"
5 6
6 #define NTSC_ACTIVE 225 7 #define NTSC_ACTIVE 225
7 #define PAL_ACTIVE 241 8 #define PAL_ACTIVE 241
8 #define BUF_BIT_PRIORITY 0x40 9 #define BUF_BIT_PRIORITY 0x40
9 #define MAP_BIT_PRIORITY 0x8000 10 #define MAP_BIT_PRIORITY 0x8000
24 #define SLOT_WEIRD_END (HSYNC_SLOT_H40+17) 25 #define SLOT_WEIRD_END (HSYNC_SLOT_H40+17)
25 #define HSYNC_END_H32 (33 * MCLKS_SLOT_H32) 26 #define HSYNC_END_H32 (33 * MCLKS_SLOT_H32)
26 #define HBLANK_CLEAR_H40 (MCLK_WEIRD_END+61*4) 27 #define HBLANK_CLEAR_H40 (MCLK_WEIRD_END+61*4)
27 #define HBLANK_CLEAR_H32 (HSYNC_END_H32 + 46*5) 28 #define HBLANK_CLEAR_H32 (HSYNC_END_H32 + 46*5)
28 29
30 int32_t color_map[1 << 12];
31 uint8_t levels[] = {0, 27, 49, 71, 87, 103, 119, 130, 146, 157, 174, 190, 206, 228, 255};
32
33 uint8_t color_map_init_done;
34
29 void init_vdp_context(vdp_context * context) 35 void init_vdp_context(vdp_context * context)
30 { 36 {
31 memset(context, 0, sizeof(*context)); 37 memset(context, 0, sizeof(*context));
32 context->vdpmem = malloc(VRAM_SIZE); 38 context->vdpmem = malloc(VRAM_SIZE);
33 memset(context->vdpmem, 0, VRAM_SIZE); 39 memset(context->vdpmem, 0, VRAM_SIZE);
34 context->oddbuf = context->framebuf = malloc(FRAMEBUF_SIZE); 40 context->oddbuf = context->framebuf = malloc(FRAMEBUF_ENTRIES * (render_depth() / 8));
35 memset(context->framebuf, 0, FRAMEBUF_SIZE); 41 memset(context->framebuf, 0, FRAMEBUF_ENTRIES * (render_depth() / 8));
36 context->evenbuf = malloc(FRAMEBUF_SIZE); 42 context->evenbuf = malloc(FRAMEBUF_ENTRIES * (render_depth() / 8));
37 memset(context->evenbuf, 0, FRAMEBUF_SIZE); 43 memset(context->evenbuf, 0, FRAMEBUF_ENTRIES * (render_depth() / 8));
38 context->linebuf = malloc(LINEBUF_SIZE + SCROLL_BUFFER_SIZE*2); 44 context->linebuf = malloc(LINEBUF_SIZE + SCROLL_BUFFER_SIZE*2);
39 memset(context->linebuf, 0, LINEBUF_SIZE + SCROLL_BUFFER_SIZE*2); 45 memset(context->linebuf, 0, LINEBUF_SIZE + SCROLL_BUFFER_SIZE*2);
40 context->tmp_buf_a = context->linebuf + LINEBUF_SIZE; 46 context->tmp_buf_a = context->linebuf + LINEBUF_SIZE;
41 context->tmp_buf_b = context->tmp_buf_a + SCROLL_BUFFER_SIZE; 47 context->tmp_buf_b = context->tmp_buf_a + SCROLL_BUFFER_SIZE;
42 context->sprite_draws = MAX_DRAWS; 48 context->sprite_draws = MAX_DRAWS;
43 context->fifo_cur = malloc(sizeof(fifo_entry) * FIFO_SIZE); 49 context->fifo_cur = malloc(sizeof(fifo_entry) * FIFO_SIZE);
44 context->fifo_end = context->fifo_cur + FIFO_SIZE; 50 context->fifo_end = context->fifo_cur + FIFO_SIZE;
51 context->b32 = render_depth() == 32;
52 if (!color_map_init_done) {
53 uint8_t b,g,r;
54 for (uint16_t color = 0; color < (1 << 12); color++) {
55 if (color & FBUF_SHADOW) {
56 b = levels[(color >> 9) & 0x7];
57 g = levels[(color >> 5) & 0x7];
58 r = levels[(color >> 1) & 0x7];
59 } else if(color & FBUF_HILIGHT) {
60 b = levels[((color >> 9) & 0x7) + 7];
61 g = levels[((color >> 5) & 0x7) + 7];
62 r = levels[((color >> 1) & 0x7) + 7];
63 } else {
64 b = levels[(color >> 8) & 0xE];
65 g = levels[(color >> 4) & 0xE];
66 r = levels[color & 0xE];
67 }
68 color_map[color] = render_map_color(r, g, b);
69 }
70 color_map_init_done = 1;
71 }
45 } 72 }
46 73
47 void render_sprite_cells(vdp_context * context) 74 void render_sprite_cells(vdp_context * context)
48 { 75 {
49 if (context->cur_slot >= context->sprite_draws) { 76 if (context->cur_slot >= context->sprite_draws) {
300 context->dma_val = read_dma_value((context->regs[REG_DMASRC_H] << 16) | (context->regs[REG_DMASRC_M] << 8) | context->regs[REG_DMASRC_L]); 327 context->dma_val = read_dma_value((context->regs[REG_DMASRC_H] << 16) | (context->regs[REG_DMASRC_M] << 8) | context->regs[REG_DMASRC_L]);
301 context->vdpmem[context->address] = context->dma_val >> 8; 328 context->vdpmem[context->address] = context->dma_val >> 8;
302 context->flags |= FLAG_DMA_PROG; 329 context->flags |= FLAG_DMA_PROG;
303 } 330 }
304 break; 331 break;
305 case CRAM_WRITE: 332 case CRAM_WRITE: {
306 context->cram[(context->address/2) & (CRAM_SIZE-1)] = read_dma_value((context->regs[REG_DMASRC_H] << 16) | (context->regs[REG_DMASRC_M] << 8) | context->regs[REG_DMASRC_L]); 333 uint16_t addr = (context->address/2) & (CRAM_SIZE-1), value;
334 context->cram[addr] = value = read_dma_value((context->regs[REG_DMASRC_H] << 16) | (context->regs[REG_DMASRC_M] << 8) | context->regs[REG_DMASRC_L]);
335 context->colors[addr] = color_map[value & 0xEEE];
336 context->colors[addr + CRAM_SIZE] = color_map[(value & 0xEEE) | FBUF_SHADOW];
337 context->colors[addr + CRAM_SIZE*2] = color_map[(value & 0xEEE) | FBUF_HILIGHT];
307 //printf("CRAM DMA | %X set to %X from %X at %d\n", (context->address/2) & (CRAM_SIZE-1), context->cram[(context->address/2) & (CRAM_SIZE-1)], (context->regs[REG_DMASRC_H] << 17) | (context->regs[REG_DMASRC_M] << 9) | (context->regs[REG_DMASRC_L] << 1), context->cycles); 338 //printf("CRAM DMA | %X set to %X from %X at %d\n", (context->address/2) & (CRAM_SIZE-1), context->cram[(context->address/2) & (CRAM_SIZE-1)], (context->regs[REG_DMASRC_H] << 17) | (context->regs[REG_DMASRC_M] << 9) | (context->regs[REG_DMASRC_L] << 1), context->cycles);
308 break; 339 break;
340 }
309 case VSRAM_WRITE: 341 case VSRAM_WRITE:
310 if (((context->address/2) & 63) < VSRAM_SIZE) { 342 if (((context->address/2) & 63) < VSRAM_SIZE) {
311 context->vsram[(context->address/2) & 63] = read_dma_value((context->regs[REG_DMASRC_H] << 16) | (context->regs[REG_DMASRC_M] << 8) | context->regs[REG_DMASRC_L]); 343 context->vsram[(context->address/2) & 63] = read_dma_value((context->regs[REG_DMASRC_H] << 16) | (context->regs[REG_DMASRC_M] << 8) | context->regs[REG_DMASRC_L]);
312 } 344 }
313 break; 345 break;
320 case VRAM_WRITE: 352 case VRAM_WRITE:
321 //Charles MacDonald's VDP doc says that the low byte gets written first 353 //Charles MacDonald's VDP doc says that the low byte gets written first
322 context->vdpmem[context->address] = context->dma_val; 354 context->vdpmem[context->address] = context->dma_val;
323 context->dma_val = (context->dma_val << 8) | ((context->dma_val >> 8) & 0xFF); 355 context->dma_val = (context->dma_val << 8) | ((context->dma_val >> 8) & 0xFF);
324 break; 356 break;
325 case CRAM_WRITE: 357 case CRAM_WRITE: {
326 context->cram[(context->address/2) & (CRAM_SIZE-1)] = context->dma_val; 358 uint16_t addr = (context->address/2) & (CRAM_SIZE-1);
359 context->cram[addr] = context->dma_val;
360 context->colors[addr] = color_map[context->dma_val & 0xEEE];
361 context->colors[addr + CRAM_SIZE] = color_map[(context->dma_val & 0xEEE) | FBUF_SHADOW];
362 context->colors[addr + CRAM_SIZE*2] = color_map[(context->dma_val & 0xEEE) | FBUF_HILIGHT];
327 //printf("CRAM DMA Fill | %X set to %X at %d\n", (context->address/2) & (CRAM_SIZE-1), context->cram[(context->address/2) & (CRAM_SIZE-1)], context->cycles); 363 //printf("CRAM DMA Fill | %X set to %X at %d\n", (context->address/2) & (CRAM_SIZE-1), context->cram[(context->address/2) & (CRAM_SIZE-1)], context->cycles);
328 break; 364 break;
365 }
329 case VSRAM_WRITE: 366 case VSRAM_WRITE:
330 if (((context->address/2) & 63) < VSRAM_SIZE) { 367 if (((context->address/2) & 63) < VSRAM_SIZE) {
331 context->vsram[(context->address/2) & 63] = context->dma_val; 368 context->vsram[(context->address/2) & 63] = context->dma_val;
332 } 369 }
333 break; 370 break;
339 switch(context->dma_cd & 0xF) 376 switch(context->dma_cd & 0xF)
340 { 377 {
341 case VRAM_WRITE: 378 case VRAM_WRITE:
342 context->vdpmem[context->address] = context->dma_val; 379 context->vdpmem[context->address] = context->dma_val;
343 break; 380 break;
344 case CRAM_WRITE: 381 case CRAM_WRITE: {
345 context->cram[(context->address/2) & (CRAM_SIZE-1)] = context->dma_val; 382 uint16_t addr = (context->address/2) & (CRAM_SIZE-1);
383 context->cram[addr] = context->dma_val;
384 context->colors[addr] = color_map[context->dma_val & 0xEEE];
385 context->colors[addr + CRAM_SIZE] = color_map[(context->dma_val & 0xEEE) | FBUF_SHADOW];
386 context->colors[addr + CRAM_SIZE*2] = color_map[(context->dma_val & 0xEEE) | FBUF_HILIGHT];
346 //printf("CRAM DMA Copy | %X set to %X from %X at %d\n", (context->address/2) & (CRAM_SIZE-1), context->cram[(context->address/2) & (CRAM_SIZE-1)], context->regs[REG_DMASRC_L] & (CRAM_SIZE-1), context->cycles); 387 //printf("CRAM DMA Copy | %X set to %X from %X at %d\n", (context->address/2) & (CRAM_SIZE-1), context->cram[(context->address/2) & (CRAM_SIZE-1)], context->regs[REG_DMASRC_L] & (CRAM_SIZE-1), context->cycles);
347 break; 388 break;
389 }
348 case VSRAM_WRITE: 390 case VSRAM_WRITE:
349 if (((context->address/2) & 63) < VSRAM_SIZE) { 391 if (((context->address/2) & 63) < VSRAM_SIZE) {
350 context->vsram[(context->address/2) & 63] = context->dma_val; 392 context->vsram[(context->address/2) & 63] = context->dma_val;
351 } 393 }
352 break; 394 break;
409 start->partial = 1; 451 start->partial = 1;
410 //skip auto-increment and removal of entry from fifo 452 //skip auto-increment and removal of entry from fifo
411 return; 453 return;
412 } 454 }
413 break; 455 break;
414 case CRAM_WRITE: 456 case CRAM_WRITE: {
415 //printf("CRAM Write | %X to %X\n", start->value, (start->address/2) & (CRAM_SIZE-1)); 457 //printf("CRAM Write | %X to %X\n", start->value, (start->address/2) & (CRAM_SIZE-1));
416 context->cram[(start->address/2) & (CRAM_SIZE-1)] = start->value; 458 uint16_t addr = (context->address/2) & (CRAM_SIZE-1);
417 break; 459 context->cram[addr] = start->value;
460 context->colors[addr] = color_map[start->value & 0xEEE];
461 context->colors[addr + CRAM_SIZE] = color_map[(start->value & 0xEEE) | FBUF_SHADOW];
462 context->colors[addr + CRAM_SIZE*2] = color_map[(start->value & 0xEEE) | FBUF_HILIGHT];
463 break;
464 }
418 case VSRAM_WRITE: 465 case VSRAM_WRITE:
419 if (((start->address/2) & 63) < VSRAM_SIZE) { 466 if (((start->address/2) & 63) < VSRAM_SIZE) {
420 //printf("VSRAM Write: %X to %X\n", start->value, context->address); 467 //printf("VSRAM Write: %X to %X\n", start->value, context->address);
421 context->vsram[(start->address/2) & 63] = start->value; 468 context->vsram[(start->address/2) & 63] = start->value;
422 } 469 }
627 { 674 {
628 if (line >= 240) { 675 if (line >= 240) {
629 return; 676 return;
630 } 677 }
631 render_map(context->col_2, context->tmp_buf_b+SCROLL_BUFFER_DRAW+8, context); 678 render_map(context->col_2, context->tmp_buf_b+SCROLL_BUFFER_DRAW+8, context);
632 uint16_t *dst, *end; 679 uint16_t *dst;
680 uint32_t *dst32;
633 uint8_t *sprite_buf, *plane_a, *plane_b; 681 uint8_t *sprite_buf, *plane_a, *plane_b;
634 if (col) 682 if (col)
635 { 683 {
636 col-=2; 684 col-=2;
637 dst = context->framebuf + line * 320 + col * 8; 685 if (context->b32) {
686 dst32 = context->framebuf;
687 dst32 += line * 320 + col * 8;
688 } else {
689 dst = context->framebuf;
690 dst += line * 320 + col * 8;
691 }
638 sprite_buf = context->linebuf + col * 8; 692 sprite_buf = context->linebuf + col * 8;
639 uint16_t a_src; 693 uint16_t a_src;
640 if (context->flags & FLAG_WINDOW) { 694 if (context->flags & FLAG_WINDOW) {
641 plane_a = context->tmp_buf_a + SCROLL_BUFFER_DRAW; 695 plane_a = context->tmp_buf_a + SCROLL_BUFFER_DRAW;
642 a_src = FBUF_SRC_W; 696 //a_src = FBUF_SRC_W;
643 } else { 697 } else {
644 plane_a = context->tmp_buf_a + SCROLL_BUFFER_DRAW - (context->hscroll_a & 0xF); 698 plane_a = context->tmp_buf_a + SCROLL_BUFFER_DRAW - (context->hscroll_a & 0xF);
645 a_src = FBUF_SRC_A; 699 //a_src = FBUF_SRC_A;
646 } 700 }
647 plane_b = context->tmp_buf_b + SCROLL_BUFFER_DRAW - (context->hscroll_b & 0xF); 701 plane_b = context->tmp_buf_b + SCROLL_BUFFER_DRAW - (context->hscroll_b & 0xF);
648 end = dst + 16;
649 uint16_t src; 702 uint16_t src;
650 //printf("A | tmp_buf offset: %d\n", 8 - (context->hscroll_a & 0x7)); 703 //printf("A | tmp_buf offset: %d\n", 8 - (context->hscroll_a & 0x7));
651 704
652 if (context->regs[REG_MODE_4] & BIT_HILIGHT) { 705 if (context->regs[REG_MODE_4] & BIT_HILIGHT) {
653 for (; dst < end; ++plane_a, ++plane_b, ++sprite_buf, ++dst) { 706 for (int i = 0; i < 16; ++plane_a, ++plane_b, ++sprite_buf, ++i) {
654 uint8_t pixel; 707 uint8_t pixel;
655 708
656 src = 0; 709 src = 0;
657 uint8_t sprite_color = *sprite_buf & 0x3F; 710 uint8_t sprite_color = *sprite_buf & 0x3F;
658 if (sprite_color == 0x3E || sprite_color == 0x3F) { 711 if (sprite_color == 0x3E || sprite_color == 0x3F) {
659 if (sprite_color == 0x3F) { 712 if (sprite_color == 0x3F) {
660 src = FBUF_SHADOW; 713 src = CRAM_SIZE;//FBUF_SHADOW;
661 } else { 714 } else {
662 src = FBUF_HILIGHT; 715 src = CRAM_SIZE*2;//FBUF_HILIGHT;
663 } 716 }
664 if (*plane_a & BUF_BIT_PRIORITY && *plane_a & 0xF) { 717 if (*plane_a & BUF_BIT_PRIORITY && *plane_a & 0xF) {
665 pixel = *plane_a; 718 pixel = *plane_a;
666 src |= a_src; 719 //src |= a_src;
667 } else if (*plane_b & BUF_BIT_PRIORITY && *plane_b & 0xF) { 720 } else if (*plane_b & BUF_BIT_PRIORITY && *plane_b & 0xF) {
668 pixel = *plane_b; 721 pixel = *plane_b;
669 src |= FBUF_SRC_B; 722 //src |= FBUF_SRC_B;
670 } else if (*plane_a & 0xF) { 723 } else if (*plane_a & 0xF) {
671 pixel = *plane_a; 724 pixel = *plane_a;
672 src |= a_src; 725 //src |= a_src;
673 } else if (*plane_b & 0xF){ 726 } else if (*plane_b & 0xF){
674 pixel = *plane_b; 727 pixel = *plane_b;
675 src |= FBUF_SRC_B; 728 //src |= FBUF_SRC_B;
676 } else { 729 } else {
677 pixel = context->regs[REG_BG_COLOR] & 0x3F; 730 pixel = context->regs[REG_BG_COLOR] & 0x3F;
678 src |= FBUF_SRC_BG; 731 //src |= FBUF_SRC_BG;
679 } 732 }
680 } else { 733 } else {
681 if (*sprite_buf & BUF_BIT_PRIORITY && *sprite_buf & 0xF) { 734 if (*sprite_buf & BUF_BIT_PRIORITY && *sprite_buf & 0xF) {
682 pixel = *sprite_buf; 735 pixel = *sprite_buf;
683 src = FBUF_SRC_S; 736 //src = FBUF_SRC_S;
684 } else if (*plane_a & BUF_BIT_PRIORITY && *plane_a & 0xF) { 737 } else if (*plane_a & BUF_BIT_PRIORITY && *plane_a & 0xF) {
685 pixel = *plane_a; 738 pixel = *plane_a;
686 src = a_src; 739 //src = a_src;
687 } else if (*plane_b & BUF_BIT_PRIORITY && *plane_b & 0xF) { 740 } else if (*plane_b & BUF_BIT_PRIORITY && *plane_b & 0xF) {
688 pixel = *plane_b; 741 pixel = *plane_b;
689 src = FBUF_SRC_B; 742 //src = FBUF_SRC_B;
690 } else { 743 } else {
691 if (!(*plane_a & BUF_BIT_PRIORITY || *plane_a & BUF_BIT_PRIORITY)) { 744 if (!(*plane_a & BUF_BIT_PRIORITY || *plane_a & BUF_BIT_PRIORITY)) {
692 src = FBUF_SHADOW; 745 src = CRAM_SIZE;//FBUF_SHADOW;
693 } 746 }
694 if (*sprite_buf & 0xF) { 747 if (*sprite_buf & 0xF) {
695 pixel = *sprite_buf; 748 pixel = *sprite_buf;
696 if (*sprite_buf & 0xF == 0xE) { 749 if (*sprite_buf & 0xF == 0xE) {
697 src = FBUF_SRC_S; 750 src = 0;//FBUF_SRC_S;
698 } else { 751 } /*else {
699 src |= FBUF_SRC_S; 752 src |= FBUF_SRC_S;
700 } 753 }*/
701 } else if (*plane_a & 0xF) { 754 } else if (*plane_a & 0xF) {
702 pixel = *plane_a; 755 pixel = *plane_a;
703 src |= a_src; 756 //src |= a_src;
704 } else if (*plane_b & 0xF){ 757 } else if (*plane_b & 0xF){
705 pixel = *plane_b; 758 pixel = *plane_b;
706 src |= FBUF_SRC_B; 759 //src |= FBUF_SRC_B;
707 } else { 760 } else {
708 pixel = context->regs[REG_BG_COLOR] & 0x3F; 761 pixel = context->regs[REG_BG_COLOR] & 0x3F;
709 src |= FBUF_SRC_BG; 762 //src |= FBUF_SRC_BG;
710 } 763 }
711 } 764 }
712 } 765 }
713 *dst = (context->cram[pixel & 0x3F] & 0xEEE) | ((pixel & BUF_BIT_PRIORITY) ? FBUF_BIT_PRIORITY : 0) | src; 766 pixel &= 0x3F;
714 } 767 pixel += src;
715 } else { 768 if (context->b32) {
716 for (; dst < end; ++plane_a, ++plane_b, ++sprite_buf, ++dst) { 769 *(dst32++) = context->colors[pixel];
770 } else {
771 *(dst++) = context->colors[pixel];
772 }
773 //*dst = (context->cram[pixel & 0x3F] & 0xEEE) | ((pixel & BUF_BIT_PRIORITY) ? FBUF_BIT_PRIORITY : 0) | src;
774 }
775 } else {
776 for (int i = 0; i < 16; ++plane_a, ++plane_b, ++sprite_buf, ++i) {
717 uint8_t pixel; 777 uint8_t pixel;
718 if (*sprite_buf & BUF_BIT_PRIORITY && *sprite_buf & 0xF) { 778 if (*sprite_buf & BUF_BIT_PRIORITY && *sprite_buf & 0xF) {
719 pixel = *sprite_buf; 779 pixel = *sprite_buf;
720 src = FBUF_SRC_S; 780 //src = FBUF_SRC_S;
721 } else if (*plane_a & BUF_BIT_PRIORITY && *plane_a & 0xF) { 781 } else if (*plane_a & BUF_BIT_PRIORITY && *plane_a & 0xF) {
722 pixel = *plane_a; 782 pixel = *plane_a;
723 src = a_src; 783 //src = a_src;
724 } else if (*plane_b & BUF_BIT_PRIORITY && *plane_b & 0xF) { 784 } else if (*plane_b & BUF_BIT_PRIORITY && *plane_b & 0xF) {
725 pixel = *plane_b; 785 pixel = *plane_b;
726 src = FBUF_SRC_B; 786 //src = FBUF_SRC_B;
727 } else if (*sprite_buf & 0xF) { 787 } else if (*sprite_buf & 0xF) {
728 pixel = *sprite_buf; 788 pixel = *sprite_buf;
729 src = FBUF_SRC_S; 789 //src = FBUF_SRC_S;
730 } else if (*plane_a & 0xF) { 790 } else if (*plane_a & 0xF) {
731 pixel = *plane_a; 791 pixel = *plane_a;
732 src = a_src; 792 //src = a_src;
733 } else if (*plane_b & 0xF){ 793 } else if (*plane_b & 0xF){
734 pixel = *plane_b; 794 pixel = *plane_b;
735 src = FBUF_SRC_B; 795 //src = FBUF_SRC_B;
736 } else { 796 } else {
737 pixel = context->regs[REG_BG_COLOR] & 0x3F; 797 pixel = context->regs[REG_BG_COLOR] & 0x3F;
738 src = FBUF_SRC_BG; 798 //src = FBUF_SRC_BG;
739 } 799 }
740 *dst = (context->cram[pixel & 0x3F] & 0xEEE) | ((pixel & BUF_BIT_PRIORITY) ? FBUF_BIT_PRIORITY : 0) | src; 800 if (context->b32) {
801 *(dst32++) = context->colors[pixel & 0x3F];
802 } else {
803 *(dst++) = context->colors[pixel & 0x3F];
804 }
805 //*dst = (context->cram[pixel & 0x3F] & 0xEEE) | ((pixel & BUF_BIT_PRIORITY) ? FBUF_BIT_PRIORITY : 0) | src;
741 } 806 }
742 } 807 }
743 } else { 808 } else {
744 //dst = context->framebuf + line * 320; 809 //dst = context->framebuf + line * 320;
745 //sprite_buf = context->linebuf + col * 8; 810 //sprite_buf = context->linebuf + col * 8;
1123 1188
1124 void check_render_bg(vdp_context * context, int32_t line, uint32_t slot) 1189 void check_render_bg(vdp_context * context, int32_t line, uint32_t slot)
1125 { 1190 {
1126 if (line > 0) { 1191 if (line > 0) {
1127 line -= 1; 1192 line -= 1;
1128 uint16_t * start = NULL, *end = NULL; 1193 int starti = -1;
1129 if (context->latched_mode & BIT_H40) { 1194 if (context->latched_mode & BIT_H40) {
1130 if (slot >= 50 && slot < 210) { 1195 if (slot >= 50 && slot < 210) {
1131 uint32_t x = (slot-50)*2; 1196 uint32_t x = (slot-50)*2;
1132 start = context->framebuf + line * 320 + x; 1197 starti = line * 320 + x;
1133 end = start + 2;
1134 } 1198 }
1135 } else { 1199 } else {
1136 if (slot >= 43 && slot < 171) { 1200 if (slot >= 43 && slot < 171) {
1137 uint32_t x = (slot-43)*2; 1201 uint32_t x = (slot-43)*2;
1138 start = context->framebuf + line * 320 + x; 1202 starti = line * 320 + x;
1139 end = start + 2; 1203 }
1140 } 1204 }
1141 } 1205 if (starti >= 0) {
1142 uint16_t color = (context->cram[context->regs[REG_BG_COLOR] & 0x3F] & 0xEEE); 1206 if (context->b32) {
1143 while (start != end) { 1207 uint32_t color = context->colors[context->regs[REG_BG_COLOR] & 0x3F];
1144 *start = color; 1208 uint32_t * start = context->framebuf;
1145 ++start; 1209 start += starti;
1210 for (int i = 0; i < 2; i++) {
1211 *(start++) = color;
1212 }
1213 } else {
1214 uint16_t color = context->colors[context->regs[REG_BG_COLOR] & 0x3F];
1215 uint16_t * start = context->framebuf;
1216 start += starti;
1217 for (int i = 0; i < 2; i++) {
1218 *(start++) = color;
1219 }
1220 }
1146 } 1221 }
1147 } 1222 }
1148 } 1223 }
1149 1224
1150 void vdp_run_context(vdp_context * context, uint32_t target_cycles) 1225 void vdp_run_context(vdp_context * context, uint32_t target_cycles)
1669 if (fread(tmp_buf, 1, sizeof(tmp_buf), state_file) != sizeof(tmp_buf)) { 1744 if (fread(tmp_buf, 1, sizeof(tmp_buf), state_file) != sizeof(tmp_buf)) {
1670 fputs("Failed to read CRAM from savestate\n", stderr); 1745 fputs("Failed to read CRAM from savestate\n", stderr);
1671 return 0; 1746 return 0;
1672 } 1747 }
1673 for (int i = 0; i < CRAM_SIZE; i++) { 1748 for (int i = 0; i < CRAM_SIZE; i++) {
1674 context->cram[i] = (tmp_buf[i*2+1] << 8) | tmp_buf[i*2]; 1749 uint16_t value;
1750 context->cram[i] = value = (tmp_buf[i*2+1] << 8) | tmp_buf[i*2];
1751 context->colors[i] = color_map[value & 0xEEE];
1752 context->colors[i + CRAM_SIZE] = color_map[(value & 0xEEE) | FBUF_SHADOW];
1753 context->colors[i + CRAM_SIZE*2] = color_map[(value & 0xEEE) | FBUF_HILIGHT];
1675 } 1754 }
1676 if (fread(tmp_buf, 2, VSRAM_SIZE, state_file) != VSRAM_SIZE) { 1755 if (fread(tmp_buf, 2, VSRAM_SIZE, state_file) != VSRAM_SIZE) {
1677 fputs("Failed to read VSRAM from savestate\n", stderr); 1756 fputs("Failed to read VSRAM from savestate\n", stderr);
1678 return 0; 1757 return 0;
1679 } 1758 }