/* const CONTROL_PCC = 0b00000000000000000000000000000001; // PC CLK UP const CONTROL_PCI = 0b00000000000000000000000000000010; // PC Input Enable const CONTROL_SPD = 0b00000000000000000000000000000100; // SP Count Down const CONTROL_SPC = 0b00000000000000000000000000001000; // SP CLK (UP / DOWN) const CONTROL_SPI = 0b00000000000000000000000000010000; // SP Input Enable const CONTROL_RAIL = 0b00000000000000000000000000100000; // GPA LOW Input Enable const CONTROL_RAIH = 0b00000000000000000000000001000000; // GPA HIGH Input Enable const CONTROL_RBIL = 0b00000000000000000000000010000000; // GPB LOW Input Enable const CONTROL_RBIH = 0b00000000000000000000000100000000; // GPB HIGH Input Enable const CONTROL_RCIL = 0b00000000000000000000001000000000; // GPC LOW Input Enable const CONTROL_RCIH = 0b00000000000000000000010000000000; // GPC HIGH Input Enable const CONTROL_RDIL = 0b00000000000000000000100000000000; // GPD LOW Input Enable const CONTROL_RDIH = 0b00000000000000000001000000000000; // GPD HIGH Input Enable const CONTROL_RRI = 0b00000000000000000010000000000000; // LOW Ram Register Input Enable const CONTROL_RHI = 0b00000000000000000100000000000000; // HIGH Ram Register Input Enable const CONTROL_ALUM0 = 0b00000000000000001000000000000000; // ALU MUX 0 const CONTROL_ALUM1 = 0b00000000000000010000000000000000; // ALU MUX 1 const CONTROL_ALUI = 0b00000000000000100000000000000000; // ALU Invert (high side) const CONTROL_ALUC = 0b00000000000001000000000000000000; // ALU Carry Input const CONTROL_ALUSL = 0b00000000000010000000000000000000; // ALU Shift Left const CONTROL_ALUSR = 0b00000000000100000000000000000000; // ALU Shift Right const CONTROL_OEM0 = 0b00000000001000000000000000000000; // Output Enable MUX 0 const CONTROL_OEM1 = 0b00000000010000000000000000000000; // Output Enable MUX 1 const CONTROL_OEM2 = 0b00000000100000000000000000000000; // Output Enable MUX 2 const CONTROL_OEM3 = 0b00000001000000000000000000000000; // Output Enable MUX 3 const CONTROL_OEM4 = 0b00000010000000000000000000000000; // Output Enable MUX 4 const CONTROL_OEME = 0b00000100000000000000000000000000; // Output Enable MUX Enable const CONTROL_RI = 0b00010000000000000000000000000000; // RAM Input Enable const CONTROL_IRI = 0b00100000000000000000000000000000; // Instruction Register Input Enable const CONTROL_MCL0 = 0b01000000000000000000000000000000; // Microcode Counter to 0 const CONTROL_MCL8 = 0b10000000000000000000000000000000; // Microcode Counter to 8 */ /* Free Instructions: 0x000 0x001 0x003 0x005 0x007 0x009 */ let Instructions = new Array(); const InstructionTypes = { SingleWord: { Name: `Singe Word`, toString() { return this.Name; } }, RTS16: { Name: `JSR 16 Return`, toString() { return this.Name; } }, RTS24: { Name: `JSR 24 Return`, toString() { return this.Name; } }, Immediate8: { Name: `8 bit Immediate`, toString() { return this.Name; } }, Immediate16: { Name: `16 bit Immediate`, toString() { return this.Name; } }, Immediate24: { Name: `24 bit Immediate`, toString() { return this.Name; } }, Indirect16: { Name: `16 bit Indirect`, toString() { return this.Name; } }, Indirect24: { Name: `24 bit Indirect`, toString() { return this.Name; } }, Absolute16: { Name: `16 bit Absolute`, toString() { return this.Name; } }, Absolute24: { Name: `24 bit Absolute`, toString() { return this.Name; } }, Register: { Name: `Register`, toString() { return this.Name; } }, RegisterImmediate: { Name: `Register Immediate`, toString() { return this.Name; } }, RegisterAbsolute: { Name: `Register Absolute`, toString() { return this.Name; } }, RegisterIndirect: { Name: `Register Indirect`, toString() { return this.Name; } } }; function IsRegister(reg) { reg = reg.toLowerCase().replace("%","").replace("[","").replace("]",""); switch (reg) { case "a": case "b": case "c": case "d": case "pc": case "sp": case "ab": case "ac": case "ad": case "ba": case "bc": case "bd": case "ca": case "cb": case "cd": case "da": case "db": case "dc": return true; break; } return false; } function ValidateInstruction(line) { let linearr = line.split(" "); let label = false; let type = false; if (linearr[0] !== "") label = linearr[0]; if (linearr.length > 2) { let operands = linearr[2].split(","); if (operands.length > 0) { if (operands.length === 1) { if (operands[0].substring(0,1) === '$') type = InstructionTypes.Immediate; if (operands[0].substring(0,1) === '[') type = InstructionTypes.Indirect; if (IsRegister(operands[0])) type = InstructionTypes.Register; if (type === false) type = InstructionTypes.Absolute; } else { // more then one operand } } } console.log(linearr[1]); let foundinstruction = FindInstructon({Instruction: linearr[1]}, type); return foundinstruction; } function FindInstructon(ins,type = false) { for (let a = 0; a < Instructions.length; a++) { if (Instructions[a].Mnemonic.toLowerCase() === ins.Instruction.toLowerCase()) { if (type) { if (Instructions[a].Type === type) return Instructions[a]; } else { return Instructions[a]; } } } return false; } function GenerateMicrocode(mcarray,cpu) { for (let a = 0; a < mcarray.length; a++) { for (let c = 0; c < 4; c++) { let offset = 0; if (c === 1) offset = 0b1000000000000000; if (c === 2) offset = 0b0100000000000000; if (c === 3) offset = 0b1100000000000000; let bytecode = mcarray[a].Bytecode & 0b1111111111; //if (c === 0 && (bytecode === 0x311)) console.log("Doing Normals"); //if (c === 1 && (bytecode === 0x311)) console.log("Doing Zero's"); //if (c === 2 && (bytecode === 0x311)) console.log("Doing Carry's"); //if (c === 3 && (bytecode === 0x311)) console.log("Doing ZC's"); for (let b = 0; b < 16; b++) { let mca = bytecode << 4; mca |= b; let mcv = mcarray[a].Microcode[b]; if (mcarray[a].UsesZero && c === 1) mcv = mcarray[a].MicrocodeZero[b]; if (mcarray[a].UsesCarry && c === 2) mcv = mcarray[a].MicrocodeCarry[b]; if (mcarray[a].UsesCarry && mcarray[a].UsesZero && c === 3) mcv = mcarray[a].MicrocodeZC[b]; if (mcarray[a].UsesCarry && !mcarray[a].UsesZero && c === 3) mcv = mcarray[a].MicrocodeCarry[b]; cpu.MCRAM[offset + mca] = mcv; mca = offset + mca; //if (bytecode === 0x311) console.log(`[${bytecode.toString(16)}] ${mca.toString(16)}: ${mcv.toString(2)}`); } } } } class Microcode_Instruction { constructor() { this.Bytecode = 0x000; // MAX IS 0x3ff this.Mnemonic = "NOP"; this.LongName = ""; this.Aliases = new Array(); this.Microcode = new Array(16); this.MicrocodeCarry = new Array(16); this.MicrocodeZero = new Array(16); this.MicrocodeZC = new Array(16); this.Operands = new Array(); this.UsesCarry = false; this.UsesZero = false; this.Words = 1; this.Cycles = 2; this.CycleCount = 2; this.CycleCountZero = 2; this.CycleCountCarry = 2; this.CycleCountZC = 2; this.Type = InstructionTypes.SingleWord; this.Microcode[0] = CONTROL_OUT_PC | CONTROL_RRI; this.Microcode[1] = CONTROL_OUT_RO | CONTROL_IRI | CONTROL_PCC; this.MicrocodeCarry[0] = CONTROL_OUT_PC | CONTROL_RRI; this.MicrocodeCarry[1] = CONTROL_OUT_RO | CONTROL_IRI | CONTROL_PCC; this.MicrocodeZero[0] = CONTROL_OUT_PC | CONTROL_RRI; this.MicrocodeZero[1] = CONTROL_OUT_RO | CONTROL_IRI | CONTROL_PCC; this.MicrocodeZC[0] = CONTROL_OUT_PC | CONTROL_RRI; this.MicrocodeZC[1] = CONTROL_OUT_RO | CONTROL_IRI | CONTROL_PCC; for (let a = 2; a < 16; a++) { this.Microcode[a] = CONTROL_MCL0; this.MicrocodeCarry[a] = CONTROL_MCL0; this.MicrocodeZero[a] = CONTROL_MCL0; this.MicrocodeZC[a] = CONTROL_MCL0; } } CloneInstruction(fromtype,totype) { // Simple function to clone instruction sets around if ((typeof totype === 'string' || totype instanceof String)) { if (totype.toLowerCase() === "all") { for (let a = 0; a < fromtype.length; a++) { if (fromtype !== this.Microcode) this.Microcode[a] = parseInt(fromtype[a]); if (fromtype !== this.MicrocodeZero) this.MicrocodeZero[a] = parseInt(fromtype[a]); if (fromtype !== this.MicrocodeCarry) this.MicrocodeCarry[a] = parseInt(fromtype[a]); if (fromtype !== this.MicrocodeZC) this.MicrocodeZC[a] = parseInt(fromtype[a]); } //console.log("Cloned ALL!"); } } else { if (fromtype === totype) return false; if (fromtype.length !== totype.length) return false; for (let a = 0; a < fromtype.length; a++) { totype[a] = parseInt(fromtype[a]); } } } AddInstruction(ins,type="") { if (type.toLowerCase() === "") { if (this.CycleCount > 15) return; // Cant find any more instructions! this.Microcode[this.CycleCount] = ins; this.CycleCount++; this.Cycles = this.CycleCount; } if (type.toLowerCase() === "zero") { if (this.CycleCountZero > 15) return; // Cant find any more instructions! this.MicrocodeZero[this.CycleCountZero] = ins; this.CycleCountZero++; } if (type.toLowerCase() === "carry") { if (this.CycleCountCarry > 15) return; // Cant find any more instructions! this.MicrocodeCarry[this.CycleCountCarry] = ins; this.CycleCountCarry++; } if (type.toLowerCase() === "zc") { if (this.CycleCountZC > 15) return; // Cant find any more instructions! this.MicrocodeZC[this.CycleCountZC] = ins; this.CycleCountZC++; } } }