From d1cefde0065be153be3b66c5729eac3b6869155b Mon Sep 17 00:00:00 2001 From: Andreas Baumann Date: Mon, 1 May 2017 18:28:00 +0200 Subject: added some primitive VGA functions and rewrote kernel.c greeting --- src/Makefile | 4 ++-- src/kernel.c | 38 ++++++++++++++++++------------------- src/stage1_functions.asm | 2 +- src/vga.c | 49 ++++++++++++++++++++++++++++++++++++++++++++++-- src/vga.h | 30 +++++++++++++++++++++++++++-- 5 files changed, 97 insertions(+), 26 deletions(-) diff --git a/src/Makefile b/src/Makefile index fcde58d..0d9cc1e 100644 --- a/src/Makefile +++ b/src/Makefile @@ -7,8 +7,8 @@ all: image.bin image.bin: boot.bin kernel.bin cat boot.bin kernel.bin > image.bin # truncate to correct number of sectors, we have - # 512 (boot, first stage) + N * 512 (N currenty is 3) + M * 512 (M is currently 2) - truncate -s 3072 image.bin + # 512 (boot, first stage) + N * 512 (N currenty is 3) + M * 512 (M is currently 3) + truncate -s 3584 image.bin boot.bin: boot.asm gdt.asm stage1_functions.asm stage2_functions.asm switch_mode.asm nasm boot.asm -f bin -o boot.bin diff --git a/src/kernel.c b/src/kernel.c index a73ead6..bdca5e7 100644 --- a/src/kernel.c +++ b/src/kernel.c @@ -4,33 +4,33 @@ void entry( void ) { - volatile uint8_t *VIDEO_MEMORY = (uint8_t *)0xb8000; - - *VIDEO_MEMORY = 'H'; - *(VIDEO_MEMORY+2) = 'E'; - *(VIDEO_MEMORY+4) = 'L'; - *(VIDEO_MEMORY+6) = 'L'; - *(VIDEO_MEMORY+8) = 'O'; - *(VIDEO_MEMORY+10) = '_'; + vga_t vga; + vga_init( &vga ); - // clang 4.0.0 eliminates the 'bar' part of the loop, unless - // we declate 'bar' volatile? + vga_set_color( &vga, VGA_COLOR_LIGHT_GREY ); + vga_set_background_color( &vga, VGA_COLOR_BLACK ); + + vga_put_char( &vga, 0, 0, 'A' ); + vga_put_char( &vga, 1, 0, 'B' ); + vga_put_char( &vga, 2, 0, 'A' ); + vga_put_char( &vga, 3, 0, 'O' ); + vga_put_char( &vga, 4, 0, 'S' ); + volatile uint8_t bar[] = "\\|/-"; - int pos = 10; + int pos = 5; int i = 0; for( i = 0; i < 10000; i++ ) { if( i % 1000 == 0 ) { - *(VIDEO_MEMORY+pos) = '.'; - *(VIDEO_MEMORY+pos+1) = 0x07; - pos += 2; + vga_put_char( &vga, pos, 0, '.' ); + pos++; } - *(VIDEO_MEMORY+pos) = bar[i%4]; - *(VIDEO_MEMORY+pos+1) = 0x07; - for( int j = 0; j < 1000; j++ ) { + vga_put_char( &vga, pos, 0, bar[i%4] ); + for( int j = 0; j < 10000; j++ ) { } } + vga_put_char( &vga, pos, 0, '.' ); - vga_t vga; - vga_init( &vga ); + vga_set_color( &vga, VGA_COLOR_WHITE ); + vga_set_background_color( &vga, VGA_COLOR_RED ); vga_clear_screen( &vga ); } diff --git a/src/stage1_functions.asm b/src/stage1_functions.asm index 35a0dbb..575a465 100644 --- a/src/stage1_functions.asm +++ b/src/stage1_functions.asm @@ -3,7 +3,7 @@ ; 3 * 512 for bootloader stage2 and the kernel code ; (note: the first sector gets loaded by the BIOS, so ; subtract 1 here!) -NOF_LOAD_SECTORS equ 5 +NOF_LOAD_SECTORS equ 6 ; IN bx: begin of memory area to dump ; IN ax: number of words to dump diff --git a/src/vga.c b/src/vga.c index 77ef043..767d45f 100644 --- a/src/vga.c +++ b/src/vga.c @@ -2,12 +2,17 @@ #include "string.h" +static int calculate_offset( vga_t *vga ); +static uint8_t calculate_color_cell( vga_t *vga ); + void vga_init( vga_t *vga ) { memset( vga, 0, sizeof( vga_t ) ); vga->res_x = VGA_DEFAULT_RES_X; vga->res_y = VGA_DEFAULT_RES_Y; + vga->color = VGA_COLOR_DARK_GREY; + vga->background_color = VGA_COLOR_BLACK; // TODO: get current position from VGA hardware //~ vga_set_cursor( vga, 0, 0 ); @@ -19,14 +24,54 @@ void vga_clear_screen( vga_t *vga ) for( int i = 0; i < 2 * ( vga->res_x * vga->res_y ); i += 2 ) { *(VIDEO_MEMORY+i) = ' '; - *(VIDEO_MEMORY+i+1) = 0x4f; + *(VIDEO_MEMORY+i+1) = calculate_color_cell( vga ); } //~ vga_set_cursor( vga, 0, 0 ); } -void vga_set_cursor( vga_t *vga, int x, int y ) +void vga_set_cursor( vga_t *vga, const int x, const int y ) { vga->cursor_x = x; vga->cursor_y = y; } + +void vga_set_color( vga_t *vga, const vga_color_t color ) +{ + vga->color = color; +} + +void vga_set_background_color( vga_t *vga, const vga_color_t color ) +{ + vga->background_color = color; +} + +static int calculate_offset( vga_t *vga ) +{ + int offset = ( vga->res_x * vga->cursor_y + vga->cursor_x ) * 2; + + return offset; +} + +static uint8_t calculate_color_cell( vga_t *vga ) +{ + uint8_t cell; + + cell = ( vga->background_color << 4 ) | vga->color; + + return cell; +} + +void vga_put_char( vga_t *vga, const int x, const int y, const uint8_t c ) +{ + // TODO: PANIC? OUT OF BOUND ACCESS + if( x > vga->res_x || y > vga->res_y ) return; + + vga_set_cursor( vga, x, y ); + + int offset = calculate_offset( vga ); + + volatile uint8_t *VIDEO_MEMORY = (uint8_t *)0xb8000; + *(VIDEO_MEMORY+offset) = c; + *(VIDEO_MEMORY+offset+1) = calculate_color_cell( vga ); +} diff --git a/src/vga.h b/src/vga.h index 43ef751..8aef4e6 100644 --- a/src/vga.h +++ b/src/vga.h @@ -1,20 +1,46 @@ #ifndef VGA_H #define VGA_H +#include "sys/types.h" + enum { VGA_DEFAULT_RES_X = 80, VGA_DEFAULT_RES_Y = 25 }; +typedef enum { + 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 +} vga_color_t; + typedef struct vga_t { int res_x; // resolution, default 80 int res_y; // resolution, default 25 int cursor_x; // current cursor position X int cursor_y; // current cursor position Y + vga_color_t color; + vga_color_t background_color; } vga_t; void vga_init( vga_t *vga ); void vga_clear_screen( vga_t *vga ); -void vga_set_cursor( vga_t *vga, int x, int y ); - +void vga_set_cursor( vga_t *vga, const int x, const int y ); +void vga_set_color( vga_t *vga, const vga_color_t color ); +void vga_set_background_color( vga_t *vga, const vga_color_t color ); +void vga_put_char( vga_t *vga, const int x, const int y, const uint8_t c ); + #endif /* VGA_H */ -- cgit v1.2.3-54-g00ecf