comparison src/vdp.c @ 11:04d8efe7a1f0

Initial stab at video output and background color rendering. Fixed address decoding in address port write handler.
author Michael Pavone <pavone@retrodev.com>
date Sun, 27 Mar 2016 17:36:02 -0700
parents 5176efdda5ae
children 04fc17376999
comparison
equal deleted inserted replaced
10:9f575f77a157 11:04d8efe7a1f0
1 #include <stdint.h> 1 #include <stdint.h>
2 #include <string.h> 2 #include <string.h>
3 #include "vdp.h" 3 #include "vdp.h"
4 #include "system.h"
4 5
5 void vdp_init(vdp *context, uint32_t clock_div) 6 void vdp_init(vdp *context, uint32_t clock_div)
6 { 7 {
7 memset(context, 0, sizeof(vdp)); 8 memset(context, 0, sizeof(vdp));
8 context->clock_inc = clock_div; 9 //clock div specifies the pixel clock divider
10 //but our emulation step is half that fast
11 context->clock_inc = clock_div*2;
12 context->drawbuffer = context->linebuffers;
13 context->readbuffer = context->linebuffers+320;
9 } 14 }
10 15
11 void vdp_run(vdp *context, uint32_t target) 16 void vdp_run(vdp *context, uint32_t target)
12 { 17 {
13 while (context->cycles < target) 18 while (context->cycles < target)
14 { 19 {
15 context->hcounter++; 20 context->hcounter+=2;
16 if (context->hcounter == 416) { 21 if (context->hcounter == 416) {
17 context->hcounter = 0; 22 context->hcounter = 0;
18 context->vcounter++; 23 context->vcounter++;
19 if (context->vcounter == 262) { 24 if (context->vcounter == 262) {
20 context->vcounter = 0; 25 context->vcounter = 0;
21 } 26 }
22 } 27 }
23 //TODO: do rendering stuff here 28 //TODO: do rendering stuff here
29 //Draw to framebuffer
30 if (context->vcounter > 8 && context->vcounter < 249 && context->hcounter < 320) {
31 if (!context->hcounter && context->vcounter == 9) {
32 context->framebuffer = system_get_framebuffer(&context->pitch);
33 //pitch is in terms of bytes, but we want it in terms of pixels
34 context->pitch /= sizeof(uint16_t);
35 }
36 uint16_t *dest = context->framebuffer + (context->vcounter - 9) * context->pitch + context->hcounter;
37 if (context->status & VDP_STATUS_ENABLED && context->vcounter > 16 && context->vcounter < 241) {
38 *dest = context->cram[0x3F & context->readbuffer[context->hcounter]];
39 dest++;
40 *dest = context->cram[0x3F & context->readbuffer[context->hcounter+1]];
41 } else {
42 //Display is disabled or we're in the border area, draw the background color
43 *dest = *context->cram;
44 dest++;
45 *dest = *context->cram;
46 }
47 } else if(!context->hcounter && context->vcounter == 249) {
48 system_framebuffer_updated();
49 context->framebuffer = NULL;
50 }
51 //Handle the FIFO
24 if (context->status & VDP_STATUS_FIFO) { 52 if (context->status & VDP_STATUS_FIFO) {
25 switch (context->fifo_dest) 53 switch (context->fifo_dest)
26 { 54 {
27 case FIFO_DEST_VRAM: 55 case FIFO_DEST_VRAM:
28 if (!(context->status & VDP_STATUS_VRAM)) { 56 if (!(context->status & VDP_STATUS_VRAM)) {
49 } 77 }
50 } 78 }
51 void vdp_write_address(vdp *context, uint16_t value) 79 void vdp_write_address(vdp *context, uint16_t value)
52 { 80 {
53 context->status &= ~VDP_STATUS_FIFO; 81 context->status &= ~VDP_STATUS_FIFO;
54 if (value & 0x8000) { 82 if (!(value & 0x8000)) {
55 context->fifo_dest = FIFO_DEST_VRAM; 83 context->fifo_dest = FIFO_DEST_VRAM;
56 context->dest_offset = (value & (sizeof(context->vram) -1))/2; 84 context->dest_offset = (value & (sizeof(context->vram) -1))/2;
57 } else if (value & 0xFF00 == 0xFE00) { 85 } else if ((value & 0xFF00) == 0xFE00) {
58 context->fifo_dest = FIFO_DEST_SRAM; 86 context->fifo_dest = FIFO_DEST_SRAM;
59 context->dest_offset = (value & (sizeof(context->sram) -1))/2; 87 context->dest_offset = (value & (sizeof(context->sram) -1))/2;
60 } else if (value & 0xFF00 == 0xFF00) { 88 } else if ((value & 0xFF00) == 0xFF00) {
61 context->fifo_dest = FIFO_DEST_CRAM; 89 context->fifo_dest = FIFO_DEST_CRAM;
62 context->dest_offset = (value & (sizeof(context->cram) -1))/2; 90 context->dest_offset = (value & (sizeof(context->cram) -1))/2;
63 } 91 }
64 } 92 }
65 93