diff options
| author | vin <git@vineetk.net> | 2024-07-03 20:40:57 -0400 |
|---|---|---|
| committer | vin <git@vineetk.net> | 2024-07-03 20:40:57 -0400 |
| commit | 4fcc8d48f4dd3f7be37d917826a148c02701d0e3 (patch) | |
| tree | 40853863152e6ed58dd03c3fb7cb1106eb99025b | |
| parent | 2236e79556053d9d59a613634433848f1f7cf513 (diff) | |
improve branching cycle accuracy
| -rw-r--r-- | cpu.c | 39 |
1 files changed, 23 insertions, 16 deletions
| @@ -1,4 +1,5 @@ | |||
| 1 | #include <libgen.h> | 1 | #include <libgen.h> |
| 2 | #include <stdbool.h> | ||
| 2 | #include <stdint.h> | 3 | #include <stdint.h> |
| 3 | #include <stdio.h> | 4 | #include <stdio.h> |
| 4 | #include <stdlib.h> | 5 | #include <stdlib.h> |
| @@ -151,6 +152,20 @@ opcode_mem(enum addressing_mode mode) | |||
| 151 | return val; | 152 | return val; |
| 152 | } | 153 | } |
| 153 | 154 | ||
| 155 | static void | ||
| 156 | branch(uint16_t addr, bool cond) | ||
| 157 | { | ||
| 158 | if (!cond) | ||
| 159 | return; | ||
| 160 | cycles++; | ||
| 161 | |||
| 162 | addr += regs.pc; | ||
| 163 | if ((regs.pc + 1) & 0xFF00 != addr & 0xFF00) | ||
| 164 | cycles++; | ||
| 165 | |||
| 166 | regs.pc = addr; | ||
| 167 | } | ||
| 168 | |||
| 154 | void | 169 | void |
| 155 | ADC(uint16_t arg) | 170 | ADC(uint16_t arg) |
| 156 | { | 171 | { |
| @@ -201,22 +216,19 @@ ASL(uint16_t mem) | |||
| 201 | void | 216 | void |
| 202 | BCC(uint16_t arg) | 217 | BCC(uint16_t arg) |
| 203 | { | 218 | { |
| 204 | if (regs.status.carry == 0) | 219 | branch(arg, regs.status.carry == 0); |
| 205 | regs.pc += arg, cycles++; | ||
| 206 | } | 220 | } |
| 207 | 221 | ||
| 208 | void | 222 | void |
| 209 | BCS(uint16_t arg) | 223 | BCS(uint16_t arg) |
| 210 | { | 224 | { |
| 211 | if (regs.status.carry == 1) | 225 | branch(arg, regs.status.carry == 1); |
| 212 | regs.pc += arg, cycles++; | ||
| 213 | } | 226 | } |
| 214 | 227 | ||
| 215 | void | 228 | void |
| 216 | BEQ(uint16_t arg) | 229 | BEQ(uint16_t arg) |
| 217 | { | 230 | { |
| 218 | if (regs.status.zero == 1) | 231 | branch(arg, regs.status.zero == 1); |
| 219 | regs.pc += arg, cycles++; | ||
| 220 | } | 232 | } |
| 221 | 233 | ||
| 222 | void | 234 | void |
| @@ -232,22 +244,19 @@ BIT(uint16_t arg) | |||
| 232 | void | 244 | void |
| 233 | BMI(uint16_t arg) | 245 | BMI(uint16_t arg) |
| 234 | { | 246 | { |
| 235 | if (regs.status.negative == 1) | 247 | branch(arg, regs.status.negative == 1); |
| 236 | regs.pc += arg, cycles++; | ||
| 237 | } | 248 | } |
| 238 | 249 | ||
| 239 | void | 250 | void |
| 240 | BNE(uint16_t arg) | 251 | BNE(uint16_t arg) |
| 241 | { | 252 | { |
| 242 | if (regs.status.zero == 0) | 253 | branch(arg, regs.status.zero == 0); |
| 243 | regs.pc += arg, cycles++; | ||
| 244 | } | 254 | } |
| 245 | 255 | ||
| 246 | void | 256 | void |
| 247 | BPL(uint16_t arg) | 257 | BPL(uint16_t arg) |
| 248 | { | 258 | { |
| 249 | if (regs.status.negative == 0) | 259 | branch(arg, regs.status.negative == 0); |
| 250 | regs.pc += arg, cycles++; | ||
| 251 | } | 260 | } |
| 252 | 261 | ||
| 253 | void | 262 | void |
| @@ -263,16 +272,14 @@ BVC(uint16_t arg) | |||
| 263 | { | 272 | { |
| 264 | //regs.status.overflow = (STATUS_TO_INT() & (1 << 6)) == 0; | 273 | //regs.status.overflow = (STATUS_TO_INT() & (1 << 6)) == 0; |
| 265 | //if (regs.status.overflow == 0) | 274 | //if (regs.status.overflow == 0) |
| 266 | if ((STATUS_TO_INT() & (1 << 6)) == 0) | 275 | branch(arg, (STATUS_TO_INT() & (1 << 6)) == 0); |
| 267 | regs.pc += arg, cycles++; | ||
| 268 | } | 276 | } |
| 269 | 277 | ||
| 270 | void | 278 | void |
| 271 | BVS(uint16_t arg) | 279 | BVS(uint16_t arg) |
| 272 | { | 280 | { |
| 273 | regs.status.overflow = (STATUS_TO_INT() & (1 << 6)) != 0; | 281 | regs.status.overflow = (STATUS_TO_INT() & (1 << 6)) != 0; |
| 274 | if (regs.status.overflow == 1) | 282 | branch(arg, regs.status.overflow == 1); |
| 275 | regs.pc += arg, cycles++; | ||
| 276 | } | 283 | } |
| 277 | 284 | ||
| 278 | void | 285 | void |
