mirror of
https://github.com/hneemann/Digital.git
synced 2025-09-19 09:54:49 -04:00
more consistent handling of int format in probe dialog, fixes #105
This commit is contained in:
parent
c41658ba55
commit
edad475434
@ -88,7 +88,7 @@ public final class Bits {
|
||||
|
||||
/**
|
||||
* Decodes a string to a long.
|
||||
* Supports decimal, octal, hex and binary
|
||||
* Supports decimal, octal, hex, binary and ascii
|
||||
*
|
||||
* @param str the string
|
||||
* @return the long value
|
||||
@ -139,6 +139,10 @@ public final class Bits {
|
||||
p++;
|
||||
if (p == str.length()) throw new NumberFormatException(str, p);
|
||||
break;
|
||||
case '\'':
|
||||
p++;
|
||||
if (p == str.length()) throw new NumberFormatException(str, p);
|
||||
return str.charAt(p);
|
||||
default:
|
||||
if (wasZero) {
|
||||
if (neg) throw new NumberFormatException(str, p);
|
||||
|
@ -1,5 +1,7 @@
|
||||
package de.neemann.digital.core;
|
||||
|
||||
import de.neemann.digital.core.io.IntFormat;
|
||||
|
||||
/**
|
||||
* A simple storage bean for signals
|
||||
*/
|
||||
@ -7,6 +9,7 @@ public final class Signal implements Comparable<Signal> {
|
||||
private final String name;
|
||||
private final ObservableValue value;
|
||||
private final Setter setter;
|
||||
private IntFormat format = IntFormat.def;
|
||||
private String pinNumber;
|
||||
private boolean isPin = false;
|
||||
|
||||
@ -53,6 +56,23 @@ public final class Signal implements Comparable<Signal> {
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the integer format to create a string
|
||||
*
|
||||
* @param format the format
|
||||
* @return this for chained calls
|
||||
*/
|
||||
public Signal setFormat(IntFormat format) {
|
||||
if (format != null) {
|
||||
if (format == IntFormat.def && value.getBits() > 1)
|
||||
this.format = IntFormat.hex;
|
||||
else
|
||||
this.format = format;
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Gets the number of this pin.
|
||||
*
|
||||
@ -96,6 +116,13 @@ public final class Signal implements Comparable<Signal> {
|
||||
return name;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the value in the spscified format
|
||||
*/
|
||||
public String getValueString() {
|
||||
return format.editableFormat(value.getCopy());
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if this signal is a valid signal.
|
||||
* Valid means there is a name and the value is non null
|
||||
@ -130,7 +157,8 @@ public final class Signal implements Comparable<Signal> {
|
||||
* Has to modify the inner state and also has to update the outputs.
|
||||
*
|
||||
* @param value the value to set
|
||||
* @param highZ true is value is in high z state
|
||||
*/
|
||||
void set(long value);
|
||||
void set(long value, boolean highZ);
|
||||
}
|
||||
}
|
||||
|
@ -77,7 +77,7 @@ abstract class FlipflopBit extends Node implements Element {
|
||||
public void registerNodes(Model model) {
|
||||
super.registerNodes(model);
|
||||
if (isProbe)
|
||||
model.addSignal(new Signal(label, q, v -> {
|
||||
model.addSignal(new Signal(label, q, (v, z) -> {
|
||||
out = v != 0;
|
||||
q.setBool(out);
|
||||
qn.setBool(!out);
|
||||
|
@ -104,7 +104,7 @@ public class FlipflopD extends Node implements Element {
|
||||
public void registerNodes(Model model) {
|
||||
super.registerNodes(model);
|
||||
if (isProbe)
|
||||
model.addSignal(new Signal(label, q, v -> {
|
||||
model.addSignal(new Signal(label, q, (v, z) -> {
|
||||
value = v;
|
||||
q.setValue(value);
|
||||
qn.setValue(~value);
|
||||
|
@ -39,6 +39,7 @@ public class In implements Element {
|
||||
private final ObservableValue output;
|
||||
private final String label;
|
||||
private final String pinNumber;
|
||||
private final IntFormat format;
|
||||
private Model model;
|
||||
|
||||
/**
|
||||
@ -53,6 +54,7 @@ public class In implements Element {
|
||||
output = new ObservableValue("out", attributes.get(Keys.BITS), highZ).setPinDescription(DESCRIPTION).setPinNumber(pinNumber);
|
||||
output.set(value.getValue(), value.isHighZ());
|
||||
label = attributes.getCleanLabel();
|
||||
format = attributes.get(Keys.INT_FORMAT);
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -67,7 +69,9 @@ public class In implements Element {
|
||||
|
||||
@Override
|
||||
public void registerNodes(Model model) {
|
||||
model.addInput(new Signal(label, output, output::setValue).setPinNumber(pinNumber));
|
||||
model.addInput(new Signal(label, output, output::set)
|
||||
.setPinNumber(pinNumber)
|
||||
.setFormat(format));
|
||||
this.model = model;
|
||||
}
|
||||
|
||||
|
@ -60,6 +60,35 @@ public enum IntFormat {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Formats the value.
|
||||
* Creates a string which can be parsed by {@link Bits#decode(String)}
|
||||
*
|
||||
* @param inValue the value to format
|
||||
* @return the formatted value as a string
|
||||
* @see Bits#decode(String)
|
||||
*/
|
||||
public String editableFormat(Value inValue) {
|
||||
if (inValue.isHighZ())
|
||||
return "?";
|
||||
|
||||
switch (this) {
|
||||
case dec:
|
||||
return Long.toString(inValue.getValue());
|
||||
case decSigned:
|
||||
return Long.toString(inValue.getValueSigned());
|
||||
case hex:
|
||||
return "0x" + toHex(inValue);
|
||||
case bin:
|
||||
return "0b" + toBin(inValue);
|
||||
case ascii:
|
||||
return "'" + (char) inValue.getValue() + "'";
|
||||
default:
|
||||
return inValue.getValueString();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private static String toHex(Value inValue) {
|
||||
final int bits = inValue.getBits();
|
||||
final int numChars = (bits - 1) / 4 + 1;
|
||||
|
@ -59,6 +59,7 @@ public class Out implements Element {
|
||||
private final int[] bits;
|
||||
private final String label;
|
||||
private final String pinNumber;
|
||||
private final IntFormat format;
|
||||
private ObservableValue value;
|
||||
|
||||
/**
|
||||
@ -70,6 +71,7 @@ public class Out implements Element {
|
||||
bits = new int[]{attributes.getBits()};
|
||||
label = attributes.getCleanLabel();
|
||||
pinNumber = attributes.get(Keys.PINNUMBER);
|
||||
format = attributes.get(Keys.INT_FORMAT);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -81,6 +83,7 @@ public class Out implements Element {
|
||||
this.bits = bits;
|
||||
label = null;
|
||||
pinNumber = "";
|
||||
format = null;
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -99,7 +102,9 @@ public class Out implements Element {
|
||||
|
||||
@Override
|
||||
public void registerNodes(Model model) {
|
||||
model.addOutput(new Signal(label, value).setPinNumber(pinNumber));
|
||||
model.addOutput(new Signal(label, value)
|
||||
.setPinNumber(pinNumber)
|
||||
.setFormat(format));
|
||||
}
|
||||
|
||||
private final static class SevenSegTypeDescription extends ElementTypeDescription {
|
||||
|
@ -25,6 +25,7 @@ public class Probe implements Element {
|
||||
.addAttribute(Keys.INT_FORMAT);
|
||||
|
||||
private final String label;
|
||||
private final IntFormat format;
|
||||
private ObservableValue value;
|
||||
|
||||
/**
|
||||
@ -34,6 +35,7 @@ public class Probe implements Element {
|
||||
*/
|
||||
public Probe(ElementAttributes attributes) {
|
||||
label = attributes.get(Keys.LABEL);
|
||||
format = attributes.get(Keys.INT_FORMAT);
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -48,7 +50,7 @@ public class Probe implements Element {
|
||||
|
||||
@Override
|
||||
public void registerNodes(Model model) {
|
||||
model.addSignal(new Signal(label, value));
|
||||
model.addSignal(new Signal(label, value).setFormat(format));
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -94,7 +94,7 @@ public class Counter extends Node implements Element {
|
||||
public void registerNodes(Model model) {
|
||||
super.registerNodes(model);
|
||||
if (probe)
|
||||
model.addSignal(new Signal(label, out, v -> {
|
||||
model.addSignal(new Signal(label, out, (v, z) -> {
|
||||
counter = v;
|
||||
boolean o = (counter == maxValue) && enable.getBool();
|
||||
out.setValue(counter);
|
||||
|
@ -78,7 +78,7 @@ public class Register extends Node implements Element {
|
||||
public void registerNodes(Model model) {
|
||||
super.registerNodes(model);
|
||||
if (isProbe)
|
||||
model.addSignal(new Signal(label, q, v -> {
|
||||
model.addSignal(new Signal(label, q, (v, z) -> {
|
||||
value = v;
|
||||
q.setValue(value);
|
||||
}));
|
||||
|
@ -175,7 +175,7 @@ public class ProbeDialog extends JDialog implements ModelStateObserverTyped {
|
||||
@Override
|
||||
public Object getValueAt(int rowIndex, int columnIndex) {
|
||||
if (columnIndex == 0) return signals.get(rowIndex).getName();
|
||||
else return signals.get(rowIndex).getValue().getValueString();
|
||||
else return signals.get(rowIndex).getValueString();
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -184,8 +184,13 @@ public class ProbeDialog extends JDialog implements ModelStateObserverTyped {
|
||||
Signal.Setter s = signals.get(rowIndex).getSetter();
|
||||
if (s != null)
|
||||
try {
|
||||
long value = Bits.decode(aValue.toString());
|
||||
modelSync.access(() -> s.set(value));
|
||||
final String str = aValue.toString();
|
||||
if (str.equals("?") || str.equals("z") || str.equals("Z")) {
|
||||
modelSync.access(() -> s.set(0, true));
|
||||
} else {
|
||||
long value = Bits.decode(str);
|
||||
modelSync.access(() -> s.set(value, false));
|
||||
}
|
||||
circuitComponent.modelHasChanged();
|
||||
} catch (Bits.NumberFormatException e) {
|
||||
// do nothing in this case!
|
||||
|
@ -77,6 +77,8 @@ public class BitsTest extends TestCase {
|
||||
assertEquals(0xFFFFFFFFFFFFFFFFL, Bits.decode("0xFFFFFFFFFFFFFFFF"));
|
||||
|
||||
assertEquals(0xFFFFFFFFFFFFFFFFL, Bits.decode("FFFFFFFFFFFFFFFF", 0, 16));
|
||||
|
||||
assertEquals(42, Bits.decode("'*'"));
|
||||
}
|
||||
|
||||
public void testDecodeInvalid() {
|
||||
|
Loading…
x
Reference in New Issue
Block a user