CDBussesImpl.mesa (part of ChipNDale)
by Christian Jacobi June 24, 1983 4:58 pm
last edited Christian Jacobi December 14, 1983 11:52 am
DIRECTORY
Atom,
CDBusses,
CD,
CDIO,
CDOrient,
CDInline,
CDCallSpecific,
CDCells,
CDDirectory,
CDProperties,
CDRects,
CDApplications,
TerminalIO,
TokenIO;
CDBussesImpl: CEDAR PROGRAM
IMPORTS Atom, CD, CDApplications, CDCallSpecific, CDCells, CDDirectory, CDInline, CDIO, CDOrient, CDProperties, CDRects, TerminalIO, TokenIO
EXPORTS CDBusses =
BEGIN
BusPtr: TYPE = CDBusses.BusPtr;
BusRec: TYPE = CDBusses.BusRec;
CreateBus: PUBLIC PROC [sizeOfFirst: CD.DesignPosition, lev: CD.Level, count: NAT, offset: CD.DesignPosition,
lengIncrement: CD.DesignNumber𡤀] RETURNS [CD.ObPtr] =
BEGIN
ob: CD.ObPtr;
bp: BusPtr ~ NEW[BusRec];
lowY, highY, left, right: CD.DesignNumber;
IF CDProperties.GetPropFromLevel[from: lev, prop: $CDxRectCreation]#NIL THEN {
TerminalIO.WriteRope["busses on level "];
TerminalIO.WriteRope[Atom.GetPName[CD.LevelKey[lev]]];
TerminalIO.WriteRope[" not implemented\n"];
RETURN [CDRects.CreateRect[size: sizeOfFirst, l: lev]]
};
count ← MAX[1, MIN[count, 512]];
IF sizeOfFirst.y<=0 THEN sizeOfFirst.y←CD.lambda;
IF sizeOfFirst.x<=0 THEN sizeOfFirst.x←CD.lambda;
IF sizeOfFirst.y+(count-1)*lengIncrement<=0 THEN lengIncrement𡤀
lowY ← MIN[0, (count-1)*offset.y];
highY ← MAX[sizeOfFirst.y, (count-1)*(offset.y+lengIncrement)+sizeOfFirst.y];
left ← MIN[0, (count-1)*offset.x];
right ← MAX[sizeOfFirst.x, (count-1)*(offset.x)+sizeOfFirst.x];
ob ← NEW[CD.ObjectDefinition ← [
p: pForBusses,
size: [x: right-left, y: highY-lowY],
level: lev,
specificRef: bp
]];
bp.sizeOfFirst ← sizeOfFirst;
bp.offsetOfFirst ← [-left, -lowY];
bp.offset ← offset;
bp.count ← count;
bp.lengIncrement ← lengIncrement;
RETURN [ob]
END;
ReadBus: CD.InternalReadProc --PROC [] RETURNS [ObPtr]-- =
BEGIN
sizeOfFirstX: INT = TokenIO.ReadInt[];
sizeOfFirstY: INT = TokenIO.ReadInt[];
lev: CD.Level = CDIO.ReadLevel[];
count: INT = TokenIO.ReadInt[];
offsetX: INT = TokenIO.ReadInt[];
offsetY: INT = TokenIO.ReadInt[];
lengIncrement: INT = TokenIO.ReadInt[];
RETURN [ CreateBus[
sizeOfFirst: [sizeOfFirstX, sizeOfFirstY],
lev: lev,
count: count,
offset: [offsetX, offsetY],
lengIncrement: lengIncrement
]];
END;
WriteBus: CD.InternalWriteProc -- PROC [me: ObPtr] -- =
BEGIN
bp: BusPtr = NARROW[me.specificRef];
TokenIO.WriteInt[bp.sizeOfFirst.x];
TokenIO.WriteInt[bp.sizeOfFirst.y];
CDIO.WriteLevel[me.level];
TokenIO.WriteInt[bp.count];
TokenIO.WriteInt[bp.offset.x];
TokenIO.WriteInt[bp.offset.y];
TokenIO.WriteInt[bp.lengIncrement];
END;
pForBusses: REF CD.ObjectProcs;
TransformToCell: CDCallSpecific.CallProc =
BEGIN
bptr: BusPtr←NARROW[aptr.ob.specificRef];
cob: CD.ObPtr ← CreateBusCell[design: design,
sizeOfFirst: bptr.sizeOfFirst,
lev: aptr.ob.level,
count: bptr.count,
offset: bptr.offset,
lengIncrement: bptr.lengIncrement
];
removeMe←TRUE;
repaintMe←TRUE;
include←LIST[CDApplications.NewApplication[
cob, aptr.location, aptr.orientation, aptr.selected, aptr.properties]];
repaintInclude←TRUE;
END;
Init: PROC [] =
BEGIN
pForBusses ← CD.RegisterObjectType[$Bus];
pForBusses.objectType ← $Bus;
pForBusses.drawMe ← DrawMeForBus;
pForBusses.internalRead ← ReadBus;
pForBusses.internalWrite ← WriteBus;
CDCallSpecific.Register[$TransformToCell, pForBusses, TransformToCell];
END;
DrawMeForBus: PROC [aptr: CD.ApplicationPtr, pos: CD.DesignPosition, orient: CD.Orientation,
pr: CD.DrawRef] =
BEGIN
bp: BusPtr ← NARROW[aptr.ob.specificRef];
rel, sz: CD.DesignPosition;
rel ← bp.offsetOfFirst;
sz ← bp.sizeOfFirst;
THROUGH [0..bp.count) DO
IF pr.stopFlag^ THEN EXIT;
pr.drawRect[
CDOrient.MapRect[
itemInCell: CDInline.RectAt[rel, sz],
cellSize: aptr.ob.size,
cellInstOrient: orient,
cellInstPos: pos],
aptr.ob.level,
pr];
rel ← CDInline.AddPoints[rel, bp.offset];
sz.y ← sz.y+bp.lengIncrement;
ENDLOOP
END;
CreateBusCell: PUBLIC PROC [design: CD.Design, sizeOfFirst: CD.DesignPosition, lev: CD.Level, count: NAT, offset: CD.DesignPosition, lengIncrement: CD.DesignNumber𡤀] RETURNS [CD.ObPtr] =
BEGIN
sz: CD.DesignPosition←sizeOfFirst;
ap: CD.ApplicationPtr;
pos: CD.DesignPosition ← [0, 0];
co: CD.ObPtr ← CDCells.CreateEmptyCell[];
cp: CD.CellPtr ← NARROW[co.specificRef];
IF CDProperties.GetPropFromLevel[from: lev, prop: $CDxRectCreation]#NIL THEN {
TerminalIO.WriteRope["busses on level "];
TerminalIO.WriteRope[Atom.GetPName[CD.LevelKey[lev]]];
TerminalIO.WriteRope[" not implemented\n"];
RETURN [CDRects.CreateRect[size: sizeOfFirst, l: lev]]
};
count ← MAX[count, 1];
IF sz.x<=0 THEN sz.x←CD.lambda;
IF sz.y<=0 THEN sz.y←CD.lambda;
IF sz.y+(count-1)*lengIncrement<0 THEN lengIncrement𡤀
IF offset.x<0 THEN {pos.x ← -offset.x*(count-1)};
IF offset.y<0 THEN {pos.y ← -offset.y*(count-1)};
FOR i: NAT IN [1..count] DO
rec: CD.ObPtr ← CDRects.CreateRect[sz, lev];
ap ← CDApplications.NewApplication[ob: rec, location: pos];
pos ← CDInline.AddPoints[pos, offset];
sz.y ← sz.y+lengIncrement;
cp.contents ← CONS[ap, cp.contents]
ENDLOOP;
co.size ← CDInline.SizeOfRect[CDApplications.BoundingRect[cp.contents]];
[] ← CDDirectory.Include[design, co, "-bus-"];
RETURN [co];
END;
Init[];
END.