Skip to content

Instantly share code, notes, and snippets.

@TuckerBMorgan
Created March 25, 2018 20:07
Show Gist options
  • Select an option

  • Save TuckerBMorgan/204660d80900a3129861e11d4a13a17f to your computer and use it in GitHub Desktop.

Select an option

Save TuckerBMorgan/204660d80900a3129861e11d4a13a17f to your computer and use it in GitHub Desktop.
void branch_instructions(long opcode) {
//almost branch instructions follow the same format
//condition test
//and branch to vvvvvvvv if pass test
//for BR just always branch
//so this just preforms the correct test for each
//branch test
//and then either drops to the branch if needs to,
//or does not
//branch insustrctions have a range of values, but still follow one another
//so by testing the instruction value against the lowest possible value of
//each branch we can know which branch to go through by the one we fail to
//be above, so BXX_MIN is the value of not the insturction we are testing
//but next one up, the correct instruction will follow as a comment to the if statment
/*
NZVC
*/
//all the condition tests are flipped because we want to not
//preform the branch here, and if they do just fall to the branch
if(opcode < BNE_MIN) {//BR
//do nothing this is our BR instruction
}
else if(opcode < BEQ_MIN ) {//BNE
//bne 0010vv if( !Z ) PC <- PC + 2*vv
if(psr(2, 2) == 1) {//if( !Z )
return;
}
}
else if(opcode < BGE_MIN) {//BEQ
//beq 0014vv if( Z ) PC <- PC + 2*vv
if(psr(2, 2) == 0) {//if( Z )
return;
}
}
else if(opcode < BLT_MIN) {//BGE
//bge 0020vv if( (N ^ V) == 0 ) PC <- PC + 2*vv
if(psr(3, 3) ^ psr(1, 1) == 1){//if( (N ^ V) == 0 )
return;
}
}
else if(opcode < BGT_MIN) {//BLT
//blt 0024vv if( (N ^ V) == 1 ) PC <- PC + 2*vv
if(psr(3, 3) ^ psr(1, 1) == 0){//if( (N ^ V) == 0 )
return;
}
}
else if(opcode < BLE_MIN) {//BGT
//bgt 0030vv if( !Z & (N == V) ) PC <- PC + 2*vv
if(psr(2, 2) == 1 || (psr(3, 3) != psr(1, 1))) {//if( !Z & (N == V) )
return;
}
}
else if (opcode < BRANCH_MAX ) {//BLE
//ble 0034vv if( Z | (N != V) ) PC <- PC + 2*vv
if(psr(2, 2) == 0 && (psr(3, 3) == psr(1, 1))) {//if( !Z & (N == V) )
return;
}
}
//branch_address_bus is a shorter bus, only 8 bits, to just pull the address
branch_address_bus.IN().pullFrom(instruction_register);
//we already got the insutrction from the mdr, so we can reuse it
mdr.latchFrom(branch_address_bus.OUT());
Clock::tick();
//if the address is a negative lets keep a record of it
//the 2 * vv(lshift by 1) will kill it, so we might need to add it back later
bool is_negative = false;
if(mdr(7) == 1) {
is_negative = true;
}
//vv to XXvv
//we have to sign extend the bits from the mdr
alu.OP1().pullFrom(mdr);
alu.OP2().pullFrom(address_extention_value_8_bit);
alu.perform(BusALU::op_extendSign);
mdr.latchFrom(alu.OUT());
Clock::tick();
//2 * vv(we do this by shitting left one bit)
alu.OP1().pullFrom(mdr);
alu.OP2().pullFrom(C);
alu.perform(BusALU::op_lshift);
mdr.latchFrom(alu.OUT());
Clock::tick();
if(is_negative) {//we lose the sign of the address when we left shift the mdr, we now have to add it back to the caluclated number
alu.OP1().pullFrom(mdr);
alu.OP2().pullFrom(negative_bit_register);
alu.perform(BusALU::op_or);
mdr.latchFrom(alu.OUT());
Clock::tick();
}
//pc + (2 * vv)
alu.OP1().pullFrom(*pc_alias);
alu.OP2().pullFrom(mdr);
alu.perform(BusALU::op_add);
//pc <- pc (2 * vv)
pc_alias->latchFrom(alu.OUT());
Clock::tick();
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment