Branch Group

Once you understand condition codes, the Branch Group is pretty straightforward. There are 2 types of branches, jumps (JMP) and calls (CALL). JMP simply sets the PC to the target address of the jump. CALL is for subroutines, it puts the return address on the stack, then sets the PC to the target address. RET returns from a CALL by getting the address off the stack and putting it in the PC.

JMP and CALL both only jump to absolute addresses which are encoded in the bytes after the opcode.

JMP

The JMP instruction unconditionally branches to the target address. There are also conditional jump instructions for all the condition codes (except AC):

Here are a few of them implemented:

        case 0xc2:                      //JNZ address    
            if (0 == state->cc.z)    
                state->pc = (opcode[2] << 8) | opcode[1];    
            else    
                // branch not taken    
                state->pc += 2;    
            break;

        case 0xc3:                      //JMP address    
            state->pc = (opcode[2] << 8) | opcode[1];    
            break;    

CALL and RET

CALL will push the address of the instruction after the call onto the stack, then jumps to the target address. RET gets an address off the stack and stores it to the PC. There are conditional versions of CALL and RET for all conditions.

        case 0xcd:                      //CALL address    
            {    
            uint16_t    ret = state->pc+2;    
            state->memory[state->sp-1] = (ret >> 8) & 0xff;    
            state->memory[state->sp-2] = (ret & 0xff);    
            state->sp = state->sp - 2;    
            state->pc = (opcode[2] << 8) | opcode[1];    
            }    
                break;

        case 0xc9:                      //RET    
            state->pc = state->memory[state->sp] | (state->memory[state->sp+1] << 8);    
            state->sp += 2;    
            break;    

Notes

← Prev: arithmetic-group   Next: logical-group →