-- definitions module for silicon (pretty picture) program
-- last modified by McCreight, December 21, 1983 10:00 AM
-- to incorporate multiple implant levels
-- modified by Petit, September 18, 1981 2:40 PM
DIRECTORY
SegmentDefs,
multiGraphicsDefs,
StreamDefs;
ppdefs: DEFINITIONS IMPORTS SegmentDefs, multiGraphicsDefs, StreamDefs =
BEGIN OPEN multiGraphicsDefs, StreamDefs;
compileChecks: BOOLEAN = TRUE;
INT: TYPE = LONG INTEGER;
NAT: TYPE = INTEGER[0..LAST[INTEGER]];
-- Note: The Chipmonk design coordinate system has x increasing to the right
-- and y increasing downward. [x: 0, y: 0] is the center of the design
-- space.
locNum: TYPE = INTEGER;
Lambda, lambda: locNum = 2; -- 2 locNums per lambda
Point: TYPE = RECORD [x, y: locNum];
Rect: TYPE = RECORD [x1, y1, x2, y2: locNum];
univ: Rect = [x1: -LAST[locNum], y1: -LAST[locNum],
x2: LAST[locNum], y2: LAST[locNum]];
universe: Rect -- ← univ -- ;
orientation: TYPE = [0..7] ← 0; -- multiple of 45 degrees clockwise
reflection: TYPE = [0..1] ← 0; -- 1 means mirror in x (x ← -x)
orientationIndex: TYPE = [0..15] ← 0; -- = 2*orientation+reflection
-- An orientationIndex idx is composed of two parts:
-- a clockwise rotation of (idx/2)*45 degrees,
-- followed by a reflection in x if (idx MOD 2)#0.
-- Odd multiples of 45 degrees are not yet supported.
Level: TYPE = MACHINE DEPENDENT{
cut(0), dif(1), pol(2), met(3), imp(4), ovg(5), bur(6),
snerd(7), cut2(8), pdif(9), pwelCont(10), met2(11), pwel(12),
nwel(13), nwelCont(14), NOcOL(15),
l16, l17, l18, l19, l20, l21, l22, l23, l24, l25, l26, l27, l28, l29, l30, l31,
l32, l33, l34, l35, l36, l37, l38, l39, l40, l41, l42, l43, l44, l45, l46, l47,
l48, l49, l50, l51, l52, l53, l54, l55, l56, l57, l58, l59, l60, l61, l62, l63};
level: TYPE = Level[cut..NOcOL];
unspecified: level = NOcOL;
ppUncZone: UNCOUNTED ZONE; -- zone where object's, list's, prop's,
-- cList's, and rectList's live
-- I t e m L i s t
masterList: listPtr; -- design now being displayed
listPtr: TYPE = LONG POINTER TO list ← NIL;
list: TYPE = RECORD [
nxt: listPtr,
lx, ly: locNum,
super: listPtr,
ob: obPtr,
selected, deleted, cfok, bfok: BOOLEAN ← FALSE,
mark: [0..1] ← 0,
idx, ridx: orientationIndex, -- ridx is BITXOR[idx,1], i.e. reflected
props: propPtr
];
-- I t e m P r o p e r t y
propPtr: TYPE = LONG POINTER TO prop ← NIL;
prop: TYPE = RECORD [next: propPtr, attribute, value: Atom];
putProp: PROC [lp: listPtr, attribute, value: Atom,
allowDuplAttr: BOOLEAN ← FALSE];
AppendProps: PROC [to: LONG STRING, from: propPtr, startPos: CARDINAL ← 0];
Atom: TYPE = LONG POINTER TO READONLY StringBody ← NIL;
MakeAtom: PROC [s: LONG STRING] RETURNS[Atom];
AtomToString: PROC [a: Atom] RETURNS [LONG STRING] = INLINE
{RETURN[LOOPHOLE[a]]};
RestartAtoms: PROC;
atomTableSize: INTEGER = 256;
atomTable: ARRAY [1..atomTableSize] OF Atom; -- for short I/O
-- O b j e c t
obPtr: TYPE = LONG POINTER TO object ← NIL;
cellPtr: TYPE = LONG POINTER TO cell object ← NIL;
object: TYPE = RECORD [
p: POINTER TO Procs,
size: ARRAY [0..2] OF locNum, -- x IN [0..size[0](=size[2])), y IN [0..size[1])
refCnt: CARDINAL,
cache: CacheHandle,
props: propPtr,
auxPnt: auxPtr,
l: level,
surround:[0..31] ← 0,
returnable, marked: BOOLEAN,
varpart: SELECT otyp: typeOfObject FROM
rect => NULL,
wire => [super: LONG POINTER TO wire object ← NIL],
xstr => [
super: LONG POINTER TO xstr object ← NIL,
width, length: locNum,
wExt, lExt: locNum[0..63],
impl: DepletionStrength,
pullup, angle: BOOLEAN ← FALSE],
cell => [
cnt: CARDINAL,
ptr: listPtr,
super: cellPtr ← NIL],
cont => [
super: LONG POINTER TO cont object ← NIL,
typ: contType,
magicN,m2Ext,c2Ext: locNum[0..15] ← 0,
lExt,wExt: locNum[0..255]←4],
bus => [
wspace, firstLength, topIncr, lenIncr, offsetFirst, wwidth: locNum ← 0,
wCnt, tWhich,bWhich: INTEGER ← 0],
text => [s: STRING],
cnText => [
s: STRING,
np: cListPtr ← NIL,
op: cellPtr ← NIL],
ENDCASE];
DepletionStrength: TYPE = [0..3] ← 0;
enhancement: DepletionStrength = FIRST[DepletionStrength];
zeroThresh: DepletionStrength = enhancement+1;
weakDepletion: DepletionStrength = zeroThresh+1;
strongDepletion: DepletionStrength = LAST[DepletionStrength];
DepletionStrengthName: PROC [imp: DepletionStrength] RETURNS [STRING];
Procs: TYPE = RECORD [ -- generic procedures for an object
drawme: ARRAY orientationIndex OF drProc,
setParm: parmProc,
inBox: ibProc,
inMe: inMeProc,
release: relProc,
anotherme: anoProc];
drProc: TYPE = PROC [
ob: obPtr, x, y: locNum, pr: POINTER TO drRecord];
ibProc: TYPE = PROC [lp: listPtr, x1, y1, x2, y2: locNum]
RETURNS [BOOLEAN];
inMeProc: TYPE = PROC [
ob: obPtr, x, y: locNum, o: orientationIndex]
RETURNS [BOOLEAN];
relProc: TYPE = PROC [ob: obPtr];
anoProc: TYPE = PROC [ob: obPtr]
RETURNS [obPtr];
parmProc: TYPE = PROC [
lp: listPtr, pt: parmType, dx, dy: locNum, cent: BOOLEAN]
RETURNS [BOOLEAN];
auxPtr: TYPE = LONG POINTER TO aux ← NIL;
aux: TYPE; -- can be implemented by any application program
CacheHandle: TYPE = LONG POINTER TO Cache ← NIL;
Cache: TYPE; -- of drawn bitmaps
-- N a m e d C e l l s
cellList: cListPtr; -- all the named cells
cListPtr: TYPE = LONG POINTER TO cList ← NIL;
cList: TYPE = RECORD [nxt: cListPtr, ob: obPtr, name: STRING];
-- P u s h e d C e l l s
cellStack: cellSEPtr; -- we are pushed down into this stack of cells
cellSEPtr: TYPE = LONG POINTER TO cellSE ← NIL;
cellSE: TYPE = RECORD [
nxt: cellSEPtr,
lp, instance, unDel: listPtr,
dest: cellPtr,
origSize: Point, -- of dest
origBB: Rect, -- of instance
changes: BOOLEAN,
udg, udi: CARDINAL];
UsuallyFalse: TYPE = BOOLEAN ← FALSE;
wireOK: ARRAY level OF UsuallyFalse =
[dif: TRUE, pdif: TRUE, pwelCont: TRUE, nwelCont: TRUE, -- s/d diffusions
pol: TRUE, met: TRUE, met2: TRUE];
Mode: TYPE = {wire, xstr, cell, null};
-- MAGIC CONSTANTS:
maxInfluence: locNum = 4*Lambda;
-- max extension of influence (or well) beyond bounding box:
wellSurround: locNum = 3*Lambda;
butconSY: locNum = 6*Lambda;
butconSX: locNum = 4*Lambda;
butconGreenOff: locNum = Lambda;
butconRedOff: locNum = (3*Lambda)/2;
cWidth: locNum = 2*Lambda;
cLength: locNum = 2*Lambda;
wXExtension: locNum = 2*Lambda;
lXExtension: locNum = 2*Lambda;
cut2min: locNum = 3*Lambda;
mmContExt: locNum = 2*Lambda;-- extension of met2 beyond cut2
--m2DifContExt: locNum = (3*Lambda)/2;- extension of met2 beyond edge of dif in a
-- met2-met-dif contact = (cut2min + 2*mmContExt - butconSX)/2
welconSurround: locNum = 3*Lambda;-- min well surround around a well-contact
-- switch controlling format of color screen:
csHor: BOOLEAN = TRUE;
-- TRUE for long direction horizontal, FALSE for vertical;
colWidth: INTEGER = IF csHor THEN 640 ELSE 480;
colHeight: INTEGER = IF csHor THEN 480 ELSE 640;
bwBottom: INTEGER = 580;
bwMsgTop: INTEGER = bwBottom;
bwMsgBottom: INTEGER = 640;
bwFeedTop:INTEGER=bwMsgBottom;
--********** command interpreter stuff:
QuitSig: SIGNAL;
RestSig: SIGNAL;
keCheckProc:TYPE = PROC [k:keyEvent] RETURNS[return,execute:BOOLEAN];
-- return true if command interpreter should return
-- execute true if command interpreter should execute the keyEvent
CmdTwerp:PROC [keCheckProc] RETURNS[keyEvent];
CmdTwerpMess:PROC [os1,os2,os3:STRING,check:keCheckProc]
RETURNS[keyEvent];
-- kbd stuff:
keyEvent: TYPE = RECORD [
k: [0..77B], ctl: [0..31], mx: [0..2000], my: [0..1000]];
nilKeyEvent: keyEvent = [k: 77B, ctl: 0, mx: 0, my: 0];
-- mx and my are the screen coordinates of the cursor when the keystroke
-- happened. (0,0) is upper left of color screen. (colWidth,0) is upper
-- left of B&W screen. (colWidth,bwBottom) is upper left of feedback area.
-- ctl indicates which control keys were down, or which mouse button was
-- pushed. k is the character key.
--key encodings (k field of keyEvent):
-- 0-11B: "0" to "9" (add 60B for ascii)
-- 12B-43B: "A" to "Z" (add 67B for ascii upper case)
-- 44B: ";" key
-- 45B: "=" key
-- 46B: "," key
-- 47B: "-" key
-- 50B: "." key
-- 51B: "/" key
-- 52B: "'" key
-- 53B: "[" key
-- 54B: "\" key
-- 55B: "]" key
-- 56B: "DONE" key (blank one below DEL)(UNdo)
-- 57B: "←" key
-- 60B: CR key
-- 61B: LF key
-- 62B: BS key
-- 63B: DEL key
-- 64B: space bar
-- 65B: ESC
-- 66B: blank to right of RET (not used)
-- 67B: swat key (not used)
-- 70B: TAB (not used, - a ctrl key instead)
-- 71B: ???
-- 72B: ???
-- 73B: yellow mouse button up (release)
-- 74B: ???
-- 75B: ???
-- 76B: ???
-- 77B: No key (for use with mouse buttons)
--ctrl key encodings (ctl field of keyEvent):
-- 1,2: Mouse buttons: 0-none, 1-red, 2-yellow, 3-blue
-- 4: CTRL
-- 10B: TAB
-- 20B: Shift (either)
mouseRed: CARDINAL = 1;
mouseYellow: CARDINAL = 2;
mouseBlue: CARDINAL = 3;
ctrlKey: CARDINAL = 4;
tabKey: CARDINAL = 10B;
shiftKey: CARDINAL = 20B;
cursorOnBW: BOOLEAN;
curx, cury: INTEGER;
gridCol, gridBW: CARDINAL;
mType: SegmentDefs.MachineType;
color: TYPE = [0..15];
-- ********
bwScale: INTEGER;
bwxoff, bwyoff: INTEGER;
cScale: INTEGER;
cxoff, cyoff: INTEGER;
bwScaleN: INTEGER;
bwScaleD: INTEGER;
cScaleN: INTEGER;
cScaleD: INTEGER;
bwClipx1: INTEGER;
bwClipx2: INTEGER;
bwClipy1: INTEGER;
bwClipy2: INTEGER;
cClipx1: INTEGER;
cClipx2: INTEGER;
cClipy1: INTEGER;
cClipy2: INTEGER;
fnt: POINTER TO StrikeFont;
typeOfObject: TYPE = {rect, wire, xstr, cell, cont, bus, text, cnText};
contType: TYPE = {burr, mDif, difShort, butt, mPol, mm2};
-- the first three types are also characterized by the layer of their
-- diffusion: ndif, pdif, nwelCont, pwelCont.
parmType: TYPE = {width, length, default, wSpace, lSpace, count, bSpace};
cmdMask: TYPE = [0..7777B];
-- 1=mark,2=draw,4=sel,10B=none,20B=ctrl,40B=tab,100B=ctrl-tab,
-- 200B=shift,400B=ctrl-shift,1000B=tab-shift,2000B=ctrl-tab-shift.
cmdProc: TYPE = PROC [k: keyEvent ← nilKeyEvent];
cmdLent: TYPE = RECORD [mask: cmdMask, proc: cmdProc];
cmdEnt: TYPE = POINTER TO ARRAY [0..0) OF cmdLent;
rems: TYPE = RECORD [r: Rect, l: level];
remPages: CARDINAL = 20000/256;
remLen: CARDINAL = (remPages*256)/SIZE[rems];
markPnt, markDPnt, selMarkPnt: Point;
rectListPtr: TYPE = LONG POINTER TO rectList ← NIL;
rectList: TYPE = RECORD [
nxt: rectListPtr, r: Rect, l: level, freebl: BOOLEAN];
--********** screen update process stuff:
sCmdType: TYPE = {nop, rect, sel, all};
sCmd: TYPE = RECORD [
cmd: sCmdType, ers: BOOLEAN, p: listPtr, r: Rect];
drawProcer: TYPE = PROC [
INTEGER, INTEGER, INTEGER, INTEGER, level, POINTER TO Rect];
drawProcerc: TYPE = PROC [
INTEGER, INTEGER, INTEGER, INTEGER, color, POINTER TO Rect];
drawProcers: TYPE = PROC [
INTEGER, INTEGER, INTEGER, INTEGER, STRING, POINTER TO Rect];
drRecord: TYPE = RECORD [
r,bigr: Rect,
orArea, saveArea: drawProcer,
outl: drawProcerc,
dtxt: drawProcers,
minSize: INTEGER,
quickDraw: PROC [ob: ppdefs.obPtr, orient: ppdefs.orientationIndex,
x, y: ppdefs.locNum, pr: POINTER TO ppdefs.drRecord]
RETURNS [drawn: BOOLEAN] ← NIL];
Raster: TYPE = LONG POINTER TO RasterDesc ← NIL;
RasterDesc: TYPE = RECORD [
nPixels: PixelPoint, -- .x is pixels*bits/pixel, .y is scan lines
scanLineWords: INTEGER,
map: LONG POINTER TO ARRAY [0..0) OF WORD
];
PixelRect: TYPE = Rect;
PixelPoint: TYPE = Point;
Pixel: TYPE = INTEGER; -- along a vertical or horizontal line
initRects: PROC;
CenterAndScale: PROC [center: Point, scale: INTEGER, bw, col: BOOLEAN ← FALSE];
reDrawRect: PROC [r: Rect, whenErase: CARDINAL, bw, col, all: BOOLEAN];
drawNewlySel: PROC [p: listPtr];
getColNewRect: PROC RETURNS [sCmd]; -- waits if none ready
getBwNewRect: PROC RETURNS [sCmd]; -- waits if none ready
--********* exports from ppspace.mesa
swdsAloc: CARDINAL;
lwdsAloc: LONG INTEGER;
GetSuperPointer: PROC RETURNS [listPtr];
GetCellSuper: PROC RETURNS [cellPtr];
GetSpace: PROC [CARDINAL] RETURNS [LONG POINTER];
FreeSpace: PROC [p: LONG POINTER];
InitHeap: PROC [np: CARDINAL];
EraseHeap: PROC;
GetString: PROC [nchars: CARDINAL] RETURNS [s: STRING];
FreeString: PROC [s: STRING];
newString: PROC [s: STRING] RETURNS [ss: STRING];
alocRectD: PROC RETURNS [p: LONG POINTER TO rect object];
alocWireD: PROC RETURNS [p: LONG POINTER TO wire object];
alocBusD: PROC RETURNS [p: LONG POINTER TO bus object];
alocXstrD: PROC RETURNS [p: LONG POINTER TO xstr object];
alocCellD: PROC RETURNS [p: cellPtr];
alocContD: PROC RETURNS [p: LONG POINTER TO cont object];
alocTextD: PROC RETURNS [p: LONG POINTER TO text object];
alocCnTextD: PROC RETURNS [p: LONG POINTER TO cnText object];
alocList: PROC RETURNS [p: listPtr];
alocCList: PROC RETURNS [p: cListPtr];
freeList: PROC [listPtr];
freeCell: PROC [p: cellPtr];
--**** old ppprocdefs stuff:
unDelGrpMax: CARDINAL = 10;
unDelItemMax: CARDINAL = 300;
unDelItemMin: CARDINAL = 30;
unDelPnt: listPtr;
unDelGrpCnt, unDelItemCnt: CARDINAL;
anyChanges, sinceIOchanges: BOOLEAN;
DiffusionType: TYPE = {n, p};
diffusionType: DiffusionType;
DiffusionPurpose: TYPE = {wiring, wellCont};
diffusionPurpose: DiffusionPurpose;
diffusionLevel: ARRAY DiffusionType OF ARRAY DiffusionPurpose OF level =
[n: [wiring: dif, wellCont: nwelCont], p: [wiring: pdif, wellCont: pwelCont]];
xRatiow: INTEGER; -- for transistors
xRatiol: INTEGER;
implant: DepletionStrength;
pRatiow: INTEGER; -- for depletion pullup structures
pRatiol: INTEGER;
pushLevel: INTEGER;
--**** from ppprocs?:
minWidthAr: ARRAY level OF INTEGER;
bwGrain: INTEGER;
colGrain: INTEGER;
abortColor, abortBW: BOOLEAN;
redoCBBox: PROC;
wireList: ARRAY level OF LONG POINTER TO wire object;
tranList: LONG POINTER TO xstr object;
puList: LONG POINTER TO xstr object;
contList: LONG POINTER TO cont object;
--doColRemember:PROC ;
--doBwRemember: PROC ;
inrect: PROC [x, y: INTEGER, lp: listPtr] RETURNS [BOOLEAN];
whatLevels: PROC [lp: listPtr, x, y: locNum]
RETURNS [levs: CARDINAL];
flushDel: PROC [lp: listPtr];
copyObject: PROC [lp, mp: listPtr, xoff, yoff: INTEGER]
RETURNS [np: listPtr];
minmax: PROC [lp: listPtr]
RETURNS [mix, miy, max, may: INTEGER];
typeInNum: PROC [os1, os2, os3: STRING]
RETURNS [bb: BOOLEAN, ii: INTEGER, ke: keyEvent];
typeIn: PROC [os1, os2, os3: STRING]
RETURNS [bb: BOOLEAN, is: STRING, ke: keyEvent];
typeInC: PROC [os1, os2, os3: STRING] RETURNS [kk: keyEvent];
typeOut: PROC [os1, os2, os3: STRING];
refreshTypeInScreen: PROC ;
initColors: PROC;
setColors: PROC;
getchr: PROC RETURNS [ke: keyEvent];
getNumber: PROC RETURNS [INTEGER];
getstr: PROC [x, y: CARDINAL] RETURNS [BOOLEAN, STRING, keyEvent];
-- ************
xx, yy: INTEGER;
bb: BOOLEAN;
moveOb: PROC [p: listPtr, x, y: INTEGER];
mergeRects: PROC [a, b: Rect] RETURNS [Rect];
ClipRect: PROC [a, b: Rect] RETURNS [Rect] = INLINE -- intersection
{RETURN[[x1: MAX[a.x1, b.x1], y1: MAX[a.y1, b.y1],
x2: MIN[a.x2, b.x2], y2: MIN[a. y2, b.y2]]]};
Empty: PROC [r: Rect] RETURNS[BOOLEAN] = INLINE
{RETURN[r.x2<r.x1 OR r.y2<r.y1]}; -- for directed Rects
cannonRect: PROC [r: Rect] RETURNS [Rect];
-- produces a non-empty Rect
getRect: PROC [l: listPtr] RETURNS [r: Rect];
Mod: PROC [x: INTEGER, y: NAT] RETURNS [NAT] = INLINE
{z: INTEGER = x MOD y; RETURN[IF z>=0 THEN z ELSE y+z]};
END.