From 573b82fd2d46ebca7f98e5323e9f18e593a7996f Mon Sep 17 00:00:00 2001 From: Andreas Baumann Date: Mon, 10 Jul 2017 21:04:18 +0200 Subject: VGA Z-buffer is now dynamically allocated and freed memory management can reuse the last pointer malloced if freed again --- src/drivers/video/vga.c | 55 +++++++++++++++++++++++++++++++++++++++++++------ src/drivers/video/vga.h | 6 +----- 2 files changed, 50 insertions(+), 11 deletions(-) (limited to 'src/drivers') 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; } } diff --git a/src/drivers/video/vga.h b/src/drivers/video/vga.h index bdc15cf..aa842dc 100644 --- a/src/drivers/video/vga.h +++ b/src/drivers/video/vga.h @@ -42,11 +42,7 @@ typedef struct { port8_t attribute_controller_reset_port; vga_mode_t mode; bool use_z_buffer; - // TODO: the Z-buffer should actually be allocated dynamically - // depending on the current mode, for now it's a static buffer - // able to store the biggest resolution, being planar - // 320x200x8 aka 64k - uint8_t zbuffer[65535]; + uint8_t *zbuffer; // stores either the address to the beginning of the segment // (real mapped I/O memory or the beginning of the Z buffer uint8_t *base_addr; -- cgit v1.2.3-54-g00ecf