-- File: SimMOSState.mesa -- Adapted by Martin Newell, January 1980, from MIT's MOSSIM -- Last Updated: December 4, 1980 12:49 PM -- For DStar compile using the /l switch DIRECTORY InlineDefs: FROM "InlineDefs" USING[BITAND, BITOR], IODefs: FROM "IODefs" USING[WriteString, WriteLine, WriteChar, CR], SimMOSAccessDefs: FROM "SimMOSAccessDefs" USING[SetNodeFlags, GetNodeFlags], SimMOSDefs: FROM "SimMOSDefs" USING[Node, EnumerateNodes, SimNode], SimMOSUtilitiesDefs: FROM "SimMOSUtilitiesDefs" USING[SimVddInputs, SimGndInputs, sVDD, sGND, GateFlag, SetDescriptor, PullupFlag, PermanentFlags, PermanentAndOldFlags, InputFlag, AllButInputFlag, OldVddFlag, OldGndFlag, GateStorage, InputP, StorageP, InList, AddToList, RemoveFromList]; SimMOSState: PROGRAM IMPORTS InlineDefs, IODefs, SimMOSAccessDefs, SimMOSDefs, SimMOSUtilitiesDefs EXPORTS SimMOSDefs = BEGIN OPEN InlineDefs, IODefs, SimMOSAccessDefs, SimMOSDefs, SimMOSUtilitiesDefs; --**State Definition**-- CircuitReset: PUBLIC PROCEDURE[value: CHARACTER] = -- Apply (SH,SL,X) to all nodes for value = (1, 0, X) BEGIN NodeReset: PROCEDURE [n: Node] RETURNS[BOOLEAN] = BEGIN IF n#sVDD AND n#sGND THEN SELECT value FROM '1 => IF ~InputP[n] THEN MakeHi[n,FALSE]; '0 => IF ~InputP[n] THEN MakeLo[n,FALSE]; 'X,'x => X1[n]; ENDCASE => BEGIN WriteString["Invalid node value in CircuitReset: "]; WriteChar[value]; WriteChar[CR]; RETURN[TRUE]; END; RETURN[FALSE]; END; [] _ EnumerateNodes[NodeReset]; END; H: PUBLIC PROCEDURE[name: STRING] = -- make node an input tied to VDD BEGIN n: Node _ SimNode[name, TRUE]; nFlags: WORD; SELECT n FROM NIL => BEGIN WriteString[name]; WriteLine[" is not a node (in hi)"]; RETURN; END; sGND => BEGIN WriteLine["Attempt to connect GND to VDD (in hi)"]; RETURN; END; ENDCASE; IF ~InList[n,SimVddInputs] THEN SimVddInputs _ AddToList[n,SimVddInputs]; SimGndInputs _ RemoveFromList[n,SimGndInputs]; nFlags _ GetNodeFlags[n]; nFlags _ BITOR[PermanentFlags[nFlags],InputFlag+OldVddFlag]; nFlags _ SetDescriptor[nFlags]; SetNodeFlags[n, nFlags]; END; L: PUBLIC PROCEDURE[name: STRING] = -- make node an input tied to GND BEGIN n: Node _ SimNode[name, TRUE]; nFlags: WORD; SELECT n FROM NIL => BEGIN WriteString[name]; WriteLine[" is not a node (in lo)"]; RETURN; END; sVDD => BEGIN WriteLine["Attempt to connect VDD to GND (in lo)"]; RETURN; END; ENDCASE; IF ~InList[n,SimGndInputs] THEN SimGndInputs _ AddToList[n,SimGndInputs]; SimVddInputs _ RemoveFromList[n,SimVddInputs]; nFlags _ GetNodeFlags[n]; nFlags _ BITOR[PermanentFlags[nFlags],InputFlag+OldGndFlag]; nFlags _ SetDescriptor[nFlags]; SetNodeFlags[n, nFlags]; END; X: PUBLIC PROCEDURE[name: STRING] = -- remove node as an input, back to normal status BEGIN n: Node _ SimNode[name, TRUE]; SELECT n FROM NIL => BEGIN WriteString[name]; WriteLine[" is not a node (in x)"]; RETURN; END; sGND,sVDD => BEGIN WriteLine["Attempt to disconnect GND or VDD (in x)"]; RETURN; END; ENDCASE; X1[n]; END; X1: PROCEDURE[n: Node] = -- internal - remove node as an input, back to normal status BEGIN nFlags: WORD; SimVddInputs _ RemoveFromList[n,SimVddInputs]; SimGndInputs _ RemoveFromList[n,SimGndInputs]; nFlags _ GetNodeFlags[n]; nFlags _ PermanentAndOldFlags[nFlags]; nFlags _ AllButInputFlag[nFlags]; nFlags _ SetDescriptor[nFlags]; SetNodeFlags[n, nFlags]; END; SH: PUBLIC PROCEDURE[name: STRING] = -- Store High on node, if connected to a gate BEGIN n: Node _ SimNode[name, TRUE]; SELECT n FROM NIL => BEGIN WriteString[name]; WriteLine[" is not a node"]; RETURN; END; sGND => BEGIN WriteLine["Attempt to store 1 on GND"]; RETURN; END; ENDCASE; MakeHi[n, TRUE]; END; InitHi: PUBLIC PROCEDURE[name: STRING] = -- Initialize High on node BEGIN n: Node _ SimNode[name, TRUE]; SELECT n FROM NIL => BEGIN WriteString[name]; WriteLine[" is not a node"]; RETURN; END; sGND => BEGIN WriteLine["Attempt to initialize GND to 1"]; RETURN; END; ENDCASE; MakeHi[n, FALSE]; END; MakeHi: PROCEDURE[n: Node, checkStorage: BOOLEAN] = -- Initialize High on node BEGIN SELECT TRUE FROM InputP[n] => WriteLine["Attempt to store high on an input node"]; checkStorage AND ~StorageP[n] => WriteLine["Attempt to store high on non-storage node"]; ENDCASE => BEGIN nFlags: WORD _ GetNodeFlags[n]; nFlags _ PermanentFlags[nFlags]; nFlags _ BITOR[nFlags,OldVddFlag]; nFlags _ SetDescriptor[nFlags]; SetNodeFlags[n, nFlags]; END; END; SL: PUBLIC PROCEDURE[name: STRING] = -- Store Low on node, if connected to a gate BEGIN n: Node _ SimNode[name, TRUE]; SELECT n FROM NIL => BEGIN WriteString[name]; WriteLine[" is not a node"]; RETURN; END; sVDD => BEGIN WriteLine["Attempt to store 0 on VDD"]; RETURN; END; ENDCASE; MakeLo[n, TRUE]; END; InitLo: PUBLIC PROCEDURE[name: STRING] = -- Initialize High on node BEGIN n: Node _ SimNode[name, TRUE]; SELECT n FROM NIL => BEGIN WriteString[name]; WriteLine[" is not a node"]; RETURN; END; sVDD => BEGIN WriteLine["Attempt to initialize VDD to 0"]; RETURN; END; ENDCASE; MakeLo[n, FALSE]; END; MakeLo: PROCEDURE[n: Node, checkStorage: BOOLEAN] = -- Store Low on node, if connected to a gate BEGIN SELECT TRUE FROM InputP[n] => WriteLine["Attempt to store low on an input node"]; checkStorage AND ~StorageP[n] => WriteLine["Attempt to store low on non-storage node"]; ENDCASE => BEGIN nFlags: WORD _ GetNodeFlags[n]; nFlags _ PermanentFlags[nFlags]; nFlags _ BITOR[nFlags,OldGndFlag]; nFlags _ SetDescriptor[nFlags]; SetNodeFlags[n, nFlags]; END; END; --**State Interrogation**-- GetNodeValue: PUBLIC PROCEDURE[name: STRING] RETURNS[CHARACTER] = -- get value of node. returns 1,0,-1 for high,low,x BEGIN n: Node; IF (n _ SimNode[name, TRUE])=NIL THEN BEGIN WriteString[name]; WriteLine[" is not a node (in GetNodeValue)"]; RETURN['X]; END; RETURN[SELECT TRUE FROM BITAND[GetNodeFlags[n],OldGndFlag]#0 => '0, BITAND[GetNodeFlags[n],OldVddFlag]#0 => '1, ENDCASE => 'X]; END; END. (635)\176b9B50f1 3f0 68f1 16f0 8f1 16f0 37f1 10f0 8f1 10f0 38f1 21f0 8f1 19f0 240f1 2f0 5b11B40f1 49f0 9f1 10f0 34f1 16f0 2f1 31f0