diff options
Diffstat (limited to 'xxx/video/vesa.c')
| -rw-r--r-- | xxx/video/vesa.c | 249 |
1 files changed, 249 insertions, 0 deletions
diff --git a/xxx/video/vesa.c b/xxx/video/vesa.c new file mode 100644 index 0000000..a5ee4e5 --- /dev/null +++ b/xxx/video/vesa.c @@ -0,0 +1,249 @@ +//http://wiki.osdev.org/GUI +#include <stdarg.h> +#include "kernel/mem.h" +#include "vesa.h" + +#include "lib/logger/log.h" // logger facilities +#include "lib/printf/printf.h" +#define FOOLOS_MODULE_NAME "vesa" + +#define FOOLSOS_SHOW_VESAMODES + + +static foolfont *deffont; +static vbemodeinfo *VbeModeInfoBlock; + +static int console_x; +static int console_y; + +static int console_lines; +static int console_cols; + +static uint8_t* buffer; +static uint8_t* physbase; + +void PutConsoleNL(); +void PutPixel(int x,int y, int color); + +void vesa_switch_buffers() +{ + for(int i=0;i<800*600*2;i++)physbase[i]=buffer[i]; + +} + +void vesa_put_rect(int x, int y, int w , int h, int color) +{ + for(int i=x;i<x+w;i++) + for(int j=y;j<y+h;j++) + PutPixel(i,j,color); +} + +void vesa_clear_screen() +{ + vesa_put_rect(0,0,VbeModeInfoBlock->Xres, VbeModeInfoBlock->Yres, 0xffffff); +} + + +void vesa_set_physbase(uint32_t addr) +{ + VbeModeInfoBlock->physbase=addr; +} + + // + // We want to get output to the screen as fast as possible! + // + // Our Fool-Boot-Loader did set up VESA already for us. + // The desired VESA mode is hardcoded in [boot/mbr.asm]. + // + // The [vesa_init(...)] function requires: + // + // * the addresses of the vbeinfo struct + // * the address of the vbemodeinfo struct (for selected mode). + // * Fool Font loaded inside ramimage + // + // The first two paramters are hardcoded in [boot/mbr.asm], + // while the last one is set in the Makefile. The font binary + // is integrated in the kernel image. + // + // this function returns the physical base address of + // our video memory + // + +uint32_t vesa_init(vbeinfo *info,vbemodeinfo *mode,foolfont *rawfont) +{ + //the only functionallu important init lines! (rest is log) + VbeModeInfoBlock=mode; + deffont=rawfont; + console_x=0; + console_y=0; + + int line_height=12; + int col_width=10; + console_lines=mode->Yres/line_height; + console_cols=mode->Xres/col_width; + + // vesa info + log(FOOLOS_MODULE_NAME,FOOLOS_LOG_INFO,"vbe version: 0x%x / video mode ptr: 0x%x 0x%x", + info->VbeVersion, info->VideoModePtr[1], info->VideoModePtr[0]); + + // vesa info on selected mode: + log(FOOLOS_MODULE_NAME,FOOLOS_LOG_INFO,"colors r:%d 0x%x g:%d 0x%x b:%d 0x%x", + mode->red_position,mode->red_mask, + mode->green_position,mode->green_mask, + mode->blue_position,mode->blue_mask); + + log(FOOLOS_MODULE_NAME,FOOLOS_LOG_INFO,"res: %d * %d / banks: %d / attr: 0x%x", + mode->Xres, mode->Yres, mode->banks, mode->attributes); + log(FOOLOS_MODULE_NAME,FOOLOS_LOG_INFO,"bpp: %d / physbase: 0x%x", + mode->bpp,mode->physbase); + + // vesa modes + // todo: take segment from vbeinfo! +#ifdef FOOLSOS_SHOW_VESAMODES + uint16_t *modeptr=info->VideoModePtr[0]; + + while(*modeptr!=0xffff&&*modeptr!=0) + { + log(FOOLOS_MODULE_NAME,FOOLOS_LOG_INFO,"mode supported : 0x%X", (*modeptr)); + modeptr++; + } +#endif + + + return VbeModeInfoBlock->physbase; + +} + +void PutPixel(int x,int y, int color){ + + //do not write memory outside the screen buffer, check parameters against the VBE mode info + if (x<0 || x>VbeModeInfoBlock->Xres|| y<0 || y>VbeModeInfoBlock->Yres) return; + if (x) x = (x*(VbeModeInfoBlock->bpp>>3)); // get bytes (divide by 8) + if (y) y = (y*VbeModeInfoBlock->pitch); + uint8_t *cTemp=VbeModeInfoBlock->physbase; + + cTemp[x+y] = (uint8_t)(color & 0xff); + cTemp[x+y+1] = (uint8_t)((color>>8) & 0xff); + //cTemp[x+y+2] = (uint8_t)((color>>16) & 0xff); + + } + + +void PutFont(char c, int x,int y, int color) +{ + + int fnt=0x126-0x20; + + if(c>=0x20&&c<=0x126)fnt=c-0x20; + + int posx, posy, sizex=8, sizey=10; + + for(posx=x;posx<x+sizex;posx++) + { + + for(posy=y;posy<y+sizey;posy++) + { + if(deffont[fnt].line[posy-y]&1<<(7-(posx-x))) + { + PutPixel(posx,posy,color); + } + else + { + PutPixel(posx,posy,0); + } + + } + } + +} + +void PutString(char *str, int x,int y, int color, va_list va) +{ + + char buff[256]; + tfp_sprintf(buff,str,va); + str=buff; + + int i=x; + while((*str)!=0) + { + PutFont(*str, i,y, color); + i+=9; // spacing + str++; + } + +} + +void PutConsoleChar(char c, int color) +{ + if(c=='\n') + { + PutConsoleNL(); + return; + } + PutFont(c, console_x*10,console_y*12, color); + console_x++; + + + #ifdef FOOLOS_CONSOLE_AUTOBREAK + if(console_x>=console_cols)PutConsoleNL(); + #endif +} + +void PutConsole(char *str, int color) +{ + + while((*str)!=0) + { + PutConsoleChar(*str,color); + str++; + } + +} +void PutConsoleNL() +{ + console_x=0; + console_y++; + if(console_y>=console_lines-5)console_y=0; + + for(int i=0;i<console_cols;i++) + { + PutFont(' ',i*10,(console_y)*12,0); + } +} + +static int boxx; +static int boxy; +//////////////// +void vesa_render() +{ + vesa_clear_screen(); + vesa_put_rect(100,100,VbeModeInfoBlock->Xres-200,VbeModeInfoBlock->Yres-200,0xff); + vesa_put_rect(boxx-10,boxy-10,20,20,0x999999); + + boxx++; +// boxy+=boxx; + if(boxx>VbeModeInfoBlock->Xres-100)boxx=100; + // if(boxy>VbeModeInfoBlock->Yres-200)boxy=200; + + + vesa_switch_buffers(); +} + +/* +void vesa_init_doublebuff() +{ + boxx=300; + boxy=300; + + int blocks=800*600*2/4096+1; + physbase=VbeModeInfoBlock->physbase; + buffer=pmmngr_alloc_blocks(blocks); + log(FOOLOS_MODULE_NAME,FOOLOS_LOG_INFO,"Init buffer of %d blocks at 0x%08X",blocks,buffer); + + VbeModeInfoBlock->physbase=buffer; +} +*/ + + + |
