diff options
author | leo <leo@azuminha.com> | 2023-12-18 14:34:08 -0300 |
---|---|---|
committer | leo <leo@azuminha.com> | 2023-12-18 14:34:08 -0300 |
commit | 0209e32e98b135a5a689a28e8db06880d29bbedf (patch) | |
tree | 2526e2f771200db3dc385d26327bffbf85f1561a | |
parent | 312f231d5d3b4523a5763eb01981885d0a66b8cd (diff) |
branch opcodes
-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 |