diff options
author | nickysn <nickysn@3ad0048d-3df7-0310-abae-a5850022a9f2> | 2013-10-06 13:39:10 +0000 |
---|---|---|
committer | nickysn <nickysn@3ad0048d-3df7-0310-abae-a5850022a9f2> | 2013-10-06 13:39:10 +0000 |
commit | d44678879db5bc9e2d40cbb96630e3ec9c0da214 (patch) | |
tree | 9c7e2b65770a5b2014f892f453fbc96fb8de02f9 /packages/graph | |
parent | 06da89d37d45037ea8ccd820b235f7fbc6259c83 (diff) | |
download | fpc-d44678879db5bc9e2d40cbb96630e3ec9c0da214.tar.gz |
+ enabled all the VESA code for the i8086-msdos graph unit
git-svn-id: http://svn.freepascal.org/svn/fpc/trunk@25687 3ad0048d-3df7-0310-abae-a5850022a9f2
Diffstat (limited to 'packages/graph')
-rw-r--r-- | packages/graph/src/msdos/graph.pp | 16 | ||||
-rw-r--r-- | packages/graph/src/msdos/vesa.inc | 822 |
2 files changed, 74 insertions, 764 deletions
diff --git a/packages/graph/src/msdos/graph.pp b/packages/graph/src/msdos/graph.pp index dac65cface..b1acb55267 100644 --- a/packages/graph/src/msdos/graph.pp +++ b/packages/graph/src/msdos/graph.pp @@ -48,10 +48,6 @@ CONST m1280x1024x32k = $119; m1280x1024x64k = $11A; -const - UseLFB : boolean = false; - UseNoSelector : boolean = false; - LFBPointer : pointer = nil; { Helpful variable to get save/restore support in IDE PM } const DontClearGraphMemory : boolean = false; @@ -3706,7 +3702,7 @@ const CrtAddress: word = 0; {$ifdef logging} LogLn('Setting RestoreVideoState to '+strf(longint(RestoreVideoState))); {$endif logging} -(* { now check all supported modes...} + { now check all supported modes...} if SearchVESAModes(m320x200x32k) then begin InitMode(mode); @@ -3818,7 +3814,7 @@ const CrtAddress: word = 0; mode.hline := {$ifdef fpc}@{$endif}HLineVESA256; mode.vline := {$ifdef fpc}@{$endif}VLineVESA256; mode.GetScanLine := {$ifdef fpc}@{$endif}GetScanLineVESA256; - mode.PatternLine := {$ifdef fpc}@{$endif}PatternLineVESA256; +// mode.PatternLine := {$ifdef fpc}@{$endif}PatternLineVESA256; mode.XAspect := 10000; mode.YAspect := 10000; AddMode(mode); @@ -3933,7 +3929,7 @@ const CrtAddress: word = 0; mode.hline := {$ifdef fpc}@{$endif}HLineVESA256; mode.vline := {$ifdef fpc}@{$endif}VLineVESA256; mode.GetScanLine := {$ifdef fpc}@{$endif}GetScanLineVESA256; - mode.PatternLine := {$ifdef fpc}@{$endif}PatternLineVESA256; +// mode.PatternLine := {$ifdef fpc}@{$endif}PatternLineVESA256; mode.XAspect := 10000; mode.YAspect := 10000; AddMode(mode); @@ -4048,7 +4044,7 @@ const CrtAddress: word = 0; mode.vline := {$ifdef fpc}@{$endif}VLineVESA256; mode.hline := {$ifdef fpc}@{$endif}HLineVESA256; mode.GetScanLine := {$ifdef fpc}@{$endif}GetScanLineVESA256; - mode.PatternLine := {$ifdef fpc}@{$endif}PatternLineVESA256; +// mode.PatternLine := {$ifdef fpc}@{$endif}PatternLineVESA256; mode.XAspect := 10000; mode.YAspect := 10000; AddMode(mode); @@ -4163,7 +4159,7 @@ const CrtAddress: word = 0; mode.vline := {$ifdef fpc}@{$endif}VLineVESA256; mode.hline := {$ifdef fpc}@{$endif}HLineVESA256; mode.GetScanLine := {$ifdef fpc}@{$endif}GetScanLineVESA256; - mode.PatternLine := {$ifdef fpc}@{$endif}PatternLineVESA256; +// mode.PatternLine := {$ifdef fpc}@{$endif}PatternLineVESA256; mode.XAspect := 10000; mode.YAspect := 10000; AddMode(mode); @@ -4219,7 +4215,7 @@ const CrtAddress: word = 0; mode.XAspect := 10000; mode.YAspect := 10000; AddMode(mode); - end;*) + end; end; end; diff --git a/packages/graph/src/msdos/vesa.inc b/packages/graph/src/msdos/vesa.inc index 9fe9ce323d..7c2f6e6aaf 100644 --- a/packages/graph/src/msdos/vesa.inc +++ b/packages/graph/src/msdos/vesa.inc @@ -64,16 +64,9 @@ var BankShift : word; { address to shift by when switching banks. } - { linear mode specific stuff } - InLinear : boolean; { true if in linear mode } - LinearPageOfs : longint; { offset used to set active page } - FrameBufferLinearAddress : longint; - ScanLines: word; { maximum number of scan lines for mode } -{//$IFDEF DPMI} - function getVESAInfo(var VESAInfo: TVESAInfo) : boolean; var st : string[4]; @@ -110,92 +103,25 @@ var {$endif logging} end; -(* function getVESAModeInfo(var ModeInfo: TVESAModeInfo;mode:word):boolean; + function getVESAModeInfo(var ModeInfo: TVESAModeInfo;mode:word):boolean; var - Ptr: longint; -{$ifndef fpc} - VESAPtr : ^TVESAModeInfo; -{$endif fpc} regs : Registers; - RealSeg: word; begin - { Alllocate real mode buffer } -{$ifndef fpc} - Ptr:=GlobalDosAlloc(sizeof(TVESAModeInfo)); - { get the selector value } - VESAPtr := pointer(longint(Ptr shl 16)); - if not assigned(VESAPtr) then - RunError(203); -{$else fpc} - Ptr:=Global_Dos_Alloc(sizeof(TVESAModeInfo)); -{$endif fpc} - { get the segment value } - RealSeg := word(Ptr shr 16); { we have to init everything to zero, since VBE < 1.1 } { may not setup fields correctly. } -{$ifndef fpc} - FillChar(VESAPtr^, sizeof(ModeInfo), #0); -{$else fpc} - DosMemFillChar(RealSeg, 0, sizeof(ModeInfo), #0); -{$endif fpc} - { setup interrupt registers } - FillChar(regs, sizeof(regs), #0); + FillChar(ModeInfo, sizeof(ModeInfo), #0); { call VESA mode information...} - regs.eax := $4f01; - regs.es := RealSeg; - regs.edi := $00; - regs.ecx := mode; - RealIntr($10, regs); - if word(regs.eax) <> $4f then + regs.ax := $4f01; + regs.es := Seg(ModeInfo); + regs.di := Ofs(ModeInfo); + regs.cx := mode; + Intr($10, regs); + if regs.ax <> $4f then getVESAModeInfo := FALSE else getVESAModeInfo := TRUE; - { copy to protected mode buffer ... } -{$ifndef fpc} - Move(VESAPtr^, ModeInfo, sizeof(ModeInfo)); -{$else fpc} - DosMemGet(RealSeg,0,ModeInfo,sizeof(ModeInfo)); -{$endif fpc} - { free real mode memory } -{$ifndef fpc} - GlobalDosFree(Word(Ptr and $ffff)); -{$else fpc} - If not Global_Dos_Free(Word(Ptr and $ffff)) then - RunError(216); -{$endif fpc} end; -{$ELSE} - function getVESAInfo(var VESAInfo: TVESAInfo) : boolean; assembler; - asm - mov ax,4F00h - les di,VESAInfo - int 10h - sub ax,004Fh {make sure we got 004Fh back} - cmp ax,1 - sbb al,al - cmp word ptr es:[di],'V'or('E'shl 8) {signature should be 'VESA'} - jne @@ERR - cmp word ptr es:[di+2],'S'or('A'shl 8) - je @@X - @@ERR: - mov al,0 - @@X: - end; - - - function getVESAModeInfo(var ModeInfo: TVESAModeInfo;mode:word):boolean;assembler; - asm - mov ax,4F01h - mov cx,mode - les di,ModeInfo - int 10h - sub ax,004Fh {make sure it's 004Fh} - cmp ax,1 - sbb al,al - end; - -{$ENDIF} function SearchVESAModes(mode: Word): boolean; {********************************************************} @@ -224,12 +150,6 @@ var { now check if the hardware supports it... } If ModeSupported then begin - { we have to init everything to zero, since VBE < 1.1 } - { may not setup fields correctly. } - { bugfix: for DPMI this is now done in GetVESAModeInfo } -{$IFNDEF DPMI} - FillChar(VESAModeInfo, sizeof(VESAModeInfo), #0); -{$ENDIF} If GetVESAModeInfo(VESAModeInfo, Mode) And ((VESAModeInfo.attr and modeAvail) <> 0) then ModeSupported := TRUE @@ -248,7 +168,7 @@ begin r.ax:=$4f05; r.bx:=win; r.dx:=BankNr; - RealIntr($10,r); + Intr($10,r); end; {********************************************************} @@ -934,7 +854,8 @@ end; end; end; - procedure PatternLineVESA256(x1,x2,y: smallint); {$ifndef fpc}far;{$endif fpc} +// disabled, causes an internal error on the i8086, TODO: fix +(* procedure PatternLineVESA256(x1,x2,y: smallint); {$ifndef fpc}far;{$endif fpc} {********************************************************} { Draws a horizontal patterned line according to the } { current Fill Settings. } @@ -1062,133 +983,8 @@ end; Until amount = 0; currentWriteMode := oldWriteMode; end; - - - {************************************************************************} - {* 256 colors VESA mode routines Linear mode *} - {************************************************************************} -{$ifdef FPC} -type - pbyte = ^byte; - pword = ^word; - - procedure DirectPutPixVESA256Linear(x, y : smallint); {$ifndef fpc}far;{$endif fpc} - var - offs : longint; - col : byte; - begin - offs := longint(y) * BytesPerLine + x; - Case CurrentWriteMode of - XorPut: - Begin - if UseNoSelector then - col:=pbyte(LFBPointer+offs+LinearPageOfs)^ - else - seg_move(WinWriteSeg,offs+LinearPageOfs,get_ds,longint(@col),1); - col := col xor byte(CurrentColor); - End; - AndPut: - Begin - if UseNoSelector then - col:=pbyte(LFBPointer+offs+LinearPageOfs)^ - else - seg_move(WinWriteSeg,offs+LinearPageOfs,get_ds,longint(@col),1); - col := col and byte(CurrentColor); - End; - OrPut: - Begin - if UseNoSelector then - col:=pbyte(LFBPointer+offs+LinearPageOfs)^ - else - seg_move(WinWriteSeg,offs+LinearPageOfs,get_ds,longint(@col),1); - col := col or byte(CurrentColor); - End - else - Begin - If CurrentWriteMode <> NotPut then - col := Byte(CurrentColor) - else col := Not(Byte(CurrentColor)); - End - End; - if UseNoSelector then - pbyte(LFBPointer+offs+LinearPageOfs)^:=col - else - seg_move(get_ds,longint(@col),WinWriteSeg,offs+LinearPageOfs,1); - end; - - procedure PutPixVESA256Linear(x, y : smallint; color : word); {$ifndef fpc}far;{$endif fpc} - var - offs : longint; - begin - X:= X + StartXViewPort; - Y:= Y + StartYViewPort; - { convert to absolute coordinates and then verify clipping...} - if ClipPixels then - Begin - if (X < StartXViewPort) or (X > (StartXViewPort + ViewWidth)) then - exit; - if (Y < StartYViewPort) or (Y > (StartYViewPort + ViewHeight)) then - exit; - end; - offs := longint(y) * BytesPerLine + x; - {$ifdef logging} - logln('putpix offset: '+hexstr(offs,8)+', color: '+strf(color)+', lpo: $'+ - hexstr(LinearPageOfs,8)); - {$endif logging} - if UseNoSelector then - pbyte(LFBPointer+offs+LinearPageOfs)^:=byte(color) - else - seg_move(get_ds,longint(@color),WinWriteSeg,offs+LinearPageOfs,1); - end; - - function GetPixVESA256Linear(x, y : smallint): word; {$ifndef fpc}far;{$endif fpc} - var - offs : longint; - col : byte; - begin - X:= X + StartXViewPort; - Y:= Y + StartYViewPort; - offs := longint(y) * BytesPerLine + x; - {$ifdef logging} - logln('getpix offset: '+hexstr(offs,8)+', lpo: $'+ - hexstr(LinearPageOfs,8)); - {$endif logging} - if UseNoSelector then - col:=pbyte(LFBPointer+offs+LinearPageOfs)^ - else - seg_move(WinWriteSeg,offs+LinearPageOfs,get_ds,longint(@col),1); - GetPixVESA256Linear:=col; - end; -(* -function SetVESADisplayStart(PageNum : word;x,y : smallint):Boolean; -var - dregs : registers; -begin - if PageNum>VesaModeInfo.NumberOfPages then - PageNum:=0; -{$ifdef DEBUG} - if PageNum>0 then - writeln(stderr,'Setting Display Page ',PageNum); -{$endif DEBUG} - dregs.RealEBX:=0{ $80 for Wait for retrace }; - dregs.RealECX:=x; - dregs.RealEDX:=y+PageNum*maxy; - dregs.RealSP:=0; - dregs.RealSS:=0; - dregs.RealEAX:=$4F07; RealIntr($10,dregs); - { idem as above !!! } - if (dregs.RealEAX and $1FF) <> $4F then - begin -{$ifdef DEBUG} - writeln(stderr,'Set Display start error'); -{$endif DEBUG} - SetVESADisplayStart:=false; - end - else - SetVESADisplayStart:=true; -end; *) -{$endif FPC} + {************************************************************************} @@ -1283,92 +1079,6 @@ end; End; end; -{$ifdef FPC} - {************************************************************************} - {* 15/16bit pixels VESA mode routines Linear mode *} - {************************************************************************} - - procedure PutPixVESA32kor64kLinear(x, y : smallint; color : word); {$ifndef fpc}far;{$endif fpc} - var - offs : longint; - begin - X:= X + StartXViewPort; - Y:= Y + StartYViewPort; - { convert to absolute coordinates and then verify clipping...} - if ClipPixels then - Begin - if (X < StartXViewPort) or (X > (StartXViewPort + ViewWidth)) then - exit; - if (Y < StartYViewPort) or (Y > (StartYViewPort + ViewHeight)) then - exit; - end; - offs := longint(y) * BytesPerLine + 2*x; - if UseNoSelector then - pword(LFBPointer+offs+LinearPageOfs)^:=color - else - seg_move(get_ds,longint(@color),WinWriteSeg,offs+LinearPageOfs,2); - end; - - function GetPixVESA32kor64kLinear(x, y : smallint): word; {$ifndef fpc}far;{$endif fpc} - var - offs : longint; - color : word; - begin - X:= X + StartXViewPort; - Y:= Y + StartYViewPort; - offs := longint(y) * BytesPerLine + 2*x; - if UseNoSelector then - color:=pword(LFBPointer+offs+LinearPageOfs)^ - else - seg_move(WinWriteSeg,offs+LinearPageOfs,get_ds,longint(@color),2); - GetPixVESA32kor64kLinear:=color; - end; - - procedure DirectPutPixVESA32kor64kLinear(x, y : smallint); {$ifndef fpc}far;{$endif fpc} - var - offs : longint; - col : word; - begin - offs := longint(y) * BytesPerLine + 2*x; - Case CurrentWriteMode of - XorPut: - Begin - if UseNoSelector then - col:=pword(LFBPointer+offs+LinearPageOfs)^ - else - seg_move(WinWriteSeg,offs+LinearPageOfs,get_ds,longint(@col),2); - col := col xor currentcolor; - End; - AndPut: - Begin - if UseNoSelector then - col:=pword(LFBPointer+offs+LinearPageOfs)^ - else - seg_move(WinWriteSeg,offs+LinearPageOfs,get_ds,longint(@col),2); - col := col and currentcolor; - End; - OrPut: - Begin - if UseNoSelector then - col:=pword(LFBPointer+offs+LinearPageOfs)^ - else - seg_move(WinWriteSeg,offs+LinearPageOfs,get_ds,longint(@col),2); - col := col or currentcolor; - End - else - Begin - If CurrentWriteMode <> NotPut Then - col := CurrentColor - Else col := Not(CurrentColor); - End - End; - if UseNoSelector then - pword(LFBPointer+offs+LinearPageOfs)^:=col - else - seg_move(get_ds,longint(@col),WinWriteSeg,offs+LinearPageOfs,2); - end; - -{$endif FPC} {************************************************************************} {* 4-bit pixels VESA mode routines *} @@ -1552,7 +1262,7 @@ end; else {the rest won't fit anymore in the current window } BankRest := $10000 - (ScrOfs and $ffff); {$ifndef tp} - seg_bytemove(dosmemselector,(WinReadSeg shl 4)+word(ScrOfs),dosmemselector,(WinWriteSeg shl 4)+word(ScrOfs),BankRest); + seg_bytemove(WinReadSeg,word(ScrOfs),WinWriteSeg,word(ScrOfs),BankRest); {$else} move(Ptr(WinReadSeg,word(ScrOfs))^, Ptr(WinWriteSeg,word(ScrOfs))^, BankRest); {$endif} @@ -1583,14 +1293,11 @@ end; {************************************************************************} -{$IFDEF DPMI} -{$ifdef fpc} Procedure SetVESARGBAllPalette(const Palette:PaletteType); var pal: array[0..255] of palrec; regs: Registers; - c, Ptr: longint; - RealSeg: word; + c: smallint; FunctionNr : byte; { use blankbit or normal RAMDAC programming? } begin if DirectColor then @@ -1617,27 +1324,16 @@ end; pal[c].blue := byte(palette.colors[c].blue); end; - { Alllocate real mode buffer } - Ptr:=Global_Dos_Alloc(sizeof(pal)); - {get the segment value} - RealSeg := word(Ptr shr 16); - { setup interrupt registers } - FillChar(regs, sizeof(regs), #0); { copy palette values to real mode buffer } - DosMemPut(RealSeg,0,pal,sizeof(pal)); - regs.eax := $4F09; - regs.ebx := FunctionNr; - regs.ecx := 256; - regs.edx := 0; - regs.es := RealSeg; - regs.edi := 0; { offset is always zero } - RealIntr($10, regs); - - { free real mode memory } - If not Global_Dos_Free(word(Ptr and $ffff)) then - RunError(216); - - if word(regs.eax) <> $004F then + regs.ax := $4F09; + regs.bx := FunctionNr; + regs.cx := 256; + regs.dx := 0; + regs.es := Seg(pal); + regs.di := Ofs(pal); + Intr($10, regs); + + if regs.ax <> $004F then begin _GraphResult := grError; exit; @@ -1650,18 +1346,12 @@ end; end; setallpalettedefault(palette); end; -{$endif fpc} Procedure SetVESARGBPalette(ColorNum, RedValue, GreenValue, BlueValue : smallint); var pal: palrec; regs: Registers; - Ptr: longint; -{$ifndef fpc} - PalPtr : ^PalRec; -{$endif fpc} - RealSeg: word; FunctionNr : byte; { use blankbit or normal RAMDAC programming? } begin if DirectColor then @@ -1686,43 +1376,15 @@ end; else FunctionNr := $00; - { Alllocate real mode buffer } -{$ifndef fpc} - Ptr:=GlobalDosAlloc(sizeof(palrec)); - { get the selector values } - PalPtr := pointer(Ptr shl 16); - if not assigned(PalPtr) then - RunError(203); -{$else fpc} - Ptr:=Global_Dos_Alloc(sizeof(palrec)); -{$endif fpc} - {get the segment value} - RealSeg := word(Ptr shr 16); - { setup interrupt registers } - FillChar(regs, sizeof(regs), #0); - { copy palette values to real mode buffer } -{$ifndef fpc} - move(pal, palptr^, sizeof(pal)); -{$else fpc} - DosMemPut(RealSeg,0,pal,sizeof(pal)); -{$endif fpc} - regs.eax := $4F09; - regs.ebx := FunctionNr; - regs.ecx := $01; - regs.edx := ColorNum; - regs.es := RealSeg; - regs.edi := 0; { offset is always zero } - RealIntr($10, regs); - - { free real mode memory } -{$ifndef fpc} - GlobalDosFree(word(Ptr and $ffff)); -{$else fpc} - If not Global_Dos_Free(word(Ptr and $ffff)) then - RunError(216); -{$endif fpc} + regs.ax := $4F09; + regs.bx := FunctionNr; + regs.cx := $01; + regs.dx := ColorNum; + regs.es := Seg(pal); + regs.di := Ofs(pal); + Intr($10, regs); - if word(regs.eax) <> $004F then + if regs.ax <> $004F then begin {$ifdef logging} logln('setvesargbpalette failed while directcolor = false!'); @@ -1743,12 +1405,7 @@ end; RedValue, GreenValue, BlueValue : smallint); var pal: PalRec; -{$ifndef fpc} - palptr : ^PalRec; -{$endif fpc} regs : Registers; - RealSeg: word; - ptr: longint; begin if DirectColor then Begin @@ -1761,44 +1418,15 @@ end; { use the set/get palette function } if VESAInfo.Version >= $0200 then Begin - { Alllocate real mode buffer } -{$ifndef fpc} - Ptr:=GlobalDosAlloc(sizeof(palrec)); - { get the selector value } - PalPtr := pointer(longint(Ptr and $0000ffff) shl 16); - if not assigned(PalPtr) then - RunError(203); -{$else fpc} - Ptr:=Global_Dos_Alloc(sizeof(palrec)); -{$endif fpc} - { get the segment value } - RealSeg := word(Ptr shr 16); - { setup interrupt registers } - FillChar(regs, sizeof(regs), #0); - - regs.eax := $4F09; - regs.ebx := $01; { get palette data } - regs.ecx := $01; - regs.edx := ColorNum; - regs.es := RealSeg; - regs.edi := 0; { offset is always zero } - RealIntr($10, regs); - - { copy to protected mode buffer ... } -{$ifndef fpc} - Move(PalPtr^, Pal, sizeof(pal)); -{$else fpc} - DosMemGet(RealSeg,0,Pal,sizeof(pal)); -{$endif fpc} - { free real mode memory } -{$ifndef fpc} - GlobalDosFree(word(Ptr and $ffff)); -{$else fpc} - If not Global_Dos_Free(word(Ptr and $ffff)) then - RunError(216); -{$endif fpc} - - if word(regs.eax) <> $004F then + regs.ax := $4F09; + regs.bx := $01; { get palette data } + regs.cx := $01; + regs.dx := ColorNum; + regs.es := Seg(pal); + regs.di := Ofs(pal); + Intr($10, regs); + + if regs.ax <> $004F then begin {$ifdef logging} logln('getvesargbpalette failed while directcolor = false!'); @@ -1816,265 +1444,11 @@ end; else GetVGARGBPalette(ColorNum, RedValue, GreenValue, BlueValue); end; -{$ELSE} - - Procedure SetVESARGBPalette(ColorNum, RedValue, GreenValue, - BlueValue : smallint); far; - var - FunctionNr : byte; { use blankbit or normal RAMDAC programming? } - pal: ^palrec; - Error : boolean; { VBE call error } - begin - if DirectColor then - Begin - _GraphResult := grError; - exit; - end; - Error := FALSE; - new(pal); - if not assigned(pal) then RunError(203); - pal^.align := 0; - pal^.red := byte(RedValue); - pal^.green := byte(GreenValue); - pal^.blue := byte(BlueValue); - { use the set/get palette function } - if VESAInfo.Version >= $0200 then - Begin - { check if blanking bit must be set when programming } - { the RAMDAC. } - if (VESAInfo.caps and attrSnowCheck) <> 0 then - FunctionNr := $80 - else - FunctionNr := $00; - asm - mov ax, 4F09h { Set/Get Palette data } - mov bl, [FunctionNr] { Set palette data } - mov cx, 01h { update one palette reg. } - mov dx, [ColorNum] { register number to update } - les di, [pal] { get palette address } - int 10h - cmp ax, 004Fh { check if success } - jz @noerror - mov [Error], TRUE - @noerror: - end; - if not Error then - Dispose(pal) - else - begin - _GraphResult := grError; - exit; - end; - end - else - { assume it's fully VGA compatible palette-wise. } - Begin - SetVGARGBPalette(ColorNum, RedValue, GreenValue, BlueValue); - end; - end; - - - - - Procedure GetVESARGBPalette(ColorNum: smallint; Var RedValue, GreenValue, - BlueValue : smallint); far; - var - Error: boolean; - pal: ^palrec; - begin - if DirectColor then - Begin - _GraphResult := grError; - exit; - end; - Error := FALSE; - new(pal); - if not assigned(pal) then RunError(203); - FillChar(pal^, sizeof(palrec), #0); - { use the set/get palette function } - if VESAInfo.Version >= $0200 then - Begin - asm - mov ax, 4F09h { Set/Get Palette data } - mov bl, 01h { Set palette data } - mov cx, 01h { update one palette reg. } - mov dx, [ColorNum] { register number to update } - les di, [pal] { get palette address } - int 10h - cmp ax, 004Fh { check if success } - jz @noerror - mov [Error], TRUE - @noerror: - end; - if not Error then - begin - RedValue := smallint(pal^.Red); - GreenValue := smallint(pal^.Green); - BlueValue := smallint(pal^.Blue); - Dispose(pal); - end - else - begin - _GraphResult := grError; - exit; - end; - end - else - GetVGARGBPalette(ColorNum, RedValue, GreenValue, BlueValue); - - end; -{$ENDIF} - - -(* -type - heaperrorproc=function(size:longint):smallint; - -Const - HeapErrorIsHooked : boolean = false; - OldHeapError : HeapErrorProc = nil; - DsLimit : dword = 0; - - function NewHeapError(size : longint) : smallint; - begin - set_segment_limit(get_ds,DsLimit); - NewHeapError:=OldHeapError(size); - DsLimit:=get_segment_limit(get_ds); - { The base of ds can be changed - we need to compute the address again PM } - LFBPointer:=pointer(FrameBufferLinearAddress-get_segment_base_address(get_ds)); - if dword(LFBPointer)+dword(VESAInfo.TotalMem shl 16)-1 > DsLimit then - set_segment_limit(get_ds,dword(LFBPointer)+dword(VESAInfo.TotalMem shl 16)-1); - end; - procedure HookHeapError; - begin - if HeapErrorIsHooked then - exit; - DsLimit:=get_segment_limit(get_ds); - OldHeapError:=HeapErrorProc(HeapError); - HeapError:=@NewHeapError; - HeapErrorIsHooked:=true; - end; - procedure UnHookHeapError; - begin - if not HeapErrorIsHooked then - exit; - LFBPointer:=nil; - set_segment_limit(get_ds,DsLimit); - HeapError:=OldHeapError; - HeapErrorIsHooked:=false; - end; -*) - - function SetupLinear(var ModeInfo: TVESAModeInfo;mode : word) : boolean; - begin - SetUpLinear:=false; - - if VESAInfo.Version >= $0300 then - BytesPerLine := VESAModeInfo.LinBytesPerScanLine - else - BytesPerLine := VESAModeInfo.BytesPerScanLine; - -{$ifdef FPC} - case mode of - m320x200x32k, - m320x200x64k, - m640x480x32k, - m640x480x64k, - m800x600x32k, - m800x600x64k, - m1024x768x32k, - m1024x768x64k, - m1280x1024x32k, - m1280x1024x64k : - begin - DirectPutPixel:=@DirectPutPixVESA32kor64kLinear; - PutPixel:=@PutPixVESA32kor64kLinear; - GetPixel:=@GetPixVESA32kor64kLinear; - { linear mode for lines not yet implemented PM } - HLine:=@HLineDefault; - VLine:=@VLineDefault; - GetScanLine := @GetScanLineDefault; - PatternLine := @PatternLineDefault; - end; - m640x400x256, - m640x480x256, - m800x600x256, - m1024x768x256, - m1280x1024x256: - begin - DirectPutPixel:=@DirectPutPixVESA256Linear; - PutPixel:=@PutPixVESA256Linear; - GetPixel:=@GetPixVESA256Linear; - { linear mode for lines not yet implemented PM } - HLine:=@HLineDefault; - VLine:=@VLineDefault; - GetScanLine := @GetScanLineDefault; - PatternLine := @PatternLineDefault; - end; - else - exit; - end; - FrameBufferLinearAddress:=Get_linear_addr(VESAModeInfo.PhysAddress and $FFFF0000, - VESAInfo.TotalMem shl 16); -{$ifdef logging} - logln('framebuffer linear address: '+hexstr(FrameBufferLinearAddress div (1024*1024),8)); - logln('total mem shl 16: '+strf(vesainfo.totalmem shl 16)); -{$endif logging} - if int31error<>0 then - begin -{$ifdef logging} - logln('Unable to get linear address for '+hexstr(VESAModeInfo.PhysAddress,8)); -{$endif logging} - writeln(stderr,'Unable to get linear address for ',hexstr(VESAModeInfo.PhysAddress,8)); - exit; - end; - if UseNoSelector then - begin -{ HookHeapError; } - LFBPointer:=pointer(FrameBufferLinearAddress-get_segment_base_address(get_ds)); - if dword(LFBPointer)+dword(VESAInfo.TotalMem shl 16)-1 > dword(get_segment_limit(get_ds)) then - set_segment_limit(get_ds,dword(LFBPointer)+dword(VESAInfo.TotalMem shl 16)-1); - end - else - begin - WinWriteSeg:=allocate_ldt_descriptors(1); -{$ifdef logging} - logln('writeseg1: '+hexstr(winwriteseg,8)); -{$endif logging} - set_segment_base_address(WinWriteSeg,FrameBufferLinearAddress); - set_segment_limit(WinWriteSeg,(VESAInfo.TotalMem shl 16)-1); - lock_linear_region(FrameBufferLinearAddress,(VESAInfo.TotalMem shl 16)); - if int31error<>0 then - begin -{$ifdef logging} - logln('Error in linear memory selectors creation'); -{$endif logging} - writeln(stderr,'Error in linear memory selectors creation'); - exit; - end; - end; - LinearPageOfs := 0; - InLinear:=true; - SetUpLinear:=true; - { WinSize:=(VGAInfo.TotalMem shl 16); - WinLoMask:=(VGAInfo.TotalMem shl 16)-1; - WinShift:=15; - Temp:=VGAInfo.TotalMem; - while Temp>0 do - begin - inc(WinShift); - Temp:=Temp shr 1; - end; } -{$endif FPC} - end; procedure SetupWindows(var ModeInfo: TVESAModeInfo); begin - InLinear:=false; - BytesPerLine := VESAModeInfo.BytesPerScanLine; { now we check the windowing scheme ...} @@ -2210,7 +1584,8 @@ Const if getVESAModeInfo(VESAmodeinfo, mode) then begin { checks if the hardware supports the video mode. } - if (VESAModeInfo.attr and modeAvail) = 0 then + if ((VESAModeInfo.attr and modeAvail) = 0) or + ((VESAModeInfo.Attr and ModeNoWindowed) <> 0) then begin SetVESAmode := FALSE; {$ifdef logging} @@ -2235,18 +1610,7 @@ Const ReadWindow := 0; WriteWindow := 0; - { VBE 2.0 and higher supports >= non VGA linear buffer types...} - { this is backward compatible. } - if (((VESAModeInfo.Attr and ModeNoWindowed) <> 0) or UseLFB) and - ((VESAModeInfo.Attr and ModeLinearBuffer) <> 0) then - begin - if not SetupLinear(VESAModeInfo,mode) then - SetUpWindows(VESAModeInfo); - end - else - { if linear and windowed is supported, then use windowed } - { method. } - SetUpWindows(VESAModeInfo); + SetUpWindows(VESAModeInfo); {$ifdef logging} LogLn('Entering vesa mode '+strf(mode)); @@ -2256,74 +1620,40 @@ Const LogLn('Window size: '+strf(VESAModeInfo.winSize)+'kb'); LogLn('Bytes per line: '+strf(bytesperline)); {$endif logging} - { Select the correct mode number if we're going to use linear access! } - if InLinear then - inc(mode,$4000); asm mov ax,4F02h mov bx,mode {$ifdef fpc} - push ebp - push esi - push edi - push ebx + push bp + push si + push di + push bx {$endif fpc} int 10h {$ifdef fpc} - pop ebx - pop edi - pop esi - pop ebp + pop bx + pop di + pop si + pop bp {$endif fpc} sub ax,004Fh cmp ax,1 sbb al,al mov res,al - end ['EBX','EAX']; + end ['BX','AX']; if not res then _GraphResult := GrNotDetected else _GraphResult := grOk; end; end; -(* - function getVESAMode:word;assembler; - asm {return -1 if error} - mov ax,4F03h -{$ifdef fpc} - push ebx - push ebp - push esi - push edi -{$endif fpc} - int 10h -{$ifdef fpc} - pop edi - pop esi - pop ebp -{$endif fpc} - cmp ax,004Fh - je @@OK - mov ax,-1 - jmp @@X - @@OK: - mov ax,bx - @@X: -{$ifdef fpc} - pop ebx -{$endif fpc} - end ['EAX']; -*) - {************************************************************************} {* VESA Modes inits *} {************************************************************************} -{$IFDEF DPMI} - {******************************************************** } { Function GetMaxScanLines() } {-------------------------------------------------------- } @@ -2335,27 +1665,12 @@ Const var regs : Registers; begin - FillChar(regs, sizeof(regs), #0); - { play it safe, call the real mode int, the 32-bit entry point } - { may not be defined as stated in VBE v3.0 } - regs.eax := $4f06; {_ setup function } - regs.ebx := $0001; { get scan line length } - RealIntr($10, regs); - GetMaxScanLines := (regs.edx and $0000ffff); + regs.ax := $4f06; {_ setup function } + regs.bx := $0001; { get scan line length } + Intr($10, regs); + GetMaxScanLines := regs.dx; end; -{$ELSE} - - function GetMaxScanLines: word; assembler; - asm - mov ax, 4f06h - mov bx, 0001h - int 10h - mov ax, dx - end; - -{$ENDIF} - procedure Init1280x1024x64k; {$ifndef fpc}far;{$endif fpc} begin SetVesaMode(m1280x1024x64k); @@ -2483,7 +1798,7 @@ Const ScanLines := GetMaxScanLines; end; -*) + Procedure SaveStateVESA; {$ifndef fpc}far;{$endif fpc} var @@ -2561,7 +1876,7 @@ Const end; end; -(* + {************************************************************************} {* VESA Page flipping routines *} @@ -2599,19 +1914,19 @@ Const mov cx, 0000h { pixel zero ! } mov dx, [NewStartVisible] { new scanline } {$ifdef fpc} - push ebp - push esi - push edi - push ebx + push bp + push si + push di + push bx {$endif} int 10h {$ifdef fpc} - pop ebx - pop edi - pop esi - pop ebp + pop bx + pop di + pop si + pop bp {$endif} - end ['EDX','ECX','EBX','EAX']; + end ['DX','CX','BX','AX']; end; procedure SetActiveVESA(page: word); {$ifndef fpc}far;{$endif fpc} @@ -2624,6 +1939,5 @@ Const exit; end; YOffset := (MaxY+1)*page; - LinearPageOfs := YOffset*(MaxX+1); end; -*) + |