📄 clext.c
字号:
//// QEMU Cirrus CLGD 54xx VGABIOS Extension.//// Copyright (c) 2004 Makoto Suzuki (suzu)//// 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// //#define CIRRUS_VESA3_PMINFO#ifdef VBE#undef CIRRUS_VESA3_PMINFO#endif#define PM_BIOSMEM_CURRENT_MODE 0x449#define PM_BIOSMEM_CRTC_ADDRESS 0x463#define PM_BIOSMEM_VBE_MODE 0x4BA#define PM_BIOSMEM_VBE_POWER 0x4BC typedef struct{ /* + 0 */ unsigned short mode; unsigned short width; unsigned short height; unsigned short depth; /* + 8 */ unsigned short hidden_dac; /* 0x3c6 */ unsigned short *seq; /* 0x3c4 */ unsigned short *graph; /* 0x3ce */ unsigned short *crtc; /* 0x3d4 */ /* +16 */ unsigned char bitsperpixel; unsigned char vesacolortype; unsigned char vesaredmask; unsigned char vesaredpos; unsigned char vesagreenmask; unsigned char vesagreenpos; unsigned char vesabluemask; unsigned char vesabluepos; /* +24 */ unsigned char vesareservedmask; unsigned char vesareservedpos;} cirrus_mode_t;#define CIRRUS_MODE_SIZE 26/* For VESA BIOS 3.0 */#define CIRRUS_PM16INFO_SIZE 20/* VGA */unsigned short cseq_vga[] = {0x0007,0xffff};unsigned short cgraph_vga[] = {0x0009,0x000a,0x000b,0xffff};unsigned short ccrtc_vga[] = {0x001a,0x001b,0x001d,0xffff};/* extensions */unsigned short cgraph_svgacolor[] = {0x0000,0x0001,0x0002,0x0003,0x0004,0x4005,0x0506,0x0f07,0xff08,0x0009,0x000a,0x000b,0xffff};/* 640x480x8 */unsigned short cseq_640x480x8[] = {0x0300,0x2101,0x0f02,0x0003,0x0e04,0x1107,0x580b,0x580c,0x580d,0x580e,0x0412,0x0013,0x2017,0x331b,0x331c,0x331d,0x331e,0xffff};unsigned short ccrtc_640x480x8[] = {0x2c11,0x5f00,0x4f01,0x4f02,0x8003,0x5204,0x1e05,0x0b06,0x3e07,0x4009,0x000c,0x000d,0xea10,0xdf12,0x5013,0x4014,0xdf15,0x0b16,0xc317,0xff18,0x001a,0x221b,0x001d,0xffff};/* 640x480x16 */unsigned short cseq_640x480x16[] = {0x0300,0x2101,0x0f02,0x0003,0x0e04,0x1707,0x580b,0x580c,0x580d,0x580e,0x0412,0x0013,0x2017,0x331b,0x331c,0x331d,0x331e,0xffff};unsigned short ccrtc_640x480x16[] = {0x2c11,0x5f00,0x4f01,0x4f02,0x8003,0x5204,0x1e05,0x0b06,0x3e07,0x4009,0x000c,0x000d,0xea10,0xdf12,0xa013,0x4014,0xdf15,0x0b16,0xc317,0xff18,0x001a,0x221b,0x001d,0xffff};/* 640x480x24 */unsigned short cseq_640x480x24[] = {0x0300,0x2101,0x0f02,0x0003,0x0e04,0x1507,0x580b,0x580c,0x580d,0x580e,0x0412,0x0013,0x2017,0x331b,0x331c,0x331d,0x331e,0xffff};unsigned short ccrtc_640x480x24[] = {0x2c11,0x5f00,0x4f01,0x4f02,0x8003,0x5204,0x1e05,0x0b06,0x3e07,0x4009,0x000c,0x000d,0xea10,0xdf12,0x0013,0x4014,0xdf15,0x0b16,0xc317,0xff18,0x001a,0x321b,0x001d,0xffff};/* 800x600x8 */unsigned short cseq_800x600x8[] = {0x0300,0x2101,0x0f02,0x0003,0x0e04,0x1107,0x230b,0x230c,0x230d,0x230e,0x0412,0x0013,0x2017,0x141b,0x141c,0x141d,0x141e,0xffff};unsigned short ccrtc_800x600x8[] = {0x2311,0x7d00,0x6301,0x6302,0x8003,0x6b04,0x1a05,0x9806,0xf007,0x6009,0x000c,0x000d,0x7d10,0x5712,0x6413,0x4014,0x5715,0x9816,0xc317,0xff18,0x001a,0x221b,0x001d,0xffff};/* 800x600x16 */unsigned short cseq_800x600x16[] = {0x0300,0x2101,0x0f02,0x0003,0x0e04,0x1707,0x230b,0x230c,0x230d,0x230e,0x0412,0x0013,0x2017,0x141b,0x141c,0x141d,0x141e,0xffff};unsigned short ccrtc_800x600x16[] = {0x2311,0x7d00,0x6301,0x6302,0x8003,0x6b04,0x1a05,0x9806,0xf007,0x6009,0x000c,0x000d,0x7d10,0x5712,0xc813,0x4014,0x5715,0x9816,0xc317,0xff18,0x001a,0x221b,0x001d,0xffff};/* 800x600x24 */unsigned short cseq_800x600x24[] = {0x0300,0x2101,0x0f02,0x0003,0x0e04,0x1507,0x230b,0x230c,0x230d,0x230e,0x0412,0x0013,0x2017,0x141b,0x141c,0x141d,0x141e,0xffff};unsigned short ccrtc_800x600x24[] = {0x2311,0x7d00,0x6301,0x6302,0x8003,0x6b04,0x1a05,0x9806,0xf007,0x6009,0x000c,0x000d,0x7d10,0x5712,0x2c13,0x4014,0x5715,0x9816,0xc317,0xff18,0x001a,0x321b,0x001d,0xffff};/* 1024x768x8 */unsigned short cseq_1024x768x8[] = {0x0300,0x2101,0x0f02,0x0003,0x0e04,0x1107,0x760b,0x760c,0x760d,0x760e,0x0412,0x0013,0x2017,0x341b,0x341c,0x341d,0x341e,0xffff};unsigned short ccrtc_1024x768x8[] = {0x2911,0xa300,0x7f01,0x7f02,0x8603,0x8304,0x9405,0x2406,0xf507,0x6009,0x000c,0x000d,0x0310,0xff12,0x8013,0x4014,0xff15,0x2416,0xc317,0xff18,0x001a,0x221b,0x001d,0xffff};/* 1024x768x16 */unsigned short cseq_1024x768x16[] = {0x0300,0x2101,0x0f02,0x0003,0x0e04,0x1707,0x760b,0x760c,0x760d,0x760e,0x0412,0x0013,0x2017,0x341b,0x341c,0x341d,0x341e,0xffff};unsigned short ccrtc_1024x768x16[] = {0x2911,0xa300,0x7f01,0x7f02,0x8603,0x8304,0x9405,0x2406,0xf507,0x6009,0x000c,0x000d,0x0310,0xff12,0x0013,0x4014,0xff15,0x2416,0xc317,0xff18,0x001a,0x321b,0x001d,0xffff};/* 1024x768x24 */unsigned short cseq_1024x768x24[] = {0x0300,0x2101,0x0f02,0x0003,0x0e04,0x1507,0x760b,0x760c,0x760d,0x760e,0x0412,0x0013,0x2017,0x341b,0x341c,0x341d,0x341e,0xffff};unsigned short ccrtc_1024x768x24[] = {0x2911,0xa300,0x7f01,0x7f02,0x8603,0x8304,0x9405,0x2406,0xf507,0x6009,0x000c,0x000d,0x0310,0xff12,0x8013,0x4014,0xff15,0x2416,0xc317,0xff18,0x001a,0x321b,0x001d,0xffff};/* 1280x1024x8 */unsigned short cseq_1280x1024x8[] = {0x0300,0x2101,0x0f02,0x0003,0x0e04,0x1107,0x760b,0x760c,0x760d,0x760e,0x0412,0x0013,0x2017,0x341b,0x341c,0x341d,0x341e,0xffff};unsigned short ccrtc_1280x1024x8[] = {0x2911,0xc300,0x9f01,0x9f02,0x8603,0x8304,0x9405,0x2406,0xf707,0x6009,0x000c,0x000d,0x0310,0xff12,0xa013,0x4014,0xff15,0x2416,0xc317,0xff18,0x001a,0x221b,0x001d,0xffff};/* 1280x1024x16 */unsigned short cseq_1280x1024x16[] = {0x0300,0x2101,0x0f02,0x0003,0x0e04,0x1707,0x760b,0x760c,0x760d,0x760e,0x0412,0x0013,0x2017,0x341b,0x341c,0x341d,0x341e,0xffff};unsigned short ccrtc_1280x1024x16[] = {0x2911,0xc300,0x9f01,0x9f02,0x8603,0x8304,0x9405,0x2406,0xf707,0x6009,0x000c,0x000d,0x0310,0xff12,0x4013,0x4014,0xff15,0x2416,0xc317,0xff18,0x001a,0x321b,0x001d,0xffff};/* 1600x1200x8 */unsigned short cseq_1600x1200x8[] = {0x0300,0x2101,0x0f02,0x0003,0x0e04,0x1107,0x760b,0x760c,0x760d,0x760e,0x0412,0x0013,0x2017,0x341b,0x341c,0x341d,0x341e,0xffff};unsigned short ccrtc_1600x1200x8[] = {0x2911,0xc300,0x9f01,0x9f02,0x8603,0x8304,0x9405,0x2406,0xf707,0x6009,0x000c,0x000d,0x0310,0xff12,0xa013,0x4014,0xff15,0x2416,0xc317,0xff18,0x001a,0x221b,0x001d,0xffff};cirrus_mode_t cirrus_modes[] ={ {0x5f,640,480,8,0x00, cseq_640x480x8,cgraph_svgacolor,ccrtc_640x480x8,8, 4,0,0,0,0,0,0,0,0}, {0x64,640,480,16,0xe1, cseq_640x480x16,cgraph_svgacolor,ccrtc_640x480x16,16, 6,5,11,6,5,5,0,0,0}, {0x66,640,480,15,0xf0, cseq_640x480x16,cgraph_svgacolor,ccrtc_640x480x16,16, 6,5,10,5,5,5,0,1,15}, {0x71,640,480,24,0xe5, cseq_640x480x24,cgraph_svgacolor,ccrtc_640x480x24,24, 6,8,16,8,8,8,0,0,0}, {0x5c,800,600,8,0x00, cseq_800x600x8,cgraph_svgacolor,ccrtc_800x600x8,8, 4,0,0,0,0,0,0,0,0}, {0x65,800,600,16,0xe1, cseq_800x600x16,cgraph_svgacolor,ccrtc_800x600x16,16, 6,5,11,6,5,5,0,0,0}, {0x67,800,600,15,0xf0, cseq_800x600x16,cgraph_svgacolor,ccrtc_800x600x16,16, 6,5,10,5,5,5,0,1,15}, {0x60,1024,768,8,0x00, cseq_1024x768x8,cgraph_svgacolor,ccrtc_1024x768x8,8, 4,0,0,0,0,0,0,0,0}, {0x74,1024,768,16,0xe1, cseq_1024x768x16,cgraph_svgacolor,ccrtc_1024x768x16,16, 6,5,11,6,5,5,0,0,0}, {0x68,1024,768,15,0xf0, cseq_1024x768x16,cgraph_svgacolor,ccrtc_1024x768x16,16, 6,5,10,5,5,5,0,1,15}, {0x78,800,600,24,0xe5, cseq_800x600x24,cgraph_svgacolor,ccrtc_800x600x24,24, 6,8,16,8,8,8,0,0,0}, {0x79,1024,768,24,0xe5, cseq_1024x768x24,cgraph_svgacolor,ccrtc_1024x768x24,24, 6,8,16,8,8,8,0,0,0}, {0x6d,1280,1024,8,0x00, cseq_1280x1024x8,cgraph_svgacolor,ccrtc_1280x1024x8,8, 4,0,0,0,0,0,0,0,0}, {0x69,1280,1024,15,0xf0, cseq_1280x1024x16,cgraph_svgacolor,ccrtc_1280x1024x16,16, 6,5,10,5,5,5,0,1,15}, {0x75,1280,1024,16,0xe1, cseq_1280x1024x16,cgraph_svgacolor,ccrtc_1280x1024x16,16, 6,5,11,6,5,5,0,0,0}, {0x7b,1600,1200,8,0x00, cseq_1600x1200x8,cgraph_svgacolor,ccrtc_1600x1200x8,8, 4,0,0,0,0,0,0,0,0}, {0xfe,0,0,0,0,cseq_vga,cgraph_vga,ccrtc_vga,0, 0xff,0,0,0,0,0,0,0,0}, {0xff,0,0,0,0,0,0,0,0, 0xff,0,0,0,0,0,0,0,0},};unsigned char cirrus_id_table[] = { // 5430 0xA0, 0x32, // 5446 0xB8, 0x39, 0xff, 0xff};unsigned short cirrus_vesa_modelist[] = {// 640x480x8 0x101, 0x5f,// 640x480x15 0x110, 0x66,// 640x480x16 0x111, 0x64,// 640x480x24 0x112, 0x71,// 800x600x8 0x103, 0x5c,// 800x600x15 0x113, 0x67,// 800x600x16 0x114, 0x65,// 800x600x24 0x115, 0x78,// 1024x768x8 0x105, 0x60,// 1024x768x15 0x116, 0x68,// 1024x768x16 0x117, 0x74,// 1024x768x24 0x118, 0x79,// 1280x1024x8 0x107, 0x6d,// 1280x1024x15 0x119, 0x69,// 1280x1024x16 0x11a, 0x75,// invalid 0xffff,0xffff};ASM_STARTcirrus_installed:.ascii "cirrus-compatible VGA is detected".byte 0x0d,0x0a.byte 0x0d,0x0a,0x00cirrus_not_installed:.ascii "cirrus-compatible VGA is not detected".byte 0x0d,0x0a.byte 0x0d,0x0a,0x00cirrus_vesa_vendorname:cirrus_vesa_productname:cirrus_vesa_oemname:.ascii "VGABIOS Cirrus extension".byte 0cirrus_vesa_productrevision:.ascii "1.0".byte 0cirrus_init: call cirrus_check jnz no_cirrus SET_INT_VECTOR(0x10, #0xC000, #cirrus_int10_handler) mov al, #0x0f ; memory setup mov dx, #0x3C4 out dx, al inc dx in al, dx and al, #0x18 mov ah, al mov al, #0x0a dec dx out dx, ax mov ax, #0x0007 ; set vga mode out dx, ax mov ax, #0x0431 ; reset bitblt mov dx, #0x3CE out dx, ax mov ax, #0x0031 out dx, axno_cirrus: retcirrus_display_info: push ds push si push cs pop ds call cirrus_check mov si, #cirrus_not_installed jnz cirrus_msgnotinstalled mov si, #cirrus_installedcirrus_msgnotinstalled: call _display_string pop si pop ds retcirrus_check: push ax push dx mov ax, #0x9206 mov dx, #0x3C4 out dx, ax inc dx in al, dx cmp al, #0x12 pop dx pop ax retcirrus_int10_handler: pushf push bp cmp ah, #0x00 ;; set video mode jz cirrus_set_video_mode cmp ah, #0x12 ;; cirrus extension jz cirrus_extbios cmp ah, #0x4F ;; VESA extension jz cirrus_vesacirrus_unhandled: pop bp popf jmp vgabios_int10_handlercirrus_return:#ifdef CIRRUS_DEBUG call cirrus_debug_dump#endif pop bp popf iretcirrus_set_video_mode:#ifdef CIRRUS_DEBUG call cirrus_debug_dump#endif push si push ax push bx push ds#ifdef CIRRUS_VESA3_PMINFO db 0x2e ;; cs: mov si, [cirrus_vesa_sel0000_data]#else xor si, si#endif mov ds, si xor bx, bx mov [PM_BIOSMEM_VBE_MODE], bx pop ds pop bx call cirrus_get_modeentry jnc cirrus_set_video_mode_extended mov al, #0xfe call cirrus_get_modeentry_nomask call cirrus_switch_mode pop ax pop si jmp cirrus_unhandledcirrus_extbios:#ifdef CIRRUS_DEBUG call cirrus_debug_dump#endif cmp bl, #0x80 jb cirrus_unhandled cmp bl, #0xAF ja cirrus_unhandled push bx and bx, #0x7F shl bx, 1 db 0x2e ;; cs: mov bp, cirrus_extbios_handlers[bx] pop bx push #cirrus_return push bp retcirrus_vesa:#ifdef CIRRUS_DEBUG call cirrus_debug_dump#endif cmp al, #0x10 ja cirrus_vesa_not_handled push bx xor bx, bx mov bl, al shl bx, 1 db 0x2e ;; cs: mov bp, cirrus_vesa_handlers[bx] pop bx push #cirrus_return push bp retcirrus_vesa_not_handled: mov ax, #0x014F ;; not implemented jmp cirrus_return#ifdef CIRRUS_DEBUGcirrus_debug_dump: push es push ds pusha push cs pop ds call _cirrus_debugmsg popa pop ds pop es ret#endifcirrus_set_video_mode_extended: call cirrus_switch_mode pop ax ;; mode test al, #0x80 jnz cirrus_set_video_mode_extended_1 push ax mov ax, #0xffff ; set to 0xff to keep win 2K happy call cirrus_clear_vram pop axcirrus_set_video_mode_extended_1: and al, #0x7f push ds#ifdef CIRRUS_VESA3_PMINFO db 0x2e ;; cs: mov si, [cirrus_vesa_sel0000_data]#else xor si, si#endif mov ds, si mov [PM_BIOSMEM_CURRENT_MODE], al pop ds mov al, #0x20 pop si jmp cirrus_returncirrus_vesa_pmbios_init:
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -