comparison vdp.c @ 1267:3772bb926be5

Initial stab at horizontal border emulation. Only works for H40 and still has a few minor holes to fill
author Michael Pavone <pavone@retrodev.com>
date Mon, 06 Mar 2017 00:23:35 -0800
parents 8dc50e50ced6
children ff8e29eeb1ec
comparison
equal deleted inserted replaced
1266:a4fa897c99ce 1267:3772bb926be5
709 709
710 #define CRAM_BITS 0xEEE 710 #define CRAM_BITS 0xEEE
711 #define VSRAM_BITS 0x7FF 711 #define VSRAM_BITS 0x7FF
712 #define VSRAM_DIRTY_BITS 0xF800 712 #define VSRAM_DIRTY_BITS 0xF800
713 713
714 //rough estimate of slot number at which active display starts 714 //rough estimate of slot number at which border display starts
715 #define BG_START_SLOT 9 715 #define BG_START_SLOT 0
716 716
717 void write_cram(vdp_context * context, uint16_t address, uint16_t value) 717 void write_cram(vdp_context * context, uint16_t address, uint16_t value)
718 { 718 {
719 uint16_t addr; 719 uint16_t addr;
720 if (context->regs[REG_MODE_2] & BIT_MODE_5) { 720 if (context->regs[REG_MODE_2] & BIT_MODE_5) {
731 731
732 if (context->hslot >= BG_START_SLOT && ( 732 if (context->hslot >= BG_START_SLOT && (
733 context->vcounter < context->inactive_start + context->border_bot 733 context->vcounter < context->inactive_start + context->border_bot
734 || context->vcounter > 0x200 - context->border_top 734 || context->vcounter > 0x200 - context->border_top
735 )) { 735 )) {
736 uint8_t bg_end_slot = BG_START_SLOT + (context->regs[REG_MODE_4] & BIT_H40) ? 320/2 : 256/2; 736 uint8_t bg_end_slot = BG_START_SLOT + (context->regs[REG_MODE_4] & BIT_H40) ? LINEBUF_SIZE/2 : (256+HORIZ_BORDER)/2;
737 if (context->hslot < bg_end_slot) { 737 if (context->hslot < bg_end_slot) {
738 uint32_t color = (context->regs[REG_MODE_2] & BIT_MODE_5) ? context->colors[addr] : context->colors[addr + CRAM_SIZE*3]; 738 uint32_t color = (context->regs[REG_MODE_2] & BIT_MODE_5) ? context->colors[addr] : context->colors[addr + CRAM_SIZE*3];
739 context->output[(context->hslot - BG_START_SLOT)*2 + 1] = color; 739 context->output[(context->hslot - BG_START_SLOT)*2 + 1] = color;
740 } 740 }
741 } 741 }
1202 uint8_t *sprite_buf, *plane_a, *plane_b; 1202 uint8_t *sprite_buf, *plane_a, *plane_b;
1203 int plane_a_off, plane_b_off; 1203 int plane_a_off, plane_b_off;
1204 if (col) 1204 if (col)
1205 { 1205 {
1206 col-=2; 1206 col-=2;
1207 dst = context->output + col * 8; 1207 dst = context->output + BORDER_LEFT + col * 8;
1208 if (context->debug < 2) { 1208 if (context->debug < 2) {
1209 sprite_buf = context->linebuf + col * 8; 1209 sprite_buf = context->linebuf + col * 8;
1210 uint8_t a_src, src; 1210 uint8_t a_src, src;
1211 if (context->flags & FLAG_WINDOW) { 1211 if (context->flags & FLAG_WINDOW) {
1212 plane_a_off = context->buf_a_off; 1212 plane_a_off = context->buf_a_off;
1484 context->frame++; 1484 context->frame++;
1485 } 1485 }
1486 context->vcounter &= 0x1FF; 1486 context->vcounter &= 0x1FF;
1487 } else { 1487 } else {
1488 if (context->vcounter == context->inactive_start) { 1488 if (context->vcounter == context->inactive_start) {
1489 render_framebuffer_updated(context->flags2 & FLAG2_EVEN_FIELD ? FRAMEBUFFER_EVEN: FRAMEBUFFER_ODD, context->h40_lines > (context->inactive_start + context->border_top) / 2 ? 320 : 256); 1489 render_framebuffer_updated(context->flags2 & FLAG2_EVEN_FIELD ? FRAMEBUFFER_EVEN: FRAMEBUFFER_ODD, context->h40_lines > (context->inactive_start + context->border_top) / 2 ? LINEBUF_SIZE : (256+HORIZ_BORDER));
1490 if (context->double_res) { 1490 if (context->double_res) {
1491 context->flags2 ^= FLAG2_EVEN_FIELD; 1491 context->flags2 ^= FLAG2_EVEN_FIELD;
1492 } 1492 }
1493 context->fb = render_get_framebuffer(context->flags2 & FLAG2_EVEN_FIELD ? FRAMEBUFFER_EVEN : FRAMEBUFFER_ODD, &context->output_pitch); 1493 context->fb = render_get_framebuffer(context->flags2 & FLAG2_EVEN_FIELD ? FRAMEBUFFER_EVEN : FRAMEBUFFER_ODD, &context->output_pitch);
1494 context->h40_lines = 0; 1494 context->h40_lines = 0;
1526 #define COLUMN_RENDER_BLOCK(column, startcyc) \ 1526 #define COLUMN_RENDER_BLOCK(column, startcyc) \
1527 case startcyc:\ 1527 case startcyc:\
1528 read_map_scroll_a(column, context->vcounter, context);\ 1528 read_map_scroll_a(column, context->vcounter, context);\
1529 CHECK_LIMIT\ 1529 CHECK_LIMIT\
1530 case ((startcyc+1)&0xFF):\ 1530 case ((startcyc+1)&0xFF):\
1531 if (column == 2) {\
1532 uint32_t bg_color = context->colors[context->regs[REG_BG_COLOR] & 0x3F];\
1533 for (int i = 0; i < BORDER_LEFT; i++) {\
1534 context->output[i] = bg_color;\
1535 }\
1536 }\
1531 external_slot(context);\ 1537 external_slot(context);\
1532 CHECK_LIMIT\ 1538 CHECK_LIMIT\
1533 case ((startcyc+2)&0xFF):\ 1539 case ((startcyc+2)&0xFF):\
1534 render_map_1(context);\ 1540 render_map_1(context);\
1535 CHECK_LIMIT\ 1541 CHECK_LIMIT\
1836 COLUMN_RENDER_BLOCK(38, 145) 1842 COLUMN_RENDER_BLOCK(38, 145)
1837 COLUMN_RENDER_BLOCK_REFRESH(40, 153) 1843 COLUMN_RENDER_BLOCK_REFRESH(40, 153)
1838 case 161: 1844 case 161:
1839 external_slot(context); 1845 external_slot(context);
1840 CHECK_LIMIT 1846 CHECK_LIMIT
1841 case 162: 1847 case 162: {
1842 external_slot(context); 1848 external_slot(context);
1843 CHECK_LIMIT 1849 uint32_t bg_color = context->colors[context->regs[REG_BG_COLOR] & 0x3F];
1850 for (int i = LINEBUF_SIZE-BORDER_RIGHT; i < LINEBUF_SIZE; i++)
1851 {
1852 context->output[i] = bg_color;
1853 }
1854 CHECK_LIMIT
1855 }
1844 //sprite render to line buffer starts 1856 //sprite render to line buffer starts
1845 case 163: 1857 case 163:
1846 context->cur_slot = MAX_DRAWS-1; 1858 context->cur_slot = MAX_DRAWS-1;
1847 memset(context->linebuf, 0, LINEBUF_SIZE); 1859 memset(context->linebuf, 0, LINEBUF_SIZE);
1848 render_sprite_cells(context); 1860 render_sprite_cells(context);
2197 2209
2198 if (mode_5) { 2210 if (mode_5) {
2199 if (is_h40) { 2211 if (is_h40) {
2200 buf_clear_slot = 161; 2212 buf_clear_slot = 161;
2201 index_reset_slot = 165; 2213 index_reset_slot = 165;
2202 bg_end_slot = BG_START_SLOT + 320/2; 2214 bg_end_slot = BG_START_SLOT + LINEBUF_SIZE/2;
2203 max_draws = MAX_DRAWS-1; 2215 max_draws = MAX_DRAWS-1;
2204 max_sprites = MAX_SPRITES_LINE; 2216 max_sprites = MAX_SPRITES_LINE;
2205 index_reset_value = 0x80; 2217 index_reset_value = 0x80;
2206 vint_slot = VINT_SLOT_H40; 2218 vint_slot = VINT_SLOT_H40;
2207 line_change = LINE_CHANGE_H40; 2219 line_change = LINE_CHANGE_H40;
2208 jump_start = 182; 2220 jump_start = 182;
2209 jump_dest = 229; 2221 jump_dest = 229;
2210 } else { 2222 } else {
2211 bg_end_slot = BG_START_SLOT + 256/2; 2223 bg_end_slot = BG_START_SLOT + (256+HORIZ_BORDER)/2;
2212 max_draws = MAX_DRAWS_H32-1; 2224 max_draws = MAX_DRAWS_H32-1;
2213 max_sprites = MAX_SPRITES_LINE_H32; 2225 max_sprites = MAX_SPRITES_LINE_H32;
2214 buf_clear_slot = 128; 2226 buf_clear_slot = 128;
2215 index_reset_slot = 132; 2227 index_reset_slot = 132;
2216 index_reset_value = 0x80; 2228 index_reset_value = 0x80;
2220 jump_dest = 233; 2232 jump_dest = 233;
2221 } 2233 }
2222 vint_line = context->inactive_start; 2234 vint_line = context->inactive_start;
2223 active_line = 0x1FF; 2235 active_line = 0x1FF;
2224 } else { 2236 } else {
2225 bg_end_slot = BG_START_SLOT + 256/2; 2237 bg_end_slot = BG_START_SLOT + (256+HORIZ_BORDER)/2;
2226 max_draws = MAX_DRAWS_H32_MODE4; 2238 max_draws = MAX_DRAWS_H32_MODE4;
2227 buf_clear_slot = 136; 2239 buf_clear_slot = 136;
2228 index_reset_slot = 253; 2240 index_reset_slot = 253;
2229 index_reset_value = 0; 2241 index_reset_value = 0;
2230 vint_line = context->inactive_start + 1; 2242 vint_line = context->inactive_start + 1;
2275 } else if (context->regs[REG_MODE_1] & BIT_MODE_4) { 2287 } else if (context->regs[REG_MODE_1] & BIT_MODE_4) {
2276 bg_color = context->colors[CRAM_SIZE * 3 + 0x10 + (context->regs[REG_BG_COLOR] & 0xF)]; 2288 bg_color = context->colors[CRAM_SIZE * 3 + 0x10 + (context->regs[REG_BG_COLOR] & 0xF)];
2277 } 2289 }
2278 *(dst++) = bg_color; 2290 *(dst++) = bg_color;
2279 *(dst++) = bg_color; 2291 *(dst++) = bg_color;
2292 if (context->hslot == (bg_end_slot-1)) {
2293 *(dst++) = bg_color;
2294 }
2280 } 2295 }
2281 2296
2282 if (!is_refresh(context, context->hslot)) { 2297 if (!is_refresh(context, context->hslot)) {
2283 external_slot(context); 2298 external_slot(context);
2284 if (context->flags & FLAG_DMA_RUN && !is_refresh(context, context->hslot)) { 2299 if (context->flags & FLAG_DMA_RUN && !is_refresh(context, context->hslot)) {