diff options
author | Andreas Baumann <mail@andreasbaumann.cc> | 2017-07-10 21:04:18 +0200 |
---|---|---|
committer | Andreas Baumann <mail@andreasbaumann.cc> | 2017-07-10 21:04:18 +0200 |
commit | 573b82fd2d46ebca7f98e5323e9f18e593a7996f (patch) | |
tree | 643d480130d1a6ac2639d63b384f43ca9cd82d83 /src/drivers/video/vga.c | |
parent | ea3afaaf2e1926328ca94fa1227c49631adaf5e7 (diff) | |
download | abaos-573b82fd2d46ebca7f98e5323e9f18e593a7996f.tar.gz abaos-573b82fd2d46ebca7f98e5323e9f18e593a7996f.tar.bz2 |
VGA Z-buffer is now dynamically allocated and freed
memory management can reuse the last pointer malloced if freed again
Diffstat (limited to 'src/drivers/video/vga.c')
-rw-r--r-- | src/drivers/video/vga.c | 55 |
1 files changed, 49 insertions, 6 deletions
diff --git a/src/drivers/video/vga.c b/src/drivers/video/vga.c index 0cd623d..751cbc5 100644 --- a/src/drivers/video/vga.c +++ b/src/drivers/video/vga.c @@ -1,6 +1,7 @@ #include "vga.h" #include "stdio.h" +#include "stdlib.h" #include "kernel.h" @@ -48,7 +49,12 @@ void vga_deactivate( void *obj ) void vga_deinit( void *obj ) { - // nothing to do + vga_t *vga = (vga_t *)obj; + + if( vga->zbuffer != NULL ) { + free( vga->zbuffer ); + vga->zbuffer = NULL; + } } void vga_print_info( void *obj ) @@ -213,19 +219,19 @@ static uint8_t *get_frame_buffer_segment( vga_t *vga ) uint8_t *segment = 0x0; switch( segment_no ) { - case 0: // A0000h - BFFFFh, 128k + case 0: // A0000h - BFFFFh segment = (uint8_t *)0xA0000; break; - case 1: // A0000h - AFFFFh, 64k + case 1: // A0000h - AFFFFh segment = (uint8_t *)0xA0000; break; - case 2: // B0000h - B7FFFh, 32k + case 2: // B0000h - B7FFFh segment = (uint8_t *)0xB0000; break; - case 3: // B8000h - BFFFFh, 32k + case 3: // B8000h - BFFFFh segment = (uint8_t *)0xB8000; break; } @@ -237,6 +243,34 @@ static uint8_t *get_frame_buffer_segment( vga_t *vga ) return segment; } +static size_t get_frame_buffer_segment_size( vga_t *vga ) +{ + port8_write( &vga->graphics_controller_index_port, 0x06 ); + uint8_t segment_no = ( port8_read( &vga->graphics_controller_data_port ) >> 2 ) & 0x03; + size_t segment_size = 0; + + switch( segment_no ) { + case 0: // 128k + segment_size = 128 * 1024; + break; + + case 1: // 64k + segment_size = 64 * 1024; + break; + + case 2: // 32k + case 3: + segment_size = 32 * 1024; + break; + } + +#ifdef DEBUG + printf( "segment size: %d 0x%X\n", segment_no, segment_size ); +#endif + + return segment_size; +} + bool vga_set_mode( vga_t *vga, const vga_mode_t mode ) { // do not allow unknown timings! @@ -252,7 +286,6 @@ bool vga_set_mode( vga_t *vga, const vga_mode_t mode ) vga->mode.segment = get_frame_buffer_segment( vga ); vga_use_z_buffer( vga, false ); - memset( vga->zbuffer, 0, sizeof( vga->zbuffer ) ); return true; } @@ -389,11 +422,21 @@ void vga_wait_for_retrace( vga_t *vga ) void vga_use_z_buffer( vga_t *vga, bool use ) { + if( vga->use_z_buffer == use ) { + return; + } + vga->use_z_buffer = use; if( vga->use_z_buffer ) { + size_t size = get_frame_buffer_segment_size( vga ); + vga->zbuffer = (uint8_t *)malloc( size ); vga->base_addr = &vga->zbuffer[0]; } else { + if( vga->zbuffer != NULL ) { + free( vga->zbuffer ); + vga->zbuffer = NULL; + } vga->base_addr = vga->mode.segment; } } |