mirror of
https://github.com/hneemann/Digital.git
synced 2025-09-23 04:11:54 -04:00
Merge branch 'telnet'
This commit is contained in:
commit
b3332e0ae3
162
src/main/dig/misc/Telnet.dig
Normal file
162
src/main/dig/misc/Telnet.dig
Normal file
@ -0,0 +1,162 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<circuit>
|
||||
<version>1</version>
|
||||
<attributes/>
|
||||
<visualElements>
|
||||
<visualElement>
|
||||
<elementName>Telnet</elementName>
|
||||
<elementAttributes>
|
||||
<entry>
|
||||
<string>port</string>
|
||||
<int>2323</int>
|
||||
</entry>
|
||||
</elementAttributes>
|
||||
<pos x="400" y="140"/>
|
||||
</visualElement>
|
||||
<visualElement>
|
||||
<elementName>Terminal</elementName>
|
||||
<elementAttributes/>
|
||||
<pos x="520" y="140"/>
|
||||
</visualElement>
|
||||
<visualElement>
|
||||
<elementName>Keyboard</elementName>
|
||||
<elementAttributes/>
|
||||
<pos x="240" y="80"/>
|
||||
</visualElement>
|
||||
<visualElement>
|
||||
<elementName>Clock</elementName>
|
||||
<elementAttributes>
|
||||
<entry>
|
||||
<string>runRealTime</string>
|
||||
<boolean>true</boolean>
|
||||
</entry>
|
||||
<entry>
|
||||
<string>Frequency</string>
|
||||
<int>20</int>
|
||||
</entry>
|
||||
</elementAttributes>
|
||||
<pos x="180" y="160"/>
|
||||
</visualElement>
|
||||
<visualElement>
|
||||
<elementName>Splitter</elementName>
|
||||
<elementAttributes>
|
||||
<entry>
|
||||
<string>Input Splitting</string>
|
||||
<string>16</string>
|
||||
</entry>
|
||||
</elementAttributes>
|
||||
<pos x="340" y="80"/>
|
||||
</visualElement>
|
||||
</visualElements>
|
||||
<wires>
|
||||
<wire>
|
||||
<p1 x="460" y="160"/>
|
||||
<p2 x="480" y="160"/>
|
||||
</wire>
|
||||
<wire>
|
||||
<p1 x="500" y="160"/>
|
||||
<p2 x="520" y="160"/>
|
||||
</wire>
|
||||
<wire>
|
||||
<p1 x="180" y="160"/>
|
||||
<p2 x="200" y="160"/>
|
||||
</wire>
|
||||
<wire>
|
||||
<p1 x="200" y="160"/>
|
||||
<p2 x="400" y="160"/>
|
||||
</wire>
|
||||
<wire>
|
||||
<p1 x="380" y="240"/>
|
||||
<p2 x="480" y="240"/>
|
||||
</wire>
|
||||
<wire>
|
||||
<p1 x="200" y="80"/>
|
||||
<p2 x="240" y="80"/>
|
||||
</wire>
|
||||
<wire>
|
||||
<p1 x="300" y="80"/>
|
||||
<p2 x="340" y="80"/>
|
||||
</wire>
|
||||
<wire>
|
||||
<p1 x="360" y="80"/>
|
||||
<p2 x="380" y="80"/>
|
||||
</wire>
|
||||
<wire>
|
||||
<p1 x="480" y="180"/>
|
||||
<p2 x="520" y="180"/>
|
||||
</wire>
|
||||
<wire>
|
||||
<p1 x="320" y="180"/>
|
||||
<p2 x="400" y="180"/>
|
||||
</wire>
|
||||
<wire>
|
||||
<p1 x="300" y="100"/>
|
||||
<p2 x="320" y="100"/>
|
||||
</wire>
|
||||
<wire>
|
||||
<p1 x="220" y="100"/>
|
||||
<p2 x="240" y="100"/>
|
||||
</wire>
|
||||
<wire>
|
||||
<p1 x="200" y="280"/>
|
||||
<p2 x="500" y="280"/>
|
||||
</wire>
|
||||
<wire>
|
||||
<p1 x="380" y="200"/>
|
||||
<p2 x="400" y="200"/>
|
||||
</wire>
|
||||
<wire>
|
||||
<p1 x="460" y="140"/>
|
||||
<p2 x="520" y="140"/>
|
||||
</wire>
|
||||
<wire>
|
||||
<p1 x="220" y="140"/>
|
||||
<p2 x="320" y="140"/>
|
||||
</wire>
|
||||
<wire>
|
||||
<p1 x="380" y="140"/>
|
||||
<p2 x="400" y="140"/>
|
||||
</wire>
|
||||
<wire>
|
||||
<p1 x="480" y="160"/>
|
||||
<p2 x="480" y="180"/>
|
||||
</wire>
|
||||
<wire>
|
||||
<p1 x="480" y="180"/>
|
||||
<p2 x="480" y="240"/>
|
||||
</wire>
|
||||
<wire>
|
||||
<p1 x="320" y="100"/>
|
||||
<p2 x="320" y="140"/>
|
||||
</wire>
|
||||
<wire>
|
||||
<p1 x="320" y="140"/>
|
||||
<p2 x="320" y="180"/>
|
||||
</wire>
|
||||
<wire>
|
||||
<p1 x="500" y="160"/>
|
||||
<p2 x="500" y="280"/>
|
||||
</wire>
|
||||
<wire>
|
||||
<p1 x="200" y="80"/>
|
||||
<p2 x="200" y="160"/>
|
||||
</wire>
|
||||
<wire>
|
||||
<p1 x="200" y="160"/>
|
||||
<p2 x="200" y="280"/>
|
||||
</wire>
|
||||
<wire>
|
||||
<p1 x="220" y="100"/>
|
||||
<p2 x="220" y="140"/>
|
||||
</wire>
|
||||
<wire>
|
||||
<p1 x="380" y="200"/>
|
||||
<p2 x="380" y="240"/>
|
||||
</wire>
|
||||
<wire>
|
||||
<p1 x="380" y="80"/>
|
||||
<p2 x="380" y="140"/>
|
||||
</wire>
|
||||
</wires>
|
||||
<measurementOrdering/>
|
||||
</circuit>
|
@ -932,5 +932,17 @@ public final class Keys {
|
||||
public static final Key.KeyEnum<ScopeTrigger.Trigger> TRIGGER =
|
||||
new Key.KeyEnum<>("trigger", ScopeTrigger.Trigger.both, ScopeTrigger.Trigger.values());
|
||||
|
||||
/**
|
||||
* Selects the telnet port
|
||||
*/
|
||||
public static final Key.KeyInteger PORT =
|
||||
new Key.KeyInteger("port", 23)
|
||||
.setMin(1)
|
||||
.setMax((1 << 16) - 1);
|
||||
/**
|
||||
* Telnet escape
|
||||
*/
|
||||
public static final Key<Boolean> TELNET_ESCAPE =
|
||||
new Key<>("telnetEscape", true).allowGroupEdit();
|
||||
|
||||
}
|
||||
|
@ -0,0 +1,84 @@
|
||||
/*
|
||||
* Copyright (c) 2021 Helmut Neemann.
|
||||
* Use of this source code is governed by the GPL v3 license
|
||||
* that can be found in the LICENSE file.
|
||||
*/
|
||||
package de.neemann.digital.core.io.telnet;
|
||||
|
||||
/**
|
||||
* A simple thread save byte queue.
|
||||
*/
|
||||
public class ByteBuffer {
|
||||
private final byte[] data;
|
||||
private final int size;
|
||||
private int inBuffer;
|
||||
private int newest;
|
||||
private int oldest;
|
||||
|
||||
/**
|
||||
* Creates a new instance
|
||||
*
|
||||
* @param size the size of the buffer
|
||||
*/
|
||||
public ByteBuffer(int size) {
|
||||
data = new byte[size];
|
||||
this.size = size;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a byte at the top of the buffer
|
||||
*
|
||||
* @param value the byte value
|
||||
*/
|
||||
synchronized public void put(byte value) {
|
||||
if (inBuffer < size) {
|
||||
data[newest] = value;
|
||||
newest = inc(newest);
|
||||
inBuffer++;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the byte at the tail of the buffer
|
||||
*/
|
||||
synchronized public byte peek() {
|
||||
if (inBuffer > 0) {
|
||||
return data[oldest];
|
||||
} else
|
||||
return -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* deletes a byte from the tail of the buffer
|
||||
*/
|
||||
synchronized public void delete() {
|
||||
if (inBuffer > 0) {
|
||||
oldest = inc(oldest);
|
||||
inBuffer--;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* deletes all buffered data
|
||||
*/
|
||||
synchronized public void deleteAll() {
|
||||
oldest = 0;
|
||||
newest = 0;
|
||||
inBuffer = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return true if there is data available
|
||||
*/
|
||||
synchronized public boolean hasData() {
|
||||
return inBuffer > 0;
|
||||
}
|
||||
|
||||
private int inc(int n) {
|
||||
n++;
|
||||
if (n >= size)
|
||||
n = 0;
|
||||
return n;
|
||||
}
|
||||
|
||||
}
|
179
src/main/java/de/neemann/digital/core/io/telnet/Server.java
Normal file
179
src/main/java/de/neemann/digital/core/io/telnet/Server.java
Normal file
@ -0,0 +1,179 @@
|
||||
/*
|
||||
* Copyright (c) 2021 Helmut Neemann.
|
||||
* Use of this source code is governed by the GPL v3 license
|
||||
* that can be found in the LICENSE file.
|
||||
*/
|
||||
package de.neemann.digital.core.io.telnet;
|
||||
|
||||
import de.neemann.digital.core.SyncAccess;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.net.ServerSocket;
|
||||
import java.net.Socket;
|
||||
|
||||
/**
|
||||
* The telnet server
|
||||
*/
|
||||
public class Server {
|
||||
private final ServerSocket serverSocket;
|
||||
private final ByteBuffer buffer;
|
||||
private final ServerThread serverThread;
|
||||
private boolean telnetEscape;
|
||||
private ClientThread client;
|
||||
private Telnet telnet;
|
||||
private SyncAccess syncAccess;
|
||||
|
||||
Server(int port) throws IOException {
|
||||
buffer = new ByteBuffer(1024);
|
||||
serverSocket = new ServerSocket(port);
|
||||
serverThread = new ServerThread();
|
||||
serverThread.start();
|
||||
}
|
||||
|
||||
void send(int value) {
|
||||
if (client != null)
|
||||
client.send(value);
|
||||
}
|
||||
|
||||
int getData() {
|
||||
return buffer.peek();
|
||||
}
|
||||
|
||||
void deleteOldest() {
|
||||
buffer.delete();
|
||||
}
|
||||
|
||||
void deleteAll() {
|
||||
buffer.deleteAll();
|
||||
}
|
||||
|
||||
/**
|
||||
* Connects the server with the telnet node
|
||||
*
|
||||
* @param telnet the telnet node
|
||||
* @param syncAccess used to access the model
|
||||
*/
|
||||
public void setTelnetNode(Telnet telnet, SyncAccess syncAccess) {
|
||||
this.telnet = telnet;
|
||||
this.syncAccess = syncAccess;
|
||||
}
|
||||
|
||||
boolean hasData() {
|
||||
return buffer.hasData();
|
||||
}
|
||||
|
||||
private void setClient(ClientThread client) {
|
||||
this.client = client;
|
||||
}
|
||||
|
||||
void setTelnetEscape(boolean telnetEscape) {
|
||||
this.telnetEscape = telnetEscape;
|
||||
}
|
||||
|
||||
private void dataReceived(int data) {
|
||||
if (syncAccess != null)
|
||||
syncAccess.modify(() -> {
|
||||
buffer.put((byte) data);
|
||||
telnet.hasChanged();
|
||||
});
|
||||
}
|
||||
|
||||
boolean isDead() {
|
||||
return !serverThread.isAlive();
|
||||
}
|
||||
|
||||
private final class ServerThread extends Thread {
|
||||
|
||||
private ServerThread() {
|
||||
setDaemon(true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
while (true) {
|
||||
Socket client = serverSocket.accept();
|
||||
ClientThread cl = new ClientThread(client, Server.this);
|
||||
cl.start();
|
||||
setClient(cl);
|
||||
}
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private static final class ClientThread extends Thread {
|
||||
|
||||
private static final int ECHO = 1;
|
||||
private static final int SGA = 3;
|
||||
private static final int WILL = 251;
|
||||
private static final int WONT = 252;
|
||||
private static final int DO = 253;
|
||||
private static final int DONT = 254;
|
||||
private static final int IAC = 255;
|
||||
|
||||
private final InputStream in;
|
||||
private final OutputStream out;
|
||||
private final Socket client;
|
||||
private final Server server;
|
||||
|
||||
private ClientThread(Socket client, Server server) throws IOException {
|
||||
setDaemon(true);
|
||||
in = client.getInputStream();
|
||||
out = client.getOutputStream();
|
||||
if (server.telnetEscape) {
|
||||
out.write(IAC);
|
||||
out.write(WILL);
|
||||
out.write(SGA);
|
||||
out.write(IAC);
|
||||
out.write(WILL);
|
||||
out.write(ECHO);
|
||||
out.flush();
|
||||
}
|
||||
this.client = client;
|
||||
this.server = server;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
while (true) {
|
||||
int data = in.read();
|
||||
if (data < 0)
|
||||
break;
|
||||
if (data == IAC && server.telnetEscape) {
|
||||
int command = in.read();
|
||||
int option = in.read();
|
||||
} else
|
||||
server.dataReceived(data);
|
||||
}
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
try {
|
||||
client.close();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
public void send(int value) {
|
||||
try {
|
||||
out.write(value);
|
||||
out.flush();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
try {
|
||||
client.close();
|
||||
} catch (IOException ioException) {
|
||||
ioException.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,44 @@
|
||||
/*
|
||||
* Copyright (c) 2021 Helmut Neemann.
|
||||
* Use of this source code is governed by the GPL v3 license
|
||||
* that can be found in the LICENSE file.
|
||||
*/
|
||||
package de.neemann.digital.core.io.telnet;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.HashMap;
|
||||
|
||||
/**
|
||||
* Simple singleton to hold the server instances.
|
||||
* Usage of this singleton allows the telnet client to stay connected
|
||||
* also if the simulation is not running.
|
||||
*/
|
||||
public final class ServerHolder {
|
||||
/**
|
||||
* The singleton instance
|
||||
*/
|
||||
public static final ServerHolder INSTANCE = new ServerHolder();
|
||||
|
||||
private final HashMap<Integer, Server> serverMap;
|
||||
|
||||
private ServerHolder() {
|
||||
serverMap = new HashMap<>();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a server.
|
||||
*
|
||||
* @param port the port
|
||||
* @return the server
|
||||
* @throws IOException IOException
|
||||
*/
|
||||
public Server getServer(int port) throws IOException {
|
||||
Server server = serverMap.get(port);
|
||||
if (server == null || server.isDead()) {
|
||||
server = new Server(port);
|
||||
serverMap.put(port, server);
|
||||
} else
|
||||
server.deleteAll();
|
||||
return server;
|
||||
}
|
||||
}
|
109
src/main/java/de/neemann/digital/core/io/telnet/Telnet.java
Normal file
109
src/main/java/de/neemann/digital/core/io/telnet/Telnet.java
Normal file
@ -0,0 +1,109 @@
|
||||
/*
|
||||
* Copyright (c) 2021 Helmut Neemann.
|
||||
* Use of this source code is governed by the GPL v3 license
|
||||
* that can be found in the LICENSE file.
|
||||
*/
|
||||
package de.neemann.digital.core.io.telnet;
|
||||
|
||||
import de.neemann.digital.core.*;
|
||||
import de.neemann.digital.core.element.Element;
|
||||
import de.neemann.digital.core.element.ElementAttributes;
|
||||
import de.neemann.digital.core.element.ElementTypeDescription;
|
||||
import de.neemann.digital.core.element.Keys;
|
||||
import de.neemann.digital.draw.elements.PinException;
|
||||
import de.neemann.digital.lang.Lang;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import static de.neemann.digital.core.element.PinInfo.input;
|
||||
|
||||
/**
|
||||
* The telnet node
|
||||
*/
|
||||
public class Telnet extends Node implements Element {
|
||||
|
||||
/**
|
||||
* The telnet server description
|
||||
*/
|
||||
public static final ElementTypeDescription DESCRIPTION = new ElementTypeDescription(Telnet.class,
|
||||
input("in"), input("C").setClock(), input("wr"), input("rd"))
|
||||
.addAttribute(Keys.ROTATE)
|
||||
.addAttribute(Keys.LABEL)
|
||||
.addAttribute(Keys.TELNET_ESCAPE)
|
||||
.addAttribute(Keys.PORT);
|
||||
|
||||
private final ObservableValue dataOut;
|
||||
private final ObservableValue dataAvail;
|
||||
private final int port;
|
||||
private final boolean telnetEscape;
|
||||
private ObservableValue dataIn;
|
||||
private ObservableValue clockValue;
|
||||
private ObservableValue writeEnable;
|
||||
private ObservableValue readEnableValue;
|
||||
private Server server;
|
||||
private boolean lastClock;
|
||||
private boolean readEnable;
|
||||
|
||||
/**
|
||||
* Creates a new instance
|
||||
*
|
||||
* @param attributes The components attributes
|
||||
*/
|
||||
public Telnet(ElementAttributes attributes) {
|
||||
dataOut = new ObservableValue("out", 8)
|
||||
.setToHighZ()
|
||||
.setPinDescription(DESCRIPTION);
|
||||
dataAvail = new ObservableValue("av", 1)
|
||||
.setPinDescription(DESCRIPTION);
|
||||
port = attributes.get(Keys.PORT);
|
||||
telnetEscape = attributes.get(Keys.TELNET_ESCAPE);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setInputs(ObservableValues inputs) throws NodeException {
|
||||
dataIn = inputs.get(0).checkBits(8, this, 0);
|
||||
clockValue = inputs.get(1).checkBits(1, this, 1).addObserverToValue(this);
|
||||
writeEnable = inputs.get(2).checkBits(1, this, 2);
|
||||
readEnableValue = inputs.get(3).checkBits(1, this, 3).addObserverToValue(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void readInputs() throws NodeException {
|
||||
boolean clock = clockValue.getBool();
|
||||
readEnable = readEnableValue.getBool();
|
||||
if (clock & !lastClock) {
|
||||
if (writeEnable.getBool())
|
||||
server.send((int) dataIn.getValue());
|
||||
if (readEnable)
|
||||
server.deleteOldest();
|
||||
}
|
||||
lastClock = clock;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeOutputs() throws NodeException {
|
||||
if (readEnable)
|
||||
dataOut.setValue(server.getData());
|
||||
else
|
||||
dataOut.setToHighZ();
|
||||
|
||||
dataAvail.setBool(server.hasData());
|
||||
}
|
||||
|
||||
@Override
|
||||
public ObservableValues getOutputs() throws PinException {
|
||||
return new ObservableValues(dataOut, dataAvail);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void init(Model model) throws NodeException {
|
||||
try {
|
||||
server = ServerHolder.INSTANCE.getServer(port);
|
||||
} catch (IOException e) {
|
||||
throw new NodeException(Lang.get("err_couldNotCreateServer"), e);
|
||||
}
|
||||
server.setTelnetEscape(telnetEscape);
|
||||
server.setTelnetNode(this, model);
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,10 @@
|
||||
/*
|
||||
* Copyright (c) 2021 Helmut Neemann.
|
||||
* Use of this source code is governed by the GPL v3 license
|
||||
* that can be found in the LICENSE file.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Implement's a telnet connection to the simulator
|
||||
*/
|
||||
package de.neemann.digital.core.io.telnet;
|
@ -15,6 +15,7 @@ import de.neemann.digital.core.extern.External;
|
||||
import de.neemann.digital.core.extern.ExternalFile;
|
||||
import de.neemann.digital.core.flipflops.*;
|
||||
import de.neemann.digital.core.io.*;
|
||||
import de.neemann.digital.core.io.telnet.Telnet;
|
||||
import de.neemann.digital.core.memory.*;
|
||||
import de.neemann.digital.core.pld.DiodeBackward;
|
||||
import de.neemann.digital.core.pld.DiodeForward;
|
||||
@ -150,6 +151,7 @@ public class ElementLibrary implements Iterable<ElementLibrary.ElementContainer>
|
||||
.add(new LibraryNode(Lang.get("lib_peripherals"))
|
||||
.add(Keyboard.DESCRIPTION)
|
||||
.add(Terminal.DESCRIPTION)
|
||||
.add(Telnet.DESCRIPTION)
|
||||
.add(VGA.DESCRIPTION)
|
||||
.add(MIDI.DESCRIPTION)
|
||||
)
|
||||
|
@ -280,6 +280,16 @@
|
||||
</string>
|
||||
<string name="elem_Terminal_pin_en">Ein High an diesem Eingang aktiviert den Takteingang.</string>
|
||||
|
||||
<string name="elem_Telnet">Telnet</string>
|
||||
<string name="elem_Telnet_tt">Erlaubt eine Telnet-Verbindung zur Schaltung.
|
||||
Es können per Telnet Zeichen empfangen und gesendet werden.</string>
|
||||
<string name="elem_Telnet_pin_out">Datenausgabe</string>
|
||||
<string name="elem_Telnet_pin_av">Gibt eine Eins aus, wenn Daten vorhanden sind.</string>
|
||||
<string name="elem_Telnet_pin_in">Die zu sendenden Daten.</string>
|
||||
<string name="elem_Telnet_pin_C">Takteingang.</string>
|
||||
<string name="elem_Telnet_pin_wr">Wenn gesetzt, wird das Eingangsdatenbyte gesendet.</string>
|
||||
<string name="elem_Telnet_pin_rd">Wenn gesetzt, wird ein empfangenes Byte ausgegeben.</string>
|
||||
|
||||
<string name="elem_VGA">VGA Bildschirm</string>
|
||||
<string name="elem_VGA_short">VGA</string>
|
||||
<string name="elem_VGA_tt">Analysiert die eingehenden Video-Signale und zeigt die entsprechende Grafik an.
|
||||
@ -1241,6 +1251,7 @@ Sind evtl. die Namen der Variablen nicht eindeutig?</string>
|
||||
<string name="err_csvToManyValues">Zu viel Werte in einer Zeile!</string>
|
||||
<string name="err_errorWritingFile_N">Fehler beim Schreiben der Datei {0}.</string>
|
||||
<string name="err_circuitContainsNoComponents">Die Schaltung enthält keine Bauteile!</string>
|
||||
<string name="err_couldNotCreateServer">Der Server konnte nicht gestartet werden!</string>
|
||||
|
||||
<string name="key_AddrBits">Adress-Bits</string><!-- ROM, RAMDualPort, RAMSinglePort, RAMSinglePortSel, EEPROM -->
|
||||
<string name="key_AddrBits_tt">Anzahl der Adress-Bits, die verwendet werden.</string>
|
||||
@ -1665,6 +1676,14 @@ Sind evtl. die Namen der Variablen nicht eindeutig?</string>
|
||||
<string name="key_probeMode_DOWN">Zähle fallende Flanken</string>
|
||||
<string name="key_probeMode_BOTH">Zähle beide Flanken</string>
|
||||
|
||||
<string name="key_telnetEscape">Telnet-Modus</string>
|
||||
<string name="key_telnetEscape_tt">Wenn gesetzt, werden die Telnet Steuerkommandos ausgewertet.
|
||||
Zusätzlich werden vom Server die Kommandos SGA und ECHO gesendet.
|
||||
Wird diese Option deaktiviert, handelt es sich um einen einfachen TCP-Server.
|
||||
</string>
|
||||
<string name="key_port">Port</string>
|
||||
<string name="key_port_tt">Der vom Server zu öffnende Port.</string>
|
||||
|
||||
<string name="key_colorScheme">Farbschema</string>
|
||||
<string name="key_colorScheme_DEFAULT">Normal</string>
|
||||
<string name="key_colorScheme_DARK">Dunkel</string>
|
||||
|
@ -280,6 +280,16 @@
|
||||
<string name="elem_Terminal_pin_D">The data to write to the terminal</string>
|
||||
<string name="elem_Terminal_pin_en">A high at this input enables the clock input.</string>
|
||||
|
||||
<string name="elem_Telnet">Telnet</string>
|
||||
<string name="elem_Telnet_tt">Allows a Telnet connection to the circuit.
|
||||
It is possible to receive and send characters via Telnet.</string>
|
||||
<string name="elem_Telnet_pin_out">Data output</string>
|
||||
<string name="elem_Telnet_pin_av">Outputs a one if data is present.</string>
|
||||
<string name="elem_Telnet_pin_in">The data to be sent.</string>
|
||||
<string name="elem_Telnet_pin_C">Clock input</string>
|
||||
<string name="elem_Telnet_pin_wr">If set, the input data byte is sent.</string>
|
||||
<string name="elem_Telnet_pin_rd">If set, a received byte is output.</string>
|
||||
|
||||
<string name="elem_VGA">VGA Monitor</string>
|
||||
<string name="elem_VGA_short">VGA</string>
|
||||
<string name="elem_VGA_tt">Analyzes the incoming video signals and displays the corresponding graphic.
|
||||
@ -1228,6 +1238,7 @@
|
||||
<string name="err_csvToManyValues">Too many values in one line!</string>
|
||||
<string name="err_errorWritingFile_N">Error writing file {0}.</string>
|
||||
<string name="err_circuitContainsNoComponents">The circuit contains no components!</string>
|
||||
<string name="err_couldNotCreateServer">Could not start the server!</string>
|
||||
|
||||
<string name="key_AddrBits">Address Bits</string><!-- ROM, RAMDualPort, RAMSinglePort, RAMSinglePortSel, EEPROM -->
|
||||
<string name="key_AddrBits_tt">Number of address bits used.</string>
|
||||
@ -1652,6 +1663,13 @@
|
||||
<string name="key_probeMode_DOWN">Count on Falling Edge</string>
|
||||
<string name="key_probeMode_BOTH">Count both Edges</string>
|
||||
|
||||
<string name="key_telnetEscape">Telnet mode</string>
|
||||
<string name="key_telnetEscape_tt">If set, the Telnet control commands are evaluated.
|
||||
In addition, the server sends the SGA and ECHO commands. If this option is disabled,
|
||||
the server is a simple TCP server.</string>
|
||||
<string name="key_port">Port</string>
|
||||
<string name="key_port_tt">The port to be opened by the server.</string>
|
||||
|
||||
<string name="key_colorScheme">Color scheme</string>
|
||||
<string name="key_colorScheme_DEFAULT">Normal</string>
|
||||
<string name="key_colorScheme_DARK">Dark</string>
|
||||
|
@ -40,7 +40,7 @@ public class TestExamples extends TestCase {
|
||||
*/
|
||||
public void testDistExamples() throws Exception {
|
||||
File examples = new File(Resources.getRoot().getParentFile().getParentFile(), "/main/dig");
|
||||
assertEquals(316, new FileScanner(this::check).scan(examples));
|
||||
assertEquals(317, new FileScanner(this::check).scan(examples));
|
||||
assertEquals(502, testCasesInFiles);
|
||||
}
|
||||
|
||||
|
@ -695,15 +695,29 @@
|
||||
<int>8</int>
|
||||
</entry>
|
||||
</elementAttributes>
|
||||
<pos x="420" y="1080"/>
|
||||
<pos x="420" y="1100"/>
|
||||
</visualElement>
|
||||
<visualElement>
|
||||
<elementName>GenericCode</elementName>
|
||||
<elementAttributes/>
|
||||
<pos x="120" y="1120"/>
|
||||
</visualElement>
|
||||
<visualElement>
|
||||
<elementName>Telnet</elementName>
|
||||
<elementAttributes>
|
||||
<entry>
|
||||
<string>port</string>
|
||||
<int>2323</int>
|
||||
</entry>
|
||||
</elementAttributes>
|
||||
<pos x="540" y="1100"/>
|
||||
</visualElement>
|
||||
</visualElements>
|
||||
<wires>
|
||||
<wire>
|
||||
<p1 x="500" y="1060"/>
|
||||
<p2 x="520" y="1100"/>
|
||||
</wire>
|
||||
<wire>
|
||||
<p1 x="1080" y="640"/>
|
||||
<p2 x="1100" y="640"/>
|
||||
@ -752,6 +766,10 @@
|
||||
<p1 x="700" y="520"/>
|
||||
<p2 x="800" y="520"/>
|
||||
</wire>
|
||||
<wire>
|
||||
<p1 x="520" y="1160"/>
|
||||
<p2 x="540" y="1160"/>
|
||||
</wire>
|
||||
<wire>
|
||||
<p1 x="400" y="1160"/>
|
||||
<p2 x="420" y="1160"/>
|
||||
@ -864,6 +882,10 @@
|
||||
<p1 x="780" y="280"/>
|
||||
<p2 x="800" y="280"/>
|
||||
</wire>
|
||||
<wire>
|
||||
<p1 x="400" y="1180"/>
|
||||
<p2 x="420" y="1180"/>
|
||||
</wire>
|
||||
<wire>
|
||||
<p1 x="220" y="540"/>
|
||||
<p2 x="260" y="540"/>
|
||||
@ -916,6 +938,10 @@
|
||||
<p1 x="580" y="1060"/>
|
||||
<p2 x="600" y="1060"/>
|
||||
</wire>
|
||||
<wire>
|
||||
<p1 x="380" y="1060"/>
|
||||
<p2 x="500" y="1060"/>
|
||||
</wire>
|
||||
<wire>
|
||||
<p1 x="760" y="1060"/>
|
||||
<p2 x="840" y="1060"/>
|
||||
@ -1073,8 +1099,8 @@
|
||||
<p2 x="240" y="1080"/>
|
||||
</wire>
|
||||
<wire>
|
||||
<p1 x="380" y="1080"/>
|
||||
<p2 x="420" y="1080"/>
|
||||
<p1 x="400" y="1080"/>
|
||||
<p2 x="500" y="1080"/>
|
||||
</wire>
|
||||
<wire>
|
||||
<p1 x="240" y="1080"/>
|
||||
@ -1181,20 +1207,24 @@
|
||||
<p2 x="1160" y="840"/>
|
||||
</wire>
|
||||
<wire>
|
||||
<p1 x="220" y="460"/>
|
||||
<p2 x="260" y="460"/>
|
||||
</wire>
|
||||
<wire>
|
||||
<p1 x="600" y="460"/>
|
||||
<p2 x="620" y="460"/>
|
||||
<p1 x="380" y="1100"/>
|
||||
<p2 x="420" y="1100"/>
|
||||
</wire>
|
||||
<wire>
|
||||
<p1 x="240" y="1100"/>
|
||||
<p2 x="260" y="1100"/>
|
||||
</wire>
|
||||
<wire>
|
||||
<p1 x="400" y="1100"/>
|
||||
<p2 x="420" y="1100"/>
|
||||
<p1 x="520" y="1100"/>
|
||||
<p2 x="540" y="1100"/>
|
||||
</wire>
|
||||
<wire>
|
||||
<p1 x="220" y="460"/>
|
||||
<p2 x="260" y="460"/>
|
||||
</wire>
|
||||
<wire>
|
||||
<p1 x="600" y="460"/>
|
||||
<p2 x="620" y="460"/>
|
||||
</wire>
|
||||
<wire>
|
||||
<p1 x="600" y="720"/>
|
||||
@ -1276,6 +1306,18 @@
|
||||
<p1 x="760" y="220"/>
|
||||
<p2 x="800" y="220"/>
|
||||
</wire>
|
||||
<wire>
|
||||
<p1 x="400" y="1120"/>
|
||||
<p2 x="420" y="1120"/>
|
||||
</wire>
|
||||
<wire>
|
||||
<p1 x="500" y="1120"/>
|
||||
<p2 x="520" y="1120"/>
|
||||
</wire>
|
||||
<wire>
|
||||
<p1 x="520" y="1120"/>
|
||||
<p2 x="540" y="1120"/>
|
||||
</wire>
|
||||
<wire>
|
||||
<p1 x="1140" y="480"/>
|
||||
<p2 x="1160" y="480"/>
|
||||
@ -1413,8 +1455,8 @@
|
||||
<p2 x="1200" y="500"/>
|
||||
</wire>
|
||||
<wire>
|
||||
<p1 x="400" y="1140"/>
|
||||
<p2 x="420" y="1140"/>
|
||||
<p1 x="520" y="1140"/>
|
||||
<p2 x="540" y="1140"/>
|
||||
</wire>
|
||||
<wire>
|
||||
<p1 x="1080" y="760"/>
|
||||
@ -1644,6 +1686,14 @@
|
||||
<p1 x="520" y="740"/>
|
||||
<p2 x="520" y="780"/>
|
||||
</wire>
|
||||
<wire>
|
||||
<p1 x="520" y="1120"/>
|
||||
<p2 x="520" y="1140"/>
|
||||
</wire>
|
||||
<wire>
|
||||
<p1 x="520" y="1140"/>
|
||||
<p2 x="520" y="1160"/>
|
||||
</wire>
|
||||
<wire>
|
||||
<p1 x="840" y="1000"/>
|
||||
<p2 x="840" y="1060"/>
|
||||
@ -1714,19 +1764,23 @@
|
||||
</wire>
|
||||
<wire>
|
||||
<p1 x="400" y="1020"/>
|
||||
<p2 x="400" y="1100"/>
|
||||
<p2 x="400" y="1080"/>
|
||||
</wire>
|
||||
<wire>
|
||||
<p1 x="400" y="1080"/>
|
||||
<p2 x="400" y="1120"/>
|
||||
</wire>
|
||||
<wire>
|
||||
<p1 x="400" y="580"/>
|
||||
<p2 x="400" y="780"/>
|
||||
</wire>
|
||||
<wire>
|
||||
<p1 x="400" y="1100"/>
|
||||
<p2 x="400" y="1140"/>
|
||||
<p1 x="400" y="1120"/>
|
||||
<p2 x="400" y="1160"/>
|
||||
</wire>
|
||||
<wire>
|
||||
<p1 x="400" y="1140"/>
|
||||
<p2 x="400" y="1160"/>
|
||||
<p1 x="400" y="1160"/>
|
||||
<p2 x="400" y="1180"/>
|
||||
</wire>
|
||||
<wire>
|
||||
<p1 x="400" y="220"/>
|
||||
@ -2028,6 +2082,10 @@
|
||||
<p1 x="500" y="560"/>
|
||||
<p2 x="500" y="580"/>
|
||||
</wire>
|
||||
<wire>
|
||||
<p1 x="500" y="1080"/>
|
||||
<p2 x="500" y="1120"/>
|
||||
</wire>
|
||||
<wire>
|
||||
<p1 x="500" y="760"/>
|
||||
<p2 x="500" y="840"/>
|
||||
@ -2160,6 +2218,10 @@
|
||||
<p1 x="380" y="140"/>
|
||||
<p2 x="380" y="160"/>
|
||||
</wire>
|
||||
<wire>
|
||||
<p1 x="380" y="1060"/>
|
||||
<p2 x="380" y="1100"/>
|
||||
</wire>
|
||||
<wire>
|
||||
<p1 x="380" y="160"/>
|
||||
<p2 x="380" y="820"/>
|
||||
@ -2170,7 +2232,7 @@
|
||||
</wire>
|
||||
<wire>
|
||||
<p1 x="380" y="920"/>
|
||||
<p2 x="380" y="1080"/>
|
||||
<p2 x="380" y="1060"/>
|
||||
</wire>
|
||||
</wires>
|
||||
<measurementOrdering/>
|
||||
|
Loading…
x
Reference in New Issue
Block a user