📄 vgabios.c
字号:
// ============================================================================================/* * vgabios.c */// ============================================================================================// // Copyright (C) 2001,2002 the LGPL VGABios developers Team//// This library is free software; you can redistribute it and/or// modify it under the terms of the GNU Lesser General Public// License as published by the Free Software Foundation; either// version 2 of the License, or (at your option) any later version.//// This library is distributed in the hope that it will be useful,// but WITHOUT ANY WARRANTY; without even the implied warranty of// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU// Lesser General Public License for more details.//// You should have received a copy of the GNU Lesser General Public// License along with this library; if not, write to the Free Software// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA// // ============================================================================================// // This VGA Bios is specific to the plex86/bochs Emulated VGA card. // You can NOT drive any physical vga card with it. // // ============================================================================================// // This file contains code ripped from :// - rombios.c of plex86 //// This VGA Bios contains fonts from :// - fntcol16.zip (c) by Joseph Gil avalable at :// ftp://ftp.simtel.net/pub/simtelnet/msdos/screen/fntcol16.zip// These fonts are public domain //// This VGA Bios is based on information taken from :// - Kevin Lawton's vga card emulation for bochs/plex86// - Ralf Brown's interrupts list available at http://www.cs.cmu.edu/afs/cs/user/ralf/pub/WWW/files.html// - Finn Thogersons' VGADOC4b available at http://home.worldonline.dk/~finth/// - Michael Abrash's Graphics Programming Black Book// - Francois Gervais' book "programmation des cartes graphiques cga-ega-vga" edited by sybex// - DOSEMU 1.0.1 source code for several tables values and formulas//// Thanks for patches, comments and ideas to :// - techt@pikeonline.net//// ============================================================================================#include "vgabios.h"#ifdef VBE#include "vbe.h"#endif#undef DEBUG#define USE_BX_INFO/* Declares */static Bit8u read_byte();static Bit16u read_word();static void write_byte();static void write_word();static Bit8u inb();static Bit16u inw();static void outb();static void outw();static Bit16u get_SS();// Outputstatic void printf();static void unimplemented();static void unknown();static Bit8u find_vga_entry();static void memsetb();static void memsetw();static void memcpyb();static void memcpyw();static void biosfn_set_video_mode();static void biosfn_set_cursor_shape();static void biosfn_set_cursor_pos();static void biosfn_get_cursor_pos();static void biosfn_set_active_page();static void biosfn_scroll();static void biosfn_read_char_attr();static void biosfn_write_char_attr();static void biosfn_write_char_only();static void biosfn_write_pixel();static void biosfn_read_pixel();static void biosfn_write_teletype();static void biosfn_perform_gray_scale_summing();static void biosfn_load_text_user_pat();static void biosfn_load_text_8_14_pat();static void biosfn_load_text_8_8_pat();static void biosfn_load_text_8_16_pat();static void biosfn_load_gfx_8_8_chars();static void biosfn_load_gfx_user_chars();static void biosfn_load_gfx_8_14_chars();static void biosfn_load_gfx_8_8_dd_chars();static void biosfn_load_gfx_8_16_chars();static void biosfn_get_font_info();static void biosfn_alternate_prtsc();static void biosfn_switch_video_interface();static void biosfn_enable_video_refresh_control();static void biosfn_write_string();static void biosfn_read_state_info();static void biosfn_read_video_state_size();static void biosfn_save_video_state();static void biosfn_restore_video_state();// This is for compiling with gcc2 and gcc3#define ASM_START #asm#define ASM_END #endasmASM_STARTMACRO SET_INT_VECTOR push ds xor ax, ax mov ds, ax mov ax, ?3 mov ?1*4, ax mov ax, ?2 mov ?1*4+2, ax pop dsMENDASM_ENDASM_START.text.rom.org 0use16 386vgabios_start:.byte 0x55, 0xaa /* BIOS signature, required for BIOS extensions */.byte 0x40 /* BIOS extension length in units of 512 bytes */vgabios_entry_point: jmp vgabios_init_funcvgabios_name:.ascii "Plex86/Bochs VGABios".ascii " ".byte 0x00// Info from Bart Oldeman.org 0x1e.ascii "IBM".byte 0x00vgabios_version:#ifndef VGABIOS_VERS.ascii "current-cvs"#else.ascii VGABIOS_VERS#endif.ascii " "vgabios_date:.ascii VGABIOS_DATE.byte 0x0a,0x0d.byte 0x00vgabios_copyright:.ascii "(C) 2003 the LGPL VGABios developers Team".byte 0x0a,0x0d.byte 0x00vgabios_license:.ascii "This VGA/VBE Bios is released under the GNU LGPL".byte 0x0a,0x0d.byte 0x0a,0x0d.byte 0x00vgabios_website:.ascii "Please visit :".byte 0x0a,0x0d;;.ascii " . http://www.plex86.org";;.byte 0x0a,0x0d.ascii " . http://bochs.sourceforge.net".byte 0x0a,0x0d.ascii " . http://www.nongnu.org/vgabios".byte 0x0a,0x0d.byte 0x0a,0x0d.byte 0x00 ;; ============================================================================================;;;; Init Entry point;;;; ============================================================================================vgabios_init_func:;; init vga card call init_vga_card;; init basic bios vars call init_bios_area#ifdef VBE ;; init vbe functions call vbe_init #endif;; set int10 vect SET_INT_VECTOR(0x10, #0xC000, #vgabios_int10_handler)#ifdef CIRRUS call cirrus_init#endif;; display splash screen call _display_splash_screen;; init video mode and clear the screen mov ax,#0x0003 int #0x10;; show info call _display_info#ifdef VBE ;; show vbe info call vbe_display_info #endif#ifdef CIRRUS;; show cirrus info call cirrus_display_info#endif retfASM_END/* * int10 handled here */ASM_STARTvgabios_int10_handler: pushf#ifdef DEBUG push es push ds pusha mov bx, #0xc000 mov ds, bx call _int10_debugmsg popa pop ds pop es#endif cmp ah, #0x0f jne int10_test_1A call biosfn_get_video_mode jmp int10_endint10_test_1A: cmp ah, #0x1a jne int10_test_0B call biosfn_group_1A jmp int10_endint10_test_0B: cmp ah, #0x0b jne int10_test_1103 call biosfn_group_0B jmp int10_endint10_test_1103: cmp ax, #0x1103 jne int10_test_12 call biosfn_set_text_block_specifier jmp int10_endint10_test_12: cmp ah, #0x12 jne int10_test_101B cmp bl, #0x10 jne int10_test_BL30 call biosfn_get_ega_info jmp int10_endint10_test_BL30: cmp bl, #0x30 jne int10_test_BL31 call biosfn_select_vert_res jmp int10_endint10_test_BL31: cmp bl, #0x31 jne int10_test_BL32 call biosfn_enable_default_palette_loading jmp int10_endint10_test_BL32: cmp bl, #0x32 jne int10_test_BL33 call biosfn_enable_video_addressing jmp int10_endint10_test_BL33: cmp bl, #0x33 jne int10_test_BL34 call biosfn_enable_grayscale_summing jmp int10_endint10_test_BL34: cmp bl, #0x34 jne int10_normal call biosfn_enable_cursor_emulation jmp int10_endint10_test_101B: cmp ax, #0x101b je int10_normal cmp ah, #0x10#ifndef VBE jne int10_normal#else jne int10_test_4F#endif call biosfn_group_10 jmp int10_end#ifdef VBEint10_test_4F: cmp ah, #0x4f jne int10_normal cmp al, #0x03 jne int10_test_vbe_05 call vbe_biosfn_return_current_mode jmp int10_endint10_test_vbe_05: cmp al, #0x05 jne int10_test_vbe_06 call vbe_biosfn_display_window_control jmp int10_endint10_test_vbe_06: cmp al, #0x06 jne int10_test_vbe_07 call vbe_biosfn_set_get_logical_scan_line_length jmp int10_endint10_test_vbe_07: cmp al, #0x07 jne int10_test_vbe_08 call vbe_biosfn_set_get_display_start jmp int10_endint10_test_vbe_08: cmp al, #0x08 jne int10_normal call vbe_biosfn_set_get_dac_palette_format jmp int10_end#endifint10_normal: push es push ds pusha;; We have to set ds to access the right data segment mov bx, #0xc000 mov ds, bx call _int10_func popa pop ds pop esint10_end: popf iretASM_END#include "vgatables.h"#include "vgafonts.h"/* * Boot time harware inits */ASM_STARTinit_vga_card:;; switch to color mode and enable CPU access 480 lines mov dx, #0x3C2 mov al, #0xC3 outb dx,al;; more than 64k 3C4/04 mov dx, #0x3C4 mov al, #0x04 outb dx,al mov dx, #0x3C5 mov al, #0x02 outb dx,al#if defined(USE_BX_INFO) || defined(DEBUG) mov bx, #msg_vga_init push bx call _printf#endif inc sp inc sp ret#if defined(USE_BX_INFO) || defined(DEBUG)msg_vga_init:.ascii "VGABios $Id: vgabios.c,v 1.61 2005/05/24 16:50:50 vruppert Exp $".byte 0x0d,0x0a,0x00#endifASM_END// --------------------------------------------------------------------------------------------/* * Boot time bios area inits */ASM_STARTinit_bios_area: push ds mov ax, # BIOSMEM_SEG mov ds, ax;; init detected hardware BIOS Area mov bx, # BIOSMEM_INITIAL_MODE mov ax, [bx] and ax, #0xffcf mov [bx], ax;; Just for the first int10 find its children;; the default char height mov bx, # BIOSMEM_CHAR_HEIGHT mov al, #0x10 mov [bx], al;; Clear the screen mov bx, # BIOSMEM_VIDEO_CTL mov al, #0x60 mov [bx], al;; Set the basic screen we have mov bx, # BIOSMEM_SWITCHES mov al, #0xf9 mov [bx], al;; Set the basic modeset options mov bx, # BIOSMEM_MODESET_CTL mov al, #0x51 mov [bx], al;; Set the default MSR mov bx, # BIOSMEM_CURRENT_MSR mov al, #0x09 mov [bx], al pop ds retASM_END// --------------------------------------------------------------------------------------------/* * Boot time Splash screen */static void display_splash_screen(){}// --------------------------------------------------------------------------------------------/* * Tell who we are */static void display_info(){ASM_START mov ax,#0xc000 mov ds,ax mov si,#vgabios_name call _display_string mov si,#vgabios_version call _display_string ;;mov si,#vgabios_copyright ;;call _display_string ;;mov si,#crlf ;;call _display_string mov si,#vgabios_license call _display_string mov si,#vgabios_website call _display_stringASM_END}static void display_string(){ // Get length of stringASM_START mov ax,ds mov es,ax mov di,si xor cx,cx not cx xor al,al cld repne scasb not cx dec cx push cx mov ax,#0x0300 mov bx,#0x0000 int #0x10 pop cx mov ax,#0x1301 mov bx,#0x000b mov bp,si int #0x10ASM_END}// --------------------------------------------------------------------------------------------#ifdef DEBUGstatic void int10_debugmsg(DI, SI, BP, SP, BX, DX, CX, AX, DS, ES, FLAGS) Bit16u DI, SI, BP, SP, BX, DX, CX, AX, ES, DS, FLAGS;{ // 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;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -