// Multiple register component for the LogicSimulator used by the 8-bit-computer // Copyright (C) 2022 Sascha Nitsch // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see . interface MultiRegisterParam extends BaseComponentParam { count?: number; } // eslint-disable-next-line @typescript-eslint/no-unused-vars function MultiRegisterInit() { class MultiRegister extends LogicBase { private regcount: number; private r: number[]; private oldCLK: boolean; private CLK: boolean; private RON: boolean; private WON: boolean; constructor(simulator: Simulator, id: string, param: MultiRegisterParam) { super(simulator, id, param); this.regcount = param.count || 1; this.r = []; for (let a = 0; a < 4; ++a) { this.pins.set('R' + (3 - a), new TriState(this, 40, a * 10 + 30)); this.pins.set('W' + (3 - a), new TriState(this, 40, a * 10 + 80)); this.pins.set('ALU_A' + (3 - a), new TriState(this, -40, a * 10 + 100)); this.pins.set('ALU_B' + (3 - a), new TriState(this, -40, a * 10 + 140)); } this.pins.set('RON', new TriState(this, 40, 70)); this.pins.set('WON', new TriState(this, 40, 120)); this.pins.set('CLK', new TriState(this, 40, 0, undefined, { id: 'CLK' })); this.pins.set('invCLK', new TriState(this, 40, 10)); for (let i = 0; i < 8; ++i) { this.pins.set('D' + (7 - i), new TriState(this, 40, i * 10 - 80)); this.pins.set('A' + (7 - i), new TriState(this, -40, i * 10 - 80)); this.pins.set('B' + (7 - i), new TriState(this, -40, i * 10 + 10)); } for (let b = 0; b < this.regcount; ++b) { this.r[b] = 0; } this.oldCLK = false; this.CLK = false; this.RON = false; this.WON = false; } setup(canvas: SVGElement) { super.doSetup('multiregister', canvas); } update(): boolean { let i; let r; let value; // is R_ON set ? then send out to databus if (this.RON) { // which register is selected via R3...R0 r = this.asint(this.getStateBool('R3'), 8) + this.asint(this.getStateBool('R2'), 4) + this.asint(this.getStateBool('R1'), 2) + this.asint(this.getStateBool('R0'), 1); value = this.r[r]; for (i = 0; i < 8; ++i) { this.getPin('D' + i).setBool((value & (1 << i)) > 0 ? true : false); } } const rising = this.CLK && this.oldCLK === false; this.oldCLK = this.CLK; // is W_ON set ? read from bus on raising clock edge if (this.WON && rising) { r = this.asint(this.getStateBool('W3'), 8) + this.asint(this.getStateBool('W2'), 4) + this.asint(this.getStateBool('W1'), 2) + this.asint(this.getStateBool('W0'), 1); value = this.asint(this.getStateBool('D7'), 128) + this.asint(this.getStateBool('D6'), 64) + this.asint(this.getStateBool('D5'), 32) + this.asint(this.getStateBool('D4'), 16) + this.asint(this.getStateBool('D3'), 8) + this.asint(this.getStateBool('D2'), 4) + this.asint(this.getStateBool('D1'), 2) + this.asint(this.getStateBool('D0'), 1); this.r[r] = value; } // output to alu A const alu_a = this.asint(this.getStateBool('ALU_A3'), 8) + this.asint(this.getStateBool('ALU_A2'), 4) + this.asint(this.getStateBool('ALU_A1'), 2) + this.asint(this.getStateBool('ALU_A0'), 1); //console.log("Alu A set to", alu_a); value = this.r[alu_a]; for (i = 0; i < 8; ++i) { this.getPin('A' + i).setBool((value & (1 << i)) > 0 ? true : false); } // output to alu B const alu_b = this.asint(this.getStateBool('ALU_B3'), 8) + this.asint(this.getStateBool('ALU_B2'), 4) + this.asint(this.getStateBool('ALU_B1'), 2) + this.asint(this.getStateBool('ALU_B0'), 1); value = this.r[alu_b]; for (i = 0; i < 8; ++i) { this.getPin('B' + i).setBool((value & (1 << i)) > 0 ? true : false); } return false; } io() { this.CLK = this.binary(this.getPin('CLK').getAndReset(), false); this.getPin('invCLK').getAndReset(); this.RON = this.binary(this.getPin('RON').getAndReset(), false); this.WON = this.binary(this.getPin('WON').getAndReset(), false); for (let i = 0; i < 8; ++i) { this.stateMapBool.set('D' + i, this.binary(this.getPin('D' + i).getAndReset(), true)); this.stateMapBool.set('A' + i, this.binary(this.getPin('A' + i).getAndReset(), true)); this.stateMapBool.set('B' + i, this.binary(this.getPin('B' + i).getAndReset(), true)); } for (let a = 0; a < 4; ++a) { this.stateMapBool.set('R' + a, this.binary(this.getPin('R' + a).getAndReset(), true)); this.stateMapBool.set('W' + a, this.binary(this.getPin('W' + a).getAndReset(), true)); this.stateMapBool.set('ALU_A' + a, this.binary(this.getPin('ALU_A' + a).getAndReset(), true)); this.stateMapBool.set('ALU_B' + a, this.binary(this.getPin('ALU_B' + a).getAndReset(), true)); } } } window.MultiRegister = MultiRegister; } // eslint-disable-next-line @typescript-eslint/no-unused-vars function MultiRegisterDepends() { return 'LogicBase'; }