Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions common/cmdline.c
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,9 @@ string_cmd("com3", opt_com3);
static char opt_com4[20];
string_cmd("com4", opt_com4);

bool opt_fb_scroll = true;
bool_cmd("fb_scroll", opt_fb_scroll);

const char *kernel_cmdline;

void __text_init cmdline_parse(const char *cmdline) {
Expand Down
59 changes: 46 additions & 13 deletions drivers/fb/fb.c
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,11 @@

extern uint64_t fonts[];

#define FONT_SIZE sizeof(fonts[0])
#define TEXT_AREA_FIRST_ROW (((LOGO_HEIGHT + FONT_SIZE) / FONT_SIZE) * FONT_SIZE)

static bool has_fb = false;
static bool scroll = false;

static uint32_t width;
static uint32_t height;
Expand All @@ -43,6 +47,10 @@ static size_t buffer_size;
static size_t banner_size;
static void *video_memory;

static void *first_line_addr;
static void *last_line_addr;
static uint64_t line_width;

static void (*put_pixel)(uint32_t x, uint32_t y, uint32_t color);

static void map_fb_area(paddr_t start, size_t size) {
Expand Down Expand Up @@ -82,7 +90,7 @@ void init_framebuffer(const struct multiboot2_tag_framebuffer *fb) {
bpp = fb->common.framebuffer_bpp;

buffer_size = (size_t) width * height;
banner_size = (size_t) width * LOGO_HEIGHT;
banner_size = (size_t) width * (LOGO_HEIGHT + FONT_SIZE);

switch (bpp) {
case 0 ... 7:
Expand Down Expand Up @@ -112,6 +120,10 @@ void init_framebuffer(const struct multiboot2_tag_framebuffer *fb) {
BUG();
}

line_width = pitch * FONT_SIZE;
first_line_addr = (uint8_t *) video_memory + TEXT_AREA_FIRST_ROW * pitch;
last_line_addr = (uint8_t *) video_memory + buffer_size - line_width;

has_fb = true;
}

Expand All @@ -123,14 +135,15 @@ bool setup_framebuffer(void) {
memset(video_memory, 0, buffer_size);

register_console_callback(fb_console_write, video_memory);
scroll = opt_fb_scroll;
return true;
}

void put_char(char c, uint32_t x, uint32_t y, uint32_t color) {
uint64_t font = fonts[(uint8_t) c];

for (int yy = 0; yy < 8; yy++) {
for (int xx = 0; xx < 8; xx++, font >>= 1) {
for (unsigned int yy = 0; yy < FONT_SIZE; yy++) {
for (unsigned int xx = 0; xx < FONT_SIZE; xx++, font >>= 1) {
if (font & 1)
put_pixel(x + xx, y + yy, color);
}
Expand All @@ -155,34 +168,54 @@ void draw_logo(void) {
put_pixel(x, y, *px++);
}

draw_line(0, LOGO_HEIGHT + 4, width, LOGO_HEIGHT + 4, FB_WHITE);
draw_line(0, LOGO_HEIGHT + 2, width, LOGO_HEIGHT + 2, FB_WHITE);
}

static void clear_screen(void *fb_addr) {
memset((uint8_t *) video_memory + banner_size, 0, buffer_size - banner_size);
void set_fb_scroll(bool state) {
scroll = state;
}

static inline void scroll_up_line(void) {
memmove(first_line_addr, first_line_addr + line_width,
last_line_addr - first_line_addr);
}

static inline void clear_screen(void) {
memset(first_line_addr, 0, last_line_addr - first_line_addr);
}

void fb_write(void *fb_addr, const char *buf, size_t len, uint32_t color) {
static uint32_t row = LOGO_HEIGHT + 8, col = 0;
static uint32_t row = TEXT_AREA_FIRST_ROW, col = 0;

for (unsigned int i = 0; i < len; i++) {
char c = buf[i];

if ((col + 8) > width || c == '\n') {
row += sizeof(fonts[0]);
if ((col + FONT_SIZE) >= width || c == '\n') {
row += FONT_SIZE;
col = 0;
}

if ((row + 8) > height) {
clear_screen(fb_addr);
row = LOGO_HEIGHT + 8;
if ((row + FONT_SIZE) >= height) {
if (scroll) {
scroll_up_line();
row -= FONT_SIZE;
}
else {
clear_screen();
row = TEXT_AREA_FIRST_ROW;
}
col = 0;
}

if (c == '\r') {
col = 0;
continue;
}

if (c == '\n')
continue;

put_char(c, col, row, color);
col += sizeof(fonts[0]);
col += FONT_SIZE;
}
}
1 change: 1 addition & 0 deletions include/cmdline.h
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@ extern bool opt_hpet;
extern bool opt_fpu;
extern bool opt_qemu_console;
extern bool opt_poweroff;
extern bool opt_fb_scroll;

extern const char *kernel_cmdline;

Expand Down
1 change: 1 addition & 0 deletions include/drivers/fb.h
Original file line number Diff line number Diff line change
Expand Up @@ -36,5 +36,6 @@ extern void draw_line(uint32_t x1, uint32_t y1, uint32_t x2, uint32_t y2, uint32
extern void draw_logo(void);
extern void fb_write(void *fb_addr, const char *buf, size_t len, uint32_t color);
extern bool setup_framebuffer(void);
extern void set_fb_scroll(bool state);

#endif /* KTF_DRV_FB_H */