-
Notifications
You must be signed in to change notification settings - Fork 1
/
vga.php
125 lines (109 loc) · 3.06 KB
/
vga.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
<?php
// EEPROM size: 131072 bytes (128 KiB)
// 600 * 100 pixel effective resolution
// 628 * 132 pixel internal resolution = 82896 pixels
//
// Timing parameters:
// Horizontal timing
$horizontal_visible_area = 100;
$horizontal_front_porch = 5;
$horizontal_sync_pulse = 16;
$horizontal_back_porch = 11;
$horizontal_total_length = $horizontal_visible_area +
$horizontal_front_porch +
$horizontal_sync_pulse +
$horizontal_back_porch;
// Vertical timings
$vertical_visible_area = 600;
$vertical_front_porch = 1;
$vertical_sync_pulse = 4;
$vertical_back_porch = 23;
$vertical_total_length = $vertical_visible_area +
$vertical_front_porch +
$vertical_sync_pulse +
$vertical_back_porch;
$total_pixel_count = $vertical_total_length * $horizontal_total_length;
//error_log("Vertical total length: " . $vertical_total_length);
//error_log("Horizontal total length: " . $horizontal_total_length);
//error_log("Total pixel count: " . $total_pixel_count);
$red = 0;
$green = 0;
$blue = 0;
$hsync = false; // Horizontal sync output
$vsync = false; // Vertical sync output
$hblank = false; // Horizontal blank output
$vblank = false; // Vertical blank output
$hvisible = false; // in Horizontal visible area
$vvisible = false; // in Vertical visible area
$finished = false;
$current_pixel = integer_value($input);
// Which line are we on?
$current_line = intdiv($current_pixel, $horizontal_total_length);
// Which position of the line are we on?
$current_horizontal_position = $current_pixel % $horizontal_total_length;
//error_log("Vertical position: " . $current_line);
//error_log("Horizontal position: " . $current_horizontal_position);
// Sync code
if ($current_pixel <= $total_pixel_count)
{
if ($current_line < $vertical_visible_area)
{
// Vertical visible area
$vvisible = true;
}
else
{
// Vertical blank
$vblank = true;
if ($current_line > $vertical_visible_area + $vertical_front_porch &&
$current_line <= $vertical_visible_area + $vertical_front_porch + $vertical_sync_pulse )
{
$vsync = true;
}
}
if ($current_horizontal_position < $horizontal_visible_area)
{
// Horizontal visible area
$hvisible = true;
}
else
{
$hblank = true;
if ($current_horizontal_position > $horizontal_visible_area + $horizontal_front_porch &&
$current_horizontal_position <= $horizontal_visible_area + $horizontal_front_porch + $horizontal_sync_pulse )
{
$hsync = true;
}
}
}
else
{
// Finished frame
$finished = true;
}
// Display content
if ($hvisible && $vvisible)
{
// Don't load the image on each evaluation cycle
global $gdimage;
if (!isset($gdimage))
{
error_log("Loading image...");
$gdimage = imagecreatefrompng("examples/vga_indexed221_2.png");
}
$rgb = imagecolorat($gdimage, $current_horizontal_position, $current_line);
$colors = imagecolorsforindex($gdimage, $rgb);
$red = $colors['red'];
$green = $colors['green'];
$blue = $colors['blue'];
}
$output = [
!!($red & 0x01),
!!($red & 0x02),
!!($green & 0x01),
!!($green & 0x02),
!!($blue & 0x02),
$finished,
$hsync,
$vsync
];