diff --git a/index.html b/index.html index 53d80a6..57c04fa 100644 --- a/index.html +++ b/index.html @@ -4,5 +4,6 @@ + \ No newline at end of file diff --git a/js/main.js b/js/main.js index f272e8f..31691e7 100644 --- a/js/main.js +++ b/js/main.js @@ -112,6 +112,16 @@ class CPU_8SA1 { } _CLOCK_HIGH() { // Call anything that needs to be called on positive clock edge + if (this.MC_Controls & CONTROL_OEME) { + let OUTMUX = (this.MC_Controls & CONTROL_OEM4) ? 0b10000 : 0; + OUTMUX |= (this.MC_Controls & CONTROL_OEM3) ? 0b01000 : 0; + OUTMUX |= (this.MC_Controls & CONTROL_OEM2) ? 0b00100 : 0; + OUTMUX |= (this.MC_Controls & CONTROL_OEM1) ? 0b00010 : 0; + OUTMUX |= (this.MC_Controls & CONTROL_OEM0) ? 0b00001 : 0; + + if (OUTMUX === OECONTROL_RO) this.DATABUS = this.RAM[this.ADDRBUS]; + } + if (this.MC_Controls & CONTROL_PCC ) this.PC_CLK(); if (this.MC_Controls & CONTROL_PCI ) this.PC_In_CLK(); if (this.MC_Controls & CONTROL_SPC ) this.SP_CLK(); @@ -138,6 +148,7 @@ class CPU_8SA1 { _FetchDecode_CLK_neg() { // We actually setup all of our fetch and decode logic during the clocks low phase + this.DATABUS = 0; this.MCC += 1; let MC_Controls = this.MCRAM[((this.IR & 0b0000001111111111) << 4) | this.MCC | ((this.SR & 0b00000011) << 14)]; if (MC_Controls & CONTROL_MCL0) this.MCC = 0; @@ -313,7 +324,7 @@ class CPU_8SA1 { break; } case OECONTROL_RO: { - this.DATABUS = this.RAM[this.ADDRBUS]; + // We dont actually want to do anything here since ram outputs on CLK break; } } @@ -359,10 +370,12 @@ class CPU_8SA1 { RR_In_CLK() { this.RR = this.DATABUS; + this.ADDRBUS = this.RR | this.RH << 16; } RH_In_CLK() { this.RH = this.DATABUS; + this.ADDRBUS = this.RR | this.RH << 16; } GPA_In_LOW_CLK() { diff --git a/js/microcode_compiler.js b/js/microcode_compiler.js new file mode 100644 index 0000000..d582e32 --- /dev/null +++ b/js/microcode_compiler.js @@ -0,0 +1,138 @@ +/* +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 +*/ +const CONTROL_OUT_PC = CONTROL_OEME; +const CONTROL_OUT_SP = CONTROL_OEME | CONTROL_OEM0; +const CONTROL_OUT_AB = CONTROL_OEME | CONTROL_OEM3 | CONTROL_OEM1; +const CONTROL_OUT_AE = CONTROL_OEME | CONTROL_OEM4 | CONTROL_OEM3 | CONTROL_OEM2; +const CONTROL_OUT_AO = CONTROL_OEME | CONTROL_OEM4 | CONTROL_OEM3 | CONTROL_OEM2 | CONTROL_OEM0; +const CONTROL_OUT_RO = CONTROL_OEME | CONTROL_OEM4 | CONTROL_OEM3 | CONTROL_OEM2 | CONTROL_OEM1 | CONTROL_OEM0; + +const CONTROL_ALU_ADD = CONTROL_OUT_AE; + +let Instructions = new Array(); + +function GenerateMicrocode(mcarray) { + for (let a = 0; a < mcarray.length; a++) { + for (let b = 0; b < 16; b++) { + let bytecode = mcarray[a].Bytecode; + let mca = mcarray[a].Bytecode << 4; + mca |= b; + let mcv = mcarray[a].Microcode[b]; + console.log(`[${bytecode.toString(16)}] ${mca.toString(16)}: ${mcv.toString(2)}`); + } + } +} + + +class Microcode_Instruction { + constructor() { + this.Bytecode = 0x000; // MAX IS 0x3ff + this.Microcode = new Array(16); + + this.UsesCarry = false; + this.UsesZero = false; + + this.Microcode[0] = CONTROL_OUT_PC | CONTROL_RRI; + this.Microcode[1] = CONTROL_OUT_RO | CONTROL_IRI | CONTROL_PCC; + for (let a = 2; a < 16; a++) { + this.Microcode[a] = CONTROL_MCL0; + } + } +} + + +class IS_LDA_imm extends Microcode_Instruction { + constructor(props) { + super(props); + this.Bytecode = 0x000; + this.Microcode[2] = CONTROL_OUT_PC | CONTROL_RRI; + this.Microcode[3] = CONTROL_OUT_RO | CONTROL_RAIL | CONTROL_PCC; + } +} +is_LDA_i = new IS_LDA_imm; +Instructions.push(is_LDA_i); + +class IS_LDB_imm extends Microcode_Instruction { + constructor(props) { + super(props); + this.Bytecode = 0x001; + this.Microcode[2] = CONTROL_OUT_PC | CONTROL_RRI; + this.Microcode[3] = CONTROL_OUT_RO | CONTROL_RBIL | CONTROL_PCC; + } +} +is_LDB_i = new IS_LDB_imm; +Instructions.push(is_LDB_i); + +class IS_LDC_imm extends Microcode_Instruction { + constructor(props) { + super(props); + this.Bytecode = 0x002; + this.Microcode[2] = CONTROL_OUT_PC | CONTROL_RRI; + this.Microcode[3] = CONTROL_OUT_RO | CONTROL_RCIL | CONTROL_PCC; + } +} +is_LDC_i = new IS_LDC_imm; +Instructions.push(is_LDC_i); + +class IS_LDD_imm extends Microcode_Instruction { + constructor(props) { + super(props); + this.Bytecode = 0x003; + this.Microcode[2] = CONTROL_OUT_PC | CONTROL_RRI; + this.Microcode[3] = CONTROL_OUT_RO | CONTROL_RDIL | CONTROL_PCC; + } +} +is_LDD_i = new IS_LDD_imm; +Instructions.push(is_LDD_i); + +// This is a simple ADD command which will ADD GPA and GPB putting the sum in GPA +class IS_ADD extends Microcode_Instruction { + constructor(props) { + super(props); + this.Bytecode = 0x100; + this.Microcode[2] = CONTROL_ALU_ADD; + this.Microcode[3] = CONTROL_RAIL | CONTROL_OUT_AO; + } +} +is_ADD = new IS_ADD; +Instructions.push(is_ADD); + +class IS_NOP extends Microcode_Instruction { + constructor(props) { + super(props); + this.Bytecode = 0x3ff; + } +} +is_NOP = new IS_NOP; +Instructions.push(is_NOP);