home *** CD-ROM | disk | FTP | other *** search
-
- { -********************************************************************** -}
- { BIOSCRT - A unit to allow text output through the standard BIOS calls }
- { This unit will work in both text and graphics modes. It was primarily }
- { written to allow use of the MS-DOS system font in graphics mode to }
- { compensate for the current lack of a BGI system font. Note: This method }
- { will *NOT* work with most Hercules boards because they don't properly }
- { support the BIOS calls in graphics mode. }
- { }
- { Notes: If you are using this unit on a CGA in the graphics mode, you }
- { should run the GRAFTABL program from your DOS supplimental program disk }
- { (this loads the extended CGA charater set into memory). }
- { }
- { To make this into a fully operational CRT type unit you will need to }
- { obtain a copy of Carley Phillips' "CRTI" unit which can be found on }
- { CompuServe in the Borland BPROGA Turbo library (DL2). Carley's CRTI }
- { unit will provide you with the sound, delay, and keyboard procedures. }
- { }
- { Written by Michael Day 23 August 1988 CIS:[73577,2225] }
- { Updated to Version 2.0 and renamed to BiosCrt 29 August 1988 }
- { This unit is released to the public domain by the author }
- { Mike Day UUCP:...!tektronix!reed!qiclab!bakwatr!mikeday }
- { Chief Bit Washer, Day Research, P.O. Box 22902, Milwaukie, OR 97222 }
- { Plans?...We don't need no stinkin' plans! }
- { -********************************************************************** -}
-
- Unit BiosCrt;
-
- interface
- uses Dos;
-
- var BiosWriteMode : byte; {Bios write mode to use for TFDD}
- BiosTextAttr : byte; {Bios text attribute byte}
- BiosStartAttr : byte; {Original startup attr}
- LastBiosMode : byte; {last Bios screen mode in use}
- LastBiosWidth : byte; {last Bios screen width used}
- LastBiosPage : byte; {last Bios screen page used}
-
- {--------------------------------------------------------------------------}
- {-- Below are listed the important Bios variables for the video display. --}
- {-- These are set by the Bios and are provided for reading only. Do not --}
- {-- change any of these values or irratic display operation will result. --}
-
- BiosMode : byte absolute $0040:$0049; {Current bios video mode}
- BiosMaxX : word absolute $0040:$004A; {Text cols on display}
- BiosCrtLength : word absolute $0040:$004C; {Crt buffer size in bytes}
- BiosCursorPos : array [0..7] of word absolute $0040:0050; {Cursor pos}
- BiosCursorMode: word absolute $0040:$0060; {Current cursor mode}
- BiosActivePage: byte absolute $0040:$0062; {Current active video page}
- BiosAddr6845 : word absolute $0040:$0063; {I/O address of controller}
- Bios6845Mode : byte absolute $0040:$0065; {Current 6845 mode value}
- BiosPalette : byte absolute $0040:$0066; {Current palette selected}
- BiosMaxY : byte absolute $0040:$0084; {Text rows on display -1}
- BiosCharSize : word absolute $0040:$0085; {Height of character cell}
- BiosInfo : byte absolute $0040:$0087; {Misc video control info}
- BiosInfo3 : byte absolute $0040:$0087; {Display card switch info}
- BiosFlags : byte absolute $0040:$0087; {Misc video control flags}
- BiosDCC : byte absolute $0040:$008A; {Display Combination Code}
- BiosSavePtr : pointer absolute $0040:$00A8; {Pointer to Bios save area}
- BiosFontTable : byte absolute $F000:$FA6E; {CGA (8x8) Bios font table}
-
- {++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}
- {-- The following are the inline macros used to access the BIOS routines --}
-
- function BiosWhereX:integer; {get current cursor X pos}
- inline(
- $B7/$00 { mov BH,0}
- /$B4/$03 { mov AH,3}
- /$55 { push BP}
- /$CD/$10 { int $10}
- /$5D { pop BP}
- /$30/$E4 { xor AH,AH}
- /$88/$D0); { mov AL,DL}
-
- function BiosWhereY:integer; {get current cursor Y pos}
- inline(
- $B7/$00 { mov BH,0}
- /$B4/$03 { mov AH,3}
- /$55 { push BP}
- /$CD/$10 { int $10}
- /$5D { pop BP}
- /$30/$E4 { xor AH,AH}
- /$88/$F0); { mov AL,DH}
-
- procedure BiosWhereXY(var X,Y:integer); {get current cursor X,Y pos}
- inline(
- $B7/$00 { mov BH,0}
- /$B4/$03 { mov AH,3}
- /$55 { push BP}
- /$CD/$10 { int $10}
- /$5D { pop BP}
- /$07 { pop ES}
- /$5B { pop BX}
- /$26/$88/$37 { mov ES:[BX],DH}
- /$07 { pop ES}
- /$5B { pop BX}
- /$26/$88/$17); { mov ES:[BX],DL}
-
-
- procedure BiosGotoXY(X,Y:integer); {move cursor to indicated X,Y}
- inline(
- $58 { pop AX}
- /$5A { pop DX}
- /$88/$C6 { mov DH,AL}
- /$B7/$00 { mov BH,0}
- /$B4/$02 { mov AH,2}
- /$55 { push BP}
- /$CD/$10 { int $10}
- /$5D); { pop BP}
-
- procedure BiosTextColor(FColor:integer); {Set text foreground color}
- inline(
- $58 { pop AX}
- /$24/$0f { and AL,$0F}
- /$8A/$26/>BiosTextAttr { mov AH,[>BiosTextAttr]}
- /$80/$E4/$F0 { and AH,$F0}
- /$08/$E0 { or AL,AH}
- /$A2/>BiosTextAttr); { mov [>BiosTextAttr],AL}
-
- procedure BiosTextBackGround(BColor:integer); {Set text background color}
- inline(
- $58 { pop AX}
- /$B1/$04 { mov CL,4}
- /$D2/$E0 { shl AL,CL}
- /$8A/$26/>BiosTextAttr { mov AH,[>BiosTextAttr]}
- /$80/$E4/$0F { and AH,$0F}
- /$08/$E0 { or AL,AH}
- /$A2/>BiosTextAttr); { mov [>BiosTextAttr],AL}
-
- function GetBiosTextAttr:integer; {Get the current Bios text Attribute}
- Inline(
- $B7/$00 { mov BH,0}
- /$B4/$08 { mov AH,8}
- /$55 { push BP}
- /$CD/$10 { int $10}
- /$5D { pop BP}
- /$88/$E0 { mov AL,AH}
- /$30/$E4); { xor AH,AH}
-
- procedure SetBiosWriteMode(Mode:integer); {Set Bios write mode to use}
- inline( {0=Reg, 1=Xor, 2=Bk}
- $58 { pop AX}
- /$A2/>BiosWriteMode); { mov [>BiosWriteMode],AL}
-
- procedure SetBiosPage(Page:integer); {set active bios video page}
- inline(
- $58 { pop AX}
- /$B4/$05 { mov AH,5}
- /$55 { push BP}
- /$CD/$10 { int $10}
- /$5D); { pop BP}
-
- procedure BiosCursorOFF; {turn the cursor off}
- inline(
- $B4/$03 { mov AH,3}
- /$55 { push BP}
- /$CD/$10 { int $10}
- /$5D { pop BP}
- /$80/$CD/$20 { or ch,$20}
- /$B4/$01 { mov AH,1}
- /$55 { push BP}
- /$CD/$10 { int $10}
- /$5D); { pop BP}
-
- procedure BiosCursorON; {turn the cursor on}
- inline(
- $B4/$03 { mov AH,3}
- /$55 { push BP}
- /$CD/$10 { int $10}
- /$5D { pop BP}
- /$80/$E5/$1F { and CH,$1F}
- /$B4/$01 { mov AH,1}
- /$55 { push BP}
- /$CD/$10 { int $10}
- /$5D); { pop BP}
-
- {++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}
- {-- The following are the string procedures to access the BIOS routines ---}
-
- procedure BiosWrite(S:String); {Bios based text write}
- procedure BiosWriteLn(S:String); {Bios based text writeln}
-
- procedure BiosClrEol; {clear to end of line}
- procedure BiosClrScr; {clear the screen}
- procedure BiosLowVideo; {turns off high intensity attr bit}
- procedure BiosHighVideo; {turns on high intensity attr bit}
- procedure BiosNormalVideo; {restores video attr to start up value}
- procedure AssignBiosText(var F:Text); {assigns text output to BiosText}
- procedure BiosTextMode(Mode:byte); {sets new Bios video display mode}
- procedure BiosPixGoto(X,Y:integer); {goto character at pixel location}
-
- { -********************************************************************** -}
- implementation
-
-
- {++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}
- {-- The following are the inline macros used to access the BIOS routines --}
-
- {-- Write Bios character via TTY write --}
- procedure TtyWrite(Ch:Char; Color:integer);
- Inline(
- $5B { pop BX}
- /$58 { pop AX}
- /$B4/$0E { mov AH,14}
- /$55 { push BP}
- /$CD/$10 { int $10}
- /$5D); { pop BP}
-
- {-- Write Bios character via Char/Attribute write --}
- procedure OutChar(Ch:Char; Color:integer);
- Inline(
- $5B { pop BX}
- /$58 { pop AX}
- /$B9/$01/$00 { mov CX,1}
- /$B4/$09 { mov AH,9}
- /$55 { push BP}
- /$CD/$10 { int $10}
- /$5D); { pop BP}
-
- {-- This does a Bios based screen scroll --}
- procedure BiosScrollUp(StartXY,EndXY,Lines:word);
- inline(
- $58 { pop AX}
- /$5A { pop DX}
- /$59 { pop CX}
- /$8A/$3E/>BiosTextAttr { mov BH,[>BiosTextAttr]}
- /$B4/$06 { mov AH,6}
- /$55 { push BP}
- /$CD/$10 { int $10}
- /$5D); { pop BP}
-
- {-- This does a Bios based screen scroll --}
- procedure BiosScrollDown(StartXY,EndXY,Lines:word);
- inline(
- $58 { pop AX}
- /$5A { pop DX}
- /$59 { pop CX}
- /$8A/$3E/>BiosTextAttr { mov BH,[>BiosTextAttr]}
- /$B4/$07 { mov AH,7}
- /$55 { push BP}
- /$CD/$10 { int $10}
- /$5D); { pop BP}
-
- {This updates the LastBios registers prior to a call that changes them}
- procedure SaveLastBiosMode;
- inline(
- $B4/$0F { mov AH,15}
- /$55 { push BP}
- /$CD/$10 { int $10}
- /$5D { pop BP}
- /$A2/>LastBiosMode { mov [>LastBiosMode],AL}
- /$88/$26/>LastBiosWidth { mov [>LastBiosWidth],AH}
- /$88/$3E/>LastBiosPage); { mov [>LastBiosPage],BH}
-
- {Sets the display mode to the values given}
- procedure ForceBiosMode(Mode:byte);
- inline(
- $58 { pop AX}
- /$B4/$00 { mov AH,0}
- /$55 { push BP}
- /$CD/$10 { int $10}
- /$5D); { pop BP}
-
- {++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}
- {This saves the current Bios display mode in the LastMode registers}
- {Then updates the display to the new mode value given}
- procedure BiosTextMode(Mode:byte);
- begin
- SaveLastBiosMode;
- ForceBiosMode(Mode);
- end;
-
- {--------------------------------------------------------------------------}
- procedure BiosLowVideo; {turns off high intensity attr bit}
- begin
- BiosTextAttr := BiosTextAttr and $08;
- end;
-
- {--------------------------------------------------------------------------}
- procedure BiosHighVideo; {turns on high intensity attr bit}
- begin
- BiosTextAttr := BiosTextAttr or $08;
- end;
-
- {--------------------------------------------------------------------------}
- procedure BiosNormalVideo; {restores video attr to start up value}
- begin
- BiosTextAttr := BiosStartAttr;
- end;
-
- {--------------------------------------------------------------------------}
- {Clear to the end of the text line starting from the current X position}
- procedure BiosClrEol;
- var i,x,y : integer;
- begin
- BiosWhereXY(x,y);
- for i := BiosWhereX to pred(BiosMaxX) do
- begin
- TtyWrite(#$20,BiosTextAttr);
- end;
- BiosGotoXY(x,y);
- end;
-
- {--------------------------------------------------------------------------}
- {Clear the entire screen}
- {Warning: in Graphics mode you must set both foreground and background}
- {to the desired color to be used or strange things will happen}
- procedure BiosClrScr;
- begin
- if BiosMaxY = 0 then
- BiosScrollUp(0,(24 shl 8) or pred(BiosMaxX),0)
- else
- BiosScrollUp(0,(BiosMaxY shl 8) or pred(BiosMaxX),0);
- end;
-
- {--------------------------------------------------------------------------}
- {Delete a line from the screen}
- {Warning: in Graphics mode you must set both foreground and background}
- {to the desired color to be used or strange things will happen}
- procedure BiosDelLine;
- begin
- if BiosMaxY = 0 then
- BiosScrollUp(BiosWhereY shl 8,(24 shl 8) or pred(BiosMaxX),0)
- else
- BiosScrollUp(BiosWhereY shl 8,(BiosMaxY shl 8) or pred(BiosMaxX),0);
- end;
-
- {--------------------------------------------------------------------------}
- {Insert a line on the screen}
- {Warning: in Graphics mode you must set both foreground and background}
- {to the desired color to be used or strange things will happen}
- procedure BiosInsLine;
- begin
- if BiosMaxY = 0 then
- BiosScrollDown(BiosWhereY shl 8,(24 shl 8) or pred(BiosMaxX),0)
- else
- BiosScrollDown(BiosWhereY shl 8,(BiosMaxY shl 8) or pred(BiosMaxX),0);
- end;
-
- {--------------------------------------------------------------------------}
- {goto to the closest character X,Y point based on the Pixel X,Y coordinate }
- procedure BiosPixGoto(X,Y:integer);
- var CxSize,CySize : integer;
- begin
- CySize := BiosCharSize;
- if CySize = 0 then CySize := 8;
- CxSize := 8;
- BiosGotoXY(X div CxSize,Y div CySize);
- end;
-
- {++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}
- procedure BWrite(Attr,Count:integer; Buf:Pointer);
- type BufArray = array[0..65521] of char;
- BufPtr = ^BufArray;
- var P : BufPtr;
- i : integer;
- begin
- P := Buf;
- i := 0;
- While i < Count do
- begin
- TtyWrite(P^[i],Attr);
- inc(i);
- end;
- end;
-
- {--------------------------------------------------------------------------}
- procedure BkWrite(FColor,BColor,Count:integer; Buf:Pointer);
- type BufArray = array[0..65521] of char;
- BufPtr = ^BufArray;
- var P : BufPtr;
- i : integer;
- begin
- P := Buf;
- i := 0;
- While i < Count do
- begin
- OutChar(#10,BColor); {Output a block character}
- OutChar(#9,BColor or $80); {Fill in the hole}
- TtyWrite(P^[i],(BColor xor FColor) or $80); {Then write char}
- inc(i);
- end;
- end;
-
- {--------------------------------------------------------------------------}
- procedure FastBkWrite(FColor,BColor,Count:integer; Buf:Pointer);
- type BufArray = array[0..65521] of char;
- BufPtr = ^BufArray;
- var P : BufPtr;
- i : integer;
- begin
- P := Buf; {this works just like BkWrite, but assumes that}
- i := 0; {the #219 character is available in the system}
- While i < Count do {for CGA systems this means that you must run}
- begin {the GRAFTABL program from your DOS disk first}
- OutChar(#219,BColor); {Output a block character}
- TtyWrite(P^[i],(BColor xor FColor) or $80); {Then write char}
- inc(i);
- end;
- end;
-
- {++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}
- {-- Write a string via the Bios TTY write function --}
- procedure BiosWrite(S:String);
- begin
-
- case BiosWriteMode of
- 1 : BWrite((BiosTextAttr and $0f) or $80,Length(S),Addr(S[1]));
- 2 : BkWrite(BiosTextAttr and $0f,(BiosTextAttr shr 4) and $0f,
- Length(S),Addr(S[1]));
- 3 : FastBkWrite(BiosTextAttr and $0f,(BiosTextAttr shr 4) and $0f,
- Length(S),Addr(S[1]));
- else
- BWrite(BiosTextAttr and $0f,Length(S),Addr(S[1]));
- end;
- end;
-
- {--------------------------------------------------------------------------}
- {-- Same thing as BiosWrite, but with CRLF added --}
- procedure BiosWriteLn(S:String);
- begin
- BiosWrite(S);
- TtyWrite(#10,BiosTextAttr);
- TtyWrite(#13,BiosTextAttr);
- end;
-
-
- { -********************************************************************** -}
- { }
- {- The following are the procedures which allows BiosWrite to use a TFDD -}
- { }
- { -********************************************************************** -}
-
- {$F+} { force fall calls for TFDD }
-
- {++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}
- {-- Ignore this function call --}
- function TfddBiosIgnore(var F:TextRec):integer;
- begin
- TfddBiosIgnore := 0;
- end;
-
- {--------------------------------------------------------------------------}
- {-- Write a string via the Bios TTY write function --}
- {-- background is palette(0) - (usually black) --}
- function TfddBiosWrite(var F:TextRec):integer;
- begin
- with F do
- begin
- case BiosWriteMode of
- 1 : BWrite((BiosTextAttr and $0f) or $80,BufPos,BufPtr);
- 2 : BkWrite(BiosTextAttr and $0f,(BiosTextAttr shr 4) and $0f,
- BufPos,BufPtr);
- 3 : FastBkWrite(BiosTextAttr and $0f,(BiosTextAttr shr 4) and $0f,
- BufPos,BufPtr);
- else
- BWrite(BiosTextAttr and $0f,BufPos,BufPtr);
- end;
- BufPos := 0;
- end;
- TfddBiosWrite := 0;
- end;
-
- {$F-} { done with local TFDD so return world to normal }
-
- procedure AssignBiosText(var F:Text);
- begin
- with TextRec(F) do
- begin
- Handle := $FFFF;
- Mode := fmClosed;
- BufSize := SizeOf(Buffer);
- BufPtr := @Buffer;
- OpenFunc := @TfddBiosIgnore;
- CloseFunc := @TfddBiosIgnore;
- FlushFunc := @TfddBiosWrite;
- InOutFunc := @TfddBiosWrite;
- Name[0] := #0;
- end;
- end;
-
- { -********************************************************************** -}
- {init with current known attribute by reading the screen}
- begin
- BiosStartAttr := GetBiosTextAttr;
- BiosTextAttr := BiosStartAttr;
- BiosWriteMode := 0;
- SaveLastBiosMode;
- end.
-
- (* *************************************************************************
- -- BiosCrt --
- What it is and what it does
-
- The variables, functions, and procedures available to the outside are shown
- below. Note that mixing the use of BiosCrt and other CRT type routines may
- cause confusion as to which background/foreground color is to be used. The
- BiosCrt will always use it's own foreground (from BiosTextAttr), and uses
- the existing Bios background. In Xor write the background is unchanged, and
- the characters are Xored into the foreground. The special BiosBkWrite
- procedure allows you to write your own background in graphics mode attribute
- in alpha mode). In graphics mode the background is generated by writing a
- solid block in the foreground and then writting the desired character on
- top with a preXored color. For this to work properly the Bios Background
- should be black (Palette(0) = black). This is because the #219 Block
- character is not normally available in CGA, so two characters that are
- available are used to simulate a block character. BiosWriteMode(3) is the
- same as mode 2, but assumes that the #219 character is available. This
- can be done by running the GRAFTABL program first for CGA displays.
-
- A Text File Device Driver has been added to the unit so that you can use the
- standard write procedures to perform the output. The simple string based
- procedure has also been retained for those who would prefer not to use the
- TFDD (Though I don't know why you wouldn't).
-
-
- There are many structures provided in this unit that may not be used by all
- programs. If you find that you are curious about what the code is doing I
- strongly recommend the book "Programmer's Guide to PC & PS/2 Video Systems."
- by Richard Wilton from MicroSoft Press. If you are doing any programming for
- video systems on the PC this book is a must have.
-
- --> Note: this unit will NOT work with most Hercules cards since they don't
- --> properly support the Bios in graphics mode.
-
- function BiosWhereX:integer; {get current cursor X pos}
- function BiosWhereY:integer; {get current cursor Y pos}
- function GetBiosTextAttr:integer; {Get the current Bios text Attribute}
- function GetBiosMode:integer; {Get the current Bios display mode}
- function GetBiosPage:integer; {Get the current Bios display page}
- function GetBiosWidth:integer; {Get the current Bios display width}
-
- procedure AssignBiosText(var F:Text); {assigns text output to BiosText}
- procedure BiosWhereXY(var X,Y:integer); {get current cursor X,Y pos}
- procedure BiosGotoXY(X,Y:integer); {move cursor to indicated X,Y}
- procedure BiosPixGoto(X,Y:integer); {goto character at pixel location}
- procedure BiosTextColor(FColor:integer); {Set text foreground color}
- procedure BiosTextBackGround(BColor:integer); {Set text background color}
- procedure BiosTextMode(Mode:byte); {sets new Bios video display mode}
- procedure BiosLowVideo; {turns off high intensity attr bit}
- procedure BiosHighVideo; {turns on high intensity attr bit}
- procedure BiosNormalVideo; {restores video attr to start up value}
- procedure BiosClrEol; {clear to end of line}
- procedure BiosClrScr; {clear the screen}
- procedure BiosCursorON; {turn the cursor on}
- procedure BiosCursorOFF; {turn the cursor off}
- procedure SetBiosPage(Page:integer); {set active bios video page}
- procedure SetBiosWriteMode(Mode:integer); {Set Bios write mode to use}
-
- procedure BiosWrite(S:String); {Bios based text write}
- procedure BiosWriteLn(S:String); {Bios based text writeln}
-
- ************************************************************************* *)
-
-