435 lines
14 KiB
JavaScript
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);
|