home *** CD-ROM | disk | FTP | other *** search
- { Turbo Pascal XGRAPH suppport definitions, procedures and functions }
-
- Const
- { Video INT 10H constants }
- { ----------------------- }
- VideoInt = $10;
-
-
- { Video functions provided by VideoInt }
- { ------------------------------------ }
- VidSetMode = $00; VidSetCursorType = $01;
- VidSetCursorPosition = $02; VidReadCursorPosition = $03;
- VidReadLightPenPosition = $04; VidSelectActiveDisplayPage = $05;
- VidScrollActivePageUp = $06; VidScrollActivePageDown = $07;
- VidReadAtributeCharacterAtCursor= $08; VidWriteAtributeCharacterAtCursor= $09;
- VidWriteCharacterOnlyAtCursor = $0A; VidSetColorPalette = $0B;
- VidWriteDot = $0C; VidReadDot = $0D;
- VidWriteTeletype = $0E; VidCurrentVideoState = $0F;
- VidSetPaletteRegisters = $10; VidCharacterGeneratorRoutine = $11;
- VidAlternateSelect = $12; VidWriteString = $13;
- VidExtendedFunctions = $6F;
- { Xgraph functions }
- VidId = $A3; VidInit = $A4;
- VidClear = $A5; VidRectFill = $A6;
- VidLine = $A7; VidPolyFill = $A8;
- VidBlit = $A9;
- { Blit and Texturing Opcodes }
- Blit0 = 0; BlitSandD = 1; BlitSandND = 2; BlitS = 3;
- BlitNSandD = 4; BlitD = 5; BlitSxorD = 6; BlitSorD = 7;
- BlitNSandND = 8; BlitNSxorD = 9; BlitND = 10; BlitSorND = 11;
- BlitNS = 12; BlitNSorD = 13; BlitNSorND = 14; Blit1 = 15;
-
- Text0 = 0; Text1 = 1; TextS = 2; TextP = 3;
- TextSorP = 4; TextSandP = 5; TextSxorP = 6; TextNP = 7;
- TextSorNP = 8; TextSandNP = 9; TextSxorNP = 10;
-
-
- { Video Modes Possible }
- { -------------------- }
- Video40x25BW = $00; Video40x25Color = $01;
- Video80x25BW = $02; Video80x25Color = $03;
- Video320x200BW = $04; Video320x200Color = $05;
- Video640x200 = $06; VideoMonochrome = $07;
- VideoEGA320x200 = $0D; VideoEGA640x200 = $0E;
- VideoEGA640x350Mono = $0F; VideoEGA640x350Color = $10;
- VideoHerculesGraphics = $11;
- VideoMulti80x27 = $12; VideoMulti40x27 = $13;
- VideoMulti640x400 = $14; VideoMulti320x400 = $15;
-
- type
- AdapterType = (CGA, Mono, EGAEnh, EGACga, EGAMono, MultiModeHires, MultiModeCga, Hercules);
-
- VidStringType = String[80];
-
- { Record used to invoke INT 10H when needed }
- VidRegs = record
- ax, bx, cx, dx, bp, si, di, ds, es, flags: Integer
- end;
-
- Raster = Record { Graphics raster descriptor }
- Offset, Segment : integer;
- Width : integer;
- OrigenX, OrigenY: integer;
- CornerX, CornerY: integer
- end;
-
- FontDescType = Record { Font graphics descriptor }
- FontRaster : Raster;
- FontWidth : integer;
- FontHeight : integer
- end;
-
- BlitParm = Record { Paramaters passed to Blit function }
- DestOffset, DestSegment : integer;
- SrcOffset, SrcSegment : integer;
- TextOffset, TextSegment : integer;
- RectOrigenX, RectOrigenY: integer;
- RectCornerX, RectCornerY: integer;
- PointX, PointY : integer;
- Opcode, TextOp : integer
- end;
-
- { Data structure describing the video raster }
- GrfDataPtr = ^GraphicsData;
- GraphicsData = record
- { Data returned by a call to XGRAPH function VidInit }
- DestOff, DestSeg : integer;
- RasterWidth : integer;
- MinimumX, MinimumY : integer;
- MaximumX, MaximumY : integer;
- RowMask, ShiftIntr : byte;
- HomeOffset, BankOffset : integer;
- PixelsPByte : byte;
- TextureOff, TextureSeg : integer;
- FontFormOff, FontFormSeg: integer;
- Font2FormOff, Font2FormSeg: integer;
-
- { Data that must be initialize base on current video mode and adapter }
- Adapter : AdapterType;
- VideoMode : integer;
- GraphicsOn : boolean;
- CurrFont : integer;
- BitPixelDensity : integer;
- MinX, MinY, MaxX, MaxY : integer
- end;
-
- procedure GraphInit(var GrfData:GraphicsData; ModeSelect : integer);
- {
- Called to make a mode change. If ModeSelect equals -1 then the routine
- selects the mode with highest resolutions of the adapter. If
- ModeSelect is equal to one of the possible modes (see table above) and
- the adapter can support it the mode is selected.
-
- After a mode is selected the variables returned from the XGRAPH function
- VidInit are copied into GrfData and the rest of GrfData is initialize
- base on the mode.
- }
- var LocalRegs : VidRegs;
- GrfPtr : GrfDataPtr;
- LocalAdapter : AdapterType;
- LocalVideoMode : integer;
- corm, mem, switch : integer;
-
- function EGAPresent(var corm, mem, switch:integer):boolean;
- begin
- { Use test suggested on IBM PC seminar proceedings }
- LocalRegs.ax:=$1200; LocalRegs.bx:=$FF10; LocalRegs.cx:=$000F;
- Intr(VideoInt, LocalRegs);
- corm := hi(LocalRegs.bx); mem := lo(LocalRegs.bx);
- switch := lo(LocalRegs.cx);
- if (switch < $0C) and (corm <= $01) and (mem <= $03) then
- EGAPresent := true
- else
- EGAPresent := false;
- end;
-
- function MultiModePresent:boolean;
- { Tests for presence of HP's High resolution adapter }
- begin
- LocalRegs.ax := VidExtendedFunctions shl 8 + $00;
- LocalRegs.bx := $FFFF;
- Intr(VideoInt, LocalRegs);
- if LocalRegs.bx <> $4850 { 'HP' }
- then MultiModePresent := false
- else begin
- LocalRegs.ax := VidExtendedFunctions shl 8 + $01;
- Intr(VideoInt, LocalRegs);
- if lo(LocalRegs.ax) = $41
- then MultimodePresent := true
- else MultimodePresent := false;
- end;
- end;
-
- function CGAPresent:boolean;
- var crt : integer;
- begin
- Port[$3d4] := $0F;
- crt := Port[$3d5];
- Port[$3d5]:=$55;
- delay(100);
- if Port[$3d5] = $55 then begin
- CGAPresent := true;
- Port[$3d5] := crt end
- else CGAPresent:=false;
- end;
-
- begin
- { Find out type of Video Adapter }
- if EGAPresent(corm,mem,switch) then begin
- if corm = $01 then { EGA attached to monochrome monitor }
- LocalAdapter := EGAMono
- else { EGA attached to color monitor }
- if (mem > 0) and (switch = $09) then { EGA and Enhanced monitor }
- LocalAdapter := EGAEnh
- else { EGA and CGA monitor }
- LocalAdapter := EGACga
- end
- else if MultiModePresent then begin
- if (Port[$3DA] and $10)=0 then { Test for 400 line monitor }
- LocalAdapter := MultiModeHires
- else
- LocalAdapter := MultiModeCga;
- end
- else if CGAPresent then begin
- LocalAdapter := CGA
- end
- else begin { Add Hercules presence test here }
- LocalAdapter := Mono
- end;
-
- { See if mode selected is appropiate for Adapter monitor combo }
- case LocalAdapter of
- CGA, MultiModeCga: begin
- if not(ModeSelect in [Video320x200BW .. Video640x200]) then
- ModeSelect:=Video640x200;
- LocalRegs.ax := VidSetMode shl 8 + ModeSelect;
- end;
- EGACga : begin
- if not(ModeSelect in
- [Video320x200BW .. Video640x200, VideoEGA320x200 .. VideoEGA640x200])
- then ModeSelect:=VideoEGA640x200;
- LocalRegs.ax := VidSetMode shl 8 + ModeSelect;
- end;
- EGAEnh : begin
- if not(ModeSelect in
- [Video320x200BW..Video640x200, VideoEGA320x200..VideoEGA640x200,
- VideoEGA640x350Color]) then ModeSelect:=VideoEGA640x350Color;
- LocalRegs.ax := VidSetMode shl 8 + ModeSelect;
- end;
- EGAMono: begin
- if ModeSelect <> VideoEGA640x350Mono then
- ModeSelect:=VideoEGA640x350Mono;
- LocalRegs.ax := VidSetMode shl 8 + ModeSelect;
- end;
- MultiModeHires: begin
- if not(ModeSelect in [Video320x200BW..Video640x200,
- VideoMulti640x400..VideoMulti320x400]) then
- ModeSelect:=VideoMulti640x400;
- LocalRegs.ax := VidExtendedFunctions shl 8 + $05;
- If ModeSelect = VideoMulti640x400 then LocalRegs.bx:=$0D
- else if ModeSelect = VideoMulti320x400 then LocalRegs.bx:=$0E
- else LocalRegs.bx := ModeSelect;
- end;
- Hercules: begin
- ModeSelect:=VideoHerculesGraphics;
- { Call procedure to put it on Herc graphics mode here }
- end;
- else { Unknow video adapter and mode }
- ModeSelect := -1;
- end;
-
- { Put it in the appropiate video mode }
- if (LocalAdapter in
- [CGA, EGACga, EGAEnh, EGAMono, MultiModeHires, MultiModeCga])
- and (ModeSelect<>-1) then
- Intr(VideoInt, LocalRegs);
-
- { After the mode is selected, Initialize XGRAPH internal data structures }
- LocalRegs.ax := VidInit shl 8; Intr(VideoInt, LocalRegs);
- GrfPtr := Ptr(LocalRegs.es, LocalRegs.di);
-
- { and copy it to our local area, and initializing rest of variables }
- GrfData := GrfPtr^;
-
- { Calculate density of bits to pixels and actual screen size in pixels }
- with GrfData do begin
- if PixelsPByte in [0,1,2,3] then { Calculate pixel/bit density }
- case PixelsPByte of { because VidLine operates in pixels }
- 3 : BitPixelDensity := 1; { and VidBlit operates in bits. }
- 2 : BitPixelDensity := 2;
- 1 : BitPixelDensity := 4;
- 0 : BitPixelDensity := 8
- end
- else BitPixelDensity := 1;
- MinX := MinimumX div BitPixelDensity; MaxX := MaximumX div BitPixelDensity;
- MinY := MinimumY; MaxY := MaximumY;
- Adapter := LocalAdapter;
- VideoMode := ModeSelect;
- if ModeSelect <> -1 then GraphicsOn:=true else GraphicsOn:=false;
- if MaxY > 199 then CurrFont:=2 else CurrFont:=1;
- end;
- end;
-
- procedure WriteChar(ch : char; X, Y: integer; GrfData:GraphicsData);
- {
- Writes a character to raster using the BitBlit procedure and one of
- the build-in fonts (FontNum=1 => use 8x8, FontNum=2 => use 8x14).
- }
- var FontPtr : ^FontDescType;
- LocalBlitParms : BlitParm;
- LocalRegs : VidRegs;
- begin
- with LocalBlitParms do begin
- DestOffset := ofs(GrfData); DestSegment := seg(GrfData);
- if GrfData.CurrFont = 2 then
- FontPtr := Ptr(GrfData.Font2FormSeg,GrfData.Font2FormOff)
- else
- FontPtr := Ptr(GrfData.FontFormSeg,GrfData.FontFormOff);
- SrcOffset := ofs(FontPtr^.FontRaster);
- SrcSegment := seg(FontPtr^.FontRaster);
- RectOrigenX := X; RectOrigenY := Y;
- RectCornerX := X + FontPtr^.FontWidth-1;
- RectCornerY := Y + FontPtr^.FontHeight-1;
- PointX := ord(ch) * FontPtr^.FontWidth; PointY := 0;
- Opcode := BlitS; TextOp := TextS;
- end;
- LocalRegs.ax := VidBlit shl 8;
- LocalRegs.ds := seg(LocalBlitParms); LocalRegs.si := ofs(LocalBlitParms);
- LocalRegs.bx := $000F; Intr(VideoInt, LocalRegs);
- end; { of WriteChar }
-
- procedure WriteStr(Strng:VidStringType; X, Y:integer; GrfData:GraphicsData);
- {
- Write the given string at (X,Y). Clipping is done by blit if it does
- not fit on the screen.
- }
- var i : integer;
- FontPtr : ^FontDescType;
- LocalBlitParms : BlitParm;
- LocalRegs : VidRegs;
- begin
- { Set up all parameters before going into loop }
- with LocalBlitParms do begin
- DestOffset := ofs(GrfData); DestSegment := seg(GrfData);
- if GrfData.CurrFont= 2 then
- FontPtr := Ptr(GrfData.Font2FormSeg,GrfData.Font2FormOff)
- else
- FontPtr := Ptr(GrfData.FontFormSeg,GrfData.FontFormOff);
- SrcOffset := ofs(FontPtr^.FontRaster);
- SrcSegment := seg(FontPtr^.FontRaster);
- RectOrigenX := X; RectOrigenY := Y;
- RectCornerX := X + FontPtr^.FontWidth-1;
- RectCornerY := Y + FontPtr^.FontHeight-1;
- PointY := 0; Opcode := BlitS; TextOp := TextS;
- end;
- LocalRegs.ax := VidBlit shl 8;
- LocalRegs.ds := seg(LocalBlitParms); LocalRegs.si := ofs(LocalBlitParms);
- LocalRegs.bx := $000F;
- { Execute a call to blit per character in string and update X position }
- for i:=1 to ord(Strng[0]) do with LocalBlitParms do begin
- PointX := ord(Strng[i]) * FontPtr^.FontWidth; Intr(VideoInt, LocalRegs);
- RectOrigenX := RectOrigenX + FontPtr^.FontWidth;
- RectCornerX := RectCornerX + FontPtr^.FontWidth;
- end;
- end; { of WriteStr }
-
- procedure WriteInt(Value, X, Y : integer;
- Base, Width : integer;
- LeftJustify : Boolean;
- GrfData : GraphicsData );
- {
- Writes an integer to the screen at location (X,Y), in the given Base,
- within a field of Width and left of right justified. If the number is
- bigger than the field the Width and LeftJustify parameters are ignored.
- Legal bases are 2, 8, 10, 16. Any other base is ignored.
- }
- var i, temp, Select, Shift, ShiftDec : integer;
- Strng : string[16];
- begin
- Strng := '';
- if Base = 10 then Str(Value,Strng)
- else if Base in [2,8,16] then begin
- case Base of
- 2 : begin Select:=$8000; Shift:=15; ShiftDec:=1 end;
- 8 : begin
- if Value < 0 then Strng := Strng+'1'
- else Strng := Strng+'0';
- Select:=$7000; Shift:=12; ShiftDec:=3
- end;
- 16 : begin Select:=$F000; Shift:=12; ShiftDec:=4 end
- end;
- while Shift >= 0 do begin
- Temp := (Value and Select) shr Shift;
- Strng[0] := succ(Strng[0]);
- if Temp in [0..9] then
- Strng[ord(Strng[0])] := chr(ord('0')+temp)
- else
- Strng[ord(Strng[0])] := chr(ord('A')+temp-10);
- Select := Select shr ShiftDec; Shift := Shift - ShiftDec;
- end
- end;
-
- if (not LeftJustify) and (Length(Strng) < Width) then
- for i:=1 to (Width - Length(Strng)) do begin
- WriteChar(' ',X,Y,GrfData); X:=X+8;
- end;
-
- WriteStr(Strng, X, Y, GrfData);
- X := X + (Length(Strng) shl 3);
-
- if LeftJustify and (Length(Strng) < Width) then
- for i:=1 to (Width - Length(Strng)) do begin
- WriteChar(' ',X,Y,GrfData); X:=X+8;
- end;
- end;
-
- procedure ReadStr(var Inp:VidStringType; x,y:integer; GrfData:GraphicsData);
- {
- Reads a string at the given bit position on the screen. It recognizes
- Backspace and carriage return as specials characters. It treats every
- thing else as part of the string.
- }
- const
- CR = 13; BS = 8;
- var
- c : char; i : integer;
- LocX, LocY : integer;
- begin
- Inp := ''; LocX := x; LocY:=y;
- repeat
- WriteChar(chr($DB),LocX,LocY,GrfData);
- read(kbd,c);
- if (c = chr(BS)) and (ord(Inp[0])>0) then begin
- WriteChar(' ',LocX,LocY,GrfData);
- if LocX > x then LocX := LocX - 8;
- Inp[0]:=pred(Inp[0]);
- end
- else if (c <> chr(CR)) and (c <> chr(BS)) then begin
- WriteChar(c,LocX,LocY,GrfData);
- if (LocX+8) < (GrfData.MaximumX) then LocX:=LocX+8;
- if (ord(Inp[0]) < 80) then begin
- Inp[0] := succ(Inp[0]);
- Inp[ord(Inp[0])]:=c;
- end;
- end;
- until (c = chr(CR));
- WriteChar(' ',LocX,LocY,GrfData);
- end; { of ReadStr }