home *** CD-ROM | disk | FTP | other *** search
- {$A+,F+,R-,S-,T-,V-,X+}
-
- {***********************************************}
- {* GIFVIDEO.PAS 1.0d *}
- {* Copyright (c) Steve Sneed 1991 *}
- {* All Rights Reserved *}
- {* *}
- {* Provided to TurboPower Software for their *}
- {* use or distribution with their products *}
- {***********************************************}
-
- {$IFNDEF Ver60}
- {$IFNDEF Ver70}
- !! FATAL: This unit requires TP6 or later !!
- {$ENDIF}
- {$ENDIF}
-
- unit GIFVideo; {basic video routines for example GIF decoder}
-
- {The following define controls whether SVGA capabilities are supported. If
- you don't have an SVGA card, undefining this conditional will save you some
- code and data space.}
-
- {$DEFINE UseSVGA}
-
- interface
-
- uses
- DOS,
- Dpmi,
- OpString,
- OpCrt,
- DeGIF;
-
- const
- UnitVers = '1.0d';
- UnitDate = '05-Jun-91';
-
- const
- DoDbl : Boolean = True;
- Use50Line : Boolean = False;
-
- const
- VGASele : Word = $A000;
- VidBIOSSele : Word = $C000;
-
- OldMode : Word = 3; {our starting text mode}
- OldFont8x8 : Boolean = False; {TRUE if in 8x8 font mode}
- GraphOn : Boolean = False; {TRUE when we are in a graphics vid mode}
- SVGAType : Integer = 0; {our type number for the SVGA chipset}
- VidChecked : Boolean = False; {TRUE after SVGAType checked at least once}
- VESAAvail : Boolean = False; {TRUE if a VESA driver is found}
- ViaBIOS : Boolean = False; {TRUE to use the BIOS for bankswitching}
- AllowEGAMode12 : Boolean = True; {set FALSE if your EGA can't do Mode $12}
-
- m360x480x256 = $F0; {special VGA "Mode X" identifier}
-
- {$IFDEF UseSVGA}
- const
- {consts for popular SVGA chipsets}
- vtEGAVGA = 0;
- vtCirrus = 1;
- vtEverex = 2;
- vtAcuMOS = 3;
- vtParadise = 4;
- vtTrident8800 = 5;
- vtTrident8900 = 6;
- vtTseng3000 = 7;
- vtTseng4000 = 8;
- vtAtiVGA = 9;
- vtAheadA = 10;
- vtAheadB = 11;
- vtOakTech = 12;
- vtVideo7 = 13;
- vtChipsTech = 14;
- vtGenoa = 15;
- vtNCR = 16;
- vtCompaq = 17;
- vtS3VGA = 18;
- vtVESA = 19;
-
- (* NOTE: Those types marked with {*} _require_ a VESA driver to be in use! *)
- SVGANames : Array[vtEGAVGA..vtVESA] of String[12] =
- ('Standard VGA',
- 'Cirrus', {*}
- 'Everex',
- 'AcuMOS',
- 'Paradise',
- 'Trident 8800',
- 'Trident 8900',
- 'Tseng 3000',
- 'Tseng 4000',
- 'VGA Wonder',
- 'Ahead "A"',
- 'Ahead "B"',
- 'Oak Tech.',
- 'Video 7',
- 'C & T',
- 'Genoa',
- 'NCR',
- 'Compaq', {*}
- 'S3 SVGA', {*}
- 'VESA driver');
-
- {internal consts for "typical" SVGA modes we support. These numbers were}
- {chosen because they do not conflict with any known BIOS mode numbers.}
- m640x400x256 = $F1;
- m640x480x256 = $F2;
- m800x600x16 = $F3;
- m800x600x256 = $F4;
- m1024x768x16 = $F5;
- m1024x768x256 = $F6;
- m1024x768x32768 = $F7;
- m1280x1024x16 = $F8;
- m1280x1024x256 = $F9;
- m1280x1024x32768 = $FA;
- {$ENDIF}
-
- type
- PlotLineProc = procedure(Y : Word); {proc ptr type for PlotLine to use}
-
- {$IFDEF UseSVGA}
- type
- {Our mode table record types}
- ModeRecord =
- record
- Index : Byte;
- ModeAX : Word;
- ModeBL : Byte;
- MaxC : Word;
- end;
- ModeTable = Array[1..6] of ModeRecord;
-
- type
- s80 = string[80];
- s8 = string[8];
-
- {types used in the VESA main records}
- ByteString = Array[0..3] of Byte;
- CharString = array[0..3] of Char;
- CharStringPtr = ^CharString;
-
- {pointer to a null-terminated list of words defining *all* modes the}
- {card supports, including text and non-VESA graphics modes. The}
- {VESA mode numbers will typically be the last ones in the list.}
- ModeListType = array[0..0] of Word;
- ModeListPtr = ^ModeListType;
-
- var
- VGAMem : Word;
- BkSize : Word;
- CurBk : Word;
-
- type
- {Record for basic VESA support info (VESA service $00)}
- VgaInfoBlockType =
- record
- VESASignature : CharString;
- VESAVersion : word;
- OEMStringPtr : CharStringPtr;
- Capabilities : ByteString;
- VideoModePtr : ModeListPtr;
- reserved : array[$00..$ED] of Byte; {Pad to 256}
- end;
-
- {pointer to a procedure that performs special memory paging. This}
- {proc may exist within the hardware BIOS or in the VESA driver, or}
- {it may be null and be used for other things.}
- PageFuncPtrType = Pointer;
-
- {Record containing information on a specific video mode. IMPORTANT:}
- {the card *must be in the requested mode* when VESA service $03 is}
- {called for this structure to be guaranteed to contain meaningful}
- {information!}
- ModeInfoBlockType =
- record
- {mandatory information}
- ModeAttributes : word;
- WinAAttributes : byte;
- WinBAttributes : byte;
- WinGranularity : word;
- WinSize : word;
- WinASegment : word;
- WinBSegment : word;
- WinFuncPtr : PageFuncPtrType;
- BytesPerScanLine : word;
- {optional information}
- XResolution : word;
- YResolution : word;
- XCharSize : byte;
- YCharSize : byte;
- NumberOfPlanes : byte;
- BitsPerPixel : byte;
- NumberOfBanks : byte;
- MemoryModel : byte;
- BankSize : byte;
- reserved : array[$00..$E2] of Byte; {Pad to 256}
- end;
-
-
- { NOTE: The following tables assume at least 512k video memory is on the }
- { supported card, with 1Mb on those that can handle it (Tseng 4000 and }
- { Trident 8900, Ahead B/5000, etc.) }
- const
- Tseng3000Table : ModeTable =
- ((Index : m640x400x256; ModeAX : $002d; ModeBL : $00; MaxC : 256),
- (Index : m640x480x256; ModeAX : $002e; ModeBL : $00; MaxC : 256),
- (Index : m800x600x16; ModeAX : $0029; ModeBL : $00; MaxC : 16),
- (Index : m800x600x256; ModeAX : $0030; ModeBL : $00; MaxC : 256),
- (Index : m1024x768x16; ModeAX : $0037; ModeBL : $00; MaxC : 16),
- (Index : 0; ModeAX : $0000; ModeBL : $00; MaxC : 0));
-
- Tseng4000Table : ModeTable =
- ((Index : m640x400x256; ModeAX : $002f; ModeBL : $00; MaxC : 256),
- (Index : m640x480x256; ModeAX : $002e; ModeBL : $00; MaxC : 256),
- (Index : m800x600x16; ModeAX : $0029; ModeBL : $00; MaxC : 16),
- (Index : m800x600x256; ModeAX : $0030; ModeBL : $00; MaxC : 256),
- (Index : m1024x768x16; ModeAX : $0037; ModeBL : $00; MaxC : 16),
- (Index : m1024x768x256; ModeAX : $0038; ModeBL : $00; MaxC : 256));
-
- TridentTable : ModeTable =
- ((Index : m640x400x256; ModeAX : $005c; ModeBL : $00; MaxC : 256),
- (Index : m640x480x256; ModeAX : $005d; ModeBL : $00; MaxC : 256),
- (Index : m800x600x16; ModeAX : $005b; ModeBL : $00; MaxC : 16),
- (Index : m800x600x256; ModeAX : $005e; ModeBL : $00; MaxC : 256),
- (Index : m1024x768x16; ModeAX : $005f; ModeBL : $00; MaxC : 16),
- (Index : 0; ModeAX : $0000; ModeBL : $00; MaxC : 0));
-
- Trident8900Table : ModeTable =
- ((Index : m640x400x256; ModeAX : $005c; ModeBL : $00; MaxC : 256),
- (Index : m640x480x256; ModeAX : $005d; ModeBL : $00; MaxC : 256),
- (Index : m800x600x16; ModeAX : $005b; ModeBL : $00; MaxC : 16),
- (Index : m800x600x256; ModeAX : $005e; ModeBL : $00; MaxC : 256),
- (Index : m1024x768x16; ModeAX : $005f; ModeBL : $00; MaxC : 16),
- (Index : m1024x768x256; ModeAX : $0062; ModeBL : $00; MaxC : 256));
-
- AheadTable : ModeTable =
- ((Index : m640x400x256; ModeAX : $0060; ModeBL : $00; MaxC : 256),
- (Index : m640x480x256; ModeAX : $0061; ModeBL : $00; MaxC : 256),
- (Index : m800x600x16; ModeAX : $006A; ModeBL : $00; MaxC : 16),
- (Index : m800x600x256; ModeAX : $0062; ModeBL : $00; MaxC : 256),
- (Index : m1024x768x16; ModeAX : $0074; ModeBL : $00; MaxC : 16),
- (Index : m1024x768x256; ModeAX : $0063; ModeBL : $00; MaxC : 256));
-
- AcuMOSTable : ModeTable =
- ((Index : m640x400x256; ModeAX : $0059; ModeBL : $00; MaxC : 256),
- (Index : m640x480x256; ModeAX : $005F; ModeBL : $00; MaxC : 256),
- (Index : m800x600x16; ModeAX : $0058; ModeBL : $00; MaxC : 16),
- (Index : m800x600x256; ModeAX : $005C; ModeBL : $00; MaxC : 256),
- (Index : m1024x768x16; ModeAX : $005D; ModeBL : $00; MaxC : 16),
- (Index : 0; ModeAX : $0000; ModeBL : $00; MaxC : 0));
-
- GenoaTable : ModeTable =
- ((Index : m640x400x256; ModeAX : $007E; ModeBL : $00; MaxC : 256),
- (Index : m640x480x256; ModeAX : $005C; ModeBL : $00; MaxC : 256),
- (Index : m800x600x16; ModeAX : $0079; ModeBL : $00; MaxC : 16),
- (Index : m800x600x256; ModeAX : $005E; ModeBL : $00; MaxC : 256),
- (Index : m1024x768x16; ModeAX : $005F; ModeBL : $00; MaxC : 16),
- (Index : 0; ModeAX : $0000; ModeBL : $00; MaxC : 0));
-
- NCRTable : ModeTable =
- ((Index : m640x400x256; ModeAX : $005E; ModeBL : $00; MaxC : 256),
- (Index : m640x480x256; ModeAX : $005F; ModeBL : $00; MaxC : 256),
- (Index : m800x600x16; ModeAX : $0058; ModeBL : $00; MaxC : 16),
- (Index : m800x600x256; ModeAX : $005C; ModeBL : $00; MaxC : 256),
- (Index : m1024x768x16; ModeAX : $005D; ModeBL : $00; MaxC : 16),
- (Index : 0; ModeAX : $0000; ModeBL : $00; MaxC : 0));
-
- OakTable : ModeTable =
- ((Index : m640x400x256; ModeAX : $0051; ModeBL : $00; MaxC : 256),
- (Index : m640x480x256; ModeAX : $0053; ModeBL : $00; MaxC : 256),
- (Index : m800x600x16; ModeAX : $0052; ModeBL : $00; MaxC : 16),
- (Index : m800x600x256; ModeAX : $0054; ModeBL : $00; MaxC : 256),
- (Index : m1024x768x16; ModeAX : $0056; ModeBL : $00; MaxC : 16),
- (Index : m1024x768x256; ModeAX : $0058; ModeBL : $00; MaxC : 256));
-
- ATITable : ModeTable =
- ((Index : m640x400x256; ModeAX : $0061; ModeBL : $00; MaxC : 256),
- (Index : m640x480x256; ModeAX : $0062; ModeBL : $00; MaxC : 256),
- (Index : m800x600x16; ModeAX : $0054; ModeBL : $00; MaxC : 16),
- (Index : m800x600x256; ModeAX : $0063; ModeBL : $00; MaxC : 256),
- (Index : m1024x768x16; ModeAX : $0065; ModeBL : $00; MaxC : 16),
- (Index : 0; ModeAX : $0000; ModeBL : $00; MaxC : 0));
-
- ChipsTechTable : ModeTable =
- ((Index : m640x400x256; ModeAX : $0078; ModeBL : $00; MaxC : 256),
- (Index : m640x480x256; ModeAX : $0079; ModeBL : $00; MaxC : 256),
- (Index : m800x600x16; ModeAX : $0070; ModeBL : $00; MaxC : 16),
- (Index : m800x600x256; ModeAX : $007b; ModeBL : $00; MaxC : 256),
- (Index : m1024x768x16; ModeAX : $0072; ModeBL : $00; MaxC : 16),
- (Index : 0; ModeAX : $0000; ModeBL : $00; MaxC : 0));
-
- ParadiseTable : ModeTable =
- ((Index : m640x400x256; ModeAX : $005e; ModeBL : $00; MaxC : 256),
- (Index : m640x480x256; ModeAX : $005f; ModeBL : $00; MaxC : 256),
- (Index : m800x600x16; ModeAX : $0058; ModeBL : $00; MaxC : 16),
- (Index : m800x600x256; ModeAX : $005C; ModeBL : $00; MaxC : 256),
- (Index : m1024x768x16; ModeAX : $005d; ModeBL : $00; MaxC : 16),
- (Index : 0; ModeAX : $0000; ModeBL : $00; MaxC : 0));
-
- EverexTable : ModeTable =
- ((Index : m640x400x256; ModeAX : $0070; ModeBL : $14; MaxC : 256),
- (Index : m640x480x256; ModeAX : $0070; ModeBL : $30; MaxC : 256),
- (Index : m800x600x16; ModeAX : $0070; ModeBL : $02; MaxC : 16),
- (Index : m800x600x256; ModeAX : $0070; ModeBL : $31; MaxC : 256),
- (Index : m1024x768x16; ModeAX : $0070; ModeBL : $20; MaxC : 16),
- (Index : m1024x768x256; ModeAX : $0070; ModeBL : $32; MaxC : 256));
-
- Video7Table : ModeTable =
- ((Index : m640x400x256; ModeAX : $6f05; ModeBL : $66; MaxC : 256),
- (Index : m640x480x256; ModeAX : $6f05; ModeBL : $67; MaxC : 256),
- (Index : m800x600x16; ModeAX : $6f05; ModeBL : $62; MaxC : 16),
- (Index : m800x600x256; ModeAX : $6f05; ModeBL : $69; MaxC : 256),
- (Index : m1024x768x16; ModeAX : $6f05; ModeBL : $65; MaxC : 16),
- (Index : m1024x768x256; ModeAX : $6f05; ModeBL : $6A; MaxC : 256));
-
- VESATable : ModeTable =
- ((Index : m640x400x256; ModeAX : $0100; ModeBL : $00; MaxC : 256),
- (Index : m640x480x256; ModeAX : $0101; ModeBL : $00; MaxC : 256),
- (Index : m800x600x16; ModeAX : $0102; ModeBL : $00; MaxC : 16),
- (Index : m800x600x256; ModeAX : $0103; ModeBL : $00; MaxC : 256),
- (Index : m1024x768x16; ModeAX : $0104; ModeBL : $00; MaxC : 16),
- (Index : m1024x768x256; ModeAX : $0105; ModeBL : $00; MaxC : 256));
-
- var
- VESAModeList : Array[0..7] of Word; {table for available VESA modes}
- ModeList : ModeTable; {our selected mode table}
- VesaVgaInfo : VgaInfoBlockType;
- VesaModeInfo : ModeInfoBlockType;
- {$ENDIF}
-
- var
- SelMode : Byte; {our selected video mode}
- {LeftEdge : Integer;} {leftmost pixel of image (0-based)}
- {RightEdge : Integer;} {rightmost pixel of image}
- TopEdge : Integer; {topmost raster line of image (0-based)}
- BotEdge : Integer; {lowest raster line in image}
- Raster : Integer; {number of scanlines in selected mode}
- Pixels : Integer; {width in pixels of selected mode}
- PlotLine : PlotLineProc; {our pointer to PlotLine for mode}
- YCord : Word; {the current raster line to plot}
-
- type
- {EGA/VGA palette needs}
- VGAPalRec =
- record
- Red,Grn,Blu : Byte;
- end;
-
- VGAPalType = Array[0..255] of VGAPalRec; {array of RGB triplets for DAC}
- EGAPalType = Array[0..16] of Byte; {include border register}
-
- const
- DefEGAPal : EGAPalType = {the default EGA palette}
- ($00,$01,$02,$03,$04,$05,$14,$07,$38,$39,$3A,$3B,$3C,$3D,$3E,$3F,$00);
-
- var
- VGAPalette : VGAPalType;
- EGAPalette : EGAPalType;
- UniqueCols : Integer;
-
- procedure DoMapping;
- {-convert a GIF 24-bit color map to a useable form}
-
- procedure SetDefMap;
- {-set a default map when none is in the image}
-
- {$IFDEF UseSVGA}
- procedure DetectSVGAType(CheckHW : Boolean);
- {-detect whether VESA driver is installed}
- {$ENDIF}
-
- procedure AdjustPalette(Mode : Byte);
- {-set hardware palette to match image and mode}
-
- procedure SetGraphicsMode(Mode : Byte);
- {-select graphics mode}
-
- procedure SetTextMode;
- {-restore text mode}
-
- function SelectMode(X,Y : Word) : Byte;
- {-select mode to use based on image dimensions}
-
- implementation
-
- var
- EGABytesPerLine : Integer; {used by EGA plotting routine}
- BankSize : Word;
-
- const
- First : Boolean = False;
- RetVal : Integer = 0;
- BankAdr : Word = 0;
-
-
- {------------------------}
- { Color mapping services }
- {------------------------}
-
- FUNCTION PaletteValue(I : Integer) : Byte;
- {-return the 6-bit (EGA) color for the I'th VGA colormap entry}
- VAR B, GI : Byte;
- begin
- with TempMap do begin
- GI := $00;
- B := Map[I, RedVal];
- case B of
- $C0..$FF:
- GI := GI or $24; {100100b} {high-intensity}
- $80..$BF:
- GI := GI or $04; {000100b} {low-intensity}
- $40..$7F:
- GI := GI or $20; {100000b} {medium-intensity}
- end;
-
- B := Map[I, GreenVal];
- case B of
- $C0..$FF:
- GI := GI or $12; {010010b}
- $80..$BF:
- GI := GI or $02; {000010b}
- $40..$7F:
- GI := GI or $10; {010000b}
- end;
-
- B := Map[I, BlueVal];
- case B of
- $C0..$FF:
- GI := GI or $09; {001001b}
- $80..$BF:
- GI := GI or $01; {000001b}
- $40..$7F:
- GI := GI or $08; {001000b}
- end;
-
- PaletteValue := GI;
- end
- end;
-
- procedure DoMapping;
- {-perform color mapping/conversion}
- var
- Temp,I,J,K,GI : byte;
- EGATemp,Votes : array[0..63] of byte;
-
- procedure SetColorA(I : Integer);
- var
- N : Integer;
- J : Integer;
- begin
- {find the nearest EGA color for the color number}
- GI := PaletteValue(I);
- for J := 1 to 4 do begin
- {walk thru the palette, looking for a match}
- for N := 0 to 15 do
- if GI = EGAPalette[n] then begin
- {match found, set Color[] and leave}
- Color[i] := N;
- exit;
- end;
- {match not found, move to next related color and try again}
- GI := (GI + 16) mod 64
- end;
- {should never get here, but just in case we set the color to the
- previous slot's value}
- Color[i] := Color[i-1];
- end;
-
- procedure ExchangeBytes(var B1, B2 : Byte);
- var
- B3 : Byte;
- begin
- B3 := B1;
- B1 := B2;
- B2 := B3;
- end;
-
- begin
- EGAPalette := DefEGAPal;
- TempMap := Maps[CurMap];
- with TempMap do begin
- {initialize the VGA palette}
- for I := 0 to HighColorNum do begin
- VGAPalette[I].Red := Map[I,RedVal] SHR 2;
- VGAPalette[I].Grn := Map[I,GreenVal] SHR 2;
- VGAPalette[I].Blu := Map[I,BlueVal] SHR 2;
- Color[I] := I;
- end;
-
- if MaxColors < 256 then begin
- if HighColorNum > 15 then begin
- {more colors than will fit in the palette; we have to perform
- color reduction.}
-
- {init important vars}
- for I := 0 to 63 do begin
- Votes[i] := 0;
- EGATemp[i] := i;
- end;
-
- {First find which of the 64 EGA colors is most popular...}
- for I := 0 to HighColorNum do begin
- GI := PaletteValue(I);
- inc(Votes[GI]);
- end;
-
- {sort the votes; put the top 16 in the palette}
- for I := 0 to 15 do begin
- for J := I to 63 do begin
- if Votes[j] > Votes[i] then begin
- ExchangeBytes(Votes[j], Votes[i]);
- ExchangeBytes(EGATemp[j], EGATemp[i]);
- end;
- end;
- end;
-
- {load the palette}
- Move(EGATemp, EGAPalette, 16);
-
- {finally, set up Color[] to work with the palette}
- for I := 0 to HighColorNum do
- SetColorA(I);
- end
- else begin
- {16 colors or less, just set things up equally}
- for I := 0 to HighColorNum do begin
- EGAPalette[I] := PaletteValue(I);
- Color[I] := I;
- end;
- end;
- end;
- end;
- end;
-
- procedure SetDefMap;
- {-assign default map. There is no defined default map in the spec, but}
- { this method matches that used by many decoders.}
- var i : byte;
- begin
- with Maps[CurMap] do
- for i := 0 to HighColorNum do
- Color[i] := i MOD succ(HighColorNum);
- end;
-
- {----------------------}
- { SVGA detect routines }
- {----------------------}
-
- {$IFDEF UseSVGA}
-
- procedure AdjustVESATable;
- {-adjusts the VESA modestable to reflect actual VESA modes supported}
- var
- W : Word;
- B : Array[0..5] of Boolean;
- begin
- FillChar(B,SizeOf(B),0);
- with VesaVgaInfo do begin
- {walk thru modeslist looking for VESA entry types ($100..$105)}
- W := 0;
- while (W < 100) and
- {$IFDEF Dpmi}
- (VideoModePtr <> nil) and
- {$ENDIF}
- (VideoModePtr^[W] <> $FFFF) do begin
- if (VideoModePtr^[W] >= $100) and (VideoModePtr^[W] < $106) then
- B[VideoModePtr^[W] - $100] := True;
- Inc(W);
- end;
- {now walk thru boolean array setting table to match}
- for W := 0 to 5 do
- if NOT(B[w]) then
- ModeList[w+1].Index := 0;
- end;
- end;
-
- procedure Cirrus; near; Assembler;
- asm
- mov dx,3d4h
- mov al,0ch
- out dx,al
- inc dx
- mov ah,al
- in al,dx
- xchg ah,al
- push ax
- push dx
- xor al,al
- out dx,al
-
- mov al,1fh
- dec dx
- out dx,al
- inc dx
- in al,dx
- mov bh,al
-
- mov cl,4
- mov dx,3c4h
- mov bl,6
-
- ror bh,cl
- mov ax,bx
- out dx,ax
- inc dx
- in al,dx
- or al,al
- jnz @@exit
-
- ror bh,cl
- dec dx
- mov ax,bx
- out dx,ax
- inc dx
- in al,dx
- cmp al,1
- jne @@exit
- mov [svgatype],vtCirrus
-
- @@exit:
- pop dx
- dec dx
- pop ax
- out dx,ax
- end;
-
-
- procedure NewBank; far; Assembler;
- asm
- push cx
- mov cx,[svgatype]
- cmp cx,vtVESA
- je @@_vesa
- cmp cx,vtTseng4000
- je @@_tseng4
- cmp cx,vtTseng3000
- je @@_tseng
- cmp cx,vtTrident8800
- je @@_trident
- cmp cx,vtTrident8900
- je @@_trident
- cmp cx,vtS3Vga
- je @@_s3vga
- cmp cx,vtATIVGA
- je @@_ativga
- cmp cx,vtacumos
- je @@_acumos
- cmp cx,vtParadise
- je @@_paradise
- cmp cx,vtVideo7
- je @@_video7
- cmp cx,vtCompaq
- je @@_compaq
- cmp cx,vtGenoa
- je @@_genoa
- cmp cx,vtChipsTech
- je @@_chipstech
- cmp cx,vtAheadA
- je @@_aheada
- cmp cx,vtAheadB
- je @@_aheadb
- cmp cx,vtNCR
- je @@_ncr
- cmp cx,vtEverex
- je @@_everex
- cmp cx,vtOakTech
- je @@_oaktech
- jmp @@_nobank
-
- @@_tseng:
- push ax
- push dx
- cli
- mov [curbk],ax
- and al,7
- mov ah,al
- shl al,1
- shl al,1
- shl al,1
- or al,ah
- or al,01000000b
- mov dx,3cdh
- out dx,al
- sti
- pop dx
- pop ax
- jmp @@alldone
-
-
- @@_tseng4:
- push ax
- push dx
- cli
- mov [curbk],ax
- mov ah,al
- mov dx,3bfh
- mov al,3
- out dx,al
- mov dl,0d8h
- mov al,0a0h
- out dx,al
- and ah,15
- mov al,ah
- shl al,1
- shl al,1
- shl al,1
- shl al,1
- or al,ah
- mov dl,0cdh
- out dx,al
- sti
- pop dx
- pop ax
- jmp @@alldone
-
-
- @@_trident:
- push ax
- push dx
- push ax
- cli
- mov [curbk],ax
- mov dx,3ceh
- mov al,6
- out dx,al
- inc dl
- in al,dx
- dec dl
- or al,4
- mov ah,al
- mov al,6
- out dx,ax
-
- mov dl,0c4h
- mov al,0bh
- out dx,al
- inc dl
- in al,dx
- dec dl
-
- pop ax
- mov ah,al
- xor ah,2
- mov dx,3c4h
- mov al,0eh
- out dx,ax
- sti
- pop dx
- pop ax
- jmp @@alldone
-
-
- @@_video7:
- push ax
- push dx
- push cx
- cli
- mov [curbk],ax
- and ax,15
- mov ch,al
- mov dx,3c4h
- mov ax,0ea06h
- out dx,ax
- mov ah,ch
- and ah,1
- mov al,0f9h
- out dx,ax
- mov al,ch
- and al,1100b
- mov ah,al
- shr ah,1
- shr ah,1
- or ah,al
- mov al,0f6h
- out dx,al
- inc dx
- in al,dx
- dec dx
- and al,not 1111b
- or ah,al
- mov al,0f6h
- out dx,ax
- mov ah,ch
- mov cl,4
- shl ah,cl
- and ah,100000b
- mov dl,0cch
- in al,dx
- mov dl,0c2h
- and al,not 100000b
- or al,ah
- out dx,al
- sti
- pop cx
- pop dx
- pop ax
- jmp @@alldone
-
-
- @@_paradise:
- push ax
- push dx
- push ax
- cli
- mov [curbk],ax
- mov dx,3ceh
- mov ax,50fh
- out dx,ax
- pop ax
- mov ah,al
- mov al,9
- out dx,ax
- sti
- pop dx
- pop ax
- jmp @@alldone
-
- @@_acumos:
- push ax
- push dx
- push ax
- cli
- mov [curbk],ax
- mov dx,3c4h
- mov ax,1206h
- out dx,ax
- mov dx,3ceh
- pop ax
- mov ah,al
- mov al,9
- out dx,ax
- sti
- pop dx
- pop ax
- jmp @@alldone
-
-
- @@_chipstech:
- push ax
- push dx
- push ax
- cli
- mov [curbk],ax
- mov dx,46e8h
- mov ax,1eh
- out dx,ax
- mov dx,103h
- mov ax,0080h
- out dx,ax
- mov dx,46e8h
- mov ax,0eh
- out dx,ax
- pop ax
- mov ah,al
- mov al,10h
- mov dx,3d6h
- out dx,ax
- sti
- pop dx
- pop ax
- jmp @@alldone
-
-
- @@_ativga:
- push ax
- push dx
- cli
- mov [curbk],ax
- mov ah,al
- mov dx,1ceh
- mov al,0b2h
- out dx,al
- inc dl
- in al,dx
- shl ah,1
- and al,0e1h
- or ah,al
- mov al,0b2h
- dec dl
- out dx,ax
- sti
- pop dx
- pop ax
- jmp @@alldone
-
-
- @@_everex:
- push ax
- push dx
- push cx
- cli
- mov [curbk],ax
- mov cl,al
- mov dx,3c4h
- mov al,8
- out dx,al
- inc dl
- in al,dx
- dec dl
- shl al,1
- shr cl,1
- rcr al,1
- mov ah,al
- mov al,8
- out dx,ax
- mov dl,0cch
- in al,dx
- mov dl,0c2h
- and al,0dfh
- shr cl,1
- jc @@nob2
- or al,20h
- @@nob2:
- out dx,al
- sti
- pop cx
- pop dx
- pop ax
- jmp @@alldone
-
-
- @@_aheada:
- push ax
- push dx
- push cx
- cli
- mov [curbk],ax
- mov ch,al
- mov dx,3ceh
- mov ax,200fh
- out dx,ax
- mov dl,0cch
- in al,dx
- mov dl,0c2h
- and al,11011111b
- shr ch,1
- jnc @@skpa
- or al,00100000b
- @@skpa:
- out dx,al
- mov dl,0cfh
- mov al,0
- out dx,al
- inc dx
- in al,dx
- dec dx
- and al,11111000b
- or al,ch
- mov ah,al
- mov al,0
- out dx,ax
- sti
- pop cx
- pop dx
- pop ax
- jmp @@alldone
-
-
- @@_aheadb:
- push ax
- push dx
- push cx
- cli
- mov [curbk],ax
- mov ch,al
- mov dx,3ceh
- mov ax,200fh
- out dx,ax
- mov ah,ch
- mov cl,4
- shl ah,cl
- or ah,ch
- mov al,0dh
- out dx,ax
- sti
- pop cx
- pop dx
- pop ax
- jmp @@alldone
-
-
- @@_oaktech:
- push ax
- push dx
- cli
- mov [curbk],ax
- and al,15
- mov ah,al
- shl al,1
- shl al,1
- shl al,1
- shl al,1
- or ah,al
- mov al,11h
- mov dx,3deh
- out dx,ax
- sti
- pop dx
- pop ax
- jmp @@alldone
-
- @@_genoa:
- push ax
- push dx
- cli
- mov [curbk],ax
- mov ah,al
- shl al,1
- shl al,1
- shl al,1
- or ah,al
- mov al,6
- or ah,40h
- mov dx,3c4h
- out dx,ax
- sti
- pop dx
- pop ax
- jmp @@alldone
-
- @@_ncr:
- push ax
- push dx
- cli
- mov [curbk],ax
- mov ah,al
- mov al,18h
- mov dx,3c4h
- out dx,ax
- mov ax,19h
- out dx,ax
- sti
- pop dx
- pop ax
- jmp @@alldone
-
- @@_compaq:
- push ax
- push dx
- push ax
- cli
- mov [curbk],ax
- mov dx,3ceh
- mov ax,50fh
- out dx,ax
- pop ax
- mov ah,al
- mov al,45h
- out dx,ax
- sti
- pop dx
- pop ax
- jmp @@alldone
-
- @@_s3vga:
- push ax
- push dx
- cli
- mov [curbk],ax
- sti
- pop dx
- pop ax
- jmp @@alldone
-
- @@_vesa:
- push ax
- cli
- mov [curbk],ax
- mov dx,ax
- xor bx,bx
- mov ax,4f05h
- push bp
- int 10h
- pop bp
- sti
- pop ax
- jmp @@alldone
-
- @@_nobank:
- cli
- mov [curbk],ax
- sti
- @@alldone:
- pop cx
- end;
-
- procedure GoChk; near; Assembler;
- asm
- push si
- mov si,bx
-
- mov al,cl
- call NewBank
- xchg bl,es:[di]
- mov al,ch
- call NewBank
- xchg bh,es:[di]
-
- xchg si,bx
-
- mov al,cl
- call NewBank
- xor bl,es:[di]
- mov al,ch
- call NewBank
- xor bh,es:[di]
-
- xchg si,bx
-
- mov al,ch
- call NewBank
- mov es:[di],bh
- mov al,cl
- call NewBank
- mov es:[di],bl
-
- mov al,0
- call NewBank
- or si,si
- pop si
- end;
-
- procedure ChkBk; near; Assembler;
- asm
- mov di,[SegB800]
- mov es,di
- xor di,di
- mov bx,1234h
- call gochk
- jnz @@badchk
- mov bx,4321h
- call gochk
- jnz @@badchk
- clc
- jmp @@goodchk
- @@badchk:
- stc
- @@goodchk:
- end;
-
- procedure IsPort2; near; Assembler;
- asm
- push bx
- mov bx,ax
- out dx,al
- mov ah,al
- inc dx
- in al,dx
- dec dx
- xchg al,ah
- push ax
- mov ax,bx
- out dx,ax
- out dx,al
- mov ah,al
- inc dx
- in al,dx
- dec dx
- and al,bh
- cmp al,bh
- jnz @@noport
- mov al,ah
- mov ah,0
- out dx,ax
- out dx,al
- mov ah,al
- inc dx
- in al,dx
- dec dx
- and al,bh
- cmp al,0
- @@noport:
- pop ax
- out dx,ax
- pop bx
- end;
-
- procedure IsPort1; near; Assembler;
- asm
- mov ah,al
- in al,dx
- push ax
- mov al,ah
- out dx,al
- in al,dx
- and al,ah
- cmp al,ah
- jnz @@noport
- mov al,0
- out dx,al
- in al,dx
- and al,ah
- cmp al,0
- @@noport:
- pop ax
- out dx,al
- end;
-
- procedure WhichVGA; Assembler;
- asm
- push bp
- push ax
- push bx
- push cx
- push dx
- push di
- push si
- push es
- cmp [first],1
- jb @@gotest
- mov ax,[retval]
- mov [svgatype],ax
- jmp @@skipout
-
- @@gotest:
- mov [first],1
- mov [vgamem],256
- mov [bksize],64
- mov [vesaavail],0
- xor ax,ax
- mov [svgatype],ax
-
- mov ax,ds
- mov es,ax
- lea di,VESAVgaInfo
- mov ax,4f00h
- push bp
- int 10h
- pop bp
- cmp ax,4fh
- jnz @@novesa
- mov [svgatype],vtVESA
- mov [vesaavail],1
- mov [bksize],64
-
- @@novesa:
- mov ax,[VidBIOSSele]
- mov es,ax
- cmp word ptr es:[40h],'13'
- jnz @@noati
- mov [svgatype],vtATIVGA
- mov [bksize],64
- mov dx,es:[10h]
- mov bl,es:[43h]
- cmp bl,'3'
- jae @@v6up
- mov al,0bbh
- cli
- out dx,al
- inc dx
- in al,dx
- sti
- test al,20h
- jz @@no512
- mov [vgamem],512
- jmp @@no512
-
- @@v6up:
- mov al,0b0h
- cli
- out dx,al
- inc dx
- in al,dx
- sti
- test al,10h
- jz @@v7up
- mov [vgamem],512
- @@v7up:
- cmp bl,'4'
- jb @@no512
- test al,8
- jz @@no512
- mov [vgamem],1024
- @@no512:
- jmp @@fini
-
- @@noati:
- mov ax,7000h
- xor bx,bx
- cld
- push bp
- int 10h
- pop bp
- cmp al,70h
- jnz @@noev
- mov [svgatype],vtEverex
- mov [bksize],64
- and ch,11000000b
- jz @@skp
- mov [vgamem],512
- @@skp:
-
- @@noev:
- mov ax,0bf03h
- xor bx,bx
- mov cx,bx
- push bp
- int 10h
- pop bp
- cmp ax,0bf03h
- jnz @@nocp
- test cl,40h
- jz @@nocp
- mov [svgatype],vtCompaq
- mov [bksize],4
- mov [vgamem],512
- jmp @@fini
-
- @@nocp:
- mov dx,3c4h
- mov ax,0ff05h
- call isport2
- jnz @@noncr
- mov ax,5
- out dx,ax
- mov ax,0ff10h
- call isport2
- jz @@noncr
- mov ax,105h
- out dx,ax
- mov ax,0ff10h
- call isport2
- jnz @@noncr
- mov [svgatype],vtNCR
- mov [bksize],16
- mov [vgamem],512
- jmp @@fini
-
- @@noncr:
- mov dx,3c4h
- mov al,0bh
- out dx,al
- inc dl
- in al,dx
- and al,0fh
- cmp al,06h
- ja @@notri
- cmp al,2
- jb @@notri
- mov [svgatype],vtTrident8800
- mov [bksize],64
- cmp al,3
- jb @@no89
- mov [svgatype],vtTrident8900
- mov dx,3d5h
- mov al,1fh
- out dx,al
- inc dx
- in al,dx
- and al,3
- cmp al,1
- jb @@notmem
- mov [vgamem],512
- je @@notmem
- mov [vgamem],1024
- @@notmem:
- jmp @@fini
-
- @@no89:
- mov [vgamem],512
- jmp @@fini
-
- @@notri:
- mov ax,6f00h
- xor bx,bx
- cld
- push bp
- int 10h
- pop bp
- cmp bx,'V7'
- jnz @@nov7
- mov [svgatype],vtVideo7
- mov [bksize],64
- mov ax,6f07h
- cld
- push bp
- int 10h
- pop bp
- and ah,7fh
- cmp ah,1
- jbe @@skp2
- mov [vgamem],512
- @@skp2:
- cmp ah,3
- jbe @@skp3
- mov [vgamem],1024
- @@skp3:
- jmp @@fini
-
- @@nov7:
- mov dx,3d4h
- mov ax,032eh
- call isport2
- jnz @@nogn
- mov dx,3c4h
- mov ax,3f06h
- call isport2
- jnz @@nogn
- mov [svgatype],vtGenoa
- mov [bksize],64
- mov [vgamem],512
- jmp @@fini
-
- @@nogn:
- call cirrus
- cmp [svgatype],vtCirrus
- jne @@noci
- jmp @@fini
-
- @@noci:
- mov dx,3ceh
- mov al,9
- out dx,al
- inc dx
- in al,dx
- dec dx
- or al,al
- jnz @@nopd
-
- mov ax,50fh
- out dx,ax
- mov [svgatype],vtParadise
- mov cx,1
- call chkbk
- mov [svgatype],0
- jc @@nopd
- mov [svgatype],vtParadise
- mov [bksize],4
- mov dx,3ceh
- mov al,0bh
- out dx,al
- inc dx
- in al,dx
- test al,80h
- jz @@nop512
- mov [vgamem],512
- @@nop512:
- jmp @@fini
-
- @@nopd:
- mov ax,5f00h
- xor bx,bx
- cld
- push bp
- int 10h
- pop bp
- cmp al,5fh
- jnz @@noct
- mov [svgatype],vtChipsTech
- mov [bksize],16
- cmp bh,1
- jb @@skp4
- mov [vgamem],512
- @@skp4:
- jmp @@fini
-
- @@noct:
- mov ch,0
- mov dx,3d4h
- mov ax,0f33h
- call isport2
- jnz @@not4
- mov ch,1
-
- mov dx,3bfh
- mov al,3
- out dx,al
- mov dx,3d8h
- mov al,0a0h
- out dx,al
- jmp @@yes4
-
- @@not4:
- mov dx,3d4h
- mov ax,1f25h
- call isport2
- jnz @@nots
- mov al,03fh
- jmp @@yes3
- @@yes4:
- mov al,0ffh
- @@yes3:
- mov dx,3cdh
- call isport1
- jnz @@nots
- mov [svgatype],vtTseng3000
- mov [bksize],64
- cmp ch,0
- jnz @@t4mem
- mov [vgamem],512
- jmp @@fini
-
- @@t4mem:
- mov dx,3d4h
- mov al,37h
- out dx,al
- inc dx
- in al,dx
- test al,1000b
- jz @@nomem
- and al,3
- cmp al,1
- jbe @@nomem
- mov [vgamem],512
- cmp al,2
- je @@nomem
- mov [vgamem],1024
- @@nomem:
- mov [svgatype],vtTseng4000
- mov [bksize],64
- jmp @@fini
-
- @@nots:
- mov dx,3ceh
- mov ax,200fh
- out dx,ax
- inc dx
- in al,dx
- cmp al,21h
- jz @@verb
- cmp al,20h
- jnz @@noab
- mov [svgatype],vtAheadA
- mov [bksize],64
- mov [vgamem],512
- jmp @@fini
-
- @@verb:
- mov [svgatype],vtAheadB
- mov [bksize],64
- mov [vgamem],512
- jmp @@fini
-
- @@noab:
- mov dx,3c4h
- mov ax,0006h
- out dx,ax
- mov ax,0ff09h
- call isport2
- jz @@noacu
- mov ax,0ff0ah
- call isport2
- jz @@noacu
- mov ax,1206h
- out dx,ax
- mov ax,0ff09h
- call isport2
- jnz @@noacu
- mov ax,0ff0ah
- call isport2
- jnz @@noacu
- mov [svgatype],vtAcuMOS
- mov cx,1
- call chkbk
- mov [svgatype],0
- jc @@noacu
- mov [svgatype],vtAcuMOS
- mov [bksize],4
- mov dx,3c4h
- mov al,0ah
- out dx,al
- inc dx
- in al,dx
- and al,3
- cmp al,1
- jb @@noamem
- mov [vgamem],512
- cmp al,2
- jb @@noamem
- mov [vgamem],1024
- cmp al,3
- jb @@noamem
- mov [vgamem],2048
- @@noamem:
- jmp @@fini
-
- @@noacu:
- mov dx,3deh
- mov ax,0ff11h
- call isport2
- jnz @@nooak
- mov [svgatype],vtOakTech
- mov [bksize],64
- mov al,0dh
- out dx,al
- inc dx
- in al,dx
- test al,11000000b
- jz @@no4ram
- mov [vgamem],512
- test al,01000000b
- jz @@no4ram
- mov [vgamem],1024
- @@no4ram:
- jmp @@fini
-
- @@nooak:
- jmp @@nos3
- mov [svgatype],vtS3Vga
- mov [bksize],64
- mov [vgamem],1024
- jmp @@fini
-
- @@nos3:
- cmp [vesaavail],0
- je @@nosvga
- mov [vgamem],2048
- jmp @@fini
-
- @@nosvga:
- mov [svgatype],0
-
- @@fini:
- cmp [vesaavail],1
- jne @@sorry
- mov [svgatype],vtVESA
- @@sorry:
- mov ax,[svgatype]
- mov [retval],ax
- @@skipout:
- pop es
- pop si
- pop di
- pop dx
- pop cx
- pop bx
- pop ax
- pop bp
- end;
-
- procedure DetectSVGAType(CheckHW : Boolean);
- var
- Reg : Registers;
- Tmp : Integer;
- begin
- if CurrentDisplay <> VGA then exit;
-
- if (CheckHW) or (not(VidChecked)) then begin
- VidChecked := True;
- WhichVGA;
- BankSize := Word((LongInt(BkSize) * 1024)-1);
- end;
- end;
-
- {$ENDIF}
-
- {-------------------------}
- { Video hardware routines }
- {-------------------------}
-
- procedure PlotBIOSPixel(X,Y : Word; C : Byte);
- {-plot a single pixel using BIOS services}
- var
- R : Registers;
- begin
- asm
- mov ah,0Ch
- mov al,C
- mov cx,X
- mov dx,Y
- push bp
- int 10h
- pop bp
- end;
- end;
-
- procedure PlotBIOSLine(Y : Word);
- {-plot a raster line using BIOS services}
- var
- X : Integer;
- begin
- asm
- xor bx,bx
- mov si,offset RasterLine
- mov dx,Y
- mov ah,0Ch
- xor al,al
- mov cx,RightEdge
- sub cx,LeftEdge
- cld
- @@Top:
- jcxz @@Done
- mov al,[si+bx]
- push ax
- push bx
- push cx
- mov cx,bx
- add cx,LeftEdge
- xor bx,bx
- push bp
- int 10h
- pop bp
- pop cx
- pop bx
- pop ax
- inc bx
- loop @@Top
- @@Done:
- end;
- end;
-
- procedure PlotCGALoLine(Y : Word);
- {-plot a raster line in CGA 320x200x4 mode}
- var
- X,M,VOfs : Word;
- Tmp : Array[0..79] of Byte;
- begin
- {calc offset in vmem of scanline to plot}
- VOfs := ((Y and 1) shl 13) + (80 * (Y shr 1)) + ((LeftEdge shr 2) mod 80);
- M := 0;
- FillChar(Tmp,80,0);
- X := LeftEdge;
- {load our holding buffer with the line. CGA low uses 2 bits/pixel}
- repeat
- Tmp[m] := Tmp[m] or (((RasterLine[X] and $03) shl 6) shr ((X mod 4) shl 1));
- Inc(X);
- if (X and 3) = 0 then Inc(M);
- until X > RightEdge;
- {move the line to vmem}
- Move(Tmp,Ptr(ColorSele,VOfs)^,M);
- end;
-
- procedure PlotCGAHiLine(Y : Word);
- {-plot a raster line in CGA 640x200x2 mode}
- var
- X,M,VOfs : Word;
- Tmp : Array[0..79] of Byte;
- begin
- {same as CGALo, but uses 1 bit/pixel}
- VOfs := ((Y and 1) shl 13) + (80 * (Y shr 1)) + ((LeftEdge shr 3) mod 80);
- M := 0;
- FillChar(Tmp,80,0);
- X := LeftEdge;
- repeat
- Tmp[m] := Tmp[m] or (((RasterLine[X] and 1) shl 7) shr (X mod 8));
- Inc(X);
- if (X and 7) = 0 then Inc(M);
- until X > RightEdge;
- Move(Tmp,Ptr(ColorSele,VOfs)^,M);
- end;
-
- procedure PlotEGALine(Y : Word);
- {-plot EGA raster line in modes $0D - $12}
- var
- I : Word;
- begin
- asm
- mov ax,Y
- mul EGABytesPerLine
- mov bx,LeftEdge
- shr bx,1
- shr bx,1
- shr bx,1
- add ax,bx
- mov di,ax
- mov es,VGASele
- mov si,offset RasterLine
- mov ah,80h
- mov cx,LeftEdge
- ror ah,cl
- mov dx,3CEh
- mov cx,RightEdge
- sub cx,LeftEdge
- inc cx
- mov al,08h
- cld
- @@Top:
- jcxz @@Done
- out dx,ax
- mov bl,[si]
- mov bh,es:[di]
- mov es:[di],bl
- inc si
- ror ah,1
- cmp ah,80h
- jne @@Check
- inc di
- @@Check:
- loop @@Top
- @@Done:
- end;
- end;
-
- procedure PlotEGALineDbl(Y : Word);
- {-plot special EGA raster line in mode $12 for expanded weather maps}
- begin
- Move(RasterLine[0], RasterLine[1280], 378);
- asm
- mov si,offset RasterLine
- mov di,si
- add si,1280
- mov ax,ds
- mov es,ax
- mov cx,378
- xor bx,bx
- cld
- @@Top:
- jcxz @@Done
- movsb
- dec si
- movsb
- inc bx
- cmp bx,5
- jne @@Skip
- xor bx,bx
- dec cx
- inc si
- @@Skip:
- loop @@Top
- @@Done:
- end;
- PlotEGALine(Y);
- PlotEGALine(Y+1);
- end;
-
- procedure PlotVGALine(Y : Word);
- {-plot a raster line in VGA mode $13}
- begin
- asm
- mov ax,Y
- mul Pixels
- add ax,LeftEdge
- mov di,ax
- mov es,VGASele
- mov si,offset RasterLine
- mov cx,RightEdge
- sub cx,LeftEdge
- cld
- rep movsb
- end;
- end;
-
- {$IFDEF UseSVGA}
- procedure PlotSVGALine(Y : Word);
- {-plot a raster line in SVGA modes}
- begin
- asm
- mov ax,Y
- cwd
- mul Pixels
- add ax,LeftEdge
- adc dx,0
- push ax
- cmp dx,CurBk
- jne @@Switch1
- mov cx,RightEdge
- sub cx,LeftEdge
- add ax,cx
- adc dx,0
- cmp dx,CurBk
- jne @@Switch2
-
- @@NoSwitch:
- mov si,offset RasterLine
- mov es,VGASele
- pop di
- cld
- rep movsb
- jmp @@Done
-
- @@Switch1:
- mov CurBk,dx
- xor dx,dx
- mov ax,CurBk
- call NewBank
- jmp @@Skip
- @@Switch2:
- mov CurBk,dx
- xor dx,dx
- @@Skip:
- mov cx,RightEdge
- sub cx,LeftEdge
- pop di
- mov si,offset RasterLine
- mov es,VGASele
- cld
- @@Top:
- jcxz @@Done
- movsb
- cmp di,0
- ja @@SkipSwitch
- mov ax,CurBk
- call NewBank
- @@SkipSwitch:
- loop @@Top
- @@Done:
- end;
- end;
- {$ENDIF}
-
- {---------------------------------------------------------------------------}
-
- procedure AdjustPalette(Mode : Byte);
- {-set hardware palette to match image map}
- var R : Registers;
- begin
- FillChar(RasterLine,SizeOf(TRasterLine),0); {blank line to start}
- with R do begin
- if Mode >= $13 then begin
- ah := $10;
- al := $12;
- bx := 0;
- cx := Maps[Curmap].HighColorNum+1; {# of palette entries in use}
- es := Seg(VGAPalette);
- dx := Ofs(VGAPalette);
- Intr($10, R);
- end
- else if Mode >= $0D then begin
- ah := $10;
- al := $02;
- bx := 0;
- es := Seg(EGAPalette);
- dx := Ofs(EGAPalette);
- Intr($10, R);
- end;
- end;
- end;
-
- procedure SetMode(Mode : Byte);
- {-low level video mode set via BIOS}
- var R : Registers;
- begin
- R.ah := $00;
- R.al := Mode;
- Intr($10,R);
- end;
-
- {$IFDEF UseSVGA}
- procedure SetSVGAMode(Mode : Byte);
- {-special BIOS setmode for SVGA chipsets, using ModeList. Some SVGA}
- {chipsets use a constant AX value for SVGA modes with a second value}
- {in BL to select the actual mode; we handle that here. }
- var
- B : Integer;
- R : Registers;
- begin
- B := Mode - $F0;
- MaxColors := ModeList[B].MaxC;
- if SVGAType = vtVESA then begin
- R.ax := $4F02;
- R.bx := ModeList[B].ModeAX;
- end
- else begin
- R.ax := ModeList[B].ModeAX;
- R.bl := ModeList[B].ModeBL;
- end;
- Intr($10,R);
- if SVGAType = vtVESA then begin
- R.ax := $4F01;
- R.cx := ModeList[B].ModeAX;
- R.es := Seg(VesaModeInfo);
- R.di := Ofs(VesaModeInfo);
- Intr($10,R);
- end;
- end;
-
- procedure SelectModeTable;
- {-select which modetable to use based on chipset type}
- begin
- FillChar(ModeList,SizeOf(ModeList),0);
- case SVGAType of
- vtTseng3000:
- ModeList := Tseng3000Table;
- vtTseng4000:
- ModeList := Tseng4000Table;
- vtTrident8800:
- ModeList := TridentTable;
- vtTrident8900:
- ModeList := Trident8900Table;
- vtParadise:
- ModeList := ParadiseTable;
- vtVideo7:
- ModeList := Video7Table;
- vtATIVGA:
- ModeList := ATITable;
- vtChipsTech:
- ModeList := ChipsTechTable;
- vtAheadA, vtAheadB:
- ModeList := AheadTable;
- vtEverex:
- ModeList := EverexTable;
- vtAcuMOS:
- ModeList := AcuMOSTable;
- vtNCR:
- ModeList := NCRTable;
- vtGenoa:
- ModeList := GenoaTable;
- vtOakTech:
- ModeList := OakTable;
- vtVESA:
- ModeList := VESATable;
- end;
- end;
- {$ENDIF}
-
- procedure SetGraphicsMode(Mode : Byte);
- {-sets selected grahics mode}
- begin
- OldMode := LastMode;
- OldFont8x8 := Font8x8Selected;
- {$IFDEF UseSVGA}
- if (Mode > $13) and (SVGAType > 0) then
- SetSVGAMode(Mode)
- else
- {$ENDIF}
- if Mode = $09 then begin
- if WhichHerc = HercInColor then
- SwitchInColorCard(False);
- SetHercMode(True,0);
- {clear the screen}
- FillChar(Ptr(SegB000, 0)^,$7FFF,0);
- end
- else
- SetMode(Mode); {low-level video mode set}
- if (Mode >= $0D) and (Mode <= $12) then begin
- {EGA, set up EGA CRTC as we need it}
- PortW[$03CE] := $1803;
- PortW[$03CE] := $0205;
- end;
- GraphOn := True;
- end;
-
- procedure SetTextMode;
- {-restore text mode}
- begin
- if SelMode = $09 then begin
- SetHercMode(False,0);
- if WhichHerc = HercInColor then
- SwitchInColorCard(True);
- end
- else
- SetMode(OldMode);
- TextMode(OldMode);
- SelectFont8x8(OldFont8x8);
- ReinitCrt;
- ClrScr;
- GraphOn := False;
- end;
-
- procedure FillBackground;
- var
- W : Word;
- begin
- LeftEdge := 0;
- RightEdge := ScrWidth;
- FillChar(RasterLine, SizeOf(RasterLine), Maps[Global].BackgrColorIndex);
- for W := 0 to Pred(ScrHeight) do
- PlotLine(W);
- FillChar(RasterLine, SizeOf(RasterLine), 0);
- end;
-
- function SelectMode(X,Y : Word) : Byte;
- {-uses image X/Y resolution to select video mode}
- var
- B : Byte;
- begin
- DetectSVGAType(True);
-
- EGABytesPerLine := 80;
- MaxColors := 16;
- Pixels := 640;
- PlotLine := PlotEGALine;
-
- if (CurrentDisplay in [EGA,VGA]) and
- (X = 378) and
- (Y = 240) then begin
- {CIS Weather map in odd size, do special handling}
- if (DoDbl) then begin
- Pixels := 378*2;
- Raster := 480;
- MaxColors := 16;
- SelectMode := $12;
- PlotLine := PlotEGALineDbl;
- end
- else begin
- Pixels := 640;
- Raster := 480;
- MaxColors := 16;
- SelectMode := $12;
- PlotLine := PlotEGALine;
- end;
- exit;
- end;
-
- {$IFDEF UseSVGA}
- {if we're an SVGA, select a matching mode}
- if (CurrentDisplay = VGA) and (SVGAType > 0) then begin
- {set our mode table and vars}
- SelectModeTable;
- PlotLine := PlotSVGALine;
- MaxColors := 256;
- CurBk := 0;
-
- {Match a mode index to Y res. The vast majority of SVGA GIFs are}
- {"tall/narrow" rather than "short/wide", so this is a safe match,}
- {but we allow for 640x200 CGA-type images as well.}
- case Y of
- 601..MaxInt:
- B := $F6;
- 481..600:
- B := $F4;
- 401..480:
- B := $F2;
- 201..400:
- B := $F1;
- else
- begin
- if X > 320 then
- B := $F1
- else begin
- SelectMode := $13;
- Raster := 200;
- Pixels := 320;
- PlotLine := PlotVGALine;
- exit;
- end;
- end;
- end;
-
- {walk up mode table til we get a supported mode}
- while (B > $F1) and (ModeList[B-$F0].Index = 0) do
- Dec(B);
-
- {now match colors and resolution}
- SelectMode := B;
- MaxColors := ModeList[B-$F0].MaxC;
- case B of
- $F5,$F6:
- begin
- Raster := 768;
- Pixels := 1024;
- end;
- $F3,$F4:
- begin
- Raster := 600;
- Pixels := 800;
- end;
- $F2:
- begin
- Raster := 480;
- Pixels := 640;
- end;
- $F1:
- begin
- Raster := 400;
- Pixels := 640;
- end;
- end;
-
- {16 color modes > 640x480 are wierd, use the BIOS to plot}
- if (MaxColors = 16) and (Raster > 480) then
- PlotLine := PlotBIOSLine;
- end
-
- else
- {$ENDIF}
- if (CurrentDisplay = EGA) or (CurrentDisplay = VGA) then begin
- {if > 350 lines, use EGA/VGA mode $12 (640x480x16)}
- EGABytesPerLine := 80;
- MaxColors := 16;
- Pixels := 640;
- PlotLine := PlotEGALine;
-
- if (Y > 350) and ((CurrentDisplay = VGA) or (AllowEGAMode12)) then begin
- Raster := 480;
- SelectMode := $12;
- end
-
- {if we fit CGAHi specs, use it}
- else if (Y <= 200) and (X <= 640) and
- (Maps[CurMap].HighColorNum < 2) then begin
- Raster := 200;
- Pixels := 640;
- PlotLine := PlotCGAHiLine;
- SelectMode := $06;
- end
-
- else if (Y <= 200) and (X <= 320) then begin
- {if we meet std. VGA specs, use VGA mode $13 (320x200x256)}
- if (CurrentDisplay = VGA) then begin
- MaxColors := 256;
- Raster := 200;
- Pixels := 320;
- PlotLine := PlotVGALine;
- SelectMode := $13;
- end
- {otherwise use EGA native mode $0D (320x200x16)}
- else begin
- Raster := 200;
- Pixels := 320;
- EGABytesPerLine := 40;
- SelectMode := $0D;
- end;
- end
-
- {default to "standard" EGA/VGA mode $10 (640x350x16)}
- else begin
- Raster := 350;
- SelectMode := $10;
- end;
- end
-
- else if CurrentDisplay = CGA then begin
- {if > 320 pixels, use CGA mode $06}
- Raster := 200;
- if X > 320 then begin
- PlotLine := PlotCGAHiLine;
- Pixels := 640;
- SelectMode := $06;
- end
- else begin
- {use CGA mode $05, which turns off color burst to "grayscale" image}
- {since the standard CGA palettes match almost nothing <g>}
- PlotLine := PlotCGALoLine;
- Pixels := 320;
- SelectMode := $05;
- end;
- end
-
- else begin
- WriteLn('** Unsupported video system detected **');
- SelectMode := 0;
- end;
- end;
-
- {$IFDEF Dpmi}
- begin
- GetSelectorForRealMem(Ptr($A000,0), $FFFF, VGASele);
- GetSelectorForRealMem(Ptr($C000,0), $FFFF, VidBIOSSele);
- {$ENDIF}
- end.
-