From 1625a4752545e54c439a38f3393ab9d72bfee721 Mon Sep 17 00:00:00 2001 From: Andreas Baumann Date: Sat, 10 Jun 2017 20:47:22 +0200 Subject: renamed text VGA module to vgatext --- src/Makefile | 10 +-- src/console.c | 18 ++-- src/console.h | 6 +- src/kernel.c | 34 ++++---- src/mouse.c | 6 +- src/vga.c | 262 ---------------------------------------------------------- src/vga.h | 68 --------------- src/vgatext.c | 262 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ src/vgatext.h | 68 +++++++++++++++ 9 files changed, 367 insertions(+), 367 deletions(-) delete mode 100644 src/vga.c delete mode 100644 src/vga.h create mode 100644 src/vgatext.c create mode 100644 src/vgatext.h (limited to 'src') diff --git a/src/Makefile b/src/Makefile index c7925bf..9688ebc 100644 --- a/src/Makefile +++ b/src/Makefile @@ -33,9 +33,9 @@ kernel.bin: kernel.elf kernel.sym: kernel.elf $(OBJCOPY) --only-keep-debug kernel.elf kernel.sym -kernel.elf: kernel.o kernel_asm.o console.o vga.o serial.o port.o port_asm.o interrupts.o interrupts_asm.o driver.o pci.o keyboard.o mouse.o string.o stdlib.o stdio.o setjmp.o +kernel.elf: kernel.o kernel_asm.o console.o vgatext.o serial.o port.o port_asm.o interrupts.o interrupts_asm.o driver.o pci.o keyboard.o mouse.o string.o stdlib.o stdio.o setjmp.o $(LD) -o kernel.elf -N -n -Ttext 0x8400 --oformat elf32-i386 \ - kernel.o kernel_asm.o console.o vga.o serial.o \ + kernel.o kernel_asm.o console.o vgatext.o serial.o \ port.o port_asm.o interrupts.o interrupts_asm.o \ driver.o pci.o \ keyboard.o mouse.o \ @@ -56,11 +56,11 @@ port.o: port.c port.h port_asm.o: port.asm $(NASM) port.asm $(NASMFLAGS) -o port_asm.o -console.o: console.c console.h vga.h serial.h +console.o: console.c console.h vgatext.h serial.h $(CC) $(CFLAGS) -c -o console.o console.c -vga.o: vga.c vga.h - $(CC) $(CFLAGS) -c -o vga.o vga.c +vgatext.o: vgatext.c vgatext.h + $(CC) $(CFLAGS) -c -o vgatext.o vgatext.c serial.o: serial.c serial.h $(CC) $(CFLAGS) -c -o serial.o serial.c diff --git a/src/console.c b/src/console.c index ef4c36f..6113823 100644 --- a/src/console.c +++ b/src/console.c @@ -7,13 +7,13 @@ void console_init( console_t *console ) { memset( console, 0, sizeof( console_t ) ); - console->vga = NULL; + console->vga_text = NULL; console->serial = NULL; } -void console_add_vga_output( console_t *console, vga_t *vga ) +void console_add_vga_text_output( console_t *console, vga_text_t *vga_text ) { - console->vga = vga; + console->vga_text = vga_text; } void console_add_serial_output( console_t *console, serial_t *serial ) @@ -23,8 +23,8 @@ void console_add_serial_output( console_t *console, serial_t *serial ) void console_put_char( console_t *console, const char c ) { - if( console->vga != NULL ) { - vga_put_char( console->vga, c ); + if( console->vga_text != NULL ) { + vga_text_put_char( console->vga_text, c ); } if( console->serial != NULL ) { @@ -34,8 +34,8 @@ void console_put_char( console_t *console, const char c ) void console_put_string( console_t *console, const char *s ) { - if( console->vga != NULL ) { - vga_put_string( console->vga, s ); + if( console->vga_text != NULL ) { + vga_text_put_string( console->vga_text, s ); } if( console->serial != NULL ) { @@ -45,8 +45,8 @@ void console_put_string( console_t *console, const char *s ) void console_put_newline( console_t *console ) { - if( console->vga != NULL ) { - vga_put_newline( console->vga ); + if( console->vga_text != NULL ) { + vga_text_put_newline( console->vga_text ); } if( console->serial != NULL ) { diff --git a/src/console.h b/src/console.h index f8eccff..a1c55ac 100644 --- a/src/console.h +++ b/src/console.h @@ -1,16 +1,16 @@ #ifndef CONSOLE_H #define CONSOLE_H -#include "vga.h" +#include "vgatext.h" #include "serial.h" typedef struct { - vga_t *vga; + vga_text_t *vga_text; serial_t *serial; } console_t; void console_init( console_t *console ); -void console_add_vga_output( console_t *console, vga_t *vga ); +void console_add_vga_text_output( console_t *console, vga_text_t *vga_text ); void console_add_serial_output( console_t *console, serial_t *serial ); void console_put_char( console_t *console, const char c ); void console_put_string( console_t *console, const char *s ); diff --git a/src/kernel.c b/src/kernel.c index 3f873ef..3c520d6 100644 --- a/src/kernel.c +++ b/src/kernel.c @@ -2,7 +2,7 @@ #include #include -#include "vga.h" +#include "vgatext.h" #include "serial.h" #include "console.h" #include "stdlib.h" @@ -35,14 +35,14 @@ void kernel_main( void ) serial_t serial; serial_init( &serial ); - vga_t vga; - vga_init( &vga ); - vga_set_color( &vga, VGA_COLOR_LIGHT_GREY ); - vga_set_background_color( &vga, VGA_COLOR_BLACK ); + vga_text_t vga_text; + vga_text_init( &vga_text ); + vga_text_set_color( &vga_text, VGA_TEXT_COLOR_LIGHT_GREY ); + vga_text_set_background_color( &vga_text, VGA_TEXT_COLOR_BLACK ); console_t console; console_init( &console ); - console_add_vga_output( &console, &vga ); + console_add_vga_text_output( &console, &vga_text ); console_add_serial_output( &console, &serial ); // initialize the early console of the kernel @@ -68,14 +68,14 @@ void kernel_main( void ) // hard-wired drivers keyboard_t keyboard; - keyboard_init( &keyboard, &handle_keyboard_event, (void *)&vga ); + keyboard_init( &keyboard, &handle_keyboard_event, (void *)&vga_text ); interrupt_handler_t keyboard_interrupt_handler; interrupt_handler_init( &keyboard_interrupt_handler, IRQ_BASE + 0x01, &interrupt, keyboard_handle_interrupt, &keyboard ); interrupts_register_interrupt_handler( keyboard_interrupt_handler ); driver_manager_add_driver( &driver_manager, (driver_t *)&keyboard ); mouse_t mouse; - mouse_init( &mouse, &handle_mouse_event, (void *)&vga ); + mouse_init( &mouse, &handle_mouse_event, (void *)&vga_text ); interrupt_handler_t mouse_interrupt_handler; interrupt_handler_init( &mouse_interrupt_handler, IRQ_BASE + 0x0C, &interrupt, mouse_handle_interrupt, &mouse ); interrupts_register_interrupt_handler( mouse_interrupt_handler ); @@ -136,9 +136,9 @@ static void handle_keyboard_event( keyboard_event_t *event, void *context ) { static int pos = 0; static char buf[80]; - vga_t *vga = (vga_t *)context; + vga_text_t *vga_text = (vga_text_t *)context; - vga_hide_mouse_cursor( vga ); + vga_text_hide_mouse_cursor( vga_text ); if( event->type == KEYBOARD_EVENT_TYPE_KEY_PRESSED ) { if( event->key == KEYBOARD_KEY_ASCII ) { @@ -177,26 +177,26 @@ static void handle_keyboard_event( keyboard_event_t *event, void *context ) static void handle_mouse_event( mouse_event_t *event, void *context ) { - vga_t *vga = (vga_t *)context; + vga_text_t *vga_text = (vga_text_t *)context; switch( event->type ) { case MOUSE_EVENT_TYPE_BUTTON_UP: - vga_hide_mouse_cursor( vga ); + vga_text_hide_mouse_cursor( vga_text ); printf( "MOUSE UP %d AT X:%d, Y:%d\n", event->button, event->cursor_x, event->cursor_y ); - vga_show_mouse_cursor( vga ); + vga_text_show_mouse_cursor( vga_text ); break; case MOUSE_EVENT_TYPE_BUTTON_DOWN: - vga_hide_mouse_cursor( vga ); + vga_text_hide_mouse_cursor( vga_text ); printf( "MOUSE DOWN %d AT X:%d, Y:%d\n", event->button, event->cursor_x, event->cursor_y ); - vga_show_mouse_cursor( vga ); + vga_text_show_mouse_cursor( vga_text ); break; case MOUSE_EVENT_TYPE_MOVE: - vga_move_mouse_cursor( vga, event->cursor_x, event->cursor_y ); - vga_show_mouse_cursor( vga ); + vga_text_move_mouse_cursor( vga_text, event->cursor_x, event->cursor_y ); + vga_text_show_mouse_cursor( vga_text ); break; } } diff --git a/src/mouse.c b/src/mouse.c index 0e1d736..46984eb 100644 --- a/src/mouse.c +++ b/src/mouse.c @@ -92,10 +92,10 @@ void mouse_init( mouse_t *mouse, mouse_event_handler_t handler, void *context ) // TODO: we should probe for wheel mouse and more than 3 packets mouse->nof_packets = DEFAULT_NOF_PACKETS; - vga_t *vga = (vga_t *)context; + vga_text_t *vga_text = (vga_text_t *)context; - mouse->res_x = vga->res_x; - mouse->res_y = vga->res_y; + mouse->res_x = vga_text->res_x; + mouse->res_y = vga_text->res_y; mouse->cursor_x = mouse->res_x / 2; mouse->cursor_y = mouse->res_y / 2; mouse->handler = handler; diff --git a/src/vga.c b/src/vga.c deleted file mode 100644 index 1356d62..0000000 --- a/src/vga.c +++ /dev/null @@ -1,262 +0,0 @@ -#include "vga.h" - -#include - -#include "string.h" -#include "stdlib.h" -#include "kernel.h" - -static bool params_ok( vga_t *vga, const int x, const int y ); -static int calculate_offset( vga_t *vga, const int x, const int y ); -static uint8_t calculate_color_cell( vga_t *vga ); -static void scroll_screen( 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; - vga->show_mouse_cursor = false; - vga->mouse_cursor_x = -1; - vga->mouse_cursor_y = -1; - - // make sure we use the 0x3dx VGA ports, is done - // in assembly in stage 2 too - port8_init( &vga->crtc_misc_port, 0x3d2 ); - port8_write( &vga->crtc_misc_port, 1 ); - - // set up VGA ports - port8_init( &vga->crtc_index_port, 0x3d4 ); - port8_init( &vga->crtc_data_port, 0x3d5 ); - - vga_set_cursor_from_hardware( vga ); -}; - -void vga_clear_screen( vga_t *vga ) -{ - volatile uint8_t *VIDEO_MEMORY = (uint8_t *)0xb8000; - - for( int i = 0; i < 2 * ( vga->res_x * vga->res_y ); i += 2 ) { - *(VIDEO_MEMORY+i) = ' '; - *(VIDEO_MEMORY+i+1) = calculate_color_cell( vga ); - } - - vga_set_cursor( vga, 0, 0 ); -} - -void vga_set_cursor( vga_t *vga, const int x, const int y ) -{ - if( !params_ok( vga, x, y ) ) { - kernel_panic( "Cursor parameters out of bounds: (%d, %d), resolution is only (%d, %d)", - x, y, vga->res_x, vga->res_y ); - } - - vga->cursor_x = x; - vga->cursor_y = y; - - // TODO: have a silent mode where we don't update the cursor - vga_set_cursor_on_hardware( vga ); -} - -void vga_set_cursor_from_hardware( vga_t *vga ) -{ - uint16_t hw_cursor_pos; - - port8_write( &vga->crtc_index_port, 14 ); - uint8_t data = port8_read( &(vga->crtc_data_port ) ); - hw_cursor_pos = data << 8; - - port8_write( &vga->crtc_index_port, 15 ); - data = port8_read( &(vga->crtc_data_port ) ); - - hw_cursor_pos |= data; - - vga->cursor_x = hw_cursor_pos % vga->res_x; - vga->cursor_y = hw_cursor_pos / vga->res_x; - - // reset to sane values if we get funny values from the VGA card - if( vga->cursor_x < 0 || vga->cursor_x > vga->res_x || - vga->cursor_y < 0 || vga->cursor_y > vga->res_y ) { - vga->cursor_x = 0; - vga->cursor_y = 0; - } -} - -void vga_set_cursor_on_hardware( vga_t *vga ) -{ - uint16_t hw_cursor_pos = vga->cursor_x + vga->cursor_y * vga->res_x; - - port8_write( &vga->crtc_index_port, 15 ); - port8_write( &vga->crtc_data_port, hw_cursor_pos & 0xff ); - port8_write( &vga->crtc_index_port, 14 ); - port8_write( &vga->crtc_data_port, hw_cursor_pos >> 8 ); -} - -int vga_get_cursor_x( vga_t *vga ) -{ - return vga->cursor_x; -} - -int vga_get_cursor_y( vga_t *vga ) -{ - return vga->cursor_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, const int x, const int y ) -{ - int offset = ( vga->res_x * y + x ) * 2; - - return offset; -} - -static void scroll_screen( vga_t *vga ) -{ - volatile uint8_t *VIDEO_MEMORY = (uint8_t *)0xb8000; - - memmove( (void *)VIDEO_MEMORY, (const void *)VIDEO_MEMORY + 2 * vga->res_x, 2 * ( vga->res_y - 1 ) * vga->res_x ); - - for( int i = 2 * ( vga->res_x * ( vga->res_y - 1 ) ); i < 2 * ( vga->res_x * vga->res_y ); i += 2 ) { - *(VIDEO_MEMORY+i) = ' '; - *(VIDEO_MEMORY+i+1) = calculate_color_cell( vga ); - } - - vga->cursor_y = vga->res_y - 1; -} - -static uint8_t calculate_color_cell( vga_t *vga ) -{ - uint8_t cell; - - cell = ( vga->background_color << 4 ) | vga->color; - - return cell; -} - -static bool params_ok( vga_t *vga, const int x, const int y ) -{ - if( x > vga->res_x || y > vga->res_y ) return false; - - return true; -} - -void vga_put_char_at( vga_t *vga, const int x, const int y, const char c ) -{ - vga_set_cursor( vga, x, y ); - vga_put_char( vga, c ); -} - - -void vga_put_string_at( vga_t *vga, const int x, const int y, const char *s ) -{ - vga_set_cursor( vga, x, y ); - vga_put_string( vga, s ); -} - -void vga_put_char( vga_t *vga, const char c ) -{ - int offset = calculate_offset( vga, vga->cursor_x, vga->cursor_y ); - - volatile uint8_t *VIDEO_MEMORY = (uint8_t *)0xb8000; - *(VIDEO_MEMORY+offset) = (uint8_t)c; - *(VIDEO_MEMORY+offset+1) = calculate_color_cell( vga ); - - vga->cursor_x++; - if( vga->cursor_x >= vga->res_x ) { - vga->cursor_x = 0; - vga->cursor_y++; - if( vga->cursor_y >= vga->res_y ) { - scroll_screen( vga ); - } - } - - vga_set_cursor_on_hardware( vga ); -} - -void vga_put_string( vga_t *vga, const char *s ) -{ - for( size_t i = 0; i < strlen( s ); i++ ) { - vga_put_char( vga, s[i] ); - } -} - -void vga_put_newline( vga_t *vga ) -{ - vga->cursor_x = 0; - vga->cursor_y++; - if( vga->cursor_y >= vga->res_y ) { - scroll_screen( vga ); - } - - vga_set_cursor_on_hardware( vga ); -} - -void vga_set_background_color_at( vga_t *vga, const int x, const int y, vga_color_t color ) -{ - int offset = calculate_offset( vga, x, y ); - - volatile uint8_t *VIDEO_MEMORY = (uint8_t *)0xb8000; - *(VIDEO_MEMORY+offset+1) = ( *(VIDEO_MEMORY+offset+1) & 0x0f ) | ( color << 4 ); -} - -vga_color_t vga_get_background_color_at( vga_t *vga, const int x, const int y ) -{ - int offset = calculate_offset( vga, x, y ); - - volatile uint8_t *VIDEO_MEMORY = (uint8_t *)0xb8000; - uint8_t cell = *(VIDEO_MEMORY+offset+1); - - return cell & 0xf0; -} - -void vga_inverse_colors_at( vga_t *vga, const int x, const int y ) -{ - int offset = calculate_offset( vga, x, y ); - - volatile uint8_t *VIDEO_MEMORY = (uint8_t *)0xb8000; - *(VIDEO_MEMORY+offset+1) = ( ( *(VIDEO_MEMORY+offset+1) & 0x0f ) << 4 ) - | ( ( *(VIDEO_MEMORY+offset+1) & 0xf0 ) >> 4 ); -} - -void vga_show_mouse_cursor( vga_t *vga ) -{ - if( !vga->show_mouse_cursor ) { - vga->show_mouse_cursor = true; - vga_inverse_colors_at( vga, vga->mouse_cursor_x, vga->mouse_cursor_y ); - } -} - -void vga_move_mouse_cursor( vga_t *vga, const int x, const int y ) -{ - if( vga->show_mouse_cursor ) { - vga_inverse_colors_at( vga, vga->mouse_cursor_x, vga->mouse_cursor_y ); - } - - vga->mouse_cursor_x = x; - vga->mouse_cursor_y = y; - - if( vga->show_mouse_cursor ) { - vga_inverse_colors_at( vga, vga->mouse_cursor_x, vga->mouse_cursor_y ); - } -} - -void vga_hide_mouse_cursor( vga_t *vga ) -{ - if( vga->show_mouse_cursor ) { - vga_inverse_colors_at( vga, vga->mouse_cursor_x, vga->mouse_cursor_y ); - vga->show_mouse_cursor = false; - } -} - diff --git a/src/vga.h b/src/vga.h deleted file mode 100644 index 695c228..0000000 --- a/src/vga.h +++ /dev/null @@ -1,68 +0,0 @@ -#ifndef VGA_H -#define VGA_H - -#include - -#include "port.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 { - 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; - port8_t crtc_misc_port; - port8_t crtc_index_port; - port8_t crtc_data_port; - bool show_mouse_cursor; - int mouse_cursor_x; - int mouse_cursor_y; -} vga_t; - -void vga_init( vga_t *vga ); -void vga_clear_screen( vga_t *vga ); -void vga_set_cursor( vga_t *vga, const int x, const int y ); -void vga_set_cursor_from_hardware( vga_t *vga ); -void vga_set_cursor_on_hardware( vga_t *vga ); -int vga_get_cursor_x( vga_t *vga ); -int vga_get_cursor_y( vga_t *vga ); -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_at( vga_t *vga, const int x, const int y, const char c ); -void vga_put_string_at( vga_t *vga, const int x, const int y, const char *s ); -void vga_put_char( vga_t *vga, const char c ); -void vga_put_string( vga_t *vga, const char *s ); -void vga_put_newline( vga_t *vga ); -void vga_set_background_color_at( vga_t *vga, const int x, const int y, vga_color_t color ); -vga_color_t vga_get_background_color_at( vga_t *vga, const int x, const int y ); -void vga_inverse_colors_at( vga_t *vga, const int x, const int y ); -void vga_show_mouse_cursor( vga_t *vga ); -void vga_move_mouse_cursor( vga_t *vga, const int x, const int y ); -void vga_hide_mouse_cursor( vga_t *vga ); - -#endif /* VGA_H */ diff --git a/src/vgatext.c b/src/vgatext.c new file mode 100644 index 0000000..cbee587 --- /dev/null +++ b/src/vgatext.c @@ -0,0 +1,262 @@ +#include "vgatext.h" + +#include + +#include "string.h" +#include "stdlib.h" +#include "kernel.h" + +static bool params_ok( vga_text_t *vga_text, const int x, const int y ); +static int calculate_offset( vga_text_t *vga_text, const int x, const int y ); +static uint8_t calculate_color_cell( vga_text_t *vga_text ); +static void scroll_screen( vga_text_t *vga_text ); + +void vga_text_init( vga_text_t *vga_text ) +{ + memset( vga_text, 0, sizeof( vga_text_t ) ); + + vga_text->res_x = VGA_TEXT_DEFAULT_RES_X; + vga_text->res_y = VGA_TEXT_DEFAULT_RES_Y; + vga_text->color = VGA_TEXT_COLOR_DARK_GREY; + vga_text->background_color = VGA_TEXT_COLOR_BLACK; + vga_text->show_mouse_cursor = false; + vga_text->mouse_cursor_x = -1; + vga_text->mouse_cursor_y = -1; + + // make sure we use the 0x3dx VGA_TEXT ports, is done + // in assembly in stage 2 too + port8_init( &vga_text->crtc_misc_port, 0x3d2 ); + port8_write( &vga_text->crtc_misc_port, 1 ); + + // set up VGA_TEXT ports + port8_init( &vga_text->crtc_index_port, 0x3d4 ); + port8_init( &vga_text->crtc_data_port, 0x3d5 ); + + vga_text_set_cursor_from_hardware( vga_text ); +}; + +void vga_text_clear_screen( vga_text_t *vga_text ) +{ + volatile uint8_t *VIDEO_MEMORY = (uint8_t *)0xb8000; + + for( int i = 0; i < 2 * ( vga_text->res_x * vga_text->res_y ); i += 2 ) { + *(VIDEO_MEMORY+i) = ' '; + *(VIDEO_MEMORY+i+1) = calculate_color_cell( vga_text ); + } + + vga_text_set_cursor( vga_text, 0, 0 ); +} + +void vga_text_set_cursor( vga_text_t *vga_text, const int x, const int y ) +{ + if( !params_ok( vga_text, x, y ) ) { + kernel_panic( "Cursor parameters out of bounds: (%d, %d), resolution is only (%d, %d)", + x, y, vga_text->res_x, vga_text->res_y ); + } + + vga_text->cursor_x = x; + vga_text->cursor_y = y; + + // TODO: have a silent mode where we don't update the cursor + vga_text_set_cursor_on_hardware( vga_text ); +} + +void vga_text_set_cursor_from_hardware( vga_text_t *vga_text ) +{ + uint16_t hw_cursor_pos; + + port8_write( &vga_text->crtc_index_port, 14 ); + uint8_t data = port8_read( &(vga_text->crtc_data_port ) ); + hw_cursor_pos = data << 8; + + port8_write( &vga_text->crtc_index_port, 15 ); + data = port8_read( &(vga_text->crtc_data_port ) ); + + hw_cursor_pos |= data; + + vga_text->cursor_x = hw_cursor_pos % vga_text->res_x; + vga_text->cursor_y = hw_cursor_pos / vga_text->res_x; + + // reset to sane values if we get funny values from the VGA_TEXT card + if( vga_text->cursor_x < 0 || vga_text->cursor_x > vga_text->res_x || + vga_text->cursor_y < 0 || vga_text->cursor_y > vga_text->res_y ) { + vga_text->cursor_x = 0; + vga_text->cursor_y = 0; + } +} + +void vga_text_set_cursor_on_hardware( vga_text_t *vga_text ) +{ + uint16_t hw_cursor_pos = vga_text->cursor_x + vga_text->cursor_y * vga_text->res_x; + + port8_write( &vga_text->crtc_index_port, 15 ); + port8_write( &vga_text->crtc_data_port, hw_cursor_pos & 0xff ); + port8_write( &vga_text->crtc_index_port, 14 ); + port8_write( &vga_text->crtc_data_port, hw_cursor_pos >> 8 ); +} + +int vga_text_get_cursor_x( vga_text_t *vga_text ) +{ + return vga_text->cursor_x; +} + +int vga_text_get_cursor_y( vga_text_t *vga_text ) +{ + return vga_text->cursor_y; +} + +void vga_text_set_color( vga_text_t *vga_text, const vga_text_color_t color ) +{ + vga_text->color = color; +} + +void vga_text_set_background_color( vga_text_t *vga_text, const vga_text_color_t color ) +{ + vga_text->background_color = color; +} + +static int calculate_offset( vga_text_t *vga_text, const int x, const int y ) +{ + int offset = ( vga_text->res_x * y + x ) * 2; + + return offset; +} + +static void scroll_screen( vga_text_t *vga_text ) +{ + volatile uint8_t *VIDEO_MEMORY = (uint8_t *)0xb8000; + + memmove( (void *)VIDEO_MEMORY, (const void *)VIDEO_MEMORY + 2 * vga_text->res_x, 2 * ( vga_text->res_y - 1 ) * vga_text->res_x ); + + for( int i = 2 * ( vga_text->res_x * ( vga_text->res_y - 1 ) ); i < 2 * ( vga_text->res_x * vga_text->res_y ); i += 2 ) { + *(VIDEO_MEMORY+i) = ' '; + *(VIDEO_MEMORY+i+1) = calculate_color_cell( vga_text ); + } + + vga_text->cursor_y = vga_text->res_y - 1; +} + +static uint8_t calculate_color_cell( vga_text_t *vga_text ) +{ + uint8_t cell; + + cell = ( vga_text->background_color << 4 ) | vga_text->color; + + return cell; +} + +static bool params_ok( vga_text_t *vga_text, const int x, const int y ) +{ + if( x > vga_text->res_x || y > vga_text->res_y ) return false; + + return true; +} + +void vga_text_put_char_at( vga_text_t *vga_text, const int x, const int y, const char c ) +{ + vga_text_set_cursor( vga_text, x, y ); + vga_text_put_char( vga_text, c ); +} + + +void vga_text_put_string_at( vga_text_t *vga_text, const int x, const int y, const char *s ) +{ + vga_text_set_cursor( vga_text, x, y ); + vga_text_put_string( vga_text, s ); +} + +void vga_text_put_char( vga_text_t *vga_text, const char c ) +{ + int offset = calculate_offset( vga_text, vga_text->cursor_x, vga_text->cursor_y ); + + volatile uint8_t *VIDEO_MEMORY = (uint8_t *)0xb8000; + *(VIDEO_MEMORY+offset) = (uint8_t)c; + *(VIDEO_MEMORY+offset+1) = calculate_color_cell( vga_text ); + + vga_text->cursor_x++; + if( vga_text->cursor_x >= vga_text->res_x ) { + vga_text->cursor_x = 0; + vga_text->cursor_y++; + if( vga_text->cursor_y >= vga_text->res_y ) { + scroll_screen( vga_text ); + } + } + + vga_text_set_cursor_on_hardware( vga_text ); +} + +void vga_text_put_string( vga_text_t *vga_text, const char *s ) +{ + for( size_t i = 0; i < strlen( s ); i++ ) { + vga_text_put_char( vga_text, s[i] ); + } +} + +void vga_text_put_newline( vga_text_t *vga_text ) +{ + vga_text->cursor_x = 0; + vga_text->cursor_y++; + if( vga_text->cursor_y >= vga_text->res_y ) { + scroll_screen( vga_text ); + } + + vga_text_set_cursor_on_hardware( vga_text ); +} + +void vga_text_set_background_color_at( vga_text_t *vga_text, const int x, const int y, vga_text_color_t color ) +{ + int offset = calculate_offset( vga_text, x, y ); + + volatile uint8_t *VIDEO_MEMORY = (uint8_t *)0xb8000; + *(VIDEO_MEMORY+offset+1) = ( *(VIDEO_MEMORY+offset+1) & 0x0f ) | ( color << 4 ); +} + +vga_text_color_t vga_text_get_background_color_at( vga_text_t *vga_text, const int x, const int y ) +{ + int offset = calculate_offset( vga_text, x, y ); + + volatile uint8_t *VIDEO_MEMORY = (uint8_t *)0xb8000; + uint8_t cell = *(VIDEO_MEMORY+offset+1); + + return cell & 0xf0; +} + +void vga_text_inverse_colors_at( vga_text_t *vga_text, const int x, const int y ) +{ + int offset = calculate_offset( vga_text, x, y ); + + volatile uint8_t *VIDEO_MEMORY = (uint8_t *)0xb8000; + *(VIDEO_MEMORY+offset+1) = ( ( *(VIDEO_MEMORY+offset+1) & 0x0f ) << 4 ) + | ( ( *(VIDEO_MEMORY+offset+1) & 0xf0 ) >> 4 ); +} + +void vga_text_show_mouse_cursor( vga_text_t *vga_text ) +{ + if( !vga_text->show_mouse_cursor ) { + vga_text->show_mouse_cursor = true; + vga_text_inverse_colors_at( vga_text, vga_text->mouse_cursor_x, vga_text->mouse_cursor_y ); + } +} + +void vga_text_move_mouse_cursor( vga_text_t *vga_text, const int x, const int y ) +{ + if( vga_text->show_mouse_cursor ) { + vga_text_inverse_colors_at( vga_text, vga_text->mouse_cursor_x, vga_text->mouse_cursor_y ); + } + + vga_text->mouse_cursor_x = x; + vga_text->mouse_cursor_y = y; + + if( vga_text->show_mouse_cursor ) { + vga_text_inverse_colors_at( vga_text, vga_text->mouse_cursor_x, vga_text->mouse_cursor_y ); + } +} + +void vga_text_hide_mouse_cursor( vga_text_t *vga_text ) +{ + if( vga_text->show_mouse_cursor ) { + vga_text_inverse_colors_at( vga_text, vga_text->mouse_cursor_x, vga_text->mouse_cursor_y ); + vga_text->show_mouse_cursor = false; + } +} + diff --git a/src/vgatext.h b/src/vgatext.h new file mode 100644 index 0000000..499e3d8 --- /dev/null +++ b/src/vgatext.h @@ -0,0 +1,68 @@ +#ifndef VGA_TEXT_H +#define VGA_TEXT_H + +#include + +#include "port.h" + +enum { + VGA_TEXT_DEFAULT_RES_X = 80, + VGA_TEXT_DEFAULT_RES_Y = 25 +}; + +typedef enum { + VGA_TEXT_COLOR_BLACK = 0, + VGA_TEXT_COLOR_BLUE = 1, + VGA_TEXT_COLOR_GREEN = 2, + VGA_TEXT_COLOR_CYAN = 3, + VGA_TEXT_COLOR_RED = 4, + VGA_TEXT_COLOR_MAGENTA = 5, + VGA_TEXT_COLOR_BROWN = 6, + VGA_TEXT_COLOR_LIGHT_GREY = 7, + VGA_TEXT_COLOR_DARK_GREY = 8, + VGA_TEXT_COLOR_LIGHT_BLUE = 9, + VGA_TEXT_COLOR_LIGHT_GREEN = 10, + VGA_TEXT_COLOR_LIGHT_CYAN = 11, + VGA_TEXT_COLOR_LIGHT_RED = 12, + VGA_TEXT_COLOR_LIGHT_MAGENTA = 13, + VGA_TEXT_COLOR_LIGHT_BROWN = 14, + VGA_TEXT_COLOR_WHITE = 15 +} vga_text_color_t; + +typedef struct { + 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_text_color_t color; + vga_text_color_t background_color; + port8_t crtc_misc_port; + port8_t crtc_index_port; + port8_t crtc_data_port; + bool show_mouse_cursor; + int mouse_cursor_x; + int mouse_cursor_y; +} vga_text_t; + +void vga_text_init( vga_text_t *vga_text ); +void vga_text_clear_screen( vga_text_t *vga_text ); +void vga_text_set_cursor( vga_text_t *vga_text, const int x, const int y ); +void vga_text_set_cursor_from_hardware( vga_text_t *vga_text ); +void vga_text_set_cursor_on_hardware( vga_text_t *vga_text ); +int vga_text_get_cursor_x( vga_text_t *vga_text ); +int vga_text_get_cursor_y( vga_text_t *vga_text ); +void vga_text_set_color( vga_text_t *vga_text, const vga_text_color_t color ); +void vga_text_set_background_color( vga_text_t *vga_text, const vga_text_color_t color ); +void vga_text_put_char_at( vga_text_t *vga_text, const int x, const int y, const char c ); +void vga_text_put_string_at( vga_text_t *vga_text, const int x, const int y, const char *s ); +void vga_text_put_char( vga_text_t *vga_text, const char c ); +void vga_text_put_string( vga_text_t *vga_text, const char *s ); +void vga_text_put_newline( vga_text_t *vga_text ); +void vga_text_set_background_color_at( vga_text_t *vga_text, const int x, const int y, vga_text_color_t color ); +vga_text_color_t vga_text_get_background_color_at( vga_text_t *vga_text, const int x, const int y ); +void vga_text_inverse_colors_at( vga_text_t *vga_text, const int x, const int y ); +void vga_text_show_mouse_cursor( vga_text_t *vga_text ); +void vga_text_move_mouse_cursor( vga_text_t *vga_text, const int x, const int y ); +void vga_text_hide_mouse_cursor( vga_text_t *vga_text ); + +#endif /* VGA_TEXT_H */ -- cgit v1.2.3-54-g00ecf