forked from s-matyukevich/raspberry-pi-os
-
Notifications
You must be signed in to change notification settings - Fork 1
/
kernel.c
147 lines (121 loc) · 4.85 KB
/
kernel.c
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
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
#include "debug.h"
#include "draw.h"
#include "hvs.h"
#include "mini_uart.h"
#include "mm.h"
#include "printf.h"
#include "utils.h"
#include <stdint.h>
void kernel_main(void)
{
uart_init();
init_printf(0, putc);
debug_print_registers();
/* "Allocate" 4 framebuffers in memory. Each is 1MiB in size, which is plenty for our purposes. */
uint16_t* const fb_one = (uint16_t*)(0x10000000); // the first 3 will use 16-bit pixels.
uint16_t* const fb_two = (uint16_t*)(0x10100000);
uint16_t* const fb_three = (uint16_t*)(0x10200000);
uint32_t* const fb_four = (uint32_t*)(0x10300000); // this one will use a 32-bit pixel format.
/* Each framebuffer will be a quarter of the screen (960 x 540) in dimensions. */
const uint16_t screen_width = 1920, screen_height = 1080;
const uint16_t fb_width = screen_width / 2, fb_height = screen_height / 2;
const uint16_t fb_center_x = fb_width / 2;
const uint16_t fb_center_y = fb_height / 2;
/* Set up initial display list - a single plane centered on the screen. */
hvs_plane plane = {
.format = HVS_PIXEL_FORMAT_RGB565,
.pixel_order = HVS_PIXEL_ORDER_ARGB,
.start_x = (screen_width - fb_width) / 2,
.start_y = (screen_height - fb_height) / 2,
.height = fb_height,
.width = fb_width,
.pitch = fb_width * sizeof(uint16_t),
.framebuffer = fb_one
};
printf("Writing initial display list.r\n");
write_display_list(&plane, 1);
/* Pause for a few seconds... */
delay(9000000);
/* We'll use this rect to draw rectangles. */
rect r = {
.left = fb_center_x - 100,
.top = fb_center_y - 100,
.right = fb_center_x + 100,
.bottom = fb_center_y + 100
};
/* Clear the framebuffer and do some drawing... */
printf("Clearing framebuffer and drawing.\r\n");
clear_plane_16(plane, GREEN_16);
draw_rectangle_16(plane, WHITE_16, r);
/* Pause for a few seconds... */
delay(9000000);
/* Move the plane across the screen. */
printf("Translating plane across screen.r\n");
for (int i = 0; i < 10; i++) {
plane.start_x = i * ((screen_width - fb_width) / 10);
plane.start_y = i * ((screen_height - fb_height) / 10);
write_display_list(&plane, 1);
delay(9000000 * 0.25);
}
/* Set up 4 planes. */
hvs_plane planes[4];
int i = 0;
for (int y = 0; y < 2; y++) {
for (int x = 0; x < 2; x++) {
planes[i].format = HVS_PIXEL_FORMAT_RGB565,
planes[i].pixel_order = HVS_PIXEL_ORDER_ARGB,
planes[i].start_x = fb_width * x;
planes[i].start_y = fb_height * y;
planes[i].height = fb_height,
planes[i].width = fb_width,
planes[i].pitch = fb_width * 2,
i++;
}
}
planes[0].framebuffer = fb_one;
planes[1].framebuffer = fb_two;
planes[2].framebuffer = fb_three;
planes[3].framebuffer = fb_four;
/* We'll make the fourth framebuffer a 32-bit pixel format, just for demonstrations. */
planes[3].format = HVS_PIXEL_FORMAT_RGBA8888;
planes[3].pitch = fb_width * sizeof(uint32_t);
printf("Updating display list with 4 framebuffers.r\n");
write_display_list(planes, 4);
/* Clear the 3 new framebuffers. */
clear_plane_16(planes[1], BLUE_16);
clear_plane_16(planes[2], WHITE_16);
clear_plane_32(planes[3], RED_32);
/* Draw some additional shapes. */
draw_rectangle_16(planes[0], WHITE_16, r);
draw_circle_16(planes[1], WHITE_16, fb_center_x, fb_center_y, 100);
draw_circle_16(planes[2], BLACK_16, fb_center_x, fb_center_y, 100);
draw_rectangle_32(planes[3], YELLOW_32, r);
delay(9000000);
/* Move the fourth plane to the center of the screen. */
planes[3].start_x = (screen_width - fb_width) / 2;
planes[3].start_y = (screen_height - fb_height) / 2;
printf("Moving the fourth plane to the center of the screen.r\n");
write_display_list(planes, 4);
delay(9000000);
/* Make the fourth plane partially-transparent with a yellow square. */
printf("Clearing the fourth plane with a partially-transparent color.r\n");
uint32_t half_trasparent_red = 0x7F0000FF;
clear_plane_32(planes[3], half_trasparent_red);
draw_rectangle_32(planes[3], YELLOW_32, r);
delay(9000000);
int first_plane = 0;
printf("Now rotating framebuffers in an infinite loop.\r\n");
while (1) {
/* Rotate the planes every so often... */
for (int y = 0; y < 2; y++) {
for (int x = 0; x < 2; x++) {
int plane_index = (y * 2 + x + first_plane) % 4;
planes[plane_index].start_x = fb_width * x;
planes[plane_index].start_y = fb_height * y;
}
}
write_display_list(planes, 4);
delay(9000000 * 1);
first_plane = (first_plane + 1) % 4;
}
}