summaryrefslogtreecommitdiff
path: root/video
diff options
context:
space:
mode:
Diffstat (limited to 'video')
-rw-r--r--video/console.c156
-rw-r--r--video/console.h43
-rw-r--r--video/vesa.c228
-rw-r--r--video/vesa.h45
4 files changed, 472 insertions, 0 deletions
diff --git a/video/console.c b/video/console.c
new file mode 100644
index 0000000..c89424b
--- /dev/null
+++ b/video/console.c
@@ -0,0 +1,156 @@
+#include "console.h"
+#include "kernel/config.h"
+
+//#define FOOLOS_CONSOLE
+
+static int posx=0;
+static int posy=0;
+
+// helper_funcs
+
+void print_char_col(int x, int y, char c, char col)
+{
+#ifdef FOOLOS_CONSOLE
+ char* video_mem=(char *)SCR_VIDEOMEM+(x+y*SCR_REAL_WIDTH)*2;
+ video_mem[0]=c;
+ video_mem[1]=col;
+#endif
+}
+
+void print_char(int x, int y, char c)
+{
+ print_char_col(x,y,c,SCR_WHITE);
+}
+
+void print_single_num(int i)
+{
+ if(i<10)print_char_col(posx,posy,'0'+i,SCR_GREEN);
+ else if(i<16)print_char_col(posx,posy,'A'+i-10,SCR_GREEN);
+ posx++;
+ if(posx>=SCR_WIDTH)scr_nextline();
+
+}
+
+void print_str_col(int x,int y,char *str, char col)
+{
+
+ while(*str!=0)
+ {
+ print_char_col(x++,y,*(str++),col);
+ }
+
+}
+
+void print_str(int x,int y,char *str)
+{
+ print_str_col(x,y,str,SCR_WHITE);
+}
+
+
+//
+//
+void scr_clear()
+{
+ int x,y;
+
+ for(x=0;x<SCR_WIDTH;x++)
+ for(y=0;y<SCR_HEIGHT;y++)
+ {
+ print_char_col(x,y,'@',SCR_BLUE);
+
+ }
+
+ posx=posy=0;
+
+}
+
+void scr_put_string_nl(char *str)
+{
+ scr_put_string(str);
+ scr_nextline();
+}
+
+void scr_nextline()
+{
+#ifdef FOOLOS_CONSOLE
+ int i,x;
+
+ posx=0;
+ posy++;
+
+ if(posy>SCR_HEIGHT-2)
+ {
+ for(i=1;i<SCR_HEIGHT-1;i++)
+ {
+
+ for(x=0;x<SCR_WIDTH;x++)
+ {
+ char* video_mem=(char *)SCR_VIDEOMEM+((x)+(i-1)*SCR_REAL_WIDTH)*2;
+ char* video_mem2=(char *)SCR_VIDEOMEM+((x)+i*SCR_REAL_WIDTH)*2;
+ *video_mem=*video_mem2;
+ *(video_mem+1)=*(video_mem2+1);
+ //clear last line
+ if(i==SCR_HEIGHT-2)
+ {
+ print_char_col(x,i,'@',SCR_LBLUE);
+
+
+ }
+ }
+ }
+
+ posy--;
+ }
+#endif
+}
+
+void scr_put_char(char ch,char col)
+{
+
+ print_char_col(posx,posy,ch,SCR_WHITE);
+ posx++;
+ if(posx>=SCR_WIDTH)scr_nextline();
+}
+
+
+void scr_put_hex(uint16_t val)
+{
+
+ int i;
+
+ scr_put_string("0x");
+
+ for(i=0;i<4;i++)
+ {
+ print_single_num((val&0xf000)>>12);
+ val=val << 4;
+
+ }
+
+}
+
+
+void scr_put_hex32(uint32_t val)
+{
+ scr_put_string("[");
+ scr_put_hex(val>>16);
+ scr_put_string(",");
+ scr_put_hex(val&0xffff);
+ scr_put_string("]");
+}
+
+void scr_put_string(char *str)
+{
+ while(*str!=0)
+ {
+ scr_put_char(*(str++),SCR_WHITE);
+ }
+}
+
+void scr_backspace()
+{
+ if(posx==0)return;
+ print_char_col(posx-1,posy,'@',SCR_LGREEN);
+ posx--;
+
+}
diff --git a/video/console.h b/video/console.h
new file mode 100644
index 0000000..22184fb
--- /dev/null
+++ b/video/console.h
@@ -0,0 +1,43 @@
+#ifndef CONSOLEINT_H
+#define CONSOLEINT_H
+
+#include "lib/int/stdint.h"
+
+#define SCR_VIDEOMEM 0xb8000
+
+#define SCR_REAL_WIDTH 80
+
+#define SCR_WIDTH 70
+#define SCR_HEIGHT 23
+
+#define SCR_CTRL 0x3D4
+#define SCR_DATA 0x3D5
+
+// colors
+#define SCR_BLACK 0x0
+#define SCR_BLUE 0x1
+#define SCR_GREEN 0x2
+#define SCR_CYAN 0x3
+#define SCR_RED 0x4
+#define SCR_VIOLET 0x5
+#define SCR_BROWN 0x6
+#define SCR_GRAY1 0x7
+#define SCR_GRAY2 0x8
+#define SCR_LBLUE 0x9
+#define SCR_LGREEN 0xa
+#define SCR_LCYAN 0xb
+#define SCR_LRED 0xc
+#define SCR_PINK 0xd
+#define SCR_YELLOW 0xe
+#define SCR_WHITE 0xf
+
+//autoscroll
+void scr_clear();
+void scr_nextline();
+void scr_backspace();
+void scr_put_char(char ch,char col);
+void scr_put_string(char *str);
+void scr_put_string_nl(char *str);
+void scr_put_hex(uint16_t val);
+
+#endif
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;
+}
+
+
+
diff --git a/video/vesa.h b/video/vesa.h
new file mode 100644
index 0000000..89cb680
--- /dev/null
+++ b/video/vesa.h
@@ -0,0 +1,45 @@
+#include "lib/int/stdint.h"
+
+typedef struct foolfont_struct
+{
+ uint8_t line[10]; //every single fool font consists of 10 lines a 8 bit
+
+}foolfont;
+
+typedef struct vbeinfo_struct{
+ char VbeSignature[4]; // == "VESA"
+ uint16_t VbeVersion; // == 0x0300 for VBE 3.0
+ uint16_t OemStringPtr[2]; // isa vbeFarPtr
+ uint8_t Capabilities[4];
+ uint16_t VideoModePtr[2]; // isa vbeFarPtr
+ uint16_t TotalMemory; // as # of 64KB blocks
+}vbeinfo;
+
+
+typedef struct ModeInfoBlock {
+ uint16_t attributes;
+ uint8_t winA,winB;
+ uint16_t granularity;
+ uint16_t winsize;
+ uint16_t segmentA, segmentB;
+ uint16_t realFctPtr[2];
+// VBE_FAR(realFctPtr);
+ uint16_t pitch; // bytes per scanline
+
+ uint16_t Xres, Yres;
+ uint8_t Wchar, Ychar, planes, bpp, banks;
+ uint8_t memory_model, bank_size, image_pages;
+ uint8_t reserved0;
+
+ uint8_t red_mask, red_position;
+ uint8_t green_mask, green_position;
+ uint8_t blue_mask, blue_position;
+ uint8_t rsv_mask, rsv_position;
+ uint8_t directcolor_attributes;
+
+ volatile uint32_t physbase; // your LFB (Linear Framebuffer) address ;)
+ uint32_t reserved1;
+ uint16_t reserved2;
+}vbemodeinfo;
+
+uint32_t vesa_init(vbeinfo *info,vbemodeinfo *mode,foolfont *rawfont);