diff --git a/index.html b/index.html
index 7d7569b..5601dcf 100644
--- a/index.html
+++ b/index.html
@@ -54,9 +54,10 @@
- 0 0x
+ 0 0x
Clock Interval: mS
- Cycles Per Interval:
+ Cycles Per Interval:
+ CPU Frequency:
@@ -65,6 +66,9 @@
RAM : [] Lines:
+
+ 0x
+
RAM (STACK):
diff --git a/js/cpu.js b/js/cpu.js
index 77315d5..68cec2c 100644
--- a/js/cpu.js
+++ b/js/cpu.js
@@ -1,6 +1,17 @@
let intval = null;
let breakpt = null;
let ramlines = {value: 1};
+let iterations = 0;
+let totalstart = performance.now();
+let lastiteration = 0;
+let cyclecount = 0;
+let cycleavg = new Array(10);
+let cycleavgval = 0;
+let cycleavgpos = 0;
+
+for (let a = 0; a < cycleavg.length; a++) {
+ cycleavg[a] = 0;
+}
function stringToRAM(rstring,ram,address) {
for (let a = 0; a < rstring.length; a++) {
@@ -24,7 +35,9 @@ function generateClocks_Interval(cycles_per_run=1) {
} else {
cpu.CLOCK(true);
}*/
-
+ let perfStart = performance.now();
+ let perfEnd = 0;
+ let perftotal = 0;
for (let a = 0; a < cycles_per_run; a++) {
cpu.CLOCK(true);
clk_count++;
@@ -34,9 +47,37 @@ function generateClocks_Interval(cycles_per_run=1) {
if (cpu.ADDRBUS === breakpt) {
btn_stopclk.disabled = true;
clearInterval(intval);
+ updateHTML();
+ perfEnd = performance.now();
+ perftotal = perfEnd - perfStart;
+ //console.log(`Performance: ${perftotal}`);
return;
}
}
+ updateHTML();
+ perfEnd = performance.now();
+ perftotal = perfEnd - perfStart;
+ iterations += 1;
+ let totalnow = performance.now();
+ let timesince = totalnow - lastiteration;
+ lastiteration = totalnow;
+ cycleavg[cycleavgpos] = ((cycles_per_run / (timesince/1000))/1000);
+ cycleavgpos++;
+ if (cycleavgpos > cycleavg.length) cycleavgpos = 0;
+ cyclecount++;
+ if (cyclecount === 10) {
+ let avg = 0;
+ for (let a = 0; a < cycleavg.length; a++) {
+ avg += cycleavg[a];
+ }
+ cycleavgval = avg/cycleavg.length;
+ //console.log(`[${iterations} +${timesince}ms] Performance: ${perftotal}, CPS: ${cycleavgval}KHz`);
+ cyclecount = 0;
+ }
+ //console.log(`[${iterations} +${timesince}ms] Performance: ${perftotal}, CPS: ${cps}`);
+
+
+
}
function drawCPUInfo() {
@@ -161,6 +202,12 @@ function updateHTML() {
if (cpu.MC_Controls & CONTROL_RDIH) sp_gpd.style.backgroundColor = "#ff5555";
if (cpu.OUTMUX === OECONTROL_DA || cpu.OUTMUX === OECONTROL_DB || cpu.OUTMUX === OECONTROL_DC || cpu.OUTMUX === OECONTROL_DL) sp_gpd.style.backgroundColor = "#55cc55";
if (cpu.OUTMUX === OECONTROL_AD || cpu.OUTMUX === OECONTROL_BD || cpu.OUTMUX === OECONTROL_CD || cpu.OUTMUX === OECONTROL_DH) sp_gpd.style.backgroundColor = "#55ff55";
+ let sp_cf = document.getElementById("clk_freq");
+ sp_cf.innerText = Math.floor(cycleavgval) + "KHz";
+
+ let sp_ramaddr = document.getElementById("txt_ramaddr");
+ let sp_ramval = document.getElementById("txt_ramval");
+ sp_ramval.value = formatHex(cpu.RAM[parseInt(sp_ramaddr.value)],4);
printRAM(cpu.RAM);
let sp_textout = document.getElementById("TEXT_OUT");
sp_textout.innerText = printTextOut(cpu.RAM,0xd00000,0xd00000 + (80*24));
@@ -268,6 +315,19 @@ class CPU_8SA1 {
if (this.MC_Controls & CONTROL_RDIH) this.GPD_In_HIGH_CLK();
if (this.MC_Controls & CONTROL_AE ) this.ALU_CLK();
+ if (this.ADDRBUS === 0xff0000 && this.DATABUS > 0) {
+ // clear the display
+ for (let a = 0xd00000; a < 0xdfffff; a++) {
+ this.RAM[a] = 0;
+ }
+ //console.log("Display Cleared");
+ }
+
+ if (this.ADDRBUS === 0xff0001 && this.DATABUS > 0) {
+ // Force an update
+ updateHTML();
+ }
+
}
_CLOCK_LOW() {
@@ -285,7 +345,7 @@ class CPU_8SA1 {
ALUMUX |= (this.MC_Controls & CONTROL_ALUM0) ? 0b01 : 0;
//console.log(`ALU: A=${ALU_A}, B=${ALU_B}, MUX: ${ALUMUX}`);
- if (this.MC_Controls & CONTROL_ALUI) console.log("ALU Inverting B");
+ //if (this.MC_Controls & CONTROL_ALUI) console.log("ALU Inverting B");
let SHIFTING = false;
if (this.MC_Controls & CONTROL_ALUSL) SHIFTING = true;
if (this.MC_Controls & CONTROL_ALUSR) SHIFTING = true;
@@ -296,6 +356,7 @@ class CPU_8SA1 {
ALU_Result = ALU_A + ALU_B;
if (this.MC_Controls & CONTROL_ALUC && !SHIFTING) ALU_Result += 1;
+ //if (this.MC_Controls & CONTROL_ALUC && !SHIFTING) console.log("We are carrying in!");
break;
}
case 1: { // AND
@@ -306,7 +367,7 @@ class CPU_8SA1 {
}
case 2: { // OR
ALU_Result = ALU_A | ALU_B;
- console.log(`ALU OR: A: ${ALU_A}, B: ${ALU_B}, Result: ${ALU_Result}`);
+ //console.log(`ALU OR: A: ${ALU_A}, B: ${ALU_B}, Result: ${ALU_Result}`);
if (this.MC_Controls & CONTROL_ALUI) ALU_Result = ~ALU_Result;
if (this.MC_Controls & CONTROL_ALUC && !SHIFTING) ALU_Result += 1;
break;
@@ -341,10 +402,10 @@ class CPU_8SA1 {
if (~(((ALU_A & 0b10000000)>>7) ^ ((ALU_B & 0b10000000)>>7)) === -1) {
if ((ALU_A & 0b10000000) !== (ALU_Result & 0b10000000)) {
// We have an OVERFLOW
- console.log("overflow");
- console.log(((ALU_A & 0b10000000)>>7));
- console.log(((ALU_B & 0b10000000)>>7));
- console.log(((ALU_Result & 0b10000000)>>7));
+ //console.log("overflow");
+ //console.log(((ALU_A & 0b10000000)>>7));
+ //console.log(((ALU_B & 0b10000000)>>7));
+ //console.log(((ALU_Result & 0b10000000)>>7));
this.SR = this.SR | 0b00000100;
}
} else {
@@ -367,7 +428,18 @@ class CPU_8SA1 {
this.DATABUS = 0;
this.MCC += 1;
if (this.MCC > 15) this.MCC = 0;
- let mcra = ((this.IR & 0b0000001111111111) << 4) | this.MCC | ((this.SR & 0b00000011) << 14);
+ let lSR = 0;
+ if ((this.IR & 0b0000010000000000) !== 0) {
+ // We are going to make the ZERO line a NEGATIVE line
+ lSR = ((this.SR & 0b00000001) << 14);
+ lSR |= ((this.SR & 0b00001000) << 12);
+ //console.log("We are doing a NEGATIVE instead of ZERO");
+ //console.log(formatBinary(lSR,16));
+ //console.log(formatHex(((this.IR & 0b0000001111111111) << 4) | this.MCC | lSR,4));
+ } else {
+ lSR = ((this.SR & 0b00000011) << 14);
+ }
+ let mcra = ((this.IR & 0b0000001111111111) << 4) | this.MCC | lSR;
let MC_Controls = this.MCRAM[mcra];
if (MC_Controls & CONTROL_MCL0) this.MCC = 0;
if (MC_Controls & CONTROL_MCL8) this.MCC = 8;
@@ -382,8 +454,18 @@ class CPU_8SA1 {
}
//if (MC_Controls & CONTROL_MCL0) console.log(`Reset microcode counter to 0`);
//if (MC_Controls & CONTROL_MCL8) console.log(`Reset microcode counter to 8`);
- mcra = ((this.IR & 0b0000001111111111) << 4) | this.MCC | ((this.SR & 0b00000011) << 14);
+ if ((this.IR & 0b0000010000000000) !== 0) {
+ // We are going to make the ZERO line a NEGATIVE line
+ lSR = ((this.SR & 0b00000001) << 14);
+ lSR |= ((this.SR & 0b00001000) << 12);
+ //console.log("We are doing a NEGATIVE instead of ZERO");
+ //console.log(formatBinary(lSR,16,4));
+ } else {
+ lSR = ((this.SR & 0b00000011) << 14);
+ }
+ mcra = ((this.IR & 0b0000001111111111) << 4) | this.MCC | lSR;
MC_Controls = this.MCRAM[mcra];
+ //if (this.IR === 0x711) console.log(formatHex(mcra,4));
if (MC_Controls === undefined) MC_Controls = 0;
//console.log(`[${mcra.toString(2)}] Control Lines: ${MC_Controls.toString(2)}`);
if (MC_Controls !== this.MC_Controls) {
@@ -495,7 +577,7 @@ class CPU_8SA1 {
break;
}
case OECONTROL_TI: {
- console.log(`Storing PC [${formatHex(this.PC,6)}] to SP [${formatHex(this.SP,6)}]`);
+ //console.log(`Storing PC [${formatHex(this.PC,6)}] to SP [${formatHex(this.SP,6)}]`);
this.DATABUS = 0x7F;
break;
}
diff --git a/js/defines.js b/js/defines.js
index 93b35f6..c5154a8 100644
--- a/js/defines.js
+++ b/js/defines.js
@@ -10,30 +10,37 @@ const CONTROL_PCC = 0b00000000000000000000000000000001; // PC CL
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_AE = 0b00001000000000000000000000000000; // ALU Enable
+
const CONTROL_RI = 0b00010000000000000000000000000000; // RAM Input Enable
const CONTROL_IRI = 0b00100000000000000000000000000000; // Instruction Register Input Enable
const CONTROL_MCL0 = 0b01000000000000000000000000000000; // Microcode Counter to 0
diff --git a/js/isa/alu.js b/js/isa/alu.js
index 570823e..49ce8b9 100644
--- a/js/isa/alu.js
+++ b/js/isa/alu.js
@@ -349,3 +349,107 @@ class IS_ADD_gpd_imm extends Microcode_Instruction {
}
is_ADD_gpdi = new IS_ADD_gpd_imm;
Instructions.push(is_ADD_gpdi);
+
+class IS_ADD_ABabs16 extends Microcode_Instruction {
+ constructor(props) {
+ super(props);
+ this.UsesCarry = true;
+ this.UsesZero = true;
+ this.Bytecode = 0x711;
+ this.Mnemonic = "ADD";
+ this.LongName = "Addition";
+ this.Aliases = new Array();
+
+ this.Type = InstructionTypes.Register;
+ this.Operands = new Array({Operand: "AB", Bitwidth: 16},{Operand: "$", Bitwidth: 16});
+ this.Words = 2;
+ this.AddInstruction(CONTROL_OUT_SP | CONTROL_RRI );
+ this.AddInstruction(CONTROL_OUT_BL | CONTROL_RI | CONTROL_SPD | CONTROL_SPC);
+ this.AddInstruction(CONTROL_OUT_PC | CONTROL_RRI );
+ this.AddInstruction(CONTROL_OUT_I2 | CONTROL_RBIL | CONTROL_PCC );
+ this.AddInstruction(CONTROL_OUT_AB | CONTROL_ALU_ADD );
+ this.AddInstruction(CONTROL_OUT_AO | CONTROL_RAIL );
+ this.AddInstruction(CONTROL_OUT_SP | CONTROL_RRI );
+ this.AddInstruction(CONTROL_OUT_AL | CONTROL_RI | CONTROL_SPC );
+ this.AddInstruction(CONTROL_OUT_SP | CONTROL_RRI );
+ this.AddInstruction(CONTROL_OUT_RO | CONTROL_RAIL );
+ this.AddInstruction(CONTROL_OUT_2O | CONTROL_RBIH | CONTROL_SPD | CONTROL_SPC);
+ this.CloneInstruction(this.Microcode,"all");
+ this.CycleCountCarry = parseInt(this.CycleCount);
+ this.CycleCountZero = parseInt(this.CycleCount);
+ this.CycleCountZC = parseInt(this.CycleCount);
+ this.AddInstruction(CONTROL_OUT_AB | CONTROL_ALU_ADD );
+ this.AddInstruction( CONTROL_MCL0 );
+ this.AddInstruction(CONTROL_OUT_AB | CONTROL_ALU_ADD , "Zero");
+ this.AddInstruction( CONTROL_MCL0 , "Zero");
+ this.AddInstruction(CONTROL_OUT_AB | CONTROL_ALU_ADD | CONTROL_ALUC, "Carry");
+ this.AddInstruction( CONTROL_MCL0 , "Carry");
+ this.AddInstruction(CONTROL_OUT_AB | CONTROL_ALU_ADD | CONTROL_ALUC, "ZC");
+ this.AddInstruction( CONTROL_MCL0 , "ZC");
+
+/*
+ this.AddInstruction(CONTROL_OUT_SP | CONTROL_RRI , "Zero");
+ this.AddInstruction(CONTROL_OUT_BL | CONTROL_RI | CONTROL_SPD | CONTROL_SPC, "Zero");
+ this.AddInstruction(CONTROL_OUT_PC | CONTROL_RRI , "Zero");
+ this.AddInstruction(CONTROL_OUT_I2 | CONTROL_RBIL | CONTROL_PCC , "Zero");
+ this.AddInstruction(CONTROL_OUT_AB | CONTROL_ALU_ADD , "Zero");
+ this.AddInstruction(CONTROL_OUT_AO | CONTROL_RAIL , "Zero");
+ this.AddInstruction(CONTROL_OUT_SP | CONTROL_RRI , "Zero");
+ this.AddInstruction(CONTROL_OUT_AL | CONTROL_RI | CONTROL_SPC , "Zero");
+ this.AddInstruction(CONTROL_OUT_SP | CONTROL_RRI , "Zero");
+ this.AddInstruction(CONTROL_OUT_RO | CONTROL_RAIL , "Zero");
+ this.AddInstruction(CONTROL_OUT_2O | CONTROL_RBIH | CONTROL_SPD | CONTROL_SPC, "Zero");
+ this.AddInstruction(CONTROL_OUT_AB | CONTROL_ALU_ADD , "Zero");
+ this.AddInstruction(CONTROL_MCL0, "Zero");
+
+ this.AddInstruction(CONTROL_OUT_SP | CONTROL_RRI , "Carry");
+ this.AddInstruction(CONTROL_OUT_BL | CONTROL_RI | CONTROL_SPD | CONTROL_SPC, "Carry");
+ this.AddInstruction(CONTROL_OUT_PC | CONTROL_RRI , "Carry");
+ this.AddInstruction(CONTROL_OUT_I2 | CONTROL_RBIL | CONTROL_PCC , "Carry");
+ this.AddInstruction(CONTROL_OUT_AB | CONTROL_ALU_ADD , "Carry");
+ this.AddInstruction(CONTROL_OUT_AO | CONTROL_RAIL , "Carry");
+ this.AddInstruction(CONTROL_OUT_SP | CONTROL_RRI , "Carry");
+ this.AddInstruction(CONTROL_OUT_AL | CONTROL_RI | CONTROL_SPC , "Carry");
+ this.AddInstruction(CONTROL_OUT_SP | CONTROL_RRI , "Carry");
+ this.AddInstruction(CONTROL_OUT_RO | CONTROL_RAIL , "Carry");
+ this.AddInstruction(CONTROL_OUT_2O | CONTROL_RBIH | CONTROL_SPD | CONTROL_SPC, "Carry");
+ this.AddInstruction(CONTROL_OUT_AB | CONTROL_ALU_ADD | CONTROL_ALUC , "Carry");
+ this.AddInstruction(CONTROL_MCL0, "Carry");
+
+ this.AddInstruction(CONTROL_OUT_SP | CONTROL_RRI , "ZC");
+ this.AddInstruction(CONTROL_OUT_BL | CONTROL_RI | CONTROL_SPD | CONTROL_SPC, "ZC");
+ this.AddInstruction(CONTROL_OUT_PC | CONTROL_RRI , "ZC");
+ this.AddInstruction(CONTROL_OUT_I2 | CONTROL_RBIL | CONTROL_PCC , "ZC");
+ this.AddInstruction(CONTROL_OUT_AB | CONTROL_ALU_ADD , "ZC");
+ this.AddInstruction(CONTROL_OUT_AO | CONTROL_RAIL , "ZC");
+ this.AddInstruction(CONTROL_OUT_SP | CONTROL_RRI , "ZC");
+ this.AddInstruction(CONTROL_OUT_AL | CONTROL_RI | CONTROL_SPC , "ZC");
+ this.AddInstruction(CONTROL_OUT_SP | CONTROL_RRI , "ZC");
+ this.AddInstruction(CONTROL_OUT_RO | CONTROL_RAIL , "ZC");
+ this.AddInstruction(CONTROL_OUT_2O | CONTROL_RBIH | CONTROL_SPD | CONTROL_SPC, "ZC");
+ this.AddInstruction(CONTROL_OUT_AB | CONTROL_ALU_ADD | CONTROL_ALUC , "ZC");
+ this.AddInstruction(CONTROL_MCL0, "ZC");
+*/
+ }
+}
+is_ADD_aab16 = new IS_ADD_ABabs16;
+Instructions.push(is_ADD_aab16);
+
+class IS_ADD_ABabs16_2 extends Microcode_Instruction {
+ constructor(props) {
+ super(props);
+ this.Bytecode = 0x712;
+ this.Mnemonic = "ADD";
+ this.LongName = "Addition";
+ this.Aliases = new Array();
+
+ this.Type = InstructionTypes.Register;
+ this.Operands = new Array();
+ this.Words = 1;
+ this.AddInstruction(CONTROL_OUT_SP | CONTROL_RRI );
+ this.AddInstruction(CONTROL_OUT_AO | CONTROL_RBIL );
+ this.AddInstruction(CONTROL_OUT_RO | CONTROL_RAIL );
+ }
+}
+is_ADD_aab16_2 = new IS_ADD_ABabs16_2;
+Instructions.push(is_ADD_aab16_2);
diff --git a/js/isa/branching.js b/js/isa/branching.js
index 32c86ac..b7a31db 100644
--- a/js/isa/branching.js
+++ b/js/isa/branching.js
@@ -432,3 +432,27 @@ class IS_RTS_abs24 extends Microcode_Instruction {
}
is_RTS_a24 = new IS_RTS_abs24;
Instructions.push(is_RTS_a24);
+
+class IS_JMP_SPabs24 extends Microcode_Instruction {
+ constructor(props) {
+ super(props);
+ this.Bytecode = 0x3DF;
+ this.Mnemonic = "JMP";
+ this.LongName = "Jump to 24 bit address stored on STACK";
+ this.Aliases = new Array();
+
+ this.Type = InstructionTypes.RegisterAbsolute;
+ this.Operands = new Array({Operand: "SP", Bitwidth: 24});
+ this.Words = 1;
+ this.Cycles = 9;
+ this.Microcode[2] = CONTROL_SPC;
+ this.Microcode[3] = CONTROL_OUT_SP | CONTROL_RRI;
+ this.Microcode[4] = CONTROL_OUT_I2 | CONTROL_SPC;
+ this.Microcode[5] = CONTROL_OUT_SP | CONTROL_RRI;
+ this.Microcode[6] = CONTROL_OUT_RO | CONTROL_PCI;
+ this.Microcode[7] = CONTROL_OUT_2O | CONTROL_RHI | CONTROL_PCC;
+ this.Microcode[8] = CONTROL_PCC;
+ }
+}
+is_JMP_spa24 = new IS_JMP_SPabs24;
+Instructions.push(is_JMP_spa24);
diff --git a/js/isa/ldx.js b/js/isa/ldx.js
index 19f07a6..f1b2a9c 100644
--- a/js/isa/ldx.js
+++ b/js/isa/ldx.js
@@ -988,6 +988,27 @@ class IS_LDSP_abs16 extends Microcode_Instruction {
is_LDSP_a = new IS_LDSP_abs16;
Instructions.push(is_LDSP_a);
+class IS_LDSPP_abs16 extends Microcode_Instruction {
+ constructor(props) {
+ super(props);
+ this.Bytecode = 0x05F;
+ this.Mnemonic = "LDSPP";
+ this.LongName = "LOAD Stack Pointer Page";
+ this.Aliases = new Array();
+
+ this.Type = InstructionTypes.Absolute16;
+ this.Operands = new Array({Operand: "", Bitwidth: 16});
+ this.Words = 2;
+ this.Cycles = 4;
+ this.Microcode[2] = CONTROL_OUT_PC | CONTROL_RRI;
+ this.Microcode[2] = CONTROL_OUT_RO | CONTROL_RRI;
+ this.Microcode[4] = CONTROL_OUT_HS | CONTROL_PCC;
+ }
+}
+is_LDSPP_a = new IS_LDSPP_abs16;
+Instructions.push(is_LDSPP_a);
+
+
class IS_LDAL_abs24 extends Microcode_Instruction {
constructor(props) {
super(props);
diff --git a/js/isa/misc.js b/js/isa/misc.js
index 92a452a..c5e60d0 100644
--- a/js/isa/misc.js
+++ b/js/isa/misc.js
@@ -54,6 +54,36 @@ class IS_CTI extends Microcode_Instruction {
is_CTI = new IS_CTI;
Instructions.push(is_CTI);
+class IS_NOPLONG extends Microcode_Instruction {
+ constructor(props) {
+ super(props);
+ this.Bytecode = 0x3fd;
+ this.Mnemonic = "NOPL";
+ this.LongName = "NO OPERATION LONG";
+ this.Aliases = new Array();
+
+ this.Type = InstructionTypes.SingleWord;
+ this.Operands = new Array();
+ this.Words = 1;
+ this.AddInstruction(0);
+ this.AddInstruction(0);
+ this.AddInstruction(0);
+ this.AddInstruction(0);
+ this.AddInstruction(0);
+ this.AddInstruction(0);
+ this.AddInstruction(0);
+ this.AddInstruction(0);
+ this.AddInstruction(0);
+ this.AddInstruction(0);
+ this.AddInstruction(0);
+ this.AddInstruction(0);
+ this.AddInstruction(0);
+ this.AddInstruction(0);
+ }
+}
+is_NOPL = new IS_NOPLONG;
+Instructions.push(is_NOPL);
+
class IS_RTI extends Microcode_Instruction {
constructor(props) {
super(props);
@@ -65,14 +95,15 @@ class IS_RTI extends Microcode_Instruction {
this.Type = InstructionTypes.SingleWord;
this.Operands = new Array();
this.Words = 1;
- this.Cycles = 6;
+ this.Cycles = 8;
this.Microcode[0] = CONTROL_OUT_SP | CONTROL_RRI;
this.Microcode[1] = CONTROL_OUT_PC | CONTROL_RI | CONTROL_SPD | CONTROL_SPC;
- this.Microcode[2] = CONTROL_OUT_TI | CONTROL_PCI;
- this.Microcode[3] = CONTROL_RHI;
- this.Microcode[4] = CONTROL_OUT_PC | CONTROL_RRI;
- this.Microcode[5] = CONTROL_OUT_RO | CONTROL_IRI | CONTROL_PCC;
-
+ this.Microcode[2] = CONTROL_OUT_SP | CONTROL_RRI;
+ this.Microcode[3] = CONTROL_OUT_HO | CONTROL_RI | CONTROL_SPD | CONTROL_SPC;
+ this.Microcode[4] = CONTROL_OUT_TI | CONTROL_PCI;
+ this.Microcode[5] = CONTROL_RHI;
+ this.Microcode[6] = CONTROL_OUT_PC | CONTROL_RRI;
+ this.Microcode[7] = CONTROL_OUT_RO | CONTROL_IRI | CONTROL_PCC;
}
}
is_RTI = new IS_RTI;
diff --git a/js/isa/stx.js b/js/isa/stx.js
index 2d03bca..2ba7988 100644
--- a/js/isa/stx.js
+++ b/js/isa/stx.js
@@ -281,9 +281,10 @@ class IS_STAB_abs16 extends Microcode_Instruction {
this.Type = InstructionTypes.Absolute16;
this.Operands = new Array({Operand: "", Bitwidth: 16});
this.Words = 2;
- this.Cycles = 4;
+ this.Cycles = 5;
this.Microcode[2] = CONTROL_OUT_PC | CONTROL_RRI;
- this.Microcode[3] = CONTROL_OUT_AB | CONTROL_RI | CONTROL_PCC;
+ this.Microcode[3] = CONTROL_OUT_RO | CONTROL_RRI;
+ this.Microcode[4] = CONTROL_OUT_AB | CONTROL_RI | CONTROL_PCC;
}
}
is_STAB_a = new IS_STAB_abs16;
diff --git a/js/main.js b/js/main.js
index 56c84f1..1aa1795 100644
--- a/js/main.js
+++ b/js/main.js
@@ -4,13 +4,55 @@ GenerateMicrocode(Instructions,cpu);
cpu.RAM[0] = is_LDSPP_i.Bytecode;
cpu.RAM[1] = 0xCF;
-cpu.RAM[2] = is_LDAB_i.Bytecode;
-cpu.RAM[3] = 0x0100;
-cpu.RAM[4] = is_PHAB.Bytecode;
-cpu.RAM[5] = is_JSR_a.Bytecode;
-cpu.RAM[6] = 0x00D0;
+cpu.RAM[2] = is_LDA_i.Bytecode;
+cpu.RAM[3] = 1;
+cpu.RAM[4] = is_STAL_a24.Bytecode;
+cpu.RAM[5] = 0xFF;
+cpu.RAM[6] = 0x0;
+cpu.RAM[7] = is_LDAB_i.Bytecode;
+cpu.RAM[8] = 0x0100;
+cpu.RAM[9] = is_PHAB.Bytecode;
+cpu.RAM[10] = is_JSR_a.Bytecode;
+cpu.RAM[11] = 0x00D0;
+cpu.RAM[12] = is_LDAB_i.Bytecode;
+cpu.RAM[13] = 0x0101;
+cpu.RAM[14] = is_STAL_a24.Bytecode;
+cpu.RAM[15] = 0xFF;
+cpu.RAM[16] = 0x1;
+cpu.RAM[17] = is_ADD.Bytecode;
+cpu.RAM[18] = is_NOPL.Bytecode;
+cpu.RAM[19] = is_NOPL.Bytecode;
+cpu.RAM[20] = is_NOPL.Bytecode;
+cpu.RAM[21] = is_NOPL.Bytecode;
+cpu.RAM[22] = is_NOPL.Bytecode;
+cpu.RAM[23] = is_NOPL.Bytecode;
+cpu.RAM[24] = is_NOPL.Bytecode;
+cpu.RAM[25] = is_NOPL.Bytecode;
+cpu.RAM[26] = is_NOPL.Bytecode;
+cpu.RAM[27] = is_NOPL.Bytecode;
+cpu.RAM[28] = is_NOPL.Bytecode;
+cpu.RAM[29] = is_BCC_a.Bytecode;
+cpu.RAM[30] = 17;
+cpu.RAM[31] = is_JMP_a.Bytecode;
+cpu.RAM[32] = 0x0;
+
/*
+
+// Experimenting with 16 bit add
+cpu.RAM[2] = is_LDAB_i.Bytecode;
+cpu.RAM[3] = 0x1337;
+cpu.RAM[4] = is_ADD_aab16.Bytecode;
+cpu.RAM[5] = 0b1111000011101001;
+cpu.RAM[6] = is_ADD_aab16_2.Bytecode;
+cpu.RAM[7] = is_STAB_a.Bytecode;
+cpu.RAM[8] = 0x0020;
+*/
+
+
+/*
+
+// Experimenting with thread interrupt
cpu.RAM[2] = is_STI.Bytecode;
cpu.RAM[3] = 0x80;
@@ -77,6 +119,10 @@ updateHTML();
let btn_clk = document.getElementById("btn_clk");
let btn_stopclk = document.getElementById("btn_stopclk");
let btn_runtil = document.getElementById("btn_runtil");
+let btn_saveram = document.getElementById("btn_saveram");
+let txt_ramaddr = document.getElementById("txt_ramaddr");
+let txt_ramval = document.getElementById("txt_ramval");
+
let brkpt = document.getElementById("addrbrk");
let clkinterval = document.getElementById("clkinterval");
let clkcycles = document.getElementById("clkcycles");
@@ -89,10 +135,12 @@ btn_clk.addEventListener('mousedown', function(evt) {
cpu.CLOCK(true);
clk_count++;
clk_counter.innerText = clk_count;
+ updateHTML();
});
btn_clk.addEventListener('mouseup', function(evt) {
cpu.CLOCK(false);
+ updateHTML();
});
@@ -107,6 +155,7 @@ btn_runtil.addEventListener('click', function(evt) {
btn_stopclk.addEventListener('click', function(evt) {
btn_stopclk.disabled = true;
clearInterval(intval);
+ updateHTML();
});
btn_rst.addEventListener('click', function(evt) {
@@ -136,6 +185,19 @@ btn_rst.addEventListener('click', function(evt) {
for (let a = 0xd00000; a < 0xe00000; a++) {
cpu.RAM[a] = 0;
}
+ updateHTML();
+
});
-window.requestAnimationFrame(drawCPUInfo);
\ No newline at end of file
+btn_saveram.addEventListener('click', function(evt) {
+ cpu.RAM[parseInt(txt_ramaddr.value)] = parseInt("0x" + txt_ramval.value);
+ updateHTML();
+});
+
+txt_ramaddr.addEventListener('change', function(evt) {
+ txt_ramval.value = formatHex(cpu.RAM[parseInt(txt_ramaddr.value)],4);
+});
+
+
+//window.requestAnimationFrame(drawCPUInfo);
+updateHTML();
\ No newline at end of file
diff --git a/js/microcode_compiler.js b/js/microcode_compiler.js
index 082d097..0d30afe 100644
--- a/js/microcode_compiler.js
+++ b/js/microcode_compiler.js
@@ -206,16 +206,23 @@ function GenerateMicrocode(mcarray,cpu) {
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 bytecode = mcarray[a].Bytecode;
- let mca = mcarray[a].Bytecode << 4;
+ 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].MicrocodeCZ[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;
- //console.log(`[${bytecode.toString(16)}] ${mca.toString(16)}: ${mcv.toString(2)}`);
+ mca = offset + mca;
+ //if (bytecode === 0x311) console.log(`[${bytecode.toString(16)}] ${mca.toString(16)}: ${mcv.toString(2)}`);
}
}
}
@@ -228,18 +235,81 @@ class Microcode_Instruction {
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++;
}
}
}