summaryrefslogtreecommitdiff
path: root/src/drivers/video/vga.c
diff options
context:
space:
mode:
authorAndreas Baumann <mail@andreasbaumann.cc>2017-07-21 21:10:12 +0200
committerAndreas Baumann <mail@andreasbaumann.cc>2017-07-21 21:10:12 +0200
commit6c1633b80a30c639bc096cc4b98a1da998af38c2 (patch)
tree0f45096ba3d4cfcb92ae84274e2ce2d53d95f3f7 /src/drivers/video/vga.c
parent3e9f594c7e06017b5d919d79530c39a58de8a3c7 (diff)
downloadabaos-6c1633b80a30c639bc096cc4b98a1da998af38c2.tar.gz
abaos-6c1633b80a30c639bc096cc4b98a1da998af38c2.tar.bz2
changed video mode management, moved to video driver,
the VGA driver registers his specific mode data with the video driver kernel function now use virtual functions of the video driver
Diffstat (limited to 'src/drivers/video/vga.c')
-rw-r--r--src/drivers/video/vga.c235
1 files changed, 101 insertions, 134 deletions
diff --git a/src/drivers/video/vga.c b/src/drivers/video/vga.c
index 094a117..c38bee1 100644
--- a/src/drivers/video/vga.c
+++ b/src/drivers/video/vga.c
@@ -11,10 +11,83 @@
static vga_vtable_t const vga_vtable = {
{
- vga_activate,
- vga_deactivate,
- vga_deinit,
- vga_print_info
+ {
+ vga_activate,
+ vga_deactivate,
+ vga_deinit,
+ vga_print_info
+ },
+ video_register_mode,
+ video_supports_mode,
+ video_set_mode,
+ vga_switch_mode
+ }
+};
+
+// from http://files.osdev.org/mirrors/geezer/osd/graphics/modes.c
+static vga_mode_t modes[] = {
+ { { VIDEO_MODE_TYPE_TEXT, 640, 480, 4 },
+ {
+ /* MISC */
+ 0x67,
+ /* SEQ */
+ 0x03, 0x00, 0x03, 0x00, 0x02,
+ /* CRTC */
+ 0x5F, 0x4F, 0x50, 0x82, 0x55, 0x81, 0xBF, 0x1F,
+ 0x00, 0x4F, 0x0D, 0x0E, 0x00, 0x00, 0x00, 0x50,
+ 0x9C, 0x0E, 0x8F, 0x28, 0x1F, 0x96, 0xB9, 0xA3,
+ 0xFF,
+ /* GC */
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x0E, 0x00,
+ 0xFF,
+ /* AC */
+ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x14, 0x07,
+ 0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0x3E, 0x3F,
+ 0x0C, 0x00, 0x0F, 0x08, 0x00
+ },
+ NULL
+ },
+ { { VIDEO_MODE_TYPE_GRAPHICS, 320, 200, 8 },
+ {
+ /* MISC */
+ 0x63,
+ /* SEQ */
+ 0x03, 0x01, 0x0F, 0x00, 0x0E,
+ /* CRTC */
+ 0x5F, 0x4F, 0x50, 0x82, 0x54, 0x80, 0xBF, 0x1F,
+ 0x00, 0x41, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x9C, 0x0E, 0x8F, 0x28, 0x40, 0x96, 0xB9, 0xA3,
+ 0xFF,
+ /* GC */
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x05, 0x0F,
+ 0xFF,
+ /* AC */
+ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
+ 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
+ 0x41, 0x00, 0x0F, 0x00, 0x00
+ },
+ NULL
+ },
+ { { VIDEO_MODE_TYPE_GRAPHICS, 640, 480, 4 },
+ {
+ /* MISC */
+ 0xE3,
+ /* SEQ */
+ 0x03, 0x01, 0x08, 0x00, 0x06,
+ /* CRTC */
+ 0x5F, 0x4F, 0x50, 0x82, 0x54, 0x80, 0x0B, 0x3E,
+ 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0xEA, 0x0C, 0xDF, 0x28, 0x00, 0xE7, 0x04, 0xE3,
+ 0xFF,
+ /* GC */
+ 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x05, 0x0F,
+ 0xFF,
+ /* AC */
+ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x14, 0x07,
+ 0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0x3E, 0x3F,
+ 0x01, 0x00, 0x0F, 0x00, 0x00
+ },
+ NULL
}
};
@@ -22,7 +95,7 @@ void vga_init( vga_t *vga, interrupt_t *interrupt, void *context )
{
memset( vga, 0, sizeof( vga_t ) );
- driver_init( (driver_t *)vga, DRIVER_TYPE_VIDEO, interrupt, context );
+ video_init( (video_t *)vga, interrupt, context );
port8_init( &vga->misc_port, 0x3C2 );
port8_init( &vga->crtc_index_port, 0x3D4 );
@@ -37,6 +110,11 @@ void vga_init( vga_t *vga, interrupt_t *interrupt, void *context )
port8_init( &vga->attribute_controller_reset_port, 0x3DA );
((driver_t *)vga)->vtable = (driver_vtable_t *)&vga_vtable;
+
+ // register modes
+ for( int i = 0; modes[i].base.x != 0; i++ ) {
+ ((video_vtable_t *)(vga->base.base.vtable))->register_mode( vga, (const video_mode_t *)&modes[i] );
+ }
}
void vga_activate( void *obj )
@@ -106,113 +184,7 @@ static void write_registers( vga_t *vga, uint8_t *regs )
(void)port8_read( &vga->attribute_controller_reset_port );
port8_write( &vga->attribute_controller_index_port, 0x20 );
}
-
-vga_mode_t vga_make_mode( const vga_mode_type_t mode_type, const int x, const int y, const int color_depth )
-{
- vga_mode_t mode;
-
- mode.mode_type = mode_type;
- mode.x = x;
- mode.y = y;
- mode.color_depth = color_depth;
-
- return mode;
-}
-// from http://files.osdev.org/mirrors/geezer/osd/graphics/modes.c
-static vga_mode_t modes[] = {
- { VGA_MODE_TYPE_TEXT, 640, 480, 4,
- {
- /* MISC */
- 0x67,
- /* SEQ */
- 0x03, 0x00, 0x03, 0x00, 0x02,
- /* CRTC */
- 0x5F, 0x4F, 0x50, 0x82, 0x55, 0x81, 0xBF, 0x1F,
- 0x00, 0x4F, 0x0D, 0x0E, 0x00, 0x00, 0x00, 0x50,
- 0x9C, 0x0E, 0x8F, 0x28, 0x1F, 0x96, 0xB9, 0xA3,
- 0xFF,
- /* GC */
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x0E, 0x00,
- 0xFF,
- /* AC */
- 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x14, 0x07,
- 0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0x3E, 0x3F,
- 0x0C, 0x00, 0x0F, 0x08, 0x00
- },
- NULL
- },
- { VGA_MODE_TYPE_GRAPHICS, 320, 200, 8,
- {
- /* MISC */
- 0x63,
- /* SEQ */
- 0x03, 0x01, 0x0F, 0x00, 0x0E,
- /* CRTC */
- 0x5F, 0x4F, 0x50, 0x82, 0x54, 0x80, 0xBF, 0x1F,
- 0x00, 0x41, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x9C, 0x0E, 0x8F, 0x28, 0x40, 0x96, 0xB9, 0xA3,
- 0xFF,
- /* GC */
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x05, 0x0F,
- 0xFF,
- /* AC */
- 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
- 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
- 0x41, 0x00, 0x0F, 0x00, 0x00
- },
- NULL
- },
- { VGA_MODE_TYPE_GRAPHICS, 640, 480, 4,
- {
- /* MISC */
- 0xE3,
- /* SEQ */
- 0x03, 0x01, 0x08, 0x00, 0x06,
- /* CRTC */
- 0x5F, 0x4F, 0x50, 0x82, 0x54, 0x80, 0x0B, 0x3E,
- 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0xEA, 0x0C, 0xDF, 0x28, 0x00, 0xE7, 0x04, 0xE3,
- 0xFF,
- /* GC */
- 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x05, 0x0F,
- 0xFF,
- /* AC */
- 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x14, 0x07,
- 0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0x3E, 0x3F,
- 0x01, 0x00, 0x0F, 0x00, 0x00
- },
- NULL
- }
-};
-
-bool vga_supports_mode( const vga_mode_t mode )
-{
- for( int i = 0; modes[i].x != 0; i++ ) {
- if( mode.mode_type == modes[i].mode_type &&
- mode.x == modes[i].x &&
- mode.y == modes[i].y &&
- mode.color_depth == modes[i].color_depth ) {
- return true;
- }
- }
-
- return false;
-}
-
-static int get_matching_mode_idx( const vga_mode_t mode )
-{
- for( int i = 0; modes[i].x != 0; i++ ) {
- if( mode.mode_type == modes[i].mode_type &&
- mode.x == modes[i].x &&
- mode.y == modes[i].y &&
- mode.color_depth == modes[i].color_depth ) {
- return i;
- }
- }
-
- return -1;
-}
static uint8_t *get_frame_buffer_segment( vga_t *vga )
{
@@ -273,27 +245,22 @@ static size_t get_frame_buffer_segment_size( vga_t *vga )
return segment_size;
}
-bool vga_set_mode( vga_t *vga, const vga_mode_t mode )
+bool vga_switch_mode( void *obj, const video_mode_t *mode )
{
- // do not allow unknown timings!
- if( !vga_supports_mode( mode ) ) {
- return false;
- }
-
- vga_mode_t matching_mode = modes[get_matching_mode_idx( mode )];
+ vga_t *vga = (vga_t *)obj;
+ vga_mode_t *vga_mode = (vga_mode_t *)mode;
- write_registers( vga, matching_mode.regs );
+ write_registers( vga, vga_mode->regs );
- vga->mode = mode;
- vga->mode.segment = get_frame_buffer_segment( vga );
- vga->mode.segment_size = get_frame_buffer_segment_size( vga );
+ 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_use_z_buffer( vga, false );
return true;
}
-
vga_color_t vga_make_RGB( int R, int G, int B )
{
vga_color_t c;
@@ -336,7 +303,7 @@ static uint8_t get_color_index( const vga_color_t c )
static bool params_ok( vga_t *vga, const int x, const int y )
{
- if( x < 0 || x > vga->mode.x || y < 0 || y > vga->mode.y ) {
+ if( x < 0 || x > vga->mode->base.x || y < 0 || y > vga->mode->base.y ) {
return false;
}
@@ -347,12 +314,12 @@ void vga_set_pixel( vga_t *vga, const int x, const int y, const vga_color_t colo
{
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.x, vga->mode.y );
+ x, y, vga->mode->base.x, vga->mode->base.y );
}
uint8_t color_idx = get_color_index( color );
- uint8_t *addr = vga->base_addr + vga->mode.x * y + x;
+ uint8_t *addr = vga->base_addr + vga->mode->base.x * y + x;
*addr = color_idx;
}
@@ -361,18 +328,18 @@ void vga_draw_rectangle( vga_t *vga, const int x, const int y, const int w, cons
{
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.x, vga->mode.y );
+ x, y, vga->mode->base.x, vga->mode->base.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.x, vga->mode.y );
+ x + w, y + h, vga->mode->base.x, vga->mode->base.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.x * yy + x;
+ uint8_t *addr = vga->base_addr + vga->mode->base.x * yy + x;
memset( addr, color_idx, w );
}
}
@@ -380,7 +347,7 @@ void vga_draw_rectangle( vga_t *vga, const int x, const int y, const int w, cons
void vga_clear_screen( vga_t *vga, const vga_color_t color )
{
memset( vga->base_addr, get_color_index( color ),
- vga->mode.x * vga->mode.y );
+ vga->mode->base.x * vga->mode->base.y );
}
void vga_draw_char( vga_t *vga, const unsigned char c, const int x, const int y, const vga_color_t background, const vga_color_t foreground )
@@ -412,7 +379,7 @@ 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.x * ( y + yy ) + x;
+ uint8_t *addr = vga->base_addr + vga->mode->base.x * ( y + yy ) + x;
memcpy( addr, data, vga_font.Width );
}
}
@@ -432,14 +399,14 @@ void vga_use_z_buffer( vga_t *vga, bool use )
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->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->segment;
}
}
@@ -447,7 +414,7 @@ void vga_refresh( vga_t *vga )
{
if( vga->use_z_buffer ) {
vga_wait_for_retrace( vga );
- memcpy( vga->mode.segment, vga->zbuffer, vga->mode.segment_size );
+ memcpy( vga->mode->segment, vga->zbuffer, vga->mode->segment_size );
}
}