Mercurial > repos > blastem
comparison vdp.c @ 822:ac65086c031e
Pretty decent optimization of vdp_h40 and vdp_h32. Gets reasonably close to the speed of 0.2.0 in the worst case and is faster than 0.2.0 in others
author | Michael Pavone <pavone@retrodev.com> |
---|---|
date | Mon, 03 Aug 2015 20:06:56 -0700 |
parents | 0565b2c1a034 |
children | 252dfd29831d |
comparison
equal
deleted
inserted
replaced
821:21a69dfb6ee7 | 822:ac65086c031e |
---|---|
493 } | 493 } |
494 context->fifo_read = (context->fifo_read+1) & (FIFO_SIZE-1); | 494 context->fifo_read = (context->fifo_read+1) & (FIFO_SIZE-1); |
495 if (context->fifo_read == context->fifo_write) { | 495 if (context->fifo_read == context->fifo_write) { |
496 context->fifo_read = -1; | 496 context->fifo_read = -1; |
497 } | 497 } |
498 context->flags &= ~FLAG_UNUSED_SLOT; | |
498 } else { | 499 } else { |
499 context->flags |= FLAG_UNUSED_SLOT; | 500 context->flags |= FLAG_UNUSED_SLOT; |
500 } | 501 } |
501 } | 502 } |
502 | 503 |
929 } | 930 } |
930 context->buf_a_off = (context->buf_a_off + SCROLL_BUFFER_DRAW) & SCROLL_BUFFER_MASK; | 931 context->buf_a_off = (context->buf_a_off + SCROLL_BUFFER_DRAW) & SCROLL_BUFFER_MASK; |
931 context->buf_b_off = (context->buf_b_off + SCROLL_BUFFER_DRAW) & SCROLL_BUFFER_MASK; | 932 context->buf_b_off = (context->buf_b_off + SCROLL_BUFFER_DRAW) & SCROLL_BUFFER_MASK; |
932 } | 933 } |
933 | 934 |
935 uint32_t const h40_hsync_cycles[] = {19, 20, 20, 20, 18, 20, 20, 20, 18, 20, 20, 20, 18, 20, 20, 20, 19}; | |
936 | |
937 void vdp_advance_line(vdp_context *context) | |
938 { | |
939 context->vcounter++; | |
940 context->vcounter &= 0x1FF; | |
941 if (context->flags2 & FLAG2_REGION_PAL) { | |
942 if (context->latched_mode & BIT_PAL) { | |
943 if (context->vcounter == 0x10B) { | |
944 context->vcounter = 0x1D2; | |
945 } | |
946 } else if (context->vcounter == 0x103){ | |
947 context->vcounter = 0x1CA; | |
948 } | |
949 } else if (!(context->latched_mode & BIT_PAL) && context->vcounter == 0xEB) { | |
950 context->vcounter = 0x1E5; | |
951 } | |
952 | |
953 if (context->vcounter > (context->latched_mode & BIT_PAL ? PAL_INACTIVE_START : NTSC_INACTIVE_START)) { | |
954 context->hint_counter = context->regs[REG_HINT]; | |
955 } else if (context->hint_counter) { | |
956 context->hint_counter--; | |
957 } else { | |
958 context->flags2 |= FLAG2_HINT_PENDING; | |
959 context->pending_hint_start = context->cycles; | |
960 context->hint_counter = context->regs[REG_HINT]; | |
961 } | |
962 } | |
963 | |
964 #define CHECK_ONLY if (context->cycles >= target_cycles) { return; } | |
965 #define CHECK_LIMIT if (context->flags & FLAG_DMA_RUN) { run_dma_src(context, context->hslot); } context->hslot++; context->cycles += slot_cycles; CHECK_ONLY | |
966 | |
934 #define COLUMN_RENDER_BLOCK(column, startcyc) \ | 967 #define COLUMN_RENDER_BLOCK(column, startcyc) \ |
935 case startcyc:\ | 968 case startcyc:\ |
936 read_map_scroll_a(column, line, context);\ | 969 read_map_scroll_a(column, context->vcounter, context);\ |
937 break;\ | 970 CHECK_LIMIT\ |
938 case (startcyc+1):\ | 971 case (startcyc+1):\ |
939 external_slot(context);\ | 972 external_slot(context);\ |
940 break;\ | 973 CHECK_LIMIT\ |
941 case (startcyc+2):\ | 974 case (startcyc+2):\ |
942 render_map_1(context);\ | 975 render_map_1(context);\ |
943 break;\ | 976 CHECK_LIMIT\ |
944 case (startcyc+3):\ | 977 case (startcyc+3):\ |
945 render_map_2(context);\ | 978 render_map_2(context);\ |
946 break;\ | 979 CHECK_LIMIT\ |
947 case (startcyc+4):\ | 980 case (startcyc+4):\ |
948 read_map_scroll_b(column, line, context);\ | 981 read_map_scroll_b(column, context->vcounter, context);\ |
949 break;\ | 982 CHECK_LIMIT\ |
950 case (startcyc+5):\ | 983 case (startcyc+5):\ |
951 read_sprite_x(line, context);\ | 984 read_sprite_x(context->vcounter, context);\ |
952 break;\ | 985 CHECK_LIMIT\ |
953 case (startcyc+6):\ | 986 case (startcyc+6):\ |
954 render_map_3(context);\ | 987 render_map_3(context);\ |
955 break;\ | 988 CHECK_LIMIT\ |
956 case (startcyc+7):\ | 989 case (startcyc+7):\ |
957 render_map_output(line, column, context);\ | 990 render_map_output(context->vcounter, column, context);\ |
958 break; | 991 CHECK_LIMIT |
959 | 992 |
960 #define COLUMN_RENDER_BLOCK_REFRESH(column, startcyc) \ | 993 #define COLUMN_RENDER_BLOCK_REFRESH(column, startcyc) \ |
961 case startcyc:\ | 994 case startcyc:\ |
962 read_map_scroll_a(column, line, context);\ | 995 read_map_scroll_a(column, context->vcounter, context);\ |
963 break;\ | 996 CHECK_LIMIT\ |
964 case (startcyc+1):\ | 997 case (startcyc+1):\ |
965 break;\ | 998 /* refresh, no don't run dma src */\ |
999 context->hslot++;\ | |
1000 context->cycles += slot_cycles;\ | |
1001 CHECK_ONLY\ | |
966 case (startcyc+2):\ | 1002 case (startcyc+2):\ |
967 render_map_1(context);\ | 1003 render_map_1(context);\ |
968 break;\ | 1004 CHECK_LIMIT\ |
969 case (startcyc+3):\ | 1005 case (startcyc+3):\ |
970 render_map_2(context);\ | 1006 render_map_2(context);\ |
971 break;\ | 1007 CHECK_LIMIT\ |
972 case (startcyc+4):\ | 1008 case (startcyc+4):\ |
973 read_map_scroll_b(column, line, context);\ | 1009 read_map_scroll_b(column, context->vcounter, context);\ |
974 break;\ | 1010 CHECK_LIMIT\ |
975 case (startcyc+5):\ | 1011 case (startcyc+5):\ |
976 read_sprite_x(line, context);\ | 1012 read_sprite_x(context->vcounter, context);\ |
977 break;\ | 1013 CHECK_LIMIT\ |
978 case (startcyc+6):\ | 1014 case (startcyc+6):\ |
979 render_map_3(context);\ | 1015 render_map_3(context);\ |
980 break;\ | 1016 CHECK_LIMIT\ |
981 case (startcyc+7):\ | 1017 case (startcyc+7):\ |
982 render_map_output(line, column, context);\ | 1018 render_map_output(context->vcounter, column, context);\ |
983 break; | 1019 if (column == 40 || (column == 32 && startcyc == 124)) {\ |
984 | 1020 vdp_advance_line(context);\ |
985 void vdp_h40(uint32_t line, uint32_t linecyc, vdp_context * context) | 1021 }\ |
1022 CHECK_LIMIT | |
1023 | |
1024 #define SPRITE_RENDER_H40(slot) \ | |
1025 case slot:\ | |
1026 render_sprite_cells( context);\ | |
1027 scan_sprite_table(context->vcounter, context);\ | |
1028 if (context->flags & FLAG_DMA_RUN) { run_dma_src(context, context->hslot); } \ | |
1029 if (slot == 182) {\ | |
1030 context->hslot = 229;\ | |
1031 context->cycles += slot_cycles;\ | |
1032 } else {\ | |
1033 context->hslot++;\ | |
1034 if (slot >= HSYNC_SLOT_H40 && slot < HSYNC_END_H40) {\ | |
1035 context->cycles += h40_hsync_cycles[slot - HSYNC_SLOT_H40];\ | |
1036 } else {\ | |
1037 context->cycles += slot_cycles;\ | |
1038 }\ | |
1039 }\ | |
1040 CHECK_ONLY | |
1041 | |
1042 #define SPRITE_RENDER_H32(slot) \ | |
1043 case slot:\ | |
1044 render_sprite_cells( context);\ | |
1045 scan_sprite_table(context->vcounter, context);\ | |
1046 if (context->flags & FLAG_DMA_RUN) { run_dma_src(context, context->hslot); } \ | |
1047 if (slot == 147) {\ | |
1048 context->hslot = 233;\ | |
1049 } else {\ | |
1050 context->hslot++;\ | |
1051 }\ | |
1052 context->cycles += slot_cycles;\ | |
1053 CHECK_ONLY | |
1054 | |
1055 | |
1056 void vdp_h40(vdp_context * context, uint32_t target_cycles) | |
986 { | 1057 { |
987 uint16_t address; | 1058 uint16_t address; |
988 uint32_t mask; | 1059 uint32_t mask; |
989 switch(linecyc) | 1060 uint32_t const slot_cycles = MCLKS_SLOT_H40; |
1061 switch(context->hslot) | |
1062 { | |
1063 for (;;) | |
990 { | 1064 { |
991 case 165: | 1065 case 165: |
1066 external_slot(context); | |
1067 CHECK_LIMIT | |
992 case 166: | 1068 case 166: |
993 external_slot(context); | 1069 external_slot(context); |
994 break; | 1070 CHECK_LIMIT |
995 //sprite render to line buffer starts | 1071 //sprite render to line buffer starts |
996 case 167: | 1072 case 167: |
1073 context->cur_slot = MAX_DRAWS-1; | |
1074 memset(context->linebuf, 0, LINEBUF_SIZE); | |
1075 if (context->vcounter == 0x1FF) { | |
1076 external_slot(context); | |
1077 } else { | |
1078 render_sprite_cells(context); | |
1079 } | |
1080 CHECK_LIMIT | |
997 case 168: | 1081 case 168: |
1082 if (context->vcounter == 0x1FF) { | |
1083 external_slot(context); | |
1084 } else { | |
1085 render_sprite_cells(context); | |
1086 } | |
1087 CHECK_LIMIT | |
998 case 169: | 1088 case 169: |
1089 if (context->vcounter == 0x1FF) { | |
1090 external_slot(context); | |
1091 } else { | |
1092 render_sprite_cells(context); | |
1093 } | |
1094 CHECK_LIMIT | |
999 case 170: | 1095 case 170: |
1000 if (line == 0xFF) { | 1096 if (context->vcounter == 0x1FF) { |
1001 external_slot(context); | 1097 external_slot(context); |
1002 } else { | 1098 } else { |
1003 render_sprite_cells(context); | 1099 render_sprite_cells(context); |
1004 } | 1100 if (context->vcounter == (context->latched_mode & BIT_PAL ? PAL_INACTIVE_START : NTSC_INACTIVE_START)) { |
1005 break; | 1101 context->hslot++; |
1102 context->cycles += slot_cycles; | |
1103 return; | |
1104 } | |
1105 } | |
1106 CHECK_LIMIT | |
1006 //sprite attribute table scan starts | 1107 //sprite attribute table scan starts |
1007 case 171: | 1108 case 171: |
1109 context->sprite_index = 0x80; | |
1110 context->slot_counter = MAX_SPRITES_LINE; | |
1008 render_sprite_cells( context); | 1111 render_sprite_cells( context); |
1009 scan_sprite_table(line, context); | 1112 scan_sprite_table(context->vcounter, context); |
1010 break; | 1113 CHECK_LIMIT |
1011 case 172: | 1114 SPRITE_RENDER_H40(172) |
1012 case 173: | 1115 SPRITE_RENDER_H40(173) |
1013 case 174: | 1116 SPRITE_RENDER_H40(174) |
1014 case 175: | 1117 SPRITE_RENDER_H40(175) |
1015 case 176: | 1118 SPRITE_RENDER_H40(176) |
1016 case 177: | 1119 SPRITE_RENDER_H40(177) |
1017 case 178: | 1120 SPRITE_RENDER_H40(178) |
1018 case 179: | 1121 SPRITE_RENDER_H40(179) |
1019 case 180: | 1122 SPRITE_RENDER_H40(180) |
1020 case 181: | 1123 SPRITE_RENDER_H40(181) |
1021 case 182: | 1124 SPRITE_RENDER_H40(182) |
1022 case 229: | 1125 SPRITE_RENDER_H40(229) |
1023 case 230: | 1126 SPRITE_RENDER_H40(230) |
1024 case 231: | 1127 SPRITE_RENDER_H40(231) |
1025 case 232: | 1128 SPRITE_RENDER_H40(232) |
1026 case 233: | 1129 SPRITE_RENDER_H40(233) |
1027 //!HSYNC asserted | 1130 //!HSYNC asserted |
1028 case 234: | 1131 SPRITE_RENDER_H40(234) |
1029 case 235: | 1132 SPRITE_RENDER_H40(235) |
1030 render_sprite_cells(context); | 1133 SPRITE_RENDER_H40(236) |
1031 scan_sprite_table(line, context); | 1134 SPRITE_RENDER_H40(237) |
1032 break; | 1135 SPRITE_RENDER_H40(238) |
1033 case 236: | 1136 SPRITE_RENDER_H40(239) |
1034 external_slot(context); | 1137 SPRITE_RENDER_H40(240) |
1035 break; | 1138 SPRITE_RENDER_H40(241) |
1036 case 237: | 1139 SPRITE_RENDER_H40(242) |
1037 case 238: | 1140 SPRITE_RENDER_H40(243) |
1038 case 239: | 1141 SPRITE_RENDER_H40(244) |
1039 case 240: | 1142 SPRITE_RENDER_H40(245) |
1040 case 241: | 1143 SPRITE_RENDER_H40(246) |
1041 case 242: | 1144 SPRITE_RENDER_H40(247) |
1042 case 243: | |
1043 case 244: | |
1044 case 245: | |
1045 case 246: | |
1046 case 247: | |
1047 render_sprite_cells(context); | |
1048 scan_sprite_table(line, context); | |
1049 break; | |
1050 case 248: | 1145 case 248: |
1051 address = (context->regs[REG_HSCROLL] & 0x3F) << 10; | 1146 address = (context->regs[REG_HSCROLL] & 0x3F) << 10; |
1052 mask = 0; | 1147 mask = 0; |
1053 if (context->regs[REG_MODE_3] & 0x2) { | 1148 if (context->regs[REG_MODE_3] & 0x2) { |
1054 mask |= 0xF8; | 1149 mask |= 0xF8; |
1055 } | 1150 } |
1056 if (context->regs[REG_MODE_3] & 0x1) { | 1151 if (context->regs[REG_MODE_3] & 0x1) { |
1057 mask |= 0x7; | 1152 mask |= 0x7; |
1058 } | 1153 } |
1059 line &= mask; | 1154 address += (context->vcounter & mask) * 4; |
1060 address += line * 4; | |
1061 context->hscroll_a = context->vdpmem[address] << 8 | context->vdpmem[address+1]; | 1155 context->hscroll_a = context->vdpmem[address] << 8 | context->vdpmem[address+1]; |
1062 context->hscroll_b = context->vdpmem[address+2] << 8 | context->vdpmem[address+3]; | 1156 context->hscroll_b = context->vdpmem[address+2] << 8 | context->vdpmem[address+3]; |
1063 //printf("%d: HScroll A: %d, HScroll B: %d\n", line, context->hscroll_a, context->hscroll_b); | 1157 //printf("%d: HScroll A: %d, HScroll B: %d\n", context->vcounter, context->hscroll_a, context->hscroll_b); |
1064 break; | 1158 if (context->flags & FLAG_DMA_RUN) { run_dma_src(context, context->hslot); } |
1065 case 249: | 1159 context->hslot++; |
1160 context->cycles += h40_hsync_cycles[14]; | |
1161 CHECK_ONLY | |
1066 //!HSYNC high | 1162 //!HSYNC high |
1067 case 250: | 1163 SPRITE_RENDER_H40(249) |
1068 case 251: | 1164 SPRITE_RENDER_H40(250) |
1069 case 252: | 1165 SPRITE_RENDER_H40(251) |
1070 render_sprite_cells(context); | 1166 SPRITE_RENDER_H40(252) |
1071 scan_sprite_table(line, context); | |
1072 break; | |
1073 case 253: | 1167 case 253: |
1074 read_map_scroll_a(0, line, context); | 1168 read_map_scroll_a(0, context->vcounter, context); |
1075 break; | 1169 CHECK_LIMIT |
1076 case 254: | 1170 SPRITE_RENDER_H40(254) |
1077 render_sprite_cells(context); | |
1078 scan_sprite_table(line, context); | |
1079 break; | |
1080 case 255: | 1171 case 255: |
1081 render_map_1(context); | 1172 render_map_1(context); |
1082 scan_sprite_table(line, context);//Just a guess | 1173 scan_sprite_table(context->vcounter, context);//Just a guess |
1083 break; | 1174 if (context->flags & FLAG_DMA_RUN) { run_dma_src(context, context->hslot); } |
1175 context->hslot = 0; | |
1176 context->cycles += slot_cycles; | |
1177 CHECK_ONLY | |
1084 case 0: | 1178 case 0: |
1085 render_map_2(context); | 1179 render_map_2(context); |
1086 scan_sprite_table(line, context);//Just a guess | 1180 scan_sprite_table(context->vcounter, context);//Just a guess |
1087 break; | 1181 CHECK_LIMIT |
1088 case 1: | 1182 case 1: |
1089 read_map_scroll_b(0, line, context); | 1183 read_map_scroll_b(0, context->vcounter, context); |
1090 break; | 1184 CHECK_LIMIT |
1091 case 2: | 1185 SPRITE_RENDER_H40(2) |
1092 render_sprite_cells(context); | |
1093 scan_sprite_table(line, context); | |
1094 break; | |
1095 case 3: | 1186 case 3: |
1096 render_map_3(context); | 1187 render_map_3(context); |
1097 scan_sprite_table(line, context);//Just a guess | 1188 scan_sprite_table(context->vcounter, context);//Just a guess |
1098 break; | 1189 CHECK_LIMIT |
1099 case 4: | 1190 case 4: |
1100 render_map_output(line, 0, context); | 1191 if (context->vcounter == (context->latched_mode & BIT_PAL ? PAL_INACTIVE_START : NTSC_INACTIVE_START)) { |
1101 scan_sprite_table(line, context);//Just a guess | 1192 context->flags2 |= FLAG2_VINT_PENDING; |
1193 context->pending_vint_start = context->cycles; | |
1194 } | |
1195 render_map_output(context->vcounter, 0, context); | |
1196 scan_sprite_table(context->vcounter, context);//Just a guess | |
1102 //reverse context slot counter so it counts the number of sprite slots | 1197 //reverse context slot counter so it counts the number of sprite slots |
1103 //filled rather than the number of available slots | 1198 //filled rather than the number of available slots |
1104 //context->slot_counter = MAX_SPRITES_LINE - context->slot_counter; | 1199 //context->slot_counter = MAX_SPRITES_LINE - context->slot_counter; |
1105 context->cur_slot = MAX_SPRITES_LINE-1; | 1200 context->cur_slot = MAX_SPRITES_LINE-1; |
1106 context->sprite_draws = MAX_DRAWS; | 1201 context->sprite_draws = MAX_DRAWS; |
1107 context->flags &= (~FLAG_CAN_MASK & ~FLAG_MASKED); | 1202 context->flags &= (~FLAG_CAN_MASK & ~FLAG_MASKED); |
1108 break; | 1203 CHECK_LIMIT |
1109 COLUMN_RENDER_BLOCK(2, 5) | 1204 COLUMN_RENDER_BLOCK(2, 5) |
1110 COLUMN_RENDER_BLOCK(4, 13) | 1205 COLUMN_RENDER_BLOCK(4, 13) |
1111 COLUMN_RENDER_BLOCK(6, 21) | 1206 COLUMN_RENDER_BLOCK(6, 21) |
1112 COLUMN_RENDER_BLOCK_REFRESH(8, 29) | 1207 COLUMN_RENDER_BLOCK_REFRESH(8, 29) |
1113 COLUMN_RENDER_BLOCK(10, 37) | 1208 COLUMN_RENDER_BLOCK(10, 37) |
1125 COLUMN_RENDER_BLOCK(34, 133) | 1220 COLUMN_RENDER_BLOCK(34, 133) |
1126 COLUMN_RENDER_BLOCK(36, 141) | 1221 COLUMN_RENDER_BLOCK(36, 141) |
1127 COLUMN_RENDER_BLOCK(38, 149) | 1222 COLUMN_RENDER_BLOCK(38, 149) |
1128 COLUMN_RENDER_BLOCK_REFRESH(40, 157) | 1223 COLUMN_RENDER_BLOCK_REFRESH(40, 157) |
1129 } | 1224 } |
1130 } | 1225 default: |
1131 | 1226 context->hslot++; |
1132 void vdp_h32(uint32_t line, uint32_t linecyc, vdp_context * context) | 1227 context->cycles += slot_cycles; |
1228 return; | |
1229 } | |
1230 } | |
1231 | |
1232 void vdp_h32(vdp_context * context, uint32_t target_cycles) | |
1133 { | 1233 { |
1134 uint16_t address; | 1234 uint16_t address; |
1135 uint32_t mask; | 1235 uint32_t mask; |
1136 switch(linecyc) | 1236 uint32_t const slot_cycles = MCLKS_SLOT_H32; |
1237 switch(context->hslot) | |
1238 { | |
1239 for (;;) | |
1137 { | 1240 { |
1138 case 132: | 1241 case 132: |
1242 external_slot(context); | |
1243 CHECK_LIMIT | |
1139 case 133: | 1244 case 133: |
1140 external_slot(context); | 1245 external_slot(context); |
1141 break; | 1246 CHECK_LIMIT |
1142 //sprite render to line buffer starts | 1247 //sprite render to line buffer starts |
1143 case 134: | 1248 case 134: |
1249 context->cur_slot = MAX_DRAWS_H32-1; | |
1250 memset(context->linebuf, 0, LINEBUF_SIZE); | |
1251 if (context->vcounter == 0x1FF) { | |
1252 external_slot(context); | |
1253 } else { | |
1254 render_sprite_cells(context); | |
1255 } | |
1256 CHECK_LIMIT | |
1144 case 135: | 1257 case 135: |
1258 if (context->vcounter == 0x1FF) { | |
1259 external_slot(context); | |
1260 } else { | |
1261 render_sprite_cells(context); | |
1262 } | |
1263 CHECK_LIMIT | |
1145 case 136: | 1264 case 136: |
1265 if (context->vcounter == 0x1FF) { | |
1266 external_slot(context); | |
1267 } else { | |
1268 render_sprite_cells(context); | |
1269 } | |
1270 CHECK_LIMIT | |
1146 case 137: | 1271 case 137: |
1147 if (line == 0xFF) { | 1272 if (context->vcounter == 0x1FF) { |
1148 external_slot(context); | 1273 external_slot(context); |
1149 } else { | 1274 } else { |
1150 render_sprite_cells(context); | 1275 render_sprite_cells(context); |
1151 } | 1276 if (context->vcounter == (context->latched_mode & BIT_PAL ? PAL_INACTIVE_START : NTSC_INACTIVE_START)) { |
1152 break; | 1277 context->hslot++; |
1278 context->cycles += slot_cycles; | |
1279 return; | |
1280 } | |
1281 } | |
1282 CHECK_LIMIT | |
1153 //sprite attribute table scan starts | 1283 //sprite attribute table scan starts |
1154 case 138: | 1284 case 138: |
1285 context->sprite_index = 0x80; | |
1286 context->slot_counter = MAX_SPRITES_LINE_H32; | |
1155 render_sprite_cells( context); | 1287 render_sprite_cells( context); |
1156 scan_sprite_table(line, context); | 1288 scan_sprite_table(context->vcounter, context); |
1157 break; | 1289 CHECK_LIMIT |
1158 case 139: | 1290 SPRITE_RENDER_H32(139) |
1159 case 140: | 1291 SPRITE_RENDER_H32(140) |
1160 case 141: | 1292 SPRITE_RENDER_H32(141) |
1161 case 142: | 1293 SPRITE_RENDER_H32(142) |
1162 case 143: | 1294 SPRITE_RENDER_H32(143) |
1163 case 144: | 1295 SPRITE_RENDER_H32(144) |
1164 case 145: | 1296 SPRITE_RENDER_H32(145) |
1165 case 146: | 1297 SPRITE_RENDER_H32(146) |
1166 case 147: | 1298 SPRITE_RENDER_H32(147) |
1167 render_sprite_cells(context); | |
1168 scan_sprite_table(line, context); | |
1169 case 233: | 1299 case 233: |
1170 external_slot(context); | 1300 external_slot(context); |
1171 break; | 1301 CHECK_LIMIT |
1172 case 234: | 1302 SPRITE_RENDER_H32(234) |
1173 case 235: | 1303 SPRITE_RENDER_H32(235) |
1174 case 236: | 1304 SPRITE_RENDER_H32(236) |
1175 case 237: | 1305 SPRITE_RENDER_H32(237) |
1176 case 238: | 1306 SPRITE_RENDER_H32(238) |
1177 //HSYNC start | 1307 //HSYNC start |
1178 case 239: | 1308 SPRITE_RENDER_H32(239) |
1179 case 240: | 1309 SPRITE_RENDER_H32(240) |
1180 case 241: | 1310 SPRITE_RENDER_H32(241) |
1181 case 242: | 1311 SPRITE_RENDER_H32(242) |
1182 case 243: | 1312 SPRITE_RENDER_H32(243) |
1183 case 244: | 1313 SPRITE_RENDER_H32(244) |
1184 case 245: | 1314 SPRITE_RENDER_H32(245) |
1185 render_sprite_cells(context); | |
1186 scan_sprite_table(line, context); | |
1187 break; | |
1188 case 246: | 1315 case 246: |
1189 external_slot(context); | 1316 external_slot(context); |
1190 break; | 1317 CHECK_LIMIT |
1191 case 247: | 1318 case 247: |
1192 address = (context->regs[REG_HSCROLL] & 0x3F) << 10; | 1319 address = (context->regs[REG_HSCROLL] & 0x3F) << 10; |
1193 mask = 0; | 1320 mask = 0; |
1194 if (context->regs[REG_MODE_3] & 0x2) { | 1321 if (context->regs[REG_MODE_3] & 0x2) { |
1195 mask |= 0xF8; | 1322 mask |= 0xF8; |
1196 } | 1323 } |
1197 if (context->regs[REG_MODE_3] & 0x1) { | 1324 if (context->regs[REG_MODE_3] & 0x1) { |
1198 mask |= 0x7; | 1325 mask |= 0x7; |
1199 } | 1326 } |
1200 line &= mask; | 1327 address += (context->vcounter & mask) * 4; |
1201 address += line * 4; | |
1202 context->hscroll_a = context->vdpmem[address] << 8 | context->vdpmem[address+1]; | 1328 context->hscroll_a = context->vdpmem[address] << 8 | context->vdpmem[address+1]; |
1203 context->hscroll_b = context->vdpmem[address+2] << 8 | context->vdpmem[address+3]; | 1329 context->hscroll_b = context->vdpmem[address+2] << 8 | context->vdpmem[address+3]; |
1204 //printf("%d: HScroll A: %d, HScroll B: %d\n", line, context->hscroll_a, context->hscroll_b); | 1330 //printf("%d: HScroll A: %d, HScroll B: %d\n", context->vcounter, context->hscroll_a, context->hscroll_b); |
1205 break; | 1331 CHECK_LIMIT |
1206 case 248: | 1332 SPRITE_RENDER_H32(248) |
1207 case 249: | 1333 SPRITE_RENDER_H32(249) |
1208 case 250: | 1334 SPRITE_RENDER_H32(250) |
1209 case 251: | 1335 SPRITE_RENDER_H32(251) |
1210 render_sprite_cells(context); | |
1211 scan_sprite_table(line, context); | |
1212 break; | |
1213 //!HSYNC high | 1336 //!HSYNC high |
1214 case 252: | 1337 case 252: |
1215 read_map_scroll_a(0, line, context); | 1338 read_map_scroll_a(0, context->vcounter, context); |
1216 break; | 1339 CHECK_LIMIT |
1217 case 253: | 1340 SPRITE_RENDER_H32(253) |
1218 render_sprite_cells(context); | |
1219 scan_sprite_table(line, context); | |
1220 break; | |
1221 case 254: | 1341 case 254: |
1222 render_map_1(context); | 1342 render_map_1(context); |
1223 scan_sprite_table(line, context);//Just a guess | 1343 scan_sprite_table(context->vcounter, context);//Just a guess |
1224 break; | 1344 CHECK_LIMIT |
1225 case 255: | 1345 case 255: |
1226 render_map_2(context); | 1346 render_map_2(context); |
1227 scan_sprite_table(line, context);//Just a guess | 1347 scan_sprite_table(context->vcounter, context);//Just a guess |
1228 break; | 1348 if (context->flags & FLAG_DMA_RUN) { run_dma_src(context, context->hslot); } |
1349 context->cycles += slot_cycles; | |
1350 context->hslot = 0; | |
1351 CHECK_ONLY | |
1229 case 0: | 1352 case 0: |
1230 read_map_scroll_b(0, line, context); | 1353 read_map_scroll_b(0, context->vcounter, context); |
1231 break; | 1354 CHECK_LIMIT |
1232 case 1: | 1355 case 1: |
1233 render_sprite_cells(context); | 1356 render_sprite_cells(context); |
1234 scan_sprite_table(line, context); | 1357 scan_sprite_table(context->vcounter, context); |
1235 break; | 1358 CHECK_LIMIT |
1236 case 2: | 1359 case 2: |
1237 render_map_3(context); | 1360 render_map_3(context); |
1238 scan_sprite_table(line, context);//Just a guess | 1361 scan_sprite_table(context->vcounter, context);//Just a guess |
1239 break; | 1362 CHECK_LIMIT |
1240 case 3: | 1363 case 3: |
1241 render_map_output(line, 0, context); | 1364 render_map_output(context->vcounter, 0, context); |
1242 scan_sprite_table(line, context);//Just a guess | 1365 scan_sprite_table(context->vcounter, context);//Just a guess |
1243 //reverse context slot counter so it counts the number of sprite slots | 1366 //reverse context slot counter so it counts the number of sprite slots |
1244 //filled rather than the number of available slots | 1367 //filled rather than the number of available slots |
1245 //context->slot_counter = MAX_SPRITES_LINE - context->slot_counter; | 1368 //context->slot_counter = MAX_SPRITES_LINE - context->slot_counter; |
1246 context->cur_slot = MAX_SPRITES_LINE_H32-1; | 1369 context->cur_slot = MAX_SPRITES_LINE_H32-1; |
1247 context->sprite_draws = MAX_DRAWS_H32; | 1370 context->sprite_draws = MAX_DRAWS_H32; |
1248 context->flags &= (~FLAG_CAN_MASK & ~FLAG_MASKED); | 1371 context->flags &= (~FLAG_CAN_MASK & ~FLAG_MASKED); |
1249 break; | 1372 CHECK_LIMIT |
1250 COLUMN_RENDER_BLOCK(2, 4) | 1373 COLUMN_RENDER_BLOCK(2, 4) |
1251 COLUMN_RENDER_BLOCK(4, 12) | 1374 COLUMN_RENDER_BLOCK(4, 12) |
1252 COLUMN_RENDER_BLOCK(6, 20) | 1375 COLUMN_RENDER_BLOCK(6, 20) |
1253 COLUMN_RENDER_BLOCK_REFRESH(8, 28) | 1376 COLUMN_RENDER_BLOCK_REFRESH(8, 28) |
1254 COLUMN_RENDER_BLOCK(10, 36) | 1377 COLUMN_RENDER_BLOCK(10, 36) |
1262 COLUMN_RENDER_BLOCK(26, 100) | 1385 COLUMN_RENDER_BLOCK(26, 100) |
1263 COLUMN_RENDER_BLOCK(28, 108) | 1386 COLUMN_RENDER_BLOCK(28, 108) |
1264 COLUMN_RENDER_BLOCK(30, 116) | 1387 COLUMN_RENDER_BLOCK(30, 116) |
1265 COLUMN_RENDER_BLOCK_REFRESH(32, 124) | 1388 COLUMN_RENDER_BLOCK_REFRESH(32, 124) |
1266 } | 1389 } |
1267 } | 1390 default: |
1268 | 1391 context->hslot++; |
1269 void vdp_h40_line(uint32_t line, vdp_context * context) | 1392 context->cycles += MCLKS_SLOT_H32; |
1270 { | |
1271 context->cur_slot = MAX_DRAWS-1; | |
1272 memset(context->linebuf, 0, LINEBUF_SIZE); | |
1273 if (line == 0xFF) { | |
1274 external_slot(context); | |
1275 if (context->flags & FLAG_DMA_RUN) { | |
1276 run_dma_src(context, 0); | |
1277 } | |
1278 external_slot(context); | |
1279 if (context->flags & FLAG_DMA_RUN) { | |
1280 run_dma_src(context, 0); | |
1281 } | |
1282 external_slot(context); | |
1283 if (context->flags & FLAG_DMA_RUN) { | |
1284 run_dma_src(context, 0); | |
1285 } | |
1286 external_slot(context); | |
1287 if (context->flags & FLAG_DMA_RUN) { | |
1288 run_dma_src(context, 0); | |
1289 } | |
1290 external_slot(context); | |
1291 if (context->flags & FLAG_DMA_RUN) { | |
1292 run_dma_src(context, 0); | |
1293 } | |
1294 external_slot(context); | |
1295 if (context->flags & FLAG_DMA_RUN) { | |
1296 run_dma_src(context, 0); | |
1297 } | |
1298 for (int i = 0; i < 19; i++) | |
1299 { | |
1300 scan_sprite_table(line, context); | |
1301 } | |
1302 external_slot(context); | |
1303 for (int i = 0; i < 21; i++) | |
1304 { | |
1305 scan_sprite_table(line, context); | |
1306 } | |
1307 //reverse context slot counter so it counts the number of sprite slots | |
1308 //filled rather than the number of available slots | |
1309 //context->slot_counter = MAX_SPRITES_LINE - context->slot_counter; | |
1310 context->cur_slot = MAX_SPRITES_LINE-1; | |
1311 context->sprite_draws = MAX_DRAWS; | |
1312 context->flags &= (~FLAG_CAN_MASK & ~FLAG_MASKED); | |
1313 for (int column = 2; column < 42; column += 8) | |
1314 { | |
1315 external_slot(context); | |
1316 if (context->flags & FLAG_DMA_RUN) { | |
1317 run_dma_src(context, 0); | |
1318 } | |
1319 read_sprite_x(line, context); | |
1320 | |
1321 external_slot(context); | |
1322 if (context->flags & FLAG_DMA_RUN) { | |
1323 run_dma_src(context, 0); | |
1324 } | |
1325 read_sprite_x(line, context); | |
1326 | |
1327 external_slot(context); | |
1328 if (context->flags & FLAG_DMA_RUN) { | |
1329 run_dma_src(context, 0); | |
1330 } | |
1331 read_sprite_x(line, context); | |
1332 | |
1333 read_sprite_x(line, context); | |
1334 } | |
1335 | |
1336 return; | |
1337 } | |
1338 external_slot(context); | |
1339 if (context->flags & FLAG_DMA_RUN) { | |
1340 run_dma_src(context, 0); | |
1341 } | |
1342 external_slot(context); | |
1343 if (context->flags & FLAG_DMA_RUN) { | |
1344 run_dma_src(context, 0); | |
1345 } | |
1346 | |
1347 render_sprite_cells(context); | |
1348 render_sprite_cells(context); | |
1349 render_sprite_cells(context); | |
1350 render_sprite_cells(context); | |
1351 context->sprite_index = 0x80; | |
1352 context->slot_counter = MAX_SPRITES_LINE; | |
1353 for (int i = 0; i < 19; i++) | |
1354 { | |
1355 render_sprite_cells(context); | |
1356 scan_sprite_table(line, context); | |
1357 } | |
1358 external_slot(context); | |
1359 for (int i = 0; i < 11; i++) | |
1360 { | |
1361 render_sprite_cells(context); | |
1362 scan_sprite_table(line, context); | |
1363 } | |
1364 uint16_t address; | |
1365 uint32_t mask; | |
1366 address = (context->regs[REG_HSCROLL] & 0x3F) << 10; | |
1367 mask = 0; | |
1368 if (context->regs[REG_MODE_3] & 0x2) { | |
1369 mask |= 0xF8; | |
1370 } | |
1371 if (context->regs[REG_MODE_3] & 0x1) { | |
1372 mask |= 0x7; | |
1373 } | |
1374 address += (line & mask) * 4; | |
1375 context->hscroll_a = context->vdpmem[address] << 8 | context->vdpmem[address+1]; | |
1376 context->hscroll_b = context->vdpmem[address+2] << 8 | context->vdpmem[address+3]; | |
1377 render_sprite_cells(context); | |
1378 scan_sprite_table(line, context); | |
1379 render_sprite_cells(context); | |
1380 scan_sprite_table(line, context); | |
1381 render_sprite_cells(context); | |
1382 scan_sprite_table(line, context); | |
1383 render_sprite_cells(context); | |
1384 scan_sprite_table(line, context); | |
1385 | |
1386 read_map_scroll_a(0, line, context); | |
1387 render_sprite_cells(context); | |
1388 scan_sprite_table(line, context); | |
1389 render_map_1(context); | |
1390 scan_sprite_table(line, context);//Just a guess | |
1391 render_map_2(context); | |
1392 scan_sprite_table(line, context);//Just a guess | |
1393 read_map_scroll_b(0, line, context); | |
1394 render_sprite_cells(context); | |
1395 scan_sprite_table(line, context); | |
1396 render_map_3(context); | |
1397 scan_sprite_table(line, context);//Just a guess | |
1398 render_map_output(line, 0, context); | |
1399 scan_sprite_table(line, context);//Just a guess | |
1400 //reverse context slot counter so it counts the number of sprite slots | |
1401 //filled rather than the number of available slots | |
1402 //context->slot_counter = MAX_SPRITES_LINE - context->slot_counter; | |
1403 context->cur_slot = MAX_SPRITES_LINE-1; | |
1404 context->sprite_draws = MAX_DRAWS; | |
1405 context->flags &= (~FLAG_CAN_MASK & ~FLAG_MASKED); | |
1406 for (int column = 2; column < 42; column += 2) | |
1407 { | |
1408 read_map_scroll_a(column, line, context); | |
1409 external_slot(context); | |
1410 if (context->flags & FLAG_DMA_RUN) { | |
1411 run_dma_src(context, 0); | |
1412 } | |
1413 render_map_1(context); | |
1414 render_map_2(context); | |
1415 read_map_scroll_b(column, line, context); | |
1416 read_sprite_x(line, context); | |
1417 render_map_3(context); | |
1418 render_map_output(line, column, context); | |
1419 | |
1420 column += 2; | |
1421 read_map_scroll_a(column, line, context); | |
1422 external_slot(context); | |
1423 if (context->flags & FLAG_DMA_RUN) { | |
1424 run_dma_src(context, 0); | |
1425 } | |
1426 render_map_1(context); | |
1427 render_map_2(context); | |
1428 read_map_scroll_b(column, line, context); | |
1429 read_sprite_x(line, context); | |
1430 render_map_3(context); | |
1431 render_map_output(line, column, context); | |
1432 | |
1433 column += 2; | |
1434 read_map_scroll_a(column, line, context); | |
1435 external_slot(context); | |
1436 if (context->flags & FLAG_DMA_RUN) { | |
1437 run_dma_src(context, 0); | |
1438 } | |
1439 render_map_1(context); | |
1440 render_map_2(context); | |
1441 read_map_scroll_b(column, line, context); | |
1442 read_sprite_x(line, context); | |
1443 render_map_3(context); | |
1444 render_map_output(line, column, context); | |
1445 | |
1446 column += 2; | |
1447 read_map_scroll_a(column, line, context); | |
1448 render_map_1(context); | |
1449 render_map_2(context); | |
1450 read_map_scroll_b(column, line, context); | |
1451 read_sprite_x(line, context); | |
1452 render_map_3(context); | |
1453 render_map_output(line, column, context); | |
1454 } | 1393 } |
1455 } | 1394 } |
1456 | 1395 |
1457 void latch_mode(vdp_context * context) | 1396 void latch_mode(vdp_context * context) |
1458 { | 1397 { |
1481 *(start++) = color; | 1420 *(start++) = color; |
1482 } | 1421 } |
1483 } | 1422 } |
1484 } | 1423 } |
1485 | 1424 |
1486 uint32_t const h40_hsync_cycles[] = {19, 20, 20, 20, 18, 20, 20, 20, 18, 20, 20, 20, 18, 20, 20, 20, 19}; | |
1487 | |
1488 void vdp_advance_line(vdp_context *context) | |
1489 { | |
1490 context->vcounter++; | |
1491 context->vcounter &= 0x1FF; | |
1492 if (context->flags2 & FLAG2_REGION_PAL) { | |
1493 if (context->latched_mode & BIT_PAL) { | |
1494 if (context->vcounter == 0x10B) { | |
1495 context->vcounter = 0x1D2; | |
1496 } | |
1497 } else if (context->vcounter == 0x103){ | |
1498 context->vcounter = 0x1CA; | |
1499 } | |
1500 } else if (!(context->latched_mode & BIT_PAL) && context->vcounter == 0xEB) { | |
1501 context->vcounter = 0x1E5; | |
1502 } | |
1503 | |
1504 if (context->vcounter > (context->latched_mode & BIT_PAL ? PAL_INACTIVE_START : NTSC_INACTIVE_START)) { | |
1505 context->hint_counter = context->regs[REG_HINT]; | |
1506 } else if (context->hint_counter) { | |
1507 context->hint_counter--; | |
1508 } else { | |
1509 context->flags2 |= FLAG2_HINT_PENDING; | |
1510 context->pending_hint_start = context->cycles; | |
1511 context->hint_counter = context->regs[REG_HINT]; | |
1512 } | |
1513 } | |
1514 | 1425 |
1515 void vdp_run_context(vdp_context * context, uint32_t target_cycles) | 1426 void vdp_run_context(vdp_context * context, uint32_t target_cycles) |
1516 { | 1427 { |
1517 while(context->cycles < target_cycles) | 1428 while(context->cycles < target_cycles) |
1518 { | 1429 { |
1519 context->flags &= ~FLAG_UNUSED_SLOT; | |
1520 uint32_t line = context->vcounter; | |
1521 uint32_t slot = context->hslot; | |
1522 | |
1523 if (!line && !slot) { | |
1524 //TODO: Figure out when this actually happens | |
1525 latch_mode(context); | |
1526 } | |
1527 uint32_t inactive_start = context->latched_mode & BIT_PAL ? PAL_INACTIVE_START : NTSC_INACTIVE_START; | 1430 uint32_t inactive_start = context->latched_mode & BIT_PAL ? PAL_INACTIVE_START : NTSC_INACTIVE_START; |
1528 | 1431 //line 0x1FF is basically active even though it's not displayed |
1432 uint8_t active_slot = context->vcounter < inactive_start || context->vcounter == 0x1FF; | |
1529 uint8_t is_h40 = context->regs[REG_MODE_4] & BIT_H40; | 1433 uint8_t is_h40 = context->regs[REG_MODE_4] & BIT_H40; |
1530 if (is_h40) { | 1434 if (context->vcounter == inactive_start) { |
1531 if (slot == 167) { | 1435 if (is_h40) { |
1532 context->cur_slot = MAX_DRAWS-1; | 1436 //the first inactive line behaves as an active one for the first 4 slots |
1533 memset(context->linebuf, 0, LINEBUF_SIZE); | 1437 if (context->hslot > LINE_CHANGE_H40 && context->hslot < 171) { |
1534 } else if (slot == 171) { | 1438 active_slot = 1; |
1535 context->sprite_index = 0x80; | 1439 } |
1536 context->slot_counter = MAX_SPRITES_LINE; | |
1537 } | |
1538 } else { | |
1539 if (slot == 134) { | |
1540 context->cur_slot = MAX_DRAWS_H32-1; | |
1541 memset(context->linebuf, 0, LINEBUF_SIZE); | |
1542 } else if (slot == 138) { | |
1543 context->sprite_index = 0x80; | |
1544 context->slot_counter = MAX_SPRITES_LINE_H32; | |
1545 } | |
1546 } | |
1547 if(line == inactive_start) { | |
1548 uint32_t intslot = context->regs[REG_MODE_4] & BIT_H40 ? VINT_SLOT_H40 : VINT_SLOT_H32; | |
1549 if (slot == intslot) { | |
1550 context->flags2 |= FLAG2_VINT_PENDING; | |
1551 context->pending_vint_start = context->cycles; | |
1552 } | |
1553 } | |
1554 uint32_t inccycles; | |
1555 //line 0x1FF is basically active even though it's not displayed | |
1556 uint8_t active_slot = line < inactive_start || line == 0x1FF; | |
1557 if (is_h40) { | |
1558 if (slot < HSYNC_SLOT_H40 || slot >= HSYNC_END_H40) { | |
1559 inccycles = MCLKS_SLOT_H40; | |
1560 } else { | 1440 } else { |
1561 inccycles = h40_hsync_cycles[slot-HSYNC_SLOT_H40]; | 1441 //the first inactive line behaves as an active one for the first few slots |
1562 } | 1442 if (context->hslot > LINE_CHANGE_H32 && context->hslot < 138) { |
1563 //the first inactive line behaves as an active one for the first 4 slots | 1443 active_slot = 1; |
1564 if (line == inactive_start && slot > 166 && slot < 171) { | 1444 } |
1565 active_slot = 1; | 1445 } |
1566 } | 1446 } |
1567 } else { | |
1568 inccycles = MCLKS_SLOT_H32; | |
1569 //the first inactive line behaves as an active one for the first 4 slots | |
1570 if (line == inactive_start && slot > 166 && slot < 171) { | |
1571 active_slot = 1; | |
1572 } | |
1573 } | |
1574 uint8_t inc_slot = 1; | |
1575 if (context->regs[REG_MODE_2] & DISPLAY_ENABLE && active_slot) { | 1447 if (context->regs[REG_MODE_2] & DISPLAY_ENABLE && active_slot) { |
1576 //run VDP rendering for a slot or a line | |
1577 if (is_h40) { | 1448 if (is_h40) { |
1578 if (slot == LINE_CHANGE_H40 && line < inactive_start && (target_cycles - context->cycles) >= MCLKS_LINE) { | 1449 vdp_h40(context, target_cycles); |
1579 vdp_h40_line(line, context); | 1450 } else { |
1580 inccycles = MCLKS_LINE; | 1451 vdp_h32(context, target_cycles); |
1581 inc_slot = 0; | 1452 } |
1453 } else { | |
1454 if (is_h40) { | |
1455 if (context->hslot == 167) { | |
1456 context->cur_slot = MAX_DRAWS-1; | |
1457 memset(context->linebuf, 0, LINEBUF_SIZE); | |
1458 } else if (context->hslot == 171) { | |
1459 context->sprite_index = 0x80; | |
1460 context->slot_counter = MAX_SPRITES_LINE; | |
1461 } | |
1462 } else { | |
1463 if (context->hslot == 134) { | |
1464 context->cur_slot = MAX_DRAWS_H32-1; | |
1465 memset(context->linebuf, 0, LINEBUF_SIZE); | |
1466 } else if (context->hslot == 138) { | |
1467 context->sprite_index = 0x80; | |
1468 context->slot_counter = MAX_SPRITES_LINE_H32; | |
1469 } | |
1470 } | |
1471 if(context->vcounter == inactive_start) { | |
1472 uint32_t intslot = context->regs[REG_MODE_4] & BIT_H40 ? VINT_SLOT_H40 : VINT_SLOT_H32; | |
1473 if (context->hslot == intslot) { | |
1474 context->flags2 |= FLAG2_VINT_PENDING; | |
1475 context->pending_vint_start = context->cycles; | |
1476 } | |
1477 } | |
1478 uint32_t inccycles; | |
1479 if (is_h40) { | |
1480 if (context->hslot < HSYNC_SLOT_H40 || context->hslot >= HSYNC_END_H40) { | |
1481 inccycles = MCLKS_SLOT_H40; | |
1582 } else { | 1482 } else { |
1583 vdp_h40(line, slot, context); | 1483 inccycles = h40_hsync_cycles[context->hslot-HSYNC_SLOT_H40]; |
1584 } | 1484 } |
1585 } else { | 1485 } else { |
1586 vdp_h32(line, slot, context); | 1486 inccycles = MCLKS_SLOT_H32; |
1587 } | 1487 } |
1588 } else { | 1488 if (!is_refresh(context, context->hslot)) { |
1589 if (!is_refresh(context, slot)) { | |
1590 external_slot(context); | 1489 external_slot(context); |
1591 } | 1490 } |
1592 if (line < inactive_start) { | 1491 if (context->vcounter < inactive_start) { |
1593 check_render_bg(context, line, slot); | 1492 check_render_bg(context, context->vcounter, context->hslot); |
1594 } | 1493 } |
1595 } | 1494 if (context->flags & FLAG_DMA_RUN && !is_refresh(context, context->hslot)) { |
1596 if (context->flags & FLAG_DMA_RUN && !is_refresh(context, slot)) { | 1495 run_dma_src(context, context->hslot); |
1597 run_dma_src(context, slot); | 1496 } |
1598 } | 1497 context->cycles += inccycles; |
1599 context->cycles += inccycles; | |
1600 if (inc_slot) { | |
1601 context->hslot++; | 1498 context->hslot++; |
1602 context->hslot &= 0xFF; | 1499 context->hslot &= 0xFF; |
1603 if (is_h40) { | 1500 if (is_h40) { |
1604 if (context->hslot == LINE_CHANGE_H40) { | 1501 if (context->hslot == LINE_CHANGE_H40) { |
1605 vdp_advance_line(context); | 1502 vdp_advance_line(context); |
1617 } | 1514 } |
1618 } else if (context->hslot == 148) { | 1515 } else if (context->hslot == 148) { |
1619 context->hslot = 233; | 1516 context->hslot = 233; |
1620 } | 1517 } |
1621 } | 1518 } |
1622 | |
1623 } else { | |
1624 vdp_advance_line(context); | |
1625 } | 1519 } |
1626 } | 1520 } |
1627 } | 1521 } |
1628 | 1522 |
1629 uint32_t vdp_run_to_vblank(vdp_context * context) | 1523 uint32_t vdp_run_to_vblank(vdp_context * context) |