summaryrefslogtreecommitdiff
path: root/cpu.c
diff options
context:
space:
mode:
authorvin <git@vineetk.net>2024-07-03 20:40:57 -0400
committervin <git@vineetk.net>2024-07-03 20:40:57 -0400
commit4fcc8d48f4dd3f7be37d917826a148c02701d0e3 (patch)
tree40853863152e6ed58dd03c3fb7cb1106eb99025b /cpu.c
parent2236e79556053d9d59a613634433848f1f7cf513 (diff)
improve branching cycle accuracy
Diffstat (limited to 'cpu.c')
-rw-r--r--cpu.c39
1 files changed, 23 insertions, 16 deletions
diff --git a/cpu.c b/cpu.c
index df9c852..bba0ed5 100644
--- a/cpu.c
+++ b/cpu.c
@@ -1,4 +1,5 @@
#include <libgen.h>
+#include <stdbool.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
@@ -151,6 +152,20 @@ opcode_mem(enum addressing_mode mode)
return val;
}
+static void
+branch(uint16_t addr, bool cond)
+{
+ if (!cond)
+ return;
+ cycles++;
+
+ addr += regs.pc;
+ if ((regs.pc + 1) & 0xFF00 != addr & 0xFF00)
+ cycles++;
+
+ regs.pc = addr;
+}
+
void
ADC(uint16_t arg)
{
@@ -201,22 +216,19 @@ ASL(uint16_t mem)
void
BCC(uint16_t arg)
{
- if (regs.status.carry == 0)
- regs.pc += arg, cycles++;
+ branch(arg, regs.status.carry == 0);
}
void
BCS(uint16_t arg)
{
- if (regs.status.carry == 1)
- regs.pc += arg, cycles++;
+ branch(arg, regs.status.carry == 1);
}
void
BEQ(uint16_t arg)
{
- if (regs.status.zero == 1)
- regs.pc += arg, cycles++;
+ branch(arg, regs.status.zero == 1);
}
void
@@ -232,22 +244,19 @@ BIT(uint16_t arg)
void
BMI(uint16_t arg)
{
- if (regs.status.negative == 1)
- regs.pc += arg, cycles++;
+ branch(arg, regs.status.negative == 1);
}
void
BNE(uint16_t arg)
{
- if (regs.status.zero == 0)
- regs.pc += arg, cycles++;
+ branch(arg, regs.status.zero == 0);
}
void
BPL(uint16_t arg)
{
- if (regs.status.negative == 0)
- regs.pc += arg, cycles++;
+ branch(arg, regs.status.negative == 0);
}
void
@@ -263,16 +272,14 @@ BVC(uint16_t arg)
{
//regs.status.overflow = (STATUS_TO_INT() & (1 << 6)) == 0;
//if (regs.status.overflow == 0)
- if ((STATUS_TO_INT() & (1 << 6)) == 0)
- regs.pc += arg, cycles++;
+ branch(arg, (STATUS_TO_INT() & (1 << 6)) == 0);
}
void
BVS(uint16_t arg)
{
regs.status.overflow = (STATUS_TO_INT() & (1 << 6)) != 0;
- if (regs.status.overflow == 1)
- regs.pc += arg, cycles++;
+ branch(arg, regs.status.overflow == 1);
}
void