-- File: SimMOSUtilities.mesa
-- Adapted by Martin Newell, January 1980, from MIT’s MOSSIM
-- Last Updated: December 4, 1980 3:17 PM

--
For DStar compile using the /l switch

DIRECTORY
InlineDefs: FROM "InlineDefs" USING[BITSHIFT
, BITAND, BITOR,
BITXOR],
IODefs: FROM "IODefs" USING[WriteString, WriteChar],
StringDefs: FROM "StringDefs" USING[EquivalentString],
SystemDefs: FROM "SystemDefs" USING[AllocateHeapNode, FreeHeapNode],
SimMOSAccessDefs: FROM "SimMOSAccessDefs" USING[AllocateNode, SetNode,
GetNodeFlags, GetNodeName, GetNodeNext],
SimMOSDefs: FROM "SimMOSDefs" USING[Node, Transistor],
SimMOS
UtilitiesDefs: FROM "SimMOSUtilitiesDefs" USING[List, ConsCell,
AllButDescriptorFlags, InputFlag, OldVddFlag, HasInputVdd, HasInputGnd,
PullupFlag, HasPullup, GateFlag, HasGateVdd, OldGndFlag, HasGateGnd,
OldFlags, NewFlags, OldXFlag, RootFlag, SimAtomsLength];

SimMOSUtilities: PROGRAM
IMPORTS InlineDefs, IODefs,
SimMOSAccessDefs, SimMOSUtilitiesDefs, StringDefs, SystemDefs
EXPORTS
SimMOSUtilitiesDefs =
BEGIN OPEN InlineDefs, IODefs,
SimMOSAccessDefs, SimMOSDefs, SimMOSUtilitiesDefs, StringDefs, SystemDefs;

SetDescriptor: PUBLIC PROCEDURE[flags: WORD] RETURNS[WORD] =
--return flags with descriptor bits set according to type and old value
BEGIN
flags ← AllButDescriptorFlags[flags];
SELECT TRUE FROM
BITAND[InputFlag,flags]#0 => flags ←
BITOR[flags, IF BITAND[flags,OldVddFlag]#0
THEN HasInputVdd ELSE HasInputGnd];
BITAND[PullupFlag,flags]#0 => flags ← BITOR[flags,HasPullup];
BITAND[GateFlag,flags]#0 => flags ← BITOR[flags,
SELECT TRUE FROM
BITAND[flags,OldVddFlag]#0 => HasGateVdd,
BITAND[flags,OldGndFlag]#0 => HasGateGnd,
ENDCASE => HasGateVdd+HasGateGnd]; --slight kludge since don’t know
ENDCASE;
RETURN[flags];
END;

--Named-structure handler for Node structure, to make it print nicer
PrintNode: PUBLIC PROCEDURE[n: Node] =
BEGIN
name: STRING ← [100];
nFlags: WORD ← GetNodeFlags[n];
WriteString[GetNodeName[n,name]];
WriteChar[’[];
PrintNodeBits[OldFlags[nFlags]];
PrintNodeBits[NewFlags[nFlags]];
IF BITAND[nFlags,InputFlag]#0 THEN WriteChar[’I];
IF BITAND[nFlags,GateFlag]#0 THEN WriteChar[’G];
IF BITAND[nFlags,PullupFlag]#0 THEN WriteChar[’P];
WriteChar[’]];
END;

--Print VGX from node bits
PrintNodeBits: PUBLIC PROCEDURE[bits: WORD] =
BEGIN
WriteChar[SELECT TRUE FROM
BITAND[bits,OldVddFlag]#0 => ’1,
BITAND[bits,OldVddFlag]#0 => ’0,
BITAND[bits,OldXFlag]#0 => ’X,
ENDCASE => ’.];
END;

SimIntern: PUBLIC PROCEDURE[str: STRING, noCreate: BOOLEAN] RETURNS[n: Node] =
--names are hashed and matched by EquivalentString
BEGIN
i,hash: CARDINAL ← 0;
name: STRING ← [100];
FOR i IN [0..str.length) DO
hash ← BITXOR[BITSHIFT[hash,1],BITOR[str[i],40B]];
ENDLOOP; --BITOR[str[i],40B] is to equate upper and lower case
hash ← hash MOD SimAtomsLength;
FOR n ← SimAtoms[hash],GetNodeNext[n] UNTIL n=NIL DO
IF EquivalentString[str, GetNodeName[n,name]] THEN RETURN[n];
ENDLOOP;
IF noCreate THEN RETURN[NIL];
n ← AllocateNode[str];
SetNode[node: n,
nodeFlags: RootFlag,
nodeEquivClass: n,
nodeName: str, --text is copied by SetNode
nodeNext: SimAtoms[hash]];
SimAtoms[hash] ← n;
END;

--List processing support

AddToList: PUBLIC PROCEDURE[element: LONG POINTER, list: List] RETURNS[l: List] =
BEGIN
l ← AllocateHeapNode[SIZE[ConsCell]];
l↑ ← [value: element, next: list];
END;

RemoveFromList: PUBLIC PROCEDURE[element: LONG POINTER, list: List] RETURNS[l: List] =
BEGIN
lPtr: POINTER TO List;
FOR lPtr ← @list, @(lPtr.next) UNTIL lPtr↑=NIL DO
IF lPtr.value=element THEN
BEGIN
lHold: List = lPtr↑;
lPtr↑ ← lHold.next;
FreeHeapNode[lHold];
EXIT;
END;
ENDLOOP;
RETURN[list];
END;

InList: PUBLIC PROCEDURE[element: LONG POINTER, list: List] RETURNS[BOOLEAN] =
BEGIN
l: List;
FOR l ← list, l.next UNTIL l=NIL DO
IF l.value=element THEN RETURN[TRUE];
ENDLOOP;
RETURN[FALSE];
END;

DestroyList: PUBLIC PROCEDURE[list: List] RETURNS[List] =
BEGIN
l,lnext: List;
FOR l ← list, lnext UNTIL l=NIL DO
lnext ← l.next;
FreeHeapNode[l];
ENDLOOP;
RETURN[NIL];
END;

-- START Code --

-- initialize Global variables
SimVddInputs: PUBLIC List ← NIL;
-- list of nodes to be forced to vdd
SimGndInputs: PUBLIC List ← NIL;
-- list of nodes to be forced to gnd
SimETrans: PUBLIC Transistor ← NIL;
-- list of enhancement mode transistors
SimDTrans: PUBLIC Transistor ← NIL;
-- list of non-pullup depletion mode transistors
SimXTrans: PUBLIC Transistor ← NIL;
-- list of transistors with gate=X
sGND: PUBLIC Node;
-- ground node
sVDD: PUBLIC Node;
-- vdd node
SimAtoms: PUBLIC ARRAY [0..SimAtomsLength) OF Node ← ALL[NIL];
--obarray for simulator nodes
GateStorage: PUBLIC BOOLEAN ← TRUE;
-- mode of charge storage

END.