Mercurial > repos > blastem
comparison vdp.c @ 317:e5e8b48ad157
Initial stab at horizontal interrupts and improving accuracy of vertical interrupts. Also added the VINT pending flag to status port.
author | Mike Pavone <pavone@retrodev.com> |
---|---|
date | Fri, 10 May 2013 22:57:56 -0700 |
parents | eea3b118940d |
children | 789f2f5f2277 |
comparison
equal
deleted
inserted
replaced
316:fd7c24b97ebf | 317:e5e8b48ad157 |
---|---|
1026 uint32_t line = context->cycles / MCLKS_LINE; | 1026 uint32_t line = context->cycles / MCLKS_LINE; |
1027 uint32_t active_lines = context->latched_mode & BIT_PAL ? PAL_ACTIVE : NTSC_ACTIVE; | 1027 uint32_t active_lines = context->latched_mode & BIT_PAL ? PAL_ACTIVE : NTSC_ACTIVE; |
1028 if (!line) { | 1028 if (!line) { |
1029 latch_mode(context); | 1029 latch_mode(context); |
1030 } | 1030 } |
1031 uint32_t linecyc = context->cycles % MCLKS_LINE; | |
1032 if (linecyc == 0) { | |
1033 if (line <= 1 || line >= active_lines) { | |
1034 context->hint_counter = context->regs[REG_HINT]; | |
1035 } else if (context->hint_counter) { | |
1036 context->hint_counter--; | |
1037 } else { | |
1038 context->flags2 |= FLAG2_HINT_PENDING; | |
1039 context->hint_counter = context->regs[REG_HINT]; | |
1040 } | |
1041 } else if(line == active_lines) { | |
1042 uint32_t intcyc = context->latched_mode & BIT_H40 ? (148 + 40) * 4 : (132 + 28) * 5;; | |
1043 if (linecyc == intcyc) { | |
1044 context->flags2 |= FLAG2_VINT_PENDING; | |
1045 } | |
1046 } | |
1031 if (line < active_lines && context->regs[REG_MODE_2] & DISPLAY_ENABLE) { | 1047 if (line < active_lines && context->regs[REG_MODE_2] & DISPLAY_ENABLE) { |
1032 //first sort-of active line is treated as 255 internally | 1048 //first sort-of active line is treated as 255 internally |
1033 //it's used for gathering sprite info for line | 1049 //it's used for gathering sprite info for line |
1034 line = (line - 1) & 0xFF; | 1050 line = (line - 1) & 0xFF; |
1035 uint32_t linecyc = context->cycles % MCLKS_LINE; | |
1036 | 1051 |
1037 //Convert to slot number | 1052 //Convert to slot number |
1038 if (context->latched_mode & BIT_H40){ | 1053 if (context->latched_mode & BIT_H40){ |
1039 //TODO: Deal with nasty clock switching during HBLANK | 1054 //TODO: Deal with nasty clock switching during HBLANK |
1055 uint32_t clock_inc = MCLKS_LINE-linecyc < 16 ? MCLKS_LINE-linecyc : 16; | |
1040 linecyc = linecyc/16; | 1056 linecyc = linecyc/16; |
1041 vdp_h40(line, linecyc, context); | 1057 vdp_h40(line, linecyc, context); |
1042 context->cycles += 16; | 1058 context->cycles += clock_inc; |
1043 } else { | 1059 } else { |
1044 linecyc = linecyc/20; | 1060 linecyc = linecyc/20; |
1045 vdp_h32(line, linecyc, context); | 1061 vdp_h32(line, linecyc, context); |
1046 context->cycles += 20; | 1062 context->cycles += 20; |
1047 } | 1063 } |
1051 } | 1067 } |
1052 if (line < active_lines) { | 1068 if (line < active_lines) { |
1053 check_render_bg(context, line); | 1069 check_render_bg(context, line); |
1054 } | 1070 } |
1055 if (context->latched_mode & BIT_H40){ | 1071 if (context->latched_mode & BIT_H40){ |
1072 uint32_t clock_inc = MCLKS_LINE-linecyc < 16 ? MCLKS_LINE-linecyc : 16; | |
1056 //TODO: Deal with nasty clock switching during HBLANK | 1073 //TODO: Deal with nasty clock switching during HBLANK |
1057 context->cycles += 16; | 1074 context->cycles += clock_inc; |
1058 } else { | 1075 } else { |
1059 context->cycles += 20; | 1076 context->cycles += 20; |
1060 } | 1077 } |
1061 } | 1078 } |
1062 } | 1079 } |
1171 value |= 0x200; | 1188 value |= 0x200; |
1172 } | 1189 } |
1173 if (context->fifo_cur == context->fifo_end) { | 1190 if (context->fifo_cur == context->fifo_end) { |
1174 value |= 0x100; | 1191 value |= 0x100; |
1175 } | 1192 } |
1193 if (context->flags2 & FLAG2_VINT_PENDING) { | |
1194 value |- 0x80; | |
1195 } | |
1176 if (context->flags & FLAG_DMA_RUN) { | 1196 if (context->flags & FLAG_DMA_RUN) { |
1177 value |= 0x2; | 1197 value |= 0x2; |
1178 } | 1198 } |
1179 uint32_t line= context->cycles / MCLKS_LINE; | 1199 uint32_t line= context->cycles / MCLKS_LINE; |
1180 if (line >= (context->latched_mode & BIT_PAL ? PAL_ACTIVE : NTSC_ACTIVE)) { | 1200 if (line >= (context->latched_mode & BIT_PAL ? PAL_ACTIVE : NTSC_ACTIVE)) { |
1181 value |= 0x8; | 1201 value |= 0x8; |
1202 } | |
1203 if (context->latched_mode & BIT_PAL) {//Not sure about this, need to verify | |
1204 value |= 0x1; | |
1182 } | 1205 } |
1183 //TODO: Lots of other bits in status port | 1206 //TODO: Lots of other bits in status port |
1184 return value; | 1207 return value; |
1185 } | 1208 } |
1186 | 1209 |
1266 start->cycle = 0; | 1289 start->cycle = 0; |
1267 } | 1290 } |
1268 } | 1291 } |
1269 } | 1292 } |
1270 | 1293 |
1294 uint32_t vdp_next_hint(vdp_context * context) | |
1295 { | |
1296 if (!(context->regs[REG_MODE_1] & 0x10)) { | |
1297 return 0xFFFFFFFF; | |
1298 } | |
1299 if (context->flags2 & FLAG2_HINT_PENDING) { | |
1300 return context->cycles; | |
1301 } | |
1302 uint32_t active_lines = context->latched_mode & BIT_PAL ? PAL_ACTIVE : NTSC_ACTIVE; | |
1303 uint32_t line = context->cycles / MCLKS_LINE; | |
1304 if (line >= active_lines) { | |
1305 return 0xFFFFFFFF; | |
1306 } | |
1307 uint32_t linecyc = context->cycles % MCLKS_LINE; | |
1308 uint32_t hcycle = context->cycles + context->hint_counter * MCLKS_LINE + MCLKS_LINE - linecyc; | |
1309 if (!line) { | |
1310 hcycle += MCLKS_LINE; | |
1311 } | |
1312 return hcycle; | |
1313 } | |
1314 | |
1315 uint32_t vdp_next_vint(vdp_context * context) | |
1316 { | |
1317 if (!(context->regs[REG_MODE_2] & 0x20)) { | |
1318 return 0xFFFFFFFF; | |
1319 } | |
1320 if (context->flags2 & FLAG2_VINT_PENDING) { | |
1321 return context->cycles; | |
1322 } | |
1323 uint32_t active_lines = context->latched_mode & BIT_PAL ? PAL_ACTIVE : NTSC_ACTIVE; | |
1324 uint32_t vcycle = MCLKS_LINE * active_lines; | |
1325 if (context->latched_mode & BIT_H40) { | |
1326 vcycle += (148 + 40) * 4; | |
1327 } else { | |
1328 vcycle += (132 + 28) * 5; | |
1329 } | |
1330 if (vcycle < context->cycles) { | |
1331 return 0xFFFFFFFF; | |
1332 } | |
1333 return vcycle; | |
1334 } | |
1335 | |
1336 void vdp_int_ack(vdp_context * context, uint16_t int_num) | |
1337 { | |
1338 if (int_num == 6) { | |
1339 context->flags2 &= ~FLAG2_VINT_PENDING; | |
1340 } else if(int_num ==4) { | |
1341 context->flags2 &= ~FLAG2_HINT_PENDING; | |
1342 } | |
1343 } | |
1344 | |
1271 #define GST_VDP_REGS 0xFA | 1345 #define GST_VDP_REGS 0xFA |
1272 #define GST_VDP_MEM 0x12478 | 1346 #define GST_VDP_MEM 0x12478 |
1273 | 1347 |
1274 void vdp_load_savestate(vdp_context * context, FILE * state_file) | 1348 void vdp_load_savestate(vdp_context * context, FILE * state_file) |
1275 { | 1349 { |