1 /*
2  * Copyright (c) 2016 Helmut Neemann
3  * Use of this source code is governed by the GPL v3 license
4  * that can be found in the LICENSE file.
5  */
6 package de.neemann.digital.gui.components.terminal;
7 
8 import de.neemann.digital.core.Node;
9 import de.neemann.digital.core.NodeException;
10 import de.neemann.digital.core.ObservableValue;
11 import de.neemann.digital.core.ObservableValues;
12 import de.neemann.digital.core.element.Element;
13 import de.neemann.digital.core.element.ElementAttributes;
14 import de.neemann.digital.core.element.ElementTypeDescription;
15 import de.neemann.digital.core.element.Keys;
16 
17 import static de.neemann.digital.core.element.PinInfo.input;
18 
19 /**
20  * The Keyboard component
21  */
22 public class Keyboard extends Node implements Element {
23 
24     /**
25      * The keyboard description
26      */
27     public static final ElementTypeDescription DESCRIPTION
28             = new ElementTypeDescription(Keyboard.class,
29             input("C").setClock(),
30             input("en"))
31             .addAttribute(Keys.ROTATE)
32             .addAttribute(Keys.LABEL)
33             .addAttribute(Keys.INVERTER_CONFIG);
34 
35     private final String label;
36     private final ObservableValue data;
37     private final ObservableValue keyAvail;
38     private KeyboardInterface keyboardInterface;
39     private ObservableValue clock;
40     private ObservableValue enable;
41     private boolean enableVal;
42     private boolean lastClock = false;
43 
44     /**
45      * Creates a new terminal instance
46      *
47      * @param attributes the attributes
48      */
Keyboard(ElementAttributes attributes)49     public Keyboard(ElementAttributes attributes) {
50         data = new ObservableValue("D", 16)
51                 .setToHighZ()
52                 .setPinDescription(DESCRIPTION);
53         keyAvail = new ObservableValue("av", 1)
54                 .setPinDescription(DESCRIPTION);
55         label = attributes.getLabel();
56     }
57 
58     @Override
setInputs(ObservableValues inputs)59     public void setInputs(ObservableValues inputs) throws NodeException {
60         clock = inputs.get(0).addObserverToValue(this).checkBits(1, this, 0);
61         enable = inputs.get(1).addObserverToValue(this).checkBits(1, this, 1);
62     }
63 
64     @Override
getOutputs()65     public ObservableValues getOutputs() {
66         return new ObservableValues(data, keyAvail);
67     }
68 
69     @Override
readInputs()70     public void readInputs() throws NodeException {
71         enableVal = enable.getBool();
72         boolean nowClock = clock.getBool();
73 
74         if (keyboardInterface != null && nowClock && !lastClock && enableVal)
75             keyboardInterface.deleteFirstChar();
76 
77         lastClock = nowClock;
78     }
79 
80     @Override
writeOutputs()81     public void writeOutputs() throws NodeException {
82         if (keyboardInterface != null) {
83             if (enableVal)
84                 data.setValue(keyboardInterface.getChar());
85             else
86                 data.setToHighZ();
87             keyAvail.setBool(keyboardInterface.getChar() != 0);
88         } else {
89             if (enableVal)
90                 data.setValue(0);
91             else
92                 data.setToHighZ();
93             keyAvail.setBool(false);
94         }
95     }
96 
97     /**
98      * Sets the keyboard interface
99      *
100      * @param keyboardInterface the keyboard interface
101      */
setKeyboard(KeyboardInterface keyboardInterface)102     public void setKeyboard(KeyboardInterface keyboardInterface) {
103         this.keyboardInterface = keyboardInterface;
104     }
105 
106     /**
107      * @return the keyboard label
108      */
getLabel()109     public String getLabel() {
110         return label;
111     }
112 
113     /**
114      * The keyboard interface
115      */
116     public interface KeyboardInterface {
117         /**
118          * @return a char or 0 if no char available, does not remove the char
119          */
getChar()120         int getChar();
121 
122         /**
123          * removes the first char
124          */
deleteFirstChar()125         void deleteFirstChar();
126 
127     }
128 }
129