Mercurial > repos > simple16
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; +}