⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 vgabios.c

📁 xen虚拟机源代码安装包
💻 C
📖 第 1 页 / 共 5 页
字号:
  } // CRTC regs 0x0c and 0x0d crtc_addr=read_word(BIOSMEM_SEG,BIOSMEM_CRTC_ADDRESS); outb(crtc_addr,0x0c); outb(crtc_addr+1,(address&0xff00)>>8); outb(crtc_addr,0x0d); outb(crtc_addr+1,address&0x00ff); // And change the BIOS page write_byte(BIOSMEM_SEG,BIOSMEM_CURRENT_PAGE,page);#ifdef DEBUG printf("Set active page %02x address %04x\n",page,address);#endif // Display the cursor, now the page is active biosfn_set_cursor_pos(page,cursor);}// --------------------------------------------------------------------------------------------static void vgamem_copy_pl4(xstart,ysrc,ydest,cols,nbcols,cheight)Bit8u xstart;Bit8u ysrc;Bit8u ydest;Bit8u cols;Bit8u nbcols;Bit8u cheight;{ Bit16u src,dest; Bit8u i; src=ysrc*cheight*nbcols+xstart; dest=ydest*cheight*nbcols+xstart; outw(VGAREG_GRDC_ADDRESS, 0x0105); for(i=0;i<cheight;i++)  {   memcpyb(0xa000,dest+i*nbcols,0xa000,src+i*nbcols,cols);  } outw(VGAREG_GRDC_ADDRESS, 0x0005);}// --------------------------------------------------------------------------------------------static void vgamem_fill_pl4(xstart,ystart,cols,nbcols,cheight,attr)Bit8u xstart;Bit8u ystart;Bit8u cols;Bit8u nbcols;Bit8u cheight;Bit8u attr;{ Bit16u dest; Bit8u i; dest=ystart*cheight*nbcols+xstart; outw(VGAREG_GRDC_ADDRESS, 0x0205); for(i=0;i<cheight;i++)  {   memsetb(0xa000,dest+i*nbcols,attr,cols);  } outw(VGAREG_GRDC_ADDRESS, 0x0005);}// --------------------------------------------------------------------------------------------static void vgamem_copy_cga(xstart,ysrc,ydest,cols,nbcols,cheight)Bit8u xstart;Bit8u ysrc;Bit8u ydest;Bit8u cols;Bit8u nbcols;Bit8u cheight;{ Bit16u src,dest; Bit8u i; src=((ysrc*cheight*nbcols)>>1)+xstart; dest=((ydest*cheight*nbcols)>>1)+xstart; for(i=0;i<cheight;i++)  {   if (i & 1)     memcpyb(0xb800,0x2000+dest+(i>>1)*nbcols,0xb800,0x2000+src+(i>>1)*nbcols,cols);   else     memcpyb(0xb800,dest+(i>>1)*nbcols,0xb800,src+(i>>1)*nbcols,cols);  }}// --------------------------------------------------------------------------------------------static void vgamem_fill_cga(xstart,ystart,cols,nbcols,cheight,attr)Bit8u xstart;Bit8u ystart;Bit8u cols;Bit8u nbcols;Bit8u cheight;Bit8u attr;{ Bit16u dest; Bit8u i; dest=((ystart*cheight*nbcols)>>1)+xstart; for(i=0;i<cheight;i++)  {   if (i & 1)     memsetb(0xb800,0x2000+dest+(i>>1)*nbcols,attr,cols);   else     memsetb(0xb800,dest+(i>>1)*nbcols,attr,cols);  }}// --------------------------------------------------------------------------------------------static void biosfn_scroll (nblines,attr,rul,cul,rlr,clr,page,dir)Bit8u nblines;Bit8u attr;Bit8u rul;Bit8u cul;Bit8u rlr;Bit8u clr;Bit8u page;Bit8u dir;{ // page == 0xFF if current Bit8u mode,line,cheight,bpp,cols; Bit16u nbcols,nbrows,i; Bit16u address; if(rul>rlr)return; if(cul>clr)return; // Get the mode mode=read_byte(BIOSMEM_SEG,BIOSMEM_CURRENT_MODE); line=find_vga_entry(mode); if(line==0xFF)return; // Get the dimensions nbrows=read_byte(BIOSMEM_SEG,BIOSMEM_NB_ROWS)+1; nbcols=read_word(BIOSMEM_SEG,BIOSMEM_NB_COLS); // Get the current page if(page==0xFF)  page=read_byte(BIOSMEM_SEG,BIOSMEM_CURRENT_PAGE); if(rlr>=nbrows)rlr=nbrows-1; if(clr>=nbcols)clr=nbcols-1; if(nblines>nbrows)nblines=0; cols=clr-cul+1; if(vga_modes[line].class==TEXT)  {   // Compute the address   address=SCREEN_MEM_START(nbcols,nbrows,page);#ifdef DEBUG   printf("Scroll, address %04x (%04x %04x %02x)\n",address,nbrows,nbcols,page);#endif   if(nblines==0&&rul==0&&cul==0&&rlr==nbrows-1&&clr==nbcols-1)    {     memsetw(vga_modes[line].sstart,address,(Bit16u)attr*0x100+' ',nbrows*nbcols);    }   else    {// if Scroll up     if(dir==SCROLL_UP)      {for(i=rul;i<=rlr;i++)        {         if((i+nblines>rlr)||(nblines==0))          memsetw(vga_modes[line].sstart,address+(i*nbcols+cul)*2,(Bit16u)attr*0x100+' ',cols);         else          memcpyw(vga_modes[line].sstart,address+(i*nbcols+cul)*2,vga_modes[line].sstart,((i+nblines)*nbcols+cul)*2,cols);        }      }     else      {for(i=rlr;i>=rul;i--)        {         if((i<rul+nblines)||(nblines==0))          memsetw(vga_modes[line].sstart,address+(i*nbcols+cul)*2,(Bit16u)attr*0x100+' ',cols);         else          memcpyw(vga_modes[line].sstart,address+(i*nbcols+cul)*2,vga_modes[line].sstart,((i-nblines)*nbcols+cul)*2,cols);         if (i>rlr) break;        }      }    }  } else  {   // FIXME gfx mode not complete   cheight=video_param_table[line_to_vpti[line]].cheight;   switch(vga_modes[line].memmodel)    {     case PLANAR4:     case PLANAR1:       if(nblines==0&&rul==0&&cul==0&&rlr==nbrows-1&&clr==nbcols-1)        {         outw(VGAREG_GRDC_ADDRESS, 0x0205);         memsetb(vga_modes[line].sstart,0,attr,nbrows*nbcols*cheight);         outw(VGAREG_GRDC_ADDRESS, 0x0005);        }       else        {// if Scroll up         if(dir==SCROLL_UP)          {for(i=rul;i<=rlr;i++)            {             if((i+nblines>rlr)||(nblines==0))              vgamem_fill_pl4(cul,i,cols,nbcols,cheight,attr);             else              vgamem_copy_pl4(cul,i+nblines,i,cols,nbcols,cheight);            }          }         else          {for(i=rlr;i>=rul;i--)            {             if((i<rul+nblines)||(nblines==0))              vgamem_fill_pl4(cul,i,cols,nbcols,cheight,attr);             else              vgamem_copy_pl4(cul,i,i-nblines,cols,nbcols,cheight);             if (i>rlr) break;            }          }        }       break;     case CGA:       bpp=vga_modes[line].pixbits;       if(nblines==0&&rul==0&&cul==0&&rlr==nbrows-1&&clr==nbcols-1)        {         memsetb(vga_modes[line].sstart,0,attr,nbrows*nbcols*cheight*bpp);        }       else        {         if(bpp==2)          {           cul<<=1;           cols<<=1;           nbcols<<=1;          }         // if Scroll up         if(dir==SCROLL_UP)          {for(i=rul;i<=rlr;i++)            {             if((i+nblines>rlr)||(nblines==0))              vgamem_fill_cga(cul,i,cols,nbcols,cheight,attr);             else              vgamem_copy_cga(cul,i+nblines,i,cols,nbcols,cheight);            }          }         else          {for(i=rlr;i>=rul;i--)            {             if((i<rul+nblines)||(nblines==0))              vgamem_fill_cga(cul,i,cols,nbcols,cheight,attr);             else              vgamem_copy_cga(cul,i,i-nblines,cols,nbcols,cheight);             if (i>rlr) break;            }          }        }       break;#ifdef DEBUG     default:       printf("Scroll in graphics mode ");       unimplemented();#endif    }  }}// --------------------------------------------------------------------------------------------static void biosfn_read_char_attr (page,car) Bit8u page;Bit16u *car;{Bit16u ss=get_SS(); Bit8u xcurs,ycurs,mode,line; Bit16u nbcols,nbrows,address; Bit16u cursor,dummy; // Get the mode mode=read_byte(BIOSMEM_SEG,BIOSMEM_CURRENT_MODE); line=find_vga_entry(mode); if(line==0xFF)return; // Get the cursor pos for the page biosfn_get_cursor_pos(page,&dummy,&cursor); xcurs=cursor&0x00ff;ycurs=(cursor&0xff00)>>8; // Get the dimensions nbrows=read_byte(BIOSMEM_SEG,BIOSMEM_NB_ROWS)+1; nbcols=read_word(BIOSMEM_SEG,BIOSMEM_NB_COLS); if(vga_modes[line].class==TEXT)  {   // Compute the address   address=SCREEN_MEM_START(nbcols,nbrows,page)+(xcurs+ycurs*nbcols)*2;   write_word(ss,car,read_word(vga_modes[line].sstart,address));  } else  {   // FIXME gfx mode#ifdef DEBUG   unimplemented();#endif  }}// --------------------------------------------------------------------------------------------static void write_gfx_char_pl4(car,attr,xcurs,ycurs,nbcols,cheight)Bit8u car;Bit8u attr;Bit8u xcurs;Bit8u ycurs;Bit8u nbcols;Bit8u cheight;{ Bit8u i,j,mask; Bit8u *fdata; Bit16u addr,dest,src; switch(cheight)  {case 14:    fdata = &vgafont14;    break;   case 16:    fdata = &vgafont16;    break;   default:    fdata = &vgafont8;  } addr=xcurs+ycurs*cheight*nbcols; src = car * cheight; outw(VGAREG_SEQU_ADDRESS, 0x0f02); outw(VGAREG_GRDC_ADDRESS, 0x0205); if(attr&0x80)  {   outw(VGAREG_GRDC_ADDRESS, 0x1803);  } else  {   outw(VGAREG_GRDC_ADDRESS, 0x0003);  } for(i=0;i<cheight;i++)  {   dest=addr+i*nbcols;   for(j=0;j<8;j++)    {     mask=0x80>>j;     outw(VGAREG_GRDC_ADDRESS, (mask << 8) | 0x08);     read_byte(0xa000,dest);     if(fdata[src+i]&mask)      {       write_byte(0xa000,dest,attr&0x0f);      }     else      {       write_byte(0xa000,dest,0x00);      }    }  }ASM_START  mov dx, # VGAREG_GRDC_ADDRESS  mov ax, #0xff08  out dx, ax  mov ax, #0x0005  out dx, ax  mov ax, #0x0003  out dx, axASM_END}// --------------------------------------------------------------------------------------------static void write_gfx_char_cga(car,attr,xcurs,ycurs,nbcols,bpp)Bit8u car;Bit8u attr;Bit8u xcurs;Bit8u ycurs;Bit8u nbcols;Bit8u bpp;{ Bit8u i,j,mask,data; Bit8u *fdata; Bit16u addr,dest,src; fdata = &vgafont8; addr=(xcurs*bpp)+ycurs*320; src = car * 8; for(i=0;i<8;i++)  {   dest=addr+(i>>1)*80;   if (i & 1) dest += 0x2000;   mask = 0x80;   if (bpp == 1)    {     if (attr & 0x80)      {       data = read_byte(0xb800,dest);      }     else      {       data = 0x00;      }     for(j=0;j<8;j++)      {       if (fdata[src+i] & mask)        {         if (attr & 0x80)          {           data ^= (attr & 0x01) << (7-j);          }         else          {           data |= (attr & 0x01) << (7-j);          }        }       mask >>= 1;      }     write_byte(0xb800,dest,data);    }   else    {     while (mask > 0)      {       if (attr & 0x80)        {         data = read_byte(0xb800,dest);        }       else        {         data = 0x00;        }       for(j=0;j<4;j++)        {         if (fdata[src+i] & mask)          {           if (attr & 0x80)            {             data ^= (attr & 0x03) << ((3-j)*2);            }           else            {             data |= (attr & 0x03) << ((3-j)*2);            }          }         mask >>= 1;        }       write_byte(0xb800,dest,data);       dest += 1;      }    }  }}// --------------------------------------------------------------------------------------------static void write_gfx_char_lin(car,attr,xcurs,ycurs,nbcols)Bit8u car;Bit8u attr;Bit8u xcurs;Bit8u ycurs;Bit8u nbcols;{ Bit8u i,j,mask,data; Bit8u *fdata; Bit16u addr,dest,src; fdata = &vgafont8; addr=xcurs*8+ycurs*nbcols*64; src = car * 8; for(i=0;i<8;i++)  {   dest=addr+i*nbcols*8;   mask = 0x80;   for(j=0;j<8;j++)    {     data = 0x00;     if (fdata[src+i] & mask)      {       data = attr;      }     write_byte(0xa000,dest+j,data);     mask >>= 1;    }  }}// --------------------------------------------------------------------------------------------static void biosfn_write_char_attr (car,page,attr,count) Bit8u car;Bit8u page;Bit8u attr;Bit16u count;{ Bit8u cheight,xcurs,ycurs,mode,line,bpp; Bit16u nbcols,nbrows,address; Bit16u cursor,dummy; // Get the mode mode=read_byte(BIOSMEM_SEG,BIOSMEM_CURRENT_MODE); line=find_vga_entry(mode); if(line==0xFF)return; // Get the cursor pos for the page biosfn_get_cursor_pos(page,&dummy,&cursor); xcurs=cursor&0x00ff;ycurs=(cursor&0xff00)>>8; // Get the dimensions nbrows=read_byte(BIOSMEM_SEG,BIOSMEM_NB_ROWS)+1; nbcols=read_word(BIOSMEM_SEG,BIOSMEM_NB_COLS); if(vga_modes[line].class==TEXT)  {   // Compute the address   address=SCREEN_MEM_START(nbcols,nbrows,page)+(xcurs+ycurs*nbcols)*2;   dummy=((Bit16u)attr<<8)+car;   memsetw(vga_modes[line].sstart,address,dummy,count);  } else  {   // FIXME gfx mode not complete   cheight=video_param_table[line_to_vpti[line]].cheight;   bpp=vga_modes[line].pixbits;   while((count-->0) && (xcurs<nbcols))    {     switch(vga_modes[line].memmodel)      {       case PLANAR4:       case PLANAR1:         write_gfx_char_pl4(car,attr,xcurs,ycurs,nbcols,cheight);         break;       case CGA:         write_gfx_char_cga(car,attr,xcurs,ycurs,nbcols,bpp);         break;       case LINEAR8:         write_gfx_char_lin(car,attr,xcurs,ycurs,nbcols);         break;#ifdef DEBUG       default:         unimplemented();#endif      }     xcurs++;    }  }}// --------------------------------------------------------------------------------------------static void biosfn_write_char_only (car,page,attr,count)Bit8u car;Bit8u page;Bit8u attr;Bit16u count;{ Bit8u cheight,xcurs,ycurs,mode,line,bpp; Bit16u nbcols,nbrows,address; Bit16u cursor,dummy; // Get the mode mode=read_byte(BIOSMEM_SEG,BIOSMEM_CURRENT_MODE); line=find_vga_entry(mode); if(line==0xFF)return; // Get the cursor pos for the page biosfn_get_cursor_pos(page,&dummy,&cursor); xcurs=cursor&0x00ff;ycurs=(cursor&0xff00)>>8; // Get the dimensions nbrows=read_byte(BIOSMEM_SEG,BIOSMEM_NB_ROWS)+1; nbcols=read_word(BIOSMEM_SEG,BIOSMEM_NB_COLS); if(vga_modes[line].class==TEXT)  {   // Compute the address   address=SCREEN_MEM_START(nbcols,nbrows,page)+(xcurs+ycurs*nbcols)*2;   while(count-->0)    {write_byte(vga_modes[line].sstart,address,car);     address+=2;    }  } else  {   // FIXME gfx mode not complete   cheight=video_param_table[line_to_vpti[line]].cheight;   bpp=vga_modes[line].pixbits;   while((count-->0) && (xcurs<nbcols))    {     switch(vga_modes[line].memmodel)      {       case PLANAR4:       case PLANAR1:         write_gfx_char_pl4(car,attr,xcurs,ycurs,nbcols,cheight);         break;       case CGA:         write_gfx_char_cga(car,attr,xcurs,ycurs,nbcols,bpp);         break;       case LINEAR8:         write_gfx_char_lin(car,attr,xcurs,ycurs,nbcols);         break;#ifdef DEBUG       default:         unimplemented();#endif      }     xcurs++;    }  }}// --------------------------------------------------------------------------------------------ASM_STARTbiosfn_group_0B:  cmp   bh, #0x00  je    biosfn_set_border_color  cmp   bh, #0x01  je    biosfn_set_palette#ifdef DEBUG  call  _unknown#endif  retbiosfn_set_border_color:  push  ax  push  bx  push  cx  push  dx  mov   dx, # VGAREG_ACTL_RESET  in    al, dx  mov   dx, # VGAREG_ACTL_ADDRESS  mov   al, #0x00  out   dx, al  mov   al, bl  and   al, #0x0f  test  al, #0x08  jz    set_low_border  add   al, #0x08set_low_border:  out   dx, al  mov   cl, #0x01  and   bl, #0x10

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -