626788149 发表于 2015-10-30 13:08

关于图形模式的问题

本帖最后由 626788149 于 2015-10-30 13:09 编辑

当屏幕满的时候 我需要向上滚动一行以显示新的内容

比如,我想打印10000行的信息,在qeum虚拟机下大概需要几秒钟的时间
但是在boch下或者在真实的机器下需要大概十分钟的时间才能全部打印完

如何才能加速呢?
void init_vbe(uint32_t *p){
//初始化VGA 获得一些VGA的信息
   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;// Linear frame buffer 基地址
   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);

}
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);
         
      }
   }

}
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 = b;
            where = g;
            where = r;
         }
         else{
            where = 0x00;
            where = 0x00;
            where = 0x00;
         }
         bit = bit >> 1;
      }
      where+=video.bpp*video.Xres/8;
      font ++;
   }
}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 = color & 255;            // BLUE
   screen = (color >> 8) & 255;   // GREEN
   screen = (color >> 16) & 255;// RED
}刷新的速度很慢
页: [1]
查看完整版本: 关于图形模式的问题