8SA1Sim/js/isa/branching.js

435 lines
14 KiB
JavaScript

/*
Branching and Jumping Instructions
OPCODE Range: 0x2C0:0x2FF
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 = 0x2C0;
this.Mnemonic = "BCC";
this.LongName = "Branch if Carry Clear";
this.Aliases = new Array("JNC");
this.Type = InstructionTypes.Absolute16;
this.Operands = new Array({Operand: "", Bitwidth: 16});
this.Words = 2;
this.Cycles = 4;
this.CarryWords = 2;
this.CarryCycles = 3;
this.MicrocodeCarry = new Array(16);
for (let a = 0; a < 16; a++) {
this.MicrocodeCarry[a] = this.Microcode[a];
}
this.Microcode[2] = CONTROL_OUT_PC | CONTROL_RRI;
this.Microcode[3] = CONTROL_OUT_RO | CONTROL_PCI;
this.MicrocodeCarry[2] = CONTROL_PCC; // Step over the immediate value
}
}
is_BCC_a = new IS_BCC_abs16;
Instructions.push(is_BCC_a);
class IS_BCS_abs16 extends Microcode_Instruction {
constructor(props) {
super(props);
this.UsesCarry = true;
this.Bytecode = 0x2C1;
this.Mnemonic = "BCS";
this.LongName = "Branch if Carry Set";
this.Aliases = new Array("JC");
this.Type = InstructionTypes.Absolute16;
this.Operands = new Array({Operand: "", Bitwidth: 16});
this.Words = 2;
this.Cycles = 3;
this.CarryWords = 2;
this.CarryCycles = 4;
this.MicrocodeCarry = new Array(16);
for (let a = 0; a < 16; a++) {
this.MicrocodeCarry[a] = this.Microcode[a];
}
this.Microcode[2] = CONTROL_PCC; // Step over the immediate value
this.MicrocodeCarry[2] = CONTROL_OUT_PC | CONTROL_RRI;
this.MicrocodeCarry[3] = CONTROL_OUT_RO | CONTROL_PCI;
}
}
is_BCS_a = new IS_BCS_abs16;
Instructions.push(is_BCS_a);
class IS_BEQ_abs16 extends Microcode_Instruction {
constructor(props) {
super(props);
this.UsesZero = true;
this.Bytecode = 0x2C4;
this.Mnemonic = "BEQ";
this.LongName = "Branch if Equal";
this.Aliases = new Array("JE","JZ");
this.Type = InstructionTypes.Absolute16;
this.Operands = new Array({Operand: "", Bitwidth: 16});
this.Words = 2;
this.Cycles = 3;
this.ZeroWords = 2;
this.ZeroCycles = 4;
this.MicrocodeZero = new Array(16);
for (let a = 0; a < 16; a++) {
this.MicrocodeZero[a] = this.Microcode[a];
}
this.Microcode[2] = CONTROL_PCC; // Step over the immediate value
this.MicrocodeZero[2] = CONTROL_OUT_PC | CONTROL_RRI;
this.MicrocodeZero[3] = CONTROL_OUT_RO | CONTROL_PCI;
}
}
is_BEQ_a = new IS_BEQ_abs16;
Instructions.push(is_BEQ_a);
class IS_BNE_abs16 extends Microcode_Instruction {
constructor(props) {
super(props);
this.UsesZero = true;
this.Bytecode = 0x2C5;
this.Mnemonic = "BNE";
this.LongName = "Branch if NOT Equal";
this.Aliases = new Array("JNE","JNZ");
this.Type = InstructionTypes.Absolute16;
this.Operands = new Array({Operand: "", Bitwidth: 16});
this.Words = 2;
this.Cycles = 4;
this.ZeroWords = 2;
this.ZeroCycles = 3;
this.MicrocodeZero = new Array(16);
for (let a = 0; a < 16; a++) {
this.MicrocodeZero[a] = this.Microcode[a];
}
this.MicrocodeZero[2] = CONTROL_PCC; // Step over the immediate value
this.Microcode[2] = CONTROL_OUT_PC | CONTROL_RRI;
this.Microcode[3] = CONTROL_OUT_RO | CONTROL_PCI;
}
}
is_BNE_a = new IS_BNE_abs16;
Instructions.push(is_BNE_a);
class IS_BGT_abs16 extends Microcode_Instruction {
constructor(props) {
super(props);
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.Absolute16;
this.Operands = new Array({Operand: "", Bitwidth: 16});
this.Words = 2;
this.Cycles = 6;
this.Microcode[2] = CONTROL_OUT_SP | CONTROL_RRI;
this.Microcode[3] = CONTROL_OUT_PC | CONTROL_RI | CONTROL_SPD | CONTROL_SPC;
this.Microcode[4] = CONTROL_OUT_PC | CONTROL_RRI;
this.Microcode[5] = CONTROL_OUT_RO | CONTROL_PCI;
}
}
is_JSR_a = new IS_JSR_abs16;
Instructions.push(is_JSR_a);
class IS_RTS_abs16 extends Microcode_Instruction {
constructor(props) {
super(props);
this.Bytecode = 0x3DE;
this.Mnemonic = "RTS";
this.LongName = "RETURN from Subroutine (called with 16 bit immediate)";
this.Aliases = new Array();
this.Type = InstructionTypes.RTS16;
this.Operands = new Array();
this.Words = 1;
this.Cycles = 6;
this.Microcode[2] = CONTROL_SPC;
this.Microcode[3] = CONTROL_OUT_SP | CONTROL_RRI;
this.Microcode[4] = CONTROL_OUT_RO | CONTROL_PCI;
this.Microcode[5] = CONTROL_PCC;
}
}
is_RTS_a = new IS_RTS_abs16;
Instructions.push(is_RTS_a);
class IS_JSR_abs24 extends Microcode_Instruction {
constructor(props) {
super(props);
this.Bytecode = 0x2DF;
this.Mnemonic = "JSR";
this.LongName = "JUMP to Subroutine";
this.Aliases = new Array();
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;
this.Microcode[3] = CONTROL_OUT_PC | CONTROL_RI | CONTROL_SPD | CONTROL_SPC;
this.Microcode[4] = CONTROL_OUT_SP | CONTROL_RRI;
this.Microcode[5] = CONTROL_OUT_HO | CONTROL_RI | CONTROL_SPD | CONTROL_SPC;
this.Microcode[6] = CONTROL_OUT_PC | CONTROL_RRI;
this.Microcode[7] = CONTROL_OUT_I2 | CONTROL_PCC;
this.Microcode[8] = CONTROL_OUT_PC | CONTROL_RRI;
this.Microcode[9] = CONTROL_OUT_RO | CONTROL_PCI;
this.Microcode[10] = CONTROL_OUT_2O | CONTROL_RHI;
}
}
is_JSR_a24 = new IS_JSR_abs24;
Instructions.push(is_JSR_a24);
class IS_RTS_abs24 extends Microcode_Instruction {
constructor(props) {
super(props);
this.Bytecode = 0x3DF;
this.Mnemonic = "RTS";
this.LongName = "RETURN from Subroutine (called with 24 bit immediate)";
this.Aliases = new Array();
this.Type = InstructionTypes.RTS24;
this.Operands = new Array();
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_RTS_a24 = new IS_RTS_abs24;
Instructions.push(is_RTS_a24);