diff src/vdp.c @ 26:083347ccd508

Implemented vblank interrupts and fixed a bug in exception vector address calculation
author Michael Pavone <pavone@retrodev.com>
date Fri, 01 Apr 2016 21:34:38 -0700
parents a085f17b79e9
children 6e7bfe83d2b0
line wrap: on
line diff
--- a/src/vdp.c	Thu Mar 31 23:25:52 2016 -0700
+++ b/src/vdp.c	Fri Apr 01 21:34:38 2016 -0700
@@ -146,6 +146,8 @@
 				context->framebuffer = system_get_framebuffer(&context->pitch);
 				//pitch is in terms of bytes, but we want it in terms of pixels
 				context->pitch /= sizeof(uint16_t);
+				//clear pending interrupt flag since VBlank is over
+				context->status &= ~VDP_STATUS_PENDING_VINT;
 			}
 			uint16_t *dest = context->framebuffer + (context->vcounter - 9) * context->pitch + context->hcounter;
 			if (context->status & VDP_STATUS_ENABLED && context->vcounter > 16 && context->vcounter < 241) {
@@ -159,6 +161,9 @@
 				*dest = *context->cram;
 			}
 		} else if(!context->hcounter && context->vcounter == 249) {
+			if (context->status & VDP_STATUS_ENABLED) {
+				context->status |= VDP_STATUS_PENDING_VINT;
+			}
 			system_framebuffer_updated();
 			context->framebuffer = NULL;
 		}
@@ -220,3 +225,30 @@
 		context->status &= ~VDP_STATUS_ENABLED;
 	}
 }
+
+uint32_t vdp_next_interrupt(vdp *context)
+{
+	if (context->status & VDP_STATUS_PENDING_VINT) {
+		return 0;
+	} else if (context->status & VDP_STATUS_ENABLED) {
+		uint32_t next_line = context->vcounter + 1;
+		uint32_t next_line_cyc = context->cycles + ((416 - context->hcounter) >> 1) * context->clock_inc;
+		if (context->vcounter < 249) {
+			return next_line_cyc + (249 - next_line) * 832;
+		} else {
+			return next_line_cyc + (249 + 262 - next_line) * 832;
+		}
+	} else {
+		return 0xFFFFFFFF;
+	}
+}
+
+void vdp_ack_interrupt(vdp *context)
+{
+	context->status &= ~VDP_STATUS_PENDING_VINT;
+}
+
+uint8_t vdp_interrupt_pending(vdp *context)
+{
+	return (context->status & VDP_STATUS_PENDING_VINT) != 0;
+}