diff options
Diffstat (limited to 'video')
| -rw-r--r-- | video/console.c | 156 | ||||
| -rw-r--r-- | video/console.h | 43 | ||||
| -rw-r--r-- | video/vesa.c | 228 | ||||
| -rw-r--r-- | video/vesa.h | 45 |
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); |
