WIP to branch instuctions, implementing OVERFLOW status register flag, implamented Thread Interupt feature

This commit is contained in:
MatCat 2021-04-13 01:43:35 -07:00
parent 77056cfc49
commit 24161774d9
9 changed files with 441 additions and 94 deletions

View File

@ -22,6 +22,9 @@
<div>
<span>MCC : </span><span id="MCC_Register"></span>
</div>
<div>
<span>IC&nbsp;&nbsp;: </span><span id="IC_Register"></span>
</div>
<div>
<span>CO&nbsp;&nbsp;: </span><span id="CO_Register"></span>
</div>

View File

@ -112,6 +112,8 @@ function updateHTML() {
if (cpu.MC_Controls & CONTROL_PCI) sp_pc.style.backgroundColor = "#ff5555";
let sp_mcc = document.getElementById("MCC_Register");
sp_mcc.innerText = "0x" + cpu.MCC.toString(16).toUpperCase();
let sp_ic = document.getElementById("IC_Register");
sp_ic.innerText = "0x" + cpu.IC.toString(16).toUpperCase();
let sp_co = document.getElementById("CO_Register");
sp_co.innerHTML = "0b" + formatBinary(cpu.MC_Controls,32,4,["Microcode Counter Reset to 8","Microcode Counter Reset to 0","Instruction Register Input Enable","RAM Input Enable","","Output MUX Enable","Output Enable MUX4","Output Enable MUX3","Output Enable MUX2","Output Enable MUX1","Output Enable MUX0","ALU Shift Right","ALU Shift Left","ALU Carry","ALU Invert B","ALU MUX1","ALU MUX0","RAM Address High Byte Input Enable","RAM Address Register Input Enable","GPD High Byte Input Enable","GPD Low Byte Input Enable","GPC High Byte Input Enable","GPC Low Byte Input Enable","GPB High Byte Input Enable","GPB Low Byte Input Enable","GPA High Byte Input Enable","GPA Low Byte Input Enable","SP Input Enable","SP Counter Clock","SP Decrement","PC Input Enable","PC Increment"]);
let sp_sp = document.getElementById("SP_Register");
@ -121,7 +123,7 @@ function updateHTML() {
if (cpu.MC_Controls & CONTROL_SPD) sp_sp.style.backgroundColor = "#7777ff";
sp_sp.innerText = "0x" + formatHex(cpu.SP | cpu.SPP << 16,6);
let sp_sr = document.getElementById("SR_Register");
sp_sr.innerHTML = "0b" + formatBinary(cpu.SR,8,4,["","","","","","Negative","Zero","Carry"]);
sp_sr.innerHTML = "0b" + formatBinary(cpu.SR,8,4,["","","","","Negative","Overflow","Zero","Carry"]);
let sp_ir = document.getElementById("IR_Register");
sp_ir.innerText = `[0x${formatHex(cpu.IR,4)}] 0b` + formatBinary(cpu.IR,16,4) + " (" + GetMnemonic(Instructions,cpu.IR) + ")";
sp_ir.style.backgroundColor = "transparent";
@ -183,7 +185,8 @@ class CPU_8SA1 {
this.GPC = 0;
this.GPD = 0;
this.MCC = 0xF; // Set the microcode counter
this.MCC = 0xF; // Set the microcode counter
this.IC = 0x0; // Set Instruction Counter to 0
this.IR = 0; // Set the initial IR
this.IR2 = 0; // IR2 is used for 3 word instructions
this.MC_Controls = 0; // Set the control output lines
@ -239,6 +242,10 @@ class CPU_8SA1 {
if (this.DATABUS === undefined) this.DATABUS = 0;
this.SPP = this.DATABUS & BITMASK_8;
}
if (OUTMUX === OECONTROL_SS) {
if (this.DATABUS === undefined) this.DATABUS = 0;
this.SR = this.DATABUS & BITMASK_8;
}
}
@ -299,6 +306,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}`);
if (this.MC_Controls & CONTROL_ALUI) ALU_Result = ~ALU_Result;
if (this.MC_Controls & CONTROL_ALUC && !SHIFTING) ALU_Result += 1;
break;
@ -330,6 +338,27 @@ class CPU_8SA1 {
this.SR = this.SR & 0b11111101;
}
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));
this.SR = this.SR | 0b00000100;
}
} else {
this.SR = this.SR & 0b11111011;
}
if ((ALU_Result & 0b10000000) === 0b10000000) {
// We have a NEGATIVE
this.SR = this.SR | 0b00001000;
} else {
this.SR = this.SR & 0b11110111;
}
this.ALUSUM = ALU_Result & BITMASK_8;
}
@ -342,6 +371,15 @@ 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 (this.MCC === 0 && (this.SR & 0b10000000)) {
// The task interupt enable is set, so we will count instructions
this.IC += 1;
if (this.IC === 256) {
// Rollover, we will setup the IR to handle this
this.IC = 0;
this.IR = 0x3FE;
}
}
//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);
@ -456,6 +494,11 @@ class CPU_8SA1 {
this.DATABUS = ((this.GPC & BITMASK_8) << 8) | (this.GPD & BITMASK_8);
break;
}
case OECONTROL_TI: {
console.log(`Storing PC [${formatHex(this.PC,6)}] to SP [${formatHex(this.SP,6)}]`);
this.DATABUS = 0x7F;
break;
}
case OECONTROL_I2: {
if (OECONTROL_I2 && (MC_Controls & CONTROL_SPC)) this.ADDRBUS = (this.ADDRBUS & BITMASK_16) | (this.SPP << 16);
break;
@ -472,6 +515,10 @@ class CPU_8SA1 {
// this is done @ clock
break;
}
case OECONTROL_SS: {
this.DATABUS = ((this.DATABUS & BITMASK_8) << 8) | (this.GPA & BITMASK_8);
break;
}
case OECONTROL_AO: {
this.DATABUS = (this.DATABUS & (BITMASK_8 << 8)) | this.ALUSUM;
//console.log("DATABUS = SUM");

View File

@ -62,7 +62,7 @@ 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
// 10110
const OECONTROL_TI = 0b10110 // 10110 Fixed 0x80 to databus
// 10111
const OECONTROL_I2 = 0b11000 // RAM Out, IR2 In
const OECONTROL_2O = 0b11001 // IR2 Out
@ -95,6 +95,7 @@ const CONTROL_OUT_CD = CONTROL_OEME | CONTROL_OEM4 | CONTROL_OEM1;
const CONTROL_OUT_DA = CONTROL_OEME | CONTROL_OEM4 | CONTROL_OEM1 | CONTROL_OEM0;
const CONTROL_OUT_DB = CONTROL_OEME | CONTROL_OEM4 | CONTROL_OEM2;
const CONTROL_OUT_DC = CONTROL_OEME | CONTROL_OEM4 | CONTROL_OEM2 | CONTROL_OEM0;
const CONTROL_OUT_TI = CONTROL_OEME | CONTROL_OEM4 | CONTROL_OEM2 | CONTROL_OEM1;
const CONTROL_OUT_I2 = CONTROL_OEME | CONTROL_OEM4 | CONTROL_OEM3;
const CONTROL_OUT_2O = CONTROL_OEME | CONTROL_OEM4 | CONTROL_OEM3 | CONTROL_OEM0;
const CONTROL_OUT_HO = CONTROL_OEME | CONTROL_OEM4 | CONTROL_OEM3 | CONTROL_OEM1;

View File

@ -206,7 +206,7 @@ class IS_CMP extends Microcode_Instruction {
this.Operands = new Array({Operand: "A", Bitwidth: 8},{Operand: "B", Bitwidth: 8});
this.Words = 1;
this.Cycles = 3;
this.Microcode[2] = CONTROL_OUT_AB | CONTROL_ALU_ADD;
this.Microcode[2] = CONTROL_OUT_AB | CONTROL_ALU_SUB;
}
}
is_CMP = new IS_CMP;
@ -225,7 +225,7 @@ class IS_CMP_gpcd_abs extends Microcode_Instruction {
this.Words = 1;
this.Cycles = 4;
this.Microcode[2] = CONTROL_OUT_CD | CONTROL_RRI;
this.Microcode[3] = CONTROL_OUT_RO | CONTROL_ALU_ADD;
this.Microcode[3] = CONTROL_OUT_RO | CONTROL_ALU_SUB;
}
}
is_CMP_cda = new IS_CMP_gpcd_abs();
@ -243,7 +243,7 @@ class IS_CMP_gpc_gpd extends Microcode_Instruction {
this.Operands = new Array({Operand: "C", Bitwidth: 8},{Operand: "D", Bitwidth: 8});
this.Words = 1;
this.Cycles = 3;
this.Microcode[2] = CONTROL_OUT_CD | CONTROL_ALU_ADD;
this.Microcode[2] = CONTROL_OUT_CD | CONTROL_ALU_SUB;
}
}
is_CMP_c_d = new IS_CMP_gpc_gpd();

View File

@ -1,56 +1,41 @@
class IS_JMP_imm16 extends Microcode_Instruction {
constructor(props) {
super(props);
this.Bytecode = 0x2C0;
this.Mnemonic = "JMP";
this.LongName = "JUMP to address";
this.Aliases = new Array();
/*
Branching and Jumping Instructions
this.Type = InstructionTypes.Immediate16;
this.Operands = new Array({Operand: "$", Bitwidth: 16});
this.Words = 2;
this.Cycles = 4;
this.Microcode[2] = CONTROL_OUT_PC | CONTROL_RRI;
this.Microcode[3] = CONTROL_OUT_RO | CONTROL_PCI;
}
}
is_JMP_i = new IS_JMP_imm16;
Instructions.push(is_JMP_i);
class IS_JMP_imm24 extends Microcode_Instruction {
constructor(props) {
super(props);
this.Bytecode = 0x2C1;
this.Mnemonic = "JMP";
this.LongName = "JUMP to address";
this.Aliases = new Array();
this.Type = InstructionTypes.Immediate24;
this.Operands = new Array({Operand: "$", Bitwidth: 24});
this.Words = 3;
this.Cycles = 7;
this.Microcode[2] = CONTROL_OUT_PC | CONTROL_RRI;
this.Microcode[3] = CONTROL_OUT_I2 | CONTROL_PCC;
this.Microcode[4] = CONTROL_OUT_PC | CONTROL_RRI;
this.Microcode[5] = CONTROL_OUT_RO | CONTROL_PCI;
this.Microcode[6] = CONTROL_OUT_2O | CONTROL_RHI;
}
}
is_JMP_i24 = new IS_JMP_imm24;
Instructions.push(is_JMP_i24);
OPCODE Range: 0x2C0:0x2FF
class IS_BCC_imm extends Microcode_Instruction {
0b2xx 00 01 10 11
0b0000 BCC a16, a24, in24, re16 Carry Clear
0b0001 BCS a16, a24, in24, re16 Carry Set
0b0010 BVC a16, a24, in24, re16 Overflow Clear
0b0011 BVS a16, a24, in24, re16 Overflow Set
0b0100 BEQ a16, a24, in24, re16 Equal
0b0101 BNE a16, a24, in24, re16 NOT Equal
0b0110 BGT a16, a24, in24, re16 Greater Then (unsigned)
0b0111 BLT a16, a24, in24, re16 Less Then (unsigned)
0b1000 BGE a16, a24, in24, re16 Greater Then or Equal (unsigned)
0b1001 BLE a16, a24, in24, re16 Less Then or Equal (unsigned)
0b1010 BSG a16, a24, in24, re16 Greater Then (signed)
0b1011 BSL a16, a24, in24, re16 Less Then (signed)
0b1100 BSGE a16, a24, in24, re16 Greater Then or Equal (signed)
0b1101 BSLE a16, a24, in24, re16 Less Then or Equal (unsigned)
0b1110 JMP a16, a24, in24, re16
0b1111 JSR a16, a24, in24, re16
0x3DE:3DF RTS (a16,a24)
*/
class IS_BCC_abs16 extends Microcode_Instruction {
constructor(props) {
super(props);
this.UsesCarry = true;
this.Bytecode = 0x2C2;
this.Bytecode = 0x2C0;
this.Mnemonic = "BCC";
this.LongName = "Branch if Carry Clear";
this.Aliases = new Array("JNC");
this.Type = InstructionTypes.Immediate;
this.Operands = new Array({Operand: "$", Bitwidth: 16});
this.Type = InstructionTypes.Absolute16;
this.Operands = new Array({Operand: "", Bitwidth: 16});
this.Words = 2;
this.Cycles = 4;
this.CarryWords = 2;
@ -65,20 +50,20 @@ class IS_BCC_imm extends Microcode_Instruction {
}
}
is_BCC_i = new IS_BCC_imm;
Instructions.push(is_BCC_i);
is_BCC_a = new IS_BCC_abs16;
Instructions.push(is_BCC_a);
class IS_BCS_imm extends Microcode_Instruction {
class IS_BCS_abs16 extends Microcode_Instruction {
constructor(props) {
super(props);
this.UsesCarry = true;
this.Bytecode = 0x2C3;
this.Bytecode = 0x2C1;
this.Mnemonic = "BCS";
this.LongName = "Branch if Carry Set";
this.Aliases = new Array("JC");
this.Type = InstructionTypes.Immediate;
this.Operands = new Array({Operand: "$", Bitwidth: 16});
this.Type = InstructionTypes.Absolute16;
this.Operands = new Array({Operand: "", Bitwidth: 16});
this.Words = 2;
this.Cycles = 3;
this.CarryWords = 2;
@ -93,10 +78,10 @@ class IS_BCS_imm extends Microcode_Instruction {
}
}
is_BCS_i = new IS_BCS_imm;
Instructions.push(is_BCS_i);
is_BCS_a = new IS_BCS_abs16;
Instructions.push(is_BCS_a);
class IS_BEQ_imm extends Microcode_Instruction {
class IS_BEQ_abs16 extends Microcode_Instruction {
constructor(props) {
super(props);
this.UsesZero = true;
@ -105,8 +90,8 @@ class IS_BEQ_imm extends Microcode_Instruction {
this.LongName = "Branch if Equal";
this.Aliases = new Array("JE","JZ");
this.Type = InstructionTypes.Immediate;
this.Operands = new Array({Operand: "$", Bitwidth: 16});
this.Type = InstructionTypes.Absolute16;
this.Operands = new Array({Operand: "", Bitwidth: 16});
this.Words = 2;
this.Cycles = 3;
this.ZeroWords = 2;
@ -121,10 +106,10 @@ class IS_BEQ_imm extends Microcode_Instruction {
}
}
is_BEQ_i = new IS_BEQ_imm;
Instructions.push(is_BEQ_i);
is_BEQ_a = new IS_BEQ_abs16;
Instructions.push(is_BEQ_a);
class IS_BNE_imm extends Microcode_Instruction {
class IS_BNE_abs16 extends Microcode_Instruction {
constructor(props) {
super(props);
this.UsesZero = true;
@ -133,8 +118,8 @@ class IS_BNE_imm extends Microcode_Instruction {
this.LongName = "Branch if NOT Equal";
this.Aliases = new Array("JNE","JNZ");
this.Type = InstructionTypes.Immediate;
this.Operands = new Array({Operand: "$", Bitwidth: 16});
this.Type = InstructionTypes.Absolute16;
this.Operands = new Array({Operand: "", Bitwidth: 16});
this.Words = 2;
this.Cycles = 4;
this.ZeroWords = 2;
@ -149,19 +134,221 @@ class IS_BNE_imm extends Microcode_Instruction {
}
}
is_BNE_i = new IS_BNE_imm;
Instructions.push(is_BNE_i);
is_BNE_a = new IS_BNE_abs16;
Instructions.push(is_BNE_a);
class IS_JSR_imm16 extends Microcode_Instruction {
class IS_BGT_abs16 extends Microcode_Instruction {
constructor(props) {
super(props);
this.Bytecode = 0x2FC;
this.UsesZero = true;
this.UsesCarry = true;
this.Bytecode = 0x2C6;
this.Mnemonic = "BGT";
this.LongName = "Branch if Greater Then";
this.Aliases = new Array();
this.Type = InstructionTypes.Absolute16;
this.Operands = new Array({Operand: "", Bitwidth: 16});
this.Words = 2;
this.Cycles = 4;
this.CZWords = 2;
this.CZCycles = 3;
this.ZeroWords = 2;
this.CarryCycles = 3;
this.MicrocodeCZ = new Array(16);
this.MicrocodeZero = new Array(16);
this.MicrocodeCarry = new Array(16);
this.Microcode[2] = CONTROL_PCC; // Step over the immediate value
for (let a = 0; a < 16; a++) {
this.MicrocodeCZ[a] = this.Microcode[a];
this.MicrocodeZero[a] = this.Microcode[a];
this.MicrocodeCarry[a] = this.Microcode[a];
}
this.Microcode[2] = CONTROL_OUT_PC | CONTROL_RRI;
this.Microcode[3] = CONTROL_OUT_RO | CONTROL_PCI;
}
}
is_BGT_a = new IS_BGT_abs16;
Instructions.push(is_BGT_a);
class IS_BLT_abs16 extends Microcode_Instruction {
constructor(props) {
super(props);
this.UsesZero = true;
this.UsesCarry = true;
this.Bytecode = 0x2C7;
this.Mnemonic = "BLT";
this.LongName = "Branch if Less Then";
this.Aliases = new Array();
this.Type = InstructionTypes.Absolute16;
this.Operands = new Array({Operand: "", Bitwidth: 16});
this.Words = 2;
this.Cycles = 3;
this.CZWords = 2;
this.CZCycles = 3;
this.ZeroWords = 2;
this.CarryCycles = 4;
this.MicrocodeCZ = new Array(16);
this.MicrocodeZero = new Array(16);
this.MicrocodeCarry = new Array(16);
this.Microcode[2] = CONTROL_PCC; // Step over the immediate value
for (let a = 0; a < 16; a++) {
this.MicrocodeCZ[a] = this.Microcode[a];
this.MicrocodeZero[a] = this.Microcode[a];
this.MicrocodeCarry[a] = this.Microcode[a];
}
this.MicrocodeCarry[2] = CONTROL_OUT_PC | CONTROL_RRI;
this.MicrocodeCarry[3] = CONTROL_OUT_RO | CONTROL_PCI;
}
}
is_BLT_a = new IS_BLT_abs16;
Instructions.push(is_BLT_a);
class IS_BGTE_abs16 extends Microcode_Instruction {
constructor(props) {
super(props);
this.UsesZero = true;
this.UsesCarry = true;
this.Bytecode = 0x2C8;
this.Mnemonic = "BGTE";
this.LongName = "Branch if Greater Then or Equal";
this.Aliases = new Array();
this.Type = InstructionTypes.Absolute16;
this.Operands = new Array({Operand: "", Bitwidth: 16});
this.Words = 2;
this.Cycles = 4;
this.CZWords = 2;
this.CZCycles = 4;
this.ZeroWords = 2;
this.CarryCycles = 3;
this.MicrocodeCZ = new Array(16);
this.MicrocodeZero = new Array(16);
this.MicrocodeCarry = new Array(16);
this.Microcode[2] = CONTROL_PCC; // Step over the immediate value
for (let a = 0; a < 16; a++) {
this.MicrocodeCZ[a] = this.Microcode[a];
this.MicrocodeZero[a] = this.Microcode[a];
this.MicrocodeCarry[a] = this.Microcode[a];
}
this.Microcode[2] = CONTROL_OUT_PC | CONTROL_RRI;
this.Microcode[3] = CONTROL_OUT_RO | CONTROL_PCI;
this.MicrocodeZero[2] = this.Microcode[2];
this.MicrocodeZero[3] = this.Microcode[3];
}
}
is_BGTE_a = new IS_BGTE_abs16;
Instructions.push(is_BGTE_a);
class IS_BLTE_abs16 extends Microcode_Instruction {
constructor(props) {
super(props);
this.UsesZero = true;
this.UsesCarry = true;
this.Bytecode = 0x2C9;
this.Mnemonic = "BLTE";
this.LongName = "Branch if Less Then or Equal";
this.Aliases = new Array();
this.Type = InstructionTypes.Absolute16;
this.Operands = new Array({Operand: "", Bitwidth: 16});
this.Words = 2;
this.Cycles = 3;
this.CZWords = 2;
this.CZCycles = 3;
this.ZeroWords = 2;
this.CarryCycles = 4;
this.MicrocodeCZ = new Array(16);
this.MicrocodeZero = new Array(16);
this.MicrocodeCarry = new Array(16);
this.Microcode[2] = CONTROL_PCC; // Step over the immediate value
for (let a = 0; a < 16; a++) {
this.MicrocodeCZ[a] = this.Microcode[a];
this.MicrocodeZero[a] = this.Microcode[a];
this.MicrocodeCarry[a] = this.Microcode[a];
}
this.MicrocodeCarry[2] = CONTROL_OUT_PC | CONTROL_RRI;
this.MicrocodeCarry[3] = CONTROL_OUT_RO | CONTROL_PCI;
}
}
is_BLTE_a = new IS_BLTE_abs16;
Instructions.push(is_BLTE_a);
class IS_JMP_abs16 extends Microcode_Instruction {
constructor(props) {
super(props);
this.Bytecode = 0x2CE;
this.Mnemonic = "JMP";
this.LongName = "JUMP to address";
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[3] = CONTROL_OUT_RO | CONTROL_PCI;
}
}
is_JMP_a = new IS_JMP_abs16;
Instructions.push(is_JMP_a);
class IS_JMP_abs24 extends Microcode_Instruction {
constructor(props) {
super(props);
this.Bytecode = 0x2DE;
this.Mnemonic = "JMP";
this.LongName = "JUMP to address";
this.Aliases = new Array();
this.Type = InstructionTypes.Absolute24;
this.Operands = new Array({Operand: "", Bitwidth: 24});
this.Words = 3;
this.Cycles = 7;
this.Microcode[2] = CONTROL_OUT_PC | CONTROL_RRI;
this.Microcode[3] = CONTROL_OUT_I2 | CONTROL_PCC;
this.Microcode[4] = CONTROL_OUT_PC | CONTROL_RRI;
this.Microcode[5] = CONTROL_OUT_RO | CONTROL_PCI;
this.Microcode[6] = CONTROL_OUT_2O | CONTROL_RHI;
}
}
is_JMP_a24 = new IS_JMP_abs24;
Instructions.push(is_JMP_a24);
class IS_JSR_abs16 extends Microcode_Instruction {
constructor(props) {
super(props);
this.Bytecode = 0x2CF;
this.Mnemonic = "JSR";
this.LongName = "JUMP to Subroutine";
this.Aliases = new Array();
this.Type = InstructionTypes.Immediate16;
this.Operands = new Array({Operand: "$", Bitwidth: 16});
this.Type = InstructionTypes.Absolute16;
this.Operands = new Array({Operand: "", Bitwidth: 16});
this.Words = 2;
this.Cycles = 6;
this.Microcode[2] = CONTROL_OUT_SP | CONTROL_RRI;
@ -171,13 +358,13 @@ class IS_JSR_imm16 extends Microcode_Instruction {
}
}
is_JSR_i = new IS_JSR_imm16;
Instructions.push(is_JSR_i);
is_JSR_a = new IS_JSR_abs16;
Instructions.push(is_JSR_a);
class IS_RTS_paged extends Microcode_Instruction {
class IS_RTS_abs16 extends Microcode_Instruction {
constructor(props) {
super(props);
this.Bytecode = 0x2FD;
this.Bytecode = 0x3DE;
this.Mnemonic = "RTS";
this.LongName = "RETURN from Subroutine (called with 16 bit immediate)";
this.Aliases = new Array();
@ -192,20 +379,20 @@ class IS_RTS_paged extends Microcode_Instruction {
this.Microcode[5] = CONTROL_PCC;
}
}
is_RTS_paged = new IS_RTS_paged();
Instructions.push(is_RTS_paged);
is_RTS_a = new IS_RTS_abs16;
Instructions.push(is_RTS_a);
class IS_JSR_imm24 extends Microcode_Instruction {
class IS_JSR_abs24 extends Microcode_Instruction {
constructor(props) {
super(props);
this.Bytecode = 0x2FE;
this.Bytecode = 0x2DF;
this.Mnemonic = "JSR";
this.LongName = "JUMP to Subroutine";
this.Aliases = new Array();
this.Type = InstructionTypes.Immediate24;
this.Operands = new Array({Operand: "$", Bitwidth: 24});
this.Type = InstructionTypes.Absolute24;
this.Operands = new Array({Operand: "", Bitwidth: 24});
this.Words = 3;
this.Cycles = 11;
this.Microcode[2] = CONTROL_OUT_SP | CONTROL_RRI;
@ -219,13 +406,13 @@ class IS_JSR_imm24 extends Microcode_Instruction {
this.Microcode[10] = CONTROL_OUT_2O | CONTROL_RHI;
}
}
is_JSR_i24 = new IS_JSR_imm24;
Instructions.push(is_JSR_i24);
is_JSR_a24 = new IS_JSR_abs24;
Instructions.push(is_JSR_a24);
class IS_RTS extends Microcode_Instruction {
class IS_RTS_abs24 extends Microcode_Instruction {
constructor(props) {
super(props);
this.Bytecode = 0x2FF;
this.Bytecode = 0x3DF;
this.Mnemonic = "RTS";
this.LongName = "RETURN from Subroutine (called with 24 bit immediate)";
this.Aliases = new Array();
@ -243,5 +430,5 @@ class IS_RTS extends Microcode_Instruction {
this.Microcode[8] = CONTROL_PCC;
}
}
is_RTS = new IS_RTS;
Instructions.push(is_RTS);
is_RTS_a24 = new IS_RTS_abs24;
Instructions.push(is_RTS_a24);

View File

@ -1,3 +1,84 @@
class IS_STI extends Microcode_Instruction {
constructor(props) {
super(props);
this.Bytecode = 0x3E0;
this.Mnemonic = "STI";
this.LongName = "Set Thread Interrupt (2nd word MUST BE 0x80)";
this.Aliases = new Array();
this.Type = InstructionTypes.SingleWord;
this.Operands = new Array();
this.Words = 2;
this.Cycles = 12;
this.Microcode[2] = CONTROL_OUT_SP | CONTROL_RRI;
this.Microcode[3] = CONTROL_OUT_AB | CONTROL_RI;
this.Microcode[4] = CONTROL_OUT_PC | CONTROL_RRI;
this.Microcode[5] = CONTROL_OUT_RO | CONTROL_RBIL | CONTROL_PCC;
this.Microcode[6] = CONTROL_OUT_SR | CONTROL_RAIL;
this.Microcode[7] = CONTROL_OUT_AB | CONTROL_ALU_OR;
this.Microcode[8] = CONTROL_OUT_AO | CONTROL_RAIL;
this.Microcode[9] = CONTROL_OUT_SS;
this.Microcode[10] = CONTROL_OUT_SP | CONTROL_RRI;
this.Microcode[11] = CONTROL_OUT_RO | CONTROL_RAIL | CONTROL_RBIH;
}
}
is_STI = new IS_STI;
Instructions.push(is_STI);
class IS_CTI extends Microcode_Instruction {
constructor(props) {
super(props);
this.Bytecode = 0x3E1;
this.Mnemonic = "CTI";
this.LongName = "Clear Thread Interrupt (2nd word MUST BE 0x7F)";
this.Aliases = new Array();
this.Type = InstructionTypes.SingleWord;
this.Operands = new Array();
this.Words = 2;
this.Cycles = 12;
this.Microcode[2] = CONTROL_OUT_SP | CONTROL_RRI;
this.Microcode[3] = CONTROL_OUT_AB | CONTROL_RI;
this.Microcode[4] = CONTROL_OUT_PC | CONTROL_RRI;
this.Microcode[5] = CONTROL_OUT_RO | CONTROL_RBIL | CONTROL_PCC;
this.Microcode[6] = CONTROL_OUT_SR | CONTROL_RAIL;
this.Microcode[7] = CONTROL_OUT_AB | CONTROL_ALU_AND;
this.Microcode[8] = CONTROL_OUT_AO | CONTROL_RAIL;
this.Microcode[9] = CONTROL_OUT_SS;
this.Microcode[10] = CONTROL_OUT_SP | CONTROL_RRI;
this.Microcode[11] = CONTROL_OUT_RO | CONTROL_RAIL | CONTROL_RBIH;
}
}
is_CTI = new IS_CTI;
Instructions.push(is_CTI);
class IS_RTI extends Microcode_Instruction {
constructor(props) {
super(props);
this.Bytecode = 0x3FE;
this.Mnemonic = "RTI";
this.LongName = "Return from Thread Interrupt (internal instruction ONLY)";
this.Aliases = new Array();
this.Type = InstructionTypes.SingleWord;
this.Operands = new Array();
this.Words = 1;
this.Cycles = 6;
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;
}
}
is_RTI = new IS_RTI;
Instructions.push(is_RTI);
class IS_NOP extends Microcode_Instruction {
constructor(props) {
super(props);

View File

@ -1,3 +1,9 @@
/*
PULL x Instructions
OPCODE Range: 0x2A0:0x2BF
*/
class IS_PLA extends Microcode_Instruction {
constructor(props) {
super(props);

View File

@ -1,12 +1,32 @@
let cpu = new CPU_8SA1();
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_i.Bytecode;
cpu.RAM[5] = is_JSR_a.Bytecode;
cpu.RAM[6] = 0x00D0;
/*
cpu.RAM[2] = is_STI.Bytecode;
cpu.RAM[3] = 0x80;
cpu.RAM[4] = is_LDAB_i.Bytecode;
cpu.RAM[5] = 0x0100;
cpu.RAM[6] = is_PHAB.Bytecode;
cpu.RAM[7] = is_JSR_a.Bytecode;
cpu.RAM[8] = 0x00D0;
cpu.RAM[0x80] = is_CTI.Bytecode;
cpu.RAM[0x81] = 0x7F;
cpu.RAM[0x82] = is_JMP_a.Bytecode;
cpu.RAM[0x83] = 0x04;
*/
let v_printloop = 0xd9;
let v_rollover = 0xe8;
let v_return = 0xf0;
@ -24,18 +44,18 @@ cpu.RAM[0xD7] = v_displayl;
cpu.RAM[0xD8] = is_PHAB.Bytecode;
cpu.RAM[0xD9] = is_LDAB_cda.Bytecode; // printloop
cpu.RAM[0xDA] = is_CMP.Bytecode;
cpu.RAM[0xDB] = is_BEQ_i.Bytecode;
cpu.RAM[0xDB] = is_BEQ_a.Bytecode;
cpu.RAM[0xDC] = v_return;
cpu.RAM[0xDD] = is_STAL_spa24.Bytecode;
cpu.RAM[0xDE] = is_ADD_gpci.Bytecode
cpu.RAM[0xDF] = 1;
cpu.RAM[0xE0] = is_BCS_i.Bytecode;
cpu.RAM[0xE0] = is_BCS_a.Bytecode;
cpu.RAM[0xE1] = v_rollover;
cpu.RAM[0xE2] = is_PLAB.Bytecode;
cpu.RAM[0xE3] = is_ADD_gpai.Bytecode;
cpu.RAM[0xE4] = 1;
cpu.RAM[0xE5] = is_PHAB.Bytecode;
cpu.RAM[0xE6] = is_JMP_i.Bytecode;
cpu.RAM[0xE6] = is_JMP_a.Bytecode;
cpu.RAM[0xE7] = v_printloop;
cpu.RAM[0xE8] = is_ADD_gpdi.Bytecode; // rollover
cpu.RAM[0xE9] = 1;
@ -43,11 +63,11 @@ cpu.RAM[0xEA] = is_PLAB.Bytecode;
cpu.RAM[0xEB] = is_ADD_gpbi.Bytecode;
cpu.RAM[0xEC] = 1;
cpu.RAM[0xED] = is_PHAB.Bytecode;
cpu.RAM[0xEE] = is_JMP_i.Bytecode;
cpu.RAM[0xEE] = is_JMP_a.Bytecode;
cpu.RAM[0xEF] = v_printloop;
cpu.RAM[0xF0] = is_PLAB.Bytecode;
cpu.RAM[0xF1] = is_PLA.Bytecode; // return
cpu.RAM[0xF2] = is_RTS_paged.Bytecode;
cpu.RAM[0xF2] = is_RTS_a.Bytecode;
stringToRAM("Welcome to the MatCat 8SA1 Computer Simulator!\n\nThis is a full hardware simulation of the computer to allow for easy development testing. It is currently a heavy work in progress as it is very early alpha, so check back often for new features!\n\n\nThis demo can be seen in the examples folder on the git page at: \nhttps://mygit.space/MatCat.OpenSource/8SA1Sim",cpu.RAM,0x100);

View File

@ -200,10 +200,11 @@ function GenerateMicrocode(mcarray,cpu) {
for (let a = 0; a < mcarray.length; a++) {
for (let c = 0; c < 3; c++) {
for (let c = 0; c < 4; c++) {
let offset = 0;
if (c === 1) offset = 0b1000000000000000;
if (c === 2) offset = 0b0100000000000000;
if (c === 3) offset = 0b1100000000000000;
for (let b = 0; b < 16; b++) {
let bytecode = mcarray[a].Bytecode;
@ -212,6 +213,7 @@ function GenerateMicrocode(mcarray,cpu) {
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];
cpu.MCRAM[offset + mca] = mcv;
//console.log(`[${bytecode.toString(16)}] ${mca.toString(16)}: ${mcv.toString(2)}`);
}