home *** CD-ROM | disk | FTP | other *** search
- {=============================================================================
-
- Handy-Dandy Turbo Pascal Routines (C) 1986 by Doug Senalik
-
- VID-TYPE.PAS V1.0 10/25/86
- V1.1 11/6/86 - Don't do trial write for 40x25 or
- graphics modes, it would cause the
- erasing of a char. on the screen, and
- we can't do direct write to screen in
- those modes anyway.
-
- Check to see if can write directly to video memory.
-
- Requires the following include files: none
-
- Functions: VideoDisplayType: integer
- Procedures: SnowOff (boolean)
- =============================================================================}
-
-
- const _VidWriteMode_: integer = -1; { Storage to remember the video state }
- { so we don't have to go through the }
- { whole function every time, just }
- { return this value. }
- var VideoBufferSeg: integer; { This variable can be used to con- }
- { veniently supply the video buffer }
- { segment, it is set by VideoDisplay- }
- { Type. It will be left as a $F000 }
- { if BIOS use is indicated. }
-
- function VideoDisplayType: integer;
-
- { Returns an integer describing the type of video setup currently in }
- { effect, mainly so we can decide if we can write directly to video }
- { memory. If you want to insist on BIOS writing even when direct }
- { screen writing is possible, simply set _VidWriteMode_ := 0 }
- { in your program, and set back to -1 to restore to fast method. If }
- { you anticipate using graphics modes or switching between a color }
- { and monochrome monitor, always set _VidWriteMode_ := -1 when }
- { switching video modes so you don't end up writing to video memory }
- { when you can't. }
-
- { Meaning of VideoDisplayType result: }
- { 0 = Use BIOS for writing to display }
- { 1 = Mono card, video memory at $B000 }
- { 2 = Color card, video memory at $B800 }
- { (for 1 & 2, the video memory segment }
- { is pointed to by VideoBufferSeg). }
-
- type Registers = record {For intr or msdos procedure}
- AX,BX,CX,DX,BP,SI,DI,DS,ES,Flags: integer;
- end;
- var Reg: Registers;
- PrevX, {Store original cursor position while we do stuff}
- PrevY, {"}
- Store: integer; {Store orig. char. on screen while we do test write}
-
- begin
- if _VidWriteMode_ = -1 then { If -1, then this is the first time this has }
- with Reg do { been called, so go through the determination }
- begin { procedure to determine video writing method. }
- { This will only be done ONCE. }
- PrevX:=wherex; {Save cursor position}
- PrevY:=wherey;
- VideoBufferSeg := $F000; {Point to ROM where writing can't do any harm}
-
- AX:=$0F00; {Determine current display mode}
- intr ($10, Reg);
-
- {We will be able to do a direct read or write to video memory only}
- {in 80x25 text modes, so if not one of those, skip the test}
-
- if lo(AX) in [2,3,7] then
- begin
- { Now do a test write to the display, and see if we can read what }
- { we wrote by looking at the video buffer. If not, use BIOS for }
- { all screen writing, otherwise we can write directly to memory. }
- { We go through this mess rather than just assume modes 2 and 3 }
- { indicate color graphics adaptor, and 7 indicates monochrome }
- { adaptor, because of the fact that some not so compatible PC }
- { compatibles are not so compatible. This method should be sure }
- { to get the correct result. Well, let's hope so, anyway. }
- AX:=$0200; {Set cursor position}
- BX:=$0000; {Display page 0}
- DX:=$0303; {Row 3 column 3}
- intr ($10, Reg);
- AX:=$0800; {Read char (AL) and attrib (AH) at current cursor position}
- BX:=$0000; {Display page 0}
- intr ($10, Reg);
- Store := AX; {Save character so we can restore it later}
- { Now write an uncommon character in black on black (so it is not }
- { visible). The character will be present for only milliseconds, }
- { so you probably would not have seen it on the screen anyway. }
- AX:=$099E; {Write one of the more obscure characters (Pt)}
- BX:=$0000; {BH=page, BL=attribute - Write in black on black }
- CX:=$0001; {Write one character}
- intr ($10, Reg);
-
- { See if either of the normal video buffers contains the expected }
- { character. If it does, then we will assume that we can write }
- { directly to video memory. If not, _VidWriteMode_ will remain }
- { at 0, indicating the need to use BIOS routines. }
- _VidWriteMode_ := 0; {BIOS assumed unless we determine otherwise}
- if memw[$B000:$01E6] = $009E then {Row 3 col 3 memory location}
- begin
- _VidWriteMode_ := 1; {Monochrome buffer in effect}
- VideoBufferSeg := $B000;
- end;
- if memw[$B800:$01E6] = $009E then {Row 3 col 3 memory location}
- begin
- _VidWriteMode_ := 2; {Color buffer in effect}
- VideoBufferSeg := $B800;
- end;
-
- { Restore the display to its original state }
- AX:=$0900 + lo(Store); {Put original character (in AL) back}
- BX:={0000 +}hi(Store); {and attribute (BL), display page 0 (BH)}
- CX:=$0001; {Write one character}
- intr ($10, Reg);
- gotoxy (PrevX, PrevY); {Restore cursor position}
- end; {if lo(AX) in [2,3,7]}
-
- end; {with Reg}
-
- VideoDisplayType := _VidWriteMode_;
-
- end; {VideoDisplayType}
-
-
- procedure SnowOff (TurnOff: boolean);
- { Turns video on or off to avoid read/write snow on Color Graphics Adaptor. }
- { All other monitor types do not have this problem, so this procedure will }
- { not do anything unless VideoDisplayType = 2 }
-
- const VideoEnableOn = $08; { Video Signal Enable Bit }
- VideoEnableOff = $F7; { and its inverse }
- var CrtAdapter: integer absolute $0040:$0063; { ADDR_6845 in BIOS data area }
- VideoMode: byte absolute $0040:$0065; { CRT_MODE_SET in BIOS data area }
-
- begin
- if VideoDisplayType = 2 then {Only do anything if using CGA}
- if TurnOff then
- port[CRTAdapter+4] := VideoMode and VideoEnableOff
- else {TurnOff = false}
- port[CRTAdapter+4] := VideoMode or VideoEnableOn;
- end; {SnowOff}
-
-
- {End of file}