Writing (debug output) to screen

This commit is contained in:
Thomas Lovén 2017-12-04 00:22:39 +01:00
parent b9e9df32f5
commit 4f00d428bf
5 changed files with 134 additions and 26 deletions

View File

@ -2,6 +2,7 @@
#include <stdarg.h> #include <stdarg.h>
#include <stdint.h> #include <stdint.h>
#include <serial.h> #include <serial.h>
#include <vga.h>
// TODO: Temporary declarations // TODO: Temporary declarations
void vga_write(char c); void vga_write(char c);

View File

@ -1,36 +1,13 @@
#include <memory.h> #include <memory.h>
#include <serial.h> #include <serial.h>
#include <vga.h>
#include <debug.h> #include <debug.h>
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() void kmain()
{ {
clear_screen();
print_string("Hello from c, world!");
serial_init(PORT_COM1); serial_init(PORT_COM1);
vga_init();
debug_printf("Hello from debug printing function!\n"); debug_printf("Hello from debug printing function!\n");
debug_printf("A number:%d\n", 12345); debug_printf("A number:%d\n", 12345);
for(;;); for(;;);

37
src/kernel/drivers/vga.c Normal file
View File

@ -0,0 +1,37 @@
#include <vga.h>
#include <memory.h>
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();
}

79
src/kernel/drivers/vga.tt Normal file
View File

@ -0,0 +1,79 @@
// vim: ft=c
#include <ttest.h>
#include <vga.h>
#undef VGA_MEMORY
#define VGA_MEMORY calloc(80*24,3)
#include "vga.c"
#include <stdint.h>
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');
}

14
src/kernel/include/vga.h Normal file
View File

@ -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);