BrowserLogic/js/elements/FFElements.js

322 lines
11 KiB
JavaScript

class FlipFlopJK extends Element {
constructor(_Container, RestoreData = null, logicengine) {
super(_Container, RestoreData,logicengine,5);
this.Name = "JK-FF";
this.Outputs = new Array(2);
this.InputLabels = new Array("J","!CLK","K","!PRE", "!CLR");
this.OutputLabels = new Array("Q","~Q");
this.removeProperty("Inputs");
this.Height = 140;
this.Outputs[0] = true;
this.Outputs[1] = true;
if (RestoreData) {
this.Outputs = RestoreData.OutputStates;
}
}
toJSON(key) {
let $superjson = super.toJSON(key);
$superjson.OutputStates = this.Outputs;
return $superjson;
}
setInput(Input, Value) {
if (Input >= this.Inputs.length) return false;
Value = this._Container.isHigh(this,Input);
if (Value !== false) Value = true;
let oldOutput = this.Outputs[0];
let oldOutput2 = this.Outputs[1];
let oldInput2 = this.Inputs[1];
let oldInput3 = this.Inputs[3];
let oldInput4 = this.Inputs[4];
this.Inputs[Input] = Value;
if (!this.Inputs[1] && oldInput2) {
if (!this.Inputs[0] && this.Inputs[2]) {
// set Q low
this.Outputs[0] = false;
this.Outputs[1] = true;
} else if (this.Inputs[0] && !this.Inputs[2]) {
// set Q low
this.Outputs[0] = true;
this.Outputs[1] = false;
} else if (this.Inputs[0] && this.Inputs[2]) {
// set Q low
this.Outputs[0] = !this.Outputs[0];
this.Outputs[1] = !this.Outputs[0];
}
}
if (this.Inputs[4] && !oldInput4 && this.Outputs[0] && this.Outputs[1]) {
this.Outputs[1] = false;
}
if (this.Inputs[3] && !oldInput3 && this.Outputs[0] && this.Outputs[1]) {
this.Outputs[0] = false;
}
if (!this.Inputs[3] && oldInput3) {
this.Outputs[0] = true;
this.Outputs[1] = false;
}
if (!this.Inputs[4] && oldInput4) {
this.Outputs[0] = false;
this.Outputs[1] = true;
}
if (oldOutput != this.getOutput(0) || oldOutput2 != this.getOutput(1)) {
this.setConnections();
}
this.drawElement(0,0,this.StaticCtx);
}
getOutput(Output=0) {
if (super.getOutput() === 0) return false;
return this.Outputs[Output];
}
drawElement(x,y,ctx) {
if (this.LogicEngine.ActiveContainer !== this._Container) return; // No point if we aren't visible
this.StaticCanvas.width = this.Width;
this.StaticCanvas.height = this.Height;
let xOffset = 20;
this.drawBorderBox(ctx, x+20,y,this.Width-40,this.Height,1,"#000","#f7e979",this.LogicEngine.Settings.ShadowColor);
this.drawTextCentered(ctx,x,y+(this.Height-14),this.Width,14,this.Designator,"10px Console","#000");
this.drawInputs(ctx,x,y,undefined,undefined,undefined,undefined,true);
this.drawOutputs(ctx,x,y,undefined,undefined,undefined,undefined,true);
}
}
let ElementCatalog_JKFlipFlop = new ElementCatalog_Element("JK-FF","The JK Flip-Flop is a common type of flip-flop that allows for either setting in a specific state, or toggling state.","",FlipFlopJK,[]);
ElementReferenceTable.push(ElementCatalog_JKFlipFlop);
ElementCategory_FlipFlop.addElement(ElementCatalog_JKFlipFlop);
class FlipFlopSR extends Element {
constructor(_Container, RestoreData = null, logicengine) {
super(_Container, RestoreData,logicengine,5);
this.Name = "SR-FF";
this.Outputs = new Array(2);
this.InputLabels = new Array("S","CLK","R","!PRE", "!CLR");
this.OutputLabels = new Array("Q","~Q");
this.removeProperty("Inputs");
this.Height = 140;
if (RestoreData) {
this.Outputs = RestoreData.OutputStates;
}
}
toJSON(key) {
let $superjson = super.toJSON(key);
$superjson.OutputStates = this.Outputs;
return $superjson;
}
setInput(Input, Value) {
if (Input >= this.Inputs.length) return false;
Value = this._Container.isHigh(this,Input);
if (Value !== false) Value = true;
let oldOutput = this.Outputs[0];
let oldOutput2 = this.Outputs[1];
let oldInput1 = this.Inputs[1];
let oldInput3 = this.Inputs[3];
let oldInput4 = this.Inputs[4];
this.Inputs[Input] = Value;
this.redraw = true;
if (this.Inputs[1] && !oldInput1) {
if (!this.Inputs[0] && this.Inputs[2]) {
// set Q low
this.Outputs[0] = false;
this.Outputs[1] = true;
} else if (this.Inputs[0] && !this.Inputs[2]) {
// set Q high
this.Outputs[0] = true;
this.Outputs[1] = false;
}
}
if (this.Inputs[4] && !oldInput4 && !this.Inputs[3] && this.Outputs[1]) {
this.Outputs[1] = false;
}
if (this.Inputs[3] && !oldInput3 && !this.Inputs[4] && this.Outputs[0]) {
this.Outputs[0] = false;
}
if (!this.Inputs[3] && oldInput3) {
this.Outputs[0] = true;
this.Outputs[1] = false;
}
if (!this.Inputs[4] && oldInput4) {
this.Outputs[0] = false;
this.Outputs[1] = true;
}
if (oldOutput != this.getOutput(0) || oldOutput2 != this.getOutput(1)) {
this.setConnections();
}
this.drawElement(0,0,this.StaticCtx);
}
getOutput(Output=0) {
if (super.getOutput() === 0) return false;
return this.Outputs[Output];
}
drawElement(x,y,ctx) {
if (this.LogicEngine.ActiveContainer !== this._Container) return; // No point if we aren't visible
this.StaticCanvas.width = this.Width;
this.StaticCanvas.height = this.Height;
let xOffset = 20;
this.drawBorderBox(ctx, x+20,y,this.Width-40,this.Height,1,"#000","#f7e979",this.LogicEngine.Settings.ShadowColor);
this.drawTextCentered(ctx,x,y+(this.Height-14),this.Width,14,this.Designator,"10px Console","#000");
this.drawInputs(ctx,x,y,undefined,undefined,undefined,undefined,true);
this.drawOutputs(ctx,x,y,undefined,undefined,undefined,undefined,true);
}
}
let ElementCatalog_SRFlipFlop = new ElementCatalog_Element("SR-FF","The SR Flip-Flop is a common type of flip-flop that allows for either setting, or resetting the output state.","",FlipFlopSR,[]);
ElementReferenceTable.push(ElementCatalog_SRFlipFlop);
ElementCategory_FlipFlop.addElement(ElementCatalog_SRFlipFlop);
class FlipFlopT extends Element {
constructor(_Container, RestoreData = null, logicengine) {
super(_Container, RestoreData,logicengine,4);
this.Name = "T-FF";
this.Outputs = new Array(2);
this.InputLabels = new Array("T","CLK","!PRE","!CLR");
this.OutputLabels = new Array("Q","~Q");
this.removeProperty("Inputs");
this.Height = 120;
if (RestoreData) {
this.Outputs = RestoreData.OutputStates;
}
}
toJSON(key) {
let $superjson = super.toJSON(key);
$superjson.OutputStates = this.Outputs;
return $superjson;
}
setInput(Input, Value) {
if (Input >= this.Inputs.length) return false;
Value = this._Container.isHigh(this,Input);
if (Value !== false) Value = true;
let oldOutput = this.Outputs[0];
let oldOutput2 = this.Outputs[1];
let oldInput2 = this.Inputs[2];
let oldInput3 = this.Inputs[3];
this.Inputs[Input] = Value;
this.redraw = true;
if (this.Inputs[0] && this.Inputs[1]) {
this.Outputs[0] = !this.Outputs[0];
this.Outputs[1] = !this.Outputs[0];
}
if (!this.Inputs[2] && oldInput2) {
this.Outputs[0] = true;
this.Outputs[1] = false;
}
if (!this.Inputs[3] && oldInput3) {
this.Outputs[0] = false;
this.Outputs[1] = true;
}
if (oldOutput != this.getOutput(0) || oldOutput2 != this.getOutput(1)) {
this.setConnections();
}
this.drawElement(0,0,this.StaticCtx);
}
getOutput(Output=0) {
if (super.getOutput() === 0) return false;
return this.Outputs[Output];
}
drawElement(x,y,ctx) {
if (this.LogicEngine.ActiveContainer !== this._Container) return; // No point if we aren't visible
this.StaticCanvas.width = this.Width;
this.StaticCanvas.height = this.Height;
let xOffset = 20;
this.drawBorderBox(ctx, x+20,y,this.Width-40,this.Height,1,"#000","#f7e979",this.LogicEngine.Settings.ShadowColor);
this.drawTextCentered(ctx,x,y+(this.Height-14),this.Width,14,this.Designator,"10px Console","#000");
this.drawInputs(ctx,x,y,undefined,undefined,undefined,undefined,true);
this.drawOutputs(ctx,x,y,undefined,undefined,undefined,undefined,true);
}
}
let ElementCatalog_TFlipFlop = new ElementCatalog_Element("T-FF","The T Flip-Flop is a common type of flip-flop that toggles the output when T is high and CLK goes high.","",FlipFlopT,[]);
ElementReferenceTable.push(ElementCatalog_TFlipFlop);
ElementCategory_FlipFlop.addElement(ElementCatalog_TFlipFlop);
class FlipFlopD extends Element {
constructor(_Container, RestoreData = null, logicengine) {
super(_Container, RestoreData,logicengine,4);
this.Name = "D-FF";
this.Outputs = new Array(2);
this.InputLabels = new Array("D","CLK","!PRE","!CLR");
this.OutputLabels = new Array("Q","~Q");
this.removeProperty("Inputs");
this.Height = 120;
if (RestoreData) {
this.Outputs = RestoreData.OutputStates;
}
}
toJSON(key) {
let $superjson = super.toJSON(key);
$superjson.OutputStates = this.Outputs;
return $superjson;
}
setInput(Input, Value) {
if (Input >= this.Inputs.length) return false;
Value = this._Container.isHigh(this,Input);
if (Value !== false) Value = true;
let oldOutput = this.Outputs[0];
let oldOutput2 = this.Outputs[1];
let oldInput = this.Inputs[1];
let oldInput2 = this.Inputs[2];
let oldInput3 = this.Inputs[3];
this.Inputs[Input] = Value;
if (this.Inputs[1] && !oldInput) {
this.Outputs[0] = this.Inputs[0];
this.Outputs[1] = !this.Outputs[0];
}
if (!this.Inputs[2] && oldInput2) {
this.Outputs[0] = true;
this.Outputs[1] = false;
}
if (!this.Inputs[3] && oldInput3) {
this.Outputs[0] = false;
this.Outputs[1] = true;
}
if (oldOutput != this.getOutput(0) || oldOutput2 != this.getOutput(1)) {
this.setConnections();
}
this.drawElement(0,0,this.StaticCtx);
}
getOutput(Output=0) {
if (super.getOutput() === 0) return false;
return this.Outputs[Output];
}
drawElement(x,y,ctx) {
if (this.LogicEngine.ActiveContainer !== this._Container) return; // No point if we aren't visible
this.StaticCanvas.width = this.Width;
this.StaticCanvas.height = this.Height;
let xOffset = 20;
this.drawBorderBox(ctx, x+20,y,this.Width-40,this.Height,1,"#000","#f7e979",this.LogicEngine.Settings.ShadowColor);
this.drawTextCentered(ctx,x,y+(this.Height-14),this.Width,14,this.Designator,"10px Console","#000");
this.drawInputs(ctx,x,y,undefined,undefined,undefined,undefined,true);
this.drawOutputs(ctx,x,y,undefined,undefined,undefined,undefined,true);
}
}
let ElementCatalog_DFlipFlop = new ElementCatalog_Element("D-FF","The D Flip-Flop is a common type of flip-flop that sets the output to equal D if the clock goes high","",FlipFlopD,[]);
ElementReferenceTable.push(ElementCatalog_DFlipFlop);
ElementCategory_FlipFlop.addElement(ElementCatalog_DFlipFlop);