From a3cb688be29ca9d5be4a4cd2959c41d69077c8ad Mon Sep 17 00:00:00 2001 From: David Timber Date: Wed, 2 Apr 2025 23:58:14 +0200 Subject: Move some files ... - Moved the ripple carry adder animations impl to subdir --- linux-casual/mp-int/anim.css | 5 - linux-casual/mp-int/animation-skel.svg | 1775 -------------------- linux-casual/mp-int/index.css | 16 - linux-casual/mp-int/index.html | 65 - linux-casual/mp-int/index.js | 483 ------ linux-casual/mp-int/ripple-carry-adder/anim.css | 5 + .../mp-int/ripple-carry-adder/animation-skel.svg | 1775 ++++++++++++++++++++ linux-casual/mp-int/ripple-carry-adder/index.css | 16 + linux-casual/mp-int/ripple-carry-adder/index.html | 65 + linux-casual/mp-int/ripple-carry-adder/index.js | 483 ++++++ .../mp-int/ripple-carry-adder/the-math.svg | 556 ++++++ linux-casual/mp-int/the-math.svg | 556 ------ 12 files changed, 2900 insertions(+), 2900 deletions(-) delete mode 100644 linux-casual/mp-int/anim.css delete mode 100755 linux-casual/mp-int/animation-skel.svg delete mode 100644 linux-casual/mp-int/index.css delete mode 100644 linux-casual/mp-int/index.html delete mode 100644 linux-casual/mp-int/index.js create mode 100644 linux-casual/mp-int/ripple-carry-adder/anim.css create mode 100755 linux-casual/mp-int/ripple-carry-adder/animation-skel.svg create mode 100644 linux-casual/mp-int/ripple-carry-adder/index.css create mode 100644 linux-casual/mp-int/ripple-carry-adder/index.html create mode 100644 linux-casual/mp-int/ripple-carry-adder/index.js create mode 100755 linux-casual/mp-int/ripple-carry-adder/the-math.svg delete mode 100755 linux-casual/mp-int/the-math.svg diff --git a/linux-casual/mp-int/anim.css b/linux-casual/mp-int/anim.css deleted file mode 100644 index 0f6c53b..0000000 --- a/linux-casual/mp-int/anim.css +++ /dev/null @@ -1,5 +0,0 @@ -@keyframes state-change { - from { - fill: orange; - } -} diff --git a/linux-casual/mp-int/animation-skel.svg b/linux-casual/mp-int/animation-skel.svg deleted file mode 100755 index 7cccd50..0000000 --- a/linux-casual/mp-int/animation-skel.svg +++ /dev/null @@ -1,1775 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - (flick me) - - - 0 - - - - - 0 - 0 - 0 - 0 - 0 - 0 - 0 - - - - - 0 - - - - 0 - - - - 0 - - - - 0 - - - - 0 - - - - 0 - - - - 0 - - - - 0 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - A - B - Co - Ci - S - - - - A - B - Co - Ci - S - - - - A - B - Co - Ci - S - - - - A - B - Co - Ci - S - - - - A - B - Co - Ci - S - - - - A - B - Co - Ci - S - - - - A - B - Co - Ci - S - - - - A - B - Co - Ci - S - - - - - - 0 - - - - 0 - - - - 0 - - - - 0 - - - - 0 - - - - 0 - - - - 0 - - - - 0 - - - - - - 0 - - - - 0 - - - - 0 - - - - 0 - - - - 0 - - - - 0 - - - - 0 - - - - 0 - - - diff --git a/linux-casual/mp-int/index.css b/linux-casual/mp-int/index.css deleted file mode 100644 index b1bf0f0..0000000 --- a/linux-casual/mp-int/index.css +++ /dev/null @@ -1,16 +0,0 @@ -fieldset { - display: inline-block; -} - -.svg-container { - text-align: center; -} - -fieldset { - font-family: monospace; -} - -.ovf { - color: red; - opacity: 0; -} diff --git a/linux-casual/mp-int/index.html b/linux-casual/mp-int/index.html deleted file mode 100644 index 6c6311a..0000000 --- a/linux-casual/mp-int/index.html +++ /dev/null @@ -1,65 +0,0 @@ - - - - Multiprecision integer arithmetics, animated - - - - - -

