From 752ff17265f23d4fa9084368d2a90f66521a98e2 Mon Sep 17 00:00:00 2001 From: Andreas Baumann Date: Sat, 22 Jul 2017 16:14:14 +0200 Subject: separated video driver in a virtual video driver and a specific VGA video driver --- src/drivers/video/vga.c | 68 +++++++++++++++++++++++++++++------------------ src/drivers/video/vga.h | 15 +++++------ src/drivers/video/video.c | 44 +++++++++++++++++++++++++++--- src/drivers/video/video.h | 28 ++++++++++++++----- 4 files changed, 111 insertions(+), 44 deletions(-) (limited to 'src/drivers/video') diff --git a/src/drivers/video/vga.c b/src/drivers/video/vga.c index 75e96e6..456e539 100644 --- a/src/drivers/video/vga.c +++ b/src/drivers/video/vga.c @@ -20,7 +20,14 @@ static vga_vtable_t const vga_vtable = { video_register_mode, video_supports_mode, video_set_mode, - vga_switch_mode + vga_switch_mode, + vga_set_pixel, + vga_draw_rectangle, + vga_clear_screen, + vga_draw_char, + vga_wait_for_retrace, + vga_use_z_buffer, + vga_refresh } }; @@ -252,9 +259,9 @@ bool vga_switch_mode( void *obj, const video_mode_t *mode ) write_registers( vga, vga_mode->regs ); - vga->mode = (vga_mode_t *)mode; - vga->mode->segment = get_frame_buffer_segment( vga ); - vga->mode->segment_size = get_frame_buffer_segment_size( vga ); + vga_mode->segment = get_frame_buffer_segment( vga ); + vga_mode->segment_size = get_frame_buffer_segment_size( vga ); + vga->base.mode = mode; vga_use_z_buffer( vga, false ); @@ -291,55 +298,62 @@ static uint8_t get_color_index( const video_rgb_color_t c ) static bool params_ok( vga_t *vga, const int x, const int y ) { - if( x < 0 || x > vga->mode->base.x || y < 0 || y > vga->mode->base.y ) { + if( x < 0 || x > vga->base.mode->x || y < 0 || y > vga->base.mode->y ) { return false; } return true; } -void vga_set_pixel( vga_t *vga, const int x, const int y, const video_rgb_color_t color ) +void vga_set_pixel( void *obj, const int x, const int y, const video_rgb_color_t color ) { + vga_t *vga = (vga_t *)obj; + if( !params_ok( vga, x, y ) ) { kernel_panic( "Pixel coordinates are out of bounds: (%d, %d), resolution is only (%d, %d)", - x, y, vga->mode->base.x, vga->mode->base.y ); + x, y, vga->base.mode->x, vga->base.mode->y ); } uint8_t color_idx = get_color_index( color ); - uint8_t *addr = vga->base_addr + vga->mode->base.x * y + x; + uint8_t *addr = vga->base_addr + vga->base.mode->x * y + x; *addr = color_idx; } -void vga_draw_rectangle( vga_t *vga, const int x, const int y, const int w, const int h, const video_rgb_color_t color ) +void vga_draw_rectangle( void *obj, const int x, const int y, const int w, const int h, const video_rgb_color_t color ) { + vga_t *vga = (vga_t *)obj; + if( !params_ok( vga, x, y ) ) { kernel_panic( "Rectangle start coordinates are out of bounds: (%d, %d), resolution is only (%d, %d)", - x, y, vga->mode->base.x, vga->mode->base.y ); + x, y, vga->base.mode->x, vga->base.mode->y ); } if( !params_ok( vga, x + w, y + h ) ) { kernel_panic( "Rectangle end coordinates are out of bounds: (%d, %d), resolution is only (%d, %d)", - x + w, y + h, vga->mode->base.x, vga->mode->base.y ); + x + w, y + h, vga->base.mode->x, vga->base.mode->y ); } uint8_t color_idx = get_color_index( color ); for( int yy = y; yy < y + h; yy++ ) { - uint8_t *addr = vga->base_addr + vga->mode->base.x * yy + x; + uint8_t *addr = vga->base_addr + vga->base.mode->x * yy + x; memset( addr, color_idx, w ); } } -void vga_clear_screen( vga_t *vga, const video_rgb_color_t color ) +void vga_clear_screen( void *obj, const video_rgb_color_t color ) { + vga_t *vga = (vga_t *)obj; + memset( vga->base_addr, get_color_index( color ), - vga->mode->base.x * vga->mode->base.y ); + vga->base.mode->x * vga->base.mode->y ); } -void vga_draw_char( vga_t *vga, const unsigned char c, const int x, const int y, const video_rgb_color_t background, const video_rgb_color_t foreground ) +void vga_draw_char( void *obj, const unsigned char c, const int x, const int y, const video_rgb_color_t background, const video_rgb_color_t foreground ) { + vga_t *vga = (vga_t *)obj; //const struct bitmap_font font = { @@ -367,42 +381,44 @@ void vga_draw_char( vga_t *vga, const unsigned char c, const int x, const int y, data[vga_font.Width-1-xx] = fg_color_idx; } } - uint8_t *addr = vga->base_addr + vga->mode->base.x * ( y + yy ) + x; + uint8_t *addr = vga->base_addr + vga->base.mode->x * ( y + yy ) + x; memcpy( addr, data, vga_font.Width ); } } -void vga_wait_for_retrace( vga_t *vga ) +void vga_wait_for_retrace( void *obj ) { + vga_t *vga = (vga_t *)obj; + while( port8_read( &vga->attribute_controller_reset_port ) & 0x08 ); while( !( port8_read( &vga->attribute_controller_reset_port ) & 0x08 ) ); } -void vga_use_z_buffer( vga_t *vga, bool use ) +void vga_use_z_buffer( void *obj, bool use ) { - if( vga->use_z_buffer == use ) { - return; - } - + vga_t *vga = (vga_t *)obj; + vga->use_z_buffer = use; if( vga->use_z_buffer ) { - vga->zbuffer = (uint8_t *)malloc( vga->mode->segment_size ); + vga->zbuffer = (uint8_t *)malloc( ((vga_mode_t *)(vga->base.mode))->segment_size ); vga->base_addr = &vga->zbuffer[0]; } else { if( vga->zbuffer != NULL ) { free( vga->zbuffer ); vga->zbuffer = NULL; } - vga->base_addr = vga->mode->segment; + vga->base_addr = ((vga_mode_t *)(vga->base.mode))->segment; } } -void vga_refresh( vga_t *vga ) +void vga_refresh( void *obj ) { + vga_t *vga = (vga_t *)obj; + if( vga->use_z_buffer ) { vga_wait_for_retrace( vga ); - memcpy( vga->mode->segment, vga->zbuffer, vga->mode->segment_size ); + memcpy( ((vga_mode_t *)(vga->base.mode))->segment, vga->zbuffer, ((vga_mode_t *)(vga->base.mode))->segment_size ); } } diff --git a/src/drivers/video/vga.h b/src/drivers/video/vga.h index 6934856..faafd8e 100644 --- a/src/drivers/video/vga.h +++ b/src/drivers/video/vga.h @@ -33,7 +33,6 @@ typedef struct { port8_t attribute_controller_read_port; port8_t attribute_controller_write_port; port8_t attribute_controller_reset_port; - vga_mode_t *mode; bool use_z_buffer; uint8_t *zbuffer; // stores either the address to the beginning of the segment @@ -53,12 +52,12 @@ void vga_print_info( void *obj ); bool vga_switch_mode( void *obj, const video_mode_t *mode ); -void vga_set_pixel( vga_t *vga, const int x, const int y, const video_rgb_color_t color ); -void vga_draw_rectangle( vga_t *vga, const int x, const int y, const int w, const int h, const video_rgb_color_t color ); -void vga_clear_screen( vga_t *vga, const video_rgb_color_t color ); -void vga_draw_char( vga_t *vga, const unsigned char c, const int x, const int y, const video_rgb_color_t background, const video_rgb_color_t foreground ); -void vga_wait_for_retrace( vga_t *vga ); -void vga_use_z_buffer( vga_t *vga, bool use ); -void vga_refresh( vga_t *vga ); +void vga_set_pixel( void *, const int x, const int y, const video_rgb_color_t color ); +void vga_draw_rectangle( void *, const int x, const int y, const int w, const int h, const video_rgb_color_t color ); +void vga_clear_screen( void *, const video_rgb_color_t color ); +void vga_draw_char( void *, const unsigned char c, const int x, const int y, const video_rgb_color_t background, const video_rgb_color_t foreground ); +void vga_wait_for_retrace( void * ); +void vga_use_z_buffer( void *, bool use ); +void vga_refresh( void * ); #endif // VGA_H diff --git a/src/drivers/video/video.c b/src/drivers/video/video.c index ca57269..064a1f6 100644 --- a/src/drivers/video/video.c +++ b/src/drivers/video/video.c @@ -27,12 +27,12 @@ void video_init( video_t *video, interrupt_t *interrupt, void *context ) void video_activate( void *obj ) { - kernel_panic( "Activating generic video driver should not be called directly." ); + kernel_panic( "Calling abstract method in file %s at line %d.", __FILE__, __LINE__ ); } void video_deactivate( void *obj ) { - kernel_panic( "Deactivating generic video driver should not be called directly." ); + kernel_panic( "Calling abstract method in file %s at line %d.", __FILE__, __LINE__ ); } void video_deinit( void *obj ) @@ -42,7 +42,7 @@ void video_deinit( void *obj ) void video_print_info( void *obj ) { - kernel_panic( "Printing info of generic video driver should not be called directly." ); + kernel_panic( "Calling abstract method in file %s at line %d.", __FILE__, __LINE__ ); } video_mode_t video_make_mode( const video_mode_type_t mode_type, const int x, const int y, const int color_depth ) @@ -114,7 +114,7 @@ bool video_set_mode( void *obj, const video_mode_t mode ) bool video_switch_mode( void *obj, const video_mode_t *mode ) { - kernel_panic( "Switching mode function of abstract video driver should not be called directly." ); + kernel_panic( "Calling abstract method in file %s at line %d.", __FILE__, __LINE__ ); return false; } @@ -149,3 +149,39 @@ const video_rgb_color_t VIDEO_RGB_COLOR_WHITE = { 0xFF, 0xFF, 0xFF }; 0xD 0X3D 63,21,63 255,85,255 #ff55ff bright magenta 0xE 0x3E 63,63,21 255,255,85 #ffff55 yellow */ + +void video_set_pixel( void *obj, const int x, const int y, const video_rgb_color_t color ) +{ + kernel_panic( "Calling abstract method in file %s at line %d.", __FILE__, __LINE__ ); +} + +void video_draw_rectangle( void *obj, const int x, const int y, const int w, const int h, const video_rgb_color_t color ) +{ + kernel_panic( "Calling abstract method in file %s at line %d.", __FILE__, __LINE__ ); +} + +void video_clear_screen( void *obj, const video_rgb_color_t color ) +{ + kernel_panic( "Calling abstract method in file %s at line %d.", __FILE__, __LINE__ ); +} + +void video_draw_char( void *obj, const unsigned char c, const int x, const int y, const video_rgb_color_t background, const video_rgb_color_t foreground ) +{ + kernel_panic( "Calling abstract method in file %s at line %d.", __FILE__, __LINE__ ); +} + +void video_wait_for_retrace( void *obj ) +{ + kernel_panic( "Calling abstract method in file %s at line %d.", __FILE__, __LINE__ ); +} + +void video_use_z_buffer( void *obj, bool use ) +{ + kernel_panic( "Calling abstract method in file %s at line %d.", __FILE__, __LINE__ ); +} + +void video_refresh( void *obj ) +{ + kernel_panic( "Calling abstract method in file %s at line %d.", __FILE__, __LINE__ ); +} + diff --git a/src/drivers/video/video.h b/src/drivers/video/video.h index 6da8e60..8cfebb3 100644 --- a/src/drivers/video/video.h +++ b/src/drivers/video/video.h @@ -23,14 +23,28 @@ typedef struct { driver_t base; unsigned int nof_modes; const video_mode_t *modes[MAX_NOF_VIDEO_MODES]; + const video_mode_t *mode; } video_t; +typedef struct { + int R; + int G; + int B; +} video_rgb_color_t; + typedef struct { driver_vtable_t base; void (*register_mode)( void *obj, const video_mode_t *mode ); bool (*supports_mode)( void *obj, const video_mode_t mode ); bool (*set_mode)( void *obj, const video_mode_t mode ); bool (*switch_mode)( void *obj, const video_mode_t *mode ); + void (*set_pixel)( void *obj, const int x, const int y, const video_rgb_color_t color ); + void (*draw_rectangle)( void *obj, const int x, const int y, const int w, const int h, const video_rgb_color_t color ); + void (*clear_screen)( void *obj, const video_rgb_color_t color ); + void (*draw_char)( void *obj, const unsigned char c, const int x, const int y, const video_rgb_color_t background, const video_rgb_color_t foreground ); + void (*wait_for_retrace)( void *obj ); + void (*use_z_buffer)( void *obj, bool use ); + void (*refresh)( void *obj ); } video_vtable_t; void video_init( video_t *video, interrupt_t *interrupt, void *context ); @@ -46,12 +60,6 @@ bool video_supports_mode( void *obj, const video_mode_t mode ); bool video_set_mode( void *obj, const video_mode_t mode ); bool video_switch_mode( void *obj, const video_mode_t *mode ); -typedef struct { - int R; - int G; - int B; -} video_rgb_color_t; - extern const video_rgb_color_t VIDEO_RGB_COLOR_BLACK; extern const video_rgb_color_t VIDEO_RGB_COLOR_BLUE; extern const video_rgb_color_t VIDEO_RGB_COLOR_GREEN; @@ -64,4 +72,12 @@ extern const video_rgb_color_t VIDEO_RGB_COLOR_WHITE; video_rgb_color_t video_make_rgb_color( const int R, const int G, const int B ); +void video_set_pixel( void *obj, const int x, const int y, const video_rgb_color_t color ); +void video_draw_rectangle( void *obj, const int x, const int y, const int w, const int h, const video_rgb_color_t color ); +void video_clear_screen( void *obj, const video_rgb_color_t color ); +void video_draw_char( void *obj, const unsigned char c, const int x, const int y, const video_rgb_color_t background, const video_rgb_color_t foreground ); +void video_wait_for_retrace( void *obj ); +void video_use_z_buffer( void *obj, bool use ); +void video_refresh( void *obj ); + #endif // VIDEO_H -- cgit v1.2.3-54-g00ecf