home *** CD-ROM | disk | FTP | other *** search
/ World of Shareware - Software Farm 2 / wosw_2.zip / wosw_2 / CPROG / DDJ1289.ZIP / AYERS.LST next >
File List  |  1989-10-30  |  29KB  |  905 lines

  1. _AN OBJECT-ORIENTED LOGIC SIMULATOR_
  2. by Kenneth E. Ayers
  3.  
  4.  
  5. [LISTIN╟ ONE]
  6.  
  7. Object subclass: #LogicLab
  8.   instanceVariableNames: 
  9.     'devices signals switches clashes changed topPane analyzer breadboard 
  10.                                                listSelector currentComponent '
  11.   classVariableNames: ''
  12.   poolDictionaries: 
  13.     'FunctionKeys CharacterConstants ' !
  14.  
  15. !LogicLab class methods !
  16. description
  17.          "Answer a String describing the
  18.          application and version."
  19.       ^'LogicLab (Version 1.0 -- 06/26/88)'.!
  20. new
  21.         "Answer an initialized LogicLab application."
  22.     | logicLab |
  23.     logicLab := super new.
  24.     logicLab initialize.
  25.     ^logicLab.! !
  26.  
  27. !LogicLab methods !
  28. addComponent: aComponent
  29.            "Add aComponent to the circuit description.
  30.          If there is an error, answer nil;  otherwise
  31.          answer aComponent."
  32.     | name |
  33.        name := aComponent name.
  34.     name size == 0
  35.          ifTrue: [
  36.            "
  37.                 User is installing -- get a name.
  38.             "
  39.          name := self getNewName.
  40.           name isNil
  41.             ifTrue: [^nil].
  42.           aComponent name: name]
  43.         ifFalse: [
  44.            "
  45.                 A name has been supplied -- this implies
  46.                 that the component is being installed from
  47.                 a file.  Need to check for a clash with
  48.                 an existing name.
  49.             "
  50.           ((self componentNamed: name) isNil)
  51.           ifFalse: [
  52.                 "
  53.                         Had a name clash -- get a synonym
  54.                         from the user and stash both of them
  55.                         away in the clashes table.  Then
  56.                         rename the component.
  57.                     "
  58.                  name := self getNewName.
  59.                 name isNilè               ifTrue: [^nil].
  60.               clashes
  61.                  at: aComponent name
  62.                     put: name.
  63.               aComponent name: name]].
  64.     changed := true.
  65.     aComponent isDevice
  66.            ifTrue:  [devices add: aComponent]
  67.      ifFalse: [
  68.            aComponent isSignal
  69.            ifTrue:  [signals add: aComponent]
  70.              ifFalse: [
  71.                 switches add: aComponent.
  72.                 analyzer isNil
  73.                    ifFalse: [analyzer addSwitch: aComponent]]].
  74.     ^aComponent.!
  75. allNames
  76.       "Answer an array of all of the
  77.          names of installed components."
  78.     ^((self deviceNames), (self signalNames), (self switchNames)).!
  79. analyzer: aModel
  80.        "Set the LogicAnalyzer Application model
  81.          to aModel."
  82.        analyzer := aModel.!
  83. breadboardList
  84.          "Answer an array of strings according to the
  85.          current list selector."
  86.     listSelector isNil
  87.            ifTrue: [listSelector := #listDevices].
  88.       ^(self perform: listSelector).!
  89. breadboardMenu
  90.            "Private -- answer the menu that processes
  91.          breadboard functions."
  92.     MenuPosition := Cursor position.
  93.     ^(Menu
  94.           labels: ('Load\Save\Erase\List\',
  95.                  'Install\Connect\Remove\Disconnect\',
  96.                'Simulate\',
  97.             'Quit') withCrs
  98.       lines: #(4 8 9)
  99.      selectors: #(load     save     erase   list
  100.                install  connect  remove  disconnect
  101.                 run
  102.                 quit)).!
  103. changed
  104.      "Answer true if the circuit has changed."
  105.     ^changed.!
  106. changed: aBoolean
  107.      "Set the circuit-changed flag to aBoolean."
  108.     changed := aBoolean.!
  109. close
  110.       "Close the LogicLab breadboarding window."
  111.     topPane dispatcher deactivateWindow closeWindow.!
  112. closeIt
  113.         "Close the breadboard application window."è    self close.!
  114. componentNamed: aName
  115.            "Answer the component (device, signal, or switch)
  116.          whose name is aName.  If no component can be found
  117.          answer nil."
  118.     | realName |
  119.     realName := aName.
  120.       clashes isNil
  121.            ifFalse: [
  122.          (clashes includesKey: aName)
  123.           ifTrue:  [realName := clashes at: aName]].
  124.     devices do: [:aDevice|
  125.          (aDevice name = realName)
  126.            ifTrue: [^aDevice]].
  127.       signals do: [:aSignal|
  128.         (aSignal name = realName)
  129.          ifTrue: [^aSignal]].
  130.     switches do: [:aSwitch|
  131.         (aSwitch name = realName)
  132.           ifTrue: [^aSwitch]].
  133.      ^nil.!
  134. componentTypeMenu: selectorArray
  135.            "Answer a user-selected action for a
  136.          component type."
  137.     ^((Menu
  138.            labels: 'Device\Signal\Switch' withCrs
  139.          lines: #()
  140.            selectors: selectorArray) popUpAt: MenuPosition).!
  141. connect
  142.         "Make a user-specified connection."
  143.     | from to |
  144.     from := self getNode.
  145.     from isNil
  146.      ifTrue: [^nil].
  147.     to := self getNode.
  148.        to isNil
  149.        ifTrue: [^nil].
  150.     from connect: to.
  151.        changed := true.
  152.     currentComponent := from model.
  153.       listSelector := #listComponentConnections.
  154.     breadboard update.!
  155. description
  156.           "Answer a string with a description of the receiver."
  157.     ^(self class description).!
  158. deviceNames
  159.          "Answer a collection of all of the
  160.          names of installed devices."
  161.     | list |
  162.     list := OrderedCollection new: (devices size).
  163.     devices  do: [:aDevice| list add: aDevice name].
  164.       ^list.!
  165. devices
  166.         "Answer the list of installed devices."
  167.        ^devices.!èdisconnect
  168.            "Remove a user-specified connection."
  169.     | node |
  170.     node := self getNode.
  171.     node isNil
  172.            ifTrue: [^nil].
  173.       node disconnect.
  174.     changed := true.
  175.       currentComponent := node model.
  176.     listSelector := #listComponentConnections.
  177.        breadboard update.!
  178. erase
  179.        "After user-verification, erase
  180.          the circuit description."
  181.     Cursor offset: MenuPosition.
  182.     (self verify: 'Erase circuit description?')
  183.        ifFalse: [^nil].
  184.     self eraseCircuit.
  185.     listSelector := #listDevices.
  186.     changed := true.
  187.       breadboard update.!
  188. eraseCircuit
  189.      "Erase the circuit description."
  190.     devices  do: [:aDevice|
  191.         self removeComponent: aDevice].
  192.     signals  do: [:aSignal|
  193.           self removeComponent: aSignal].
  194.      switches do: [:aSwitch|
  195.         self removeComponent: aSwitch].
  196.        self initialize.!
  197. getExistingComponent
  198.         "Answer a user-specified component."
  199.     | name component reply list |
  200.      name := self getName.
  201.       name isNil
  202.         ifTrue: [^nil].
  203.     component := self componentNamed: name.
  204.       component isNil
  205.      ifFalse: [^component].
  206.        Cursor offset: MenuPosition.
  207.        (Menu message:
  208.          (name, ' not installed -- select from list?')) isNil
  209.      ifTrue: [^nil].
  210.     Cursor offset: MenuPosition.
  211.     reply := self componentTypeMenu:
  212.                  #(deviceNames signalNames switchNames).
  213.        Cursor offset: MenuPosition.
  214.        reply isNil
  215.           ifTrue: [^nil].
  216.      list := self perform: reply.
  217.      (list size == 0)
  218.      ifTrue: [
  219.           Menu message: 'None installed'.
  220.           Cursor offset: MenuPosition.
  221.           ^nil].è       name := VariableMenu selectFrom: list.
  222.     name isNil
  223.            ifTrue: [^nil].
  224.       name := list at: name.
  225.     ^(self componentNamed: name).!
  226. getExistingName
  227.      "Answer a user-specified name of
  228.          an existing component."
  229.     | component |
  230.     component := self getExistingComponent.
  231.      component isNil
  232.         ifTrue: [^nil].
  233.        ^(component name).!
  234. getFile
  235.          "Answer a FileStream for a
  236.          user-specified filename."
  237.     | name |
  238.      name := self getFilename.
  239.     name isNil
  240.         ifTrue: [^nil].
  241.        ^(File pathName: name).!
  242. getFilename
  243.           "Answer a user-specified filename."
  244.     | name |
  245.      Cursor offset: MenuPosition.
  246.      name :=
  247.         Prompter
  248.          prompt: 'Enter filename'
  249.             default: ''.
  250.     Cursor offset: MenuPosition.
  251.     ^name.!
  252. getName
  253.           "Answer a user-specified name."
  254.      | name |
  255.     Cursor offset: MenuPosition.
  256.     name :=
  257.         Prompter
  258.             prompt: 'Enter component name'
  259.            default: ''.
  260.       Cursor offset: MenuPosition.
  261.       ^name.!
  262. getNewName
  263.        "Answer a user-specified name for
  264.          a new component."
  265.       | name |
  266.     Cursor offset: MenuPosition.
  267.     name :=
  268.          Prompter
  269.           prompt: 'Enter name for new component'
  270.             default: ''.
  271.        Cursor offset: MenuPosition.
  272.        name isNil
  273.          ifTrue: [^nil].
  274.     [(self componentNamed: name) isNil]
  275.        whileFalse: [è         name :=
  276.             Prompter
  277.                 prompt: 'Name exists -- enter NEW name'
  278.                 default: name.
  279.          Cursor offset: MenuPosition.
  280.          name isNil
  281.                ifTrue: [^nil]].
  282.       ^name.!
  283. getNode
  284.         "Answer a user-specified LogicNode."
  285.     | component |
  286.      component := self getExistingComponent.
  287.     component isNil
  288.        ifTrue: [^nil].
  289.     ^(component getNode).!
  290. initialize
  291.           "Private -- initialize a new
  292.          LogicLab application."
  293.     devices  := OrderedCollection new.
  294.        signals  := OrderedCollection new.
  295.      switches := OrderedCollection new.
  296.     changed := true.!
  297. install
  298.            "Install a user-specified component."
  299.     | component |
  300.      component := LogicComponent install.
  301.      component isNil
  302.         ifTrue: [^nil].
  303.        self addComponent: component.
  304.     listSelector := self listSelectorFor: component.
  305.     breadboard update.
  306.     ^component.!
  307. installClassFrom: aStream
  308.        "Install a LogicComponent subclass
  309.          whose name is the next word on aStream."
  310.       | className |
  311.        className := aStream nextWord.
  312.     (Smalltalk includesKey: className asSymbol)
  313.         ifFalse: [
  314.           self error: ('Class: ', className, ' not installed')].!
  315. installComponentFrom: aStream
  316.       "Install a LogicComponent instance
  317.          whose name is the next word on aStream."
  318.      | className class component |
  319.       className := aStream nextWord.
  320.     class := LogicComponent classNamed: className.
  321.     class isNil
  322.      ifTrue: [
  323.           self error: ('Unknown class: ', className).
  324.          ^nil].
  325.     component := class new installFrom: aStream.
  326.     component isNil
  327.           ifTrue: [^nil].
  328.      ^(self addComponent: component).!
  329. installConnectionFrom: aStreamè        "Install a connection from aStream."
  330.     | fromName from toName to fromNode toNode |
  331.     fromName := aStream nextWord.
  332.     from := self componentNamed: fromName.
  333.       from isNil
  334.         ifTrue: [
  335.           self error: ('Unknown component: ', fromName).
  336.             ^nil].
  337.     fromNode := from getNodeFrom: aStream.
  338.     fromNode isNil
  339.          ifTrue: [
  340.            self error: ('Unknown node on: ', fromName).
  341.            ^nil].
  342.     toName := aStream nextWord.
  343.        to := self componentNamed: toName.
  344.      to isNil
  345.      ifTrue: [
  346.           self error: ('Unknown component: ', toName).
  347.           ^nil].
  348.     toNode := to getNodeFrom: aStream.
  349.     toNode isNil
  350.       ifTrue: [
  351.            self error: ('Unknown node on: ', toName).
  352.          ^nil].
  353.     ^(fromNode connect: toNode).!
  354. installFrom: aStream
  355.         "Load a circuit from the description
  356.          on aStream."
  357.     | keyWord |
  358.     clashes := Dictionary new.
  359.       [(aStream atEnd)
  360.       or: [(keyWord := aStream nextWord) isNil]]
  361.         whileFalse: [
  362.          keyWord = 'LOAD'
  363.               ifTrue:  [
  364.                  self installClassFrom: aStream]
  365.            ifFalse: [
  366.                  keyWord = 'INSTALL'
  367.                  ifTrue:  [
  368.                     self installComponentFrom: aStream]
  369.                   ifFalse: [
  370.                      keyWord = 'CONNECT'
  371.                         ifTrue:  [
  372.                            self installConnectionFrom: aStream]
  373.                           ifFalse: [
  374.                         self error:
  375.                             ('Unknown command: ',
  376.                               keyWord)]]]].
  377.       clashes release.
  378.     clashes := nil.!
  379. list
  380.       "Process a user-specified list request."
  381.     | selection |
  382.     selection :=
  383.        (Menuè         labels: ('Components\Connections\',
  384.                   'Circuit Description') withCrs
  385.           lines: #()
  386.          selectors: #(listComponents
  387.                       listConnections
  388.                       listCircuit))
  389.          popUpAt: MenuPosition.
  390.     selection isNil
  391.           ifTrue: [^nil].
  392.      listSelector := selection.
  393.     breadboard update.!
  394. listCircuit
  395.          "Answer a collection of strings with
  396.          the circuit description."
  397.     | name stream list |
  398.     CursorManager execute change.
  399.     name := 'logiclab.tmp'.
  400.        stream := File pathName: name.
  401.     list := OrderedCollection new.
  402.     stream
  403.          nextPutAll: '****  Circuit Description  ****';
  404.        cr;
  405.           cr.
  406.     self storeOn: stream.
  407.     stream flush.
  408.     stream position: 0.
  409.     [stream atEnd]
  410.         whileFalse: [list add: stream nextLine].
  411.     stream close.
  412.      File remove: name.
  413.     CursorManager normal change.
  414.     ^list.!
  415. listComponentConnections
  416.           "Answer a collection of strings listing
  417.          the connection chain(s) for the
  418.          'currentComponent'."
  419.     currentComponent isNil
  420.         ifTrue:  [^#()]
  421.        ifFalse: [
  422.           ^(#('****  Connection List  ****' ' '),
  423.               currentComponent connectionList)].!
  424. listComponents
  425.          "Answer a collection of strings containing
  426.          a list of installed components."
  427.     | selection |
  428.     selection :=
  429.      self componentTypeMenu:
  430.              #(listDevices listSignals listSwitches).
  431.     selection isNil
  432.        ifTrue: [^#()].
  433.     ^(self perform: selection).!
  434. listConnections
  435.      "Answer a collection of strings listing
  436.          the connection chain(s) for a
  437.          user-specified component."è    | component |
  438.     component := self getExistingComponent.
  439.      component isNil
  440.         ifTrue: [^#()].
  441.        currentComponent := component.
  442.     ^self listComponentConnections.!
  443. listContaining: aComponent
  444.            "Answer the list (devices, signals, or switches)
  445.          that includes aComponent."
  446.     (devices includes: aComponent)
  447.         ifTrue: [^devices].
  448.        (signals includes: aComponent)
  449.      ifTrue: [^signals].
  450.     ^switches.!
  451. listDevices
  452.           "Answer a collection of strings containing
  453.          a list of all the installed devices."
  454.       | size list |
  455.        size := devices size.
  456.     size == 0
  457.          ifTrue: [^#('No devices installed')].
  458.     size := size + 1.
  459.        list := OrderedCollection new: size.
  460.        list add: 'DEVICES'.
  461.        devices do: [:aDevice| list add: ('  ', (aDevice identify))].
  462.     ^list.!
  463. listSelectorFor: aComponent
  464.           "Answer the list selector method used
  465.          to produce the list for aComponent's type."
  466.        aComponent isDevice
  467.           ifTrue: [^#listDevices].
  468.       aComponent isSignal
  469.          ifTrue: [^#listSignals].
  470.      ^#listSwitches.!
  471. listSignals
  472.         "Answer a collection of strings containing
  473.          a list of all the installed input signals."
  474.     | size list |
  475.     size := signals size.
  476.     size == 0
  477.      ifTrue: [^#('No signals installed')].
  478.       size := size + 1.
  479.     list := OrderedCollection new: size.
  480.     list add: 'SIGNALS'.
  481.     signals do: [:aSignal| list add: ('  ', (aSignal identify))].
  482.     ^list.!
  483. listSwitches
  484.        "Answer a collection of strings containing
  485.          a list of all the installed swithces."
  486.     | size list |
  487.      size := switches size.
  488.        size == 0
  489.         ifTrue: [^#('No switches installed')].
  490.     size := size + 1.
  491.        list := OrderedCollection new: size.è       list add: 'SWITHCES'.
  492.     switches do: [:aSwitch| list add: ('  ', (aSwitch identify))].
  493.     ^list.!
  494. load
  495.      "Load a circuit description from
  496.          a user-specified file."
  497.     | file |
  498.      file := self getFile.
  499.       file isNil
  500.         ifTrue: [^nil].
  501.     self installFrom: file.
  502.       listSelector := #listDevices.
  503.        breadboard update.!
  504. noDelay
  505.          "Setup all components to ignore
  506.          propagation delays."
  507.     signals  do: [:signal| signal noDelay].
  508.     switches do: [:switch| switch noDelay].
  509.        devices  do: [:device| device noDelay].!
  510. noMenu
  511.      "Private -- answer an empty menu."
  512.     ^(EmptyMenu new).!
  513. open
  514.          "Open the Breadboard and Analyzer windows."
  515.     | size position |
  516.      size := (Display boundingBox extent * 3) // 4.
  517.        position := Display boundingBox center - (size // 2).
  518.     topPane :=
  519.           TopPane new
  520.          label: ((self class description),
  521.                     ' -- Breadboard');
  522.          model: self;
  523.          menu: #noMenu;
  524.           yourself.
  525.        topPane addSubpane:
  526.           (breadboard := ListPane new
  527.          name: #breadboardList;
  528.            model: self;
  529.            menu: #breadboardMenu;
  530.           change: #doNothing:;
  531.           framingRatio: (0 @ 0 extent: 1 @ 1)).
  532.       topPane reframe: (position extent: size).
  533.     topPane dispatcher openWindow scheduleWindow.!
  534. quit
  535.      "Quit this LogicLab."
  536.       (self verify: 'Quit this LogicLab?')
  537.           ifFalse: [^nil].
  538.       self eraseCircuit.
  539.     signals := switches := devices := nil.
  540.       analyzer isNil
  541.         ifFalse: [
  542.           analyzer closeWindow.
  543.            analyzer := nil].
  544.     breadboard dispatcher deactivateWindow closeWindow.
  545.        Scheduler systemDispatcher redraw.è     Scheduler resume.!
  546. remove
  547.      "Remove a user-specified component."
  548.      | component |
  549.       component := self getExistingComponent.
  550.     component isNil
  551.         ifTrue: [^nil].
  552.     changed := true.
  553.        listSelector := self listSelectorFor: component.
  554.     self removeComponent: component.
  555.        breadboard update.!
  556. removeComponent: aComponent
  557.      "Remove aComponent from the circuit."
  558.       analyzer isNil
  559.         ifFalse: [analyzer removeComponent: aComponent].
  560.     (self listContaining: aComponent) remove: aComponent.
  561.     aComponent remove.!
  562. reset
  563.          "Reset all components."
  564.     signals     do: [:signal| signal reset].
  565.      switches do: [:switch| switch reset].
  566.       devices  do: [:device| device reset].!
  567. restoreDelay
  568.         "Setup all components to use
  569.          propagation delays."
  570.      signals  do: [:signal| signal restoreDelay].
  571.      switches do: [:switch| switch restoreDelay].
  572.      devices  do: [:device| device restoreDelay].!
  573. resume
  574.         "Resume the breadboarding application
  575.          after running the simulation."
  576.     Cursor offset: breadboard frame center.
  577.     topPane dispatcher scheduleWindow.!
  578. run
  579.          "Invoke the LogicAnalyzer to run the simulation."
  580.       analyzer isNil
  581.         ifTrue: [
  582.          analyzer := LogicAnalyzer new.
  583.            analyzer openOn: self]
  584.          ifFalse: [analyzer activate].!
  585. save
  586.            "Store the circuit description in
  587.          a user-specified file."
  588.     | file |
  589.     file := self getFile.
  590.      file isNil
  591.        ifTrue: [^nil].
  592.     CursorManager execute change.
  593.     self storeOn: file.
  594.     file
  595.       flush;
  596.         close.
  597.       CursorManager normal change.!
  598. selectName
  599.      "Answer a user-selected name from a listè         of the names of installed components."
  600.     | names index |
  601.     names := self allNames.
  602.       (names size == 0)
  603.        ifTrue: [^nil].
  604.     index := VariableMenu selectFrom: names.
  605.       index isNil
  606.          ifTrue: [^nil].
  607.     ^(names at: index).!
  608. signalNames
  609.            "Answer a collection of all of the
  610.          names of installed signals."
  611.       | list |
  612.     list := OrderedCollection new: (signals size).
  613.     signals     do: [:aSignal| list add: aSignal name].
  614.     ^list.!
  615. signals
  616.       "Answer the list of installed signals."
  617.     ^signals.!
  618. simulate
  619.            "Simulate one pseudo-time interval."
  620.     signals  do: [:signal| signal simulate].
  621.        switches do: [:switch| switch simulate].
  622.     devices  do: [:device| device simulate].!
  623. storeClassesOn: aStream
  624.            "Write a record of each component class
  625.          used by the circuit on aStream."
  626.        | classes |
  627.       classes := Set new.
  628.      devices  do: [:aDevice| classes add: aDevice class].
  629.      signals  do: [:aSignal| classes add: aSignal class].
  630.      switches do: [:aSwitch| classes add: aSwitch class].
  631.      classes do: [:aClass|
  632.           aStream
  633.           nextPutAll: ('LOAD ', (aClass name));
  634.            cr].!
  635. storeComponentsFrom: aCollection on: aStream
  636.        "Write a record of each logic component from
  637.          aCollection installed in the circuit on aStream."
  638.     aCollection do: [:aComponent|
  639.       aStream nextPutAll: 'INSTALL '.
  640.      aComponent storeOn: aStream.
  641.          aStream cr].!
  642. storeConnectionsOn: aStream
  643.          "Write a record of each connection
  644.          in the circuit on aStream."
  645.     devices  do: [:aDevice| aDevice storeConnectionsOn: aStream].
  646.     signals     do: [:aSignal| aSignal storeConnectionsOn: aStream].
  647.      switches do: [:aSwitch| aSwitch storeConnectionsOn: aStream].
  648.       devices  do: [:aDevice| aDevice unMark].
  649.     signals  do: [:aSignal| aSignal unMark].
  650.       switches do: [:aSwitch| aSwitch unMark].!
  651. storeDevicesOn: aStream
  652.       "Write a record of each logic device
  653.          installed in the circuit on aStream."è    self storeComponentsFrom: devices on: aStream.!
  654. storeOn: aStream
  655.            "Write a description of the circuit on
  656.          aStream in a form that can be recovered
  657.          by the 'installOn:' method."
  658.     self
  659.       storeClassesOn: aStream;
  660.       storeDevicesOn: aStream;
  661.       storeSignalsOn: aStream;
  662.       storeSwitchesOn: aStream;
  663.        storeConnectionsOn: aStream.!
  664. storeSignalsOn: aStream
  665.            "Write a record of each logic signal
  666.          installed in the circuit on aStream."
  667.     self storeComponentsFrom: signals on: aStream.!
  668. storeSwitchesOn: aStream
  669.         "Write a record of each logic switch
  670.          installed in the circuit on aStream."
  671.       self storeComponentsFrom: switches on: aStream.!
  672. switches
  673.       "Answer the list of installed switches."
  674.     ^switches.!
  675. switchNames
  676.         "Answer a collection of all of the
  677.          names of installed swithces."
  678.     | list |
  679.     list := OrderedCollection new: (switches size).
  680.     switches     do: [:aSwitch| list add: aSwitch name].
  681.     ^list.!
  682. verify: aPrompt
  683.       "Ask the user to verify some condition."
  684.     Cursor offset: MenuPosition.
  685.     ^((Menu message: aPrompt) notNil).! !
  686.  ì
  687.  
  688. [LISTIN╟ TWO]
  689.  
  690. LogicSwitch subclass: #ToggleSwitch
  691.   instanceVariableNames: ''
  692.   classVariableNames: ''
  693.   poolDictionaries: '' !
  694.  
  695. !ToggleSwitch class methods !
  696.  
  697. type
  698.         "Answer a string with the receiver's type."
  699.     ^'Toggle Switch'.! !
  700. !ToggleSwitch methods !
  701. identify
  702.         "Answer a string identifying the receiver."
  703.     ^((self name),
  704.         ' (', (self type), ')').!
  705. push: aButton
  706.         "Simulate pushing a toggle switch by
  707.          inverting its state."
  708.     node invert.
  709.     node isHigh
  710.         ifTrue:  [aButton lampOn]
  711.         ifFalse: [aButton lampOff].
  712.     (model isNil or: [changeSelector isNil])
  713.         ifFalse: [model perform: changeSelector].!
  714. reset
  715.         "Reset the receiver."
  716.     button isNil
  717.         ifFalse: [
  718.             node isHigh
  719.                 ifTrue:  [button lampOn]
  720.                 ifFalse: [button lampOff]].!
  721. simulate
  722.         "Simulate a toggle switch."
  723.     node output.! !
  724.  
  725.  
  726. [LISTIN╟ THREE]
  727.  
  728. LogicSwitch subclass: #PulserSwitch
  729.   instanceVariableNames: 
  730.     'rest time timer '
  731.   classVariableNames: ''
  732.   poolDictionaries: '' !
  733.  
  734. !PulserSwitch class methods !
  735.  
  736. type
  737.         "Answer a string with the receiver's type."
  738.     ^'Pulser'.! !
  739. !PulserSwitch methods !
  740. identify
  741.         "Answer a string identifying the receiver."
  742.     ^((self name),
  743.         ' (', (self type), ' -- ',
  744.             (LogicNode
  745.                 statePrintString: (LogicNode not: rest)), ': ',
  746.             (TimeInterval timePrintString: time), ')').!
  747. initialize
  748.         "Initialize a new PulserSwitch."
  749.     super initialize.
  750.     rest := false.
  751.     time := timer := 0.!
  752.  
  753. install
  754.         "Answer the receiver with user-specified
  755.          rest state and pulse time."
  756.     rest := LogicNode getState.     "User will select pulse state"
  757.     rest isNil
  758.         ifTrue: [^super release].
  759.     rest := LogicNode not: rest.
  760.     time := TimeInterval getTimeFor: 'pulse'.
  761.     time isNil
  762.         ifTrue: [^super release].
  763.     ^self.!
  764. installFrom: aStream
  765.         "Answer a new PulserSwitch initialized with
  766.          parameters read from aStream."
  767.     super installFrom: aStream.
  768.     rest := LogicNode stateNamed: aStream nextWord.
  769.     node state: rest.
  770.     time  := aStream nextWord asInteger.
  771.     ^self.!
  772. push: aButton
  773.         "Simulate pushing a Pulser Switch."
  774.     timer == 0
  775.         ifTrue: [node state: (LogicNode not: rest)].
  776.     timer := time.
  777.     node isHigh
  778.         ifTrue:  [aButton lampOn]
  779.         ifFalse: [aButton lampOff].
  780.     (model isNil or: [changeSelector isNil])è        ifFalse: [model perform: changeSelector].!
  781. reset
  782.         "Reset the receiver's state to its resting
  783.          state and its timer to zero."
  784.     node state: rest.
  785.     timer := 0.
  786.     button isNil
  787.         ifFalse: [
  788.             node isHigh
  789.                 ifTrue:  [button lampOn]
  790.                 ifFalse: [button lampOff]].!
  791. simulate
  792.         "Simulate a Pulser Switch."
  793.     timer == 0
  794.         ifTrue: [
  795.             node state: rest.
  796.             button isNil
  797.                 ifFalse: [
  798.                     node isHigh
  799.                         ifTrue:  [button lampOn]
  800.                         ifFalse: [button lampOff]]]
  801.         ifFalse: [timer := timer - 1].
  802.     node output.!
  803. storeOn: aStream
  804.         "Store a record of the receiver on aStream."
  805.     super storeOn: aStream.
  806.     aStream
  807.         nextPutAll: (' ',
  808.                         (LogicNode statePrintString: rest), ' ',
  809.                         (time printString)).! !
  810.  
  811. [LISTIN╟ FOUR]
  812.  
  813. LogicDevice subclass: #N74LS00
  814.   instanceVariableNames: ''
  815.   classVariableNames: ''
  816.   poolDictionaries: '' !
  817.  
  818. !N74LS00 class methods !
  819. description
  820.         "Answer a string with a description
  821.          of the receiver's function."
  822.     ^'Quad 2-input NAND gate'.!
  823. type
  824.         "Answer a string with the receiver's type."
  825.     ^'74LS00'.! !
  826. !N74LS00 methods !
  827. initialize
  828.         "Private -- initialize the propagation delays
  829.          for a new 74LS00 LogicDevice."
  830.     super
  831.         initialize;
  832.         initializeDelays:
  833.             #(  5  5 10    5  5 10    0
  834.                10  5  5   10  5  5    0 ).!
  835. simulate
  836.         "Simulate a 74LS00 device."
  837.     ((pins at: 1) isHigh and: [(pins at: 2) isHigh])
  838.         ifTrue:  [(pins at: 3) output: false]
  839.         ifFalse: [(pins at: 3) output: true].
  840.     ((pins at: 4) isHigh and: [(pins at: 5) isHigh])
  841.         ifTrue:  [(pins at: 6) output: false]
  842.         ifFalse: [(pins at: 6) output: true].
  843.     ((pins at: 10) isHigh and: [(pins at: 9) isHigh])
  844.         ifTrue:  [(pins at: 8) output: false]
  845.         ifFalse: [(pins at: 8) output: true].
  846.     ((pins at: 13) isHigh and: [(pins at: 12) isHigh])
  847.         ifTrue:  [(pins at: 11) output: false]
  848.         ifFalse: [(pins at: 11) output: true].! !
  849.  
  850.  
  851. [LISTIN╟ FIVE]
  852.  
  853. output: aState ì
  854.  
  855.         "Generate aState as an output from the node." ì
  856.  
  857.     old := int. ì
  858.     int := aState. ì
  859.     int == ext ì
  860.         ifTrue: [ ì
  861.             "State is stable" ì
  862.             timer := 0. ì
  863.             ^self outputToConnections]. ì
  864.     "State has changed" ì
  865.     timer == 0 ì
  866.         ifTrue: [ ì
  867.             "No delay in progress -- initiate prop delay" ì
  868.             delay == 0 ì
  869.                 ifTrue: [ ì
  870.                     "No delay -- just change state" ì
  871.                     ext := int] ì
  872.                 ifFalse: [ ì
  873.                     "Arm delay timer" ì
  874.                     timer := delay]. ì
  875.             ^self outputToConnections]. ì
  876.     "Propagation delay in progress" ì
  877.     timer := timer - 1. ì
  878.     timer == 0 ì
  879.         ifTrue: [ ì
  880.             "Timer has expired -- update state" ì
  881.             ext := int]. ì
  882.     self outputToConnections. ì
  883.  
  884.  
  885. [LISTIN╟ SIX]
  886.  
  887. simulate ì
  888.  
  889.         "Simulate a 74LS00 device." ì
  890.  
  891.     ((pins at: 1) isHigh and: [(pins at: 2) isHigh]) ì
  892.         ifTrue:  [(pins at: 3) output: false] ì
  893.         ifFalse: [(pins at: 3) output: true]. ì
  894.     ((pins at: 4) isHigh and: [(pins at: 5) isHigh]) ì
  895.         ifTrue:  [(pins at: 6) output: false] ì
  896.         ifFalse: [(pins at: 6) output: true]. ì
  897.     ((pins at: 10) isHigh and: [(pins at: 9) isHigh]) ì
  898.         ifTrue:  [(pins at: 8) output: false] ì
  899.         ifFalse: [(pins at: 8) output: true]. ì
  900.     ((pins at: 13) isHigh and: [(pins at: 12) isHigh]) ì
  901.         ifTrue:  [(pins at: 11) output: false] ì
  902.         ifFalse: [(pins at: 11) output: true]. ì
  903. ì
  904.  
  905.