322 lines
11 KiB
JavaScript
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);
|