- -

-

- -

- -
-

Programmer

- -
-
- OP -
- - -
-
- - -
-
- -
- Operand -
- - - 🛑 error -
-
- - - 🛑 error -
-
- -
- ACT -
- -
- -

-

- Animations - -
- -
- -
-
- - - diff --git a/linux-casual/mp-int/index.js b/linux-casual/mp-int/index.js deleted file mode 100644 index 5d25e8e..0000000 --- a/linux-casual/mp-int/index.js +++ /dev/null @@ -1,483 +0,0 @@ -const BITS = 8; -const INTMAX = (() => { - let ret = 0; - - for (let i = 0; i < BITS; i += 1) { - ret = (ret << 1) | 1 - } - - return ret; -})(); -const STATE_DELAY_DEFAULT = 250; -const ANIMATIONS_DEFAULT = 'state-change 0.5s ease-in 0s 1'; -let state_delay, animations; - -function myParseInt (str) { - let v, radix; - - if (str.startsWith("0b")) { - v = str.substring(2); - radix = 2; - } - else if (str.startsWith("0x")) { - v = str.substring(2); - radix = 16; - } - else if (str.startsWith("0")) { - v = str.substring(1); - radix = 1; - } - else { - v = str; - radix = 10; - } - - if (v === '') { - return 0; - } - - return parseInt(v, radix); -} - -function onOperandChange (val, span) { - if (val.trim() === '') { - span.style.opacity = 0; - } - else { - const n = myParseInt(val); - - if (!(n <= INTMAX)) { // NaN is also handled with this single conditional - span.style.opacity = 1; - } - else { - span.style.opacity = 0; - } - } -} - -function restartClassAnimation (element) { - const evtOpts = { "once": true }; - - // I fucking hate modern web development - - element.querySelectorAll('.state').forEach((element) => { - element.style.animation = ''; - }); - element.querySelectorAll('.state-op tspan').forEach((element) => { - element.style.animation = ''; - }); - element.querySelectorAll('.state').forEach((element) => { - element.style.animation = animations; - element.addEventListener('animationend', () => { - element.style.animation = ''; - }, evtOpts); - element.addEventListener('animationcancel', () => { - element.style.animation = ''; - }, evtOpts); - }); - element.querySelectorAll('.state-op tspan').forEach((element) => { - element.style.animation = animations; - element.addEventListener('animationend', () => { - element.style.animation = ''; - }, evtOpts); - element.addEventListener('animationcancel', () => { - element.style.animation = ''; - }, evtOpts); - }); -} - -class Renderer { - reset () {} - start (opr_a, opr_b, carry) {} -} -class MathRenderer extends Renderer {} -class AdderRenderer extends Renderer {} - -class State { - timer; - outputList = []; - - addOutput (output_f) { - this.outputList.push(output_f); - } - - clearTimer () { - if (this.timer) { - clearTimeout(this.timer); - } - } - - startTimer (v, ms) { - this.clearTimer(); - this.timer = setTimeout(() => { - this.outputList.forEach((output_f) => { - output_f(v) - }); - }, ms); - } - - detach () { - this.clearTimer(); - this.outputList = null; - } -} - -class Register extends State { - #elements; - #txts = []; - #bit = false; - #onclick = null; - - constructor (elements, clickable = true) { - super(); - const self = this; - - this.#elements = elements; - - this.#elements.forEach((e) => { - const t = e.querySelector('text tspan'); - - this.#txts.push(t); - t.innerHTML = '0'; - }); - - - if (clickable) { - this.#onclick = () => { - self.value = !self.value; - }; - - this.#elements.forEach((e) => { - e.style.cursor = 'pointer'; - e.addEventListener('click', this.#onclick); - }); - } - } - - get value () { - return this.#bit; - } - - set value (v_in) { - const v = !!v_in; - - if (this.#bit == v) { - return; - } - this.#bit = v; - - this.#elements.forEach((e) => { - restartClassAnimation(e); - }); - this.#txts.forEach((e) => { - if (v) { - e.innerHTML = '1'; - } - else { - e.innerHTML = '0'; - } - }); - - this.startTimer(v, state_delay); - } - - detach () { - super.detach(); - - if (this.#onclick) { - this.#elements.forEach((e) => { - e.removeEventListener('click', this.#onclick); - }); - - this.#onclick = null; - } - - this.#elements = null; - this.#txts = null; - } -} - -class Adder extends State { - #a = false; - #b = false; - #c = false; - - #update () { - this.startTimer(this.value, state_delay); - } - - set a (v_in) { - this.#a = !!v_in; - this.#update(); - } - - set b (v_in) { - this.#b = !!v_in; - this.#update(); - } - - set c (v_in) { - this.#c = !!v_in; - this.#update(); - } - - get value () { - let sum = 0; - - if (this.#a) { - sum += 1; - } - if (this.#b) { - sum += 1; - } - if (this.#c) { - sum += 1; - } - - return { - "a": this.#a, - "b": this.#b, - "ci": this.#c, - "co": (sum & 2) > 0, - "s": (sum & 1) > 0 - }; - } -} - -function forEachBit (n, nb_bits, f) { - let bit; - - for (let i = 0; i < nb_bits; i += 1) { - bit = n & 1; - f(bit > 0); - - n = n >> 1; - } -} - -function getLocalstorageData () { - const item = localStorage.getItem('animations'); - - if (item) { - return JSON.parse(item); - } - else { - return { - "state-delay": STATE_DELAY_DEFAULT, - "animations": ANIMATIONS_DEFAULT - }; - } -} - -function setLocalstorageData (obj) { - localStorage.setItem('animations', JSON.stringify(obj)); -} - -function clearLocalstorageData () { - localStorage.removeItem('animations'); -} - -function uploadLocalstorageData (elements) { - state_delay = elements["state-delay"].value; - animations = elements["animations"].value; - setLocalstorageData({ - "state-delay": elements["state-delay"].value, - "animations": elements["animations"].value - }); -} - -function downloadLocalstorageData (elements) { - const obj = getLocalstorageData(); - - state_delay = elements["state-delay"].value = obj["state-delay"]; - animations = elements["animations"].value = obj["animations"]; -} - -window.addEventListener('load', async () => { - const svg_math = document.getElementById("svg_the-math"); - const svg_adder = document.getElementById("svg_adder"); - const span_operand_a = document.getElementById("span_operand-a"); - const span_operand_b = document.getElementById("span_operand-b"); - const css_anim = await (await fetch('./anim.css')).text(); - - // inject animation - svg_math.contentDocument.getElementById('style1').innerHTML = css_anim; - svg_adder.contentDocument.getElementById('style1').innerHTML = css_anim; - - let stateList = []; - let adders; - let registerCarry; - let registerA; - let registerB; - let registerS; - let carryState; - - function doReset () { - stateList.forEach((s) => { - s.detach(); - }); - stateList = []; - adders = []; - registerCarry = []; - registerA = []; - registerB = []; - registerS = []; - carryState = null; - carry0 = null; - - // carryState - (() => { - const eMath = svg_math.contentDocument.getElementById('carry-ovf'); - const eAdder = svg_adder.contentDocument.getElementById('ovf'); - - carryState = new Register([ eMath, eAdder ]); - stateList.push(carryState); - })(); - - // registerS - for (let i = 0; i < BITS; i += 1) { - const eMath = svg_math.contentDocument.getElementById('result-' + i); - const eAdder = svg_adder.contentDocument.getElementById('8-bit-register-c-' + i); - const r = new Register([ eMath, eAdder ], false); - - stateList.push(r); - registerS.push(r); - } - - // registerCarry - for (let i = 1; i <= BITS - 1; i += 1) { - const eMath = svg_math.contentDocument.getElementById('carry-' + i); - const eAdder = svg_adder.contentDocument.getElementById('carry-' + (i - 1)); - const r = new Register([ eMath, eAdder ], false); - - stateList.push(r); - registerCarry.push(r); - } - registerCarry.push(carryState); - - // carry0 - const carry0element = svg_math.contentDocument.getElementById('carry-0'); - carry0 = new Register([ carry0element ]); - carry0.addOutput((v) => { - adders[0].c = v; - }); - stateList.push(carry0); - - // adders - for (let i = 0; i < BITS; i += 1) { - const a = new Adder(); - - a.addOutput((v) => { - registerS[i].value = v['s']; - registerCarry[i].value = v['co']; - }); - adders.push(a); - stateList.push(a); - } - for (let i = 1; i < BITS; i += 1) { - adders[i - 1].addOutput((v) => { - adders[i].c = v['co']; - }); - } - - // registerA - for (let i = 0; i < BITS; i += 1) { - const eMath = svg_math.contentDocument.getElementById('operand-a-' + i); - const eAdder = svg_adder.contentDocument.getElementById('8-bit-register-a-' + i); - const r = new Register([ eMath, eAdder ]); - - r.addOutput((v) => { - adders[i].a = v; - }); - stateList.push(r); - registerA.push(r); - } - - // registerB - for (let i = 0; i < BITS; i += 1) { - const eMath = svg_math.contentDocument.getElementById('operand-b-' + i); - const eAdder = svg_adder.contentDocument.getElementById('8-bit-register-b-' + i); - const r = new Register([ eMath, eAdder ]); - - r.addOutput((v) => { - adders[i].b = v; - }); - stateList.push(r); - registerB.push(r); - } - } - - doReset(); - - const txt_operand_a = document.getElementById("txt_operand-a"); - const txt_operand_b = document.getElementById("txt_operand-b"); - const radio_op_add = document.getElementById("radio_op-add"); - const radio_op_adc = document.getElementById("radio_op-adc"); - const txt_state_animations = document.getElementById("txt_state-animations"); - const txt_state_change_delay = document.getElementById("txt_state-change-delay"); - const btn_animation_defaults = document.getElementById("btn_animation-defaults"); - - document.getElementById("btn_exec").addEventListener('click', () => { - const a = myParseInt(txt_operand_a.value); - const b = myParseInt(txt_operand_b.value); - let c; - - if (isNaN(a) || isNaN(b)) { - return; - } - let i; - - function setRegisters () { - i = 0; - forEachBit(a, BITS, (v) => { - registerA[i].value = v; - i += 1; - }); - i = 0; - forEachBit(b, BITS, (v) => { - registerB[i].value = v; - i += 1; - }); - } - - if (radio_op_add.checked) { - setRegisters(); - c = (a + b) & INTMAX; - } - else if (radio_op_adc.checked) { - carry0.value = carryState.value; - setRegisters(); - c = (a + b + (carryState.value ? 1 : 0)) & INTMAX; - } - - txt_operand_a.value = c; - }); - - document.getElementById("btn_reset").addEventListener('click', () => { - doReset(); - }); - - txt_operand_a.addEventListener('change', (evt) => { - onOperandChange(evt.target.value, span_operand_a); - }); - txt_operand_b.addEventListener('change', (evt) => { - onOperandChange(evt.target.value, span_operand_b); - }); - - const animations_conf_elements = { - "animations": txt_state_animations, - "state-delay": txt_state_change_delay - }; - downloadLocalstorageData(animations_conf_elements); - - txt_state_animations.addEventListener('change', () => { - uploadLocalstorageData(animations_conf_elements); - }); - txt_state_change_delay.addEventListener('change', () => { - uploadLocalstorageData(animations_conf_elements); - }); - btn_animation_defaults.addEventListener('click', () => { - clearLocalstorageData(); - downloadLocalstorageData(animations_conf_elements); - }); -}); diff --git a/linux-casual/mp-int/ripple-carry-adder/anim.css b/linux-casual/mp-int/ripple-carry-adder/anim.css new file mode 100644 index 0000000..0f6c53b --- /dev/null +++ b/linux-casual/mp-int/ripple-carry-adder/anim.css @@ -0,0 +1,5 @@ +@keyframes state-change { + from { + fill: orange; + } +} diff --git a/linux-casual/mp-int/ripple-carry-adder/animation-skel.svg b/linux-casual/mp-int/ripple-carry-adder/animation-skel.svg new file mode 100755 index 0000000..7cccd50 --- /dev/null +++ b/linux-casual/mp-int/ripple-carry-adder/animation-skel.svg @@ -0,0 +1,1775 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + (flick me) + + + 0 + + + + + 0 + 0 + 0 + 0 + 0 + 0 + 0 + + + + + 0 + + + + 0 + + + + 0 + + + + 0 + + + + 0 + + + + 0 + + + + 0 + + + + 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + A + B + Co + Ci + S + + + + A + B + Co + Ci + S + + + + A + B + Co + Ci + S + + + + A + B + Co + Ci + S + + + + A + B + Co + Ci + S + + + + A + B + Co + Ci + S + + + + A + B + Co + Ci + S + + + + A + B + Co + Ci + S + + + + + + 0 + + + + 0 + + + + 0 + + + + 0 + + + + 0 + + + + 0 + + + + 0 + + + + 0 + + + + + + 0 + + + + 0 + + + + 0 + + + + 0 + + + + 0 + + + + 0 + + + + 0 + + + + 0 + + + diff --git a/linux-casual/mp-int/ripple-carry-adder/index.css b/linux-casual/mp-int/ripple-carry-adder/index.css new file mode 100644 index 0000000..b1bf0f0 --- /dev/null +++ b/linux-casual/mp-int/ripple-carry-adder/index.css @@ -0,0 +1,16 @@ +fieldset { + display: inline-block; +} + +.svg-container { + text-align: center; +} + +fieldset { + font-family: monospace; +} + +.ovf { + color: red; + opacity: 0; +} diff --git a/linux-casual/mp-int/ripple-carry-adder/index.html b/linux-casual/mp-int/ripple-carry-adder/index.html new file mode 100644 index 0000000..6c6311a --- /dev/null +++ b/linux-casual/mp-int/ripple-carry-adder/index.html @@ -0,0 +1,65 @@ + + + + Multiprecision integer arithmetics, animated + + + + + +

+ +

+

+ +

+ +
+

Programmer

+ +
+
+ OP +
+ + +
+
+ + +
+
+ +
+ Operand +
+ + + 🛑 error +
+
+ + + 🛑 error +
+
+ +
+ ACT +
+ +
+ +

+

+ Animations + +
+ +
+ +
+
+ + + diff --git a/linux-casual/mp-int/ripple-carry-adder/index.js b/linux-casual/mp-int/ripple-carry-adder/index.js new file mode 100644 index 0000000..5d25e8e --- /dev/null +++ b/linux-casual/mp-int/ripple-carry-adder/index.js @@ -0,0 +1,483 @@ +const BITS = 8; +const INTMAX = (() => { + let ret = 0; + + for (let i = 0; i < BITS; i += 1) { + ret = (ret << 1) | 1 + } + + return ret; +})(); +const STATE_DELAY_DEFAULT = 250; +const ANIMATIONS_DEFAULT = 'state-change 0.5s ease-in 0s 1'; +let state_delay, animations; + +function myParseInt (str) { + let v, radix; + + if (str.startsWith("0b")) { + v = str.substring(2); + radix = 2; + } + else if (str.startsWith("0x")) { + v = str.substring(2); + radix = 16; + } + else if (str.startsWith("0")) { + v = str.substring(1); + radix = 1; + } + else { + v = str; + radix = 10; + } + + if (v === '') { + return 0; + } + + return parseInt(v, radix); +} + +function onOperandChange (val, span) { + if (val.trim() === '') { + span.style.opacity = 0; + } + else { + const n = myParseInt(val); + + if (!(n <= INTMAX)) { // NaN is also handled with this single conditional + span.style.opacity = 1; + } + else { + span.style.opacity = 0; + } + } +} + +function restartClassAnimation (element) { + const evtOpts = { "once": true }; + + // I fucking hate modern web development + + element.querySelectorAll('.state').forEach((element) => { + element.style.animation = ''; + }); + element.querySelectorAll('.state-op tspan').forEach((element) => { + element.style.animation = ''; + }); + element.querySelectorAll('.state').forEach((element) => { + element.style.animation = animations; + element.addEventListener('animationend', () => { + element.style.animation = ''; + }, evtOpts); + element.addEventListener('animationcancel', () => { + element.style.animation = ''; + }, evtOpts); + }); + element.querySelectorAll('.state-op tspan').forEach((element) => { + element.style.animation = animations; + element.addEventListener('animationend', () => { + element.style.animation = ''; + }, evtOpts); + element.addEventListener('animationcancel', () => { + element.style.animation = ''; + }, evtOpts); + }); +} + +class Renderer { + reset () {} + start (opr_a, opr_b, carry) {} +} +class MathRenderer extends Renderer {} +class AdderRenderer extends Renderer {} + +class State { + timer; + outputList = []; + + addOutput (output_f) { + this.outputList.push(output_f); + } + + clearTimer () { + if (this.timer) { + clearTimeout(this.timer); + } + } + + startTimer (v, ms) { + this.clearTimer(); + this.timer = setTimeout(() => { + this.outputList.forEach((output_f) => { + output_f(v) + }); + }, ms); + } + + detach () { + this.clearTimer(); + this.outputList = null; + } +} + +class Register extends State { + #elements; + #txts = []; + #bit = false; + #onclick = null; + + constructor (elements, clickable = true) { + super(); + const self = this; + + this.#elements = elements; + + this.#elements.forEach((e) => { + const t = e.querySelector('text tspan'); + + this.#txts.push(t); + t.innerHTML = '0'; + }); + + + if (clickable) { + this.#onclick = () => { + self.value = !self.value; + }; + + this.#elements.forEach((e) => { + e.style.cursor = 'pointer'; + e.addEventListener('click', this.#onclick); + }); + } + } + + get value () { + return this.#bit; + } + + set value (v_in) { + const v = !!v_in; + + if (this.#bit == v) { + return; + } + this.#bit = v; + + this.#elements.forEach((e) => { + restartClassAnimation(e); + }); + this.#txts.forEach((e) => { + if (v) { + e.innerHTML = '1'; + } + else { + e.innerHTML = '0'; + } + }); + + this.startTimer(v, state_delay); + } + + detach () { + super.detach(); + + if (this.#onclick) { + this.#elements.forEach((e) => { + e.removeEventListener('click', this.#onclick); + }); + + this.#onclick = null; + } + + this.#elements = null; + this.#txts = null; + } +} + +class Adder extends State { + #a = false; + #b = false; + #c = false; + + #update () { + this.startTimer(this.value, state_delay); + } + + set a (v_in) { + this.#a = !!v_in; + this.#update(); + } + + set b (v_in) { + this.#b = !!v_in; + this.#update(); + } + + set c (v_in) { + this.#c = !!v_in; + this.#update(); + } + + get value () { + let sum = 0; + + if (this.#a) { + sum += 1; + } + if (this.#b) { + sum += 1; + } + if (this.#c) { + sum += 1; + } + + return { + "a": this.#a, + "b": this.#b, + "ci": this.#c, + "co": (sum & 2) > 0, + "s": (sum & 1) > 0 + }; + } +} + +function forEachBit (n, nb_bits, f) { + let bit; + + for (let i = 0; i < nb_bits; i += 1) { + bit = n & 1; + f(bit > 0); + + n = n >> 1; + } +} + +function getLocalstorageData () { + const item = localStorage.getItem('animations'); + + if (item) { + return JSON.parse(item); + } + else { + return { + "state-delay": STATE_DELAY_DEFAULT, + "animations": ANIMATIONS_DEFAULT + }; + } +} + +function setLocalstorageData (obj) { + localStorage.setItem('animations', JSON.stringify(obj)); +} + +function clearLocalstorageData () { + localStorage.removeItem('animations'); +} + +function uploadLocalstorageData (elements) { + state_delay = elements["state-delay"].value; + animations = elements["animations"].value; + setLocalstorageData({ + "state-delay": elements["state-delay"].value, + "animations": elements["animations"].value + }); +} + +function downloadLocalstorageData (elements) { + const obj = getLocalstorageData(); + + state_delay = elements["state-delay"].value = obj["state-delay"]; + animations = elements["animations"].value = obj["animations"]; +} + +window.addEventListener('load', async () => { + const svg_math = document.getElementById("svg_the-math"); + const svg_adder = document.getElementById("svg_adder"); + const span_operand_a = document.getElementById("span_operand-a"); + const span_operand_b = document.getElementById("span_operand-b"); + const css_anim = await (await fetch('./anim.css')).text(); + + // inject animation + svg_math.contentDocument.getElementById('style1').innerHTML = css_anim; + svg_adder.contentDocument.getElementById('style1').innerHTML = css_anim; + + let stateList = []; + let adders; + let registerCarry; + let registerA; + let registerB; + let registerS; + let carryState; + + function doReset () { + stateList.forEach((s) => { + s.detach(); + }); + stateList = []; + adders = []; + registerCarry = []; + registerA = []; + registerB = []; + registerS = []; + carryState = null; + carry0 = null; + + // carryState + (() => { + const eMath = svg_math.contentDocument.getElementById('carry-ovf'); + const eAdder = svg_adder.contentDocument.getElementById('ovf'); + + carryState = new Register([ eMath, eAdder ]); + stateList.push(carryState); + })(); + + // registerS + for (let i = 0; i < BITS; i += 1) { + const eMath = svg_math.contentDocument.getElementById('result-' + i); + const eAdder = svg_adder.contentDocument.getElementById('8-bit-register-c-' + i); + const r = new Register([ eMath, eAdder ], false); + + stateList.push(r); + registerS.push(r); + } + + // registerCarry + for (let i = 1; i <= BITS - 1; i += 1) { + const eMath = svg_math.contentDocument.getElementById('carry-' + i); + const eAdder = svg_adder.contentDocument.getElementById('carry-' + (i - 1)); + const r = new Register([ eMath, eAdder ], false); + + stateList.push(r); + registerCarry.push(r); + } + registerCarry.push(carryState); + + // carry0 + const carry0element = svg_math.contentDocument.getElementById('carry-0'); + carry0 = new Register([ carry0element ]); + carry0.addOutput((v) => { + adders[0].c = v; + }); + stateList.push(carry0); + + // adders + for (let i = 0; i < BITS; i += 1) { + const a = new Adder(); + + a.addOutput((v) => { + registerS[i].value = v['s']; + registerCarry[i].value = v['co']; + }); + adders.push(a); + stateList.push(a); + } + for (let i = 1; i < BITS; i += 1) { + adders[i - 1].addOutput((v) => { + adders[i].c = v['co']; + }); + } + + // registerA + for (let i = 0; i < BITS; i += 1) { + const eMath = svg_math.contentDocument.getElementById('operand-a-' + i); + const eAdder = svg_adder.contentDocument.getElementById('8-bit-register-a-' + i); + const r = new Register([ eMath, eAdder ]); + + r.addOutput((v) => { + adders[i].a = v; + }); + stateList.push(r); + registerA.push(r); + } + + // registerB + for (let i = 0; i < BITS; i += 1) { + const eMath = svg_math.contentDocument.getElementById('operand-b-' + i); + const eAdder = svg_adder.contentDocument.getElementById('8-bit-register-b-' + i); + const r = new Register([ eMath, eAdder ]); + + r.addOutput((v) => { + adders[i].b = v; + }); + stateList.push(r); + registerB.push(r); + } + } + + doReset(); + + const txt_operand_a = document.getElementById("txt_operand-a"); + const txt_operand_b = document.getElementById("txt_operand-b"); + const radio_op_add = document.getElementById("radio_op-add"); + const radio_op_adc = document.getElementById("radio_op-adc"); + const txt_state_animations = document.getElementById("txt_state-animations"); + const txt_state_change_delay = document.getElementById("txt_state-change-delay"); + const btn_animation_defaults = document.getElementById("btn_animation-defaults"); + + document.getElementById("btn_exec").addEventListener('click', () => { + const a = myParseInt(txt_operand_a.value); + const b = myParseInt(txt_operand_b.value); + let c; + + if (isNaN(a) || isNaN(b)) { + return; + } + let i; + + function setRegisters () { + i = 0; + forEachBit(a, BITS, (v) => { + registerA[i].value = v; + i += 1; + }); + i = 0; + forEachBit(b, BITS, (v) => { + registerB[i].value = v; + i += 1; + }); + } + + if (radio_op_add.checked) { + setRegisters(); + c = (a + b) & INTMAX; + } + else if (radio_op_adc.checked) { + carry0.value = carryState.value; + setRegisters(); + c = (a + b + (carryState.value ? 1 : 0)) & INTMAX; + } + + txt_operand_a.value = c; + }); + + document.getElementById("btn_reset").addEventListener('click', () => { + doReset(); + }); + + txt_operand_a.addEventListener('change', (evt) => { + onOperandChange(evt.target.value, span_operand_a); + }); + txt_operand_b.addEventListener('change', (evt) => { + onOperandChange(evt.target.value, span_operand_b); + }); + + const animations_conf_elements = { + "animations": txt_state_animations, + "state-delay": txt_state_change_delay + }; + downloadLocalstorageData(animations_conf_elements); + + txt_state_animations.addEventListener('change', () => { + uploadLocalstorageData(animations_conf_elements); + }); + txt_state_change_delay.addEventListener('change', () => { + uploadLocalstorageData(animations_conf_elements); + }); + btn_animation_defaults.addEventListener('click', () => { + clearLocalstorageData(); + downloadLocalstorageData(animations_conf_elements); + }); +}); diff --git a/linux-casual/mp-int/ripple-carry-adder/the-math.svg b/linux-casual/mp-int/ripple-carry-adder/the-math.svg new file mode 100755 index 0000000..867adc4 --- /dev/null +++ b/linux-casual/mp-int/ripple-carry-adder/the-math.svg @@ -0,0 +1,556 @@ + + + + + + + + + + + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + + + + + + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + + + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + + + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + + diff --git a/linux-casual/mp-int/the-math.svg b/linux-casual/mp-int/the-math.svg deleted file mode 100755 index 867adc4..0000000 --- a/linux-casual/mp-int/the-math.svg +++ /dev/null @@ -1,556 +0,0 @@ - - - - - - - - - - - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - - + - - - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - - - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - - - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - - -- cgit