annotate 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
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
8
5176efdda5ae Initial work on VDP emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
1 #include <stdint.h>
5176efdda5ae Initial work on VDP emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
2 #include <string.h>
19
04fc17376999 Sort of working tile rendering and tile test ROM
Michael Pavone <pavone@retrodev.com>
parents: 11
diff changeset
3 #include <stdio.h>
8
5176efdda5ae Initial work on VDP emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
4 #include "vdp.h"
11
04d8efe7a1f0 Initial stab at video output and background color rendering. Fixed address decoding in address port write handler.
Michael Pavone <pavone@retrodev.com>
parents: 8
diff changeset
5 #include "system.h"
8
5176efdda5ae Initial work on VDP emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
6
5176efdda5ae Initial work on VDP emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
7 void vdp_init(vdp *context, uint32_t clock_div)
5176efdda5ae Initial work on VDP emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
8 {
5176efdda5ae Initial work on VDP emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
9 memset(context, 0, sizeof(vdp));
11
04d8efe7a1f0 Initial stab at video output and background color rendering. Fixed address decoding in address port write handler.
Michael Pavone <pavone@retrodev.com>
parents: 8
diff changeset
10 //clock div specifies the pixel clock divider
04d8efe7a1f0 Initial stab at video output and background color rendering. Fixed address decoding in address port write handler.
Michael Pavone <pavone@retrodev.com>
parents: 8
diff changeset
11 //but our emulation step is half that fast
04d8efe7a1f0 Initial stab at video output and background color rendering. Fixed address decoding in address port write handler.
Michael Pavone <pavone@retrodev.com>
parents: 8
diff changeset
12 context->clock_inc = clock_div*2;
04d8efe7a1f0 Initial stab at video output and background color rendering. Fixed address decoding in address port write handler.
Michael Pavone <pavone@retrodev.com>
parents: 8
diff changeset
13 context->drawbuffer = context->linebuffers;
04d8efe7a1f0 Initial stab at video output and background color rendering. Fixed address decoding in address port write handler.
Michael Pavone <pavone@retrodev.com>
parents: 8
diff changeset
14 context->readbuffer = context->linebuffers+320;
8
5176efdda5ae Initial work on VDP emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
15 }
5176efdda5ae Initial work on VDP emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
16
5176efdda5ae Initial work on VDP emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
17 void vdp_run(vdp *context, uint32_t target)
5176efdda5ae Initial work on VDP emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
18 {
5176efdda5ae Initial work on VDP emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
19 while (context->cycles < target)
5176efdda5ae Initial work on VDP emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
20 {
11
04d8efe7a1f0 Initial stab at video output and background color rendering. Fixed address decoding in address port write handler.
Michael Pavone <pavone@retrodev.com>
parents: 8
diff changeset
21 context->hcounter+=2;
8
5176efdda5ae Initial work on VDP emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
22 if (context->hcounter == 416) {
5176efdda5ae Initial work on VDP emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
23 context->hcounter = 0;
5176efdda5ae Initial work on VDP emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
24 context->vcounter++;
5176efdda5ae Initial work on VDP emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
25 if (context->vcounter == 262) {
5176efdda5ae Initial work on VDP emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
26 context->vcounter = 0;
5176efdda5ae Initial work on VDP emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
27 }
5176efdda5ae Initial work on VDP emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
28 }
19
04fc17376999 Sort of working tile rendering and tile test ROM
Michael Pavone <pavone@retrodev.com>
parents: 11
diff changeset
29 context->status &= ~(VDP_STATUS_VRAM|VDP_STATUS_SRAM);
04fc17376999 Sort of working tile rendering and tile test ROM
Michael Pavone <pavone@retrodev.com>
parents: 11
diff changeset
30 //Render to linebuffer
21
91ded3b12d96 Only run rendering hardware when display is enabled
Michael Pavone <pavone@retrodev.com>
parents: 19
diff changeset
31 if ((context->status & VDP_STATUS_ENABLED) && context->vcounter > 15 && context->vcounter < 240 && context->hcounter < 406) {
19
04fc17376999 Sort of working tile rendering and tile test ROM
Michael Pavone <pavone@retrodev.com>
parents: 11
diff changeset
32 if (context->hcounter < 246) {
04fc17376999 Sort of working tile rendering and tile test ROM
Michael Pavone <pavone@retrodev.com>
parents: 11
diff changeset
33 context->status |= VDP_STATUS_VRAM;
04fc17376999 Sort of working tile rendering and tile test ROM
Michael Pavone <pavone@retrodev.com>
parents: 11
diff changeset
34 if (!context->hcounter) {
04fc17376999 Sort of working tile rendering and tile test ROM
Michael Pavone <pavone@retrodev.com>
parents: 11
diff changeset
35 //flip linebuffers
04fc17376999 Sort of working tile rendering and tile test ROM
Michael Pavone <pavone@retrodev.com>
parents: 11
diff changeset
36 if (context->drawbuffer == context->linebuffers) {
04fc17376999 Sort of working tile rendering and tile test ROM
Michael Pavone <pavone@retrodev.com>
parents: 11
diff changeset
37 context->drawbuffer = context->linebuffers + 328;
04fc17376999 Sort of working tile rendering and tile test ROM
Michael Pavone <pavone@retrodev.com>
parents: 11
diff changeset
38 context->readbuffer = context->linebuffers;
04fc17376999 Sort of working tile rendering and tile test ROM
Michael Pavone <pavone@retrodev.com>
parents: 11
diff changeset
39 } else {
04fc17376999 Sort of working tile rendering and tile test ROM
Michael Pavone <pavone@retrodev.com>
parents: 11
diff changeset
40 context->drawbuffer = context->linebuffers;
04fc17376999 Sort of working tile rendering and tile test ROM
Michael Pavone <pavone@retrodev.com>
parents: 11
diff changeset
41 context->readbuffer = context->linebuffers + 328;
04fc17376999 Sort of working tile rendering and tile test ROM
Michael Pavone <pavone@retrodev.com>
parents: 11
diff changeset
42 }
04fc17376999 Sort of working tile rendering and tile test ROM
Michael Pavone <pavone@retrodev.com>
parents: 11
diff changeset
43 context->draw_dest = 0;
22
407725d9a02f Implemented sprite drawing. Added small sprite example.
Michael Pavone <pavone@retrodev.com>
parents: 21
diff changeset
44 //enable sprite scanning
407725d9a02f Implemented sprite drawing. Added small sprite example.
Michael Pavone <pavone@retrodev.com>
parents: 21
diff changeset
45 context->status |= VDP_STATUS_SPRITE_SCAN;
407725d9a02f Implemented sprite drawing. Added small sprite example.
Michael Pavone <pavone@retrodev.com>
parents: 21
diff changeset
46 context->current_draw = 0;
19
04fc17376999 Sort of working tile rendering and tile test ROM
Michael Pavone <pavone@retrodev.com>
parents: 11
diff changeset
47 }
04fc17376999 Sort of working tile rendering and tile test ROM
Michael Pavone <pavone@retrodev.com>
parents: 11
diff changeset
48 if (context->draw_counter) {
04fc17376999 Sort of working tile rendering and tile test ROM
Michael Pavone <pavone@retrodev.com>
parents: 11
diff changeset
49 context->draw_counter--;
04fc17376999 Sort of working tile rendering and tile test ROM
Michael Pavone <pavone@retrodev.com>
parents: 11
diff changeset
50 uint16_t pixels = context->vram[context->draw_source++];
23
a085f17b79e9 Implement hflip
Michael Pavone <pavone@retrodev.com>
parents: 22
diff changeset
51 for (int i = context->hflip ? 0 : 12; i >= 0 && i < 16; i+= context->hflip ? 4 : -4)
19
04fc17376999 Sort of working tile rendering and tile test ROM
Michael Pavone <pavone@retrodev.com>
parents: 11
diff changeset
52 {
23
a085f17b79e9 Implement hflip
Michael Pavone <pavone@retrodev.com>
parents: 22
diff changeset
53 uint8_t pixel = ((pixels >> i) & 0xF) | context->palpriority;
a085f17b79e9 Implement hflip
Michael Pavone <pavone@retrodev.com>
parents: 22
diff changeset
54 context->drawbuffer[context->draw_dest ^ (context->hflip << 2)] = pixel;
a085f17b79e9 Implement hflip
Michael Pavone <pavone@retrodev.com>
parents: 22
diff changeset
55 context->draw_dest++;
19
04fc17376999 Sort of working tile rendering and tile test ROM
Michael Pavone <pavone@retrodev.com>
parents: 11
diff changeset
56 }
04fc17376999 Sort of working tile rendering and tile test ROM
Michael Pavone <pavone@retrodev.com>
parents: 11
diff changeset
57 } else {
04fc17376999 Sort of working tile rendering and tile test ROM
Michael Pavone <pavone@retrodev.com>
parents: 11
diff changeset
58 //00VV VVVV VVHH HHHH
04fc17376999 Sort of working tile rendering and tile test ROM
Michael Pavone <pavone@retrodev.com>
parents: 11
diff changeset
59 uint16_t vpos = (context->vscroll & 0x7FF) + context->vcounter - 16;
04fc17376999 Sort of working tile rendering and tile test ROM
Michael Pavone <pavone@retrodev.com>
parents: 11
diff changeset
60 uint16_t vmask = (context->vscroll >> 2) & 0x3E00;
04fc17376999 Sort of working tile rendering and tile test ROM
Michael Pavone <pavone@retrodev.com>
parents: 11
diff changeset
61 uint16_t vcoarse = (vpos << 3) & 0x3FC0;
04fc17376999 Sort of working tile rendering and tile test ROM
Michael Pavone <pavone@retrodev.com>
parents: 11
diff changeset
62 uint16_t vfine = vpos & 7;
04fc17376999 Sort of working tile rendering and tile test ROM
Michael Pavone <pavone@retrodev.com>
parents: 11
diff changeset
63 uint16_t hcoarse = ((context->hscroll >> 3) + context->hcounter/6) & 0x3F;
04fc17376999 Sort of working tile rendering and tile test ROM
Michael Pavone <pavone@retrodev.com>
parents: 11
diff changeset
64 uint16_t tableaddress = hcoarse | (vcoarse & ~vmask) | ((context->vscroll << 3) & vmask);
04fc17376999 Sort of working tile rendering and tile test ROM
Michael Pavone <pavone@retrodev.com>
parents: 11
diff changeset
65 //printf("VCounter: %X, VScroll: %X, HCounter: %X, Table: %X\n", context->vcounter, context->vscroll, context->hcounter, tableaddress);
04fc17376999 Sort of working tile rendering and tile test ROM
Michael Pavone <pavone@retrodev.com>
parents: 11
diff changeset
66 uint16_t entry = context->vram[tableaddress];
04fc17376999 Sort of working tile rendering and tile test ROM
Michael Pavone <pavone@retrodev.com>
parents: 11
diff changeset
67 context->draw_source = (entry & 0x3FF) * 16;
04fc17376999 Sort of working tile rendering and tile test ROM
Michael Pavone <pavone@retrodev.com>
parents: 11
diff changeset
68 if (entry & 0x1000) {
04fc17376999 Sort of working tile rendering and tile test ROM
Michael Pavone <pavone@retrodev.com>
parents: 11
diff changeset
69 context->draw_source += 14 - vfine * 2;
04fc17376999 Sort of working tile rendering and tile test ROM
Michael Pavone <pavone@retrodev.com>
parents: 11
diff changeset
70 } else {
04fc17376999 Sort of working tile rendering and tile test ROM
Michael Pavone <pavone@retrodev.com>
parents: 11
diff changeset
71 context->draw_source += vfine * 2;
04fc17376999 Sort of working tile rendering and tile test ROM
Michael Pavone <pavone@retrodev.com>
parents: 11
diff changeset
72 }
04fc17376999 Sort of working tile rendering and tile test ROM
Michael Pavone <pavone@retrodev.com>
parents: 11
diff changeset
73 context->palpriority = entry >> 9 & 0x70;
04fc17376999 Sort of working tile rendering and tile test ROM
Michael Pavone <pavone@retrodev.com>
parents: 11
diff changeset
74 context->draw_counter = 2;
23
a085f17b79e9 Implement hflip
Michael Pavone <pavone@retrodev.com>
parents: 22
diff changeset
75 context->hflip = (entry & 0x800) != 0;
19
04fc17376999 Sort of working tile rendering and tile test ROM
Michael Pavone <pavone@retrodev.com>
parents: 11
diff changeset
76 }
22
407725d9a02f Implemented sprite drawing. Added small sprite example.
Michael Pavone <pavone@retrodev.com>
parents: 21
diff changeset
77 if (context->status & VDP_STATUS_SPRITE_SCAN) {
407725d9a02f Implemented sprite drawing. Added small sprite example.
Michael Pavone <pavone@retrodev.com>
parents: 21
diff changeset
78 context->status |= VDP_STATUS_SRAM;
407725d9a02f Implemented sprite drawing. Added small sprite example.
Michael Pavone <pavone@retrodev.com>
parents: 21
diff changeset
79 uint16_t pos = context->sram[context->hcounter];
407725d9a02f Implemented sprite drawing. Added small sprite example.
Michael Pavone <pavone@retrodev.com>
parents: 21
diff changeset
80 uint16_t y = pos & 0xFF;
407725d9a02f Implemented sprite drawing. Added small sprite example.
Michael Pavone <pavone@retrodev.com>
parents: 21
diff changeset
81 uint16_t x = pos >> 8;
407725d9a02f Implemented sprite drawing. Added small sprite example.
Michael Pavone <pavone@retrodev.com>
parents: 21
diff changeset
82 uint16_t atts = context->sram[context->hcounter+1];
407725d9a02f Implemented sprite drawing. Added small sprite example.
Michael Pavone <pavone@retrodev.com>
parents: 21
diff changeset
83 x |= atts << 2 & 0x100;
407725d9a02f Implemented sprite drawing. Added small sprite example.
Michael Pavone <pavone@retrodev.com>
parents: 21
diff changeset
84 if (x | y) {
407725d9a02f Implemented sprite drawing. Added small sprite example.
Michael Pavone <pavone@retrodev.com>
parents: 21
diff changeset
85 uint16_t size = atts & 0x400 ? 16 : 8;
407725d9a02f Implemented sprite drawing. Added small sprite example.
Michael Pavone <pavone@retrodev.com>
parents: 21
diff changeset
86 if (context->vcounter >= y && context->vcounter < y + size) {
407725d9a02f Implemented sprite drawing. Added small sprite example.
Michael Pavone <pavone@retrodev.com>
parents: 21
diff changeset
87 uint16_t address = (atts & 0x3F) * 16;
407725d9a02f Implemented sprite drawing. Added small sprite example.
Michael Pavone <pavone@retrodev.com>
parents: 21
diff changeset
88 if (atts & 0x1000) {
407725d9a02f Implemented sprite drawing. Added small sprite example.
Michael Pavone <pavone@retrodev.com>
parents: 21
diff changeset
89 address += (size-1) * 2 - (context->vcounter - y) * 2;
407725d9a02f Implemented sprite drawing. Added small sprite example.
Michael Pavone <pavone@retrodev.com>
parents: 21
diff changeset
90 } else {
407725d9a02f Implemented sprite drawing. Added small sprite example.
Michael Pavone <pavone@retrodev.com>
parents: 21
diff changeset
91 address += (context->vcounter - y) * 2;
407725d9a02f Implemented sprite drawing. Added small sprite example.
Michael Pavone <pavone@retrodev.com>
parents: 21
diff changeset
92 }
407725d9a02f Implemented sprite drawing. Added small sprite example.
Michael Pavone <pavone@retrodev.com>
parents: 21
diff changeset
93 context->sprite_draws[context->current_draw].source = address;
407725d9a02f Implemented sprite drawing. Added small sprite example.
Michael Pavone <pavone@retrodev.com>
parents: 21
diff changeset
94 context->sprite_draws[context->current_draw].x = x;
407725d9a02f Implemented sprite drawing. Added small sprite example.
Michael Pavone <pavone@retrodev.com>
parents: 21
diff changeset
95 context->sprite_draws[context->current_draw].hflip = (atts & 0x800) != 0;
407725d9a02f Implemented sprite drawing. Added small sprite example.
Michael Pavone <pavone@retrodev.com>
parents: 21
diff changeset
96 context->sprite_draws[context->current_draw].palpriority = 0x80 | (atts >> 9 & 0x50);
407725d9a02f Implemented sprite drawing. Added small sprite example.
Michael Pavone <pavone@retrodev.com>
parents: 21
diff changeset
97 context->current_draw++;
407725d9a02f Implemented sprite drawing. Added small sprite example.
Michael Pavone <pavone@retrodev.com>
parents: 21
diff changeset
98 if (size == 16) {
407725d9a02f Implemented sprite drawing. Added small sprite example.
Michael Pavone <pavone@retrodev.com>
parents: 21
diff changeset
99 context->sprite_draws[context->current_draw].source = address + 32;
407725d9a02f Implemented sprite drawing. Added small sprite example.
Michael Pavone <pavone@retrodev.com>
parents: 21
diff changeset
100 context->sprite_draws[context->current_draw].x = x + 8;
407725d9a02f Implemented sprite drawing. Added small sprite example.
Michael Pavone <pavone@retrodev.com>
parents: 21
diff changeset
101 context->sprite_draws[context->current_draw].hflip = (atts & 0x800) != 0;
407725d9a02f Implemented sprite drawing. Added small sprite example.
Michael Pavone <pavone@retrodev.com>
parents: 21
diff changeset
102 context->sprite_draws[context->current_draw].palpriority = 0x80 | (atts >> 9 & 0x50);
23
a085f17b79e9 Implement hflip
Michael Pavone <pavone@retrodev.com>
parents: 22
diff changeset
103 if (context->sprite_draws[context->current_draw].hflip) {
a085f17b79e9 Implement hflip
Michael Pavone <pavone@retrodev.com>
parents: 22
diff changeset
104 context->sprite_draws[context->current_draw].x -= 8;
a085f17b79e9 Implement hflip
Michael Pavone <pavone@retrodev.com>
parents: 22
diff changeset
105 context->sprite_draws[context->current_draw-1].x += 8;
a085f17b79e9 Implement hflip
Michael Pavone <pavone@retrodev.com>
parents: 22
diff changeset
106 }
22
407725d9a02f Implemented sprite drawing. Added small sprite example.
Michael Pavone <pavone@retrodev.com>
parents: 21
diff changeset
107 }
407725d9a02f Implemented sprite drawing. Added small sprite example.
Michael Pavone <pavone@retrodev.com>
parents: 21
diff changeset
108 context->current_draw++;
407725d9a02f Implemented sprite drawing. Added small sprite example.
Michael Pavone <pavone@retrodev.com>
parents: 21
diff changeset
109 if (context->current_draw == 40) {
407725d9a02f Implemented sprite drawing. Added small sprite example.
Michael Pavone <pavone@retrodev.com>
parents: 21
diff changeset
110 //no more rendering capacity
407725d9a02f Implemented sprite drawing. Added small sprite example.
Michael Pavone <pavone@retrodev.com>
parents: 21
diff changeset
111 context->status &= ~VDP_STATUS_SPRITE_SCAN;
407725d9a02f Implemented sprite drawing. Added small sprite example.
Michael Pavone <pavone@retrodev.com>
parents: 21
diff changeset
112 context->current_draw = 0;
407725d9a02f Implemented sprite drawing. Added small sprite example.
Michael Pavone <pavone@retrodev.com>
parents: 21
diff changeset
113 }
407725d9a02f Implemented sprite drawing. Added small sprite example.
Michael Pavone <pavone@retrodev.com>
parents: 21
diff changeset
114 }
407725d9a02f Implemented sprite drawing. Added small sprite example.
Michael Pavone <pavone@retrodev.com>
parents: 21
diff changeset
115 } else {
407725d9a02f Implemented sprite drawing. Added small sprite example.
Michael Pavone <pavone@retrodev.com>
parents: 21
diff changeset
116 //hit sprite list terminator
407725d9a02f Implemented sprite drawing. Added small sprite example.
Michael Pavone <pavone@retrodev.com>
parents: 21
diff changeset
117 context->status &= ~VDP_STATUS_SPRITE_SCAN;
407725d9a02f Implemented sprite drawing. Added small sprite example.
Michael Pavone <pavone@retrodev.com>
parents: 21
diff changeset
118 context->current_draw = 0;
407725d9a02f Implemented sprite drawing. Added small sprite example.
Michael Pavone <pavone@retrodev.com>
parents: 21
diff changeset
119 }
407725d9a02f Implemented sprite drawing. Added small sprite example.
Michael Pavone <pavone@retrodev.com>
parents: 21
diff changeset
120 }
19
04fc17376999 Sort of working tile rendering and tile test ROM
Michael Pavone <pavone@retrodev.com>
parents: 11
diff changeset
121 } else {
22
407725d9a02f Implemented sprite drawing. Added small sprite example.
Michael Pavone <pavone@retrodev.com>
parents: 21
diff changeset
122 sprite_draw *draw = context->sprite_draws + (context->current_draw >> 1);
407725d9a02f Implemented sprite drawing. Added small sprite example.
Michael Pavone <pavone@retrodev.com>
parents: 21
diff changeset
123 if (draw->palpriority) {
407725d9a02f Implemented sprite drawing. Added small sprite example.
Michael Pavone <pavone@retrodev.com>
parents: 21
diff changeset
124 context->status |= VDP_STATUS_VRAM;
407725d9a02f Implemented sprite drawing. Added small sprite example.
Michael Pavone <pavone@retrodev.com>
parents: 21
diff changeset
125 uint16_t pixels = context->vram[draw->source + (context->current_draw & 1)];
407725d9a02f Implemented sprite drawing. Added small sprite example.
Michael Pavone <pavone@retrodev.com>
parents: 21
diff changeset
126 uint16_t x = draw->x - 16 + (context->hscroll & 7);
23
a085f17b79e9 Implement hflip
Michael Pavone <pavone@retrodev.com>
parents: 22
diff changeset
127 for (int i = draw->hflip ? 0 : 12; i >= 0 && i < 16; i+= draw->hflip ? 4 : -4, x++)
22
407725d9a02f Implemented sprite drawing. Added small sprite example.
Michael Pavone <pavone@retrodev.com>
parents: 21
diff changeset
128 {
23
a085f17b79e9 Implement hflip
Michael Pavone <pavone@retrodev.com>
parents: 22
diff changeset
129 uint8_t pixel = (pixels >> i) & 0xF;
22
407725d9a02f Implemented sprite drawing. Added small sprite example.
Michael Pavone <pavone@retrodev.com>
parents: 21
diff changeset
130 if (pixel && x < 328 && ((draw->palpriority & 0x40) || !(context->drawbuffer[x] & 0x40))) {
23
a085f17b79e9 Implement hflip
Michael Pavone <pavone@retrodev.com>
parents: 22
diff changeset
131 context->drawbuffer[x ^ (draw->hflip << 2)] = pixel | draw->palpriority;
22
407725d9a02f Implemented sprite drawing. Added small sprite example.
Michael Pavone <pavone@retrodev.com>
parents: 21
diff changeset
132 }
407725d9a02f Implemented sprite drawing. Added small sprite example.
Michael Pavone <pavone@retrodev.com>
parents: 21
diff changeset
133 }
407725d9a02f Implemented sprite drawing. Added small sprite example.
Michael Pavone <pavone@retrodev.com>
parents: 21
diff changeset
134 if (context->current_draw & 1) {
407725d9a02f Implemented sprite drawing. Added small sprite example.
Michael Pavone <pavone@retrodev.com>
parents: 21
diff changeset
135 draw->palpriority = 0;
407725d9a02f Implemented sprite drawing. Added small sprite example.
Michael Pavone <pavone@retrodev.com>
parents: 21
diff changeset
136 } else {
407725d9a02f Implemented sprite drawing. Added small sprite example.
Michael Pavone <pavone@retrodev.com>
parents: 21
diff changeset
137 draw->x += 4;
407725d9a02f Implemented sprite drawing. Added small sprite example.
Michael Pavone <pavone@retrodev.com>
parents: 21
diff changeset
138 }
407725d9a02f Implemented sprite drawing. Added small sprite example.
Michael Pavone <pavone@retrodev.com>
parents: 21
diff changeset
139 }
407725d9a02f Implemented sprite drawing. Added small sprite example.
Michael Pavone <pavone@retrodev.com>
parents: 21
diff changeset
140 context->current_draw++;
19
04fc17376999 Sort of working tile rendering and tile test ROM
Michael Pavone <pavone@retrodev.com>
parents: 11
diff changeset
141 }
04fc17376999 Sort of working tile rendering and tile test ROM
Michael Pavone <pavone@retrodev.com>
parents: 11
diff changeset
142 }
11
04d8efe7a1f0 Initial stab at video output and background color rendering. Fixed address decoding in address port write handler.
Michael Pavone <pavone@retrodev.com>
parents: 8
diff changeset
143 //Draw to framebuffer
04d8efe7a1f0 Initial stab at video output and background color rendering. Fixed address decoding in address port write handler.
Michael Pavone <pavone@retrodev.com>
parents: 8
diff changeset
144 if (context->vcounter > 8 && context->vcounter < 249 && context->hcounter < 320) {
04d8efe7a1f0 Initial stab at video output and background color rendering. Fixed address decoding in address port write handler.
Michael Pavone <pavone@retrodev.com>
parents: 8
diff changeset
145 if (!context->hcounter && context->vcounter == 9) {
04d8efe7a1f0 Initial stab at video output and background color rendering. Fixed address decoding in address port write handler.
Michael Pavone <pavone@retrodev.com>
parents: 8
diff changeset
146 context->framebuffer = system_get_framebuffer(&context->pitch);
04d8efe7a1f0 Initial stab at video output and background color rendering. Fixed address decoding in address port write handler.
Michael Pavone <pavone@retrodev.com>
parents: 8
diff changeset
147 //pitch is in terms of bytes, but we want it in terms of pixels
04d8efe7a1f0 Initial stab at video output and background color rendering. Fixed address decoding in address port write handler.
Michael Pavone <pavone@retrodev.com>
parents: 8
diff changeset
148 context->pitch /= sizeof(uint16_t);
26
083347ccd508 Implemented vblank interrupts and fixed a bug in exception vector address calculation
Michael Pavone <pavone@retrodev.com>
parents: 23
diff changeset
149 //clear pending interrupt flag since VBlank is over
083347ccd508 Implemented vblank interrupts and fixed a bug in exception vector address calculation
Michael Pavone <pavone@retrodev.com>
parents: 23
diff changeset
150 context->status &= ~VDP_STATUS_PENDING_VINT;
11
04d8efe7a1f0 Initial stab at video output and background color rendering. Fixed address decoding in address port write handler.
Michael Pavone <pavone@retrodev.com>
parents: 8
diff changeset
151 }
04d8efe7a1f0 Initial stab at video output and background color rendering. Fixed address decoding in address port write handler.
Michael Pavone <pavone@retrodev.com>
parents: 8
diff changeset
152 uint16_t *dest = context->framebuffer + (context->vcounter - 9) * context->pitch + context->hcounter;
04d8efe7a1f0 Initial stab at video output and background color rendering. Fixed address decoding in address port write handler.
Michael Pavone <pavone@retrodev.com>
parents: 8
diff changeset
153 if (context->status & VDP_STATUS_ENABLED && context->vcounter > 16 && context->vcounter < 241) {
04d8efe7a1f0 Initial stab at video output and background color rendering. Fixed address decoding in address port write handler.
Michael Pavone <pavone@retrodev.com>
parents: 8
diff changeset
154 *dest = context->cram[0x3F & context->readbuffer[context->hcounter]];
04d8efe7a1f0 Initial stab at video output and background color rendering. Fixed address decoding in address port write handler.
Michael Pavone <pavone@retrodev.com>
parents: 8
diff changeset
155 dest++;
04d8efe7a1f0 Initial stab at video output and background color rendering. Fixed address decoding in address port write handler.
Michael Pavone <pavone@retrodev.com>
parents: 8
diff changeset
156 *dest = context->cram[0x3F & context->readbuffer[context->hcounter+1]];
04d8efe7a1f0 Initial stab at video output and background color rendering. Fixed address decoding in address port write handler.
Michael Pavone <pavone@retrodev.com>
parents: 8
diff changeset
157 } else {
04d8efe7a1f0 Initial stab at video output and background color rendering. Fixed address decoding in address port write handler.
Michael Pavone <pavone@retrodev.com>
parents: 8
diff changeset
158 //Display is disabled or we're in the border area, draw the background color
04d8efe7a1f0 Initial stab at video output and background color rendering. Fixed address decoding in address port write handler.
Michael Pavone <pavone@retrodev.com>
parents: 8
diff changeset
159 *dest = *context->cram;
04d8efe7a1f0 Initial stab at video output and background color rendering. Fixed address decoding in address port write handler.
Michael Pavone <pavone@retrodev.com>
parents: 8
diff changeset
160 dest++;
04d8efe7a1f0 Initial stab at video output and background color rendering. Fixed address decoding in address port write handler.
Michael Pavone <pavone@retrodev.com>
parents: 8
diff changeset
161 *dest = *context->cram;
04d8efe7a1f0 Initial stab at video output and background color rendering. Fixed address decoding in address port write handler.
Michael Pavone <pavone@retrodev.com>
parents: 8
diff changeset
162 }
04d8efe7a1f0 Initial stab at video output and background color rendering. Fixed address decoding in address port write handler.
Michael Pavone <pavone@retrodev.com>
parents: 8
diff changeset
163 } else if(!context->hcounter && context->vcounter == 249) {
26
083347ccd508 Implemented vblank interrupts and fixed a bug in exception vector address calculation
Michael Pavone <pavone@retrodev.com>
parents: 23
diff changeset
164 if (context->status & VDP_STATUS_ENABLED) {
083347ccd508 Implemented vblank interrupts and fixed a bug in exception vector address calculation
Michael Pavone <pavone@retrodev.com>
parents: 23
diff changeset
165 context->status |= VDP_STATUS_PENDING_VINT;
083347ccd508 Implemented vblank interrupts and fixed a bug in exception vector address calculation
Michael Pavone <pavone@retrodev.com>
parents: 23
diff changeset
166 }
11
04d8efe7a1f0 Initial stab at video output and background color rendering. Fixed address decoding in address port write handler.
Michael Pavone <pavone@retrodev.com>
parents: 8
diff changeset
167 system_framebuffer_updated();
04d8efe7a1f0 Initial stab at video output and background color rendering. Fixed address decoding in address port write handler.
Michael Pavone <pavone@retrodev.com>
parents: 8
diff changeset
168 context->framebuffer = NULL;
04d8efe7a1f0 Initial stab at video output and background color rendering. Fixed address decoding in address port write handler.
Michael Pavone <pavone@retrodev.com>
parents: 8
diff changeset
169 }
04d8efe7a1f0 Initial stab at video output and background color rendering. Fixed address decoding in address port write handler.
Michael Pavone <pavone@retrodev.com>
parents: 8
diff changeset
170 //Handle the FIFO
8
5176efdda5ae Initial work on VDP emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
171 if (context->status & VDP_STATUS_FIFO) {
5176efdda5ae Initial work on VDP emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
172 switch (context->fifo_dest)
5176efdda5ae Initial work on VDP emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
173 {
5176efdda5ae Initial work on VDP emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
174 case FIFO_DEST_VRAM:
5176efdda5ae Initial work on VDP emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
175 if (!(context->status & VDP_STATUS_VRAM)) {
5176efdda5ae Initial work on VDP emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
176 context->vram[context->dest_offset++] = context->fifo;
5176efdda5ae Initial work on VDP emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
177 context->dest_offset &= sizeof(context->vram)/2-1;
5176efdda5ae Initial work on VDP emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
178 context->status &= ~VDP_STATUS_FIFO;
5176efdda5ae Initial work on VDP emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
179 }
5176efdda5ae Initial work on VDP emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
180 break;
5176efdda5ae Initial work on VDP emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
181 case FIFO_DEST_SRAM:
5176efdda5ae Initial work on VDP emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
182 if (!(context->status & VDP_STATUS_SRAM)) {
5176efdda5ae Initial work on VDP emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
183 context->sram[context->dest_offset++] = context->fifo;
5176efdda5ae Initial work on VDP emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
184 context->dest_offset &= sizeof(context->sram)/2-1;
5176efdda5ae Initial work on VDP emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
185 context->status &= ~VDP_STATUS_FIFO;
5176efdda5ae Initial work on VDP emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
186 }
5176efdda5ae Initial work on VDP emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
187 break;
5176efdda5ae Initial work on VDP emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
188 case FIFO_DEST_CRAM:
5176efdda5ae Initial work on VDP emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
189 context->cram[context->dest_offset++] = context->fifo;
5176efdda5ae Initial work on VDP emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
190 context->dest_offset &= sizeof(context->cram)/2-1;
5176efdda5ae Initial work on VDP emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
191 context->status &= ~VDP_STATUS_FIFO;
5176efdda5ae Initial work on VDP emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
192 break;
5176efdda5ae Initial work on VDP emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
193 }
5176efdda5ae Initial work on VDP emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
194 }
5176efdda5ae Initial work on VDP emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
195 context->cycles += context->clock_inc;
5176efdda5ae Initial work on VDP emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
196 }
5176efdda5ae Initial work on VDP emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
197 }
5176efdda5ae Initial work on VDP emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
198 void vdp_write_address(vdp *context, uint16_t value)
5176efdda5ae Initial work on VDP emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
199 {
5176efdda5ae Initial work on VDP emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
200 context->status &= ~VDP_STATUS_FIFO;
11
04d8efe7a1f0 Initial stab at video output and background color rendering. Fixed address decoding in address port write handler.
Michael Pavone <pavone@retrodev.com>
parents: 8
diff changeset
201 if (!(value & 0x8000)) {
8
5176efdda5ae Initial work on VDP emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
202 context->fifo_dest = FIFO_DEST_VRAM;
5176efdda5ae Initial work on VDP emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
203 context->dest_offset = (value & (sizeof(context->vram) -1))/2;
11
04d8efe7a1f0 Initial stab at video output and background color rendering. Fixed address decoding in address port write handler.
Michael Pavone <pavone@retrodev.com>
parents: 8
diff changeset
204 } else if ((value & 0xFF00) == 0xFE00) {
8
5176efdda5ae Initial work on VDP emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
205 context->fifo_dest = FIFO_DEST_SRAM;
5176efdda5ae Initial work on VDP emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
206 context->dest_offset = (value & (sizeof(context->sram) -1))/2;
11
04d8efe7a1f0 Initial stab at video output and background color rendering. Fixed address decoding in address port write handler.
Michael Pavone <pavone@retrodev.com>
parents: 8
diff changeset
207 } else if ((value & 0xFF00) == 0xFF00) {
8
5176efdda5ae Initial work on VDP emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
208 context->fifo_dest = FIFO_DEST_CRAM;
5176efdda5ae Initial work on VDP emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
209 context->dest_offset = (value & (sizeof(context->cram) -1))/2;
5176efdda5ae Initial work on VDP emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
210 }
5176efdda5ae Initial work on VDP emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
211 }
5176efdda5ae Initial work on VDP emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
212
5176efdda5ae Initial work on VDP emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
213 void vdp_write_data(vdp *context, uint16_t value)
5176efdda5ae Initial work on VDP emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
214 {
5176efdda5ae Initial work on VDP emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
215 context->fifo = value;
5176efdda5ae Initial work on VDP emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
216 context->status |= VDP_STATUS_FIFO;
5176efdda5ae Initial work on VDP emulation
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
217 }
19
04fc17376999 Sort of working tile rendering and tile test ROM
Michael Pavone <pavone@retrodev.com>
parents: 11
diff changeset
218
04fc17376999 Sort of working tile rendering and tile test ROM
Michael Pavone <pavone@retrodev.com>
parents: 11
diff changeset
219 void vdp_write_hscroll(vdp *context, uint16_t value)
04fc17376999 Sort of working tile rendering and tile test ROM
Michael Pavone <pavone@retrodev.com>
parents: 11
diff changeset
220 {
04fc17376999 Sort of working tile rendering and tile test ROM
Michael Pavone <pavone@retrodev.com>
parents: 11
diff changeset
221 context->hscroll = value & 0x1FF;
04fc17376999 Sort of working tile rendering and tile test ROM
Michael Pavone <pavone@retrodev.com>
parents: 11
diff changeset
222 if (value & 0x8000) {
04fc17376999 Sort of working tile rendering and tile test ROM
Michael Pavone <pavone@retrodev.com>
parents: 11
diff changeset
223 context->status |= VDP_STATUS_ENABLED;
04fc17376999 Sort of working tile rendering and tile test ROM
Michael Pavone <pavone@retrodev.com>
parents: 11
diff changeset
224 } else {
04fc17376999 Sort of working tile rendering and tile test ROM
Michael Pavone <pavone@retrodev.com>
parents: 11
diff changeset
225 context->status &= ~VDP_STATUS_ENABLED;
04fc17376999 Sort of working tile rendering and tile test ROM
Michael Pavone <pavone@retrodev.com>
parents: 11
diff changeset
226 }
04fc17376999 Sort of working tile rendering and tile test ROM
Michael Pavone <pavone@retrodev.com>
parents: 11
diff changeset
227 }
26
083347ccd508 Implemented vblank interrupts and fixed a bug in exception vector address calculation
Michael Pavone <pavone@retrodev.com>
parents: 23
diff changeset
228
083347ccd508 Implemented vblank interrupts and fixed a bug in exception vector address calculation
Michael Pavone <pavone@retrodev.com>
parents: 23
diff changeset
229 uint32_t vdp_next_interrupt(vdp *context)
083347ccd508 Implemented vblank interrupts and fixed a bug in exception vector address calculation
Michael Pavone <pavone@retrodev.com>
parents: 23
diff changeset
230 {
083347ccd508 Implemented vblank interrupts and fixed a bug in exception vector address calculation
Michael Pavone <pavone@retrodev.com>
parents: 23
diff changeset
231 if (context->status & VDP_STATUS_PENDING_VINT) {
083347ccd508 Implemented vblank interrupts and fixed a bug in exception vector address calculation
Michael Pavone <pavone@retrodev.com>
parents: 23
diff changeset
232 return 0;
083347ccd508 Implemented vblank interrupts and fixed a bug in exception vector address calculation
Michael Pavone <pavone@retrodev.com>
parents: 23
diff changeset
233 } else if (context->status & VDP_STATUS_ENABLED) {
083347ccd508 Implemented vblank interrupts and fixed a bug in exception vector address calculation
Michael Pavone <pavone@retrodev.com>
parents: 23
diff changeset
234 uint32_t next_line = context->vcounter + 1;
083347ccd508 Implemented vblank interrupts and fixed a bug in exception vector address calculation
Michael Pavone <pavone@retrodev.com>
parents: 23
diff changeset
235 uint32_t next_line_cyc = context->cycles + ((416 - context->hcounter) >> 1) * context->clock_inc;
083347ccd508 Implemented vblank interrupts and fixed a bug in exception vector address calculation
Michael Pavone <pavone@retrodev.com>
parents: 23
diff changeset
236 if (context->vcounter < 249) {
083347ccd508 Implemented vblank interrupts and fixed a bug in exception vector address calculation
Michael Pavone <pavone@retrodev.com>
parents: 23
diff changeset
237 return next_line_cyc + (249 - next_line) * 832;
083347ccd508 Implemented vblank interrupts and fixed a bug in exception vector address calculation
Michael Pavone <pavone@retrodev.com>
parents: 23
diff changeset
238 } else {
083347ccd508 Implemented vblank interrupts and fixed a bug in exception vector address calculation
Michael Pavone <pavone@retrodev.com>
parents: 23
diff changeset
239 return next_line_cyc + (249 + 262 - next_line) * 832;
083347ccd508 Implemented vblank interrupts and fixed a bug in exception vector address calculation
Michael Pavone <pavone@retrodev.com>
parents: 23
diff changeset
240 }
083347ccd508 Implemented vblank interrupts and fixed a bug in exception vector address calculation
Michael Pavone <pavone@retrodev.com>
parents: 23
diff changeset
241 } else {
083347ccd508 Implemented vblank interrupts and fixed a bug in exception vector address calculation
Michael Pavone <pavone@retrodev.com>
parents: 23
diff changeset
242 return 0xFFFFFFFF;
083347ccd508 Implemented vblank interrupts and fixed a bug in exception vector address calculation
Michael Pavone <pavone@retrodev.com>
parents: 23
diff changeset
243 }
083347ccd508 Implemented vblank interrupts and fixed a bug in exception vector address calculation
Michael Pavone <pavone@retrodev.com>
parents: 23
diff changeset
244 }
083347ccd508 Implemented vblank interrupts and fixed a bug in exception vector address calculation
Michael Pavone <pavone@retrodev.com>
parents: 23
diff changeset
245
083347ccd508 Implemented vblank interrupts and fixed a bug in exception vector address calculation
Michael Pavone <pavone@retrodev.com>
parents: 23
diff changeset
246 void vdp_ack_interrupt(vdp *context)
083347ccd508 Implemented vblank interrupts and fixed a bug in exception vector address calculation
Michael Pavone <pavone@retrodev.com>
parents: 23
diff changeset
247 {
083347ccd508 Implemented vblank interrupts and fixed a bug in exception vector address calculation
Michael Pavone <pavone@retrodev.com>
parents: 23
diff changeset
248 context->status &= ~VDP_STATUS_PENDING_VINT;
083347ccd508 Implemented vblank interrupts and fixed a bug in exception vector address calculation
Michael Pavone <pavone@retrodev.com>
parents: 23
diff changeset
249 }
083347ccd508 Implemented vblank interrupts and fixed a bug in exception vector address calculation
Michael Pavone <pavone@retrodev.com>
parents: 23
diff changeset
250
083347ccd508 Implemented vblank interrupts and fixed a bug in exception vector address calculation
Michael Pavone <pavone@retrodev.com>
parents: 23
diff changeset
251 uint8_t vdp_interrupt_pending(vdp *context)
083347ccd508 Implemented vblank interrupts and fixed a bug in exception vector address calculation
Michael Pavone <pavone@retrodev.com>
parents: 23
diff changeset
252 {
083347ccd508 Implemented vblank interrupts and fixed a bug in exception vector address calculation
Michael Pavone <pavone@retrodev.com>
parents: 23
diff changeset
253 return (context->status & VDP_STATUS_PENDING_VINT) != 0;
083347ccd508 Implemented vblank interrupts and fixed a bug in exception vector address calculation
Michael Pavone <pavone@retrodev.com>
parents: 23
diff changeset
254 }