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). }
-
- 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;
- BiosMaxX : word absolute $0040:$004A;
- BiosCrtLength : word absolute $0040:$004C;
- BiosCursorPos : array [0..7] of word absolute $0040:0050;
- BiosCursorMode: word absolute $0040:$0060;
- BiosActivePage: byte absolute $0040:$0062;
- BiosAddr6845 : word absolute $0040:$0063;
- Bios6845Mode : byte absolute $0040:$0065;
- BiosPalette : byte absolute $0040:$0066;
- BiosMaxY : byte absolute $0040:$0084;
- BiosCharSize : word absolute $0040:$0085;
- BiosInfo : byte absolute $0040:$0087;
- BiosInfo3 : byte absolute $0040:$0087;
- BiosFlags : byte absolute $0040:$0087;
- BiosDCC : byte absolute $0040:$008A;
- BiosSavePtr : pointer absolute $0040:$00A8;
- BiosFontTable : byte absolute $F000:$FA6E;
-
- { 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(
- $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 AssignBiosCrt(var F:Text);
- { Assigns text output to BiosCrt }
- 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 (BiosMaxX - 2) do
- begin
- TtyWrite(#$20,BiosTextAttr);
- end;
- OutChar(#$20,BiosTextAttr);
- 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 the 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-} { finished with the local TFDD so return world to normal }
-
- procedure AssignBiosCrt(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.
-