12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109 |
- {$MODE objfpc}
- {$ASMMODE intel}
- { $DEFINE DEBUGOUTPUT}
- Unit vesa;
- Interface
- Type
- TVesaModeInfoBlock = Packed Record
- {Mandatory information for all VBE revisions}
- ModeAttributes : Word; {mode attributes}
- WinAAttributes : Byte; {window A attributes}
- WinBAttributes : Byte; {window B attributes}
- WinGranularity : Word; {window granularity}
- WinSize : Word; {window size}
- WinASegment : Word; {window A start segment}
- WinBSegment : Word; {window B start segment}
- WinFuncPtr : DWord; {real mode pointer to window function}
- BytesPerScanLine : Word; {bytes per scan line}
- {Mandatory information for VBE 1.2 and above}
- XResolution : Word; {horizontal resolution in pixels or characters}
- YResolution : Word; {vertical resolution in pixels or characters}
- XCharSize : Byte; {character cell width in pixels}
- YCharSize : Byte; {character cell height in pixels}
- NumberOfPlanes : Byte; {number of memory planes}
- BitsPerPixel : Byte; {bits per pixel}
- NumberOfBanks : Byte; {number of banks}
- MemoryModel : Byte; {memory model type}
- BankSize : Byte; {bank size in KB}
- NumberOfImagePages : Byte; {number of images}
- Reserved : Byte;{=1} {reserved for page function}
- {Direct color fields (required for direct/6 and YUV/7 memory models)}
- RedMaskSize : Byte; {size of direct color red mask in bits}
- RedFieldPosition : Byte; {bit position of lsb of red mask}
- GreenMaskSize : Byte; {size of direct color green mask in bits}
- GreenFieldPosition : Byte; {bit position of lsb of green mask}
- BlueMaskSize : Byte; {size of direct color blue mask in bits}
- BlueFieldPosition : Byte; {bit position of lsb of blue mask}
- RsvdMaskSize : Byte; {size of direct color reserved mask in bits}
- RsvdFieldPosition : Byte; {bit position of lsb of reserved mask}
- DirectColorModeInfo : Byte; {direct color mode attributes}
- {Mandatory information for VBE 2.0 and above}
- PhysBasePtr : DWord; {physical address for flat memory frame buffer}
- Reserved2 : DWord;{=0} {Reserved - always set to 0}
- Reserved3 : Word;{=0} {Reserved - always set to 0}
- {Mandatory information for VBE 3.0 and above}
- LinBytesPerScanLine : Word; {bytes per scan line for linear modes}
- BnkNumberOfImagePages : Byte; {number of images for banked modes}
- LinNumberOfImagePages : Byte; {number of images for linear modes}
- LinRedMaskSize : Byte; {size of direct color red mask (linear modes)}
- LinRedFieldPosition : Byte; {bit position of lsb of red mask (linear modes)}
- LinGreenMaskSize : Byte; {size of direct color green mask (linear modes)}
- LinGreenFieldPosition : Byte; {bit position of lsb of green mask (linear modes)}
- LinBlueMaskSize : Byte; {size of direct color blue mask (linear modes)}
- LinBlueFieldPosition : Byte; {bit position of lsb of blue mask (linear modes)}
- LinRsvdMaskSize : Byte; {size of direct color reserved mask (linear modes)}
- LinRsvdFieldPosition : Byte; {bit position of lsb of reserved mask (linear modes)}
- MaxPixelClock : DWord; {maximum pixel clock (in Hz) for graphics mode}
- Reserved4 : Array[1..189] Of Byte; {remainder of ModeInfoBlock}
- End;
- PModeInfo = ^TModeInfo;
- TModeInfo = Record
- ModeNumber : DWord;
- VesaModeInfo : TVesaModeInfoBlock;
- End;
- Var
- ModeInfo : PModeInfo;
- NrOfModes : Integer;
- VBEPresent : Boolean;
- Procedure InitVESA;
- Function SetVESAMode(M : Integer) : Boolean;
- Procedure RestoreTextMode;
- Procedure WriteToVideoMemory(Src : Pointer; Dest : DWord; Size : DWord);
- Procedure SetPalette(Palette : Pointer; First, Num : Integer);
- Procedure GetPalette(Palette : Pointer; First, Num : Integer);
- Function MakeMask(MaskSize, FieldPosition : Integer) : DWord;
- Implementation
- Uses
- go32;
- Type
- TVBEInfoBlock = Packed Record
- {VBE 1.0+}
- VBESignature : DWord; {'VESA'}
- VBEVersion : Word;
- OemStringPtr : DWord; {VbeFarPtr to OEM String}
- Capabilities : DWord; {Capabilities of graphics controller}
- VideoModePtr : DWord; {VbeFarPtr to VideoModeList}
- {added for VBE 1.1+}
- TotalMemory : Word; {Number of 64kb memory blocks}
- {added for VBE 2.0+}
- OemSoftwareRev : Word; {VBE implementation Software revision}
- OemVendorNamePtr : DWord; {VbeFarPtr to Vendor Name String}
- OemProductNamePtr : DWord; {VbeFarPtr to Product Name String}
- OemProductRevPtr : DWord; {VbeFarPtr to Product Revision String}
- Reserved : Array[1..222] Of Byte; {Reserved for VBE implementation scratch area}
- OemData : Array[1..256] Of Char; {Data Area for OEM Strings}
- End;
- Var
- VBEInfoBlock : TVBEInfoBlock;
- VideoMemory : DWord;
- EightBitDACSupported : Boolean;
- nonVGA : Boolean;
- SnowyRAMDAC : Boolean;
- StereoSignalingSupport : Boolean;
- StereoSignalingVesaEVC : Boolean;
- OEMString : String;
- OEMVendorName : String;
- OEMProductName : String;
- OEMProductRev : String;
- OEMSoftwareRev : Integer;
- CurrentMode : Integer;
- LFBUsed : Boolean;
- UseLFB : Boolean;
- RealModePaletteSel : Word;
- RealModePaletteSeg : Word;
- SetPaletteHW : Boolean;
- PaletteDACbits : Integer;
- ReadWindow, WriteWindow : Integer;
- ReadWindowStart, WriteWindowStart : Integer;
- ReadWindowAddress, WriteWindowAddress : Integer;
- WindowGranularity : DWord;
- WindowSize, WindowSizeG : DWord;
- VESAInit : Boolean;
- RealRegs : TRealRegs;
- temp : Pointer;
- Procedure StandardMode(ModeNumber : DWord; Var ModeInfo : TVesaModeInfoBlock);
- Begin
- {
- 100 640x400x256
- 101 640x480x256
- 102 800x600x16
- 103 800x600x256
- 104 1024x768x16
- 105 1024x768x256
- 106 1280x1024x16
- 107 1280x1024x256
- 108 80x60t
- 109 132x25t
- 10A 132x43t
- 10B 132x50t
- 10C 132x60t
- 10D 320x200x32k
- 10E 320x200x64k
- 10F 320x200x16.8m
- 110 640x480x32k
- 111 640x480x64k
- 112 640x480x16.8m
- 113 800x600x32k
- 114 800x600x64k
- 115 800x600x16.8m
- 116 1024x768x32k
- 117 1024x768x64k
- 118 1024x768x16.8m
- 119 1280x1024x32k
- 11A 1280x1024x64k
- 11B 1280x1024x16.8m
- }
- With ModeInfo Do
- Begin
- ModeAttributes := ModeAttributes Or 2;
- Case ModeNumber Of
- $100 : Begin
- XResolution := 640;
- YResolution := 400;
- XCharSize := 8;
- YCharSize := 16;
- NumberOfPlanes := 1;
- BitsPerPixel := 8;
- MemoryModel := 4;
- End;
- $101 : Begin
- XResolution := 640;
- YResolution := 480;
- XCharSize := 8;
- YCharSize := 16;
- NumberOfPlanes := 1;
- BitsPerPixel := 8;
- MemoryModel := 4;
- End;
- $102 : Begin
- XResolution := 800;
- YResolution := 600;
- XCharSize := 8;
- YCharSize := 16;
- NumberOfPlanes := 4;
- BitsPerPixel := 4;
- MemoryModel := 3;
- End;
- $103 : Begin
- XResolution := 800;
- YResolution := 600;
- XCharSize := 8;
- YCharSize := 16;
- NumberOfPlanes := 1;
- BitsPerPixel := 8;
- MemoryModel := 4;
- End;
- $104 : Begin
- XResolution := 1024;
- YResolution := 768;
- XCharSize := 8;
- YCharSize := 16;
- NumberOfPlanes := 4;
- BitsPerPixel := 4;
- MemoryModel := 3;
- End;
- $105 : Begin
- XResolution := 1024;
- YResolution := 768;
- XCharSize := 8;
- YCharSize := 16;
- NumberOfPlanes := 1;
- BitsPerPixel := 8;
- MemoryModel := 4;
- End;
- $106 : Begin
- XResolution := 1280;
- YResolution := 1024;
- XCharSize := 8;
- YCharSize := 16;
- NumberOfPlanes := 4;
- BitsPerPixel := 4;
- MemoryModel := 3;
- End;
- $107 : Begin
- XResolution := 1280;
- YResolution := 1024;
- XCharSize := 8;
- YCharSize := 16;
- NumberOfPlanes := 1;
- BitsPerPixel := 8;
- MemoryModel := 4;
- End;
- $108 : Begin
- XResolution := 80;
- YResolution := 60;
- XCharSize := 8;
- YCharSize := 16;
- NumberOfPlanes := 4;
- BitsPerPixel := 4;
- MemoryModel := 0;
- End;
- $109 : Begin
- XResolution := 132;
- YResolution := 25;
- XCharSize := 8;
- YCharSize := 16;
- NumberOfPlanes := 4;
- BitsPerPixel := 4;
- MemoryModel := 0;
- End;
- $10A : Begin
- XResolution := 132;
- YResolution := 43;
- XCharSize := 8;
- YCharSize := 16;
- NumberOfPlanes := 4;
- BitsPerPixel := 4;
- MemoryModel := 0;
- End;
- $10B : Begin
- XResolution := 132;
- YResolution := 50;
- XCharSize := 8;
- YCharSize := 16;
- NumberOfPlanes := 4;
- BitsPerPixel := 4;
- MemoryModel := 0;
- End;
- $10C : Begin
- XResolution := 132;
- YResolution := 60;
- XCharSize := 8;
- YCharSize := 16;
- NumberOfPlanes := 4;
- BitsPerPixel := 4;
- MemoryModel := 0;
- End;
- {todo:10D..11B}
- Else
- ModeAttributes := ModeAttributes And $FFFD;
- End;
- // NumberOfImagePages := 0;{...}
- End;
- End;
- Function bcd(q : Integer) : Integer;
- Begin
- q := q And $FF;
- If ((q And $F) < 10) And ((q Shr 4) < 10) Then
- bcd := (q And $F) + (q Shr 4) * 10
- Else
- bcd := q;
- End;
- Procedure DisposeRealModePalette;
- Begin
- If RealModePaletteSel = 0 Then
- Exit;
- global_dos_free(RealModePaletteSel);
- RealModePaletteSel := 0;
- RealModePaletteSeg := 0;
- End;
- Procedure AllocateRealModePalette;
- Var
- Addr : DWord;
- Begin
- DisposeRealModePalette;
- Addr := global_dos_alloc(256*4);
- RealModePaletteSeg := Addr Shr 16;
- RealModePaletteSel := Addr And $FFFF;
- End;
- Procedure SetPalette2(Palette : Pointer; Num : Integer); Assembler;
- Asm
- push es
- cld
- mov ax, fs
- mov es, ax
- mov esi, [Palette]
- movzx edi, word [RealModePaletteSeg]
- shl edi, 4
- mov ecx, Num
- { mov edx, 03F3F3F3Fh}
- mov edx, 0003F3F3Fh
- @@1:
- lodsd
- shr eax, 2 {convert 8->6bit}
- and eax, edx
- stosd
- dec ecx
- jnz @@1
- pop es
- End;
- Procedure SetPalette3(Palette : Pointer; Num : Integer); Assembler;
- Asm
- push es
- cld
- mov ax, fs
- mov es, ax
- mov esi, [Palette]
- movzx edi, word [RealModePaletteSeg]
- shl edi, 4
- mov ecx, Num
- { mov edx, 07F7F7F7Fh}
- mov edx, 0007F7F7Fh
- @@1:
- lodsd
- shr eax, 1 {convert 8->7bit}
- and eax, edx
- stosd
- dec ecx
- jnz @@1
- pop es
- End;
- Procedure SetPaletteHW6(Palette : Pointer; First, Num : Integer);
- Var
- I : Integer;
- p : PDWord;
- c : DWord;
- Begin
- p := PDWord(Palette);
- outportb($3C8, First);
- While Num > 0 Do
- Begin
- c := (p^ Shr 2) And $3F3F3F;
- outportb($3C9, c Shr 16);
- outportb($3C9, c Shr 8);
- outportb($3C9, c);
- Inc(p);
- Dec(Num);
- End;
- End;
- Procedure SetPaletteHW7(Palette : Pointer; First, Num : Integer);
- Var
- I : Integer;
- p : PDWord;
- c : DWord;
- Begin
- p := PDWord(Palette);
- outportb($3C8, First);
- While Num > 0 Do
- Begin
- c := (p^ Shr 1) And $7F7F7F;
- outportb($3C9, c Shr 16);
- outportb($3C9, c Shr 8);
- outportb($3C9, c);
- Inc(p);
- Dec(Num);
- End;
- End;
- Procedure SetPaletteHW8(Palette : Pointer; First, Num : Integer);
- Var
- I : Integer;
- p : PDWord;
- Begin
- p := PDWord(Palette);
- outportb($3C8, First);
- While Num > 0 Do
- Begin
- outportb($3C9, p^ Shr 16);
- outportb($3C9, p^ Shr 8);
- outportb($3C9, p^);
- Inc(p);
- Dec(Num);
- End;
- End;
- Procedure SetPalette(Palette : Pointer; First, Num : Integer);
- Begin
- If SetPaletteHW Then
- Begin
- Case PaletteDACbits Of
- 8 : SetPaletteHW8(Palette, First, Num);
- 7 : SetPaletteHW7(Palette, First, Num);
- 6 : SetPaletteHW6(Palette, First, Num);
- End;
- End
- Else
- Begin
- If PaletteDACbits = 8 Then
- dosmemput(RealModePaletteSeg, 0, Palette^, Num * 4) {8bits}
- Else
- If PaletteDACbits = 7 Then
- SetPalette3(Palette, Num) {7bits}
- Else
- SetPalette2(Palette, Num); {6bits}
- RealRegs.ax := $4F09;
- RealRegs.bl := 0;
- RealRegs.cx := Num;
- RealRegs.dx := First;
- RealRegs.es := RealModePaletteSeg;
- RealRegs.di := 0;
- realintr($10, RealRegs);
- End;
- End;
- Procedure GetPalette(Palette : Pointer; First, Num : Integer);
- Begin
- RealRegs.ax := $4F09;
- RealRegs.bl := 1;
- RealRegs.cx := Num;
- RealRegs.dx := First;
- RealRegs.es := RealModePaletteSeg;
- RealRegs.di := 0;
- realintr($10, RealRegs);
- {...}
- End;
- Procedure SwitchTo8bitDAC;
- Begin
- RealRegs.ax := $4F08;
- RealRegs.bl := 0;
- RealRegs.bh := 8;
- realintr($10, RealRegs);
- PaletteDACbits := RealRegs.bh;
- If PaletteDACbits < 6 Then
- PaletteDACbits := 6;
- End;
- Function MakeMask(MaskSize, FieldPosition : Integer) : DWord;
- Var
- Mask : DWord;
- I : Integer;
- Begin
- Mask := 1 Shl FieldPosition;
- For I := 2 To MaskSize Do
- Mask := Mask Or (Mask Shl 1);
- MakeMask := Mask;
- End;
- Function GetRMString(SegOfs : DWord) : String;
- Var
- S : String;
- C : Char;
- Seg, Ofs : Word;
- Begin
- If SegOfs = 0 Then
- Begin
- GetRMString := '';
- Exit;
- End;
- S := '';
- Ofs := SegOfs And $FFFF;
- Seg := SegOfs Shr 16;
- Repeat
- dosmemget(Seg, Ofs, C, 1);
- If C <> #0 Then
- Begin
- S := S + C;
- If Ofs = $FFFF Then
- Begin
- Ofs := 0;
- Inc(Seg, $1000);
- End
- Else
- Inc(Ofs);
- End;
- Until C = #0;
- GetRMString := S;
- End;
- Procedure SetWriteWindowStart(WinPos : DWord);
- Begin
- RealRegs.ax := $4F05;
- RealRegs.bx := WriteWindow;
- RealRegs.dx := WinPos;
- realintr($10, RealRegs);
- End;
- Procedure WriteToVideoMemory(Src : Pointer; Dest : DWord; Size : DWord);
- Var
- WW : Integer;
- ToDo : Integer;
- Begin
- WW := Dest Div WindowGranularity;
- Dest := Dest Mod WindowGranularity;
- { Writeln(WindowSize);}
- While Size > 0 Do
- Begin
- { Write(WW, ' ');}
- SetWriteWindowStart(WW);
- ToDo := WindowSize - Dest;
- If Size < ToDo Then
- ToDo := Size;
- Asm
- push es
- mov esi, Src
- mov edi, Dest
- add edi, WriteWindowAddress
- mov ax, fs
- mov es, ax
- mov ecx, ToDo
- shr ecx, 2
- cld
- rep movsd
- mov ecx, ToDo
- and ecx, 3
- jz @@1
- rep movsb
- @@1:
- pop es
- End ['EAX', 'ECX', 'ESI', 'EDI'];
- Dest := 0;
- Inc(WW, WindowSizeG);
- { Inc(WW);}
- Inc(Src, ToDo);
- Dec(Size, ToDo);
- End;
- End;
- {$IFDEF DEBUGOUTPUT}
- Procedure WinAttrib(q : Integer);
- Begin
- If (q And 1) <> 0 Then
- Write(' supported')
- Else
- Write(' not_supported');
- If (q And 2) <> 0 Then
- Write(' readable');
- If (q And 4) <> 0 Then
- Write(' writeable');
- Writeln;
- End;
- {$ENDIF DEBUGOUTPUT}
- Procedure GetModes;
- Type
- PModesList = ^TModesList;
- TModesList = Record
- ModeInfo : TModeInfo;
- Next : PModesList;
- End;
- Var
- First, Last, Run, Tmp : PModesList;
- Procedure AddToList;
- Begin
- If Last = Nil Then
- Begin
- New(Last);
- First := Last;
- End
- Else
- Begin
- New(Last^.Next);
- Last := Last^.Next;
- Last^.Next := Nil;
- End;
- End;
- Var
- I : DWord;
- Addr : DWord;
- AddrSeg, AddrSel : Word;
- VesaModeInfo : TVesaModeInfoBlock;
- ScanStart, ScanEnd : Integer;
- ModeAttr : Integer;
- IsModeOk : Boolean;
- hasReadWindow, hasWriteWindow : Boolean;
- Begin
- NrOfModes := -1;
- First := Nil;
- Last := Nil;
- Addr := global_dos_alloc(512);
- AddrSeg := Addr Shr 16;
- AddrSel := Addr And $FFFF;
- ScanStart := 0;
- { ScanEnd := $7FFF;} {VBE 1.0+ ??}
- { ScanEnd := $3FFF;} {VBE 1.2+ ??}
- ScanEnd := $7FF; {VBE 3.0+}
- {$IFDEF DEBUGOUTPUT}
- Writeln('scanning modes $', HexStr(ScanStart, 4), '..$', HexStr(ScanEnd, 4));
- {$ENDIF DEBUGOUTPUT}
- For I := ScanStart To ScanEnd Do
- Begin
- FillChar(VesaModeInfo, SizeOf(VesaModeInfo), 0);
- dosmemput(AddrSeg, 0, VesaModeInfo, SizeOf(VesaModeInfo));
- RealRegs.ax := $4F01; {return VBE mode information}
- RealRegs.cx := I;
- RealRegs.es := AddrSeg;
- RealRegs.di := 0;
- realintr($10, RealRegs);
- dosmemget(AddrSeg, 0, VesaModeInfo, SizeOf(VesaModeInfo));
- {display mode info}
- {$IFDEF DEBUGOUTPUT}
- If ((VesaModeInfo.ModeAttributes And 1) <> 0) Or
- (VesaModeInfo.BytesPerScanLine <> 0) Then
- Begin
- Writeln('ModeNumber: $', HexStr(I, 4));
- Write('ModeAttributes:');
- If (VesaModeInfo.ModeAttributes And 1) <> 0 Then
- Write(' supported')
- Else
- Write(' not_supported');
- If (VesaModeInfo.ModeAttributes And 2) <> 0 Then
- Write('')
- Else
- Write(' reserved_is_zero(noresolutioninfo_for_vbe1.1-)');
- If (VesaModeInfo.ModeAttributes And 4) <> 0 Then
- Write(' TTY')
- Else
- Write(' noTTY');
- If (VesaModeInfo.ModeAttributes And 8) <> 0 Then
- Write(' color')
- Else
- Write(' monochrome');
- If (VesaModeInfo.ModeAttributes And 16) <> 0 Then
- Write(' graph')
- Else
- Write(' text');
- If (VesaModeInfo.ModeAttributes And 32) <> 0 Then
- Write(' nonVGA')
- Else
- Write(' VGA');
- If (VesaModeInfo.ModeAttributes And 64) <> 0 Then
- Write(' noWINDOWED')
- Else
- Write(' WINDOWED');
- If (VesaModeInfo.ModeAttributes And 128) <> 0 Then
- Write(' LFB')
- Else
- Write(' noLFB');
- If (VesaModeInfo.ModeAttributes And 256) <> 0 Then
- Write(' DoubleScanMode_is_available')
- Else
- Write('');
- If (VesaModeInfo.ModeAttributes And 512) <> 0 Then
- Write(' InterlacedMode_is_available')
- Else
- Write('');
- If (VesaModeInfo.ModeAttributes And 1024) <> 0 Then
- Write(' TripleBuffering')
- Else
- Write('');
- If (VesaModeInfo.ModeAttributes And 2048) <> 0 Then
- Write(' StereoscopicDisplaySupport')
- Else
- Write('');
- If (VesaModeInfo.ModeAttributes And 4096) <> 0 Then
- Write(' DualDisplayStartAddressSupport')
- Else
- Write('');
- Writeln;
- Write('WinAAtributes:');
- WinAttrib(VesaModeInfo.WinAAttributes);
- Write('WinBAttributes:');
- WinAttrib(VesaModeInfo.WinBAttributes);
- Writeln('WinGranularity: ', VesaModeInfo.WinGranularity, ' KB');
- Writeln('WinSize: ', VesaModeInfo.WinSize, ' KB');
- Writeln('WinASegment: $', HexStr(VesaModeInfo.WinASegment, 4));
- Writeln('WinBSegment: $', HexStr(VesaModeInfo.WinBSegment, 4));
- Writeln('WinFuncPtr: ', HexStr(VesaModeInfo.WinFuncPtr Shr 16, 4), ':', HexStr(VesaModeInfo.WinFuncPtr And $FFFF, 4));
- Writeln('BytesPerScanLine: ', VesaModeInfo.BytesPerScanLine);
- Writeln('vbe1.2+');
- Writeln('XResolution: ', VesaModeInfo.XResolution);
- Writeln('YResolution: ', VesaModeInfo.YResolution);
- Writeln('XCharSize: ', VesaModeInfo.XCharSize);
- Writeln('YCharSize: ', VesaModeInfo.YCharSize);
- Writeln('NumberOfPlanes: ', VesaModeInfo.NumberOfPlanes);
- Writeln('BitsPerPixel: ', VesaModeInfo.BitsPerPixel);
- Writeln('NumberOfBanks: ', VesaModeInfo.NumberOfBanks);
- Write('MemoryModel: ');
- Case VesaModeInfo.MemoryModel Of
- 0 : Write('Text mode');
- 1 : Write('CGA graphics');
- 2 : Write('Hercules graphics');
- 3 : Write('Planar');
- 4 : Write('Packed pixel');
- 5 : Write('Non-chain 4, 256 color');
- 6 : Write('Direct Color');
- 7 : Write('YUV');
- 8..15 : Write('Reserved, to be defined by VESA');
- Else
- Write('To be defined by OEM');
- End;
- Writeln('/', VesaModeInfo.MemoryModel);
- Writeln('BankSize: ', VesaModeInfo.BankSize, ' KB');
- Writeln('NumberOfImagePages: ', VesaModeInfo.NumberOfImagePages);
- Writeln('Reserved(=1): ', VesaModeInfo.Reserved);
- Writeln('RedMaskSize: ', VesaModeInfo.RedMaskSize);
- Writeln('RedFieldPosition: ', VesaModeInfo.RedFieldPosition);
- Writeln('GreenMaskSize: ', VesaModeInfo.GreenMaskSize);
- Writeln('GreenFieldPosition: ', VesaModeInfo.GreenFieldPosition);
- Writeln('BlueMaskSize: ', VesaModeInfo.BlueMaskSize);
- Writeln('BlueFieldPosition: ', VesaModeInfo.BlueFieldPosition);
- Writeln('RsvdMaskSize: ', VesaModeInfo.RsvdMaskSize);
- Writeln('RsvdFieldPosition: ', VesaModeInfo.RsvdFieldPosition);
- Write('DirectColorModeInfo:');
- If (VesaModeInfo.DirectColorModeInfo And 1) <> 0 Then
- Write(' Color_ramp_is_programmable')
- Else
- Write(' Color_ramp_is_fixed');
- If (VesaModeInfo.DirectColorModeInfo And 2) <> 0 Then
- Write(' Rsvd_bits_usable_by_app')
- Else
- Write(' Rsvd_bits_reserved');
- Writeln;
- Writeln('vbe2.0+');
- Writeln('PhysBasePtr: $', HexStr(VesaModeInfo.PhysBasePtr, 8));
- Writeln('Reserved2(=0): ', VesaModeInfo.Reserved2);
- Writeln('Reserved3(=0): ', VesaModeInfo.Reserved3);
- Writeln;
- { Write(VesaModeInfo.XResolution, 'x', VesaModeInfo.YResolution, 'x',
- VesaModeInfo.BitsPerPixel, '-', VesaModeInfo.MemoryModel,
- 'R', VesaModeInfo.RedMaskSize, ':', VesaModeInfo.RedFieldPosition,
- 'G', VesaModeInfo.GreenMaskSize, ':', VesaModeInfo.GreenFieldPosition,
- 'B', VesaModeInfo.BlueMaskSize, ':', VesaModeInfo.BlueFieldPosition,
- 'A', VesaModeInfo.RsvdMaskSize, ':', VesaModeInfo.RsvdFieldPosition, ' ');}
- End;
- {$ENDIF DEBUGOUTPUT}
- {/display mode info}
- If (VesaModeInfo.ModeAttributes And 1) <> 0 Then
- Begin
- If (VesaModeInfo.ModeAttributes And 2) = 0 Then
- Begin
- If VBEInfoBlock.VBEVersion >= $0102 Then
- IsModeOk := False
- Else
- StandardMode(I, VesaModeInfo);
- End;
- ModeAttr := (VesaModeInfo.ModeAttributes And $C0) Shr 6;
- IsModeOk := True;
- If ModeAttr = 1 Then
- IsModeOk := False;
- If IsModeOk And ((ModeAttr = 0) Or (ModeAttr = 2)) Then
- Begin {check windowed}
- hasReadWindow := False;
- hasWriteWindow := False;
- If (VesaModeInfo.WinAAttributes And $01) <> 0 Then
- Begin
- If (VesaModeInfo.WinAAttributes And $02) <> 0 Then
- hasReadWindow := True;
- If (VesaModeInfo.WinAAttributes And $04) <> 0 Then
- hasWriteWindow := True;
- End;
- If (VesaModeInfo.WinBAttributes And $01) <> 0 Then
- Begin
- If (VesaModeInfo.WinBAttributes And $02) <> 0 Then
- hasReadWindow := True;
- If (VesaModeInfo.WinBAttributes And $04) <> 0 Then
- hasWriteWindow := True;
- End;
- If (Not hasReadWindow) Or (Not hasWriteWindow) Then
- IsModeOk := False;
- End;
- If IsModeOk And ((ModeAttr = 2) Or (ModeAttr = 3)) Then
- Begin {check lfb...}
- {...}
- End;
- If IsModeOk Then
- Begin
- // Write(HexStr(I, 4), ' ');
- AddToList;
- Inc(NrOfModes);
- Last^.ModeInfo.ModeNumber := I;
- Last^.ModeInfo.VesaModeInfo := VesaModeInfo;
- End;
- End;
- End;
- global_dos_free(AddrSel);
- If ModeInfo <> Nil Then
- FreeMem(ModeInfo);
- If NrOfModes <> -1 Then
- ModeInfo := GetMem((NrOfModes + 1) * SizeOf(TModeInfo))
- Else
- ModeInfo := Nil;
- Run := First;
- For I := 0 To NrOfModes Do
- Begin
- ModeInfo[I] := Run^.ModeInfo;
- Tmp := Run;
- Run := Run^.Next;
- Dispose(Tmp);
- End;
- {$IFDEF DEBUGOUTPUT}
- Writeln;
- {$ENDIF DEBUGOUTPUT}
- End;
- Procedure GetVBEInfo;
- Var
- Addr : DWord;
- AddrSeg : Word;
- AddrSel : Word;
- tmp : DWord;
- Begin
- Addr := global_dos_alloc(512);
- AddrSeg := Addr Shr 16;
- AddrSel := Addr And $FFFF;
- VBEInfoBlock.VBESignature := $32454256; {'VBE2'}
- dosmemput(AddrSeg, 0, VBEInfoBlock, 4);
- RealRegs.ax := $4F00;
- RealRegs.es := AddrSeg;
- RealRegs.di := 0;
- realintr($10, RealRegs);
- VBEPresent := RealRegs.al = $4F;
- If VBEPresent Then
- Begin
- dosmemget(AddrSeg, 0, VBEInfoBlock, SizeOf(VBEInfoBlock));
- {todo: check for 'VESA' id string}
- VideoMemory := VBEInfoBlock.TotalMemory * 64;
- EightBitDACSupported := (VBEInfoBlock.Capabilities And 1) <> 0;
- nonVGA := (VBEInfoBlock.Capabilities And 2) <> 0;
- SnowyRAMDAC := (VBEInfoBlock.Capabilities And 4) <> 0;
- StereoSignalingSupport := (VBEInfoBlock.Capabilities And 8) <> 0;
- StereoSignalingVesaEVC := (VBEInfoBlock.Capabilities And 16) <> 0;
- OEMString := GetRMString(VBEInfoBlock.OemStringPtr);
- If VBEInfoBlock.VBEVersion >= $0200 Then
- Begin
- OEMVendorName := GetRMString(VBEInfoBlock.OemVendorNamePtr);
- OEMProductName := GetRMString(VBEInfoBlock.OemProductNamePtr);
- OEMProductRev := GetRMString(VBEInfoBlock.OemProductRevPtr);
- OEMSoftwareRev := VBEInfoBlock.OemSoftwareRev;
- End
- Else
- Begin
- OEMVendorName := '';
- OEMProductName := '';
- OEMProductRev := '';
- OEMSoftwareRev := -1;
- End;
- End;
- global_dos_free(AddrSel);
- {$IFDEF DEBUGOUTPUT}
- If VBEPresent Then
- Begin
- Writeln('VBEVersion: ', bcd(VBEInfoBlock.VBEVersion Shr 8), '.', bcd(VBEInfoBlock.VBEVersion And $FF));
- Writeln('VideoMemory: ', VideoMemory, ' KB');
- Writeln('EightBitDACSupported: ', EightBitDACSupported);
- Writeln('nonVGA: ', nonVGA);
- Writeln('SnowyRAMDAC: ', SnowyRAMDAC);
- Writeln('StereoSignalingSupport: ', StereoSignalingSupport);
- If StereoSignalingSupport Then
- If StereoSignalingVesaEVC Then
- Writeln('Stereo signaling supported via VESA EVC connector')
- Else
- Writeln('Stereo signaling supported via external VESA stereo connector');
- If OEMString <> '' Then
- Writeln('OEMString: ', OEMString);
- If OEMVendorName <> '' Then
- Writeln('OEMVendorName: ', OEMVendorName);
- If OEMProductName <> '' Then
- Writeln('OEMProductName: ', OEMProductName);
- If OEMProductRev <> '' Then
- Writeln('OEMProductRev: ', OEMProductRev);
- If OEMSoftwareRev <> -1 Then
- Writeln('OEMSoftwareRev: ', bcd(OEMSoftwareRev Shr 8), '.', bcd(OEMSoftwareRev And $FF));
- Write('VideoModeList:');
- tmp := (VBEInfoBlock.VideoModePtr Shr 16) * 16 + (VBEInfoBlock.VideoModePtr And $FFFF);
- While MemW[tmp] <> $FFFF Do
- Begin
- Write(' $', HexStr(MemW[tmp], 4));
- Inc(tmp, 2);
- End;
- Writeln;
- Writeln;
- End;
- {$ENDIF DEBUGOUTPUT}
- End;
- Function SetVESAMode(M : Integer) : Boolean;
- Var
- ModeAttr : DWord;
- lLFBUsed : Boolean;
- lReadWindow, lWriteWindow : Integer;
- lReadWindowStart, lWriteWindowStart : Integer;
- lReadWindowAddress, lWriteWindowAddress : Integer;
- lWindowGranularity : DWord;
- lWindowSize, lWindowSizeG : DWord;
- Begin
- SetVESAMode := False;
- DisposeRealModePalette;
- ModeAttr := (ModeInfo[M].VesaModeInfo.ModeAttributes And $C0) Shr 6;
- Case ModeAttr Of
- 0 : lLFBUsed := False; {windowed frame buffer only}
- 2 : lLFBUsed := UseLFB; {both windowed and linear}
- 3 : lLFBUsed := True; {linear frame buffer only}
- End;
- If Not lLFBUsed Then
- Begin
- With ModeInfo[M].VesaModeInfo Do
- Begin
- lReadWindow := -1;
- lWriteWindow := -1;
- If (WinAAttributes And $01) <> 0 Then
- Begin
- If (WinAAttributes And $02) <> 0 Then
- lReadWindow := 0;
- If (WinAAttributes And $04) <> 0 Then
- lWriteWindow := 0;
- End;
- If (lReadWindow = -1) Or (lWriteWindow = -1) Then
- If (WinBAttributes And $01) <> 0 Then
- Begin
- If (lReadWindow = -1) And ((WinBAttributes And $02) <> 0) Then
- lReadWindow := 1;
- If (lWriteWindow = -1) And ((WinBAttributes And $04) <> 0) Then
- lWriteWindow := 1;
- End;
- Case lReadWindow Of
- -1 : Exit{err};
- 0 : lReadWindowAddress := WinASegment Shl 4;
- 1 : lReadWindowAddress := WinBSegment Shl 4;
- End;
- Case lWriteWindow Of
- -1 : Exit{err};
- 0 : lWriteWindowAddress := WinASegment Shl 4;
- 1 : lWriteWindowAddress := WinBSegment Shl 4;
- End;
- lWindowGranularity := WinGranularity * 1024;
- lWindowSize := WinSize * 1024;
- lWindowSizeG := lWindowSize Div lWindowGranularity;
- lWindowSize := lWindowSizeG * lWindowGranularity;
- End;
- End
- Else
- Begin
- {TODO: lfb}
- End;
- RealRegs.ax := $4F02;
- If lLFBUsed Then
- RealRegs.bx := ModeInfo[M].ModeNumber Or $4000
- Else
- RealRegs.bx := ModeInfo[M].ModeNumber;
- realintr($10, RealRegs);
- PaletteDACbits := 6;
- With ModeInfo[M].VesaModeInfo Do
- Begin
- If (BitsPerPixel = 8) And (MemoryModel = 4{packed pixel}) Then
- Begin
- SetPaletteHW := True;
- If (VBEInfoBlock.VBEVersion >= $200) And
- ((ModeAttributes And 32) <> 0) Then {if nonVGA, use func9 to set palette}
- SetPaletteHW := False;
- If EightBitDACSupported Then
- SwitchTo8bitDAC;
- If Not SetPaletteHW Then
- AllocateRealModePalette;
- End;
- End;
- LFBUsed := lLFBUsed;
- ReadWindow := lReadWindow;
- WriteWindow := lWriteWindow;
- ReadWindowStart := lReadWindowStart;
- WriteWindowStart := lWriteWindowStart;
- ReadWindowAddress := lReadWindowAddress;
- WriteWindowAddress := lWriteWindowAddress;
- WindowGranularity := lWindowGranularity;
- WindowSize := lWindowSize;
- WindowSizeG := lWindowSizeG;
- SetVESAMode := True;
- End;
- Procedure RestoreTextMode;
- Begin
- DisposeRealModePalette;
- RealRegs.ax := $0003;
- realintr($10, RealRegs);
- End;
- Procedure InitVESA;
- Begin
- If Not VESAInit Then
- VESAInit := True
- Else
- Exit;
- GetVBEInfo;
- If VBEPresent Then
- GetModes;
- End;
- Initialization
- VESAInit := False;
- CurrentMode := -1;
- UseLFB := {True}False;
- ModeInfo := Nil;
- RealModePaletteSel := 0;
- RealModePaletteSeg := 0;
- Finalization
- temp := ModeInfo;
- ModeInfo := Nil;
- If temp <> Nil Then
- FreeMem(temp);
- DisposeRealModePalette;
- End.
|