From 4f00d428bff0034e4fad314bc5872a7e01315ef4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20Lov=C3=A9n?= Date: Mon, 4 Dec 2017 00:22:39 +0100 Subject: [PATCH] Writing (debug output) to screen --- src/kernel/boot/debug.c | 1 + src/kernel/boot/kmain.c | 29 ++------------ src/kernel/drivers/vga.c | 37 ++++++++++++++++++ src/kernel/drivers/vga.tt | 79 +++++++++++++++++++++++++++++++++++++++ src/kernel/include/vga.h | 14 +++++++ 5 files changed, 134 insertions(+), 26 deletions(-) create mode 100644 src/kernel/drivers/vga.c create mode 100644 src/kernel/drivers/vga.tt create mode 100644 src/kernel/include/vga.h diff --git a/src/kernel/boot/debug.c b/src/kernel/boot/debug.c index 79a3410..8369926 100644 --- a/src/kernel/boot/debug.c +++ b/src/kernel/boot/debug.c @@ -2,6 +2,7 @@ #include #include #include +#include // TODO: Temporary declarations void vga_write(char c); diff --git a/src/kernel/boot/kmain.c b/src/kernel/boot/kmain.c index f631748..60d4a80 100644 --- a/src/kernel/boot/kmain.c +++ b/src/kernel/boot/kmain.c @@ -1,36 +1,13 @@ #include #include +#include #include -void clear_screen() -{ - unsigned char *vidmem = P2V(0xB8000); - for(int i=0; i < 80*24*2; i++) - *vidmem++ = 0; -} - -void print_string(char *str) -{ - unsigned char *vidmem = P2V(0xB8000); - while(*str) - { - *vidmem++ = *str++; - *vidmem++ = 0x7; - } -} - -void vga_write(char c) -{ -// TODO: DUMMY - (void)c; -} - void kmain() { - clear_screen(); - print_string("Hello from c, world!"); - serial_init(PORT_COM1); + vga_init(); + debug_printf("Hello from debug printing function!\n"); debug_printf("A number:%d\n", 12345); for(;;); diff --git a/src/kernel/drivers/vga.c b/src/kernel/drivers/vga.c new file mode 100644 index 0000000..c1c3924 --- /dev/null +++ b/src/kernel/drivers/vga.c @@ -0,0 +1,37 @@ +#include +#include + +void *vidmem; +struct { + uint8_t character; + uint8_t format; +}__attribute__((packed)) buffer[VGA_SIZE]; + +uint64_t cursor; + +void vga_init() +{ + vidmem = VGA_MEMORY; + memset(vidmem, 0, VGA_SIZE*2); +} + +void flush() +{ + memcpy(vidmem, buffer, sizeof(buffer)); +} + +void vga_write(char c) +{ + switch(c) + { + case '\n': + cursor += VGA_COLS; + cursor -= VGA_COL(cursor); + break; + default: + buffer[cursor].character = c; + buffer[cursor].format = 0x7; + cursor++; + } + flush(); +} diff --git a/src/kernel/drivers/vga.tt b/src/kernel/drivers/vga.tt new file mode 100644 index 0000000..3e0971e --- /dev/null +++ b/src/kernel/drivers/vga.tt @@ -0,0 +1,79 @@ +// vim: ft=c +#include + +#include +#undef VGA_MEMORY +#define VGA_MEMORY calloc(80*24,3) +#include "vga.c" + +#include + +struct cell +{ + uint8_t c; + uint8_t f; +}__attribute__((packed)); + +struct cell *cells; + +BEFORE() +{ + vga_init(); + cells = vidmem; + cells[VGA_COLS*VGA_ROWS].c = '$'; +} + +#define VGA_ASSERT_EQ(pos, ch) ASSERT_EQ_CHR(cells[(pos)].c, (ch)) + + +TEST(vga_starts_with_a_clear_screen) +{ + VGA_ASSERT_EQ(VGA_COLS*VGA_ROWS-1, '\0'); +} + +TEST(vga_write_adds_character_to_vidmem) +{ + vga_write('a'); + VGA_ASSERT_EQ(0, 'a'); +} + +TEST(vga_output_is_visible) +{ + vga_write('a'); + ASSERT_NEQ_INT(cells[0].f, 0); +} + +TEST(vga_write_adds_multiple_characters_to_vidmem) +{ + vga_write('a'); + vga_write('b'); + VGA_ASSERT_EQ(1, 'b'); +} + +TEST(vga_writes_entire_screen_full) +{ + for(int i = 0; i < VGA_COLS*VGA_ROWS; i++) + vga_write('x'); + + VGA_ASSERT_EQ(VGA_POS(VGA_ROWS-1, VGA_COLS-1), 'x'); +} +TEST(vga_does_not_overflow_memory_area) +{ + for(int i = 0; i < (VGA_COLS*VGA_ROWS+1); i++) + vga_write('x'); + VGA_ASSERT_EQ(VGA_COLS*VGA_ROWS, '$'); +} + +TEST(newline_moves_down_one_line_when_at_beginning) +{ + vga_write('\n'); + vga_write('a'); + VGA_ASSERT_EQ(VGA_POS(1,0), 'a'); +} +TEST(newline_moves_to_beginning_of_line) +{ + vga_write('a'); + vga_write('\n'); + vga_write('b'); + VGA_ASSERT_EQ(VGA_POS(1,0), 'b'); +} diff --git a/src/kernel/include/vga.h b/src/kernel/include/vga.h new file mode 100644 index 0000000..8af2110 --- /dev/null +++ b/src/kernel/include/vga.h @@ -0,0 +1,14 @@ +#pragma once + +#define VGA_COLS 80 +#define VGA_ROWS 24 +#define VGA_SIZE (VGA_COLS*VGA_ROWS) + +#define VGA_ROW(pos) ((pos)/VGA_COLS) +#define VGA_COL(pos) ((pos)%VGA_COLS) +#define VGA_POS(row, col) ((row)*VGA_COLS + (col)) + +#define VGA_MEMORY P2V(0xB8000) + +void vga_init(); +void vga_write(char c);