comparison vdp.c @ 1135:8506b305e0e8

Update Mode 4 rendering to match logic analyzer captures
author Michael Pavone <pavone@retrodev.com>
date Sun, 01 Jan 2017 21:06:32 -0800
parents 15a32da89d23
children 52f25c41abdd
comparison
equal deleted inserted replaced
1134:15a32da89d23 1135:8506b305e0e8
221 } 221 }
222 } 222 }
223 223
224 static void fetch_sprite_cells_mode4(vdp_context * context) 224 static void fetch_sprite_cells_mode4(vdp_context * context)
225 { 225 {
226 if (context->cur_slot >= context->sprite_draws) { 226 if (context->sprite_index >= context->sprite_draws) {
227 sprite_draw * d = context->sprite_draw_list + context->cur_slot; 227 sprite_draw * d = context->sprite_draw_list + context->sprite_index;
228 uint32_t address = mode4_address_map[d->address & 0x3FFF]; 228 uint32_t address = mode4_address_map[d->address & 0x3FFF];
229 context->fetch_tmp[0] = context->vdpmem[address]; 229 context->fetch_tmp[0] = context->vdpmem[address];
230 context->fetch_tmp[1] = context->vdpmem[address + 1]; 230 context->fetch_tmp[1] = context->vdpmem[address + 1];
231 } 231 }
232 } 232 }
233 233
234 static void render_sprite_cells_mode4(vdp_context * context) 234 static void render_sprite_cells_mode4(vdp_context * context)
235 { 235 {
236 if (context->cur_slot >= context->sprite_draws) { 236 if (context->sprite_index >= context->sprite_draws) {
237 sprite_draw * d = context->sprite_draw_list + context->cur_slot; 237 sprite_draw * d = context->sprite_draw_list + context->sprite_index;
238 uint32_t pixels = planar_to_chunky[context->fetch_tmp[0]] << 1; 238 uint32_t pixels = planar_to_chunky[context->fetch_tmp[0]] << 1;
239 pixels |= planar_to_chunky[context->fetch_tmp[1]]; 239 pixels |= planar_to_chunky[context->fetch_tmp[1]];
240 uint32_t address = mode4_address_map[(d->address + 2) & 0x3FFF]; 240 uint32_t address = mode4_address_map[(d->address + 2) & 0x3FFF];
241 pixels |= planar_to_chunky[context->vdpmem[address]] << 3; 241 pixels |= planar_to_chunky[context->vdpmem[address]] << 3;
242 pixels |= planar_to_chunky[context->vdpmem[address + 1]] << 2; 242 pixels |= planar_to_chunky[context->vdpmem[address + 1]] << 2;
247 context->flags2 |= FLAG2_SPRITE_COLLIDE; 247 context->flags2 |= FLAG2_SPRITE_COLLIDE;
248 } else { 248 } else {
249 context->linebuf[x] = pixels >> i & 0xF; 249 context->linebuf[x] = pixels >> i & 0xF;
250 } 250 }
251 } 251 }
252 context->cur_slot--; 252 context->sprite_index--;
253 } 253 }
254 } 254 }
255 255
256 void vdp_print_sprite_table(vdp_context * context) 256 void vdp_print_sprite_table(vdp_context * context)
257 { 257 {
461 context->sprite_index = context->sat_cache[address+3] & 0x7F; 461 context->sprite_index = context->sat_cache[address+3] & 0x7F;
462 } 462 }
463 } 463 }
464 } 464 }
465 465
466 static void scan_sprite_table_mode4(uint32_t line, vdp_context * context) 466 static void scan_sprite_table_mode4(vdp_context * context)
467 { 467 {
468 if (context->sprite_index < MAX_SPRITES_FRAME_H32 && context->slot_counter) { 468 if (context->sprite_index < MAX_SPRITES_FRAME_H32) {
469 line += 1; 469 uint32_t line = context->vcounter + 1;
470 line &= 0xFF; 470 line &= 0xFF;
471 471
472 uint32_t y = context->sat_cache[context->sprite_index]; 472 uint32_t sat_address = mode4_address_map[(context->regs[REG_SAT] << 7 & 0x3F00) + context->sprite_index];
473 uint32_t y = context->vdpmem[sat_address];
473 uint32_t size = (context->regs[REG_MODE_2] & BIT_SPRITE_SZ) ? 16 : 8; 474 uint32_t size = (context->regs[REG_MODE_2] & BIT_SPRITE_SZ) ? 16 : 8;
474 475
475 if (y >= 0xd0) { 476 if (y >= 0xd0) {
476 context->sprite_index = MAX_SPRITES_FRAME_H32; 477 context->sprite_index = MAX_SPRITES_FRAME_H32;
477 return; 478 return;
478 } else { 479 } else {
479 if (y <= line && line < (y + size)) { 480 if (y <= line && line < (y + size)) {
481 if (!context->slot_counter) {
482 context->sprite_index = MAX_SPRITES_FRAME_H32;
483 context->flags |= FLAG_DOT_OFLOW;
484 return;
485 }
480 context->sprite_info_list[--(context->slot_counter)].size = size; 486 context->sprite_info_list[--(context->slot_counter)].size = size;
481 context->sprite_info_list[context->slot_counter].index = context->sprite_index; 487 context->sprite_info_list[context->slot_counter].index = context->sprite_index;
482 context->sprite_info_list[context->slot_counter].y = y; 488 context->sprite_info_list[context->slot_counter].y = y;
483 } 489 }
484 context->sprite_index++; 490 context->sprite_index++;
485 } 491 }
486 492
487 if (context->sprite_index < MAX_SPRITES_FRAME_H32 && context->slot_counter) { 493 if (context->sprite_index < MAX_SPRITES_FRAME_H32) {
488 y = context->sat_cache[context->sprite_index]; 494 y = context->vdpmem[sat_address+1];
489 if (y >= 0xd0) { 495 if (y >= 0xd0) {
490 context->sprite_index = MAX_SPRITES_FRAME_H32; 496 context->sprite_index = MAX_SPRITES_FRAME_H32;
491 return; 497 return;
492 } else { 498 } else {
493 if (y <= line && line < (y + size)) { 499 if (y <= line && line < (y + size)) {
500 if (!context->slot_counter) {
501 context->sprite_index = MAX_SPRITES_FRAME_H32;
502 context->flags |= FLAG_DOT_OFLOW;
503 return;
504 }
494 context->sprite_info_list[--(context->slot_counter)].size = size; 505 context->sprite_info_list[--(context->slot_counter)].size = size;
495 context->sprite_info_list[context->slot_counter].index = context->sprite_index; 506 context->sprite_info_list[context->slot_counter].index = context->sprite_index;
496 context->sprite_info_list[context->slot_counter].y = y; 507 context->sprite_info_list[context->slot_counter].y = y;
497 } 508 }
498 context->sprite_index++; 509 context->sprite_index++;
577 context->flags |= FLAG_DOT_OFLOW; 588 context->flags |= FLAG_DOT_OFLOW;
578 } 589 }
579 } 590 }
580 } 591 }
581 592
582 static void read_sprite_x_mode4(uint32_t line, vdp_context * context) 593 static void read_sprite_x_mode4(vdp_context * context)
583 { 594 {
584 if (context->cur_slot >= context->slot_counter) { 595 if (context->cur_slot >= context->slot_counter) {
585 if (context->sprite_draws) { 596 uint32_t address = (context->regs[REG_SAT] << 7 & 0x3F00) + 0x80 + context->sprite_info_list[context->cur_slot].index * 2;
586 line += 1; 597 address = mode4_address_map[address];
587 line &= 0xFF; 598 --context->sprite_draws;
588 599 uint32_t tile_address = context->vdpmem[address] * 32 + (context->regs[REG_STILE_BASE] << 11 & 0x2000);
589 uint32_t address = (context->regs[REG_SAT] << 7 & 0x3F00) + 0x80 + context->sprite_info_list[context->cur_slot].index * 2; 600 if (context->regs[REG_MODE_2] & BIT_SPRITE_SZ) {
590 address = mode4_address_map[address]; 601 tile_address &= ~32;
591 --context->sprite_draws; 602 }
592 uint32_t tile_address = context->vdpmem[address] * 32 + (context->regs[REG_STILE_BASE] << 11 & 0x2000); 603 tile_address += (context->vcounter - context->sprite_info_list[context->cur_slot].y)* 4;
593 if (context->regs[REG_MODE_2] & BIT_SPRITE_SZ) { 604 context->sprite_draw_list[context->sprite_draws].x_pos = context->vdpmem[address + 1];
594 tile_address &= ~32; 605 context->sprite_draw_list[context->sprite_draws].address = tile_address;
595 } 606 context->cur_slot--;
596 tile_address += (line - context->sprite_info_list[context->cur_slot].y)* 4;
597 context->sprite_draw_list[context->sprite_draws].x_pos = context->vdpmem[address + 1];
598 context->sprite_draw_list[context->sprite_draws].address = tile_address;
599 context->cur_slot--;
600 } else {
601 context->flags |= FLAG_DOT_OFLOW;
602 }
603 } 607 }
604 } 608 }
605 609
606 #define CRAM_BITS 0xEEE 610 #define CRAM_BITS 0xEEE
607 #define VSRAM_BITS 0x7FF 611 #define VSRAM_BITS 0x7FF
649 cache_address = (cache_address & 3) | (cache_address >> 1 & 0x1FC); 653 cache_address = (cache_address & 3) | (cache_address >> 1 & 0x1FC);
650 context->sat_cache[cache_address] = value; 654 context->sat_cache[cache_address] = value;
651 } 655 }
652 } 656 }
653 } else { 657 } else {
654 if (!(address & 0xC0)) {
655 uint16_t sat_address = context->regs[REG_SAT] << 7 & 0x3F00;
656 if (address >= sat_address && address < (sat_address + 0x40)) {
657 context->sat_cache[address-sat_address] = value;
658 }
659 }
660 address = mode4_address_map[address & 0x3FFF]; 658 address = mode4_address_map[address & 0x3FFF];
661 } 659 }
662 context->vdpmem[address] = value; 660 context->vdpmem[address] = value;
663 } 661 }
664 662
1427 #define COLUMN_RENDER_BLOCK_MODE4(column, startcyc) \ 1425 #define COLUMN_RENDER_BLOCK_MODE4(column, startcyc) \
1428 case startcyc:\ 1426 case startcyc:\
1429 read_map_mode4(column, context->vcounter, context);\ 1427 read_map_mode4(column, context->vcounter, context);\
1430 CHECK_LIMIT\ 1428 CHECK_LIMIT\
1431 case ((startcyc+1)&0xFF):\ 1429 case ((startcyc+1)&0xFF):\
1432 if (column & 1) {\ 1430 if (column & 3) {\
1433 read_sprite_x_mode4(context->vcounter, context);\ 1431 scan_sprite_table_mode4(context);\
1434 } else {\ 1432 } else {\
1435 external_slot(context);\ 1433 external_slot(context);\
1436 }\ 1434 }\
1437 CHECK_LIMIT\ 1435 CHECK_LIMIT\
1438 case ((startcyc+2)&0xFF):\ 1436 case ((startcyc+2)&0xFF):\
1439 fetch_map_mode4(column, context->vcounter, context);\ 1437 fetch_map_mode4(column, context->vcounter, context);\
1440 CHECK_LIMIT\ 1438 CHECK_LIMIT\
1441 case ((startcyc+3)&0xFF):\ 1439 case ((startcyc+3)&0xFF):\
1442 render_map_mode4(context->vcounter, column, context);\
1443 CHECK_LIMIT
1444
1445 #define COLUMN_RENDER_BLOCK_REFRESH_MODE4(column, startcyc) \
1446 case startcyc:\
1447 read_map_mode4(column, context->vcounter, context);\
1448 CHECK_LIMIT\
1449 case (startcyc+1):\
1450 /* refresh, no don't run dma src */\
1451 context->hslot++;\
1452 context->cycles += slot_cycles;\
1453 CHECK_ONLY\
1454 case (startcyc+2):\
1455 fetch_map_mode4(column, context->vcounter, context);\
1456 CHECK_LIMIT\
1457 case (startcyc+3):\
1458 render_map_mode4(context->vcounter, column, context);\ 1440 render_map_mode4(context->vcounter, column, context);\
1459 CHECK_LIMIT 1441 CHECK_LIMIT
1460 1442
1461 #define SPRITE_RENDER_H40(slot) \ 1443 #define SPRITE_RENDER_H40(slot) \
1462 case slot:\ 1444 case slot:\
1489 context->cycles += slot_cycles;\ 1471 context->cycles += slot_cycles;\
1490 CHECK_ONLY 1472 CHECK_ONLY
1491 1473
1492 #define SPRITE_RENDER_H32_MODE4(slot) \ 1474 #define SPRITE_RENDER_H32_MODE4(slot) \
1493 case slot:\ 1475 case slot:\
1476 read_sprite_x_mode4(context);\
1477 CHECK_LIMIT\
1478 case (slot+1):\
1479 read_sprite_x_mode4(context);\
1480 CHECK_LIMIT\
1481 case (slot+2):\
1494 fetch_sprite_cells_mode4(context);\ 1482 fetch_sprite_cells_mode4(context);\
1495 scan_sprite_table(context->vcounter, context);\ 1483 CHECK_LIMIT\
1496 if (context->flags & FLAG_DMA_RUN) { run_dma_src(context, -1); } \ 1484 case (slot+3):\
1497 if (slot == 147) {\
1498 context->hslot = 233;\
1499 } else {\
1500 context->hslot++;\
1501 }\
1502 context->cycles += slot_cycles;\
1503 CHECK_ONLY\
1504 case (slot == 147 ? 233 : slot+1):\
1505 render_sprite_cells_mode4(context);\ 1485 render_sprite_cells_mode4(context);\
1506 scan_sprite_table(context->vcounter, context);\ 1486 CHECK_LIMIT\
1507 if (context->flags & FLAG_DMA_RUN) { run_dma_src(context, -1); } \ 1487 case (slot+4):\
1508 if ((slot+1) == 147) {\ 1488 fetch_sprite_cells_mode4(context);\
1509 context->hslot = 233;\ 1489 CHECK_LIMIT\
1510 } else {\ 1490 case (slot+5):\
1511 context->hslot++;\ 1491 render_sprite_cells_mode4(context);\
1512 }\ 1492 CHECK_LIMIT
1513 context->cycles += slot_cycles;\
1514 CHECK_ONLY
1515 1493
1516 static void vdp_h40(vdp_context * context, uint32_t target_cycles) 1494 static void vdp_h40(vdp_context * context, uint32_t target_cycles)
1517 { 1495 {
1518 uint16_t address; 1496 uint16_t address;
1519 uint32_t mask; 1497 uint32_t mask;
1826 uint32_t const slot_cycles = MCLKS_SLOT_H32; 1804 uint32_t const slot_cycles = MCLKS_SLOT_H32;
1827 switch(context->hslot) 1805 switch(context->hslot)
1828 { 1806 {
1829 for (;;) 1807 for (;;)
1830 { 1808 {
1831 //sprite attribute table scan starts
1832 case 132: 1809 case 132:
1833 context->sprite_index = 0x80; 1810 external_slot(context);
1834 //in theory, Mode 4 should only allow 8 sprites per line, but if we assume that thee
1835 //Genesis VDP uses the SAT cache for sprite scans in Mode 4 like it does in Mode 5,
1836 //there should be enough bandwidth for 16 like in Mode 5 (though only 128 pixels rather than 256)
1837 context->slot_counter = MAX_SPRITES_LINE_H32;
1838 fetch_sprite_cells_mode4(context);
1839 scan_sprite_table_mode4(context->vcounter, context);
1840 CHECK_LIMIT 1811 CHECK_LIMIT
1841 case 133: 1812 case 133:
1842 render_sprite_cells_mode4(context); 1813 external_slot(context);
1843 scan_sprite_table_mode4(context->vcounter, context); 1814 //set things up for sprite rendering in the next slot
1844 CHECK_LIMIT 1815 memset(context->linebuf, 0, LINEBUF_SIZE);
1816 context->cur_slot = context->sprite_index = MAX_DRAWS_H32_MODE4-1;
1817 context->sprite_draws = MAX_DRAWS_H32_MODE4;
1818 CHECK_LIMIT
1819 //sprite rendering starts
1845 SPRITE_RENDER_H32_MODE4(134) 1820 SPRITE_RENDER_H32_MODE4(134)
1846 SPRITE_RENDER_H32_MODE4(136)
1847 SPRITE_RENDER_H32_MODE4(138)
1848 SPRITE_RENDER_H32_MODE4(140) 1821 SPRITE_RENDER_H32_MODE4(140)
1849 case 142: 1822 case 146:
1850 external_slot(context); 1823 external_slot(context);
1851 CHECK_LIMIT 1824 CHECK_LIMIT
1852 SPRITE_RENDER_H32_MODE4(143) 1825 case 147:
1853 SPRITE_RENDER_H32_MODE4(145) 1826 external_slot(context);
1854 SPRITE_RENDER_H32_MODE4(147) 1827 CHECK_LIMIT
1855 //HSYNC start @233 1828 //!HSYNC low
1856 SPRITE_RENDER_H32_MODE4(234) 1829 case 233:
1830 external_slot(context);
1831 CHECK_LIMIT
1832 case 234:
1833 external_slot(context);
1834 CHECK_LIMIT
1835 case 235:
1836 external_slot(context);
1837 CHECK_LIMIT
1857 SPRITE_RENDER_H32_MODE4(236) 1838 SPRITE_RENDER_H32_MODE4(236)
1858 SPRITE_RENDER_H32_MODE4(238) 1839 SPRITE_RENDER_H32_MODE4(242)
1859 case 240: 1840 case 248:
1860 external_slot(context); 1841 external_slot(context);
1861 CHECK_LIMIT 1842 CHECK_LIMIT
1862 case 241: 1843 case 249:
1844 external_slot(context);
1863 if (context->regs[REG_MODE_1] & BIT_HSCRL_LOCK && context->vcounter < 16) { 1845 if (context->regs[REG_MODE_1] & BIT_HSCRL_LOCK && context->vcounter < 16) {
1864 context->hscroll_a = 0; 1846 context->hscroll_a = 0;
1865 } else { 1847 } else {
1866 context->hscroll_a = context->regs[REG_X_SCROLL]; 1848 context->hscroll_a = context->regs[REG_X_SCROLL];
1867 } 1849 }
1868 CHECK_LIMIT 1850 CHECK_LIMIT
1869 SPRITE_RENDER_H32_MODE4(242)
1870 SPRITE_RENDER_H32_MODE4(244)
1871 //!HSYNC high
1872 case 246:
1873 external_slot(context);
1874 CHECK_LIMIT
1875 case 247:
1876 fetch_sprite_cells_mode4(context);
1877 scan_sprite_table_mode4(context->vcounter, context);
1878 CHECK_LIMIT
1879 case 248:
1880 external_slot(context);
1881 scan_sprite_table_mode4(context->vcounter, context);//Just a guess
1882 CHECK_LIMIT
1883 case 249:
1884 external_slot(context);
1885 scan_sprite_table_mode4(context->vcounter, context);//Just a guess
1886 CHECK_LIMIT
1887 case 250: 1851 case 250:
1888 external_slot(context); 1852 context->sprite_index = 0;
1853 context->slot_counter = MAX_DRAWS_H32_MODE4;
1854 scan_sprite_table_mode4(context);
1889 CHECK_LIMIT 1855 CHECK_LIMIT
1890 case 251: 1856 case 251:
1891 render_sprite_cells_mode4(context); 1857 scan_sprite_table_mode4(context);
1892 scan_sprite_table_mode4(context->vcounter, context);
1893 CHECK_LIMIT 1858 CHECK_LIMIT
1894 case 252: 1859 case 252:
1895 external_slot(context); 1860 scan_sprite_table_mode4(context);
1896 scan_sprite_table_mode4(context->vcounter, context);//Just a guess
1897 CHECK_LIMIT 1861 CHECK_LIMIT
1898 case 253: 1862 case 253:
1899 external_slot(context); 1863 scan_sprite_table_mode4(context);
1900 scan_sprite_table_mode4(context->vcounter, context);//Just a guess 1864 CHECK_LIMIT
1865 case 254:
1866 scan_sprite_table_mode4(context);
1867 CHECK_LIMIT
1868 case 255:
1869 scan_sprite_table_mode4(context);
1870 CHECK_LIMIT
1871 case 0:
1872 scan_sprite_table_mode4(context);
1873 CHECK_LIMIT
1874 case 1:
1875 scan_sprite_table_mode4(context);
1901 context->buf_a_off = 8; 1876 context->buf_a_off = 8;
1902 memset(context->tmp_buf_a, 0, 8); 1877 memset(context->tmp_buf_a, 0, 8);
1903 //reverse context slot counter so it counts the number of sprite slots 1878 CHECK_LIMIT
1904 //filled rather than the number of available slots 1879 COLUMN_RENDER_BLOCK_MODE4(0, 2)
1905 //context->slot_counter = MAX_SPRITES_LINE - context->slot_counter; 1880 COLUMN_RENDER_BLOCK_MODE4(1, 6)
1906 context->cur_slot = MAX_SPRITES_LINE_H32-1; 1881 COLUMN_RENDER_BLOCK_MODE4(2, 10)
1907 context->sprite_draws = MAX_DRAWS_H32_MODE4; 1882 COLUMN_RENDER_BLOCK_MODE4(3, 14)
1908 context->flags &= (~FLAG_CAN_MASK & ~FLAG_MASKED); 1883 COLUMN_RENDER_BLOCK_MODE4(4, 18)
1909 CHECK_LIMIT 1884 COLUMN_RENDER_BLOCK_MODE4(5, 22)
1910 COLUMN_RENDER_BLOCK_MODE4(0, 254) 1885 COLUMN_RENDER_BLOCK_MODE4(6, 26)
1911 COLUMN_RENDER_BLOCK_MODE4(1, 2) 1886 COLUMN_RENDER_BLOCK_MODE4(7, 30)
1912 COLUMN_RENDER_BLOCK_MODE4(2, 6) 1887 COLUMN_RENDER_BLOCK_MODE4(8, 34)
1913 COLUMN_RENDER_BLOCK_MODE4(3, 10) 1888 COLUMN_RENDER_BLOCK_MODE4(9, 38)
1914 COLUMN_RENDER_BLOCK_MODE4(4, 14) 1889 COLUMN_RENDER_BLOCK_MODE4(10, 42)
1915 COLUMN_RENDER_BLOCK_MODE4(5, 18) 1890 COLUMN_RENDER_BLOCK_MODE4(11, 46)
1916 COLUMN_RENDER_BLOCK_REFRESH_MODE4(6, 22) 1891 COLUMN_RENDER_BLOCK_MODE4(12, 50)
1917 COLUMN_RENDER_BLOCK_MODE4(7, 26) 1892 COLUMN_RENDER_BLOCK_MODE4(13, 54)
1918 COLUMN_RENDER_BLOCK_MODE4(8, 30) 1893 COLUMN_RENDER_BLOCK_MODE4(14, 58)
1919 COLUMN_RENDER_BLOCK_MODE4(9, 34) 1894 COLUMN_RENDER_BLOCK_MODE4(15, 62)
1920 COLUMN_RENDER_BLOCK_MODE4(10, 38) 1895 COLUMN_RENDER_BLOCK_MODE4(16, 66)
1921 COLUMN_RENDER_BLOCK_MODE4(11, 42) 1896 COLUMN_RENDER_BLOCK_MODE4(17, 70)
1922 COLUMN_RENDER_BLOCK_MODE4(12, 46) 1897 COLUMN_RENDER_BLOCK_MODE4(18, 74)
1923 COLUMN_RENDER_BLOCK_MODE4(13, 50) 1898 COLUMN_RENDER_BLOCK_MODE4(19, 78)
1924 COLUMN_RENDER_BLOCK_REFRESH_MODE4(14, 54) 1899 COLUMN_RENDER_BLOCK_MODE4(20, 82)
1925 COLUMN_RENDER_BLOCK_MODE4(15, 58) 1900 COLUMN_RENDER_BLOCK_MODE4(21, 86)
1926 COLUMN_RENDER_BLOCK_MODE4(16, 62) 1901 COLUMN_RENDER_BLOCK_MODE4(22, 90)
1927 COLUMN_RENDER_BLOCK_MODE4(17, 66) 1902 COLUMN_RENDER_BLOCK_MODE4(23, 94)
1928 COLUMN_RENDER_BLOCK_MODE4(18, 70) 1903 COLUMN_RENDER_BLOCK_MODE4(24, 98)
1929 COLUMN_RENDER_BLOCK_MODE4(19, 74) 1904 COLUMN_RENDER_BLOCK_MODE4(25, 102)
1930 COLUMN_RENDER_BLOCK_MODE4(20, 78) 1905 COLUMN_RENDER_BLOCK_MODE4(26, 106)
1931 COLUMN_RENDER_BLOCK_MODE4(21, 82) 1906 COLUMN_RENDER_BLOCK_MODE4(27, 110)
1932 COLUMN_RENDER_BLOCK_REFRESH_MODE4(22, 86) 1907 COLUMN_RENDER_BLOCK_MODE4(28, 114)
1933 COLUMN_RENDER_BLOCK_MODE4(23, 90) 1908 COLUMN_RENDER_BLOCK_MODE4(29, 118)
1934 COLUMN_RENDER_BLOCK_MODE4(24, 94) 1909 COLUMN_RENDER_BLOCK_MODE4(30, 122)
1935 COLUMN_RENDER_BLOCK_MODE4(25, 98) 1910 COLUMN_RENDER_BLOCK_MODE4(31, 126)
1936 COLUMN_RENDER_BLOCK_MODE4(26, 102) 1911 case 130:
1937 COLUMN_RENDER_BLOCK_MODE4(27, 106)
1938 COLUMN_RENDER_BLOCK_MODE4(28, 110)
1939 COLUMN_RENDER_BLOCK_MODE4(29, 114)
1940 COLUMN_RENDER_BLOCK_REFRESH_MODE4(30, 118)
1941 COLUMN_RENDER_BLOCK_MODE4(31, 122)
1942 case 126:
1943 external_slot(context); 1912 external_slot(context);
1944 CHECK_LIMIT 1913 CHECK_LIMIT
1945 case 127: 1914 case 131:
1946 external_slot(context); 1915 external_slot(context);
1947 CHECK_LIMIT
1948 //sprite render to line buffer starts
1949 case 128:
1950 context->cur_slot = MAX_DRAWS_H32_MODE4-1;
1951 memset(context->linebuf, 0, LINEBUF_SIZE);
1952 fetch_sprite_cells_mode4(context);
1953 CHECK_LIMIT
1954 case 129:
1955 render_sprite_cells_mode4(context);
1956 CHECK_LIMIT
1957 case 130:
1958 fetch_sprite_cells_mode4(context);
1959 CHECK_LIMIT
1960 case 131:
1961 render_sprite_cells_mode4(context);
1962 vdp_advance_line(context); 1916 vdp_advance_line(context);
1963 if (context->vcounter == MODE4_INACTIVE_START) { 1917 if (context->vcounter == MODE4_INACTIVE_START) {
1964 context->hslot++; 1918 context->hslot++;
1965 context->cycles += slot_cycles; 1919 context->cycles += slot_cycles;
1966 return; 1920 return;