Support for negative and overflow, ISA work, display registers for clearing and forcing update (on SIM only for force update), memory editor, and more

This commit is contained in:
MatCat 2021-04-15 00:37:00 -07:00
parent 24161774d9
commit 11862865f8
10 changed files with 436 additions and 30 deletions

View File

@ -54,9 +54,10 @@
</div>
<div>
<input type="button" id ="btn_clk" value="CLOCK" />
<span id="clk_counter">0</span><input type="button" id ="btn_runtil" value="BREAK AT:" /> 0x<input id="addrbrk" type="text" value="07" pattern="[a-fA-F\d]+" /> <input type="button" id ="btn_stopclk" value="STOP CLOCK" disabled /><br />
<span id="clk_counter">0</span><input type="button" id ="btn_runtil" value="BREAK AT:" /> 0x<input id="addrbrk" type="text" value="30" pattern="[a-fA-F\d]+" /> <input type="button" id ="btn_stopclk" value="STOP CLOCK" disabled /><br />
<span>Clock Interval: </span><input id="clkinterval" type="number" value="1" size="4" min="1" max="999999" />mS
<span>Cycles Per Interval: </span><input id="clkcycles" type="number" value="25" size="4" min="1" max="999999" />
<span>Cycles Per Interval: </span><input id="clkcycles" type="number" value="50" size="4" min="1" max="999999" /><br />
CPU Frequency: <span id="clk_freq"> </span>
</div>
</div>
@ -65,6 +66,9 @@
<div style="font-size: 0.9em;">
<span>RAM : [<span id="Address_BUS"></span>] <span>Lines: </span><input id="ramlines" type="number" value="4" size="4" min="1" max="1024" /></span><br /><span id="RAM"></span>
</div>
<div style="font-size: 0.9em;">
0x<input type="text" value="000000" pattern="[a-fA-F\d]+" id="txt_ramaddr" size="6"><input type="text" pattern="[a-fA-F\d]+" value="0000" id="txt_ramval" size="4"><input type="button" value="Save" id="btn_saveram">
</div>
<div style="font-size: 0.9em;">
<span>RAM (STACK): </span><br /><span id="STACK-RAM"></span>
</div>

102
js/cpu.js
View File

@ -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;
}

View File

@ -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

View File

@ -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);

View File

@ -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);

View File

@ -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);

View File

@ -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;

View File

@ -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;

View File

@ -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);
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();

View File

@ -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++;
}
}
}