comparison vdp.c @ 647:5d58dcd94733

Fix the HV counter and adjust the slots of certain VDP events
author Michael Pavone <pavone@retrodev.com>
date Sun, 14 Dec 2014 18:14:50 -0800
parents 9089951a1994
children a7971650c04e
comparison
equal deleted inserted replaced
646:fa345ce3e5bd 647:5d58dcd94733
25 #define VINT_SLOT_H40 4 //21 slots before HSYNC, 16 during, 10 after 25 #define VINT_SLOT_H40 4 //21 slots before HSYNC, 16 during, 10 after
26 #define VINT_SLOT_H32 23 //33 slots before HSYNC, 20 during, 7 after TODO: confirm final number 26 #define VINT_SLOT_H32 23 //33 slots before HSYNC, 20 during, 7 after TODO: confirm final number
27 #define HSYNC_SLOT_H40 240 27 #define HSYNC_SLOT_H40 240
28 #define HSYNC_END_H40 (240+17) 28 #define HSYNC_END_H40 (240+17)
29 #define HSYNC_END_H32 (33 * MCLKS_SLOT_H32) 29 #define HSYNC_END_H32 (33 * MCLKS_SLOT_H32)
30 #define HBLANK_START_H40 167 30 #define HBLANK_START_H40 178 //should be 179 according to Nemesis, but 178 seems to fit slightly better with my test ROM results
31 #define HBLANK_END_H40 11 //should be 10.25 according to Nemesis IIRC 31 #define HBLANK_END_H40 0 //should be 5.5 according to Nemesis, but 0 seems to fit better with my test ROM results
32 #define HBLANK_START_H32 134 32 #define HBLANK_START_H32 233 //should be 147 according to Nemesis which is very different from my test ROM result
33 #define HBLANK_END_H32 8 //should be 7.5 according to Nemesis IIRC 33 #define HBLANK_END_H32 0 //should be 5 according to Nemesis, but 0 seems to fit better with my test ROM results
34 #define LINE_CHANGE_H40 165
35 #define LINE_CHANGE_H32 132
34 #define FIFO_LATENCY 3 36 #define FIFO_LATENCY 3
35 37
36 int32_t color_map[1 << 12]; 38 int32_t color_map[1 << 12];
37 uint8_t levels[] = {0, 27, 49, 71, 87, 103, 119, 130, 146, 157, 174, 190, 206, 228, 255}; 39 uint8_t levels[] = {0, 27, 49, 71, 87, 103, 119, 130, 146, 157, 174, 190, 206, 228, 255};
38 40
258 context->regs[REG_DMASRC_H] << 17 | context->regs[REG_DMASRC_M] << 9 | context->regs[REG_DMASRC_L] << 1, 260 context->regs[REG_DMASRC_H] << 17 | context->regs[REG_DMASRC_M] << 9 | context->regs[REG_DMASRC_L] << 1,
259 src_types[context->regs[REG_DMASRC_H] >> 6 & 3]); 261 src_types[context->regs[REG_DMASRC_H] >> 6 & 3]);
260 printf("\n**Internal Group**\n" 262 printf("\n**Internal Group**\n"
261 "Address: %X\n" 263 "Address: %X\n"
262 "CD: %X\n" 264 "CD: %X\n"
263 "Pending: %s\n", 265 "Pending: %s\n"
264 context->address, context->cd, (context->flags & FLAG_PENDING) ? "true" : "false"); 266 "VCounter: %d\n"
267 "HCounter: %d\n",
268 context->address, context->cd, (context->flags & FLAG_PENDING) ? "true" : "false",
269 context->vcounter, context->hslot*2);
265 270
266 //TODO: Window Group, DMA Group 271 //TODO: Window Group, DMA Group
267 } 272 }
268 273
269 void scan_sprite_table(uint32_t line, vdp_context * context) 274 void scan_sprite_table(uint32_t line, vdp_context * context)
909 { 914 {
910 uint16_t address; 915 uint16_t address;
911 uint32_t mask; 916 uint32_t mask;
912 switch(linecyc) 917 switch(linecyc)
913 { 918 {
919 case 165:
920 case 166:
921 external_slot(context);
922 break;
914 //sprite render to line buffer starts 923 //sprite render to line buffer starts
915 case 167: 924 case 167:
916 context->cur_slot = MAX_DRAWS-1;
917 memset(context->linebuf, 0, LINEBUF_SIZE);
918 case 168: 925 case 168:
919 case 169: 926 case 169:
920 case 170: 927 case 170:
921 if (line == 0xFF) { 928 if (line == 0xFF) {
922 external_slot(context); 929 external_slot(context);
925 } 932 }
926 break; 933 break;
927 //sprite attribute table scan starts 934 //sprite attribute table scan starts
928 case 171: 935 case 171:
929 render_sprite_cells( context); 936 render_sprite_cells( context);
930 context->sprite_index = 0x80;
931 context->slot_counter = MAX_SPRITES_LINE;
932 scan_sprite_table(line, context); 937 scan_sprite_table(line, context);
933 break; 938 break;
934 case 172: 939 case 172:
935 case 173: 940 case 173:
936 case 174: 941 case 174:
1047 COLUMN_RENDER_BLOCK_REFRESH(32, 125) 1052 COLUMN_RENDER_BLOCK_REFRESH(32, 125)
1048 COLUMN_RENDER_BLOCK(34, 133) 1053 COLUMN_RENDER_BLOCK(34, 133)
1049 COLUMN_RENDER_BLOCK(36, 141) 1054 COLUMN_RENDER_BLOCK(36, 141)
1050 COLUMN_RENDER_BLOCK(38, 149) 1055 COLUMN_RENDER_BLOCK(38, 149)
1051 COLUMN_RENDER_BLOCK_REFRESH(40, 157) 1056 COLUMN_RENDER_BLOCK_REFRESH(40, 157)
1052 case 165:
1053 case 166:
1054 external_slot(context);
1055 break;
1056 } 1057 }
1057 } 1058 }
1058 1059
1059 void vdp_h32(uint32_t line, uint32_t linecyc, vdp_context * context) 1060 void vdp_h32(uint32_t line, uint32_t linecyc, vdp_context * context)
1060 { 1061 {
1061 uint16_t address; 1062 uint16_t address;
1062 uint32_t mask; 1063 uint32_t mask;
1063 switch(linecyc) 1064 switch(linecyc)
1064 { 1065 {
1066 case 132:
1067 case 133:
1068 external_slot(context);
1069 break;
1065 //sprite render to line buffer starts 1070 //sprite render to line buffer starts
1066 case 134: 1071 case 134:
1067 context->cur_slot = MAX_DRAWS_H32-1;
1068 memset(context->linebuf, 0, LINEBUF_SIZE);
1069 case 135: 1072 case 135:
1070 case 136: 1073 case 136:
1071 case 137: 1074 case 137:
1072 if (line == 0xFF) { 1075 if (line == 0xFF) {
1073 external_slot(context); 1076 external_slot(context);
1076 } 1079 }
1077 break; 1080 break;
1078 //sprite attribute table scan starts 1081 //sprite attribute table scan starts
1079 case 138: 1082 case 138:
1080 render_sprite_cells( context); 1083 render_sprite_cells( context);
1081 context->sprite_index = 0x80;
1082 context->slot_counter = MAX_SPRITES_LINE_H32;
1083 scan_sprite_table(line, context); 1084 scan_sprite_table(line, context);
1084 break; 1085 break;
1085 case 139: 1086 case 139:
1086 case 140: 1087 case 140:
1087 case 141: 1088 case 141:
1188 COLUMN_RENDER_BLOCK_REFRESH(24, 92) 1189 COLUMN_RENDER_BLOCK_REFRESH(24, 92)
1189 COLUMN_RENDER_BLOCK(26, 100) 1190 COLUMN_RENDER_BLOCK(26, 100)
1190 COLUMN_RENDER_BLOCK(28, 108) 1191 COLUMN_RENDER_BLOCK(28, 108)
1191 COLUMN_RENDER_BLOCK(30, 116) 1192 COLUMN_RENDER_BLOCK(30, 116)
1192 COLUMN_RENDER_BLOCK_REFRESH(32, 124) 1193 COLUMN_RENDER_BLOCK_REFRESH(32, 124)
1193 case 132:
1194 case 133:
1195 external_slot(context);
1196 break;
1197 } 1194 }
1198 } 1195 }
1199 1196
1200 void vdp_h40_line(uint32_t line, vdp_context * context) 1197 void vdp_h40_line(uint32_t line, vdp_context * context)
1201 { 1198 {
1202 context->cur_slot = MAX_DRAWS-1; 1199 context->cur_slot = MAX_DRAWS-1;
1203 memset(context->linebuf, 0, LINEBUF_SIZE); 1200 memset(context->linebuf, 0, LINEBUF_SIZE);
1204 if (line == 0xFF) { 1201 if (line == 0xFF) {
1202 external_slot(context);
1203 if (context->flags & FLAG_DMA_RUN) {
1204 run_dma_src(context, 0);
1205 }
1206 external_slot(context);
1207 if (context->flags & FLAG_DMA_RUN) {
1208 run_dma_src(context, 0);
1209 }
1205 external_slot(context); 1210 external_slot(context);
1206 if (context->flags & FLAG_DMA_RUN) { 1211 if (context->flags & FLAG_DMA_RUN) {
1207 run_dma_src(context, 0); 1212 run_dma_src(context, 0);
1208 } 1213 }
1209 external_slot(context); 1214 external_slot(context);
1253 } 1258 }
1254 read_sprite_x(line, context); 1259 read_sprite_x(line, context);
1255 1260
1256 read_sprite_x(line, context); 1261 read_sprite_x(line, context);
1257 } 1262 }
1258 external_slot(context); 1263
1259 if (context->flags & FLAG_DMA_RUN) {
1260 run_dma_src(context, 0);
1261 }
1262 external_slot(context);
1263 return; 1264 return;
1265 }
1266 external_slot(context);
1267 if (context->flags & FLAG_DMA_RUN) {
1268 run_dma_src(context, 0);
1269 }
1270 external_slot(context);
1271 if (context->flags & FLAG_DMA_RUN) {
1272 run_dma_src(context, 0);
1264 } 1273 }
1265 1274
1266 render_sprite_cells(context); 1275 render_sprite_cells(context);
1267 render_sprite_cells(context); 1276 render_sprite_cells(context);
1268 render_sprite_cells(context); 1277 render_sprite_cells(context);
1369 read_map_scroll_b(column, line, context); 1378 read_map_scroll_b(column, line, context);
1370 read_sprite_x(line, context); 1379 read_sprite_x(line, context);
1371 render_map_3(context); 1380 render_map_3(context);
1372 render_map_output(line, column, context); 1381 render_map_output(line, column, context);
1373 } 1382 }
1374 external_slot(context);
1375 if (context->flags & FLAG_DMA_RUN) {
1376 run_dma_src(context, 0);
1377 }
1378 external_slot(context);
1379 } 1383 }
1380 1384
1381 void latch_mode(vdp_context * context) 1385 void latch_mode(vdp_context * context)
1382 { 1386 {
1383 context->latched_mode = context->regs[REG_MODE_2] & BIT_PAL; 1387 context->latched_mode = context->regs[REG_MODE_2] & BIT_PAL;
1428 uint32_t slot = context->hslot; 1432 uint32_t slot = context->hslot;
1429 //TODO: Figure out when this actually happens 1433 //TODO: Figure out when this actually happens
1430 if (!line && !slot) { 1434 if (!line && !slot) {
1431 latch_mode(context); 1435 latch_mode(context);
1432 } 1436 }
1437
1433 uint8_t is_h40 = context->regs[REG_MODE_4] & BIT_H40; 1438 uint8_t is_h40 = context->regs[REG_MODE_4] & BIT_H40;
1434 if (is_h40 && slot == HBLANK_START_H40 || !is_h40 && slot == 134) { 1439 if (is_h40) {
1440 if (slot == 167) {
1441 context->cur_slot = MAX_DRAWS-1;
1442 memset(context->linebuf, 0, LINEBUF_SIZE);
1443 } else if (slot == 171) {
1444 context->sprite_index = 0x80;
1445 context->slot_counter = MAX_SPRITES_LINE;
1446 }
1447 } else {
1448 if (slot == 134) {
1449 context->cur_slot = MAX_DRAWS_H32-1;
1450 memset(context->linebuf, 0, LINEBUF_SIZE);
1451 } else if (slot == 138) {
1452 context->sprite_index = 0x80;
1453 context->slot_counter = MAX_SPRITES_LINE_H32;
1454 }
1455 }
1456 if (is_h40 && slot == LINE_CHANGE_H40 || !is_h40 && slot == LINE_CHANGE_H32) {
1435 if (line >= inactive_start) { 1457 if (line >= inactive_start) {
1436 context->hint_counter = context->regs[REG_HINT]; 1458 context->hint_counter = context->regs[REG_HINT];
1437 } else if (context->hint_counter) { 1459 } else if (context->hint_counter) {
1438 context->hint_counter--; 1460 context->hint_counter--;
1439 } else { 1461 } else {
1468 } 1490 }
1469 uint8_t inc_slot = 1; 1491 uint8_t inc_slot = 1;
1470 if (context->regs[REG_MODE_2] & DISPLAY_ENABLE && active_slot) { 1492 if (context->regs[REG_MODE_2] & DISPLAY_ENABLE && active_slot) {
1471 //run VDP rendering for a slot or a line 1493 //run VDP rendering for a slot or a line
1472 if (is_h40) { 1494 if (is_h40) {
1473 if (slot == HBLANK_START_H40 && line < inactive_start && (target_cycles - context->cycles) >= MCLKS_LINE) { 1495 if (slot == LINE_CHANGE_H40 && line < inactive_start && (target_cycles - context->cycles) >= MCLKS_LINE) {
1474 vdp_h40_line(line, context); 1496 vdp_h40_line(line, context);
1475 inccycles = MCLKS_LINE; 1497 inccycles = MCLKS_LINE;
1476 context->vcounter++; 1498 context->vcounter++;
1477 inc_slot = 0; 1499 inc_slot = 0;
1478 } else { 1500 } else {
1494 } 1516 }
1495 if (inc_slot) { 1517 if (inc_slot) {
1496 context->hslot++; 1518 context->hslot++;
1497 context->hslot &= 0xFF; 1519 context->hslot &= 0xFF;
1498 if (is_h40) { 1520 if (is_h40) {
1499 if (context->hslot == HBLANK_START_H40) { 1521 if (context->hslot == LINE_CHANGE_H40) {
1500 context->vcounter++; 1522 context->vcounter++;
1501 } else if (context->hslot == 183) { 1523 } else if (context->hslot == 183) {
1502 context->hslot = 229; 1524 context->hslot = 229;
1503 } 1525 }
1504 } else { 1526 } else {
1505 if (context->hslot == 134) { 1527 if (context->hslot == LINE_CHANGE_H32) {
1506 context->vcounter++; 1528 context->vcounter++;
1507 } else if (context->hslot == 148) { 1529 } else if (context->hslot == 148) {
1508 context->hslot = 233; 1530 context->hslot = 233;
1509 } 1531 }
1510 } 1532 }
1679 if ((context->regs[REG_MODE_4] & BIT_INTERLACE) && context->framebuf == context->oddbuf) { 1701 if ((context->regs[REG_MODE_4] & BIT_INTERLACE) && context->framebuf == context->oddbuf) {
1680 value |= 0x10; 1702 value |= 0x10;
1681 } 1703 }
1682 uint32_t line= context->vcounter; 1704 uint32_t line= context->vcounter;
1683 uint32_t slot = context->hslot; 1705 uint32_t slot = context->hslot;
1684 if (line >= (context->latched_mode & BIT_PAL ? PAL_INACTIVE_START : NTSC_INACTIVE_START) || !(context->regs[REG_MODE_2] & BIT_DISP_EN)) { 1706 if (
1707 (
1708 line >= (context->latched_mode & BIT_PAL ? PAL_INACTIVE_START : NTSC_INACTIVE_START)
1709 && line < 0x1FF
1710 )
1711 || !(context->regs[REG_MODE_2] & BIT_DISP_EN)
1712 ) {
1685 value |= 0x8; 1713 value |= 0x8;
1686 } 1714 }
1687 if (context->regs[REG_MODE_4] & BIT_H40) { 1715 if (context->regs[REG_MODE_4] & BIT_H40) {
1688 if (slot < HBLANK_END_H40 || slot > HBLANK_START_H40) { 1716 if (slot < HBLANK_END_H40 || slot > HBLANK_START_H40) {
1689 value |= 0x4; 1717 value |= 0x4;
1757 { 1785 {
1758 if (context->regs[REG_MODE_1] & BIT_HVC_LATCH) { 1786 if (context->regs[REG_MODE_1] & BIT_HVC_LATCH) {
1759 return context->hv_latch; 1787 return context->hv_latch;
1760 } 1788 }
1761 uint32_t line= context->vcounter & 0xFF; 1789 uint32_t line= context->vcounter & 0xFF;
1762 uint32_t linecyc = (context->hslot * 2) & 0xFF; 1790 uint32_t linecyc = context->hslot;
1763 linecyc &= 0xFF; 1791 linecyc &= 0xFF;
1764 if (context->double_res) { 1792 if (context->double_res) {
1765 line <<= 1; 1793 line <<= 1;
1766 if (line & 0x100) { 1794 if (line & 0x100) {
1767 line |= 1; 1795 line |= 1;
1793 } 1821 }
1794 1822
1795 uint32_t vdp_cycles_next_line(vdp_context * context) 1823 uint32_t vdp_cycles_next_line(vdp_context * context)
1796 { 1824 {
1797 if (context->regs[REG_MODE_4] & BIT_H40) { 1825 if (context->regs[REG_MODE_4] & BIT_H40) {
1798 if (context->hslot < HBLANK_START_H40) { 1826 if (context->hslot < LINE_CHANGE_H40) {
1799 return (HBLANK_START_H40 - context->hslot) * MCLKS_SLOT_H40; 1827 return (HBLANK_START_H40 - context->hslot) * MCLKS_SLOT_H40;
1800 } else if (context->hslot < 183) { 1828 } else if (context->hslot < 183) {
1801 return MCLKS_LINE - (context->hslot - HBLANK_START_H40) * MCLKS_SLOT_H40; 1829 return MCLKS_LINE - (context->hslot - LINE_CHANGE_H40) * MCLKS_SLOT_H40;
1802 } else { 1830 } else {
1803 return (256-context->hslot + HBLANK_START_H40) * MCLKS_SLOT_H40; 1831 return (256-context->hslot + LINE_CHANGE_H40) * MCLKS_SLOT_H40;
1804 } 1832 }
1805 } else { 1833 } else {
1806 if (context->hslot < HBLANK_START_H32) { 1834 if (context->hslot < LINE_CHANGE_H32) {
1807 return (HBLANK_START_H32 - context->hslot) * MCLKS_SLOT_H32; 1835 return (LINE_CHANGE_H32 - context->hslot) * MCLKS_SLOT_H32;
1808 } else if (context->hslot < 148) { 1836 } else if (context->hslot < 148) {
1809 return MCLKS_LINE - (context->hslot - HBLANK_START_H32) * MCLKS_SLOT_H32; 1837 return MCLKS_LINE - (context->hslot - LINE_CHANGE_H32) * MCLKS_SLOT_H32;
1810 } else { 1838 } else {
1811 return (256-context->hslot + HBLANK_START_H32) * MCLKS_SLOT_H32; 1839 return (256-context->hslot + LINE_CHANGE_H32) * MCLKS_SLOT_H32;
1812 } 1840 }
1813 } 1841 }
1814 } 1842 }
1815 1843
1816 uint32_t vdp_cycles_to_line(vdp_context * context, uint32_t target) 1844 uint32_t vdp_cycles_to_line(vdp_context * context, uint32_t target)