From 0209e32e98b135a5a689a28e8db06880d29bbedf Mon Sep 17 00:00:00 2001 From: leo Date: Mon, 18 Dec 2023 14:34:08 -0300 Subject: branch opcodes --- CPU.c | 37 +++++++++++++++++++++++++++++++++++++ CPU.h | 2 ++ opcode_pc.h | 26 +++++++++++++++++++++++++- 3 files changed, 64 insertions(+), 1 deletion(-) diff --git a/CPU.c b/CPU.c index b44a84c..4e7dfa1 100644 --- a/CPU.c +++ b/CPU.c @@ -2,6 +2,7 @@ #include #include #include +#include #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; } diff --git a/CPU.h b/CPU.h index 4600621..5069ab3 100644 --- a/CPU.h +++ b/CPU.h @@ -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 -- cgit v1.2.3