comparison 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
comparison
equal deleted inserted replaced
25:fb14515266f4 26:083347ccd508
144 if (context->vcounter > 8 && context->vcounter < 249 && context->hcounter < 320) { 144 if (context->vcounter > 8 && context->vcounter < 249 && context->hcounter < 320) {
145 if (!context->hcounter && context->vcounter == 9) { 145 if (!context->hcounter && context->vcounter == 9) {
146 context->framebuffer = system_get_framebuffer(&context->pitch); 146 context->framebuffer = system_get_framebuffer(&context->pitch);
147 //pitch is in terms of bytes, but we want it in terms of pixels 147 //pitch is in terms of bytes, but we want it in terms of pixels
148 context->pitch /= sizeof(uint16_t); 148 context->pitch /= sizeof(uint16_t);
149 //clear pending interrupt flag since VBlank is over
150 context->status &= ~VDP_STATUS_PENDING_VINT;
149 } 151 }
150 uint16_t *dest = context->framebuffer + (context->vcounter - 9) * context->pitch + context->hcounter; 152 uint16_t *dest = context->framebuffer + (context->vcounter - 9) * context->pitch + context->hcounter;
151 if (context->status & VDP_STATUS_ENABLED && context->vcounter > 16 && context->vcounter < 241) { 153 if (context->status & VDP_STATUS_ENABLED && context->vcounter > 16 && context->vcounter < 241) {
152 *dest = context->cram[0x3F & context->readbuffer[context->hcounter]]; 154 *dest = context->cram[0x3F & context->readbuffer[context->hcounter]];
153 dest++; 155 dest++;
157 *dest = *context->cram; 159 *dest = *context->cram;
158 dest++; 160 dest++;
159 *dest = *context->cram; 161 *dest = *context->cram;
160 } 162 }
161 } else if(!context->hcounter && context->vcounter == 249) { 163 } else if(!context->hcounter && context->vcounter == 249) {
164 if (context->status & VDP_STATUS_ENABLED) {
165 context->status |= VDP_STATUS_PENDING_VINT;
166 }
162 system_framebuffer_updated(); 167 system_framebuffer_updated();
163 context->framebuffer = NULL; 168 context->framebuffer = NULL;
164 } 169 }
165 //Handle the FIFO 170 //Handle the FIFO
166 if (context->status & VDP_STATUS_FIFO) { 171 if (context->status & VDP_STATUS_FIFO) {
218 context->status |= VDP_STATUS_ENABLED; 223 context->status |= VDP_STATUS_ENABLED;
219 } else { 224 } else {
220 context->status &= ~VDP_STATUS_ENABLED; 225 context->status &= ~VDP_STATUS_ENABLED;
221 } 226 }
222 } 227 }
228
229 uint32_t vdp_next_interrupt(vdp *context)
230 {
231 if (context->status & VDP_STATUS_PENDING_VINT) {
232 return 0;
233 } else if (context->status & VDP_STATUS_ENABLED) {
234 uint32_t next_line = context->vcounter + 1;
235 uint32_t next_line_cyc = context->cycles + ((416 - context->hcounter) >> 1) * context->clock_inc;
236 if (context->vcounter < 249) {
237 return next_line_cyc + (249 - next_line) * 832;
238 } else {
239 return next_line_cyc + (249 + 262 - next_line) * 832;
240 }
241 } else {
242 return 0xFFFFFFFF;
243 }
244 }
245
246 void vdp_ack_interrupt(vdp *context)
247 {
248 context->status &= ~VDP_STATUS_PENDING_VINT;
249 }
250
251 uint8_t vdp_interrupt_pending(vdp *context)
252 {
253 return (context->status & VDP_STATUS_PENDING_VINT) != 0;
254 }