home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Share Gallery 1
/
share_gal_1.zip
/
share_gal_1
/
GA
/
GA028.ZIP
/
PLOT.INC
< prev
next >
Wrap
Text File
|
1986-08-27
|
14KB
|
415 lines
{**** Include file containing EGA Graphics primitives. ****}
(****************************************************)
(* COPYRIGHT (C) 1986 by Kevin McCarty. *)
(* All commercial use prohibited. *)
(* Permission is granted for copying, distribution, *)
(* adaptation, and incorporation into other works, *)
(* but for personal or educational use only, *)
(* and this notice is to be preserved. *)
(****************************************************)
CONST
XDOTMAX = 639; { highest possible horizontal resolution }
YDOTMAX = 349; { highest possible vertical resolution }
TYPE
Registers = RECORD
CASE integer OF
0: (AX, BX, CX, DX, BP, SI, DI, DS, ES, Flags : Integer);
1: (AL,AH, BL,BH, CL,CH, DL,DH : Byte);
END;
Palette_Registers = array [0..16] of byte;
Rainbow = array [1..15] of byte;
CONST
EGA_10 : Palette_Registers = ( { For mode $10 ONLY (ECD) }
0, 1, 2, 3, 4, 5, $14, 7,
$38, $39, $3A, $3B, $3C, $3D, $3E, $3F, 0);
EGA_0E : Palette_Registers = ( { For mode $0E ONLY (COLOR DISP) }
0, 1, 2, 3, 4, 5, 6, 7,
$10, $11, $12, $13, $14, $15, $16, $17, 0);
ColorList : rainbow = (
LightCyan, {start with some bright colors}
LightMagenta, Magenta,
Red, LightRed,
Brown, Yellow,
LightGreen, Green,
Blue, LightBlue,
White, LightGray,
DarkGray, Cyan { put all the dull colors last}
);
VAR
Rec : Registers;
Xaddr : array [0..XDOTMAX] of integer;
Yaddr : array [0..YDOTMAX] of integer;
Point : array [0..XDOTMAX] of integer;
Hue : Palette_Registers; { EGA palette values }
MaxXdot : integer; { highest usable horizontal dot coordinate }
MaxYdot : integer; { highest usable vertical dot coordinate }
Mono : boolean; { only one color }
EGAthere : boolean; { true if EGA }
CGAthere : boolean; { true if CGA and not EGA }
XorDot : boolean; { if mono, XOR pixels, else use OR }
MaxColor : integer; { number of non-black colors available }
G_Mode : integer;
T_Mode : integer;
PaletteNo : integer; { for graphics mode 4-6 }
MaxPalette : integer;
resp : char;
PROCEDURE Set_Palette;
BEGIN
REPEAT
CASE G_Mode OF
4: BEGIN
Writeln('Select Palette Number:');
Writeln('0) Green Red Brown');
Writeln('1) Cyan Magenta Light Grey');
Writeln('2) Light Green Light Red Yellow');
Write ('3) Light Cyan Light Magenta White : ');
MaxPalette := 3;
END;
5: BEGIN
Writeln('Select Palette Number:');
Writeln('0) Blue Red Light Grey');
Write ('1) Light Blue Light Red White :');
MaxPalette := 1;
END;
6: BEGIN
Write ('Select Background Color: (0 - 15):');
MaxPalette := 15;
END;
ELSE MaxPalette := 0;
END; (* CASE *)
IF MaxPalette > 0 THEN Readln(PaletteNo);
UNTIL (MaxPalette <= 0) OR (PaletteNo in [0..MaxPalette]);
END; (* Set_Palette *)
PROCEDURE Cycle_Palette;
VAR
i, j1, j2 : integer;
c : byte;
BEGIN
PaletteNo := (PaletteNo + 1) mod (MaxPalette + 1);
CASE G_Mode OF
4, 5: Palette (PaletteNo);
6: GraphBackground (PaletteNo); { actually a color, not a palette }
$E, $10: { 16-color EGA }
BEGIN
{ cycle palette colors one step through the rainbow }
{ black and overscan values stay put at 0 }
c := hue [ ColorList [1]];
FOR i := 1 TO 14 DO
BEGIN
j1 := ColorList [i];
j2 := ColorList [i + 1];
hue [j1] := hue [j2];
END;
hue [j2] := c;
{now reprogram palette }
{don't worry-- mode set to text mode will
restore old values back to normal }
WITH rec DO
BEGIN
AX := $1002; { program all registers }
ES := Seg(Hue);
DX := Ofs(Hue);
Intr ($10, rec);
END;
END; { 16-color EGA }
END; { CASE }
END; (* Cycle_Palette *)
PROCEDURE Init_Graphics;
{ determine appropriate graphics mode to use }
{ If EGA present then
if mono then mode $0F, 640x350, 1 color;
if color then mode $0E, 640x200, 15 colors;
if ECD then mode $10, 640x350, 15 colors; (256k)
Else if CGA present then
User choice of mode $04, 320x200, 3 colors;
or mode $05, 320x200, 3 colors;
or mode $06, 640x200, 1 color;
Else you're out of luck
}
VAR
i : integer;
Equipflag: integer;
Switches : byte;
EGAInfo : byte;
BEGIN
PaletteNo := 0;
MaxPalette := 0;
MaxColor := 0;
EGAthere := false;
CGAthere := false;
WITH rec DO
BEGIN
{ If EGA is present, then use it }
AX := $1200; { EGA information }
BX := $0010;
CX := $00FF; { preset CX in case EGA not there }
Intr ($10, rec);
Switches := CL AND $0F;
EGAthere := (Switches <> $0F);
IF EGAthere THEN
BEGIN
EGAInfo := Mem [$40 : $87];
Mono := EGAthere AND ((EGAInfo AND 2) = 2);
T_Mode := 3; { unless mono... }
IF Mono THEN
BEGIN
G_Mode := $0F; { 640 X 350 monochrome }
T_Mode := $07;
MaxXdot := XDOTMAX; MaxYdot := YDOTMAX;
MaxColor := 1;
Write('XOR Dots (Y/N): ');
Read(kbd,resp);
XorDot := (UpCase(resp) = 'Y');
END
ELSE { Color Display or ECD }
{ see EGA Tech. Ref. p. 108 }
CASE switches OF
6 : BEGIN { Color 40 X 25 -- 320 X 200 }
G_Mode := $0D;
MaxXdot := 319; MaxYdot := 199;
MaxColor := 15;
Hue := EGA_0E;
END;
7 : BEGIN { Color 80 X 25 -- 640 X 200 }
G_Mode := $0E;
MaxXdot := 639; MaxYdot := 199;
MaxColor := 3;
Hue := EGA_0E;
END;
8, { Enhanced color -- normal mode, or }
9 : BEGIN { Enhanced color -- enhanced mode }
G_Mode := $10;
MaxXdot := 639; MaxYdot := 349;
MaxColor := 15;
Hue := EGA_10;
END;
ELSE { Default to 640 X 200 mode}
BEGIN
G_Mode := $0E;
MaxXdot := 639; MaxYdot := 199;
MaxColor := 15;
Hue := EGA_0E;
END;
END; { CASE }
END { EGAthere}
ELSE
BEGIN { verify presence of CGA }
Intr ($11, rec); { determine hardware }
Equipflag := AL;
CGAthere := (Equipflag AND $30) IN [$10,$20];
IF CGAthere THEN
BEGIN
T_Mode := 3;
REPEAT
Writeln('Select Graphics Mode:');
Writeln('4) 3-Color Lo-Res (320x200)');
Writeln('5) 3-Color Lo-Res (320x200)');
Write ('6) Monochrome Hi-Res (640x200): ');
Readln(G_Mode);
UNTIL G_Mode in [4,5,6];
CASE G_Mode OF
4, 5: BEGIN
MaxXdot := 319; MaxYdot := 199;
MaxColor := 3;
MaxPalette := 3;
END;
6: BEGIN
MaxXdot := 639; MaxYdot := 199;
MaxColor := 1;
MaxPalette := 15;
END;
END; { CASE }
Set_Palette;
END { CGAthere }
ELSE
BEGIN
Writeln('No graphics hardware detected!');
Writeln('I give up!');
Halt;
END;
END; { not EGAthere }
END; { WITH }
Writeln;
Writeln('Using Graphics Mode ',G_Mode:2);
Writeln(MaxXdot+1:3, ' x ',MaxYdot+1:3, ' Resolution with ',Maxcolor+1:2,
' colors.');
Writeln('Will return to Text Mode ',T_Mode:2);
{**** Arrays used to avoid repetitive address calculations.}
FOR i := 0 TO YDOTMAX DO Yaddr [i] := 80*i;
FOR i := 0 TO XDOTMAX DO Xaddr [i] := i DIV 8;
FOR i := 0 TO XDOTMAX DO Point [i] := $80 SHR (i MOD 8)
END; (* Init_Graphics *)
Procedure Graphics_Mode;
BEGIN
Write('Press any key when ready---');
Read(kbd,ch);
IF EGAthere THEN
BEGIN
rec.ax := G_Mode;
Intr ($10,rec); { switch to graphics mode }
END
ELSE { must be CGA }
CASE G_Mode OF
6: BEGIN
Hires;
HiResColor (PaletteNo);
END;
4: BEGIN
GraphColorMode;
Palette (PaletteNo);
END;
5: BEGIN
GraphMode;
Palette (PaletteNo);
END;
END; { CASE }
END; (* Graphics_Mode *)
Procedure Text_Mode;
BEGIN
IF EGAthere THEN
BEGIN
rec.ax := T_Mode;
Intr ($10,rec); { switch to text mode }
END
ELSE { must be CGA }
TextMode;
END; (* Text_Mode *)
PROCEDURE CgaPlot (x, y, color : INTEGER);
BEGIN (* Use Turbo's builtin CGA Plot *)
Plot (x, y, color);
END; (* CgaPlot *)
PROCEDURE EgaPlot (bitmask, addr, color : integer);
{ plot a dot of given color at given pixel bit address }
{ based on EGA information in BYTE Magazine's
Special Issue on IBM PC, September 1985 }
VAR scratch : byte;
BEGIN
Port [$3CE] := 8;
Port [$3CF] := bitmask;
Mem [$A000:addr] := Mem [$A000:addr] AND 0; { latch bit planes }
{ set bit planes to zero }
Port [$3C4] := 2; { map mode }
Port [$3C5] := color;
Mem [$A000:addr] := Mem [$A000:addr] OR $FF;
Port [$3C4] := 2;
Port [$3C5] := $F;
Port [$3CE] := 8;
Port [$3CF] := $FF;
END; (* EgaPlot *)
PROCEDURE Plot (x, y, color : INTEGER);
{ NOTE: for mono displays, using XOR instead of OR below
can have quite a pleasant effect: instead of display getting
denser and denser, the image +glistens+ and ~coruscates~}
{ NOTE: There are actually THREE colors on an EGA-controlled
monochrome display: off, on, and bright (blinking doesn't count)}
VAR
total : integer;
BEGIN
{ If out of range then don't plot anything }
IF (x >= 0) AND (x <= MaxXdot) AND (y >= 0) AND (y <= MaxYdot) THEN
IF EGAthere THEN
BEGIN
total := Xaddr [x] + Yaddr [y];
{ EGA graphics memory is sequential starting at $A000 }
IF Mono THEN CASE XorDot OF
true: MEM [$A000: total] := point [x] XOR MEM [$A000: total];
false: MEM [$A000: total] := point [x] OR MEM [$A000: total];
END
ELSE
EgaPlot (point [x], total, color);
END
ELSE { CGAthere }
CgaPlot (x, y, color);
END; (* Plot *)
(**** PROCEDURES FOR GRAPHICS SCREEN DUMPS *****)
FUNCTION Pixels (addr : integer): byte;
{ return byte with bits set wherever nonzero pixel values at addr }
{ used for monochrome graphics screen dump }
VAR
bits, mask : byte;
i : integer;
BEGIN
bits := 0;
FOR i := 3 DOWNTO 0 DO
BEGIN
Port [$3CE] := 4; { Read Map Select Register }
Port [$3CF] := i; { bit plane number }
bits := bits OR Mem [$A000:addr];
END;
Pixels := bits
END; (* Pixels *)
PROCEDURE Screen_Dump;
{ adapted from "Scientific Graphics with the EGA"
by Victor Mansfield, PC Tech Journal, v.3 n.9, Sept 1985
Copyright 1985 by Ziff-Davis Publishing Company }
VAR
xindx, yindx : integer;
init_char : string [4];
BEGIN
{ codes are for EPSON graphics modes }
IF EGAthere THEN
BEGIN { Do it the hard way }
WRITELN(LST,CHR(27)+'A'+CHR(7));
INIT_CHAR := CHR(27)+'K'+CHR(94)+CHR(1);
FOR xindx := 0 TO 79 DO
BEGIN
WRITE (LST, init_char);
FOR yindx:=YDOTMAX DOWNTO 0 DO
WRITE (LST, CHR (Pixels (Yaddr [yindx] + xindx)));
WRITELN (LST);
END;
WRITELN(LST,CHR(12),CHR(27) + '@'); {**** Clear printer attributes.}
WRITELN(LST);
END
ELSE
Intr (5,rec); {***** ASSUME GRAPHICS.COM IS LOADED ***** }
END; (* Screen_Dump *)