Created
March 25, 2018 20:07
-
-
Save TuckerBMorgan/204660d80900a3129861e11d4a13a17f to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| 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