1
/* $XFree86: xc/programs/Xserver/hw/xfree86/vbe/vbe.c,v 1.1 2003/02/17 17:06:45 dawes Exp $ */
5
* Copyright 2000 Egbert Eich
7
* The mode query/save/set/restore functions from the vesa driver
8
* have been moved here.
9
* Copyright (c) 2000 by Conectiva S.A. (http://www.conectiva.com)
10
* Authors: Paulo C�sar Pereira de Andrade <pcpa@conectiva.com.br>
14
#include "xf86_ansic.h"
18
#include "extensions/dpms.h"
20
#define VERSION(x) VBE_VERSION_MAJOR(x),VBE_VERSION_MINOR(x)
22
#if X_BYTE_ORDER == X_LITTLE_ENDIAN
26
#define B_O16(x) ((((x) & 0xff) << 8) | (((x) & 0xff) >> 8))
27
#define B_O32(x) ((((x) & 0xff) << 24) | (((x) & 0xff00) << 8) \
28
| (((x) & 0xff0000) >> 8) | (((x) & 0xff000000) >> 24))
30
#define L_ADD(x) (B_O32(x) & 0xffff) + ((B_O32(x) >> 12) & 0xffff00)
32
#define FARP(p) (((unsigned)(p & 0xffff0000) >> 12) | (p & 0xffff))
33
#define R16(v) ((v) & 0xffff)
35
static unsigned char * vbeReadEDID(vbeInfoPtr pVbe);
36
static Bool vbeProbeDDC(vbeInfoPtr pVbe);
38
const char *vbe_ddcSymbols[] = {
43
static const char vbeVersionString[] = "VBE2";
46
VBEInit(xf86Int10InfoPtr pInt, int entityIndex)
48
return VBEExtendedInit(pInt, entityIndex, 0);
52
VBEExtendedInit(xf86Int10InfoPtr pInt, int entityIndex, int Flags)
56
ScrnInfoPtr pScrn = xf86FindScreenForEntity(entityIndex);
57
vbeControllerInfoPtr vbe = NULL;
58
Bool init_int10 = FALSE;
59
vbeInfoPtr vip = NULL;
60
int screen = pScrn->scrnIndex;
63
if (!xf86LoadSubModule(pScrn, "int10"))
66
xf86DrvMsg(screen,X_INFO,"initializing int10\n");
67
pInt = xf86InitInt10(entityIndex);
73
page = xf86Int10AllocPages(pInt,1,&RealOff);
74
if (!page) goto error;
75
vbe = (vbeControllerInfoPtr) page;
76
memcpy(vbe->VbeSignature,vbeVersionString,4);
79
pInt->es = SEG_ADDR(RealOff);
80
pInt->di = SEG_OFF(RealOff);
83
xf86ExecX86int10(pInt);
85
if ((pInt->ax & 0xff) != 0x4f) {
86
xf86DrvMsgVerb(screen,X_INFO,3,"VESA BIOS not detected\n");
90
switch (pInt->ax & 0xff00) {
92
xf86DrvMsg(screen,X_INFO,"VESA BIOS detected\n");
95
xf86DrvMsg(screen,X_INFO,"VESA BIOS function failed\n");
98
xf86DrvMsg(screen,X_INFO,"VESA BIOS not supported\n");
101
xf86DrvMsg(screen,X_INFO,"VESA BIOS not supported in current mode\n");
104
xf86DrvMsg(screen,X_INFO,"Invalid\n");
108
xf86DrvMsgVerb(screen, X_INFO, 4,
109
"VbeVersion is %d, OemStringPtr is 0x%08x,\n"
110
"\tOemVendorNamePtr is 0x%08x, OemProductNamePtr is 0x%08x,\n"
111
"\tOemProductRevPtr is 0x%08x\n",
112
vbe->VbeVersion, vbe->OemStringPtr, vbe->OemVendorNamePtr,
113
vbe->OemProductNamePtr, vbe->OemProductRevPtr);
115
xf86DrvMsgVerb(screen,X_INFO,3,"VESA VBE Version %i.%i\n",
116
VERSION(vbe->VbeVersion));
117
xf86DrvMsgVerb(screen,X_INFO,3,"VESA VBE Total Mem: %i kB\n",
119
xf86DrvMsgVerb(screen,X_INFO,3,"VESA VBE OEM: %s\n",
120
(CARD8*)xf86int10Addr(pInt,L_ADD(vbe->OemStringPtr)));
122
if (B_O16(vbe->VbeVersion) >= 0x200) {
123
xf86DrvMsgVerb(screen,X_INFO,3,"VESA VBE OEM Software Rev: %i.%i\n",
124
VERSION(vbe->OemSoftwareRev));
125
if (vbe->OemVendorNamePtr)
126
xf86DrvMsgVerb(screen,X_INFO,3,"VESA VBE OEM Vendor: %s\n",
127
(CARD8*)xf86int10Addr(pInt,L_ADD(vbe->OemVendorNamePtr)));
128
if (vbe->OemProductNamePtr)
129
xf86DrvMsgVerb(screen,X_INFO,3,"VESA VBE OEM Product: %s\n",
130
(CARD8*)xf86int10Addr(pInt,L_ADD(vbe->OemProductNamePtr)));
131
if (vbe->OemProductRevPtr)
132
xf86DrvMsgVerb(screen,X_INFO,3,"VESA VBE OEM Product Rev: %s\n",
133
(CARD8*)xf86int10Addr(pInt,L_ADD(vbe->OemProductRevPtr)));
135
vip = (vbeInfoPtr)xnfalloc(sizeof(vbeInfoRec));
136
vip->version = B_O16(vbe->VbeVersion);
138
vip->ddc = DDC_UNCHECKED;
140
vip->real_mode_base = RealOff;
142
vip->init_int10 = init_int10;
148
xf86Int10FreePages(pInt, page, 1);
155
vbeFree(vbeInfoPtr pVbe)
160
xf86Int10FreePages(pVbe->pInt10,pVbe->memory,pVbe->num_pages);
161
/* If we have initalized int10 we ought to free it, too */
162
if (pVbe->init_int10)
163
xf86FreeInt10(pVbe->pInt10);
169
vbeProbeDDC(vbeInfoPtr pVbe)
172
int screen = pVbe->pInt10->scrnIndex;
174
if (!pVbe || (pVbe->ddc == DDC_NONE))
176
if (pVbe->ddc != DDC_UNCHECKED)
179
pVbe->pInt10->ax = 0x4F15;
180
pVbe->pInt10->bx = 0;
181
pVbe->pInt10->cx = 0;
182
pVbe->pInt10->es = 0;
183
pVbe->pInt10->di = 0;
184
pVbe->pInt10->num = 0x10;
186
xf86ExecX86int10(pVbe->pInt10);
188
if ((pVbe->pInt10->ax & 0xff) != 0x4f) {
189
xf86DrvMsgVerb(screen,X_INFO,3,"VESA VBE DDC not supported\n");
190
pVbe->ddc = DDC_NONE;
194
switch ((pVbe->pInt10->ax >> 8) & 0xff) {
196
xf86DrvMsg(screen,X_INFO,"VESA VBE DDC supported\n");
197
switch (pVbe->pInt10->bx & 0x3) {
200
pVbe->ddc = DDC_NONE;
211
ddc_level = " 1 + 2";
216
pVbe->ddc = DDC_NONE;
219
xf86DrvMsgVerb(screen,X_INFO,3,"VESA VBE DDC Level%s\n",ddc_level);
220
if (pVbe->pInt10->bx & 0x4) {
221
xf86DrvMsgVerb(screen,X_INFO,3,"VESA VBE DDC Screen blanked"
222
"for data transfer\n");
223
pVbe->ddc_blank = TRUE;
225
pVbe->ddc_blank = FALSE;
227
xf86DrvMsgVerb(screen,X_INFO,3,
228
"VESA VBE DDC transfer in appr. %x sec.\n",
229
(pVbe->pInt10->bx >> 8) & 0xff);
240
static const OptionInfoRec VBEOptions[] = {
241
{ VBEOPT_NOVBE, "NoVBE", OPTV_BOOLEAN, {0}, FALSE },
242
{ VBEOPT_NODDC, "NoDDC", OPTV_BOOLEAN, {0}, FALSE },
243
{ -1, NULL, OPTV_NONE, {0}, FALSE },
246
static unsigned char *
247
vbeReadEDID(vbeInfoPtr pVbe)
249
int RealOff = pVbe->real_mode_base;
250
pointer page = pVbe->memory;
251
unsigned char *tmp = NULL;
254
int screen = pVbe->pInt10->scrnIndex;
255
OptionInfoPtr options;
257
if (!page) return NULL;
259
options = xnfalloc(sizeof(VBEOptions));
260
(void)memcpy(options, VBEOptions, sizeof(VBEOptions));
261
xf86ProcessOptions(screen, xf86Screens[screen]->options, options);
262
xf86GetOptValBool(options, VBEOPT_NOVBE, &novbe);
263
xf86GetOptValBool(options, VBEOPT_NODDC, &noddc);
265
if (novbe || noddc) return NULL;
267
if (!vbeProbeDDC(pVbe)) goto error;
269
memset(page,0,sizeof(vbeInfoPtr));
270
strcpy(page,vbeVersionString);
272
pVbe->pInt10->ax = 0x4F15;
273
pVbe->pInt10->bx = 0x01;
274
pVbe->pInt10->cx = 0;
275
pVbe->pInt10->dx = 0;
276
pVbe->pInt10->es = SEG_ADDR(RealOff);
277
pVbe->pInt10->di = SEG_OFF(RealOff);
278
pVbe->pInt10->num = 0x10;
280
xf86ExecX86int10(pVbe->pInt10);
282
if ((pVbe->pInt10->ax & 0xff) != 0x4f) {
283
xf86DrvMsgVerb(screen,X_INFO,3,"VESA VBE DDC invalid\n");
286
switch (pVbe->pInt10->ax & 0xff00) {
288
xf86DrvMsgVerb(screen,X_INFO,3,"VESA VBE DDC read successfully\n");
289
tmp = (unsigned char *)xnfalloc(128);
290
memcpy(tmp,page,128);
293
xf86DrvMsgVerb(screen,X_INFO,3,"VESA VBE DDC read failed\n");
296
xf86DrvMsgVerb(screen,X_INFO,3,"VESA VBE DDC unkown failure %i\n",
297
pVbe->pInt10->ax & 0xff00);
306
vbeDoEDID(vbeInfoPtr pVbe, pointer pDDCModule)
310
unsigned char *DDC_data = NULL;
312
if (!pVbe) return NULL;
313
if (pVbe->version < 0x200)
316
if (!(pModule = pDDCModule)) {
318
xf86LoadSubModule(xf86Screens[pVbe->pInt10->scrnIndex], "ddc");
322
xf86LoaderReqSymLists(vbe_ddcSymbols, NULL);
325
DDC_data = vbeReadEDID(pVbe);
330
pMonitor = xf86InterpretEDID(pVbe->pInt10->scrnIndex, DDC_data);
333
xf86UnloadSubModule(pModule);
339
VBEGetVBEInfo(vbeInfoPtr pVbe)
341
VbeInfoBlock *block = NULL;
344
CARD16 major, minor, *modes;
346
bzero(pVbe->memory, sizeof(VbeInfoBlock));
350
AH := 4Fh Super VGA support
351
AL := 00h Return Super VGA information
352
ES:DI := Pointer to buffer
356
(All other registers are preserved)
359
((char*)pVbe->memory)[0] = 'V';
360
((char*)pVbe->memory)[1] = 'B';
361
((char*)pVbe->memory)[2] = 'E';
362
((char*)pVbe->memory)[3] = '2';
364
pVbe->pInt10->num = 0x10;
365
pVbe->pInt10->ax = 0x4f00;
366
pVbe->pInt10->es = SEG_ADDR(pVbe->real_mode_base);
367
pVbe->pInt10->di = SEG_OFF(pVbe->real_mode_base);
368
xf86ExecX86int10(pVbe->pInt10);
370
if (R16(pVbe->pInt10->ax) != 0x4f)
373
block = xcalloc(sizeof(VbeInfoBlock), 1);
374
block->VESASignature[0] = ((char*)pVbe->memory)[0];
375
block->VESASignature[1] = ((char*)pVbe->memory)[1];
376
block->VESASignature[2] = ((char*)pVbe->memory)[2];
377
block->VESASignature[3] = ((char*)pVbe->memory)[3];
379
block->VESAVersion = *(CARD16*)(((char*)pVbe->memory) + 4);
380
major = (unsigned)block->VESAVersion >> 8;
381
minor = block->VESAVersion & 0xff;
383
pStr = *(CARD32*)(((char*)pVbe->memory) + 6);
384
str = xf86int10Addr(pVbe->pInt10, FARP(pStr));
385
block->OEMStringPtr = strdup(str);
387
block->Capabilities[0] = ((char*)pVbe->memory)[10];
388
block->Capabilities[1] = ((char*)pVbe->memory)[11];
389
block->Capabilities[2] = ((char*)pVbe->memory)[12];
390
block->Capabilities[3] = ((char*)pVbe->memory)[13];
392
pModes = *(CARD32*)(((char*)pVbe->memory) + 14);
393
modes = xf86int10Addr(pVbe->pInt10, FARP(pModes));
395
while (modes[i] != 0xffff)
397
block->VideoModePtr = xalloc(sizeof(CARD16) * i + 1);
398
memcpy(block->VideoModePtr, modes, sizeof(CARD16) * i);
399
block->VideoModePtr[i] = 0xffff;
401
block->TotalMemory = *(CARD16*)(((char*)pVbe->memory) + 18);
404
memcpy(&block->OemSoftwareRev, ((char*)pVbe->memory) + 20, 236);
406
block->OemSoftwareRev = *(CARD16*)(((char*)pVbe->memory) + 20);
407
pStr = *(CARD32*)(((char*)pVbe->memory) + 22);
408
str = xf86int10Addr(pVbe->pInt10, FARP(pStr));
409
block->OemVendorNamePtr = strdup(str);
410
pStr = *(CARD32*)(((char*)pVbe->memory) + 26);
411
str = xf86int10Addr(pVbe->pInt10, FARP(pStr));
412
block->OemProductNamePtr = strdup(str);
413
pStr = *(CARD32*)(((char*)pVbe->memory) + 30);
414
str = xf86int10Addr(pVbe->pInt10, FARP(pStr));
415
block->OemProductRevPtr = strdup(str);
416
memcpy(&block->Reserved, ((char*)pVbe->memory) + 34, 222);
417
memcpy(&block->OemData, ((char*)pVbe->memory) + 256, 256);
424
VBEFreeVBEInfo(VbeInfoBlock *block)
426
xfree(block->OEMStringPtr);
427
xfree(block->VideoModePtr);
428
if (((unsigned)block->VESAVersion >> 8) >= 2) {
429
xfree(block->OemVendorNamePtr);
430
xfree(block->OemProductNamePtr);
431
xfree(block->OemProductRevPtr);
437
VBESetVBEMode(vbeInfoPtr pVbe, int mode, VbeCRTCInfoBlock *block)
441
AH := 4Fh Super VGA support
442
AL := 02h Set Super VGA video mode
445
D9-D10 := Reserved (must be 0)
446
D11 := 0 Use current default refresh rate
447
:= 1 Use user specified CRTC values for refresh rate
448
D12-13 Reserved for VBE/AF (must be 0)
449
D14 := 0 Use windowed frame buffer model
450
:= 1 Use linear/flat frame buffer model
451
D15 := 0 Clear video memory
452
:= 1 Don't clear video memory
453
ES:DI := Pointer to VbeCRTCInfoBlock structure
456
(All other registers are preserved)
458
pVbe->pInt10->num = 0x10;
459
pVbe->pInt10->ax = 0x4f02;
460
pVbe->pInt10->bx = mode;
462
pVbe->pInt10->bx |= 1 << 11;
463
memcpy(pVbe->memory, block, sizeof(VbeCRTCInfoBlock));
464
pVbe->pInt10->es = SEG_ADDR(pVbe->real_mode_base);
465
pVbe->pInt10->di = SEG_OFF(pVbe->real_mode_base);
468
xf86ExecX86int10(pVbe->pInt10);
470
return (R16(pVbe->pInt10->ax) == 0x4f);
474
VBEGetVBEMode(vbeInfoPtr pVbe, int *mode)
478
AH := 4Fh Super VGA support
479
AL := 03h Return current video mode
483
BX := Current video mode
484
(All other registers are preserved)
486
pVbe->pInt10->num = 0x10;
487
pVbe->pInt10->ax = 0x4f03;
489
xf86ExecX86int10(pVbe->pInt10);
491
if (R16(pVbe->pInt10->ax) == 0x4f) {
492
*mode = R16(pVbe->pInt10->bx);
501
VBEGetModeInfo(vbeInfoPtr pVbe, int mode)
503
VbeModeInfoBlock *block = NULL;
505
bzero(pVbe->memory, sizeof(VbeModeInfoBlock));
509
AH := 4Fh Super VGA support
510
AL := 01h Return Super VGA mode information
511
CX := Super VGA video mode
512
(mode number must be one of those returned by Function 0)
513
ES:DI := Pointer to buffer
517
(All other registers are preserved)
519
pVbe->pInt10->num = 0x10;
520
pVbe->pInt10->ax = 0x4f01;
521
pVbe->pInt10->cx = mode;
522
pVbe->pInt10->es = SEG_ADDR(pVbe->real_mode_base);
523
pVbe->pInt10->di = SEG_OFF(pVbe->real_mode_base);
524
xf86ExecX86int10(pVbe->pInt10);
525
if (R16(pVbe->pInt10->ax) != 0x4f)
528
block = xcalloc(sizeof(VbeModeInfoBlock), 1);
530
block->ModeAttributes = *(CARD16*)pVbe->memory;
531
block->WinAAttributes = ((char*)pVbe->memory)[2];
532
block->WinBAttributes = ((char*)pVbe->memory)[3];
533
block->WinGranularity = *(CARD16*)(((char*)pVbe->memory) + 4);
534
block->WinSize = *(CARD16*)(((char*)pVbe->memory) + 6);
535
block->WinASegment = *(CARD16*)(((char*)pVbe->memory) + 8);
536
block->WinBSegment = *(CARD16*)(((char*)pVbe->memory) + 10);
537
block->WinFuncPtr = *(CARD32*)(((char*)pVbe->memory) + 12);
538
block->BytesPerScanline = *(CARD16*)(((char*)pVbe->memory) + 16);
540
/* mandatory information for VBE 1.2 and above */
541
block->XResolution = *(CARD16*)(((char*)pVbe->memory) + 18);
542
block->YResolution = *(CARD16*)(((char*)pVbe->memory) + 20);
543
block->XCharSize = ((char*)pVbe->memory)[22];
544
block->YCharSize = ((char*)pVbe->memory)[23];
545
block->NumberOfPlanes = ((char*)pVbe->memory)[24];
546
block->BitsPerPixel = ((char*)pVbe->memory)[25];
547
block->NumberOfBanks = ((char*)pVbe->memory)[26];
548
block->MemoryModel = ((char*)pVbe->memory)[27];
549
block->BankSize = ((char*)pVbe->memory)[28];
550
block->NumberOfImages = ((char*)pVbe->memory)[29];
551
block->Reserved = ((char*)pVbe->memory)[30];
553
/* Direct color fields (required for direct/6 and YUV/7 memory models) */
554
block->RedMaskSize = ((char*)pVbe->memory)[31];
555
block->RedFieldPosition = ((char*)pVbe->memory)[32];
556
block->GreenMaskSize = ((char*)pVbe->memory)[33];
557
block->GreenFieldPosition = ((char*)pVbe->memory)[34];
558
block->BlueMaskSize = ((char*)pVbe->memory)[35];
559
block->BlueFieldPosition = ((char*)pVbe->memory)[36];
560
block->RsvdMaskSize = ((char*)pVbe->memory)[37];
561
block->RsvdFieldPosition = ((char*)pVbe->memory)[38];
562
block->DirectColorModeInfo = ((char*)pVbe->memory)[39];
564
/* Mandatory information for VBE 2.0 and above */
565
if (pVbe->version >= 0x200) {
566
block->PhysBasePtr = *(CARD32*)(((char*)pVbe->memory) + 40);
567
block->Reserved32 = *(CARD32*)(((char*)pVbe->memory) + 44);
568
block->Reserved16 = *(CARD16*)(((char*)pVbe->memory) + 48);
570
/* Mandatory information for VBE 3.0 and above */
571
if (pVbe->version >= 0x300) {
572
block->LinBytesPerScanLine = *(CARD16*)(((char*)pVbe->memory) + 50);
573
block->BnkNumberOfImagePages = ((char*)pVbe->memory)[52];
574
block->LinNumberOfImagePages = ((char*)pVbe->memory)[53];
575
block->LinRedMaskSize = ((char*)pVbe->memory)[54];
576
block->LinRedFieldPosition = ((char*)pVbe->memory)[55];
577
block->LinGreenMaskSize = ((char*)pVbe->memory)[56];
578
block->LinGreenFieldPosition = ((char*)pVbe->memory)[57];
579
block->LinBlueMaskSize = ((char*)pVbe->memory)[58];
580
block->LinBlueFieldPosition = ((char*)pVbe->memory)[59];
581
block->LinRsvdMaskSize = ((char*)pVbe->memory)[60];
582
block->LinRsvdFieldPosition = ((char*)pVbe->memory)[61];
583
block->MaxPixelClock = *(CARD32*)(((char*)pVbe->memory) + 62);
584
memcpy(&block->Reserved2, ((char*)pVbe->memory) + 66, 188);
587
memcpy(&block->LinBytesPerScanLine, ((char*)pVbe->memory) + 50, 206);
590
memcpy(&block->PhysBasePtr, ((char*)pVbe->memory) + 40, 216);
596
VBEFreeModeInfo(VbeModeInfoBlock *block)
602
VBESaveRestore(vbeInfoPtr pVbe, vbeSaveRestoreFunction function,
603
pointer *memory, int *size, int *real_mode_pages)
607
AH := 4Fh Super VGA support
608
AL := 04h Save/restore Super VGA video state
609
DL := 00h Return save/restore state buffer size
610
CX := Requested states
611
D0 = Save/restore video hardware state
612
D1 = Save/restore video BIOS data state
613
D2 = Save/restore video DAC state
614
D3 = Save/restore Super VGA state
618
BX = Number of 64-byte blocks to hold the state buffer
619
(All other registers are preserved)
623
AH := 4Fh Super VGA support
624
AL := 04h Save/restore Super VGA video state
625
DL := 01h Save Super VGA video state
626
CX := Requested states (see above)
627
ES:BX := Pointer to buffer
631
(All other registers are preserved)
635
AH := 4Fh Super VGA support
636
AL := 04h Save/restore Super VGA video state
637
DL := 02h Restore Super VGA video state
638
CX := Requested states (see above)
639
ES:BX := Pointer to buffer
643
(All other registers are preserved)
646
if ((pVbe->version & 0xff00) > 0x100) {
647
int screen = pVbe->pInt10->scrnIndex;
648
if (function == MODE_QUERY ||
649
(function == MODE_SAVE && !*memory)) {
650
/* Query amount of memory to save state */
652
pVbe->pInt10->num = 0x10;
653
pVbe->pInt10->ax = 0x4f04;
654
pVbe->pInt10->dx = 0;
655
pVbe->pInt10->cx = 0x000f;
656
xf86ExecX86int10(pVbe->pInt10);
657
if (R16(pVbe->pInt10->ax) != 0x4f)
660
if (function == MODE_SAVE) {
661
int npages = (R16(pVbe->pInt10->bx) * 64) / 4096 + 1;
662
if ((*memory = xf86Int10AllocPages(pVbe->pInt10, npages,
663
real_mode_pages)) == NULL) {
664
xf86DrvMsg(screen, X_ERROR,
665
"Cannot allocate memory to save SVGA state.\n");
669
*size = pVbe->pInt10->bx * 64;
672
/* Save/Restore Super VGA state */
673
if (function != MODE_QUERY) {
675
if (!*memory) return FALSE;
676
pVbe->pInt10->num = 0x10;
677
pVbe->pInt10->ax = 0x4f04;
680
pVbe->pInt10->dx = 1;
683
pVbe->pInt10->dx = 2;
688
pVbe->pInt10->cx = 0x000f;
690
pVbe->pInt10->es = SEG_ADDR(*real_mode_pages);
691
pVbe->pInt10->bx = SEG_OFF(*real_mode_pages);
692
xf86ExecX86int10(pVbe->pInt10);
693
return (R16(pVbe->pInt10->ax) == 0x4f);
701
VBEBankSwitch(vbeInfoPtr pVbe, unsigned int iBank, int window)
705
AH := 4Fh Super VGA support
710
pVbe->pInt10->num = 0x10;
711
pVbe->pInt10->ax = 0x4f05;
712
pVbe->pInt10->bx = window;
713
pVbe->pInt10->dx = iBank;
714
xf86ExecX86int10(pVbe->pInt10);
716
if (R16(pVbe->pInt10->ax) != 0x4f)
723
VBESetGetLogicalScanlineLength(vbeInfoPtr pVbe, vbeScanwidthCommand command,
724
int width, int *pixels, int *bytes, int *max)
726
if (command < SCANWID_SET || command > SCANWID_GET_MAX)
731
AX := 4F06h VBE Set/Get Logical Scan Line Length
732
BL := 00h Set Scan Line Length in Pixels
733
:= 01h Get Scan Line Length
734
:= 02h Set Scan Line Length in Bytes
735
:= 03h Get Maximum Scan Line Length
736
CX := If BL=00h Desired Width in Pixels
737
If BL=02h Desired Width in Bytes
738
(Ignored for Get Functions)
741
AX := VBE Return Status
742
BX := Bytes Per Scan Line
743
CX := Actual Pixels Per Scan Line
744
(truncated to nearest complete pixel)
745
DX := Maximum Number of Scan Lines
748
pVbe->pInt10->num = 0x10;
749
pVbe->pInt10->ax = 0x4f06;
750
pVbe->pInt10->bx = command;
751
if (command == SCANWID_SET || command == SCANWID_SET_BYTES)
752
pVbe->pInt10->cx = width;
753
xf86ExecX86int10(pVbe->pInt10);
755
if (R16(pVbe->pInt10->ax) != 0x4f)
758
if (command == SCANWID_GET || command == SCANWID_GET_MAX) {
760
*pixels = R16(pVbe->pInt10->cx);
762
*bytes = R16(pVbe->pInt10->bx);
764
*max = R16(pVbe->pInt10->dx);
771
VBESetDisplayStart(vbeInfoPtr pVbe, int x, int y, Bool wait_retrace)
773
pVbe->pInt10->num = 0x10;
774
pVbe->pInt10->ax = 0x4f07;
775
pVbe->pInt10->bx = wait_retrace ? 0x80 : 0x00;
776
pVbe->pInt10->cx = x;
777
pVbe->pInt10->dx = y;
778
xf86ExecX86int10(pVbe->pInt10);
780
if (R16(pVbe->pInt10->ax) != 0x4f)
787
VBEGetDisplayStart(vbeInfoPtr pVbe, int *x, int *y)
789
pVbe->pInt10->num = 0x10;
790
pVbe->pInt10->ax = 0x4f07;
791
pVbe->pInt10->bx = 0x01;
792
xf86ExecX86int10(pVbe->pInt10);
794
if (R16(pVbe->pInt10->ax) != 0x4f)
797
*x = pVbe->pInt10->cx;
798
*y = pVbe->pInt10->dx;
804
VBESetGetDACPaletteFormat(vbeInfoPtr pVbe, int bits)
808
AX := 4F08h VBE Set/Get Palette Format
809
BL := 00h Set DAC Palette Format
810
:= 01h Get DAC Palette Format
811
BH := Desired bits of color per primary
812
(Set DAC Palette Format only)
815
AX := VBE Return Status
816
BH := Current number of bits of color per primary
819
pVbe->pInt10->num = 0x10;
820
pVbe->pInt10->ax = 0x4f08;
822
pVbe->pInt10->bx = 0x01;
824
pVbe->pInt10->bx = (bits & 0x00ff) << 8;
825
xf86ExecX86int10(pVbe->pInt10);
827
if (R16(pVbe->pInt10->ax) != 0x4f)
830
return (bits != 0 ? bits : (pVbe->pInt10->bx >> 8) & 0x00ff);
834
VBESetGetPaletteData(vbeInfoPtr pVbe, Bool set, int first, int num,
835
CARD32 *data, Bool secondary, Bool wait_retrace)
840
AX := 4F09h VBE Load/Unload Palette Data
841
BL := 00h Set Palette Data
842
:= 01h Get Palette Data
843
:= 02h Set Secondary Palette Data
844
:= 03h Get Secondary Palette Data
845
:= 80h Set Palette Data during Vertical Retrace
846
CX := Number of palette registers to update (to a maximum of 256)
847
DX := First of the palette registers to update (start)
848
ES:DI := Table of palette values (see below for format)
851
AX := VBE Return Status
856
BL := 00h Set Palette Data
857
:= 80h Set Palette Data during Vertical Retrace
858
CX := Number of palette registers to update (to a maximum of 256)
859
DX := First of the palette registers to update (start)
860
ES:EDI := Table of palette values (see below for format)
861
DS := Selector for memory mapped registers
864
pVbe->pInt10->num = 0x10;
865
pVbe->pInt10->ax = 0x4f09;
867
pVbe->pInt10->bx = set && wait_retrace ? 0x80 : set ? 0 : 1;
869
pVbe->pInt10->bx = set ? 2 : 3;
870
pVbe->pInt10->cx = num;
871
pVbe->pInt10->dx = first;
872
pVbe->pInt10->es = SEG_ADDR(pVbe->real_mode_base);
873
pVbe->pInt10->di = SEG_OFF(pVbe->real_mode_base);
875
memcpy(pVbe->memory, data, num * sizeof(CARD32));
876
xf86ExecX86int10(pVbe->pInt10);
878
if (R16(pVbe->pInt10->ax) != 0x4f)
884
data = xalloc(num * sizeof(CARD32));
885
memcpy(data, pVbe->memory, num * sizeof(CARD32));
891
VBEGetVBEpmi(vbeInfoPtr pVbe)
897
AH := 4Fh Super VGA support
898
AL := 0Ah Protected Mode Interface
899
BL := 00h Return Protected Mode Table
903
ES := Real Mode Segment of Table
904
DI := Offset of Table
905
CX := Lenght of Table including protected mode code in bytes (for copying purposes)
906
(All other registers are preserved)
909
pVbe->pInt10->num = 0x10;
910
pVbe->pInt10->ax = 0x4f0a;
911
pVbe->pInt10->bx = 0;
912
pVbe->pInt10->di = 0;
913
xf86ExecX86int10(pVbe->pInt10);
915
if (R16(pVbe->pInt10->ax) != 0x4f)
918
pmi = xalloc(sizeof(VBEpmi));
919
pmi->seg_tbl = R16(pVbe->pInt10->es);
920
pmi->tbl_off = R16(pVbe->pInt10->di);
921
pmi->tbl_len = R16(pVbe->pInt10->cx);
928
VBEBuildVbeModeList(vbeInfoPtr pVbe, VbeInfoBlock *vbe)
930
vbeModeInfoPtr ModeList = NULL;
933
while (vbe->VideoModePtr[i] != 0xffff) {
935
VbeModeInfoBlock *mode;
936
int id = vbe->VideoModePtr[i++];
939
if ((mode = VBEGetModeInfo(pVbe, id)) == NULL)
942
bpp = mode->BitsPerPixel;
944
m = xnfcalloc(sizeof(vbeModeInfoRec),1);
945
m->width = mode->XResolution;
946
m->height = mode->YResolution;
951
xf86DrvMsgVerb(pVbe->pInt10->scrnIndex, X_PROBED, 3,
952
"BIOS reported VESA mode 0x%x: x:%i y:%i bpp:%i\n",
953
m->n, m->width, m->height, m->bpp);
957
VBEFreeModeInfo(mode);
963
VBECalcVbeModeIndex(vbeModeInfoPtr m, DisplayModePtr mode, int bpp)
967
&& mode->HDisplay == m->width
968
&& mode->VDisplay == m->height)
977
VBEVesaSaveRestore(vbeInfoPtr pVbe, vbeSaveRestorePtr vbe_sr,
978
vbeSaveRestoreFunction function)
980
Bool SaveSucc = FALSE;
982
if (VBE_VERSION_MAJOR(pVbe->version) > 1
983
&& (function == MODE_SAVE || vbe_sr->pstate)) {
984
if (function == MODE_RESTORE)
985
memcpy(vbe_sr->state, vbe_sr->pstate, vbe_sr->stateSize);
986
ErrorF("VBESaveRestore\n");
987
if ((VBESaveRestore(pVbe,function,
988
(pointer)&vbe_sr->state,
989
&vbe_sr->stateSize,&vbe_sr->statePage))) {
990
if (function == MODE_SAVE) {
992
vbe_sr->stateMode = -1; /* invalidate */
993
/* don't rely on the memory not being touched */
994
if (vbe_sr->pstate == NULL)
995
vbe_sr->pstate = xalloc(vbe_sr->stateSize);
996
memcpy(vbe_sr->pstate, vbe_sr->state, vbe_sr->stateSize);
998
ErrorF("VBESaveRestore done with success\n");
1001
ErrorF("VBESaveRestore done\n");
1004
if (function == MODE_SAVE && !SaveSucc)
1005
(void)VBEGetVBEMode(pVbe, &vbe_sr->stateMode);
1007
if (function == MODE_RESTORE && vbe_sr->stateMode != -1)
1008
VBESetVBEMode(pVbe, vbe_sr->stateMode, NULL);
1013
VBEGetPixelClock(vbeInfoPtr pVbe, int mode, int clock)
1017
AX := 4F0Bh VBE Get Pixel Clock
1018
BL := 01h Get Pixel Clock
1019
ECX := pixel clock in units of Hz
1023
AX := VBE Return Status
1024
ECX := Closest pixel clock
1027
pVbe->pInt10->num = 0x10;
1028
pVbe->pInt10->ax = 0x4f0b;
1029
pVbe->pInt10->bx = 0x01;
1030
pVbe->pInt10->cx = clock;
1031
pVbe->pInt10->dx = mode;
1032
xf86ExecX86int10(pVbe->pInt10);
1034
if (R16(pVbe->pInt10->ax) != 0x4f)
1037
return (pVbe->pInt10->cx);
1041
VBEDPMSSet(vbeInfoPtr pVbe, int mode)
1046
BL := 01h Set Display Power State
1047
BH := requested power state
1050
AX := VBE Return Status
1053
pVbe->pInt10->num = 0x10;
1054
pVbe->pInt10->ax = 0x4f10;
1055
pVbe->pInt10->bx = 0x01;
1059
case DPMSModeStandby:
1060
pVbe->pInt10->bx |= 0x100;
1062
case DPMSModeSuspend:
1063
pVbe->pInt10->bx |= 0x200;
1066
pVbe->pInt10->bx |= 0x400;
1069
xf86ExecX86int10(pVbe->pInt10);
1070
return (R16(pVbe->pInt10->ax) == 0x4f);