A problem with graphics mode,
Posted: Thu Oct 29, 2015 9:21 pm
When the screen is full,I need scroll down one row to show new information;
But this process is very slow;
For example, if i print 10000 rows on screen,it will take ten seconds of the time to complete this process under the qeum.
But it will take more than ten minutes under the boch or real machine.
How would i can do to fix it up?
But this process is very slow;
For example, if i print 10000 rows on screen,it will take ten seconds of the time to complete this process under the qeum.
But it will take more than ten minutes under the boch or real machine.
How would i can do to fix it up?
Code: Select all
void init_vbe(uint32_t *p){
multiboot_info_t* minf = (multiboot_info_t*)p;
//find if there have info about vbe
//
if((minf == NULL) || (minf->flags & 0x800) != 0x800)
return;
VbeInfoBlock* vbeib = (VbeInfoBlock*)minf->vbe_info.vbe_control_info;
ModeInfoBlock* vebmb = (ModeInfoBlock*)minf->vbe_info.vbe_mode_info;
//D7 = Linear frame buffer mode is available
//0 = No
//1 = Yes
if((vebmb == NULL) || (vebmb->attributes & 0x80) != 0x80){
//Linear frame buffer mode is unavailable
return;
}
if((vebmb->attributes & 0x10) == 0x10){
//text mode
video.mode = 0;
}else{
video.mode = 1;
}
extern char _binary_font_bin_start[];
video.screen = (unsigned char*)vebmb->physbase;
video.Xres = vebmb->Xres;
video.Yres = vebmb->Yres;
video.bpp = vebmb->bpp;
video.pitch = vebmb->pitch;
video.font_address = _binary_font_bin_start;
video.buff_size = video.Xres * video.Yres * (video.bpp/8);
video.crt_pos = 0;
video.fonth = 16; //font pixel height
video.fontw = 8;
video.xpos = video.ypos = 0;
if(video.mode)
video.numchars = video.Xres * video.Yres / video.fonth /video.fontw;
else
video.numchars = video.Xres * video.Yres;
video.nchars_colum = video.Xres / video.fontw;
video.nchars_line = video.Yres / video.fonth;
cprintf("video.bpp:%d\n",video.bpp);
cprintf("video.pitch:%d\n",video.pitch);
cprintf("vbeib->TotalMemory:%dMB\n",vbeib->TotalMemory*64/1024);
cprintf("vbeib.buff_size:%dkb\n",video.buff_size/1024);
cprintf("vbeib->screen:%x\n",video.screen);
}
Code: Select all
void vga_putc(int c){
// if no attribute given, then use black on white
if (!(c & ~0xFF))
c |= 0xFFFFFF00;
switch (c & 0xff) {
case '\n':
video.ypos++;
/* fallthru */
case '\r':
video.xpos = 0;
break;
case '\t':
cons_putc(' ');
cons_putc(' ');
cons_putc(' ');
cons_putc(' ');
cons_putc(' ');
break;
default:
//x * video.fontw, y * video.fontw
draw_char((c & 0xFF),video.xpos * video.fontw, video.ypos * video.fonth ,(c>>8) & 0xFF, (c>>16) & 0xFF,(c>>24) & 0xFF);
video.xpos++;
break;
}
if (video.xpos >= video.nchars_colum ){
video.xpos = 0;
video.ypos++;
}
if(video.ypos >= video.nchars_line){
//video.fonth is height of font
memmove(video.screen, video.screen + video.Xres * video.bpp/8 * video.fonth,
(video.buff_size - video.Xres * video.bpp/8* video.fonth));
video.ypos--;
int i;
for (i = 0; i < video.nchars_colum; i++){
draw_char(' ',(video.xpos + i) * video.fontw, video.ypos * video.fonth ,(c>>8) & 0xFF, (c>>16) & 0xFF,(c>>24) & 0xFF);
}
}
}
Code: Select all
void draw_char(char ch, int x, int y,unsigned char r,unsigned char g,unsigned char b)
{
int bar = video.bpp/8;
char* font = video.font_address + ch*16;
unsigned char *where = video.screen + x*bar + y*video.Xres*bar;
int i, j;
for (i = 0; i < 16; i++) {
uint8_t bit = 0x80;
for (j = 0; j < 8; j++) {
if(*font & bit){
where[j*bar] = b;
where[j*bar + 1] = g;
where[j*bar + 2] = r;
}
else{
where[j*bar] = 0x00;
where[j*bar + 1] = 0x00;
where[j*bar + 2] = 0x00;
}
bit = bit >> 1;
}
where+=video.bpp*video.Xres/8;
font ++;
}
}
Code: Select all
static void putpixel(unsigned char* screen, int x,int y, int color) {
int i = video.bpp/8;
unsigned where = x*i + y*i*video.Xres;
screen[where] = color & 255; // BLUE
screen[where + 1] = (color >> 8) & 255; // GREEN
screen[where + 2] = (color >> 16) & 255; // RED
}