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:
parent
24161774d9
commit
11862865f8
@ -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
102
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;
|
||||
}
|
||||
|
@ -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
|
||||
|
104
js/isa/alu.js
104
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);
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
74
js/main.js
74
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);
|
||||
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();
|
@ -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++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user