-- File CIFDrcUtils.mesa
-- Written by Dan Fitzpatrick and Martin Newell, August 1980
-- Last updated: July 21, 1981 4:39 PM

DIRECTORY

-- CIFDevicesDefs: FROM "CIFDevicesDefs" USING
-- [MaxLENGTHLayerArray],
CIFDrcUtilsDefs: FROM "CIFDrcUtilsDefs" USING [Trapezoid, TrapType, TrapezoidRecord, Edge, EdgeRecord],
--CGraphicsDefs: FROM "CGraphicsDefs" USING [Texture, GetDisplayContext],
IntDefs: FROM "IntDefs" USING[IBoundBox],
IODefs: FROM "IODefs" USING [WriteString, WriteLine, WriteDecimal],
--MoreTrapezoidDefs: FROM "MoreTrapezoidDefs" USING [GetDefaultOutputTrapezoid],
Real: FROM "Real" USING [AppendReal,Fix],
StringDefs: FROM "StringDefs" USING [AppendString],
SystemDefs: FROM "SystemDefs" USING[AllocateHeapString],
XFSPDefs: FROM "XFSPDefs" USING[XAllocateHeapNode];
--TrapezoidDefs: FROM "TrapezoidDefs" USING [TrapezoidBlock],
--XGraphicsDefs: FROM "XGraphicsDefs" USING [Bitmap];

CIFDrcUtils: PROGRAM
IMPORTS IntDefs, IODefs, Real, StringDefs, SystemDefs, XFSPDefs
EXPORTS CIFDrcUtilsDefs =

BEGIN OPEN --CIFDevicesDefs,-- CIFDrcUtilsDefs, IntDefs, IODefs, Real, StringDefs, SystemDefs, XFSPDefs;


DisplayTrap:PUBLIC PROCEDURE [trap:Trapezoid] =
BEGIN
number: CARDINAL;
SELECT trap.type FROM
mask => number ← trap.layer;
sanctuary => number ← 5;
inclusion => number ← 8;
exclusion => number ← 9;
ENDCASE;
DrawTrap[trap.left, trap.miny, trap.right, trap.maxy, number];
END;

DrawTrap
: PUBLIC PROCEDURE[left: Edge, ystart: REAL, right: Edge, yend: REAL, layer: CARDINAL] =
BEGIN --draw left and right edges on screen for debugging
--
t: TrapezoidBlock ← [
--
ystart: ConvertY[yend],
--
yend: ConvertY[ystart],
--
xsleft: ConvertX[XatY[left,ystart]],
--
xsright: ConvertX[XatY[right,ystart]],
--
xeleft: ConvertX[XatY[left,yend]],
--
xeright: ConvertX[XatY[right,yend]],
--
function: paint,
--
xbase: ScreenBase,
--
xwords: ScreenWords,
--
texture: @Stipple[layer]
--
];
--
ScreenTrapezoid[@t];
END;

Tag: PUBLIC PROCEDURE[this,that: STRING] RETURNS [STRING] =
-- Tags this with that and returns a string
BEGIN
s: STRING;
s ← AllocateHeapString[this.length+that.length+2];
AppendString[s,this];
AppendString[s,"."];
AppendString[s,that];
RETURN[s];
END;

MakeTrap: PUBLIC PROCEDURE [left,right:Edge, start,end:REAL, layer:CARDINAL, type:TrapType]
RETURNS[trap: Trapezoid] =
BEGIN
IF left = NIL OR right = NIL THEN RETURN[NIL];
trap ← AllocTrap[];
trap↑ ← TrapezoidRecord[
front: NIL,
back: NIL,
left: CopyEdge[left],
right: CopyEdge[right],
minx: Fix[MIN[XatY[left,left.ystart],XatY[left,left.yend]]],
maxx: Fix[MIN[XatY[right,left.ystart],XatY[right,left.yend]]],
miny: Fix[start],
maxy: Fix[end],
layer: layer,
type: type,
number: NIL
];
END;

CopyTrap: PUBLIC PROCEDURE [oldTrap: Trapezoid]
RETURNS[trap: Trapezoid] =
BEGIN
trap ← AllocTrap[];
trap↑ ← TrapezoidRecord[
front: oldTrap.front,
back: oldTrap.back,
left: CopyEdge[oldTrap.left],
right: CopyEdge[oldTrap.right],
minx: oldTrap.minx,
maxx: oldTrap.maxx,
miny: oldTrap.miny,
maxy: oldTrap.maxy,
layer: oldTrap.layer,
type: oldTrap.type,
number: oldTrap.number
];
END;

AllocTrap:PUBLIC PROCEDURE RETURNS[trap:Trapezoid] =
BEGIN
AllocTrapCount ← AllocTrapCount + 1;
IF FreeTrapRecords#NIL THEN {
trap ← FreeTrapRecords;
FreeTrapRecords ← FreeTrapRecords.front;
}
ELSE trap ← XAllocateHeapNode[SIZE[TrapezoidRecord]];
RETURN[trap];
END;

