1 Star 0 Fork 0

alexi/vgabios

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
克隆/下载
clext.c 30.12 KB
一键复制 编辑 原始数据 按行查看 历史
12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652
//
// 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
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_START
cirrus_installed:
.ascii "cirrus-compatible VGA is detected"
.byte 0x0d,0x0a
.byte 0x0d,0x0a,0x00
cirrus_not_installed:
.ascii "cirrus-compatible VGA is not detected"
.byte 0x0d,0x0a
.byte 0x0d,0x0a,0x00
cirrus_vesa_vendorname:
cirrus_vesa_productname:
cirrus_vesa_oemname:
.ascii "VGABIOS Cirrus extension"
.byte 0
cirrus_vesa_productrevision:
.ascii "1.0"
.byte 0
cirrus_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, ax
no_cirrus:
ret
cirrus_display_info:
push ds
push si
push cs
pop ds
call cirrus_check
mov si, #cirrus_not_installed
jnz cirrus_msgnotinstalled
mov si, #cirrus_installed
cirrus_msgnotinstalled:
call _display_string
pop si
pop ds
ret
cirrus_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
ret
cirrus_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_vesa
cirrus_unhandled:
pop bp
popf
jmp vgabios_int10_handler
cirrus_return:
#ifdef CIRRUS_DEBUG
call cirrus_debug_dump
#endif
pop bp
popf
iret
cirrus_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_unhandled
cirrus_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
ret
cirrus_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
ret
cirrus_vesa_not_handled:
mov ax, #0x014F ;; not implemented
jmp cirrus_return
#ifdef CIRRUS_DEBUG
cirrus_debug_dump:
push es
push ds
pusha
push cs
pop ds
call _cirrus_debugmsg
popa
pop ds
pop es
ret
#endif
cirrus_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 ax
cirrus_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_return
cirrus_vesa_pmbios_init:
retf
cirrus_vesa_pmbios_entry:
pushf
push bp
cmp ah, #0x4F
jnz cirrus_vesa_pmbios_unimplemented
cmp al, #0x0F
ja cirrus_vesa_pmbios_unimplemented
push bx
xor bx, bx
mov bl, al
shl bx, 1
db 0x2e ;; cs:
mov bp, cirrus_vesa_handlers[bx]
pop bx
push #cirrus_vesa_pmbios_return
push bp
ret
cirrus_vesa_pmbios_unimplemented:
mov ax, #0x014F
cirrus_vesa_pmbios_return:
pop bp
popf
retf
; in si:mode table
cirrus_switch_mode:
push ds
push bx
push dx
push cs
pop ds
mov bx, [si+10] ;; seq
mov dx, #0x3c4
mov ax, #0x1206
out dx, ax ;; Unlock cirrus special
call cirrus_switch_mode_setregs
mov bx, [si+12] ;; graph
mov dx, #0x3ce
call cirrus_switch_mode_setregs
mov bx, [si+14] ;; crtc
call cirrus_get_crtc
call cirrus_switch_mode_setregs
mov dx, #0x3c6
mov al, #0x00
out dx, al
in al, dx
in al, dx
in al, dx
in al, dx
mov al, [si+8] ;; hidden dac
out dx, al
mov al, #0xff
out dx, al
mov al, #0x00
mov bl, [si+17] ;; memory model
or bl, bl
jz is_text_mode
mov al, #0x01
cmp bl, #0x03
jnz is_text_mode
or al, #0x40
is_text_mode:
mov bl, #0x10
call biosfn_get_single_palette_reg
and bh, #0xfe
or bh, al
call biosfn_set_single_palette_reg
mov al, [si+6] ;; bpp
cmp al, #0x08
jnz no_8bpp_mode
mov al, #0x03
xor ah,ah
push ax
call _load_dac_palette
inc sp
inc sp
no_8bpp_mode:
pop dx
pop bx
pop ds
ret
cirrus_enable_16k_granularity:
push ax
push dx
mov dx, #0x3ce
mov al, #0x0b
out dx, al
inc dx
in al, dx
or al, #0x20 ;; enable 16k
out dx, al
pop dx
pop ax
ret
cirrus_switch_mode_setregs:
csms_1:
mov ax, [bx]
cmp ax, #0xffff
jz csms_2
out dx, ax
add bx, #0x2
jmp csms_1
csms_2:
ret
cirrus_extbios_80h:
push dx
call cirrus_get_crtc
mov al, #0x27
out dx, al
inc dx
in al, dx
mov bx, #_cirrus_id_table
c80h_1:
db 0x2e ;; cs:
mov ah, [bx]
cmp ah, al
jz c80h_2
cmp ah, #0xff
jz c80h_2
inc bx
inc bx
jmp c80h_1
c80h_2:
db 0x2e ;; cs:
mov al, 0x1[bx]
pop dx
mov ah, #0x00
xor bx, bx
ret
cirrus_extbios_81h:
mov ax, #0x100 ;; XXX
ret
cirrus_extbios_82h:
push dx
call cirrus_get_crtc
xor ax, ax
mov al, #0x27
out dx, al
inc dx
in al, dx
and al, #0x03
mov ah, #0xAF
pop dx
ret
cirrus_extbios_85h:
push cx
push dx
mov dx, #0x3C4
mov al, #0x0f ;; get DRAM band width
out dx, al
inc dx
in al, dx
;; al = 4 << bandwidth
mov cl, al
shr cl, #0x03
and cl, #0x03
cmp cl, #0x03
je c85h2
mov al, #0x04
shl al, cl
jmp c85h3
c85h2:
;; 4MB or 2MB
and al, #0x80
mov al, #0x20 ;; 2 MB
je c85h3
mov al, #0x40 ;; 4 MB
c85h3:
pop dx
pop cx
ret
cirrus_extbios_9Ah:
mov ax, #0x4060
mov cx, #0x1132
ret
cirrus_extbios_A0h:
call cirrus_get_modeentry
mov ah, #0x01
sbb ah, #0x00
mov bx, cirrus_extbios_A0h_callback
mov si, #0xffff
mov di, bx
mov ds, bx
mov es, bx
ret
cirrus_extbios_A0h_callback:
;; fatal: not implemented yet
cli
hlt
retf
cirrus_extbios_A1h:
mov bx, #0x0E00 ;; IBM 8512/8513, color
ret
cirrus_extbios_A2h:
mov al, #0x07 ;; HSync 31.5 - 64.0 kHz
ret
cirrus_extbios_AEh:
mov al, #0x01 ;; High Refresh 75Hz
ret
cirrus_extbios_unimplemented:
ret
cirrus_vesa_00h:
push ds
push si
mov bp, di
push es
pop ds
cld
mov ax, [di]
cmp ax, #0x4256 ;; VB
jnz cv00_1
mov ax, [di+2]
cmp ax, #0x3245 ;; E2
jnz cv00_1
;; VBE2
lea di, 0x14[bp]
mov ax, #0x0100 ;; soft ver.
stosw
mov ax, # cirrus_vesa_vendorname
stosw
mov ax, cs
stosw
mov ax, # cirrus_vesa_productname
stosw
mov ax, cs
stosw
mov ax, # cirrus_vesa_productrevision
stosw
mov ax, cs
stosw
cv00_1:
mov di, bp
mov ax, #0x4556 ;; VE
stosw
mov ax, #0x4153 ;; SA
stosw
mov ax, #0x0200 ;; v2.00
stosw
mov ax, # cirrus_vesa_oemname
stosw
mov ax, cs
stosw
xor ax, ax ;; caps
stosw
stosw
lea ax, 0x40[bp]
stosw
mov ax, es
stosw
call cirrus_extbios_85h ;; vram in 64k
mov ah, #0x00
stosw
push cs
pop ds
lea di, 0x40[bp]
mov si, #_cirrus_vesa_modelist
cv00_2:
lodsw
stosw
add si, #2
cmp ax, #0xffff
jnz cv00_2
mov ax, #0x004F
mov di, bp
pop si
pop ds
ret
cirrus_vesa_01h:
mov ax, cx
and ax, #0x3fff
call cirrus_vesamode_to_mode
cmp ax, #0xffff
jnz cirrus_vesa_01h_1
jmp cirrus_vesa_unimplemented
cirrus_vesa_01h_1:
push ds
push si
push cx
push dx
push bx
mov bp, di
cld
push cs
pop ds
call cirrus_get_modeentry_nomask
push di
xor ax, ax
mov cx, #0x80
rep
stosw ;; clear buffer
pop di
mov ax, #0x003b ;; mode
stosw
mov ax, #0x0007 ;; attr
stosw
mov ax, #0x0010 ;; granularity =16K
stosw
mov ax, #0x0040 ;; size =64K
stosw
mov ax, #0xA000 ;; segment A
stosw
xor ax, ax ;; no segment B
stosw
mov ax, #cirrus_vesa_05h_farentry
stosw
mov ax, cs
stosw
call cirrus_get_line_offset_entry
stosw ;; bytes per scan line
mov ax, [si+2] ;; width
stosw
mov ax, [si+4] ;; height
stosw
mov ax, #0x08
stosb
mov ax, #0x10
stosb
mov al, #1 ;; count of planes
stosb
mov al, [si+6] ;; bpp
stosb
mov al, #0x1 ;; XXX number of banks
stosb
mov al, [si+17]
stosb ;; memory model
mov al, #0x0 ;; XXX size of bank in K
stosb
call cirrus_get_line_offset_entry
mov bx, [si+4]
mul bx ;; dx:ax=vramdisp
or ax, ax
jz cirrus_vesa_01h_3
inc dx
cirrus_vesa_01h_3:
call cirrus_extbios_85h ;; al=vram in 64k
mov ah, #0x00
mov cx, dx
xor dx, dx
div cx
dec ax
stosb ;; number of image pages = vramtotal/vramdisp-1
mov al, #0x00
stosb
;; v1.2+ stuffs
push si
add si, #18
movsw
movsw
movsw
movsw
pop si
mov ah, [si+16]
mov al, #0x0
sub ah, #9
rcl al, #1 ; bit 0=palette flag
stosb ;; direct screen mode info
;; v2.0+ stuffs
;; 32-bit LFB address
xor ax, ax
stosw
mov ax, #0x1013 ;; vendor Cirrus
call _pci_get_lfb_addr
stosw
or ax, ax
jz cirrus_vesa_01h_4
push di
mov di, bp
db 0x26 ;; es:
mov ax, [di]
or ax, #0x0080 ;; mode bit 7:LFB
stosw
pop di
cirrus_vesa_01h_4:
xor ax, ax
stosw ; reserved
stosw ; reserved
stosw ; reserved
mov ax, #0x004F
mov di, bp
pop bx
pop dx
pop cx
pop si
pop ds
test cx, #0x4000 ;; LFB flag
jz cirrus_vesa_01h_5
push cx
db 0x26 ;; es:
mov cx, [di]
cmp cx, #0x0080 ;; is LFB supported?
jnz cirrus_vesa_01h_6
mov ax, #0x014F ;; error - no LFB
cirrus_vesa_01h_6:
pop cx
cirrus_vesa_01h_5:
ret
cirrus_vesa_02h:
;; XXX support CRTC registers
test bx, #0x3e00
jnz cirrus_vesa_02h_2 ;; unknown flags
mov ax, bx
and ax, #0x1ff ;; bit 8-0 mode
cmp ax, #0x100 ;; legacy VGA mode
jb cirrus_vesa_02h_legacy
call cirrus_vesamode_to_mode
cmp ax, #0xffff
jnz cirrus_vesa_02h_1
cirrus_vesa_02h_2:
jmp cirrus_vesa_unimplemented
cirrus_vesa_02h_legacy:
#ifdef CIRRUS_VESA3_PMINFO
db 0x2e ;; cs:
cmp byte ptr [cirrus_vesa_is_protected_mode], #0
jnz cirrus_vesa_02h_2
#endif // CIRRUS_VESA3_PMINFO
int #0x10
mov ax, #0x004F
ret
cirrus_vesa_02h_1:
push si
push ax
call cirrus_get_modeentry_nomask
call cirrus_switch_mode
test bx, #0x4000 ;; LFB
jnz cirrus_vesa_02h_3
call cirrus_enable_16k_granularity
cirrus_vesa_02h_3:
test bx, #0x8000 ;; no clear
jnz cirrus_vesa_02h_4
push ax
xor ax,ax
call cirrus_clear_vram
pop ax
cirrus_vesa_02h_4:
pop ax
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
mov [PM_BIOSMEM_VBE_MODE], bx
pop ds
pop si
mov ax, #0x004F
ret
cirrus_vesa_03h:
push ds
#ifdef CIRRUS_VESA3_PMINFO
db 0x2e ;; cs:
mov ax, [cirrus_vesa_sel0000_data]
#else
xor ax, ax
#endif
mov ds, ax
mov bx, # PM_BIOSMEM_VBE_MODE
mov ax, [bx]
mov bx, ax
test bx, bx
jnz cirrus_vesa_03h_1
mov bx, # PM_BIOSMEM_CURRENT_MODE
mov al, [bx]
mov bl, al
xor bh, bh
cirrus_vesa_03h_1:
mov ax, #0x004f
pop ds
ret
cirrus_vesa_05h_farentry:
call cirrus_vesa_05h
retf
cirrus_vesa_05h:
cmp bl, #0x01
ja cirrus_vesa_05h_1
cmp bh, #0x00
jz cirrus_vesa_05h_setmempage
cmp bh, #0x01
jz cirrus_vesa_05h_getmempage
cirrus_vesa_05h_1:
jmp cirrus_vesa_unimplemented
cirrus_vesa_05h_setmempage:
or dh, dh ; address must be < 0x100
jnz cirrus_vesa_05h_1
push dx
mov al, bl ;; bl=bank number
add al, #0x09
mov ah, dl ;; dx=window address in granularity
mov dx, #0x3ce
out dx, ax
pop dx
mov ax, #0x004F
ret
cirrus_vesa_05h_getmempage:
mov al, bl ;; bl=bank number
add al, #0x09
mov dx, #0x3ce
out dx, al
inc dx
in al, dx
xor dx, dx
mov dl, al ;; dx=window address in granularity
mov ax, #0x004F
ret
cirrus_vesa_06h:
mov ax, cx
cmp bl, #0x01
je cirrus_vesa_06h_3
cmp bl, #0x02
je cirrus_vesa_06h_2
jb cirrus_vesa_06h_1
mov ax, #0x0100
ret
cirrus_vesa_06h_1:
call cirrus_get_bpp_bytes
mov bl, al
xor bh, bh
mov ax, cx
mul bx
cirrus_vesa_06h_2:
call cirrus_set_line_offset
cirrus_vesa_06h_3:
call cirrus_get_bpp_bytes
mov bl, al
xor bh, bh
xor dx, dx
call cirrus_get_line_offset
push ax
div bx
mov cx, ax
pop bx
call cirrus_extbios_85h ;; al=vram in 64k
xor dx, dx
mov dl, al
xor ax, ax
div bx
mov dx, ax
mov ax, #0x004f
ret
cirrus_vesa_07h:
cmp bl, #0x80
je cirrus_vesa_07h_1
cmp bl, #0x01
je cirrus_vesa_07h_2
jb cirrus_vesa_07h_1
mov ax, #0x0100
ret
cirrus_vesa_07h_1:
push dx
call cirrus_get_bpp_bytes
mov bl, al
xor bh, bh
mov ax, cx
mul bx
pop bx
push ax
call cirrus_get_line_offset
mul bx
pop bx
add ax, bx
jnc cirrus_vesa_07h_3
inc dx
cirrus_vesa_07h_3:
push dx
and dx, #0x0003
mov bx, #0x04
div bx
pop dx
shr dx, #2
call cirrus_set_start_addr
mov ax, #0x004f
ret
cirrus_vesa_07h_2:
call cirrus_get_start_addr
shl dx, #2
push dx
mov bx, #0x04
mul bx
pop bx
or dx, bx
push ax
call cirrus_get_line_offset
mov bx, ax
pop ax
div bx
push ax
push dx
call cirrus_get_bpp_bytes
mov bl, al
xor bh, bh
pop ax
xor dx, dx
div bx
mov cx, ax
pop dx
mov ax, #0x004f
ret
cirrus_vesa_10h:
cmp bl, #0x00
jne cirrus_vesa_10h_01
mov bx, #0x0f30
mov ax, #0x004f
ret
cirrus_vesa_10h_01:
cmp bl, #0x01
jne cirrus_vesa_10h_02
push dx
push ds
mov dx, #0x40
mov ds, dx
mov [0xb9], bh
pop ds
pop dx
mov ax, #0x004f
ret
cirrus_vesa_10h_02:
cmp bl, #0x02
jne cirrus_vesa_unimplemented
push dx
push ds
mov dx, #0x40
mov ds, dx
mov bh, [0xb9]
pop ds
pop dx
mov ax, #0x004f
ret
cirrus_vesa_unimplemented:
mov ax, #0x014F ;; not implemented
ret
;; in ax:vesamode, out ax:cirrusmode
cirrus_vesamode_to_mode:
push ds
push cx
push si
push cs
pop ds
mov cx, #0xffff
mov si, #_cirrus_vesa_modelist
cvtm_1:
cmp [si],ax
jz cvtm_2
cmp [si],cx
jz cvtm_2
add si, #4
jmp cvtm_1
cvtm_2:
mov ax,[si+2]
pop si
pop cx
pop ds
ret
; cirrus_get_crtc
;; NOTE - may be called in protected mode
cirrus_get_crtc:
push ds
push ax
mov dx, #0x3cc
in al, dx
and al, #0x01
shl al, #5
mov dx, #0x3b4
add dl, al
pop ax
pop ds
ret
;; in - al:mode, out - cflag:result, si:table, ax:destroyed
cirrus_get_modeentry:
and al, #0x7f
cirrus_get_modeentry_nomask:
mov si, #_cirrus_modes
cgm_1:
db 0x2e ;; cs:
mov ah, [si]
cmp al, ah
jz cgm_2
cmp ah, #0xff
jz cgm_4
add si, # CIRRUS_MODE_SIZE
jmp cgm_1
cgm_4:
xor si, si
stc ;; video mode is not supported
jmp cgm_3
cgm_2:
clc ;; video mode is supported
cgm_3:
ret
;; out - al:bytes per pixel
cirrus_get_bpp_bytes:
push dx
mov dx, #0x03c4
mov al, #0x07
out dx, al
inc dx
in al, dx
and al, #0x0e
cmp al, #0x06
jne cirrus_get_bpp_bytes_1
and al, #0x02
cirrus_get_bpp_bytes_1:
shr al, #1
cmp al, #0x04
je cirrus_get_bpp_bytes_2
inc al
cirrus_get_bpp_bytes_2:
pop dx
ret
;; in - ax: new line offset
cirrus_set_line_offset:
shr ax, #3
push ax
call cirrus_get_crtc
mov al, #0x13
out dx, al
inc dx
pop ax
out dx, al
dec dx
mov al, #0x1b
out dx, al
inc dx
shl ah, #4
in al, dx
and al, #ef
or al, ah
out dx, al
ret
;; out - ax: active line offset
cirrus_get_line_offset:
push dx
push bx
call cirrus_get_crtc
mov al, #0x13
out dx, al
inc dx
in al, dx
mov bl, al
dec dx
mov al, #0x1b
out dx, al
inc dx
in al, dx
mov ah, al
shr ah, #4
and ah, #0x01
mov al, bl
shl ax, #3
pop bx
pop dx
ret
;; in - si: table
;; out - ax: line offset for mode
cirrus_get_line_offset_entry:
push bx
mov bx, [si+14] ;; crtc table
push bx
offset_loop1:
mov ax, [bx]
cmp al, #0x13
je offset_found1
inc bx
inc bx
jnz offset_loop1
offset_found1:
xor al, al
shr ax, #5
pop bx
push ax
offset_loop2:
mov ax, [bx]
cmp al, #0x1b
je offset_found2
inc bx
inc bx
jnz offset_loop2
offset_found2:
pop bx
and ax, #0x1000
shr ax, #1
or ax, bx
pop bx
ret
;; in - new address in DX:AX
cirrus_set_start_addr:
push bx
push dx
push ax
call cirrus_get_crtc
mov al, #0x0d
out dx, al
inc dx
pop ax
out dx, al
dec dx
mov al, #0x0c
out dx, al
inc dx
mov al, ah
out dx, al
dec dx
mov al, #0x1d
out dx, al
inc dx
in al, dx
and al, #0x7f
pop bx
mov ah, bl
shl bl, #4
and bl, #0x80
or al, bl
out dx, al
dec dx
mov bl, ah
and ah, #0x01
shl bl, #1
and bl, #0x0c
or ah, bl
mov al, #0x1b
out dx, al
inc dx
in al, dx
and al, #0xf2
or al, ah
out dx, al
pop bx
ret
;; out - current address in DX:AX
cirrus_get_start_addr:
push bx
call cirrus_get_crtc
mov al, #0x0c
out dx, al
inc dx
in al, dx
mov ah, al
dec dx
mov al, #0x0d
out dx, al
inc dx
in al, dx
push ax
dec dx
mov al, #0x1b
out dx, al
inc dx
in al, dx
dec dx
mov bl, al
and al, #0x01
and bl, #0x0c
shr bl, #1
or bl, al
mov al, #0x1d
out dx, al
inc dx
in al, dx
and al, #0x80
shr al, #4
or bl, al
mov dl, bl
xor dh, dh
pop ax
pop bx
ret
cirrus_clear_vram:
pusha
push es
mov si, ax
call cirrus_enable_16k_granularity
call cirrus_extbios_85h
shl al, #2
mov bl, al
xor ah,ah
cirrus_clear_vram_1:
mov al, #0x09
mov dx, #0x3ce
out dx, ax
push ax
mov cx, #0xa000
mov es, cx
xor di, di
mov ax, si
mov cx, #8192
cld
rep
stosw
pop ax
inc ah
cmp ah, bl
jne cirrus_clear_vram_1
xor ah,ah
mov dx, #0x3ce
out dx, ax
pop es
popa
ret
cirrus_extbios_handlers:
;; 80h
dw cirrus_extbios_80h
dw cirrus_extbios_81h
dw cirrus_extbios_82h
dw cirrus_extbios_unimplemented
;; 84h
dw cirrus_extbios_unimplemented
dw cirrus_extbios_85h
dw cirrus_extbios_unimplemented
dw cirrus_extbios_unimplemented
;; 88h
dw cirrus_extbios_unimplemented
dw cirrus_extbios_unimplemented
dw cirrus_extbios_unimplemented
dw cirrus_extbios_unimplemented
;; 8Ch
dw cirrus_extbios_unimplemented
dw cirrus_extbios_unimplemented
dw cirrus_extbios_unimplemented
dw cirrus_extbios_unimplemented
;; 90h
dw cirrus_extbios_unimplemented
dw cirrus_extbios_unimplemented
dw cirrus_extbios_unimplemented
dw cirrus_extbios_unimplemented
;; 94h
dw cirrus_extbios_unimplemented
dw cirrus_extbios_unimplemented
dw cirrus_extbios_unimplemented
dw cirrus_extbios_unimplemented
;; 98h
dw cirrus_extbios_unimplemented
dw cirrus_extbios_unimplemented
dw cirrus_extbios_9Ah
dw cirrus_extbios_unimplemented
;; 9Ch
dw cirrus_extbios_unimplemented
dw cirrus_extbios_unimplemented
dw cirrus_extbios_unimplemented
dw cirrus_extbios_unimplemented
;; A0h
dw cirrus_extbios_A0h
dw cirrus_extbios_A1h
dw cirrus_extbios_A2h
dw cirrus_extbios_unimplemented
;; A4h
dw cirrus_extbios_unimplemented
dw cirrus_extbios_unimplemented
dw cirrus_extbios_unimplemented
dw cirrus_extbios_unimplemented
;; A8h
dw cirrus_extbios_unimplemented
dw cirrus_extbios_unimplemented
dw cirrus_extbios_unimplemented
dw cirrus_extbios_unimplemented
;; ACh
dw cirrus_extbios_unimplemented
dw cirrus_extbios_unimplemented
dw cirrus_extbios_AEh
dw cirrus_extbios_unimplemented
cirrus_vesa_handlers:
;; 00h
dw cirrus_vesa_00h
dw cirrus_vesa_01h
dw cirrus_vesa_02h
dw cirrus_vesa_03h
;; 04h
dw cirrus_vesa_unimplemented
dw cirrus_vesa_05h
dw cirrus_vesa_06h
dw cirrus_vesa_07h
;; 08h
dw cirrus_vesa_unimplemented
dw cirrus_vesa_unimplemented
dw cirrus_vesa_unimplemented
dw cirrus_vesa_unimplemented
;; 0Ch
dw cirrus_vesa_unimplemented
dw cirrus_vesa_unimplemented
dw cirrus_vesa_unimplemented
dw cirrus_vesa_unimplemented
;; 10h
dw cirrus_vesa_10h
ASM_END
#ifdef CIRRUS_VESA3_PMINFO
ASM_START
cirrus_vesa_pminfo:
/* + 0 */
.byte 0x50,0x4d,0x49,0x44 ;; signature[4]
/* + 4 */
dw cirrus_vesa_pmbios_entry ;; entry_bios
dw cirrus_vesa_pmbios_init ;; entry_init
/* + 8 */
cirrus_vesa_sel0000_data:
dw 0x0000 ;; sel_00000
cirrus_vesa_selA000_data:
dw 0xA000 ;; sel_A0000
/* +12 */
cirrus_vesa_selB000_data:
dw 0xB000 ;; sel_B0000
cirrus_vesa_selB800_data:
dw 0xB800 ;; sel_B8000
/* +16 */
cirrus_vesa_selC000_data:
dw 0xC000 ;; sel_C0000
cirrus_vesa_is_protected_mode:
;; protected mode flag and checksum
dw (~((0xf2 + (cirrus_vesa_pmbios_entry >> 8) + (cirrus_vesa_pmbios_entry) \
+ (cirrus_vesa_pmbios_init >> 8) + (cirrus_vesa_pmbios_init)) & 0xff) << 8) + 0x01
ASM_END
#endif // CIRRUS_VESA3_PMINFO
#ifdef CIRRUS_DEBUG
static void cirrus_debugmsg(DI, SI, BP, SP, BX, DX, CX, AX, DS, ES, FLAGS)
Bit16u DI, SI, BP, SP, BX, DX, CX, AX, ES, DS, FLAGS;
{
if((GET_AH()!=0x0E)&&(GET_AH()!=0x02)&&(GET_AH()!=0x09)&&(AX!=0x4F05))
printf("vgabios call ah%02x al%02x bx%04x cx%04x dx%04x\n",GET_AH(),GET_AL(),BX,CX,DX);
}
#endif
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化
1
https://gitee.com/alexi126/vgabios.git
[email protected]:alexi126/vgabios.git
alexi126
vgabios
vgabios
master

搜索帮助