Skip to content

Commit 54ba076

Browse files
author
Scrap Computing
committed
Fix porch sizes which caused incorrect colors in some monitors
Many thanks to @Bs0Dd for not only reporting the issue but also finding the root cause!
1 parent bdfbac5 commit 54ba076

3 files changed

Lines changed: 27 additions & 20 deletions

File tree

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -188,7 +188,7 @@ $ make -j
188188
# Change Log
189189
- Rev 0.1: Initial release.
190190
- Rev 0.2: Major redesign. Manual TTL, menus show live background
191-
- Rev 0.3: Better adjustment of pixel clock with sampling offset, support for Pico 2
191+
- Rev 0.3: Better adjustment of pixel clock with sampling offset, support for Pico 2, and fix colors in some monitors
192192

193193
# License
194194
The project is GPLv2.

firmware/src/TimingsVGA.def

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,12 @@
44
//
55
// Neg: ~~~|_|~~~
66
//
7+
// Front Porch Back Porch
8+
// |----| |----|
9+
// Video: ...Visible______________Visible...
10+
//
11+
// HSync: _______________|~~|________________
12+
//
713
//
814
// Horizontal Vertical Polarity
915
// --------------------- --------------- ----------

firmware/src/VGAWriter.cpp

Lines changed: 20 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -38,8 +38,8 @@ void __not_in_flash_func(VGAWriter::DrawBlackLineWithMask4x1)(bool InVertSync) {
3838
Black4_Main |= VMask_4;
3939

4040
for (unsigned i = 0;
41-
i < TimingsVGA[M].H_FrontPorch + TimingsVGA[M].H_Visible +
42-
TimingsVGA[M].H_BackPorch;
41+
i < TimingsVGA[M].H_BackPorch + TimingsVGA[M].H_Visible +
42+
TimingsVGA[M].H_FrontPorch;
4343
i += 4)
4444
pio_sm_put_blocking(VGAPio, VGASM, Black4_Main);
4545

@@ -65,8 +65,8 @@ void __not_in_flash_func(VGAWriter::DrawLineVSyncHigh4x1)(unsigned Line) {
6565
if constexpr (VPolarity == Polarity::Neg)
6666
Black4_Porch |= VMask_4;
6767

68-
// Front Porch is black.
69-
for (unsigned i = 0; i < TimingsVGA[M].H_FrontPorch; i += 4)
68+
// Back Porch is black.
69+
for (unsigned i = 0; i < TimingsVGA[M].H_BackPorch; i += 4)
7070
pio_sm_put_blocking(VGAPio, VGASM, Black4_Porch);
7171

7272
// The visible part of the line.
@@ -79,8 +79,8 @@ void __not_in_flash_func(VGAWriter::DrawLineVSyncHigh4x1)(unsigned Line) {
7979
pio_sm_put_blocking(VGAPio, VGASM, Pix4);
8080
}
8181

82-
// Back Porch is black
83-
for (unsigned i = 0; i < TimingsVGA[M].H_BackPorch; i += 4)
82+
// Front Porch is black
83+
for (unsigned i = 0; i < TimingsVGA[M].H_FrontPorch; i += 4)
8484
pio_sm_put_blocking(VGAPio, VGASM, Black4_Porch);
8585

8686
// Sync.
@@ -98,8 +98,8 @@ void __not_in_flash_func(VGAWriter::DrawBlackLineWithMaskMDA8x1)(uint32_t Mask_8
9898
static constexpr auto M = VGA_800x600_56Hz;
9999
const uint32_t BlackMDA_8_HM = BlackMDA_8 | HMaskMDA_8 | Mask_8;
100100
for (unsigned i = 0;
101-
i < TimingsVGA[M].H_FrontPorch + TimingsVGA[M].H_Visible +
102-
TimingsVGA[M].H_BackPorch;
101+
i < TimingsVGA[M].H_BackPorch + TimingsVGA[M].H_Visible +
102+
TimingsVGA[M].H_FrontPorch;
103103
i += 8)
104104
pio_sm_put_blocking(VGAPio, VGASM, BlackMDA_8_HM);
105105

@@ -112,8 +112,8 @@ void __not_in_flash_func(VGAWriter::DrawLineVSyncHighMDA8x1)(unsigned Line) {
112112
static constexpr auto M = VGA_800x600_56Hz;
113113
// VSync is High throughout.
114114
// HSync is High for the boarders + visible parts.
115-
// Front Porch
116-
for (unsigned i = 0; i < TimingsVGA[M].H_FrontPorch; i += 8)
115+
// Back Porch
116+
for (unsigned i = 0; i < TimingsVGA[M].H_BackPorch; i += 8)
117117
pio_sm_put_blocking(VGAPio, VGASM, BlackMDA_8_HV);
118118

119119
// Visible TTL is 720 pixels but VGA is 800 so we need to pad with black
@@ -283,24 +283,25 @@ void VGAWriter::checkInputSignal() {
283283

284284
template <VGAResolution R, bool LineDoubling>
285285
void __not_in_flash_func(VGAWriter::drawFrame4x1)() {
286-
for (uint32_t Line = 0; Line != TimingsVGA[R].V_FrontPorch; ++Line)
286+
// Back porch is black.
287+
for (uint32_t Line = 0; Line != TimingsVGA[R].V_BackPorch; ++Line)
287288
DrawBlackLineWithMask4x1(/*InVSync=*/false);
288289

289290
// 1. TTL Visible.
290-
// Note: We limit to min(TTL Visible, VGA V_Visble + V_BackPorch) in case the
291+
// Note: We limit to min(TTL Visible, VGA V_Visble + V_FrontPorch) in case the
291292
// TTL input signal is slightly taller than VGA visible. This is useful for
292293
// some strange inputs that are 260 lines but we would still want to use VGA
293294
// 640x480.
294295
uint32_t Line = 0;
295296
uint32_t LineTTLE =
296297
std::min(std::min((LineDoubling ? 2 : 1) * TimingsTTL.V_Visible,
297-
TimingsVGA[R].V_Visible + TimingsVGA[R].V_BackPorch),
298+
TimingsVGA[R].V_Visible + TimingsVGA[R].V_FrontPorch),
298299
(LineDoubling ? 2 : 1) * DisplayBuffer::BuffY);
299300
for (; Line < LineTTLE; ++Line)
300301
DrawLineVSyncHigh4x1(Line / (LineDoubling ? 2 : 1));
301-
// 2. The rest is black, including the back porch
302+
// 2. The rest is black, including the front porch
302303
static constexpr const uint32_t LineVGAE =
303-
TimingsVGA[R].V_Visible + TimingsVGA[R].V_BackPorch;
304+
TimingsVGA[R].V_Visible + TimingsVGA[R].V_FrontPorch;
304305
for (; Line < LineVGAE; ++Line)
305306
DrawBlackLineWithMask4x1(/*InVSync=*/false);
306307

@@ -310,8 +311,8 @@ void __not_in_flash_func(VGAWriter::drawFrame4x1)() {
310311

311312
template <VGAResolution R, bool LineDoubling>
312313
void __not_in_flash_func(VGAWriter::drawFrame8x1)() {
313-
// 0. Non-visible Front porch
314-
for (uint32_t InvisLine = 0; InvisLine != TimingsVGA[R].V_FrontPorch;
314+
// 0. Non-visible Back porch
315+
for (uint32_t InvisLine = 0; InvisLine != TimingsVGA[R].V_BackPorch;
315316
++InvisLine)
316317
DrawBlackLineWithMaskMDA8x1(VMaskMDA_8);
317318

@@ -339,8 +340,8 @@ void __not_in_flash_func(VGAWriter::drawFrame8x1)() {
339340
for (; TTLLine < LineVGAE; ++TTLLine)
340341
DrawBlackLineWithMaskMDA8x1(VMaskMDA_8);
341342

342-
// 4. Non-visible back porch
343-
for (uint32_t Line = 0; Line != TimingsVGA[R].V_BackPorch; ++Line)
343+
// 4. Non-visible front porch
344+
for (uint32_t Line = 0; Line != TimingsVGA[R].V_FrontPorch; ++Line)
344345
DrawBlackLineWithMaskMDA8x1(VMaskMDA_8);
345346
// 5. Retrace
346347
for (uint32_t Line = 0; Line != TimingsVGA[R].V_Retrace; ++Line)

0 commit comments

Comments
 (0)