diff options
| -rw-r--r-- | CPU.c | 37 | ||||
| -rw-r--r-- | CPU.h | 2 | ||||
| -rw-r--r-- | opcode_pc.h | 26 | 
3 files changed, 64 insertions, 1 deletions
@@ -2,6 +2,7 @@  #include <stdint.h>  #include <stdio.h>  #include <assert.h> +#include <stdbool.h>  #include "CPU.h"  #include "opcode_pc.h" @@ -170,6 +171,17 @@ void disable_flag(struct CPU *cpu, uint8_t flag){      cpu->status &= !flag;  } +int test_flag(struct CPU *cpu, uint8_t flag){ +    return (flag & cpu->status) > 0; +} + +void branch(struct CPU *cpu, bool cond){ +    if(cond){ +        int8_t jump = mem_read(cpu, cpu->pc); +        cpu->pc = (cpu->pc + jump + 1) % 0x10000; +    } +} +  void asl(struct CPU *cpu, enum adressing_mode mode){      uint16_t addr = get_operand_address(cpu, mode);      uint8_t value = mem_read(cpu, addr); @@ -222,6 +234,31 @@ void interpret(struct CPU *cpu){                      asl(cpu, OPCODE[opcode].mode);                  }                  cpu->pc += OPCODE[opcode].bytes - 1; +                break; +            case BCC: +                branch(cpu, !test_flag(cpu, CARRY)); +                break; +            case BCS: +                branch(cpu, test_flag(cpu, CARRY)); +                break; +            case BEQ: +                branch(cpu, test_flag(cpu, ZERO)); +                break; +            case BMI: +                branch(cpu, test_flag(cpu, NEGATIV)); +                break; +            case BNE: +                branch(cpu, !test_flag(cpu, ZERO)); +                break; +            case BPL: +                branch(cpu, !test_flag(cpu, NEGATIV)); +                break; +            case BVC: +                branch(cpu, !test_flag(cpu, OVERFLOW)); +                break; +            case BVS: +                branch(cpu, test_flag(cpu, OVERFLOW)); +                break;              default:                  break;          } @@ -49,7 +49,9 @@ uint16_t get_operand_address(struct CPU *cpu, enum adressing_mode mode);  void and(struct CPU *cpu, enum adressing_mode mode);  void enable_flag(struct CPU *cpu, uint8_t flag);  void disable_flag(struct CPU *cpu, uint8_t flag); +int test_flag(struct CPU *cpu, uint8_t flag);  void asl(struct CPU *cpu, enum adressing_mode mode); +void branch(struct CPU *cpu, bool cond);  #endif
\ No newline at end of file diff --git a/opcode_pc.h b/opcode_pc.h index 7a79bbe..0d79aad 100644 --- a/opcode_pc.h +++ b/opcode_pc.h @@ -11,6 +11,14 @@ enum _INSTRUCTION{      INX,      AND,      ASL, +    BCC, +    BCS, +    BEQ, +    BMI, +    BNE, +    BPL, +    BVC, +    BVS,  };  struct _OPCODE{ @@ -57,7 +65,23 @@ void init_opcode_pc(){      OPCODE[0x06] = (struct _OPCODE){ASL, ZeroPage, 2};      OPCODE[0x16] = (struct _OPCODE){ASL, ZeroPage_X, 2};      OPCODE[0x0E] = (struct _OPCODE){ASL, Absolute, 3}; -    OPCODE[0x1E] = (struct _OPCODE){ASL, Absolute_X, 3};     +    OPCODE[0x1E] = (struct _OPCODE){ASL, Absolute_X, 3};    +    /*BCC*/ +    OPCODE[0x90] = (struct _OPCODE){BCC, NoneAddressing, 2};  +    /*BCS*/ +    OPCODE[0xB0] = (struct _OPCODE){BCS, NoneAddressing, 2}; +    /*BEQ*/ +    OPCODE[0xF0] = (struct _OPCODE){BEQ, NoneAddressing, 2}; +    /*BMI*/ +    OPCODE[0x30] = (struct _OPCODE){BMI, NoneAddressing, 2}; +    /*BNE*/ +    OPCODE[0xD0] = (struct _OPCODE){BNE, NoneAddressing, 2}; +    /*BPL*/ +    OPCODE[0x10] = (struct _OPCODE){BPL, NoneAddressing, 2}; +    /*BVC*/ +    OPCODE[0x50] = (struct _OPCODE){BVC, NoneAddressing, 2}; +    /*BVS*/ +    OPCODE[0x70] = (struct _OPCODE){BVS, NoneAddressing, 2};  }  #endif
\ No newline at end of file  | 
