You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: docs/user_peripherals/12_vga.md
+76-4Lines changed: 76 additions & 4 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -11,15 +11,65 @@ You can also include images in this folder and reference them in the markdown. E
11
11
512 kb in size, and the combined size of all images must be less than 1 MB.
12
12
-->
13
13
14
-
# VGA adapter for TinyQV
14
+
# 4 color flexible resolution VGA adapter for TinyQV
15
15
16
16
Author: ReJ aka Renaldas Zioma
17
17
18
18
Peripheral index: 12
19
19
20
20
## What it does
21
21
22
-
TODO: Explain what your peripheral does and how it works
22
+
Flexible VGA framebuffer that allows multiple resolutions, up to 4 colors per scanline, 64 unique colors per frame and provides 1024x768 60Hz video signal (64 MHz pixel clock) suitable for a [TinyVGA PMOD](https://github.com/mole99/tiny-vga).
23
+
24
+
By default it is configured to display **20 x 16 pixels** choosing colors from a 2 entrees palette. Each pixel is 1 bit where 0 selects background and 1 foreground color. In this configuration CPU is completely free to attend to other tasks.
25
+
26
+
### Racing the Beam
27
+
28
+
This peripheral is inspired by the 8-bit era designs when Video RAM (VRAM) was prohibitively expensive and there was not enough memory worth of the whole screen resolution - frankly the situation is similar with Tiny Tapeout and TinyQV peripherals where the amount of memory bits is very limited.
29
+
30
+
Instead of large framebuffers, **Racing the Beam** technique was utilised to synchronize CPU with video signal and allow CPU to modify pixels in VRAM immediately after they have been displayed, forming the image of high resolution line by line.
31
+
32
+
**Racing the Beam** means that CPU has to run in tandem with video signal:
33
+
-**interrupts** can be used for a coarse wait - for the start of the frame or scanline,
34
+
-**blocking reads** for precise syncronisation - for scanline or even in the middle of the scanline.
35
+
36
+
Racing the Beam requires high CPU utilisation to support high screen resolutions. In the case of game, CPU could be processing game-pad inputs and executing gameplay logic only during the vertical blanking. The vertical blanking happens between scanlines 768 and 804 - roughly just 5% of the whole frame.
37
+
38
+
Of course sacrifice up to 95% of CPU time is significant, but it might be worth for games or graphical demos. With this peripheral, it is up to you to decide!
39
+
40
+
### Technical capabilities
41
+
42
+
A very wide range of possible resolutions:
43
+
- from 16 x 10 4-color to 1024 x 768 2-color modes,
44
+
- vertical and horizontal counters define the size of the pixel,
45
+
- visible portion of the horizontal line can be set to 960 or 1024 clock cycles.
46
+
47
+
The resolution of the screen, as well as 2 or 4 color mode can be changed at any point of the frame providing extra flexibility.
48
+
49
+
Video RAM and color palette:
50
+
-**320 bit** of Video RAM worth of 320 or 160 pixels depending on the color mode,
51
+
- configurable stride in bits for each new row of visible pixels,
52
+
- up to 4 color palette, can be modified at any point of the frame.
53
+
54
+
**Coarse** and **precise** syncronisation primitives:
55
+
- interrupts,
56
+
- cycle accurate blocking of the CPU,
57
+
- register to read out the current scanline number of the video signal.
58
+
59
+
### Syncronisation primitives
60
+
61
+
Syncronisation between CPU and video signal can be used either to update
62
+
63
+
User interrupts can be triggered by:
64
+
- end of the frame,
65
+
- end of the visible portion of the scanline,
66
+
- end of the row of pixels
67
+
68
+
CPU can be blocked with cycle level precision until:
69
+
- end of the visible portion of the scanline and start of the horizontal blanking is reached - `WAIT_HBLANK`
70
+
- the first pixel of the Video RAM was visualized and can be safely be modified by CPU again - `WAIT_PIXEL0`
71
+
72
+
Read-only register to access the current scanline number - `SCANLINE`.
23
73
24
74
## Register map
25
75
@@ -45,8 +95,30 @@ TODO: Explain what your peripheral does and how it works
45
95
46
96
## How to test
47
97
48
-
TODO: Explain how to use your project
98
+
### Default 20 x 16 pixels
99
+
100
+
By default VGA peripheral is configured to display screen resolution of 20 x 16 pixels.
101
+
Write to `PIXELS` register to change the pixels. Each pixel is 1 bit and CPU is free to attend to other tasks.
102
+
103
+
### 4-color 160 x 192
104
+
105
+
By default VGA peripheral will count 1024 cycles per visible line, however 1024 is not divisible by intended resolution of 160 pixels. You can shorten the screen width to 960 clocks instead since 960 are nicely divisible by 320. This is achieved by setting the **5th bit** of `MODE` register.
106
+
107
+
4 colors mode is enabled by setting the **6th bit** of `MODE` register.
108
+
109
+
The whole 160 pixel row nicely fits into the 320-bit VRAM and every new row of pixels will start from the very beginning of VRAM, therefore `VRAM_STRIDE` will be 0 (-1 will have the same effect reseting VRAM address to 0 at every row).
110
+
111
+
Finally, calculated pixel horizontal and vertical counters dividing 960x768 the visible VGA resolution by the inteded frame resolution 160x192 and subtract 1. Write counter values in `PIXEL_SIZE` register.
0 commit comments