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

📄 vgabios.c

📁 xen虚拟机源代码安装包
💻 C
📖 第 1 页 / 共 5 页
字号:
 // 0E is write char... if(GET_AH()!=0x0E)  printf("vgabios call ah%02x al%02x bx%04x cx%04x dx%04x\n",GET_AH(),GET_AL(),BX,CX,DX);}#endif// --------------------------------------------------------------------------------------------/* * int10 main dispatcher */static void int10_func(DI, SI, BP, SP, BX, DX, CX, AX, DS, ES, FLAGS)  Bit16u DI, SI, BP, SP, BX, DX, CX, AX, ES, DS, FLAGS;{ // BIOS functions switch(GET_AH())  {   case 0x00:     biosfn_set_video_mode(GET_AL());     switch(GET_AL()&0x7F)      {case 6:         SET_AL(0x3F);        break;       case 0:       case 1:       case 2:       case 3:       case 4:       case 5:       case 7:        SET_AL(0x30);        break;      default:        SET_AL(0x20);      }     break;   case 0x01:     biosfn_set_cursor_shape(GET_CH(),GET_CL());     break;   case 0x02:     biosfn_set_cursor_pos(GET_BH(),DX);     break;   case 0x03:     biosfn_get_cursor_pos(GET_BH(),&CX,&DX);     break;   case 0x04:     // Read light pen pos (unimplemented)#ifdef DEBUG     unimplemented();#endif     AX=0x00;     BX=0x00;     CX=0x00;     DX=0x00;     break;   case 0x05:     biosfn_set_active_page(GET_AL());     break;   case 0x06:     biosfn_scroll(GET_AL(),GET_BH(),GET_CH(),GET_CL(),GET_DH(),GET_DL(),0xFF,SCROLL_UP);     break;   case 0x07:     biosfn_scroll(GET_AL(),GET_BH(),GET_CH(),GET_CL(),GET_DH(),GET_DL(),0xFF,SCROLL_DOWN);     break;   case 0x08:     biosfn_read_char_attr(GET_BH(),&AX);     break;   case 0x09:     biosfn_write_char_attr(GET_AL(),GET_BH(),GET_BL(),CX);     break;   case 0x0A:     biosfn_write_char_only(GET_AL(),GET_BH(),GET_BL(),CX);     break;   case 0x0C:     biosfn_write_pixel(GET_BH(),GET_AL(),CX,DX);     break;   case 0x0D:     biosfn_read_pixel(GET_BH(),CX,DX,&AX);     break;   case 0x0E:     // Ralf Brown Interrupt list is WRONG on bh(page)     // We do output only on the current page !     biosfn_write_teletype(GET_AL(),0xff,GET_BL(),NO_ATTR);     break;   case 0x10:     // All other functions of group AH=0x10 rewritten in assembler     biosfn_perform_gray_scale_summing(BX,CX);     break;   case 0x11:     switch(GET_AL())      {       case 0x00:       case 0x10:        biosfn_load_text_user_pat(GET_AL(),ES,BP,CX,DX,GET_BL(),GET_BH());        break;       case 0x01:       case 0x11:        biosfn_load_text_8_14_pat(GET_AL(),GET_BL());        break;       case 0x02:       case 0x12:        biosfn_load_text_8_8_pat(GET_AL(),GET_BL());        break;       case 0x04:       case 0x14:        biosfn_load_text_8_16_pat(GET_AL(),GET_BL());        break;       case 0x20:        biosfn_load_gfx_8_8_chars(ES,BP);        break;       case 0x21:        biosfn_load_gfx_user_chars(ES,BP,CX,GET_BL(),GET_DL());        break;       case 0x22:        biosfn_load_gfx_8_14_chars(GET_BL());        break;       case 0x23:        biosfn_load_gfx_8_8_dd_chars(GET_BL());        break;       case 0x24:        biosfn_load_gfx_8_16_chars(GET_BL());        break;       case 0x30:        biosfn_get_font_info(GET_BH(),&ES,&BP,&CX,&DX);        break;#ifdef DEBUG       default:        unknown();#endif      }          break;   case 0x12:     switch(GET_BL())      {       case 0x20:        biosfn_alternate_prtsc();        break;       case 0x35:        biosfn_switch_video_interface(GET_AL(),ES,DX);        SET_AL(0x12);        break;       case 0x36:        biosfn_enable_video_refresh_control(GET_AL());        SET_AL(0x12);        break;#ifdef DEBUG       default:        unknown();#endif      }     break;   case 0x13:     biosfn_write_string(GET_AL(),GET_BH(),GET_BL(),CX,GET_DH(),GET_DL(),ES,BP);     break;   case 0x1B:     biosfn_read_state_info(BX,ES,DI);     SET_AL(0x1B);     break;   case 0x1C:     switch(GET_AL())      {       case 0x00:        biosfn_read_video_state_size(CX,&BX);        break;       case 0x01:        biosfn_save_video_state(CX,ES,BX);        break;       case 0x02:        biosfn_restore_video_state(CX,ES,BX);        break;#ifdef DEBUG       default:        unknown();#endif      }     SET_AL(0x1C);     break;#ifdef VBE    case 0x4f:     if (vbe_has_vbe_display()) {       switch(GET_AL())       {         case 0x00:          vbe_biosfn_return_controller_information(&AX,ES,DI);          break;         case 0x01:          vbe_biosfn_return_mode_information(&AX,CX,ES,DI);          break;         case 0x02:          vbe_biosfn_set_mode(&AX,BX,ES,DI);          break;         case 0x04:          vbe_biosfn_save_restore_state(&AX, CX, DX, ES, &BX);          break;         case 0x09:          //FIXME#ifdef DEBUG          unimplemented();#endif          // function failed          AX=0x100;          break;         case 0x0A:          //FIXME#ifdef DEBUG          unimplemented();#endif          // function failed          AX=0x100;          break;         default:#ifdef DEBUG          unknown();#endif   		           // function failed          AX=0x100;          }        }        else {          // No VBE display          AX=0x0100;          }        break;#endif#ifdef DEBUG   default:     unknown();#endif  }}// ============================================================================================// // BIOS functions// // ============================================================================================static void biosfn_set_video_mode(mode) Bit8u mode; {// mode: Bit 7 is 1 if no clear screen // Should we clear the screen ? Bit8u noclearmem=mode&0x80; Bit8u line,mmask,*palette,vpti; Bit16u i,twidth,theightm1,cheight; Bit8u modeset_ctl,video_ctl,vga_switches; Bit16u crtc_addr; #ifdef VBE if (vbe_has_vbe_display()) {    dispi_set_enable(VBE_DISPI_DISABLED);  }#endif // def VBE  // The real mode mode=mode&0x7f; // find the entry in the video modes line=find_vga_entry(mode);#ifdef DEBUG printf("mode search %02x found line %02x\n",mode,line);#endif if(line==0xFF)  return; vpti=line_to_vpti[line]; twidth=video_param_table[vpti].twidth; theightm1=video_param_table[vpti].theightm1; cheight=video_param_table[vpti].cheight;  // Read the bios vga control video_ctl=read_byte(BIOSMEM_SEG,BIOSMEM_VIDEO_CTL); // Read the bios vga switches vga_switches=read_byte(BIOSMEM_SEG,BIOSMEM_SWITCHES); // Read the bios mode set control modeset_ctl=read_byte(BIOSMEM_SEG,BIOSMEM_MODESET_CTL); // Then we know the number of lines// FIXME // if palette loading (bit 3 of modeset ctl = 0) if((modeset_ctl&0x08)==0)  {// Set the PEL mask   outb(VGAREG_PEL_MASK,vga_modes[line].pelmask);   // Set the whole dac always, from 0   outb(VGAREG_DAC_WRITE_ADDRESS,0x00);   // From which palette   switch(vga_modes[line].dacmodel)    {case 0:      palette=&palette0;      break;     case 1:      palette=&palette1;      break;     case 2:      palette=&palette2;      break;     case 3:      palette=&palette3;      break;    }   // Always 256*3 values   for(i=0;i<0x0100;i++)    {if(i<=dac_regs[vga_modes[line].dacmodel])      {outb(VGAREG_DAC_DATA,palette[(i*3)+0]);       outb(VGAREG_DAC_DATA,palette[(i*3)+1]);       outb(VGAREG_DAC_DATA,palette[(i*3)+2]);      }     else      {outb(VGAREG_DAC_DATA,0);       outb(VGAREG_DAC_DATA,0);       outb(VGAREG_DAC_DATA,0);      }    }   if((modeset_ctl&0x02)==0x02)    {     biosfn_perform_gray_scale_summing(0x00, 0x100);    }  } // Reset Attribute Ctl flip-flop inb(VGAREG_ACTL_RESET); // Set Attribute Ctl for(i=0;i<=0x13;i++)  {outb(VGAREG_ACTL_ADDRESS,i);   outb(VGAREG_ACTL_WRITE_DATA,video_param_table[vpti].actl_regs[i]);  } outb(VGAREG_ACTL_ADDRESS,0x14); outb(VGAREG_ACTL_WRITE_DATA,0x00); // Set Sequencer Ctl outb(VGAREG_SEQU_ADDRESS,0); outb(VGAREG_SEQU_DATA,0x03); for(i=1;i<=4;i++)  {outb(VGAREG_SEQU_ADDRESS,i);   outb(VGAREG_SEQU_DATA,video_param_table[vpti].sequ_regs[i - 1]);  } // Set Grafx Ctl for(i=0;i<=8;i++)  {outb(VGAREG_GRDC_ADDRESS,i);   outb(VGAREG_GRDC_DATA,video_param_table[vpti].grdc_regs[i]);  } // Set CRTC address VGA or MDA  crtc_addr=vga_modes[line].memmodel==MTEXT?VGAREG_MDA_CRTC_ADDRESS:VGAREG_VGA_CRTC_ADDRESS; // Disable CRTC write protection outw(crtc_addr,0x0011); // Set CRTC regs for(i=0;i<=0x18;i++)  {outb(crtc_addr,i);   outb(crtc_addr+1,video_param_table[vpti].crtc_regs[i]);  } // Set the misc register outb(VGAREG_WRITE_MISC_OUTPUT,video_param_table[vpti].miscreg); // Enable video outb(VGAREG_ACTL_ADDRESS,0x20); inb(VGAREG_ACTL_RESET); if(noclearmem==0x00)  {   if(vga_modes[line].class==TEXT)    {     memsetw(vga_modes[line].sstart,0,0x0720,0x4000); // 32k    }   else    {     if(mode<0x0d)      {       memsetw(vga_modes[line].sstart,0,0x0000,0x4000); // 32k      }     else      {       outb( VGAREG_SEQU_ADDRESS, 0x02 );       mmask = inb( VGAREG_SEQU_DATA );       outb( VGAREG_SEQU_DATA, 0x0f ); // all planes       memsetw(vga_modes[line].sstart,0,0x0000,0x8000); // 64k       outb( VGAREG_SEQU_DATA, mmask );      }    }  } // Set the BIOS mem write_byte(BIOSMEM_SEG,BIOSMEM_CURRENT_MODE,mode); write_word(BIOSMEM_SEG,BIOSMEM_NB_COLS,twidth); write_word(BIOSMEM_SEG,BIOSMEM_PAGE_SIZE,*(Bit16u *)&video_param_table[vpti].slength_l); write_word(BIOSMEM_SEG,BIOSMEM_CRTC_ADDRESS,crtc_addr); write_byte(BIOSMEM_SEG,BIOSMEM_NB_ROWS,theightm1); write_word(BIOSMEM_SEG,BIOSMEM_CHAR_HEIGHT,cheight); write_byte(BIOSMEM_SEG,BIOSMEM_VIDEO_CTL,(0x60|noclearmem)); write_byte(BIOSMEM_SEG,BIOSMEM_SWITCHES,0xF9); write_byte(BIOSMEM_SEG,BIOSMEM_MODESET_CTL,read_byte(BIOSMEM_SEG,BIOSMEM_MODESET_CTL)&0x7f); // FIXME We nearly have the good tables. to be reworked write_byte(BIOSMEM_SEG,BIOSMEM_DCC_INDEX,0x08);    // 8 is VGA should be ok for now write_word(BIOSMEM_SEG,BIOSMEM_VS_POINTER, video_save_pointer_table); write_word(BIOSMEM_SEG,BIOSMEM_VS_POINTER+2, 0xc000); // FIXME write_byte(BIOSMEM_SEG,BIOSMEM_CURRENT_MSR,0x00); // Unavailable on vanilla vga, but... write_byte(BIOSMEM_SEG,BIOSMEM_CURRENT_PAL,0x00); // Unavailable on vanilla vga, but...  // Set cursor shape if(vga_modes[line].class==TEXT)  {   biosfn_set_cursor_shape(0x06,0x07);  } // Set cursor pos for page 0..7 for(i=0;i<8;i++)  biosfn_set_cursor_pos(i,0x0000); // Set active page 0 biosfn_set_active_page(0x00); // Write the fonts in memory if(vga_modes[line].class==TEXT)  { ASM_START  ;; copy and activate 8x16 font  mov ax, #0x1104  mov bl, #0x00  int #0x10  mov ax, #0x1103  mov bl, #0x00  int #0x10ASM_END  } // Set the ints 0x1F and 0x43ASM_START SET_INT_VECTOR(0x1f, #0xC000, #_vgafont8+128*8)ASM_END  switch(cheight)   {case 8:ASM_START     SET_INT_VECTOR(0x43, #0xC000, #_vgafont8)ASM_END     break;    case 14:ASM_START     SET_INT_VECTOR(0x43, #0xC000, #_vgafont14)ASM_END     break;    case 16:ASM_START     SET_INT_VECTOR(0x43, #0xC000, #_vgafont16)ASM_END     break;   }}// --------------------------------------------------------------------------------------------static void biosfn_set_cursor_shape (CH,CL) Bit8u CH;Bit8u CL; {Bit16u cheight,curs,crtc_addr; Bit8u modeset_ctl; CH&=0x3f; CL&=0x1f; curs=(CH<<8)+CL; write_word(BIOSMEM_SEG,BIOSMEM_CURSOR_TYPE,curs); modeset_ctl=read_byte(BIOSMEM_SEG,BIOSMEM_MODESET_CTL); cheight = read_word(BIOSMEM_SEG,BIOSMEM_CHAR_HEIGHT); if((modeset_ctl&0x01) && (cheight>8) && (CL<8) && (CH<0x20))  {   if(CL!=(CH+1))    {     CH = ((CH+1) * cheight / 8) -1;    }   else    {     CH = ((CL+1) * cheight / 8) - 2;    }   CL = ((CL+1) * cheight / 8) - 1;  } // CTRC regs 0x0a and 0x0b crtc_addr=read_word(BIOSMEM_SEG,BIOSMEM_CRTC_ADDRESS); outb(crtc_addr,0x0a); outb(crtc_addr+1,CH); outb(crtc_addr,0x0b); outb(crtc_addr+1,CL);}// --------------------------------------------------------------------------------------------static void biosfn_set_cursor_pos (page, cursor) Bit8u page;Bit16u cursor;{ Bit8u xcurs,ycurs,current; Bit16u nbcols,nbrows,address,crtc_addr; // Should not happen... if(page>7)return; // Bios cursor pos write_word(BIOSMEM_SEG, BIOSMEM_CURSOR_POS+2*page, cursor); // Set the hardware cursor current=read_byte(BIOSMEM_SEG,BIOSMEM_CURRENT_PAGE); if(page==current)  {   // Get the dimensions   nbcols=read_word(BIOSMEM_SEG,BIOSMEM_NB_COLS);   nbrows=read_byte(BIOSMEM_SEG,BIOSMEM_NB_ROWS)+1;   xcurs=cursor&0x00ff;ycurs=(cursor&0xff00)>>8;    // Calculate the address knowing nbcols nbrows and page num   address=SCREEN_IO_START(nbcols,nbrows,page)+xcurs+ycurs*nbcols;      // CRTC regs 0x0e and 0x0f   crtc_addr=read_word(BIOSMEM_SEG,BIOSMEM_CRTC_ADDRESS);   outb(crtc_addr,0x0e);   outb(crtc_addr+1,(address&0xff00)>>8);   outb(crtc_addr,0x0f);   outb(crtc_addr+1,address&0x00ff);  }}// --------------------------------------------------------------------------------------------static void biosfn_get_cursor_pos (page,shape, pos) Bit8u page;Bit16u *shape;Bit16u *pos;{ Bit16u ss=get_SS(); // Default write_word(ss, shape, 0); write_word(ss, pos, 0); if(page>7)return; // FIXME should handle VGA 14/16 lines write_word(ss,shape,read_word(BIOSMEM_SEG,BIOSMEM_CURSOR_TYPE)); write_word(ss,pos,read_word(BIOSMEM_SEG,BIOSMEM_CURSOR_POS+page*2));}// --------------------------------------------------------------------------------------------static void biosfn_set_active_page (page) Bit8u page;{ Bit16u cursor,dummy,crtc_addr; Bit16u nbcols,nbrows,address; Bit8u mode,line; if(page>7)return; // Get the mode mode=read_byte(BIOSMEM_SEG,BIOSMEM_CURRENT_MODE); line=find_vga_entry(mode); if(line==0xFF)return; // Get pos curs pos for the right page  biosfn_get_cursor_pos(page,&dummy,&cursor); if(vga_modes[line].class==TEXT)  {   // Get the dimensions   nbcols=read_word(BIOSMEM_SEG,BIOSMEM_NB_COLS);   nbrows=read_byte(BIOSMEM_SEG,BIOSMEM_NB_ROWS)+1;    // Calculate the address knowing nbcols nbrows and page num   address=SCREEN_MEM_START(nbcols,nbrows,page);   write_word(BIOSMEM_SEG,BIOSMEM_CURRENT_START,address);   // Start address   address=SCREEN_IO_START(nbcols,nbrows,page);  } else  {   address = page * (*(Bit16u *)&video_param_table[line_to_vpti[line]].slength_l);

⌨️ 快捷键说明

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