//http://wiki.osdev.org/GUI #include #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); //static char buf[80][24]; void vesa_update_cursor(uint32_t col,uint32_t row) { console_x=col; console_y=row; } // helper_funcs static void vesa_print_char_col(int x, int y, char c, char col_fg, char col_bg) { // uint16_t attrib = (col_bg << 4) | (col_fg & 0x0F); // uint16_t* video_mem=(uint16_t *)SCR_VIDEOMEM+(x+y*SCR_REAL_WIDTH); // *video_mem=c | (attrib << 8) ; } // same colors as in screen.h static uint32_t cols[] = { 0x0, // black 0x0066cc, //blue 0x009900, //green 0x33ffff, //cyan 0xff3333, //red 0xcc00cc, //magenta 0x994c00, //brown 0xa0a0a0, //light gray 0x404040, //dark gray 0x3399ff, //light blue 0x99ff33, //light green 0x99ffff, //cyan light 0xff9999, //red light 0xff99ff, //magenta light 0xffff00, //yellow 0xffffff, //white }; // glue func for terminal void vesa_console_put_char(uint8_t c,uint8_t color_bg, uint8_t color_fg, uint32_t x, uint32_t y) { // print_char_col(x,y,c, color_bg, color_fg); //PutFont(c, console_x*10,console_y*12, cols[color_fg],cols[color_bg]); //PutFont(c, x*10,y*12, cols[color_bg],cols[color_fg]); PutFont(c, x*9,y*11, cols[color_bg],cols[color_fg]); // buf[console_x][console_y]=c; // console_x++; // #ifdef FOOLOS_CONSOLE_AUTOBREAK // if(console_x>=console_cols)PutConsoleNL(); // #endif } 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;iXres, 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; //TODO dynamic (but need to sync with terminal!) console_cols=80; console_lines=24; // 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; } // TODO: what will happen in 24bit mode? 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_fg,int color_bg) { int fnt=0x126-0x20; if(c>=0x20&&c<=0x126)fnt=c-0x20; int posx, posy, sizex=8, sizey=10; for(posx=x;posx=console_cols)PutConsoleNL(); #endif } void PutConsole(char *str, int color) { while((*str)!=0) { PutConsoleChar(*str,color); str++; } } void PutConsoleNL() { console_y++; if(console_yXres-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; } */