Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,8 @@
public class BasicCircuits extends CircuitLibrary {
@Override
public Class[] getCircuitClasses() {
return new Class[] { adder.class, and.class, clock.class, counter.class, demultiplexer.class, divider.class, flipflop.class,
multiplexer.class, multiplier.class, or.class, pisoregister.class, print.class, random.class, receiver.class,
return new Class[] { adder.class, and.class, clock.class, counter.class, combocounter.class, demultiplexer.class, divider.class,
flipflop.class, multiplexer.class, multiplier.class, or.class, pisoregister.class, print.class, random.class, receiver.class,
shiftregister.class, transmitter.class, xor.class, decoder.class, encoder.class, pixel.class, pulse.class, not.class,
synth.class, srnor.class, terminal.class, router.class, ringcounter.class, iptransmitter.class, ipreceiver.class,
comparator.class, delay.class, repeater.class, nand.class, nor.class, xnor.class, segdriver.class, dregister.class,
Expand Down
92 changes: 92 additions & 0 deletions src/main/java/org/redstonechips/basiccircuits/combocounter.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
package org.redstonechips.basiccircuits;

import java.util.HashMap;
import java.util.Map;
import org.redstonechips.circuit.Circuit;

/**
* Combination counter that can both increment and decrement
*/
public class combocounter extends Circuit {
private int incPin = 0;
private int decPin = 1;
private int resetPin = 2;

int min;
int max;
int count;

@Override
public void input(boolean state, int inIdx) {
if (state) {
if (inIdx == incPin) {
if (count >= max) {
count = min;
}
else {
count = count + 1;
}

if (chip.hasListeners()) debug("Counting " + count + ".");
this.writeInt(count, 0, outputlen);
}
else if (inIdx == decPin) {
if (count <= min) {
count = max;
}
else {
count = count - 1;
}

if (chip.hasListeners()) debug("Counting " + count + ".");
this.writeInt(count, 0, outputlen);
}
else if (inIdx == resetPin) {
count = 0;

if (chip.hasListeners()) debug("Resetting counter to " + count + ".");
this.writeInt(count, 0, outputlen);
}

}
}

@Override
public Circuit init(String[] args) {
if (inputlen == 0) {
return error("Expecting at least 1 input.");
}

if (args.length==0) {
min = 0;
max = (int)Math.pow(2, outputlen) - 1;
}
else {
return error("Illegal number of arguments (max 0).");
}

count = min;
return this;
}

@Override
public boolean isStateless() {
return false;
}

@Override
public void setInternalState(Map<String, String> state) {
String loadedCount = state.get("count");
if (loadedCount != null) {
count = Integer.decode(loadedCount);
writeInt(count, 0, outputlen);
}
}

@Override
public Map<String, String> getInternalState() {
Map<String,String> state = new HashMap<String, String>();
state.put("count", Integer.toString(count));
return state;
}
}
4 changes: 3 additions & 1 deletion src/main/java/org/redstonechips/basiccircuits/display.java
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
import org.redstonechips.memory.RamListener;
import org.redstonechips.util.BooleanArrays;
import org.redstonechips.util.BooleanSubset;
import org.redstonechips.util.Optional;
import org.redstonechips.wireless.Receiver;

/**
Expand Down Expand Up @@ -101,7 +102,8 @@ public void dataChanged(Ram ram, long address, boolean[] data) {
private void refreshDisplayFromRam() {
long offset = ramPage * ramPageLength;
for (long i=offset; i<offset+ramPageLength; i++) {
int color = (int)BooleanArrays.toUnsignedInt(ram.read(i));
boolean[] data = ram.readDefaultZero(i, colorWordlength);
int color = (int)BooleanArrays.toUnsignedInt(data);
int x = (int)((i-offset) % screen.getDescription().addrWidth);
int y = (int)((i-offset) / screen.getDescription().addrWidth);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ public Circuit init(String[] args) {
if (ram != null) {
ramListener = new dregisterRamListener();
ram.addListener(ramListener);
this.writeBits(ram.read(ramaddr));
this.writeBits(ram.read(ramaddr).get());
info("Created "+outputlen+"-bit register backed by memory: "+ram.getId()+"@"+Long.toHexString(ramaddr));
} else
info("Created "+outputlen+"-bit register.");
Expand Down
17 changes: 14 additions & 3 deletions src/main/java/org/redstonechips/basiccircuits/encoder.java
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,20 @@ public class encoder extends Circuit {

@Override
public void input(boolean state, int inIdx) {
if (state) {
writeInt(inIdx, 0, outputlen);
} else {
int totalEnabledBits = 0;
int mostSignificantBit = -1;

for (int i = 0; i < inputs.length; i++) {
if (inputs[i]) {
totalEnabledBits++;
mostSignificantBit = i;
}
}

if (totalEnabledBits == 1) {
writeInt(mostSignificantBit, 0, outputlen);
}
else {
this.clearOutputs();
}
}
Expand Down
6 changes: 5 additions & 1 deletion src/main/java/org/redstonechips/basiccircuits/pixel.java
Original file line number Diff line number Diff line change
Expand Up @@ -181,7 +181,11 @@ public void receive(BooleanSubset bits) {
// if we have 0 or 1 inputs there's no clock to adjust. just use the incoming bits.
boolean[] valbits;
if (inputlen<=1) {
valbits = bits.copy(0, (inputlen==0?5:inputlen));
int copylen = 5;
if (bits.length() < copylen) {
copylen = bits.length();
}
valbits = bits.copy(0, copylen);
} else {
valbits = new boolean[bits.length()+1];
for (int i=0; i<bits.length(); i++)
Expand Down
83 changes: 65 additions & 18 deletions src/main/java/org/redstonechips/basiccircuits/pulse.java
Original file line number Diff line number Diff line change
Expand Up @@ -10,23 +10,22 @@
public class pulse extends Circuit {

public enum EdgeTriggering { positive, negative, doubleEdge };
public enum RepeatedTriggerMode { legacy, ignore, extend };

private EdgeTriggering trigger = EdgeTriggering.positive;
private RepeatedTriggerMode repeatedTriggerMode = RepeatedTriggerMode.legacy;

private long interval;
private PulseOff[] pulseOffs;
private Integer[] pulseOffIds;
private long intervalInTicks;

@Override
public void input(boolean state, final int inIdx) {
if (state && (trigger==EdgeTriggering.positive || trigger==EdgeTriggering.doubleEdge)) {
if (inputlen==outputlen)
pulse(inIdx);
else pulseSequence();
trigger(inIdx);
} else if (!state && (trigger == EdgeTriggering.negative || trigger == EdgeTriggering.doubleEdge)) {
if (inputlen==outputlen)
pulse(inIdx);
else pulseSequence();
trigger(inIdx);
}

}
Expand All @@ -38,7 +37,6 @@ public Circuit init(String[] args) {

if (inputlen==0)
return error("Expecting at least one input and one output.");


if (args.length==0) interval = 1000; // 1 sec default

Expand All @@ -51,33 +49,75 @@ public Circuit init(String[] args) {
}

if (args.length>=2) {
if (args.length==2) {
try {
trigger = EdgeTriggering.valueOf(args[1]);
} catch (IllegalArgumentException ie) {
return error("Bad trigger argument: " + args[1]);
}
try {
trigger = EdgeTriggering.valueOf(args[1]);
} catch (IllegalArgumentException ie) {
return error("Bad trigger argument: " + args[1]);
}
}

if (args.length>=3) {
try {
repeatedTriggerMode = RepeatedTriggerMode.valueOf(args[2]);
} catch (IllegalArgumentException e) {
return error("Bad repeated trigger mode argument: " + args[2]);
}
}

if (repeatedTriggerMode==RepeatedTriggerMode.extend && inputlen!=outputlen) {
return error("Extend mode is incompatible with sequence mode");
}

if (interval!=0) {
intervalInTicks = Math.round(interval/50);
pulseOffIds = new Integer[outputlen];

pulseOffs = new PulseOff[outputlen];
for (int i=0; i < outputlen; i++) {
pulseOffs[i] = new PulseOff(i);
pulseOffs[i] = new PulseOff(i, pulseOffIds);
}
}

return this;
}


private void trigger(final int idx) {
int checkRepeatIdx = 0;

if (repeatedTriggerMode==RepeatedTriggerMode.legacy) {
pulse(idx);
}
else {
if (inputlen==outputlen) {
checkRepeatIdx = idx;
}
if (repeatedTriggerMode==RepeatedTriggerMode.ignore) {
if (pulseOffIds[checkRepeatIdx]==null) {
pulse(idx);
}
}
else if (repeatedTriggerMode==RepeatedTriggerMode.extend) {
if (pulseOffIds[checkRepeatIdx]!=null) {
rc.getServer().getScheduler().cancelTask(pulseOffIds[checkRepeatIdx]);
pulseOffIds[checkRepeatIdx] = null;
}
pulse(idx);
}
}
}

private void pulse(final int idx) {
if (inputlen==outputlen)
pulseSingle(idx);
else pulseSequence();
}

private void pulseSingle(final int idx) {
write(true, idx);
if (interval==0) {
write(false, idx);
} else {
rc.getServer().getScheduler().scheduleSyncDelayedTask(rc, pulseOffs[idx], intervalInTicks);
pulseOffIds[idx] = rc.getServer().getScheduler().scheduleSyncDelayedTask(rc, pulseOffs[idx], intervalInTicks);
}

}
Expand All @@ -90,18 +130,25 @@ private void pulseSequence() {
}
} else {
write(true, 0);
rc.getServer().getScheduler().scheduleSyncDelayedTask(rc, pulseOffs[0], intervalInTicks);
pulseOffIds[0] = rc.getServer().getScheduler().scheduleSyncDelayedTask(rc, pulseOffs[0], intervalInTicks);
}
}

class PulseOff implements Runnable {
int index;
Integer[] pulseOffIds;

public PulseOff(int index) { this.index = index; }
public PulseOff(int index, Integer[] pulseOffIds) {
this.index = index;
this.pulseOffIds = pulseOffIds;
}

@Override
public void run() {
write(false, index);
if (inputlen==outputlen || index==0) {
pulseOffIds[index] = null;
}
if (inputlen!=outputlen && pulseOffs.length>index+1) {
write(true, index+1);
rc.getServer().getScheduler().scheduleSyncDelayedTask(rc, pulseOffs[index+1], intervalInTicks);
Expand Down
18 changes: 14 additions & 4 deletions src/main/java/org/redstonechips/basiccircuits/sram.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
package org.redstonechips.basiccircuits;

import java.io.IOException;
import java.util.Arrays;
import java.util.logging.Level;
import org.redstonechips.paging.LineSource;
import org.redstonechips.parsing.Range;
Expand All @@ -16,6 +17,7 @@
import org.redstonechips.memory.RamListener;
import org.redstonechips.paging.Pager;
import org.redstonechips.util.BooleanArrays;
import org.redstonechips.util.Optional;

/**
*
Expand Down Expand Up @@ -155,7 +157,8 @@ public void save() {

private void readMemory() {
long address = getInputAddress();
boolean[] data = memory.read(address);
boolean[] data = memory.readDefaultZero(address, wordLength);

if (chip.hasListeners()) debug("Reading " + BooleanArrays.toPrettyString(data, wordLength) + " from address " + address);
writeBits(data, 0, wordLength);
}
Expand Down Expand Up @@ -301,9 +304,16 @@ public MemoryLineSource(int offset, int length) {
public String getLine(int idx) {
String value;
String address = zeroPad(idx+offset, (int)Math.pow(2, addressLength)-1);
boolean[] data = memory.read(idx+offset);
if (wordLength>32) value = Long.toHexString(BooleanArrays.toSignedInt(data, 0, wordLength));
else value = BooleanArrays.toPrettyString(data, wordLength);
Optional<boolean[]> dataOpt = memory.read(idx+offset);
boolean[] data = memory.readDefaultZero(idx+offset, wordLength);

if (wordLength > 32) {
value = Long.toHexString(BooleanArrays.toSignedInt(data, 0, wordLength));
}
else {
value = BooleanArrays.toPrettyString(data, wordLength);
}

return ChatColor.YELLOW.toString() + address + ": " + ChatColor.WHITE + value + "\n";
}

Expand Down