summaryrefslogtreecommitdiff
path: root/video/vesa.c
diff options
context:
space:
mode:
Diffstat (limited to 'video/vesa.c')
-rw-r--r--video/vesa.c228
1 files changed, 228 insertions, 0 deletions
diff --git a/video/vesa.c b/video/vesa.c
new file mode 100644
index 0000000..2addea7
--- /dev/null
+++ b/video/vesa.c
@@ -0,0 +1,228 @@
+//http://wiki.osdev.org/GUI
+#include <stdarg.h>
+#include "kernel/mem.h"
+#include "vesa.h"
+
+#include "lib/logger/log.h" // logger facilities
+#include "lib/int/stdint.h"
+#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;
+}
+
+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_DEBUG,"mode supported : 0x%x", (*modeptr));
+ scr_put_hex(*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;
+}
+
+
+