|
|
|
@ -1,10 +1,167 @@
|
|
|
|
|
/* See the end of this file for copyright and license terms. */
|
|
|
|
|
|
|
|
|
|
#include <multiboot.h>
|
|
|
|
|
#include <string.h>
|
|
|
|
|
|
|
|
|
|
#include <gay/kprintf.h>
|
|
|
|
|
#include <gay/types.h>
|
|
|
|
|
#include <gay/util.h>
|
|
|
|
|
|
|
|
|
|
enum vga_color {
|
|
|
|
|
VGA_COLOR_BLACK = 0,
|
|
|
|
|
VGA_COLOR_BLUE = 1,
|
|
|
|
|
VGA_COLOR_GREEN = 2,
|
|
|
|
|
VGA_COLOR_CYAN = 3,
|
|
|
|
|
VGA_COLOR_RED = 4,
|
|
|
|
|
VGA_COLOR_MAGENTA = 5,
|
|
|
|
|
VGA_COLOR_BROWN = 6,
|
|
|
|
|
VGA_COLOR_LIGHT_GREY = 7,
|
|
|
|
|
VGA_COLOR_DARK_GREY = 8,
|
|
|
|
|
VGA_COLOR_LIGHT_BLUE = 9,
|
|
|
|
|
VGA_COLOR_LIGHT_GREEN = 10,
|
|
|
|
|
VGA_COLOR_LIGHT_CYAN = 11,
|
|
|
|
|
VGA_COLOR_LIGHT_RED = 12,
|
|
|
|
|
VGA_COLOR_LIGHT_MAGENTA = 13,
|
|
|
|
|
VGA_COLOR_LIGHT_BROWN = 14,
|
|
|
|
|
VGA_COLOR_WHITE = 15,
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
#define FB_ADDRESS 0xb8000
|
|
|
|
|
#define FB_LINES 24
|
|
|
|
|
#define FB_COLS 80
|
|
|
|
|
|
|
|
|
|
struct fb_cell {
|
|
|
|
|
u8 c;
|
|
|
|
|
enum vga_color fg:4;
|
|
|
|
|
enum vga_color bg:4;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
/* struct fb_cell gets aligned to 4 bytes for some reason, so we need to use u16 internally */
|
|
|
|
|
static volatile u16 *const framebuffer = (volatile u16 *)FB_ADDRESS;
|
|
|
|
|
/** @brief current line in the framebuffer */
|
|
|
|
|
static unsigned int fb_line;
|
|
|
|
|
/** @brief current column in the framebuffer */
|
|
|
|
|
static unsigned int fb_col;
|
|
|
|
|
/** @brief current background color */
|
|
|
|
|
enum vga_color fb_background;
|
|
|
|
|
/** @brief current foreground color */
|
|
|
|
|
enum vga_color fb_foreground;
|
|
|
|
|
|
|
|
|
|
static inline volatile struct fb_cell *cell_at(unsigned int line, unsigned int col)
|
|
|
|
|
{
|
|
|
|
|
return (volatile struct fb_cell *)&framebuffer[line * FB_COLS + col];
|
|
|
|
|
}
|
|
|
|
|
#define current_cell (cell_at(fb_line, fb_col))
|
|
|
|
|
|
|
|
|
|
static void fb_newline(void)
|
|
|
|
|
{
|
|
|
|
|
fb_col = 0;
|
|
|
|
|
|
|
|
|
|
void _boot(u32 magic, u32 address)
|
|
|
|
|
if (fb_line == FB_LINES - 1) {
|
|
|
|
|
u8 *first_row = (u8 *)cell_at(0, 0);
|
|
|
|
|
u8 *second_row = (u8 *)cell_at(0, 1);
|
|
|
|
|
u8 *last_row_end = (u8 *)cell_at(FB_LINES, FB_COLS);
|
|
|
|
|
memmove(first_row, second_row, last_row_end - second_row);
|
|
|
|
|
} else {
|
|
|
|
|
fb_line++;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static ssize_t fb_write(struct kprintf_renderer *renderer, const void *buf, size_t size)
|
|
|
|
|
{
|
|
|
|
|
ssize_t ret = 0;
|
|
|
|
|
const u8 *s = buf;
|
|
|
|
|
|
|
|
|
|
while (size > s - (const u8 *)buf) {
|
|
|
|
|
u8 c = *s++;
|
|
|
|
|
ret++;
|
|
|
|
|
|
|
|
|
|
if (fb_col == FB_COLS)
|
|
|
|
|
fb_newline();
|
|
|
|
|
|
|
|
|
|
if (c == '\n') {
|
|
|
|
|
fb_newline();
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
current_cell->c = c;
|
|
|
|
|
current_cell->fg = fb_foreground;
|
|
|
|
|
current_cell->bg = fb_background;
|
|
|
|
|
|
|
|
|
|
fb_col++;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return ret;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static ssize_t fb_flush(struct kprintf_renderer *renderer)
|
|
|
|
|
{
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static struct kprintf_renderer fb_kprintf_renderer = {
|
|
|
|
|
.write = fb_write,
|
|
|
|
|
.flush = fb_flush,
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
static void cls(void)
|
|
|
|
|
{
|
|
|
|
|
for (unsigned int l = 0; l < FB_LINES; l++) {
|
|
|
|
|
for (unsigned int c = 0; c < FB_COLS; c++) {
|
|
|
|
|
cell_at(l, c)->c = '\0';
|
|
|
|
|
cell_at(l, c)->fg = fb_foreground;
|
|
|
|
|
cell_at(l, c)->bg = fb_background;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void vga_init(enum vga_color fg, enum vga_color bg)
|
|
|
|
|
{
|
|
|
|
|
fb_line = 0;
|
|
|
|
|
fb_col = 0;
|
|
|
|
|
fb_foreground = VGA_COLOR_LIGHT_GREY;
|
|
|
|
|
fb_background = VGA_COLOR_BLACK;
|
|
|
|
|
|
|
|
|
|
cls();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void print_gay_propaganda(void)
|
|
|
|
|
{
|
|
|
|
|
static const enum vga_color rainbow[] = {
|
|
|
|
|
VGA_COLOR_RED,
|
|
|
|
|
VGA_COLOR_LIGHT_RED,
|
|
|
|
|
VGA_COLOR_LIGHT_BROWN,
|
|
|
|
|
VGA_COLOR_LIGHT_GREEN,
|
|
|
|
|
VGA_COLOR_LIGHT_CYAN,
|
|
|
|
|
VGA_COLOR_BLUE,
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
enum vga_color bg_before = fb_background;
|
|
|
|
|
enum vga_color fg_before = fb_foreground;
|
|
|
|
|
for (int i = 0; i < ARRAY_SIZE(rainbow); i++) {
|
|
|
|
|
fb_background = rainbow[i];
|
|
|
|
|
for (int i = 0; i < FB_COLS; i++)
|
|
|
|
|
fb_write(NULL, " ", 1);
|
|
|
|
|
}
|
|
|
|
|
fb_background = bg_before;
|
|
|
|
|
|
|
|
|
|
kprintf("\nWelcome to ");
|
|
|
|
|
const char *gaybsd = "GayBSD";
|
|
|
|
|
for (const char *tmp = gaybsd; *tmp != '\0'; tmp++) {
|
|
|
|
|
fb_foreground = rainbow[tmp - gaybsd];
|
|
|
|
|
kprintf("%c", *tmp);
|
|
|
|
|
}
|
|
|
|
|
fb_foreground = fg_before;
|
|
|
|
|
kprintf(", be gay do crime!");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void _boot(u32 magic, void *address)
|
|
|
|
|
{
|
|
|
|
|
kprintf_set_renderer(&fb_kprintf_renderer);
|
|
|
|
|
vga_init(VGA_COLOR_LIGHT_GREY, VGA_COLOR_BLACK);
|
|
|
|
|
|
|
|
|
|
print_gay_propaganda();
|
|
|
|
|
|
|
|
|
|
while (1);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|