Memory now follows the location, shows red when writing to RAM and GREEN when reading, yellow when the address bus just happens to be sitting on the address but not actively reading or writing.

This commit is contained in:
MatCat 2021-04-05 23:49:23 -07:00
parent 3943201db1
commit a3f5382437
5 changed files with 181 additions and 43 deletions

View File

@ -41,11 +41,12 @@
</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="00" pattern="[a-fA-F\d]+" />
<span id="clk_counter">0</span><input type="button" id ="btn_runtil" value="BREAK AT:" /> 0x<input id="addrbrk" type="text" value="05" pattern="[a-fA-F\d]+" />
<span>Clock Interval: </span><input id="clkinterval" type="text" value="1" />mS
</div>
<div>
<span>Text Output (0x8000-0x83ff):</span><br />
<span id="TEXT_OUT"></span>
<span id="TEXT_OUT" style="border: 1px solid black; min-width: 48em; min-height: 2.2em; display: inline-block;"></span>
</div>
<div>
<span>RAM : [<span id="Address_BUS"></span>]</span><br /><span id="RAM"></brspan>
@ -57,5 +58,6 @@
<script src="js/cpu.js"></script>
<script src="js/microcode_compiler.js"></script>
<script src="js/main.js"></script>
<script src="js/asm_compiler.js"></script>
</body>
</html>

113
js/asm_compiler.js Normal file
View File

@ -0,0 +1,113 @@
class ASM_Compiler {
constructor(assemblycode) {
this.ASM = assemblycode.replace(/ +/g, ' ').replace(/\\t+/g, ' ').replace(/\\r+/g, '');
this.Labels = new Array();
this.Directives = {
Globals: new Array()
};
this.Sections = new Array();
this.CompileError = false;
this.CompileErrorReason = "";
}
firstPass() {
let codeLines = this.ASM.split("\n");
let currentSection = "";
console.log(`There are ${codeLines.length} lines`);
for (let linenum = 0; linenum < codeLines.length; linenum++) {
console.log(`Line ${linenum}: ${codeLines[linenum]}`);
let globalDeclared = false;
let sectionDeclared = false;
let lineColumns = codeLines[linenum].split(" ");
for (let colnum = 0; colnum < lineColumns.length; colnum++) {
console.log(`Column ${colnum}: ${lineColumns[colnum]}`);
switch (colnum) {
case 0: { // Labels
if (currentSection === "" && lineColumns[colnum] !== "") {
// error, shouldn't be anything here in the directives section
this.CompileError = true;
this.CompileErrorReason = "Unexpected label in directives section: " + lineColumns[colnum];
this.CompileErrorLine = linenum+1;
return false;
}
break;
}
case 1: { // Instructions
if (currentSection === "" && lineColumns[colnum] === "") {
// Error, in directive there should be SOMETHING here
this.CompileError = true;
this.CompileErrorReason = "Missing Directive";
this.CompileErrorLine = linenum+1;
return false;
}
if (currentSection === "") {
switch (lineColumns[colnum].toLowerCase()) {
case "global": {
if (colnum === lineColumns.length - 1) {
this.CompileError = true;
this.CompileErrorReason = "Missing Global Label";
this.CompileErrorLine = linenum + 1;
return false;
}
globalDeclared = true;
break;
}
case "section": {
if (colnum === lineColumns.length - 1) {
this.CompileError = true;
this.CompileErrorReason = "Missing section type";
this.CompileErrorLine = linenum + 1;
return false;
}
sectionDeclared = true;
break;
}
default: {
this.CompileError = true;
this.CompileErrorReason = "Unknown directive: " + lineColumns[colnum];
this.CompileErrorLine = linenum + 1;
return false;
}
}
break;
} else {
if (!FindInstructon({Instruction:lineColumns[colnum]})) {
this.CompileError = true;
this.CompileErrorReason = "Unknown instruction: " + lineColumns[colnum];
this.CompileErrorLine = linenum + 1;
return false;
}
}
}
case 2: { // Operands
if (currentSection === "" && lineColumns[colnum] === "" && (globalDeclared === true || sectionDeclared === true)) {
// There should be a label here!
this.CompileError = true;
if (globalDeclared) this.CompileErrorReason = "Missing Global Label";
if (sectionDeclared) this.CompileErrorReason = "Missing Section type";
this.CompileErrorLine = linenum+1;
return false;
}
if (globalDeclared) {
let globallabel = {
Label: lineColumns[colnum].replace(":", ""),
Address: 0
};
this.Directives.Globals.push(globallabel);
}
if (sectionDeclared) {
let sectionType = {
Label: lineColumns[colnum].replace(".", ""),
Address: 0
};
currentSection = sectionType;
this.Sections.push(currentSection);
}
break;
}
}
}
}
}
}

