home *** CD-ROM | disk | FTP | other *** search
- {*********************************************************}
- {* TSVGA.PAS 1.00 *}
- {* Copyright (c) T P Systems, Inc. 1994. *}
- {* All rights reserved. *}
- {*********************************************************}
-
- (* Implements standard VGA video functions of Int 10. In so far as
- possible the formats of these routines is the same as those in
- SVGA.
- *)
-
- {$A-,B-,E+,F+,I-,N-,O+,R-,S-,V-,X+}
-
- Unit TsVga;
-
- interface
-
- uses
- Dos,
- OpConst,
- OpString,
- OpCrt;
-
- var
- BiosMode : byte absolute $0040:$0049;
- BiosRows : byte absolute $0040:$0084;
- BiosCols : byte absolute $0040:$004A;
- BiosCharH : byte absolute $0040:$0085;
-
- const
- MaxScreenModes = 10;
-
- {new error codes}
- ecVgaFuncNotSupported = 3993;
- ecVgaFuncFailed = 3994;
- ecVgaNotActive = 3995;
- ecInvalidFontFile = 3996;
- ecScrResolNotSupported= 3997;
- ecNotRomFont = 3998;
- ecStateNotSaved = 3999;
-
- type
- ScreenModePtr = ^ScreenModeRec;
- ScreenModeRec = record
- smVidMode : word;
- smFontSize : byte;
- smRows : byte;
- smCols : byte;
- smIsText : boolean;
- smPixW : word;
- smPixH : word;
- smColors : word; {number of colors supported}
- end;
-
- ScreenModeArPtr = ^ScreenModeArray;
- ScreenModeArray = array[1..MaxScreenModes] of ScreenModeRec;
- ModeSet = set of 0..$13;
- RowSet = set of 12..60;
- FontSet = set of 8..16;
-
- const
- StdTextModes : ModeSet = [0,1,2,3,7];
-
- StdEgaFonts : FontSet = [8, 14];
- StdVgaFonts : FontSet = [8, 14, 16];
-
- {Standard font screen resolutions for text}
- StdEgaRows : RowSet = [25, 43];
- {for text modes below the smPixH value is equivalent to scan lines}
- StdEgaModes : ScreenModeArray = (
- (smVidMode: $03; smFontSize: 14; smRows: 25; smCols: 80; smIsText: true;
- smPixW: 640; smPixH: 350; smColors: 16),
- (smVidMode: $03; smFontSize: 8; smRows: 43; smCols: 80; smIsText: true;
- smPixW: 640; smPixH: 350; smColors: 16),
- (smVidMode: $01; smFontSize: 14; smRows: 25; smCols: 40; smIsText: true;
- smPixW: 320; smPixH: 350; smColors: 16),
- (smVidMode: $00; smFontSize: 0; smRows: 0; smCols: 0; smIsText: false;
- smPixW: 0; smPixH: 0; smColors: 0),
- (smVidMode: $00; smFontSize: 0; smRows: 0; smCols: 0; smIsText: false;
- smPixW: 0; smPixH: 0; smColors: 0),
- (smVidMode: $00; smFontSize: 0; smRows: 0; smCols: 0; smIsText: false;
- smPixW: 0; smPixH: 0; smColors: 0),
- (smVidMode: $00; smFontSize: 0; smRows: 0; smCols: 0; smIsText: false;
- smPixW: 0; smPixH: 0; smColors: 0),
- (smVidMode: $00; smFontSize: 0; smRows: 0; smCols: 0; smIsText: false;
- smPixW: 0; smPixH: 0; smColors: 0),
- (smVidMode: $00; smFontSize: 0; smRows: 0; smCols: 0; smIsText: false;
- smPixW: 0; smPixH: 0; smColors: 0),
- (smVidMode: $00; smFontSize: 0; smRows: 0; smCols: 0; smIsText: false;
- smPixW: 0; smPixH: 0; smColors: 0));
-
- {Non-standard font screen resolutions for text}
- SplEgaRows : RowSet = [26, 29, 31, 35, 38];
- {for text modes below the smPixH value is equivalent to scan lines}
- SplEgaModes : ScreenModeArray = (
- (smVidMode: $03; smFontSize: 13; smRows: 26; smCols: 80; smIsText: true;
- smPixW: 640; smPixH: 350; smColors: 16),
- (smVidMode: $03; smFontSize: 12; smRows: 29; smCols: 80; smIsText: true;
- smPixW: 640; smPixH: 350; smColors: 16),
- (smVidMode: $03; smFontSize: 11; smRows: 31; smCols: 80; smIsText: true;
- smPixW: 640; smPixH: 350; smColors: 16),
- (smVidMode: $03; smFontSize: 10; smRows: 35; smCols: 80; smIsText: true;
- smPixW: 640; smPixH: 350; smColors: 16),
- (smVidMode: $03; smFontSize: 9; smRows: 38; smCols: 80; smIsText: true;
- smPixW: 640; smPixH: 350; smColors: 16),
- (smVidMode: $00; smFontSize: 0; smRows: 0; smCols: 0; smIsText: false;
- smPixW: 0; smPixH: 0; smColors: 0),
- (smVidMode: $00; smFontSize: 0; smRows: 0; smCols: 0; smIsText: false;
- smPixW: 0; smPixH: 0; smColors: 0),
- (smVidMode: $00; smFontSize: 0; smRows: 0; smCols: 0; smIsText: false;
- smPixW: 0; smPixH: 0; smColors: 0),
- (smVidMode: $00; smFontSize: 0; smRows: 0; smCols: 0; smIsText: false;
- smPixW: 0; smPixH: 0; smColors: 0),
- (smVidMode: $00; smFontSize: 0; smRows: 0; smCols: 0; smIsText: false;
- smPixW: 0; smPixH: 0; smColors: 0));
-
- StdVgaRows : RowSet = [12, 14, 21, 25, 28, 30, 43, 50, 60];
- {for text modes below the smPixH value is equivalent to scan lines}
- StdVgaModes : ScreenModeArray = (
- (smVidMode: $01; smFontSize: 16; smRows: 25; smCols: 40; smIsText: true;
- smPixW: 360; smPixH: 400; smColors: 16),
- (smVidMode: $03; smFontSize: 16; smRows: 25; smCols: 80; smIsText: true;
- smPixW: 720; smPixH: 400; smColors: 16),
- (smVidMode: $03; smFontSize: 16; smRows: 12; smCols: 80; smIsText: true;
- smPixW: 720; smPixH: 200; smColors: 16),
- (smVidMode: $03; smFontSize: 14; smRows: 14; smCols: 80; smIsText: true;
- smPixW: 720; smPixH: 200; smColors: 16),
- (smVidMode: $01; smFontSize: 16; smRows: 21; smCols: 40; smIsText: true;
- smPixW: 360; smPixH: 350; smColors: 16),
- (smVidMode: $03; smFontSize: 14; smRows: 28; smCols: 80; smIsText: true;
- smPixW: 720; smPixH: 400; smColors: 16),
- (smVidMode: $12; smFontSize: 16; smRows: 30; smCols: 80; smIsText: false;
- smPixW: 640; smPixH: 480; smColors: 16),
- (smVidMode: $03; smFontSize: 8; smRows: 43; smCols: 80; smIsText: true;
- smPixW: 720; smPixH: 350; smColors: 16),
- (smVidMode: $03; smFontSize: 8; smRows: 50; smCols: 80; smIsText: true;
- smPixW: 720; smPixH: 400; smColors: 16),
- (smVidMode: $12; smFontSize: 8; smRows: 60; smCols: 80; smIsText: false;
- smPixW: 640; smPixH: 480; smColors: 16));
-
- {Non-standard font screen resolutions for text}
- SplVgaRows : RowSet = [26, 29, 30, 31, 33, 35, 36, 38, 40, 44];
- {for text modes below the smPixH value is equivalent to scan lines}
- SplVgaModes : ScreenModeArray = (
- (smVidMode: $03; smFontSize: 15; smRows: 26; smCols: 80; smIsText: true;
- smPixW: 720; smPixH: 400; smColors: 16),
- (smVidMode: $03; smFontSize: 12; smRows: 29; smCols: 80; smIsText: true;
- smPixW: 720; smPixH: 350; smColors: 16),
- (smVidMode: $03; smFontSize: 13; smRows: 30; smCols: 80; smIsText: true;
- smPixW: 720; smPixH: 400; smColors: 16),
- (smVidMode: $03; smFontSize: 11; smRows: 31; smCols: 80; smIsText: true;
- smPixW: 720; smPixH: 350; smColors: 16),
- (smVidMode: $03; smFontSize: 12; smRows: 33; smCols: 80; smIsText: true;
- smPixW: 720; smPixH: 400; smColors: 16),
- (smVidMode: $03; smFontSize: 10; smRows: 35; smCols: 80; smIsText: true;
- smPixW: 720; smPixH: 350; smColors: 16),
- (smVidMode: $03; smFontSize: 11; smRows: 36; smCols: 80; smIsText: true;
- smPixW: 720; smPixH: 400; smColors: 16),
- (smVidMode: $03; smFontSize: 9; smRows: 38; smCols: 80; smIsText: true;
- smPixW: 720; smPixH: 350; smColors: 16),
- (smVidMode: $03; smFontSize: 10; smRows: 40; smCols: 80; smIsText: true;
- smPixW: 720; smPixH: 400; smColors: 16),
- (smVidMode: $03; smFontSize: 9; smRows: 44; smCols: 80; smIsText: true;
- smPixW: 720; smPixH: 400; smColors: 16));
-
- type
-
- VgaStatePtr = ^VgaStateTable;
- VgaStateTable = record
- vsTable : pointer; {address of static functionality table}
- vsMode : byte; {video mode}
- vsCols : word; {column/row}
- vsBufLen : word; {display buffer length}
- vsAddr : word; {starting address of buffer}
- vsCurPos : array [1..8] of word; {array of 8 cursor positions}
- vsCurType : word; {cursor type}
- vsActPage : byte; {active page}
- vsCrtCtrl : word; {CRT Controller base address}
- vsVal3x8 : byte; {current value of 3x8 register}
- vsVal3x9 : byte; {current value of 3x9 register}
- vsRows : byte; {rows on screen}
- vsCharHigh : word; {character height - bytes/char}
- vsActDisp : byte; {active display code}
- vsInActDisp : byte; {inactive display code}
- vsNrColors : word; {number of colors available in current mode}
- vsNrPages : byte; {number of display pages in current mode}
- vsNrScanLns : byte; {number of scan lines - coded}
- vsPriCharBlk: byte; {primary character block}
- vsSecCharBlk: byte; {secondary character block}
- vsMiscInfo : byte; {miscellaneous state info - bit mapped}
- vsRes1 : array[1..3] of byte; {reserved}
- vsVidMem : byte; {video memory available - coded}
- vsPtrState : byte; {save pointer state - bit mapped}
- vsRes2 : array[1..13] of byte; {reserved}
- end;
-
- const
- {bit masks for vsMiscInfo byte above}
- vsAllModes = $01; {all modes on all displays active}
- vsGrayScale = $02; {gray scale summing is active}
- vsMonoDisp = $04; {mono display is attached}
- vsNoAutoPal = $08; {mode set auto palette loading disabled}
- vsCurEmul = $10; {cursor emulation is active}
- vsBlink = $20; {on=blink, off=background intensity}
-
- {scan line array}
- ScanLines : array[0..3] of word = (200, 350, 400, 480);
-
- {Save Video State Bit Masks}
- ssHardware = $0001;
- ssBios = $0002;
- ssDac = $0004;
- ssSvga = $0008;
- ssAllVga = $0007;
- ssAllSvga = $000F;
-
- var
- CurVideoMode : integer;
- CurScreenRows : integer;
- CurScreenCols : integer;
-
- const
- CurBlinkOff : boolean = false;
- OrigBlinkOff : boolean = false;
-
- {*****************************************************************
- VGA Routines -- some will work with EGA
- ******************************************************************}
-
- function ReturnVgaInfo(VI: VgaStatePtr): word;
- {-Returns status 0 if successful and VgaStateTable filled in or if fails,
- returns ecVgaFuncFailed.}
-
- function SetVgaMode(Mode: word; Clear: boolean): word;
- {-Sets VGA mode. Clears display memory if Clear. Returns standard Vga status.}
-
- function ReturnCurVgaMode(var Mode: word): word;
- {-Returns status and current video mode in Mode. Bit 7 indicates whether
- video display memory was cleared on last set mode.}
-
- function ReturnVgaSaveBufferSize(var Size: word; States: word): word;
- {-Returns status and size of save state buffer in Size (in bytes). Must be
- called before SaveVgaState to get size of required buffer. States is
- bit mapped to indicate which states are to be saved. See bit masks above.}
-
- function SaveVgaState(Buf: pointer; States: word): word;
- {-Returns status of saving video states specified in States. Buf points
- to a save buffer of size determined by ReturnVgaSaveBufferSize. No checking
- that Buf points to area large enough. States must be same as used in
- ReturnSaveBufferSize.}
-
- function RestoreVgaState(Buf: pointer; States: word): word;
- {-Returns status of restoring video states specified in States. Buf must
- point to buffer that was previously saved with SaveSvgaState and States
- must be same as used previously.}
-
- function ReturnScreenMode(ScreenModes: ScreenModeArPtr;
- var ScreenMode: ScreenModeRec): boolean;
- {-Searches ScreenModes for a mode with matching smRows and smCols and/or
- smVidMode and returns true plus the appropriate ScreenModeRec.}
-
- function SetVgaFont(FontName: string; ScrMode: ScreenModeRec;
- FontBuf: pointer): word;
- {-If FontName is blank, a the appropriate standard ROM based font will
- be loaded. Otherwise it loads user fonts in file FontName for the
- appropriate number of screen rows. FontBuf points to a buffer of
- appropriate size that has already been allocated. This assumes the video
- display adpater is already in the appropriate video mode and scan lines
- are set for text mode cases. If successful, it returns 0; otherwise the
- error.}
-
- function PreservePalette(On: boolean): word;
- {-Supported only on VGA. If On then with a set mode the palette is not
- changed to the default. Returns ecVgaFuncNotSupported if it fails.}
-
- function SetScanLines(Lines: word): word;
- {-Supported only on VGA. Selects scan lines for text modes. Valid
- values of Lines are 200, 350, 400. Returns ecVgaFuncNotSupported or
- ecVgaNotActive if function fails.}
-
- function DisableVideoRefresh(Off: boolean): word;
- {-If Off is true, disables video refresh which blanks the screen. If Off
- is false, the video refresh is enabled. Returns status of action.}
-
- {**********************************************************}
-
- implementation
-
- type
- OS = record
- O,S : word;
- end;
-
- function ReturnVgaInfo(VI: VgaStatePtr): word; assembler;
- {-Returns status 0 if successful and VgaStateTable filled in or if fails,
- returns ecVgaFuncFailed.}
- asm
- push bx
- push di
- push es
- mov ax,$1B00
- xor bx,bx
- mov di,OS(VI).S
- mov es,di
- mov di,OS(VI).O
- int $10
- cmp al,$1B
- je @1
- mov ax,ecVgaFuncFailed
- jmp @2
- @1:
- xor ax,ax
- @2:
- pop es
- pop di
- pop bx
- end;
-
- function SetVgaMode(Mode: word; Clear: boolean): word; assembler;
- {-Sets VGA mode. Clears display memory if Clear. Returns standard Vga status.}
- asm
- push bx
- mov ax,Mode
- mov ah,0
- mov bl,Clear
- xor bl,1
- ror bl,1
- or al,bl
- int $10
- xor ax,ax
- pop bx
- end;
-
- function ReturnCurVgaMode(var Mode: word): word; assembler;
- {-Returns status and current video mode in Mode. Bit 7 is always
- cleared to be compatible with SVGA function.}
- asm
- push bx
- push si
- push ds
- mov ah,$0F
- int $10
- xor ah,ah
- and al,$7F
- lds si,Mode
- mov word ptr [si],ax
- xor ax,ax
- pop ds
- pop si
- pop bx
- end;
-
- function ReturnVgaSaveBufferSize(var Size: word; States: word): word; assembler;
- {-Returns status and size of save state buffer in Size (in bytes). Must be
- called before SaveVgaState to get size of required buffer. States is
- bit mapped to indicate which states are to be saved. See bit masks above.}
- asm
- push bx
- push cx
- push si
- push ds
- mov ah,$1C
- mov al,0
- mov cx,States
- int $10
- cmp al,$1C
- je @1
- mov ax,ecVgaFuncFailed
- jmp @2
- @1:
- lds si,Size
- shl bx,1 {bx returns size in 64 byte blocks}
- shl bx,1
- shl bx,1
- shl bx,1
- shl bx,1
- shl bx,1
- mov word ptr [si],bx
- xor ax,ax
- @2:
- pop ds
- pop si
- pop cx
- pop bx
- end;
-
- function SaveVgaState(Buf: pointer; States: word): word; assembler;
- {-Returns status of saving video states specified in States. Buf points
- to a save buffer of size determined by ReturnVgaSaveBufferSize. No checking
- that Buf points to area large enough. States must be same as used in
- ReturnSaveBufferSize. Should be followed by RestoreVgaState since Phoenix
- AT Systems BIOS reference says saving modifies video registers.}
- asm
- push bx
- push cx
- push es
- mov ah,$1C
- mov al,1
- mov cx,States
- mov es,OS(Buf).S
- mov bx,OS(Buf).O
- int $10
- cmp al,$1C
- je @1
- mov ax,ecVgaFuncFailed
- jmp @2
- @1:
- xor ax,ax
- @2:
- pop es
- pop cx
- pop bx
- end;
-
- function RestoreVgaState(Buf: pointer; States: word): word; assembler;
- {-Returns status of restoring video states specified in States. Buf must
- point to buffer that was previously saved with SaveSvgaState and States
- must be same as used previously.}
- asm
- push bx
- push cx
- push es
- mov ah,$1C
- mov al,2
- mov cx,States
- mov es,OS(Buf).S
- mov bx,OS(Buf).O
- int $10
- cmp al,$1C
- je @1
- mov ax,ecVgaFuncFailed
- jmp @2
- @1:
- xor ax,ax
- @2:
- pop es
- pop cx
- pop bx
- end;
-
- procedure SetTypematicRate(Delay, Rate: byte); {!!1.35}
- {-Sets keyboard typematic features. See Phoenix System BIOS manual page 143.
- Text applications when using an underlying graphics mode, usually need
- to have key repeat rate slowed down.}
- begin
- asm
- mov ax,$0305
- mov bh,Delay
- mov bl,Rate
- int $16
- end;
- end;
-
- const
- {key repeat rates for each video mode to take into account slower screen}
- { 0 = 30 chars/sec; $14 = 5 chars/sec }
- VGAKeyRate : array [1..4] of byte = (0, $12, 0, $12);
-
- function ReturnScreenMode(ScreenModes: ScreenModeArPtr;
- var ScreenMode: ScreenModeRec): boolean;
- {-Searches ScreenModes for a mode with matching smRows and smCols and/or
- smVidMode and returns true plus the appropriate ScreenModeRec.}
- var
- i : byte;
- begin
- ReturnScreenMode := false;
- if ScreenMode.smVidMode = 0 then begin
- for i := 1 to MaxScreenModes do begin
- if (ScreenMode.smRows = ScreenModes^[i].smRows) and
- (ScreenMode.smCols = ScreenModes^[i].smCols) then begin
- ScreenMode := ScreenModes^[i];
- ReturnScreenMode := true;
- Exit;
- end;
- end;
- end else begin
- for i := 1 to MaxScreenModes do begin
- if (ScreenMode.smVidMode = ScreenModes^[i].smVidMode) then begin
- if ((ScreenMode.smRows <> 0) and (ScreenMode.smCols <> 0)) then begin
- if (ScreenMode.smRows = ScreenModes^[i].smRows) and
- (ScreenMode.smCols = ScreenModes^[i].smCols) then begin
- ScreenMode := ScreenModes^[i];
- ReturnScreenMode := true;
- Exit;
- end;
- end else begin
- ScreenMode := ScreenModes^[i];
- ReturnScreenMode := true;
- Exit;
- end;
- end;
- end;
- end;
- end;
-
- function SetVgaFont(FontName: string; ScrMode: ScreenModeRec;
- FontBuf: pointer): word;
- {-If FontName is blank, a the appropriate standard ROM based font will
- be loaded. Otherwise it loads user fonts in file FontName for the
- appropriate number of screen rows. FontBuf points to a buffer of
- appropriate size that has already been allocated. This assumes the video
- display adpater is already in the appropriate video mode and scan lines
- are set for text mode cases. If successful, it returns 0; otherwise the
- error.}
- var
- F : file;
- BufSize : word;
- Status : word;
- Standard : boolean;
- Regs : Registers;
- begin
- Standard := (FontName = '');
- with ScrMode do begin
- if not Standard then begin
- BufSize := Word(256)*smFontSize;
- Assign(F, FontName);
- Reset(F, 1);
- Status := IOResult;
- if Status <> 0 then begin
- SetVgaFont := Status;
- Exit;
- end;
- if FileSize(F) <> BufSize then begin
- Close(F);
- Status := IOResult;
- SetVgaFont := ecInvalidFontFile;
- Exit;
- end;
- BlockRead(F, FontBuf^, BufSize);
- Close(F);
- Status := IOResult;
- if Status <> 0 then begin
- SetVgaFont := Status;
- Exit;
- end;
- end;
- with Regs do begin
- AH := $11;
- BL := 0;
- if Standard then begin
- if smIsText then begin
- case smFontSize of
- 8 : AL := $12;
- 14 : AL := $11;
- 16 : AL := $14;
- else begin
- SetVgaFont := ecNotRomFont;
- Exit;
- end;
- end;
- end else begin
- case smFontSize of
- 8 : AL := $23;
- 14 : AL := $22;
- 16 : AL := $24;
- else begin
- SetVgaFont := ecNotRomFont;
- Exit;
- end;
- end;
- DL := smRows;
- end;
- end else begin
- if smIsText then begin
- AL := $10;
- BH := smFontSize;
- CX := 256;
- DX := 0;
- end else begin
- AL := $21;
- CX := smFontSize;
- DL := smRows
- end;
- ES := OS(FontBuf).S;
- BP := OS(FontBuf).O;
- end;
- end;
- end;
- Intr($10, Regs);
- SetVgaFont := 0;
- end;
-
- function PreservePalette(On: boolean): word; assembler;
- {-Supported only on VGA. If On then with a set mode the palette is not
- changed to the default. Returns ecVgaFuncNotSupported if it fails.}
- asm
- push bx
- mov ah,$12
- mov al,On
- mov bl,$31
- int $10
- cmp al,$12
- je @1
- mov ax,ecVgaFuncNotSupported
- jmp @2
- @1:
- xor ax,ax
- @2:
- pop bx
- end;
-
-
- function SetScanLines(Lines: word): word; assembler;
- {-Supported only on VGA. Selects scan lines for text modes. Valid
- values of Lines are 200, 350, 400. Returns ecVgaFuncNotSupported or
- ecVgaNotActive if function fails. Since some adapters use non-standard
- scan lines for some of their text modes, if the Lines values is not
- valid, the function does nothing and does not return an error; thus it
- depends on the proprietary mode setting to set the correct number of
- scan lines.}
- asm
- push bx
- mov ah,$12
- mov bl,$30
- mov al,2 {assume 400 scan lines}
- cmp Lines,400
- je @4
- cmp Lines,350
- je @5
- cmp Lines,200
- jne @2 {its not a standard number of scan lines so do nothing}
- @6:
- mov al,0
- jmp @4
- @5:
- mov al,1
- @4:
- int $10
- cmp al,$12
- je @2
- cmp al,0
- je @1
- mov ax,ecVgaFuncNotSupported
- jmp @3
- @1:
- mov ax,ecVgaNotActive
- jmp @3
- @2:
- xor ax,ax
- @3:
- pop bx
- end;
-
- function DisableVideoRefresh(Off: boolean): word; assembler;
- {-If Off is true, disables video refresh which blanks the screen. If Off
- is false, the video refresh is enabled. Returns status of action.}
- asm
- push bx
- push bp {this call is known to trash bp}
- mov ah,$12
- mov al,Off
- mov bl,$36
- int $10
- cmp al,$12
- je @1
- mov ax,ecVgaFuncNotSupported
- jmp @2
- @1:
- xor ax,ax
- @2:
- pop bp
- pop bx
- end;
-
- {**********************************************************}
-
- begin
- CurVideoMode := Lo(LastMode);
- CurScreenRows := Integer(ScreenHeight);
- CurScreenCols := Integer(ScreenWidth);
- end.