FreeTrap:PUBLIC PROCEDURE [trap:Trapezoid] =
BEGIN
IF trap = NIL THEN RETURN;
FreeEdge[trap.left];
FreeEdge[trap.right];
trap.front ← FreeTrapRecords; FreeTrapRecords ← trap;
AllocTrapCount ← AllocTrapCount - 1;
END;

XatY: PUBLIC PROCEDURE[edge: Edge, y: REAL] RETURNS[x: REAL] =
BEGIN
RETURN[
WITH e:edge SELECT IF edge.vert THEN vertical ELSE oblique FROM
oblique => --i.e. oblique
SELECT TRUE FROM
y=e.ystart => e.xstart,
y=e.yend => e.xend,
ENDCASE => e.xstart + (y-e.ystart)*e.slope, --must compute from consistent end!
ENDCASE => edge.xstart --i.e. vertical
];
END;

CopyEdge:PUBLIC PROCEDURE [oldEdge:Edge] RETURNS[newEdge:Edge] =
BEGIN
--make edge of appropriate type
newEdge ← oldEdge;
newEdge.refs ← newEdge.refs + 1;
END;

MakeEdge: PUBLIC PROCEDURE [xstart,ystart,xend,yend: REAL, up: BOOLEAN] RETURNS[edge: Edge] =
BEGIN
--make edge of appropriate type
dx: REAL;
dy: REAL ← yend-ystart;
IF dy<=0 THEN RETURN[NIL];
dx ← xend-xstart;
IF dx=0 THEN
BEGIN --make vertical edge
edge ← AllocateVerticalEdge[];
edge↑ ← [
next: ,
xstart: xstart,
ystart: ystart,
yend: yend,
lastouty: ystart,
refs: 1,
mate: NIL,
up: up,
flagout: FALSE,
vert: TRUE,
var: vertical[]
];
END
ELSE
BEGIN --make oblique edge
edge ← AllocateObliqueEdge[];
edge↑ ← [
next: ,
xstart: xstart,
ystart: ystart,
yend: yend,
lastouty: ystart,
refs: 1,
mate: NIL,
up: up,
flagout: FALSE,
vert: FALSE,
var: oblique[
xend: xend,
slope: dx/dy
]
];
END;
RETURN[edge];
END;

AllocateVerticalEdge: PUBLIC PROCEDURE RETURNS[e: Edge] =
BEGIN
AllocEdgeCount ← AllocEdgeCount + 1;
IF FreeVEdgeRecords#NIL THEN
{e ← FreeVEdgeRecords;
FreeVEdgeRecords ← FreeVEdgeRecords.next;
}
ELSE e ← XAllocateHeapNode[SIZE[vertical EdgeRecord]];
END;

AllocateObliqueEdge: PUBLIC PROCEDURE RETURNS[e: Edge] =
BEGIN
AllocEdgeCount ← AllocEdgeCount + 1;
IF FreeOEdgeRecords#NIL THEN
{e ← FreeOEdgeRecords;
FreeOEdgeRecords ← FreeOEdgeRecords.next;
}
ELSE e ← XAllocateHeapNode[SIZE[oblique EdgeRecord]];
END;


FreeEdge: PUBLIC PROCEDURE[edge: Edge] =
BEGIN
IF edge = NIL THEN RETURN;
edge.refs ← edge.refs - 1;
IF edge.refs # 0 THEN RETURN;
IF edge.vert THEN {-- vertical
edge.next ← FreeVEdgeRecords; FreeVEdgeRecords ← edge;
}
ELSE {-- oblique
edge.next ← FreeOEdgeRecords; FreeOEdgeRecords ← edge;
};
AllocEdgeCount ← AllocEdgeCount - 1;
END;

PrintTrapList: PUBLIC PROCEDURE[trapList: Trapezoid] =
BEGIN
ptr: Trapezoid;
WriteLine["***Trapezoid List***"];
IF trapList = NIL THEN WriteLine["List is empty"]
ELSE BEGIN
FOR ptr ← trapList,trapList.front UNTIL ptr = NIL DO
IF ptr.back = NIL THEN WriteString["***"]
ELSE IF ptr.back # trapList THEN WriteLine["Inconsistant Trap List"];
trapList ← ptr;
WriteFloat[ptr.minx];
WriteString[" "];
WriteFloat[ptr.maxx];
WriteString[" "];
WriteFloat[ptr.miny];
WriteString[" "];
WriteFloat[ptr.maxy];
WriteLine[""];
ENDLOOP;
END;
END;