View File

@ -66,9 +66,9 @@ function GetMnemonic(mcarray,instruction) {
function generateClocks(clk_cnt) {
for (let a = 0; a < clk_cnt; a++) {
cpu.CLOCK(true);
updateHTML();
clk_count++;
clk_counter.innerText = clk_count;
cpu.CLOCK(false);
updateHTML();
}
}
@ -79,17 +79,23 @@ function generateClocks_Interval() {
cpu.CLOCK(true);
}*/
cpu.CLOCK(true);
clk_count++;
clk_counter.innerText = clk_count;
cpu.CLOCK(false);
updateHTML();
if (cpu.ADDRBUS === breakpt) clearInterval(intval);
}
function drawCPUInfo() {
updateHTML();
window.requestAnimationFrame(drawCPUInfo);
}
function RunUntilBreak(addr) {
breakpt = addr;
intval = setInterval(function(){
generateClocks_Interval();
}, 1);
}, parseInt(clkinterval.value));
}
function printTextOut(ram,startaddr,endaddr) {
@ -101,14 +107,22 @@ function printTextOut(ram,startaddr,endaddr) {
}
function printRAM(ram) {
let startADDR = (cpu.ADDRBUS & 0xfff0) - 0x80;
if (startADDR < 0) startADDR = 0;
if (startADDR > 0xFEFF) startADDR = 0xFF00;
let sp_ram = document.getElementById("RAM");
let ramtext = "ADDR&nbsp;&nbsp;:&nbsp;&nbsp;&nbsp;0&nbsp;&nbsp;&nbsp;&nbsp;1&nbsp;&nbsp;&nbsp;&nbsp;2&nbsp;&nbsp;&nbsp;&nbsp;3&nbsp;&nbsp;&nbsp;&nbsp;4&nbsp;&nbsp;&nbsp;&nbsp;5&nbsp;&nbsp;&nbsp;&nbsp;6&nbsp;&nbsp;&nbsp;&nbsp;7&nbsp;&nbsp;&nbsp;&nbsp;8&nbsp;&nbsp;&nbsp;&nbsp;9&nbsp;&nbsp;&nbsp;&nbsp;A&nbsp;&nbsp;&nbsp;&nbsp;B&nbsp;&nbsp;&nbsp;&nbsp;C&nbsp;&nbsp;&nbsp;&nbsp;D&nbsp;&nbsp;&nbsp;&nbsp;E&nbsp;&nbsp;&nbsp;&nbsp;F<br />";
for (let a = 0; a < 16; a++) {
ramtext += "0x" + formatHex(a*16,4) + ": ";
for (let a = startADDR; a < (startADDR+255); a+=16) {
ramtext += "0x" + formatHex(a,4) + ": ";
for (let b = 0; b < 16; b++) {
if (cpu.ADDRBUS === (a*16)+b) ramtext += '<span style="background-color: #ffff55">';
ramtext += formatHex(ram[(a*16)+b],4) + " ";
if (cpu.ADDRBUS === (a*16)+b) ramtext += '</span>';
if (cpu.ADDRBUS === (a)+b) {
let bgcolor = "#ffff55";
if ((cpu.MC_Controls & CONTROL_OUT_RO) === CONTROL_OUT_RO) bgcolor = "#55ff55";
if (cpu.MC_Controls & CONTROL_RI) bgcolor = "#ff5555";
ramtext += `<span style="background-color: ${bgcolor}">`;
}
ramtext += formatHex(ram[(a)+b],4) + " ";
if (cpu.ADDRBUS === (a)+b) ramtext += '</span>';
}
ramtext += "<br />";
}
@ -116,7 +130,7 @@ function printRAM(ram) {
let sp_stackram = document.getElementById("STACK-RAM");
ramtext = "ADDR&nbsp;&nbsp;:&nbsp;&nbsp;&nbsp;0&nbsp;&nbsp;&nbsp;&nbsp;1&nbsp;&nbsp;&nbsp;&nbsp;2&nbsp;&nbsp;&nbsp;&nbsp;3&nbsp;&nbsp;&nbsp;&nbsp;4&nbsp;&nbsp;&nbsp;&nbsp;5&nbsp;&nbsp;&nbsp;&nbsp;6&nbsp;&nbsp;&nbsp;&nbsp;7&nbsp;&nbsp;&nbsp;&nbsp;8&nbsp;&nbsp;&nbsp;&nbsp;9&nbsp;&nbsp;&nbsp;&nbsp;A&nbsp;&nbsp;&nbsp;&nbsp;B&nbsp;&nbsp;&nbsp;&nbsp;C&nbsp;&nbsp;&nbsp;&nbsp;D&nbsp;&nbsp;&nbsp;&nbsp;E&nbsp;&nbsp;&nbsp;&nbsp;F<br />";
for (let a = 0xffa0; a < 0x10000; a+=16) {
for (let a = 0xffe0; a < 0x10000; a+=16) {
ramtext += "0x" + formatHex(a,4) + ": ";
for (let b = 0; b < 16; b++) {
if (cpu.ADDRBUS === (a)+b) ramtext += '<span style="background-color: #ffff55">';
@ -283,7 +297,7 @@ class CPU_8SA1 {
OUTMUX |= (this.MC_Controls & CONTROL_OEM0) ? 0b00001 : 0;
if (OUTMUX === OECONTROL_RO) {
console.log("DATABUS = RAM");
//console.log("DATABUS = RAM");
this.DATABUS = this.RAM[this.ADDRBUS];
if (this.DATABUS === undefined) this.DATABUS = 0;
}
@ -322,12 +336,12 @@ class CPU_8SA1 {
let MC_Controls = this.MCRAM[mcra];
if (MC_Controls & CONTROL_MCL0) this.MCC = 0;
if (MC_Controls & CONTROL_MCL8) this.MCC = 8;
if (MC_Controls & CONTROL_MCL0) console.log(`Reset microcode counter to 0`);
if (MC_Controls & CONTROL_MCL8) console.log(`Reset microcode counter to 8`);
//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);
MC_Controls = this.MCRAM[mcra];
if (MC_Controls === undefined) MC_Controls = 0;
console.log(`[${mcra.toString(2)}] Control Lines: ${MC_Controls.toString(2)}`);
//console.log(`[${mcra.toString(2)}] Control Lines: ${MC_Controls.toString(2)}`);
if (MC_Controls !== this.MC_Controls) {
if (MC_Controls & CONTROL_OEME) {
// Set the DATABUS based on whatever output we are controlling
@ -337,46 +351,46 @@ class CPU_8SA1 {
OUTMUX |= (MC_Controls & CONTROL_OEM1) ? 0b00010 : 0;
OUTMUX |= (MC_Controls & CONTROL_OEM0) ? 0b00001 : 0;
console.log(`OUTPUT MUX: ${OUTMUX.toString(2)}`);
//console.log(`OUTPUT MUX: ${OUTMUX.toString(2)}`);
switch (OUTMUX) {
case OECONTROL_PC: {
this.DATABUS = this.PC;
console.log("DATABUS = PC");
//console.log("DATABUS = PC");
break;
}
case OECONTROL_SP: {
this.DATABUS = this.SP;
console.log("DATABUS = SP");
//console.log("DATABUS = SP");
break;
}
case OECONTROL_AL: {
this.DATABUS = ((this.DATABUS & BITMASK_8) << 8) | (this.GPA & BITMASK_8);
console.log("DATABUS LOW = A");
//console.log("DATABUS LOW = A");
break;
}
case OECONTROL_AH: {
this.DATABUS = ((this.GPA & BITMASK_8) << 8) | (this.DATABUS & BITMASK_8);
console.log("DATABUS HIGH = A");
//console.log("DATABUS HIGH = A");
break;
}
case OECONTROL_BL: {
this.DATABUS = ((this.DATABUS & BITMASK_8) << 8) | (this.GPB & BITMASK_8);
console.log("DATABUS LOW = B");
//console.log("DATABUS LOW = B");
break;
}
case OECONTROL_BH: {
this.DATABUS = ((this.GPB & BITMASK_8) << 8) | (this.DATABUS & BITMASK_8);
console.log("DATABUS HIGH = B");
// console.log("DATABUS HIGH = B");
break;
}
case OECONTROL_CL: {
this.DATABUS = ((this.DATABUS & BITMASK_8) << 8) | (this.GPC & BITMASK_8);
console.log("DATABUS LOW = C");
//console.log("DATABUS LOW = C");
break;
}
case OECONTROL_CH: {
this.DATABUS = ((this.GPC & BITMASK_8) << 8) | (this.DATABUS & BITMASK_8);
console.log("DATABUS HIGH = C");
//console.log("DATABUS HIGH = C");
break;
}
case OECONTROL_DL: {
@ -389,7 +403,7 @@ class CPU_8SA1 {
}
case OECONTROL_AB: {
this.DATABUS = ((this.GPB & BITMASK_8) << 8) | (this.GPA & BITMASK_8);
console.log("DATABUS = AB");
//console.log("DATABUS = AB");
break;
}
case OECONTROL_AC: {
@ -437,7 +451,7 @@ class CPU_8SA1 {
break;
}
case OECONTROL_AE: {
console.log("ALU Enable");
//console.log("ALU Enable");
this.DATABUS = (this.GPB << 8) | this.GPA;
let ALU_A = this.DATABUS & BITMASK_8;
let ALU_B = (this.DATABUS & (BITMASK_8 << 8)) >> 8;
@ -446,7 +460,7 @@ class CPU_8SA1 {
let ALUMUX = (MC_Controls & CONTROL_ALUM1) ? 0b10 : 0;
ALUMUX |= (MC_Controls & CONTROL_ALUM0) ? 0b01 : 0;
console.log(`ALU: A=${ALU_A}, B=${ALU_B}, MUX: ${ALUMUX}`);
//console.log(`ALU: A=${ALU_A}, B=${ALU_B}, MUX: ${ALUMUX}`);
if (MC_Controls & CONTROL_ALUI) console.log("ALU Inverting B");
let SHIFTING = false;
if (MC_Controls & CONTROL_ALUSL) SHIFTING = true;
@ -504,17 +518,17 @@ class CPU_8SA1 {
}
case OECONTROL_AO: {
this.DATABUS = (this.DATABUS & (BITMASK_8 << 8)) | this.ALUSUM;
console.log("DATABUS = SUM");
//console.log("DATABUS = SUM");
break;
}
case OECONTROL_SR: {
this.DATABUS = ((this.DATABUS & BITMASK_8) << 8) | (this.SR & BITMASK_8);
console.log("DATABUS = STATUS REGISTER");
//console.log("DATABUS = STATUS REGISTER");
break;
}
case OECONTROL_RO: {
// We dont actually want to do anything here since ram outputs on CLK
console.log("DATABUS = RAM (on CLK)");
//console.log("DATABUS = RAM (on CLK)");
break;
}
}
@ -570,32 +584,32 @@ class CPU_8SA1 {
GPA_In_LOW_CLK() {
this.GPA = this.DATABUS & 0x00ff;
console.log(`GPA = DATABUS LOW`);
//console.log(`GPA = DATABUS LOW`);
}
GPA_In_HIGH_CLK() {
this.GPA = (this.DATABUS & 0xff00) >> 8;
console.log(`GPA = DATABUS HIGH`);
//console.log(`GPA = DATABUS HIGH`);
}
GPB_In_LOW_CLK() {
this.GPB = this.DATABUS & 0x00ff;
console.log(`GPB = DATABUS LOW`);
//console.log(`GPB = DATABUS LOW`);
}
GPB_In_HIGH_CLK() {
this.GPB = (this.DATABUS & 0xff00) >> 8;
console.log(`GPB = DATABUS HIGH`);
//console.log(`GPB = DATABUS HIGH`);
}
GPC_In_LOW_CLK() {
this.GPC = this.DATABUS & 0x00ff;
console.log(`GPC = DATABUS LOW`);
//console.log(`GPC = DATABUS LOW`);
}
GPC_In_HIGH_CLK() {
this.GPC = (this.DATABUS & 0xff00) >> 8;
console.log(`GPC = DATABUS HIGH`);
//console.log(`GPC = DATABUS HIGH`);
}
GPD_In_LOW_CLK() {

View File

@ -36,7 +36,7 @@ cpu.RAM[4] = is_CMP.Bytecode;
*/
cpu.RAM[0] = is_LDAB_i.Bytecode;
cpu.RAM[1] = 0x0050;
cpu.RAM[1] = 0x0100;
cpu.RAM[2] = is_PHAB.Bytecode;
cpu.RAM[3] = is_JSR.Bytecode;
cpu.RAM[4] = 0x00D0;
@ -89,12 +89,13 @@ cpu.RAM[0xFC] = is_RTS.Bytecode;
stringToRAM("Blackbeard420 is a Butt Fuckers",cpu.RAM,0x50);
stringToRAM("Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nunc maximus erat mollis, fermentum quam at, blandit turpis. Pellentesque arcu tortor, smoke weed guam sagittis ac, posuere ut ipsum. Nulla facilisi. Mauris eget urna id sem porttitor consequat ultrices porttitor magna. Quisque condimentum porta viverra. Suspendisse ac condimentum ante. Duis accumsan augue urna, at ultricies nunc accumsan eget. Nullam eleifend.",cpu.RAM,0x100);
updateHTML();
let btn_clk = document.getElementById("btn_clk");
let btn_runtil = document.getElementById("btn_runtil");
let brkpt = document.getElementById("addrbrk");
let clkinterval = document.getElementById("clkinterval");
let btn_rst = document.getElementById("btn_rst");
let clk_counter = document.getElementById("clk_counter");
let clk_count = 0;
@ -103,12 +104,10 @@ 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();
});
btn_runtil.addEventListener('click', function(evt) {
@ -134,5 +133,6 @@ btn_rst.addEventListener('click', function(evt) {
clk_count = 0;
clk_counter.innerText = clk_count;
updateHTML();
});
window.requestAnimationFrame(drawCPUInfo);

View File

@ -59,6 +59,15 @@ const CONTROL_ALU_XNOR = CONTROL_OUT_AE | CONTROL_ALUM1 | CONTROL_ALUM0 | CONTRO
let Instructions = new Array();
function FindInstructon(ins) {
for (let a = 0; a < Instructions.length; a++) {
if (Instructions[a].Mnemonic.toLowerCase() === ins.Instruction.toLowerCase()) {
return Instructions[a];
}
}
return false;
}
function GenerateMicrocode(mcarray,cpu) {
for (let a = 0; a < mcarray.length; a++) {