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 {