Working on ISA documentation
This commit is contained in:
parent
875a69fad6
commit
d21c723894
@ -1,6 +1,6 @@
|
||||
<html>
|
||||
<head>
|
||||
<title>MatCat's 8SA1 CPU Simulator</title>
|
||||
<title>MatCat's 8SA1 CPU Emulator</title>
|
||||
</head>
|
||||
<body style="font-family: monospace; font-size: 1.5em;">
|
||||
<div>
|
||||
@ -56,6 +56,7 @@
|
||||
<span>RAM (STACK): </span><br /><span id="STACK-RAM"></span>
|
||||
</div>
|
||||
|
||||
<script src="js/defines.js"></script>
|
||||
<script src="js/cpu.js"></script>
|
||||
<script src="js/microcode_compiler.js"></script>
|
||||
<script src="js/main.js"></script>
|
||||
|
15
isa.html
Normal file
15
isa.html
Normal file
@ -0,0 +1,15 @@
|
||||
<html>
|
||||
<head>
|
||||
<title>MatCat's 8SA1 CPU ISA Documentation</title>
|
||||
</head>
|
||||
<body style="font-family: monospace; font-size: 1.5em;">
|
||||
|
||||
<div id="isa_list">
|
||||
|
||||
</div>
|
||||
<script src="js/defines.js"></script>
|
||||
<script src="js/microcode_compiler.js"></script>
|
||||
<script src="js/asm_compiler.js"></script>
|
||||
<script src="js/instruction_doc.js"></script>
|
||||
</body>
|
||||
</html>
|
125
js/cpu.js
125
js/cpu.js
@ -1,73 +1,3 @@
|
||||
// Setup a few bitmasks we can use in the code that are handy to clean inputs to registers
|
||||
const BITMASK_8 = 0x00000000000000ff;
|
||||
const BITMASK_16 = 0x000000000000ffff;
|
||||
const BITMASK_24 = 0x0000000000ffffff;
|
||||
|
||||
|
||||
|
||||
// These are the control lines that are controlled by the microcode RAM output
|
||||
const CONTROL_PCC = 0b00000000000000000000000000000001; // PC CLK UP
|
||||
const CONTROL_PCI = 0b00000000000000000000000000000010; // PC Input Enable
|
||||
const CONTROL_SPD = 0b00000000000000000000000000000100; // SP Count Down
|
||||
const CONTROL_SPC = 0b00000000000000000000000000001000; // SP CLK (UP / DOWN)
|
||||
const CONTROL_SPI = 0b00000000000000000000000000010000; // SP Input Enable
|
||||
const CONTROL_RAIL = 0b00000000000000000000000000100000; // GPA LOW Input Enable
|
||||
const CONTROL_RAIH = 0b00000000000000000000000001000000; // GPA HIGH Input Enable
|
||||
const CONTROL_RBIL = 0b00000000000000000000000010000000; // GPB LOW Input Enable
|
||||
const CONTROL_RBIH = 0b00000000000000000000000100000000; // GPB HIGH Input Enable
|
||||
const CONTROL_RCIL = 0b00000000000000000000001000000000; // GPC LOW Input Enable
|
||||
const CONTROL_RCIH = 0b00000000000000000000010000000000; // GPC HIGH Input Enable
|
||||
const CONTROL_RDIL = 0b00000000000000000000100000000000; // GPD LOW Input Enable
|
||||
const CONTROL_RDIH = 0b00000000000000000001000000000000; // GPD HIGH Input Enable
|
||||
const CONTROL_RRI = 0b00000000000000000010000000000000; // LOW Ram Register Input Enable
|
||||
const CONTROL_RHI = 0b00000000000000000100000000000000; // HIGH Ram Register Input Enable
|
||||
const CONTROL_ALUM0 = 0b00000000000000001000000000000000; // ALU MUX 0
|
||||
const CONTROL_ALUM1 = 0b00000000000000010000000000000000; // ALU MUX 1
|
||||
const CONTROL_ALUI = 0b00000000000000100000000000000000; // ALU Invert (high side)
|
||||
const CONTROL_ALUC = 0b00000000000001000000000000000000; // ALU Carry Input
|
||||
const CONTROL_ALUSL = 0b00000000000010000000000000000000; // ALU Shift Left
|
||||
const CONTROL_ALUSR = 0b00000000000100000000000000000000; // ALU Shift Right
|
||||
const CONTROL_OEM0 = 0b00000000001000000000000000000000; // Output Enable MUX 0
|
||||
const CONTROL_OEM1 = 0b00000000010000000000000000000000; // Output Enable MUX 1
|
||||
const CONTROL_OEM2 = 0b00000000100000000000000000000000; // Output Enable MUX 2
|
||||
const CONTROL_OEM3 = 0b00000001000000000000000000000000; // Output Enable MUX 3
|
||||
const CONTROL_OEM4 = 0b00000010000000000000000000000000; // Output Enable MUX 4
|
||||
const CONTROL_OEME = 0b00000100000000000000000000000000; // Output Enable MUX Enable
|
||||
const CONTROL_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
|
||||
const CONTROL_MCL8 = 0b10000000000000000000000000000000; // Microcode Counter to 8
|
||||
|
||||
// These are the output enable control lines, they are muxed since none of them can ever be on together
|
||||
const OECONTROL_PC = 0b00000 // PC Register
|
||||
const OECONTROL_SP = 0b00001 // SP Register
|
||||
const OECONTROL_AL = 0b00010 // GPA to LOW
|
||||
const OECONTROL_AH = 0b00011 // GPA to HIGH
|
||||
const OECONTROL_BL = 0b00100 // GPB to LOW
|
||||
const OECONTROL_BH = 0b00101 // GPB to HIGH
|
||||
const OECONTROL_CL = 0b00110 // GPC to LOW
|
||||
const OECONTROL_CH = 0b00111 // GPC to HIGH
|
||||
const OECONTROL_DL = 0b01000 // GPD to LOW
|
||||
const OECONTROL_DH = 0b01001 // GPD to HIGH
|
||||
const OECONTROL_AB = 0b01010 // GPB to HIGH, GPA to LOW
|
||||
const OECONTROL_AC = 0b01011 // GPC to HIGH, GPA to LOW
|
||||
const OECONTROL_AD = 0b01100 // GPD to HIGH, GPA to LOW
|
||||
const OECONTROL_BA = 0b01101 // GPA to HIGH, GPB to LOW
|
||||
const OECONTROL_BC = 0b01110 // GPC to HIGH, GPB to LOW
|
||||
const OECONTROL_BD = 0b01111 // GPD to HIGH, GPB to LOW
|
||||
const OECONTROL_CA = 0b10000 // GPA to HIGH, GPC to LOW
|
||||
const OECONTROL_CB = 0b10001 // GPB to HIGH, GPC to LOW
|
||||
const OECONTROL_CD = 0b10010 // GPD to HIGH, GPC to LOW
|
||||
const OECONTROL_DA = 0b10011 // GPA to HIGH, GPD to LOW
|
||||
const OECONTROL_DB = 0b10100 // GPB to HIGH, GPD to LOW
|
||||
const OECONTROL_DC = 0b10101 // GPC to HIGH, GPD to LOW
|
||||
const OECONTROL_AO = 0b11101 // ALU Output to LOW
|
||||
const OECONTROL_SR = 0b11110 // Status Register to LOW
|
||||
const OECONTROL_RO = 0b11111 // RAM to DATABUS Enable
|
||||
|
||||
|
||||
|
||||
let intval = null;
|
||||
let breakpt = null;
|
||||
let ramlines = {value: 1};
|
||||
@ -78,61 +8,6 @@ function stringToRAM(rstring,ram,address) {
|
||||
}
|
||||
}
|
||||
|
||||
function reverseString(str) {
|
||||
return str.split("").reverse().join("");
|
||||
}
|
||||
|
||||
function formatHex(value,places,spaces=0) {
|
||||
let hexval = parseInt(value,10).toString(16).toUpperCase();
|
||||
if (hexval.length < places) {
|
||||
let placecount = (places - hexval.length);
|
||||
for (let a = 0; a < placecount; a++) {
|
||||
hexval = "0" + hexval;
|
||||
}
|
||||
}
|
||||
if (spaces > 0) {
|
||||
hexval = reverseString(hexval);
|
||||
let newhexval = "";
|
||||
for (let a = 0; a < hexval.length; a++) {
|
||||
newhexval += hexval.substring(a,a+1);
|
||||
if ((a % spaces) === 3 && a !== hexval.length-1) newhexval += " ";
|
||||
}
|
||||
hexval = reverseString(newhexval);
|
||||
}
|
||||
return hexval;
|
||||
}
|
||||
|
||||
function formatBinary(value,places,spaces=0,labels = false) {
|
||||
let hexval = parseInt(value,10).toString(2);
|
||||
if (hexval.length < places) {
|
||||
let placecount = (places - hexval.length);
|
||||
for (let a = 0; a < placecount; a++) {
|
||||
hexval = "0" + hexval;
|
||||
}
|
||||
}
|
||||
if (spaces > 0) {
|
||||
hexval = reverseString(hexval);
|
||||
let newhexval = "";
|
||||
for (let a = 0; a < hexval.length; a++) {
|
||||
if (labels) {
|
||||
newhexval += reverseString(`</span>`) + hexval.substring(a,a+1) + reverseString(`<span title="${labels[(places-1)-a]}">`);
|
||||
} else {
|
||||
newhexval += hexval.substring(a,a+1);
|
||||
}
|
||||
if ((a % spaces) === 3 && a !== hexval.length-1) newhexval += " ";
|
||||
}
|
||||
hexval = reverseString(newhexval);
|
||||
}
|
||||
return hexval;
|
||||
}
|
||||
|
||||
function GetMnemonic(mcarray,instruction) {
|
||||
for (let a = 0; a < mcarray.length; a++) {
|
||||
if (mcarray[a] === instruction || mcarray[a].Bytecode === instruction) {
|
||||
return mcarray[a].Mnemonic;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function generateClocks(clk_cnt) {
|
||||
for (let a = 0; a < clk_cnt; a++) {
|
||||
|
124
js/defines.js
Normal file
124
js/defines.js
Normal file
@ -0,0 +1,124 @@
|
||||
// Setup a few bitmasks we can use in the code that are handy to clean inputs to registers
|
||||
const BITMASK_8 = 0x00000000000000ff;
|
||||
const BITMASK_16 = 0x000000000000ffff;
|
||||
const BITMASK_24 = 0x0000000000ffffff;
|
||||
|
||||
|
||||
|
||||
// These are the control lines that are controlled by the microcode RAM output
|
||||
const CONTROL_PCC = 0b00000000000000000000000000000001; // PC CLK UP
|
||||
const CONTROL_PCI = 0b00000000000000000000000000000010; // PC Input Enable
|
||||
const CONTROL_SPD = 0b00000000000000000000000000000100; // SP Count Down
|
||||
const CONTROL_SPC = 0b00000000000000000000000000001000; // SP CLK (UP / DOWN)
|
||||
const CONTROL_SPI = 0b00000000000000000000000000010000; // SP Input Enable
|
||||
const CONTROL_RAIL = 0b00000000000000000000000000100000; // GPA LOW Input Enable
|
||||
const CONTROL_RAIH = 0b00000000000000000000000001000000; // GPA HIGH Input Enable
|
||||
const CONTROL_RBIL = 0b00000000000000000000000010000000; // GPB LOW Input Enable
|
||||
const CONTROL_RBIH = 0b00000000000000000000000100000000; // GPB HIGH Input Enable
|
||||
const CONTROL_RCIL = 0b00000000000000000000001000000000; // GPC LOW Input Enable
|
||||
const CONTROL_RCIH = 0b00000000000000000000010000000000; // GPC HIGH Input Enable
|
||||
const CONTROL_RDIL = 0b00000000000000000000100000000000; // GPD LOW Input Enable
|
||||
const CONTROL_RDIH = 0b00000000000000000001000000000000; // GPD HIGH Input Enable
|
||||
const CONTROL_RRI = 0b00000000000000000010000000000000; // LOW Ram Register Input Enable
|
||||
const CONTROL_RHI = 0b00000000000000000100000000000000; // HIGH Ram Register Input Enable
|
||||
const CONTROL_ALUM0 = 0b00000000000000001000000000000000; // ALU MUX 0
|
||||
const CONTROL_ALUM1 = 0b00000000000000010000000000000000; // ALU MUX 1
|
||||
const CONTROL_ALUI = 0b00000000000000100000000000000000; // ALU Invert (high side)
|
||||
const CONTROL_ALUC = 0b00000000000001000000000000000000; // ALU Carry Input
|
||||
const CONTROL_ALUSL = 0b00000000000010000000000000000000; // ALU Shift Left
|
||||
const CONTROL_ALUSR = 0b00000000000100000000000000000000; // ALU Shift Right
|
||||
const CONTROL_OEM0 = 0b00000000001000000000000000000000; // Output Enable MUX 0
|
||||
const CONTROL_OEM1 = 0b00000000010000000000000000000000; // Output Enable MUX 1
|
||||
const CONTROL_OEM2 = 0b00000000100000000000000000000000; // Output Enable MUX 2
|
||||
const CONTROL_OEM3 = 0b00000001000000000000000000000000; // Output Enable MUX 3
|
||||
const CONTROL_OEM4 = 0b00000010000000000000000000000000; // Output Enable MUX 4
|
||||
const CONTROL_OEME = 0b00000100000000000000000000000000; // Output Enable MUX Enable
|
||||
const CONTROL_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
|
||||
const CONTROL_MCL8 = 0b10000000000000000000000000000000; // Microcode Counter to 8
|
||||
|
||||
// These are the output enable control lines, they are muxed since none of them can ever be on together
|
||||
const OECONTROL_PC = 0b00000 // PC Register
|
||||
const OECONTROL_SP = 0b00001 // SP Register
|
||||
const OECONTROL_AL = 0b00010 // GPA to LOW
|
||||
const OECONTROL_AH = 0b00011 // GPA to HIGH
|
||||
const OECONTROL_BL = 0b00100 // GPB to LOW
|
||||
const OECONTROL_BH = 0b00101 // GPB to HIGH
|
||||
const OECONTROL_CL = 0b00110 // GPC to LOW
|
||||
const OECONTROL_CH = 0b00111 // GPC to HIGH
|
||||
const OECONTROL_DL = 0b01000 // GPD to LOW
|
||||
const OECONTROL_DH = 0b01001 // GPD to HIGH
|
||||
const OECONTROL_AB = 0b01010 // GPB to HIGH, GPA to LOW
|
||||
const OECONTROL_AC = 0b01011 // GPC to HIGH, GPA to LOW
|
||||
const OECONTROL_AD = 0b01100 // GPD to HIGH, GPA to LOW
|
||||
const OECONTROL_BA = 0b01101 // GPA to HIGH, GPB to LOW
|
||||
const OECONTROL_BC = 0b01110 // GPC to HIGH, GPB to LOW
|
||||
const OECONTROL_BD = 0b01111 // GPD to HIGH, GPB to LOW
|
||||
const OECONTROL_CA = 0b10000 // GPA to HIGH, GPC to LOW
|
||||
const OECONTROL_CB = 0b10001 // GPB to HIGH, GPC to LOW
|
||||
const OECONTROL_CD = 0b10010 // GPD to HIGH, GPC to LOW
|
||||
const OECONTROL_DA = 0b10011 // GPA to HIGH, GPD to LOW
|
||||
const OECONTROL_DB = 0b10100 // GPB to HIGH, GPD to LOW
|
||||
const OECONTROL_DC = 0b10101 // GPC to HIGH, GPD to LOW
|
||||
const OECONTROL_AO = 0b11101 // ALU Output to LOW
|
||||
const OECONTROL_SR = 0b11110 // Status Register to LOW
|
||||
const OECONTROL_RO = 0b11111 // RAM to DATABUS Enable
|
||||
|
||||
|
||||
function reverseString(str) {
|
||||
return str.split("").reverse().join("");
|
||||
}
|
||||
|
||||
function formatHex(value,places,spaces=0) {
|
||||
let hexval = parseInt(value,10).toString(16).toUpperCase();
|
||||
if (hexval.length < places) {
|
||||
let placecount = (places - hexval.length);
|
||||
for (let a = 0; a < placecount; a++) {
|
||||
hexval = "0" + hexval;
|
||||
}
|
||||
}
|
||||
if (spaces > 0) {
|
||||
hexval = reverseString(hexval);
|
||||
let newhexval = "";
|
||||
for (let a = 0; a < hexval.length; a++) {
|
||||
newhexval += hexval.substring(a,a+1);
|
||||
if ((a % spaces) === 3 && a !== hexval.length-1) newhexval += " ";
|
||||
}
|
||||
hexval = reverseString(newhexval);
|
||||
}
|
||||
return hexval;
|
||||
}
|
||||
|
||||
function formatBinary(value,places,spaces=0,labels = false) {
|
||||
let hexval = parseInt(value,10).toString(2);
|
||||
if (hexval.length < places) {
|
||||
let placecount = (places - hexval.length);
|
||||
for (let a = 0; a < placecount; a++) {
|
||||
hexval = "0" + hexval;
|
||||
}
|
||||
}
|
||||
if (spaces > 0) {
|
||||
hexval = reverseString(hexval);
|
||||
let newhexval = "";
|
||||
for (let a = 0; a < hexval.length; a++) {
|
||||
if (labels) {
|
||||
newhexval += reverseString(`</span>`) + hexval.substring(a,a+1) + reverseString(`<span title="${labels[(places-1)-a]}">`);
|
||||
} else {
|
||||
newhexval += hexval.substring(a,a+1);
|
||||
}
|
||||
if ((a % spaces) === 3 && a !== hexval.length-1) newhexval += " ";
|
||||
}
|
||||
hexval = reverseString(newhexval);
|
||||
}
|
||||
return hexval;
|
||||
}
|
||||
|
||||
function GetMnemonic(mcarray,instruction) {
|
||||
for (let a = 0; a < mcarray.length; a++) {
|
||||
if (mcarray[a] === instruction || mcarray[a].Bytecode === instruction) {
|
||||
return mcarray[a].Mnemonic;
|
||||
}
|
||||
}
|
||||
}
|
72
js/instruction_doc.js
Normal file
72
js/instruction_doc.js
Normal file
@ -0,0 +1,72 @@
|
||||
let isalist = document.getElementById("isa_list");
|
||||
|
||||
let ISAPrepList = new Array();
|
||||
|
||||
function hasInstruction(ins) {
|
||||
for (let a = 0; a < ISAPrepList.length; a++) {
|
||||
if (ISAPrepList[a].Mnemonic.toLowerCase() === ins.Mnemonic.toLowerCase()) {
|
||||
return a;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
for (let a = 0; a < Instructions.length; a++) {
|
||||
if (hasInstruction(Instructions[a]) === false) {
|
||||
ISAPrepList.push({Mnemonic: Instructions[a].Mnemonic,LongName: Instructions[a].LongName,Varients: new Array(Instructions[a])});
|
||||
} else {
|
||||
console.log(`${Instructions[a].Mnemonic} IS ALREADY THERE LETS ADD TO IT`);
|
||||
ISAPrepList[hasInstruction(Instructions[a])].Varients.push(Instructions[a]);
|
||||
}
|
||||
}
|
||||
|
||||
let outHTML = "";
|
||||
for (let a = 0; a < ISAPrepList.length; a++) {
|
||||
outHTML += `<div style="width: 50%;">`;
|
||||
outHTML += `<h4>${ISAPrepList[a].Mnemonic} ${ISAPrepList[a].LongName} </h4>`;
|
||||
outHTML += `<table style="width: 100%;">`;
|
||||
outHTML += `<tr>`;
|
||||
outHTML += `<td>Address Mode</td><td>Example</td><td>Bytecode</td><td>Words</td><td>Cycles</td>`;
|
||||
outHTML += `</tr>`;
|
||||
for (let b=0; b < ISAPrepList[a].Varients.length; b++) {
|
||||
let operandtext = "";
|
||||
for (let c = 0; c < ISAPrepList[a].Varients[b].Operands.length; c++) {
|
||||
let operandresult = ISAPrepList[a].Varients[b].Operands[c].Operand;
|
||||
let ogor = operandresult;
|
||||
if (operandresult === "#") operandresult = "";
|
||||
if (operandresult === "$" || operandresult === "") {
|
||||
switch (Math.floor(Math.random() * 9)) {
|
||||
case 0:
|
||||
case 1:
|
||||
case 2:
|
||||
case 3: {
|
||||
operandresult = ((ogor === "#") ? "" : ogor) + formatHex(Math.floor(Math.random() * (2 ** ISAPrepList[a].Varients[b].Operands[c].Bitwidth)), ((ISAPrepList[a].Varients[b].Operands[c].Bitwidth === 16) ? 4 : 2)) + "h";
|
||||
break;
|
||||
}
|
||||
case 4:
|
||||
case 5:
|
||||
case 6:
|
||||
case 7: {
|
||||
operandresult = ((ogor === "#") ? "" : ogor) + Math.floor(Math.random() * (2 ** ISAPrepList[a].Varients[b].Operands[c].Bitwidth));
|
||||
break;
|
||||
}
|
||||
case 8: {
|
||||
operandresult = ((ogor === "#") ? "" : ogor) + "MyVar";
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (ogor === "#") operandresult = "[" + operandresult + "]";
|
||||
|
||||
operandtext += ` ${operandresult},`;
|
||||
}
|
||||
operandtext = operandtext.substring(0,operandtext.length-1);
|
||||
outHTML += `<tr>`;
|
||||
outHTML += `<td>${ISAPrepList[a].Varients[b].Type}</td><td>${ISAPrepList[a].Mnemonic}${operandtext}</td><td>0x${formatHex(ISAPrepList[a].Varients[b].Bytecode,4)}</td><td>${ISAPrepList[a].Varients[b].Words}</td><td>${ISAPrepList[a].Varients[b].Cycles}</td>`;
|
||||
outHTML += `</tr>`;
|
||||
}
|
||||
outHTML += `</table>`;
|
||||
outHTML += `</div>`;
|
||||
}
|
||||
|
||||
isalist.innerHTML = outHTML;
|
@ -16,7 +16,7 @@ cpu.RAM[0xD3] = is_LDAB_i.Bytecode;
|
||||
cpu.RAM[0xD4] = 0x8000;
|
||||
cpu.RAM[0xD5] = is_PHAB.Bytecode;
|
||||
cpu.RAM[0xD6] = is_LDAB_GPCD.Bytecode; // printloop
|
||||
cpu.RAM[0xD7] = is_CMP_gpab.Bytecode;
|
||||
cpu.RAM[0xD7] = is_CMP.Bytecode;
|
||||
cpu.RAM[0xD8] = is_BEQ_i.Bytecode;
|
||||
cpu.RAM[0xD9] = 0x00ED;
|
||||
cpu.RAM[0xDA] = is_STAL_spin.Bytecode;
|
||||
|
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue
Block a user