NESe (pronounced "Nessie") is a NES emulator based on the e6502 emulator, also written in C with a focus on speed and portability for use on embedded platforms, especially ARM.
Ви не можете вибрати більше 25 тем Теми мають розпочинатися з літери або цифри, можуть містити дефіси (-) і не повинні перевищувати 35 символів.

1640 рядки
42KB

  1. #include <stdbool.h>
  2. #include <string.h>
  3. #include "f6502.h"
  4. #include "f6502_consts.h"
  5. #ifdef F6502_TRACE
  6. #include "f6502_opcodes.h"
  7. #include <stdio.h>
  8. #endif
  9. #ifdef F6502_TEST
  10. #include <stddef.h>
  11. #define container_of(ptr, type, member) ({ \
  12. const typeof( ((type *)0)->member ) *__mptr = (ptr); \
  13. (type *)((char *)__mptr - offsetof(type,member));})
  14. #endif
  15. //#define DEBUG "Core"
  16. #include "log.h"
  17. // TOTO: Temp Hack
  18. volatile uint8_t memval;
  19. static inline uint8_t f6502_read_zp(nes_Memory* mem,
  20. uint8_t addr) {
  21. return mem->ram[addr];
  22. }
  23. static inline uint16_t f6502_read16_zp(nes_Memory* mem,
  24. uint8_t addr) {
  25. return ( f6502_read_zp(mem, addr) |
  26. ((uint16_t)f6502_read_zp(mem, addr + 1) << 8));
  27. }
  28. static inline uint8_t read_gamepad_bit(nes_Gamepad* gamepad) {
  29. uint8_t state = 1;
  30. if (gamepad->shift < 0) {
  31. state = (gamepad->buttons >> Button_A) & 1;
  32. } else if (gamepad->shift < nes_controller_num_buttons) {
  33. state = (gamepad->buttons >> gamepad->shift) & 1;
  34. gamepad->shift++;
  35. }
  36. return state;
  37. }
  38. static inline uint8_t f6502_read(nes_Memory* mem,
  39. uint16_t addr) {
  40. #ifdef F6502_FLAT
  41. #ifdef F6502_TRACE
  42. // printf("R $%04X -> %02X\n", addr, mem->ram[addr]);
  43. #endif
  44. return mem->ram[addr];
  45. #else
  46. if (addr >= 0x8000U) {
  47. return mem->rom_bank[(addr - 0x8000U) >> 13][addr & 0x1FFFU];
  48. }
  49. switch (addr & 0x6000U) {
  50. case 0x0000:
  51. return mem->ram[addr & 0x7FFU];
  52. case 0x2000:
  53. switch(addr & 0x7) {
  54. case ppu_reg_status:
  55. { uint8_t val = mem->ppu.status;
  56. mem->ppu.status &= ~ppu_Status_VBlank;
  57. mem->ppu.latch = 0;
  58. // TODO: Set nametable to 0 when in VBlank??
  59. return val;
  60. }
  61. case ppu_reg_oam_data:
  62. return mem->ppu.oam[mem->ppu.oam_addr++];
  63. case ppu_reg_data:
  64. { addr = mem->ppu.addr & 0x3FFFU;
  65. mem->ppu.addr += mem->ppu.addr_inc;
  66. uint8_t val = mem->ppu.data;
  67. mem->ppu.data = mem->ppu.bank[addr >> 10][addr & 0x3FFU];
  68. return val;
  69. }
  70. }
  71. break;
  72. case 0x4000:
  73. switch (addr & 0x1FU) {
  74. case 0x16:
  75. case 0x17:
  76. { nes_Gamepad* gamepad = &mem->input.gamepads[addr & 1];
  77. return ((addr >> 8) & nes_controller_bus_mask) |
  78. read_gamepad_bit(gamepad);
  79. } break;
  80. default:
  81. // TODO: APU Reg
  82. }
  83. break;
  84. case 0x6000:
  85. if (mem->sram_bank) {
  86. return mem->sram_bank[addr & 0x1FFFU];
  87. }
  88. }
  89. // Upper byte stays on the bus
  90. return (addr >> 8);
  91. #endif
  92. }
  93. static inline uint16_t f6502_read16(nes_Memory* mem,
  94. uint16_t addr) {
  95. return ( f6502_read(mem, addr) |
  96. ((uint16_t)f6502_read(mem, addr + 1) << 8));
  97. }
  98. static inline int f6502_write(nes_Memory* mem,
  99. uint16_t addr, uint8_t val) {
  100. int ret = 0;
  101. #ifdef F6502_TRACE
  102. printf("W $%04X <- %02X\n", addr, val);
  103. #endif
  104. #ifdef F6502_FLAT
  105. #ifdef F6502_TEST
  106. if (addr == 0xbffc) {
  107. f6502_Core* core = container_of(mem, f6502_Core, memory);
  108. int irq = val & 0b01;
  109. int nmi = val & 0b10;
  110. #ifdef F6502_TRACE
  111. if (!irq ^ !(core->interrupts & f6502_Int_IRQ)) {
  112. fprintf(stdout, "%s IRQ\n", irq ? "Set" : "Clear");
  113. }
  114. if (!nmi ^ !(core->interrupts & f6502_Int_NMI)) {
  115. fprintf(stdout, "%s NMI\n", nmi ? "Set" : "Clear");
  116. }
  117. #endif
  118. f6502_set_NMI(core, nmi);
  119. f6502_set_IRQ(core, irq);
  120. // Interrupt [may have been] triggered
  121. // We're not strictly counting cycles,
  122. // so just overload the counter
  123. ret = 1000;
  124. }
  125. #endif
  126. mem->ram[addr] = val;
  127. #else
  128. switch (addr & 0xe000) {
  129. case 0x0000:
  130. mem->ram[addr & 0x7FFU] = val;
  131. break;
  132. case 0x2000:
  133. switch (addr & 0x7U) {
  134. case ppu_reg_ctrl:
  135. mem->ppu.ctrl &= ppu_Control_Nametable_Mask;
  136. mem->ppu.ctrl |= (val & ~ppu_Control_Nametable_Mask);
  137. mem->ppu.t &= ~(ppu_Control_Nametable_Mask << 10);
  138. mem->ppu.t |= ((uint16_t)val & ppu_Control_Nametable_Mask) << 10;
  139. mem->ppu.addr_inc = (val & ppu_Control_VRAM_Inc) ? 32 : 1;
  140. // TODO: Trigger NMI if VBlank status is set?
  141. break;
  142. case ppu_reg_mask:
  143. mem->ppu.mask = val;
  144. break;
  145. case ppu_reg_oam_addr:
  146. mem->ppu.oam_addr = val;
  147. break;
  148. case ppu_reg_oam_data:
  149. mem->ppu.oam[(int)mem->ppu.oam_addr++] = val;
  150. break;
  151. case ppu_reg_scroll:
  152. if (mem->ppu.latch) {
  153. LOGI("PPU: SCROLL_Y %02X", val);
  154. mem->ppu.t &= 0b0000110000011111U;
  155. mem->ppu.t |= (uint16_t)(val & 0b00000111U) << 12;
  156. mem->ppu.t |= (uint16_t)(val & 0b11111000U) << 2;
  157. } else {
  158. LOGI("PPU: SCROLL_X %02X", val);
  159. mem->ppu.t &= ~(0b11111U);
  160. mem->ppu.t |= (val & 0b11111000U) >> 3;
  161. mem->ppu.x = (val & 0b111U);
  162. }
  163. mem->ppu.latch = !mem->ppu.latch;
  164. break;
  165. case ppu_reg_addr:
  166. if (mem->ppu.latch) {
  167. mem->ppu.t &= 0xFF00U;
  168. mem->ppu.t |= val;
  169. mem->ppu.addr = (mem->ppu.t & 0x3FFFU);
  170. // Keep ctrl & t nametable in sync
  171. mem->ppu.ctrl &= ~ppu_Control_Nametable_Mask;
  172. mem->ppu.ctrl |= ((val >> 10) & ppu_Control_Nametable_Mask);
  173. LOGI("PPU: ADDR %04X", mem->ppu.addr);
  174. } else {
  175. mem->ppu.t &= 0x00FFU;
  176. mem->ppu.t |= (uint16_t)(val & 0x3FU) << 8;
  177. }
  178. mem->ppu.latch = !mem->ppu.latch;
  179. break;
  180. case ppu_reg_data:
  181. // Disallow CHR ROM writes
  182. addr = mem->ppu.addr & 0x3FFFU;
  183. if (addr >= NES_PPU_CHR_SIZE || mem->ppu.chr_ram) {
  184. LOGI("PPU W %04X < %02X", addr, val);
  185. mem->ppu.bank[addr >> 10][addr & 0x3FFU] = val;
  186. if (addr >= NES_PPU_PAL_START) {
  187. // Copy to render reference
  188. addr &= 0x1FU;
  189. uint8_t* pal = mem->ppu.palette;
  190. if (0 == (addr & 0x3)) {
  191. // TODO: Just initialize this
  192. pal[0] = pal[4] = pal[8] = pal[12] =
  193. pal[16] = pal[20] = pal[24] =
  194. pal[28] = 0xFFU;
  195. } else {
  196. pal[addr] = val;
  197. }
  198. // Memory-mapped mirroring
  199. addr |= 0x300U;
  200. for (int mirror = 0; mirror < 0x100; mirror += 0x20) {
  201. mem->ppu.pal_bank[addr + mirror] = val;
  202. }
  203. if (0 == (addr & 3)) {
  204. for (int mirror = 0; mirror < 0x100; mirror += 0x20) {
  205. mem->ppu.pal_bank[(addr ^ 0x10U) + mirror] = val;
  206. }
  207. }
  208. }
  209. } else {
  210. LOGE("PPU W %04X < %02X : INVALID", addr, val);
  211. }
  212. mem->ppu.addr += mem->ppu.addr_inc;
  213. break;
  214. }
  215. break;
  216. case 0x4000:
  217. // TODO: APU
  218. switch (addr & 0x1FU) {
  219. case 0x14: // OAM DMA
  220. { uint8_t* src = NULL;
  221. // OAM DMA
  222. switch (val >> 5) {
  223. case 0: // 0x0000 - 0x1FFF RAM
  224. src = &mem->ram[((int)val << 8) & 0x7FFU];
  225. break;
  226. case 3: // 0x6000 - 0x7FFF SRAM
  227. if (mem->sram_bank) {
  228. src = &mem->sram_bank[((int)val << 8) & 0x1FFFU];
  229. }
  230. break;
  231. case 4: // 0x8000 - 0x9FFF ROM
  232. case 5: // 0xA000 - 0xBFFF ROM
  233. case 6: // 0xC000 - 0xDFFF ROM
  234. case 7: // 0xE000 - 0xFFFF ROM
  235. src = &mem->rom_bank[(val >> 5) & 3][((int)val << 8) & 0x1FFFU];
  236. break;
  237. }
  238. if (NULL != src) {
  239. memcpy(mem->ppu.oam, src, NES_PPU_OAM_SIZE);
  240. }
  241. ret = 513;
  242. } break;
  243. case 0x16: // Reset Gamepad
  244. if (val & 1) {
  245. mem->input.gamepads[0].shift = -1;
  246. mem->input.gamepads[1].shift = -1;
  247. } else {
  248. mem->input.gamepads[0].shift = 0;
  249. mem->input.gamepads[1].shift = 0;
  250. }
  251. break;
  252. }
  253. break;
  254. case 0x6000:
  255. if (mem->sram_bank) {
  256. mem->sram_bank[addr & 0x1FFFU] = val;
  257. mem->flags |= nes_Mem_SRAM_Used;
  258. } else if (mem->mapper.write_sram) {
  259. ret = mem->mapper.write_sram(&mem->mapper,
  260. addr, val);
  261. }
  262. }
  263. #endif
  264. return ret;
  265. }
  266. void f6502_init(f6502_Core* core) {
  267. // TODO: Nothing for now
  268. }
  269. void f6502_reset(f6502_Core* core) {
  270. core->registers.PC = f6502_read16(&core->memory,
  271. f6502_Vector_Reset),
  272. core->registers.S -= 3;
  273. core->registers.P |= (f6502_Status_B | f6502_Status_1);
  274. }
  275. void f6502_set_NMI(f6502_Core* core, bool active) {
  276. if (active) core->interrupts |= f6502_Int_NMI;
  277. else core->interrupts &= ~(f6502_Int_NMI | f6502_Int_NMI_Serviced);
  278. }
  279. void f6502_set_IRQ(f6502_Core* core, bool active) {
  280. if (active) core->interrupts |= f6502_Int_IRQ;
  281. else core->interrupts &= ~f6502_Int_IRQ;
  282. }
  283. #define PUSH(core, S, val) \
  284. f6502_write(&core->memory, f6502_Base_Stack + S--, (val))
  285. #define PUSH16(core, S, val) \
  286. PUSH(core, S, ((val) >> 8)); \
  287. PUSH(core, S, ((val) & 0xFFU))
  288. #define POP(core, S, dst) \
  289. dst = f6502_read(&core->memory, f6502_Base_Stack + ++S)
  290. #define POP16(core, S, dst) \
  291. POP(core, S, dst); \
  292. dst |= (f6502_read(&core->memory, \
  293. f6502_Base_Stack + ++S) << 8)
  294. #define CLR(R, flags) R &= ~(flags)
  295. #define SET(R, flags) R |= (flags)
  296. static inline int f6502_interrupt(f6502_Core* core,
  297. uint16_t addr) {
  298. PUSH16(core, core->registers.S, core->registers.PC);
  299. PUSH(core, core->registers.S,
  300. core->registers.P & ~f6502_Status_B);
  301. SET(core->registers.P, f6502_Status_I);
  302. core->registers.PC = f6502_read16(&core->memory, addr);
  303. return 7;
  304. }
  305. static inline bool f6502_nmi_ready(const f6502_Core* core) {
  306. return ( (core->interrupts & f6502_Int_NMI) &&
  307. !(core->interrupts & f6502_Int_NMI_Serviced));
  308. }
  309. static inline bool f6502_irq_ready(const f6502_Core* core) {
  310. return ( (core->interrupts & f6502_Int_IRQ) &&
  311. !(core->registers.P & f6502_Status_I));
  312. }
  313. static inline int f6502_check_interrupts(f6502_Core* core) {
  314. if (f6502_nmi_ready(core)) {
  315. core->interrupts |= f6502_Int_NMI_Serviced;
  316. return f6502_interrupt(core, f6502_Vector_NMI);
  317. } else if (f6502_irq_ready(core)) {
  318. return f6502_interrupt(core, f6502_Vector_IRQ);
  319. }
  320. return 0;
  321. }
  322. #define CLK(n) clocks_elapsed += n
  323. #define TEST(val) \
  324. CLR(P, f6502_Status_Z | f6502_Status_N); \
  325. SET(P, table_test[val])
  326. #define A_ABS ({ \
  327. uint16_t addr_lo = f6502_read(&core->memory, PC++); \
  328. uint16_t addr_hi = f6502_read(&core->memory, PC++); \
  329. (addr_lo | (addr_hi << 8)); \
  330. })
  331. #define A_ABSX (A_ABS + X)
  332. #define A_ABSY (A_ABS + Y)
  333. #define A_ZP f6502_read(&core->memory, PC++)
  334. #define A_ZPX (uint8_t)(f6502_read(&core->memory, PC++) + X)
  335. #define A_ZPY (uint8_t)(f6502_read(&core->memory, PC++) + Y)
  336. #define A_IX f6502_read16_zp( \
  337. &core->memory, \
  338. f6502_read(&core->memory, PC++) + X \
  339. )
  340. #define A_IY (f6502_read16_zp( \
  341. &core->memory, \
  342. f6502_read(&core->memory, PC++) \
  343. ) + Y)
  344. #define D_IMM f6502_read(&core->memory, PC++)
  345. #define D_ABS f6502_read(&core->memory, A_ABS)
  346. #define D_ABSX ({ \
  347. register uint16_t addr_base = A_ABS; \
  348. register uint16_t addr = addr_base + X; \
  349. CLK((addr_base & 0x100U) != (addr & 0x100U)); \
  350. f6502_read(&core->memory, addr); \
  351. })
  352. #define D_ABSY ({ \
  353. register uint16_t addr_base = A_ABS; \
  354. register uint16_t addr = addr_base + Y; \
  355. CLK((addr_base & 0x100U) != (addr & 0x100U)); \
  356. f6502_read(&core->memory, addr); \
  357. })
  358. #define D_ZP f6502_read_zp(&core->memory, A_ZP)
  359. #define D_ZPX f6502_read_zp(&core->memory, A_ZPX)
  360. #define D_ZPY f6502_read_zp(&core->memory, A_ZPY)
  361. #define D_IX f6502_read(&core->memory, A_IX)
  362. #define D_IY ({ \
  363. register uint16_t addr_base = f6502_read16_zp( \
  364. &core->memory, \
  365. f6502_read(&core->memory, PC++) \
  366. ); \
  367. register uint16_t addr = addr_base + Y; \
  368. CLK((addr_base & 0x100U) != (addr & 0x100U)); \
  369. f6502_read(&core->memory, addr); \
  370. })
  371. #define ADC(v) { \
  372. register uint8_t val = v; \
  373. register uint16_t res = A + val + (P & f6502_Status_C); \
  374. CLR(P, f6502_Status_N | f6502_Status_V | \
  375. f6502_Status_Z | f6502_Status_C); \
  376. SET(P, table_test[(uint8_t)res]); \
  377. SET(P, (res > 0xFFU)); \
  378. if ((~(A ^ val) & (A ^ (uint8_t)res)) & 0x80) { \
  379. SET(P, f6502_Status_V); \
  380. } \
  381. A = res; \
  382. }
  383. #define AND(v) A &= (v); TEST(A)
  384. #define ASL(a) ({ \
  385. CLR(P, f6502_Status_N | f6502_Status_Z | f6502_Status_C); \
  386. register uint16_t addr = a; \
  387. register uint8_t val = f6502_read(&core->memory, addr); \
  388. SET(P, table_asl[val]); \
  389. val <<= 1; \
  390. clocks_elapsed += f6502_write(&core->memory, addr, val); \
  391. })
  392. #define ASL_A() \
  393. CLR(P, f6502_Status_N | f6502_Status_Z | f6502_Status_C); \
  394. SET(P, table_asl[A]); \
  395. A <<= 1
  396. #ifdef F6502_HCF
  397. #define BIF_HCF() \
  398. if (pc_prev == PC + 2) { \
  399. ++PC; \
  400. clocks_elapsed = -clocks_elapsed; \
  401. goto step_done; \
  402. }
  403. #else
  404. #define BIF_HCF()
  405. #endif
  406. #define BIF(cond) \
  407. if (cond) { \
  408. register uint16_t pc_prev = PC; \
  409. PC += (int8_t)f6502_read(&core->memory, PC); \
  410. BIF_HCF(); \
  411. CLK(3 + ((pc_prev & 0x100U) != (PC & 0x100U))); \
  412. } else { \
  413. CLK(2); \
  414. } \
  415. ++PC
  416. #define BIT(v) { \
  417. register uint8_t val = (v); \
  418. CLR(P, f6502_Status_N | f6502_Status_V | f6502_Status_Z); \
  419. SET(P, (val & (f6502_Status_N | f6502_Status_V))); \
  420. if (!(val & A)) SET(P, f6502_Status_Z); \
  421. }
  422. #define CP(reg, v) { \
  423. uint16_t diff = (uint16_t)reg - (v); \
  424. CLR(P, f6502_Status_N | f6502_Status_Z | f6502_Status_C); \
  425. SET(P, table_test[diff & 0xFFU]); \
  426. if (diff < 0x100) SET(P, f6502_Status_C); \
  427. }
  428. #define DEC(a) ({ \
  429. register uint16_t addr = a; \
  430. register uint8_t val = f6502_read(&core->memory, addr); \
  431. --val; \
  432. TEST(val); \
  433. clocks_elapsed += f6502_write(&core->memory, addr, val); \
  434. })
  435. #define EOR(v) A ^= (v); TEST(A)
  436. #define INC(a) ({ \
  437. register uint16_t addr = a; \
  438. register uint8_t val = f6502_read(&core->memory, addr); \
  439. ++val; \
  440. TEST(val); \
  441. clocks_elapsed += f6502_write(&core->memory, addr, val); \
  442. })
  443. #define JMP(a) PC = (a)
  444. #define LD(reg, v) reg = (v); TEST(reg)
  445. #define LSR(a) ({ \
  446. register uint16_t addr = a; \
  447. register uint8_t val = f6502_read(&core->memory, addr); \
  448. CLR(P, f6502_Status_N | f6502_Status_Z | f6502_Status_C); \
  449. SET(P, val & f6502_Status_C); \
  450. val >>= 1; \
  451. SET(P, val & f6502_Status_N); \
  452. if (!val) SET(P, f6502_Status_Z); \
  453. clocks_elapsed += f6502_write(&core->memory, addr, val); \
  454. })
  455. #define LSR_A() \
  456. CLR(P, f6502_Status_N | f6502_Status_Z | f6502_Status_C); \
  457. SET(P, A & f6502_Status_C); \
  458. A >>= 1; \
  459. SET(P, A & f6502_Status_N); \
  460. if (!A) SET(P, f6502_Status_Z)
  461. #define ORA(v) A |= (v); TEST(A)
  462. #define ROL(a) ({ \
  463. register uint16_t addr = a; \
  464. register uint8_t val = f6502_read(&core->memory, addr); \
  465. register uint8_t new_c = (val & 0x80) ? f6502_Status_C : 0; \
  466. val = (val << 1) | (P & f6502_Status_C); \
  467. CLR(P, f6502_Status_C | f6502_Status_Z | f6502_Status_N); \
  468. P |= new_c; \
  469. if (!val) SET(P, f6502_Status_Z); \
  470. SET(P, val & f6502_Status_N); \
  471. clocks_elapsed += f6502_write(&core->memory, addr, val); \
  472. })
  473. #define ROL_A() { \
  474. register uint8_t new_c = (A & 0x80) ? f6502_Status_C : 0; \
  475. A = (A << 1) | (P & f6502_Status_C); \
  476. CLR(P, f6502_Status_C | f6502_Status_Z | f6502_Status_N); \
  477. P |= new_c; \
  478. if (!A) SET(P, f6502_Status_Z); \
  479. SET(P, A & f6502_Status_N); \
  480. }
  481. #define ROR(a) ({ \
  482. register uint16_t addr = a; \
  483. register uint8_t val = f6502_read(&core->memory, addr); \
  484. register uint8_t new_c = (val & f6502_Status_C); \
  485. val >>= 1; \
  486. if (P & f6502_Status_C) val |= f6502_Status_N; \
  487. CLR(P, f6502_Status_C | f6502_Status_Z | f6502_Status_N); \
  488. P |= new_c; \
  489. if (!val) SET(P, f6502_Status_Z); \
  490. SET(P, (val & f6502_Status_N)); \
  491. clocks_elapsed += f6502_write(&core->memory, addr, val); \
  492. })
  493. #define ROR_A() { \
  494. register uint8_t new_c = (A & f6502_Status_C); \
  495. A >>= 1; \
  496. if (P & f6502_Status_C) A |= f6502_Status_N; \
  497. CLR(P, f6502_Status_C | f6502_Status_Z | f6502_Status_N); \
  498. P |= new_c; \
  499. if (!A) SET(P, f6502_Status_Z); \
  500. SET(P, (A & f6502_Status_N)); \
  501. }
  502. #define SBC(v) { \
  503. register uint8_t val = v; \
  504. register uint16_t res = A - val - (~P & f6502_Status_C);\
  505. CLR(P, f6502_Status_N | f6502_Status_V | \
  506. f6502_Status_Z | f6502_Status_C); \
  507. SET(P, table_test[(uint8_t)res]); \
  508. SET(P, (res < 0x100U)); \
  509. if (((A ^ val) & (A ^ (uint8_t)res)) & 0x80) { \
  510. SET(P, f6502_Status_V); \
  511. } \
  512. A = res; \
  513. }
  514. #define ST(reg, a) clocks_elapsed += f6502_write(&core->memory, (a), reg)
  515. static int f6502_do_step(f6502_Core* core, int clocks) {
  516. register int clocks_elapsed = 0;
  517. register uint16_t PC = core->registers.PC;
  518. register uint8_t S = core->registers.S;
  519. register uint8_t A = core->registers.A;
  520. register uint8_t X = core->registers.X;
  521. register uint8_t Y = core->registers.Y;
  522. register uint8_t P = core->registers.P;
  523. while (clocks_elapsed < clocks) {
  524. uint8_t opcode = f6502_read(&core->memory, PC++);
  525. #ifdef F6502_TRACE
  526. printf("S:%02x A:%02x X:%02x Y:%02x P:%02x\n",
  527. S, A, X, Y, P);
  528. printf("$%04x:", (int)S + f6502_Base_Stack);
  529. for (int i = S; i < 256; ++i)
  530. printf(" %02x", (int)f6502_read(&core->memory, i + f6502_Base_Stack));
  531. putc('\n', stdout);
  532. // printf("INT %02x\n", core->interrupts);
  533. uint16_t operand = f6502_read16(&core->memory, PC);
  534. printf("$%04x: ", PC - 1);
  535. f6502_dump_instr(core, opcode, (uint8_t*)&operand);
  536. printf(" -> ");
  537. f6502_fprintf_instr(stdout, opcode, (uint8_t*)&operand);
  538. putc('\n', stdout);
  539. #endif
  540. switch (opcode) {
  541. case 0x00: // BRK
  542. ++PC;
  543. PUSH16(core, S, PC);
  544. PUSH(core, S, P | f6502_Status_B | f6502_Status_1);
  545. SET(P, f6502_Status_I);
  546. PC = f6502_read16(&core->memory, f6502_Vector_IRQ);
  547. CLK(7);
  548. break;
  549. case 0x01: // ORA (zp, X)
  550. ORA(D_IX);
  551. CLK(6);
  552. break;
  553. // Undefined: 0x02 - 0x04
  554. case 0x05: // ORA zp
  555. ORA(D_ZP);
  556. CLK(3);
  557. break;
  558. case 0x06: // ASL zp
  559. ASL(A_ZP);
  560. CLK(5);
  561. break;
  562. // Undefined: 0x07
  563. case 0x08: // PHP
  564. SET(P, f6502_Status_B);
  565. PUSH(core, S, P);
  566. CLK(3);
  567. break;
  568. case 0x09: // ORA imm
  569. ORA(D_IMM);
  570. CLK(2);
  571. break;
  572. case 0x0A: // ASL A
  573. ASL_A();
  574. CLK(2);
  575. break;
  576. // Undefined: 0x0B
  577. // Special: 0x0C
  578. case 0x0D: // ORA abs
  579. ORA(D_ABS);
  580. CLK(4);
  581. break;
  582. case 0x0E: // ASL abs
  583. ASL(A_ABS);
  584. CLK(6);
  585. break;
  586. // Undefined: 0x0F
  587. case 0x10: // BPL
  588. BIF(!(P & f6502_Status_N));
  589. break;
  590. case 0x11: // ORA (zp), Y
  591. ORA(D_IY);
  592. CLK(5);
  593. break;
  594. // Undefined: 0x12 - 0x13
  595. // Special: 0x14
  596. case 0x15: // ORA zp, X
  597. ORA(D_ZPX);
  598. CLK(4);
  599. break;
  600. case 0x16: // ASL zp, X
  601. ASL(A_ZPX);
  602. CLK(4);
  603. break;
  604. // Undefined: 0x17
  605. case 0x18: // CLC
  606. CLR(P, f6502_Status_C);
  607. CLK(2);
  608. break;
  609. case 0x19: // ORA abs, Y
  610. ORA(D_ABSY);
  611. CLK(4);
  612. break;
  613. // Special: 0x1A
  614. // Undefined: 0x1B
  615. // Special: 0x1C
  616. case 0x1D: // ORA abs, X
  617. ORA(D_ABSX);
  618. CLK(4);
  619. break;
  620. case 0x1E: // ASL abs, X
  621. ASL(A_ABSX);
  622. CLK(7);
  623. break;
  624. // Undefined: 0x1F
  625. case 0x20: // JSR
  626. { uint16_t addr_lo = f6502_read(&core->memory, PC++);
  627. uint16_t addr_hi = f6502_read(&core->memory, PC);
  628. PUSH16(core, S, PC);
  629. PC = addr_lo | (addr_hi << 8);
  630. CLK(6);
  631. } break;
  632. case 0x21: // AND (zp, X)
  633. AND(D_IX);
  634. CLK(6);
  635. break;
  636. // Undefined: 0x22 - 0x23
  637. case 0x24: // BIT zp
  638. BIT(D_ZP);
  639. CLK(3);
  640. break;
  641. case 0x25: // AND zp
  642. AND(D_ZP);
  643. CLK(3);
  644. break;
  645. case 0x26: // ROL zp
  646. ROL(A_ZP);
  647. CLK(5);
  648. break;
  649. // Undefined: 0x27
  650. case 0x28: // PLP
  651. POP(core, S, P);
  652. SET(P, f6502_Status_1 | f6502_Status_B);
  653. CLK(4);
  654. break;
  655. case 0x29: // AND imm
  656. AND(D_IMM);
  657. CLK(2);
  658. break;
  659. case 0x2A: // ROL A
  660. ROL_A();
  661. CLK(2);
  662. break;
  663. // Undefined: 0x2B
  664. case 0x2C: // BIT abs
  665. BIT(D_ABS);
  666. CLK(4);
  667. break;
  668. case 0x2D: // AND abs
  669. AND(D_ABS);
  670. CLK(4);
  671. break;
  672. case 0x2E: // ROL abs
  673. ROL(A_ABS);
  674. CLK(6);
  675. break;
  676. // Undefined: 0x2F
  677. case 0x30: // BMI
  678. BIF(P & f6502_Status_N);
  679. break;
  680. case 0x31: // AND (zp), Y
  681. AND(D_IY);
  682. CLK(5);
  683. break;
  684. // Undefined: 0x32 - 0x33
  685. // Special: 0x34
  686. case 0x35: // AND zp, X
  687. AND(D_ZPX);
  688. CLK(4);
  689. break;
  690. case 0x36: // ROL zp, X
  691. ROL(A_ZPX);
  692. CLK(6);
  693. break;
  694. // Undefined: 0x37
  695. case 0x38: // SEC
  696. SET(P, f6502_Status_C);
  697. CLK(2);
  698. break;
  699. case 0x39: // AND abs, Y
  700. AND(D_ABSY);
  701. CLK(4);
  702. break;
  703. // Special: 0x3A
  704. // Undefined: 0x3B
  705. // Special: 0x3C
  706. case 0x3D: // AND abs, X
  707. AND(D_ABSX);
  708. CLK(4);
  709. break;
  710. case 0x3E: // ROL abs, X
  711. ROL(A_ABSX);
  712. CLK(7);
  713. break;
  714. // Undefined: 0x3F
  715. case 0x40: // RTI
  716. POP(core, S, P);
  717. SET(P, f6502_Status_1 | f6502_Status_B);
  718. POP16(core, S, PC);
  719. CLK(6);
  720. // Interrupt might be triggered; break out
  721. clocks = 0;
  722. break;
  723. case 0x41: // EOR (zp, X)
  724. EOR(D_IX);
  725. CLK(6);
  726. break;
  727. // Undefined: 0x42 - 0x43
  728. // Special: 0x44
  729. case 0x45: // EOR zp
  730. EOR(D_ZP);
  731. CLK(3);
  732. break;
  733. case 0x46: // LSR zp
  734. LSR(A_ZP);
  735. CLK(5);
  736. break;
  737. // Undefined: 0x47
  738. case 0x48: // PHA
  739. PUSH(core, S, A);
  740. CLK(3);
  741. break;
  742. case 0x49: // EOR imm
  743. EOR(D_IMM);
  744. CLK(2);
  745. break;
  746. case 0x4A: // LSR A
  747. LSR_A();
  748. CLK(2);
  749. break;
  750. // Undefined: 0x4B
  751. case 0x4C: // JMP abs
  752. #ifdef F6502_HCF
  753. { uint16_t addr = A_ABS;
  754. if (PC - 3 == addr) {
  755. JMP(addr);
  756. clocks_elapsed = -clocks_elapsed;
  757. goto step_done;
  758. }
  759. JMP(addr);
  760. }
  761. #else
  762. JMP(A_ABS);
  763. #endif
  764. CLK(3);
  765. break;
  766. case 0x4D: // EOR abs
  767. EOR(D_ABS);
  768. CLK(4);
  769. break;
  770. case 0x4E: // LSR abs
  771. LSR(A_ABS);
  772. CLK(6);
  773. break;
  774. // Undefined: 0x4F
  775. case 0x50: // BVC
  776. BIF(!(P & f6502_Status_V));
  777. break;
  778. case 0x51: // EOR (zp), Y
  779. EOR(D_IY);
  780. CLK(5);
  781. break;
  782. // Undefined: 0x52 - 0x53
  783. // Special: 0x54
  784. case 0x55: // EOR zp, X
  785. EOR(D_ZPX);
  786. CLK(4);
  787. break;
  788. case 0x56: // LSR zp, X
  789. LSR(A_ZPX);
  790. CLK(6);
  791. break;
  792. // Undefined: 0x57
  793. case 0x58: // CLI
  794. { register uint8_t p_old = P;
  795. CLR(P, f6502_Status_I);
  796. CLK(2);
  797. if ( (p_old & f6502_Status_I) &&
  798. (core->interrupts & f6502_Int_IRQ)) {
  799. CLK(7);
  800. PUSH16(core, S, PC);
  801. PUSH(core, S, P & ~f6502_Status_B);
  802. SET(P, f6502_Status_I);
  803. PC = f6502_read16(&core->memory,
  804. f6502_Vector_IRQ);
  805. }
  806. } break;
  807. case 0x59: // EOR abs, Y
  808. EOR(D_ABSY);
  809. CLK(4);
  810. break;
  811. // Special: 0x5A
  812. // Undefined: 0x5B
  813. // Special: 0x5C
  814. case 0x5D: // EOR abs, X
  815. EOR(D_ABSX);
  816. CLK(4);
  817. break;
  818. case 0x5E: // LSR abs, X
  819. LSR(A_ABSX);
  820. CLK(7);
  821. break;
  822. // Undefined: 0x5F
  823. case 0x60: // RTS
  824. POP16(core, S, PC);
  825. ++PC;
  826. CLK(6);
  827. break;
  828. case 0x61: // ADC (zp, X)
  829. ADC(D_IX);
  830. CLK(6);
  831. break;
  832. // Undefined: 0x62 - 0x63
  833. // Special: 0x64
  834. case 0x65: // ADC zp
  835. ADC(D_ZP);
  836. CLK(3);
  837. break;
  838. case 0x66: // ROR zp
  839. ROR(A_ZP);
  840. CLK(5);
  841. break;
  842. // Undefined: 0x67
  843. case 0x68: // PLA
  844. POP(core, S, A);
  845. TEST(A);
  846. CLK(4);
  847. break;
  848. case 0x69: // ADC imm
  849. ADC(D_IMM);
  850. CLK(2);
  851. break;
  852. case 0x6A: // ROR A
  853. ROR_A();
  854. CLK(2);
  855. break;
  856. // Undefined: 0x6B
  857. case 0x6C: // JMP (abs)
  858. { // Reproduce the indirect addressing bug
  859. register uint16_t addr = A_ABS;
  860. register uint8_t addr_lo = f6502_read(&core->memory,
  861. addr);
  862. if ((addr & 0xFFU) == 0xFFU) {
  863. addr = f6502_read(&core->memory, addr - 0xffU);
  864. } else {
  865. addr = f6502_read(&core->memory, addr + 1);
  866. }
  867. JMP(addr_lo | (addr << 8));
  868. CLK(5);
  869. } break;
  870. case 0x6D: // ADC abs
  871. ADC(D_ABS);
  872. CLK(4);
  873. break;
  874. case 0x6E: // ROR abs
  875. ROR(A_ABS);
  876. CLK(6);
  877. break;
  878. // Undefined: 0x6F
  879. case 0x70: // BVS
  880. BIF(P & f6502_Status_V);
  881. break;
  882. case 0x71: // ADC (zp), Y
  883. ADC(D_IY);
  884. CLK(5);
  885. break;
  886. // Undefined: 0x72 - 0x73
  887. // Special: 0x74
  888. case 0x75: // ADC zp, X
  889. ADC(D_ZPX);
  890. CLK(4);
  891. break;
  892. case 0x76: // ROR zp, X
  893. ROR(A_ZPX);
  894. CLK(6);
  895. break;
  896. // Undefined: 0x77
  897. case 0x78: // SEI
  898. SET(P, f6502_Status_I);
  899. CLK(2);
  900. break;
  901. case 0x79: // ADC abs, Y
  902. ADC(D_ABSY);
  903. CLK(4);
  904. break;
  905. // Special: 0x7A
  906. // Undefined: 0x7B
  907. // Special: 0x7C
  908. case 0x7D: // ADC abs, X
  909. ADC(D_ABSX);
  910. CLK(4);
  911. break;
  912. case 0x7E: // ROR abs, X
  913. ROR(A_ABSX);
  914. CLK(7);
  915. break;
  916. // Undefined: 0x7F
  917. // Special: 0x80
  918. case 0x81: // STA (zp, X)
  919. ST(A, A_IX);
  920. CLK(6);
  921. break;
  922. // Special: 0x82
  923. // Undefined: 0x83
  924. case 0x84: // STY zp
  925. ST(Y, A_ZP);
  926. CLK(3);
  927. break;
  928. case 0x85: // STA zp
  929. ST(A, A_ZP);
  930. CLK(3);
  931. break;
  932. case 0x86: // STX zp
  933. ST(X, A_ZP);
  934. CLK(3);
  935. break;
  936. // Undefined: 0x87
  937. case 0x88: // DEY
  938. --Y;
  939. TEST(Y);
  940. CLK(2);
  941. break;
  942. // Undefined: 0x89
  943. case 0x8A: // TXA
  944. A = X;
  945. TEST(A);
  946. CLK(2);
  947. break;
  948. // Undefined: 0x8B
  949. case 0x8C: // STY abs
  950. ST(Y, A_ABS);
  951. CLK(4);
  952. break;
  953. case 0x8D: // STA abs
  954. ST(A, A_ABS);
  955. CLK(4);
  956. break;
  957. case 0x8E: // STX abs
  958. ST(X, A_ABS);
  959. CLK(4);
  960. break;
  961. case 0x90: // BCC
  962. BIF(!(P & f6502_Status_C));
  963. break;
  964. case 0x91: // STA (zp), Y
  965. ST(A, A_IY);
  966. CLK(6);
  967. break;
  968. // Undefined: 0x92 - 0x93
  969. case 0x94: // STY zp, X
  970. ST(Y, A_ZPX);
  971. CLK(4);
  972. break;
  973. case 0x95: // STA zp, X
  974. ST(A, A_ZPX);
  975. CLK(4);
  976. break;
  977. case 0x96: // STX zp, Y
  978. ST(X, A_ZPY);
  979. CLK(4);
  980. break;
  981. // Undefined: 0x97
  982. case 0x98: // TYA
  983. A = Y;
  984. TEST(A);
  985. CLK(2);
  986. break;
  987. case 0x99: // STA abs, Y
  988. ST(A, A_ABSY);
  989. CLK(5);
  990. break;
  991. case 0x9A: // TXS
  992. S = X;
  993. CLK(2);
  994. break;
  995. // Undefined: 0x9B - 0x9C
  996. case 0x9D: // STA abs, X
  997. ST(A, A_ABSX);
  998. CLK(5);
  999. break;
  1000. // Undefined: 0x9E - 0x9F
  1001. case 0xA0: // LDY imm
  1002. LD(Y, D_IMM);
  1003. CLK(2);
  1004. break;
  1005. case 0xA1: // LDA (zp, X)
  1006. LD(A, D_IX);
  1007. CLK(6);
  1008. break;
  1009. case 0xA2: // LDX imm
  1010. LD(X, D_IMM);
  1011. CLK(2);
  1012. break;
  1013. // Undefined: 0xA3
  1014. case 0xA4: // LDY zp
  1015. LD(Y, D_ZP);
  1016. CLK(3);
  1017. break;
  1018. case 0xA5: // LDA zp
  1019. LD(A, D_ZP);
  1020. CLK(3);
  1021. break;
  1022. case 0xA6: // LDX zp
  1023. LD(X, D_ZP);
  1024. CLK(3);
  1025. break;
  1026. // Undefined: 0xA7
  1027. case 0xA8: // TAY
  1028. Y = A;
  1029. TEST(A);
  1030. CLK(2);
  1031. break;
  1032. case 0xA9: // LDA imm
  1033. LD(A, D_IMM);
  1034. CLK(2);
  1035. break;
  1036. case 0xAA: // TAX
  1037. X = A;
  1038. TEST(A);
  1039. CLK(2);
  1040. break;
  1041. // Undefined: 0xAB
  1042. case 0xAC: // LDY abs
  1043. LD(Y, D_ABS);
  1044. CLK(4);
  1045. break;
  1046. case 0xAD: // LDA abs
  1047. LD(A, D_ABS);
  1048. CLK(4);
  1049. break;
  1050. case 0xAE: // LDX abs
  1051. LD(X, D_ABS);
  1052. CLK(4);
  1053. break;
  1054. // Undefined: 0xAF
  1055. case 0xB0: // BCS
  1056. BIF(P & f6502_Status_C);
  1057. break;
  1058. case 0xB1: // LDA (zp), Y
  1059. LD(A, D_IY);
  1060. CLK(5);
  1061. break;
  1062. // Undefined: 0xB2 - 0xB3
  1063. case 0xB4: // LDY zp, X
  1064. LD(Y, D_ZPX);
  1065. CLK(4);
  1066. break;
  1067. case 0xB5: // LDA zp, X
  1068. LD(A, D_ZPX);
  1069. CLK(4);
  1070. break;
  1071. case 0xB6: // LDX zp, Y
  1072. LD(X, D_ZPY);
  1073. CLK(4);
  1074. break;
  1075. // Undefined: 0xB7
  1076. case 0xB8: // CLV
  1077. CLR(P, f6502_Status_V);
  1078. CLK(2);
  1079. break;
  1080. case 0xB9: // LDA abs, Y
  1081. LD(A, D_ABSY);
  1082. CLK(4);
  1083. break;
  1084. case 0xBA: // TSX
  1085. X = S;
  1086. TEST(X);
  1087. CLK(2);
  1088. break;
  1089. // Undefined: 0xBB
  1090. case 0xBC: // LDY abs, X
  1091. LD(Y, D_ABSX);
  1092. CLK(4);
  1093. break;
  1094. case 0xBD: // LDA abs, X
  1095. LD(A, D_ABSX);
  1096. CLK(4);
  1097. break;
  1098. case 0xBE: // LDX abs, Y
  1099. LD(X, D_ABSY);
  1100. CLK(4);
  1101. break;
  1102. // Undefined: 0xBF
  1103. case 0xC0: // CPY imm
  1104. CP(Y, D_IMM);
  1105. CLK(2);
  1106. break;
  1107. case 0xC1: // CMP (zp, X)
  1108. CP(A, D_IX);
  1109. CLK(6);
  1110. break;
  1111. // Special: 0xC2
  1112. // Undefined: 0xC3
  1113. case 0xC4: // CPY zp
  1114. CP(Y, D_ZP);
  1115. CLK(3);
  1116. break;
  1117. case 0xC5: // CMP zp
  1118. CP(A, D_ZP);
  1119. CLK(3);
  1120. break;
  1121. case 0xC6: // DEC zp
  1122. DEC(A_ZP);
  1123. CLK(5);
  1124. break;
  1125. // Undefined: 0xC7
  1126. case 0xC8: // INY
  1127. ++Y;
  1128. TEST(Y);
  1129. CLK(2);
  1130. break;
  1131. case 0xC9: // CMP imm
  1132. CP(A, D_IMM);
  1133. CLK(2);
  1134. break;
  1135. case 0xCA: // DEX
  1136. --X;
  1137. TEST(X);
  1138. CLK(2);
  1139. break;
  1140. // Undefined: 0xCB
  1141. case 0xCC: // CPY abs
  1142. CP(Y, D_ABS);
  1143. CLK(4);
  1144. break;
  1145. case 0xCD: // CMP abs
  1146. CP(A, D_ABS);
  1147. CLK(4);
  1148. break;
  1149. case 0xCE: // DEC abs
  1150. DEC(A_ABS);
  1151. CLK(6);
  1152. break;
  1153. // Undefined: 0xCF
  1154. case 0xD0: // BNE
  1155. BIF(!(P & f6502_Status_Z));
  1156. break;
  1157. case 0xD1: // CMP (zp), Y
  1158. CP(A, D_IY);
  1159. CLK(5);
  1160. break;
  1161. // Undefined: 0xD2 - 0xD3
  1162. // Special: 0xD4
  1163. case 0xD5: // CMP zp, X
  1164. CP(A, D_ZPX);
  1165. CLK(4);
  1166. break;
  1167. case 0xD6: // DEC zp, X
  1168. DEC(A_ZPX);
  1169. CLK(6);
  1170. break;
  1171. // Undefined: 0xD7
  1172. case 0xD8: // CLD
  1173. CLR(P, f6502_Status_D);
  1174. CLK(2);
  1175. break;
  1176. case 0xD9: // CMP abs, Y
  1177. CP(A, D_ABSY);
  1178. CLK(4);
  1179. break;
  1180. // Special: 0xDA
  1181. // Undefined: 0xDB
  1182. // Special: 0xDC
  1183. case 0xDD: // CMP abs, X
  1184. CP(A, D_ABSX);
  1185. CLK(4);
  1186. break;
  1187. case 0xDE: // DEC abs, X
  1188. DEC(A_ABSX);
  1189. CLK(7);
  1190. break;
  1191. // Undefined: 0xDF
  1192. case 0xE0: // CPX imm
  1193. CP(X, D_IMM);
  1194. CLK(2);
  1195. break;
  1196. case 0xE1: // SBC (xp, X)
  1197. SBC(D_IX);
  1198. CLK(6);
  1199. break;
  1200. // Special: 0xE2
  1201. // Undefined: 0xE3
  1202. case 0xE4: // CPX zp
  1203. CP(X, D_ZP);
  1204. CLK(3);
  1205. break;
  1206. case 0xE5: // SBC zp
  1207. SBC(D_ZP);
  1208. CLK(3);
  1209. break;
  1210. case 0xE6: // INC zp
  1211. INC(A_ZP);
  1212. CLK(5);
  1213. break;
  1214. case 0xE8: // INX
  1215. ++X;
  1216. TEST(X);
  1217. CLK(2);
  1218. break;
  1219. case 0xE9: // SBC imm
  1220. SBC(D_IMM);
  1221. CLK(2);
  1222. break;
  1223. case 0xEA: // NOP
  1224. CLK(2);
  1225. break;
  1226. // Undefined: 0xEB
  1227. case 0xEC: // CPX abs
  1228. CP(X, D_ABS);
  1229. CLK(4);
  1230. break;
  1231. case 0xED: // SBC abs
  1232. SBC(D_ABS);
  1233. CLK(4);
  1234. break;
  1235. case 0xEE: // INC abs
  1236. INC(A_ABS);
  1237. CLK(6);
  1238. break;
  1239. // Undefined: 0xEF
  1240. case 0xF0: // BEQ
  1241. BIF(P & f6502_Status_Z);
  1242. break;
  1243. case 0xF1: // SBC (zp), Y
  1244. SBC(D_IY);
  1245. CLK(5);
  1246. break;
  1247. // Undefined: 0xF2 - 0xF3
  1248. // Special: 0xF4
  1249. case 0xF5: // SBC zp, X
  1250. SBC(D_ZPX);
  1251. CLK(4);
  1252. break;
  1253. case 0xF6: // INC zp, X
  1254. INC(A_ZPX);
  1255. CLK(6);
  1256. break;
  1257. // Undefined: 0xF7
  1258. case 0xF8: // SED
  1259. SET(P, f6502_Status_D);
  1260. CLK(2);
  1261. break;
  1262. case 0xF9: // SBC abs, Y
  1263. SBC(D_ABSY);
  1264. CLK(4);
  1265. break;
  1266. // Special: 0xFA
  1267. // Undefined: 0xFB
  1268. // Special: 0xFC
  1269. case 0xFD: // SBC abs, X
  1270. SBC(D_ABSX);
  1271. CLK(4);
  1272. break;
  1273. case 0xFE: // INC abs, X
  1274. INC(A_ABSX);
  1275. CLK(7);
  1276. break;
  1277. /* "Special" i.e. "unofficial" instructions */
  1278. /* Timing & progression only, no side effects */
  1279. // DOP, 2 Cycles
  1280. case 0x80:
  1281. case 0x82:
  1282. case 0x89:
  1283. case 0xC2:
  1284. case 0xE2:
  1285. ++PC;
  1286. CLK(2);
  1287. break;
  1288. // DOP, 3 Cycles
  1289. case 0x04:
  1290. case 0x44:
  1291. case 0x64:
  1292. ++PC;
  1293. CLK(3);
  1294. break;
  1295. // DOP, 4 Cycles
  1296. case 0x14:
  1297. case 0x34:
  1298. case 0x54:
  1299. case 0x74:
  1300. case 0xD4:
  1301. case 0xF4:
  1302. ++PC;
  1303. CLK(4);
  1304. break;
  1305. // TOP, 4 Cycles
  1306. case 0x1C:
  1307. case 0x3C:
  1308. case 0x5C:
  1309. case 0x7C:
  1310. case 0xDC:
  1311. case 0xFC:
  1312. PC += 2;
  1313. CLK(4);
  1314. break;
  1315. // NOP, 2 Cycles
  1316. default:
  1317. CLK(2);
  1318. break;
  1319. }
  1320. }
  1321. #ifdef F6502_TRACE
  1322. // if (int_trig) printf("Possible interrupt trigger\n");
  1323. #endif
  1324. #ifdef F6502_HCF
  1325. step_done:
  1326. #endif
  1327. core->registers = (f6502_Registers){
  1328. .PC = PC,
  1329. .S = S,
  1330. .A = A,
  1331. .X = X,
  1332. .Y = Y,
  1333. .P = P,
  1334. };
  1335. return clocks_elapsed;
  1336. }
  1337. int f6502_step(f6502_Core* core, int clocks) {
  1338. int clocks_elapsed = 0;
  1339. // TODO: Why are we processing seven clocks prior to NMI?
  1340. // This passes the interrupt test with 6 steps
  1341. /*
  1342. if (f6502_nmi_ready(core)) {
  1343. clocks_elapsed += f6502_do_step(core, 7);
  1344. clocks -= clocks_elapsed;
  1345. }
  1346. */
  1347. clocks_elapsed += f6502_check_interrupts(core);
  1348. return ( f6502_do_step(core, clocks - clocks_elapsed) +
  1349. clocks_elapsed);
  1350. }