(SimMOS Utilities of November 5, 1980 4:00 PM ).print (simmos)(simmosdict /begin).cvx .def (simmosdict).where (.pop).cvx ((simmosdict)256 .dict .def).cvx .ifelse simmosdict .begin (begin) (jamrun simmosrun .eq .not ((SimMOS.bcd) .loadbcd (simmosrun)jamrun .def ).cvx .if (SimMOS)/print ).cvx .def (simmosrun)0 .def (simstep) (carry out one solution of the circuit ) (simsolve .pop ).cvx /def (arraysim) (<array of input string names><array of output string names> arraysim for each input value: sets up values of each input, calls clock1, collects outputs, calls clock2. See also resumearraysim ) ((arraysimOut) .exch .def (arraysimIn) .exch .def arraysimIn .length 1 .sub (arraysimInL) .exch .def arraysimOut .length 1 .sub (arraysimOutL) .exch .def (arraysimSi)0 .def resumearraysim ).cvx /def (resumearraysim) (Resume arraysim after interruption no parameters ) (arraysimIn 0 .aget .load .length 1 .sub (arraysimSL) .exch .def arraysimcheckinputs arraysimsetupoutputs arraysimrun ).cvx /def (arraysimcheckinputs) (1 1 arraysimInL ( arraysimIn .exch .aget .dup .load .length 1 .sub arraysimSL .eq (.pop).cvx (.print ( has different length from ).print arraysimIn 0 .aget /print .stop ).cvx .ifelse ).cvx .for ).cvx .def (arraysimsetupoutputs) (0 1 arraysimOutL ( arraysimOut .exch .aget .dup arraysimcheckoutputok .not ( .dup arraysimSL 1 .add .string .def).cvx .if .load arraysimsetblanks ).cvx .for ).cvx .def (arraysimcheckoutputok) ( .where ( .pop .dup .load .type (.stringtype) .eq ( .dup .load .length 1 .sub arraysimSL .eq).cvx ( .false).cvx .ifelse ).cvx ( .false).cvx .ifelse ).cvx .def (arraysimsetblanks) ( arraysimSi 1 arraysimSL ( ( ).putstring ).cvx .for .pop ).cvx .def (arraysimrun) (arraysimsetinterrupt arraysimSi 1 arraysimSL ( (arraysimSi) .exch .def 0 1 arraysimInL ( arraysimIn .exch .aget .dup .load arraysimSi 1 .substring .load .exec ).cvx .for clock1 0 1 arraysimOutL ( arraysimOut .exch .aget .dup .load .exch getnodevalue arraysimSi .exch .putstring .pop ).cvx .for clock2 arraysimcheckinterrupt ).cvx .for arraysimunsetinterrupt ).cvx .def (arraysimsetinterrupt) ((arraysimsaveinterrupt)(.interrupt).load .def (arraysiminterruptflag).false .def (.interrupt)((arraysiminterruptflag).true .def).cvx .def ).cvx .def (arraysimcheckinterrupt) (arraysiminterruptflag ((arraysim interrupted after step ).print arraysimSi = (arraysimSi)arraysimSi 1 .add .def arraysimunsetinterrupt .stop ).cvx .if ).cvx .def (arraysimunsetinterrupt) ((.interrupt)(arraysimsaveinterrupt).load .def ).cvx .def (arraysimSi)0 .def (0)(lo).cvx .def (1)(hi).cvx .def (arraynames) (<array of output string names> arraynames prints names of signals in the array ) ((arraysimOut) .exch .def 0 1 arraysimOut .length 1 .sub ( arraysimOut .exch .aget /lp .print .print /rp .print ).cvx .for ()/print ).cvx /def (arrayvalues) (<array of output string names> arrayvalues prints values of signals in the array ) ((arraysimOut) .exch .def 0 1 arraysimOut .length 1 .sub ( arraysimOut .exch .aget .dup .print ( = ).print getnodevalue /print ).cvx .for ).cvx /def (arraystrings) (<array of output string names> printarray prints stored strings of signals in the array ) ((arraysimOut) .exch .def (arraysimOutSL) arraysimOut 0 .aget .load .length .def 0 64 arraysimOutSL 1 .sub ( ()/print .dup arraysimOutSL .exch .sub 64 2 .copy .lt (.pop).cvx (.exch .pop).cvx .ifelse 0 1 arraysimOut .length 1 .sub ( arraysimOut .exch .aget .dup .load 4 .copy .pop .pop .substring .print ( = ).print /print ).cvx .for .pop .pop ).cvx .for ).cvx /def (logchanges) (<outstream> logchanges switches on log of commands that change the stored circuit for subsequent redoing ) ((logstream).exch .def /cr logprint logging .not ( (simreset1)(simreset).load .def (simreset) ((simreset) logprint /cr logprint simreset1 ).cvx .def (etrans1)(etrans).load .def (etrans) (3 logrollprint 3 logrollprint 3 logrollprint (etrans) logprint /cr logprint etrans1 ).cvx .def (dtrans1)(dtrans).load .def (dtrans) (3 logrollprint 3 logrollprint 3 logrollprint (dtrans) logprint /cr logprint dtrans1 ).cvx .def (redefinetrans1)(redefinetrans).load .def (redefinetrans) (6 logrollprint 6 logrollprint 6 logrollprint 6 logrollprint 6 logrollprint 6 logrollprint (redefinetrans) logprint /cr logprint redefinetrans1 ).cvx .def (logging).true .def ).cvx .if ).cvx /def (unlogchanges) (unlogchanges switches off log of commands that change the stored circuit for subsequent redoing ) (logging ((simreset)(simreset1).load .def (etrans)(etrans1).load .def (dtrans)(dtrans1).load .def (redefinetrans)(redefinetrans1).load .def (logging).false .def ).cvx .if ).cvx /def (logging).false .def (logrollprint)(-1 .roll /lp logprint .dup logprint /rp logprint).cvx .def (logprint)(logstream .exch .writebytes).cvx .def (getbit) ((nodename) getbit get value of node as integer 0,-1,0 for lo,hi,x ) (getnodevalue (1).eq -1 0 .ifelse ).cvx /def (putbit) ((nodename)value putbit set value of node to lo,hi for value=0,#0 ) (0 .eq (lo).load (hi).load .ifelse ).cvx /def (getword) (wordspecifier getword get a word made up of the values of the nodes given in wordspecifier wordspecifier is an array of node names, e.g. [ (bit3)(bit2)(bit1)(bit0) ] The node values are right justified in the word ) ((gwarray).exch .def (gwbit)15 .def 0 gwarray .length 1 .sub -1 0 ( gwarray .exch .aget getbit gwmaskarray gwbit .aget .bitand .bitor (gwbit) gwbit 1 .sub .def ).cvx .for ).cvx /def (putword) (wordspecifier word putword put a word made up of the values of the nodes given in wordspecifier wordspecifier is an array of node names, e.g. [ (bit3)(bit2)(bit1)(bit0) ] The node values are right justified in the word ) ((pwword).exch .def (pwarray).exch .def (pwbit)15 .def pwarray .length 1 .sub -1 0 ( pwarray .exch .aget gwmaskarray pwbit .aget pwword .bitand putbit (pwbit) pwbit 1 .sub .def ).cvx .for ).cvx /def (gwmaskarray) [ -32768 16384 8192 4096 2048 1024 512 256 128 64 32 16 8 4 2 1 ] .def (listtrans)(3 .copy listetrans listdtrans).cvx .def (clock1) (simstep ) .cvx .def (clock2) () .cvx .def (pullup) ((node)pullup ) (.dup (VDD) dtrans ).cvx /def (inverter) ((input)(output)inverter ) (.dup pullup (GND) .exch etrans ) .cvx /def (nand) ((input1)(input2)(output)nand ) (.dup pullup gensym .dup 4 1 .roll .exch etrans (GND) .exch etrans ) .cvx /def (nor) ((input1)(input2)(output)nor ) (.dup pullup .dup 3 1 .roll (GND) .exch etrans (GND) .exch etrans ) .cvx /def (gensym) (makes a unique name ) (6 .string genindex .exch .cvis (genindex)genindex 1 .add .def) .cvx /def (genindex)0 .def (gennames) (Generate node names e.g. (in out int) gennames would generate 3 JaM variables - in, out, and int, with the string values (in#),(out#), and (int#), respectively, where # is the result of a single call to gensym ) (gensym .exch (2 .copy .exch /concat .def).cvx /tokall .pop ).cvx /def (nodedict) 256 .dict .def (namedict) 256 .dict .def (namenode) (<JaMname><SimMOSname> namenode make name by which node will subsequently be known ) (2 .copy nodedict 3 1 .roll .put namedict 3 1 .roll .put ).cvx /def (node) (<JaMname> node => <SimMOSname> ) (nodedict .exch 2 .copy .known (.get).load (.exch .pop).cvx .ifelse ).cvx /def (name) (<SimMOSname> name => <JaMname> ) (namedict .exch 2 .copy .known (.get).load (.exch .pop).cvx .ifelse ).cvx /def (VDD)(VDD).def (GND)(GND).def (dummysimmos) 50 .dict .def dummysimmos .begin (simreset) ((simreset) /print).cvx .def (circuitreset) ((circuitreset) /print).cvx .def (etrans) ((etrans) : 3 -1 .roll : .exch : : ()/print).cvx .def (dtrans) ((dtrans) : 3 -1 .roll : .exch : : ()/print).cvx .def (hi) ((hi) : /print).cvx .def (lo) ((lo) : /print).cvx .def (x) ((x) : /print).cvx .def (chhi) ((chhi) : /print).cvx .def (chlo) ((chlo) : /print).cvx .def (printwatchednodes) ((printwatchednodes) /print).cvx .def (watch) ((watch) : /print).cvx .def (unwatch) ((unwatch) : /print).cvx .def (simstep) ((simstep) /print).cvx .def (microstep) ((microstep) /print).cvx .def .end (.prompt)(.displayon (>).print).cvx .def .end ()/print simmos