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