PrintAlloc: PUBLIC PROCEDURE =
BEGIN
free: INTEGER;
WriteLine["***Allocation Summary***"];
free ← 0;
FOR s:Trapezoid ← FreeTrapRecords, s.front UNTIL s=NIL DO free←free+1; ENDLOOP;
WriteAlloc["Trapezoids",AllocTrapCount,free];
free ← 0;
FOR s:Edge ← FreeVEdgeRecords, s.next UNTIL s=NIL DO free←free+1; ENDLOOP;
FOR s:Edge ← FreeOEdgeRecords, s.next UNTIL s=NIL DO free←free+1; ENDLOOP;
WriteAlloc["Edges",AllocEdgeCount,free];
END;

WriteAlloc: PROCEDURE[s: STRING, nAlloc,nFree: CARDINAL] =
BEGIN
WriteString[s];WriteString[": "];WriteDecimal[nAlloc];
WriteString[" ("]; WriteDecimal[nFree]; WriteLine[" free)"];
END;

InitUtils: PUBLIC PROCEDURE =
BEGIN
l,r,b,t: LONG INTEGER;
[l,r,b,t] ← IBoundBox[];
ChipMinX ← l;
ChipMaxX ← r;
ChipMinY ← b;
ChipMaxY ← t;
IF ChipMaxX - ChipMinX < ChipMaxY - ChipMinY THEN ChipMaxX ← ChipMinX + (ChipMaxY - ChipMinY)
ELSE ChipMaxY ← ChipMinY + (ChipMaxX - ChipMinX);
END;

ConvertX
: PROCEDURE [oldx:REAL] RETURNS [newx:REAL] =
BEGIN
newx ← (ScreenMaxX - ScreenMinX) * (oldx - (ChipMinX-900))/((ChipMaxX+900)-(ChipMinX-900)) + ScreenMinX;
END;

ConvertY
: PROCEDURE [oldy:REAL] RETURNS [newy:REAL] =
BEGIN
-- INVERT Y Co-ords
newy ← (ScreenMaxY - ScreenMinY) * (1 - ((oldy - (ChipMinY-900))/((ChipMaxY+900)-(ChipMinY-900)))) + ScreenMinY;
END;

WriteFloat: PUBLIC PROCEDURE[r: REAL] =
BEGIN
s: STRING ← [50];
AppendReal[s,r];
WriteString[s];
END;

WriteLongOctal: PUBLIC PROCEDURE[e: LONG POINTER] =
BEGIN
WriteLine["*** WriteLongOctal not implemented!"];
END;

Visible: PUBLIC PROCEDURE =
BEGIN
--Set up default stipples
--
Stipple[0] ← [ 0, 0,010421B, 0];-- --implant
--
Stipple[1] ← [042104B,010421B,042104B,010421B];-- --diffusion
--
Stipple[2] ← [010421B,104210B,042104B,021042B];-- --poly
--
Stipple[3] ← [167356B,135673B,114631B,073567B];-- --contact
--
Stipple[4] ← [ 0, 0,021042B,104210B];-- --metal
--
Stipple[5] ← [ 0,021042B,042104B,104210B];-- --buried
--
Stipple[6] ← [ 0,021042B,052525B,021042B];-- --glass
--
Stipple[7] ← [177777B,177777B,177777B,177777B];-- --undef
--
Stipple[8] ← [177777B, 0, 0, 0];-- --inclusion
--
Stipple[9] ← [010421B,010421B,010421B,010421B];-- --exclusion
END;

InVisible: PUBLIC PROCEDURE [i:CARDINAL] =
BEGIN
--Make stipple i invisible
--
Stipple[i] ← [ 0, 0,0, 0];
END;

AllocTrapCount: CARDINAL ← 0;
AllocEdgeCount: CARDINAL ← 0;

FreeTrapRecords: Trapezoid ← NIL;
FreeVEdgeRecords: Edge ← NIL;
FreeOEdgeRecords: Edge ← NIL;

ScreenMaxY: REAL ← 600;
ScreenMinY: REAL ← 1;
ScreenMaxX: REAL ← 600;
ScreenMinX: REAL ← 1;

ChipMaxY, ChipMinY, ChipMaxX, ChipMinX: REAL;


--ScreenTrapezoid: PROCEDURE [t:POINTER TO TrapezoidBlock] ←
--GetDefaultOutputTrapezoid[];
--ScreenBitmap: POINTER TO Bitmap ← GetDisplayContext[].DisplayBuff;
--ScreenBase: POINTER ← ScreenBitmap.bits;
--ScreenWords: CARDINAL ← ScreenBitmap.nWords;

--Stipple: ARRAY [0..MaxLENGTHLayerArray) OF Texture ←

--
ALL[[177777B,177777B,177777B,177777B]];-- --undef

Visible[];
-- Make the stipples visible
InVisible[8];
-- Don’t make exclusion or inclusion boxes visible
InVisible[9];

END.