summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorleo <leo@azuminha.com>2023-12-18 14:34:08 -0300
committerleo <leo@azuminha.com>2023-12-18 14:34:08 -0300
commit0209e32e98b135a5a689a28e8db06880d29bbedf (patch)
tree2526e2f771200db3dc385d26327bffbf85f1561a
parent312f231d5d3b4523a5763eb01981885d0a66b8cd (diff)
branch opcodes
-rw-r--r--CPU.c37
-rw-r--r--CPU.h2
-rw-r--r--opcode_pc.h26
3 files changed, 64 insertions, 1 deletions
diff --git a/CPU.c b/CPU.c
index b44a84c..4e7dfa1 100644
--- a/CPU.c
+++ b/CPU.c
@@ -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;
}
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