From 16b51620a65bc30798cbba23ccb82899c5d5f8d8 Mon Sep 17 00:00:00 2001 From: JakeBreath Date: Sun, 9 Aug 2026 11:06:08 -0500 Subject: [PATCH] implemented the INC and DEC family of instructions --- STATE.md | 7 ++- ours.log | 172 +++++++++++++++++++++++++++++++++++++++++++++++++++++ src/cpu.rs | 92 ++++++++++++++++++++++++++++ 3 files changed, 268 insertions(+), 3 deletions(-) diff --git a/STATE.md b/STATE.md index 1ff4b36..cac457a 100644 --- a/STATE.md +++ b/STATE.md @@ -24,7 +24,8 @@ - Batch 1 done (subroutines + stack): JSR, RTS, PHA, PLA, PHP, PLP, RTI, BRK, plus NOP and SEC as quick wins. Verified SP:FD->FB across JSR (push high-then-low works) - Batch 2 done (branches): all 8 branches (BEQ/BNE/BCC/BCS/BPL/BMI/BVC/BVS) via one shared branch() routine with condition param. Taken = +3 cycles, page-cross = +1 more. Verified both taken and not-taken paths in the log - Flag set/clear ops done (part of Batch 10): CLC, CLI, CLV, CLD, SEI, SED (SEC done in Batch 1). SEI/SED set, the rest clear. Fixed a real bug where SEI/SED were clearing instead of setting -- Trace now matches the nestest reference log through line 506 (CBB9 INY, CYC:1168), field-for-field (PC/A/X/Y/P/SP/CYC verified by label-comparison script). Next panic is on 0xC8 (INY) at line 506, top of Batch 8 +- Trace now matches the nestest reference log through line 678 (CCBA TAY, CYC:1592), field-for-field (PC/A/X/Y/P/SP/CYC verified by label-comparison script). Next panic is on 0xA8 (TAY) at line 678, a Batch 10 transfer opcode +- Batch 8 done (inc/dec): INC (4 modes), DEC (4 modes), INX, INY, DEX, DEY. RMW cores (inc/dec) read-modify-write and correctly return base WITHOUT the page-cross extra (RMW cycles are fixed). Register ops are wrapping_add/sub with Z/N only. 124 of 151 official opcodes done. INY/INX carried the log from 506 to 678 lines - Batch 3 done (loads): LDA (8 modes), LDX (5 modes), LDY (5 modes) via three shared cores (lda/ldx/ldy) + thin wrappers. Caught two real bugs in review: all 4 LDY wrappers called self.ldx (would write to X instead of Y), and 6 of 8 LDX/LDY wrappers had wrong base cycles (3 instead of 4). Both fixed - Batch 4 done (stores): STA (7 modes), STX (3 modes), STY (3 modes) via three shared cores (sta/stx/sty) + thin wrappers. No flag changes. Refactored stx_zp to use the shared stx core for consistency. Fixed a comment typo (sta_abx was labeled 0x95 instead of 0x9D) - Batch 5 done (compares): CMP (8 modes), CPX (3 modes), CPY (3 modes) via three shared cores (cmp/cpx/cpy) + wrappers + immediate variants. Sets C (reg >= mem), Z, N; no store. Uses wrapping_sub for the borrow math. 70 of 151 official opcodes done. No diff progress expected until the log reaches these opcodes @@ -46,9 +47,9 @@ CPU implementation batches (by family, ordered by nestest log frequency): - Batch 5 - DONE (compares, see Done section) - Batch 6 - DONE (arithmetic, see Done section) - Batch 7 - DONE (logic, see Done section) -- Batch 8 - Inc/Dec: INC/DEC 4 modes each (RMW), INX, INY, DEX, DEY. Next up +- Batch 8 - DONE (inc/dec, see Done section) - Batch 9 - Shifts: ASL, LSR, ROL, ROR (accumulator + 4 memory modes each, RMW) -- Batch 10 - PARTIAL: flag ops done (CLC/CLI/CLV/CLD/SEI/SED, plus SEC/NOP). Remaining: JMP ind 6C, transfers TAX/TAY/TXA/TYA/TSX/TXS +- Batch 10 - PARTIAL: flag ops done (CLC/CLI/CLV/CLD/SEI/SED, plus SEC/NOP). Remaining: JMP ind 6C, transfers TAX/TAY/TXA/TYA/TSX/TXS. Next in log: TAY (0xA8) at line 678 Rules for each batch: - Add the opcode's length to opcode_len in the same edit (never let them drift) diff --git a/ours.log b/ours.log index d979fe3..fa40da0 100644 --- a/ours.log +++ b/ours.log @@ -504,3 +504,175 @@ F93F C9 00 A:00 X:AA Y:71 P:27 SP:F9 CYC:1158 F941 D0 01 A:00 X:AA Y:71 P:27 SP:F9 CYC:1160 F943 60 A:00 X:AA Y:71 P:27 SP:F9 CYC:1162 CBB9 C8 A:00 X:AA Y:71 P:27 SP:FB CYC:1168 +CBBA 20 47 F9 A:00 X:AA Y:72 P:25 SP:FB CYC:1170 +F947 B8 A:00 X:AA Y:72 P:25 SP:F9 CYC:1176 +F948 38 A:00 X:AA Y:72 P:25 SP:F9 CYC:1178 +F949 A9 40 A:00 X:AA Y:72 P:25 SP:F9 CYC:1180 +F94B 60 A:40 X:AA Y:72 P:25 SP:F9 CYC:1182 +CBBD E9 3F A:40 X:AA Y:72 P:25 SP:FB CYC:1188 +CBBF 20 4C F9 A:01 X:AA Y:72 P:25 SP:FB CYC:1190 +F94C F0 0B A:01 X:AA Y:72 P:25 SP:F9 CYC:1196 +F94E 30 09 A:01 X:AA Y:72 P:25 SP:F9 CYC:1198 +F950 90 07 A:01 X:AA Y:72 P:25 SP:F9 CYC:1200 +F952 70 05 A:01 X:AA Y:72 P:25 SP:F9 CYC:1202 +F954 C9 01 A:01 X:AA Y:72 P:25 SP:F9 CYC:1204 +F956 D0 01 A:01 X:AA Y:72 P:27 SP:F9 CYC:1206 +F958 60 A:01 X:AA Y:72 P:27 SP:F9 CYC:1208 +CBC2 C8 A:01 X:AA Y:72 P:27 SP:FB CYC:1214 +CBC3 20 5C F9 A:01 X:AA Y:73 P:25 SP:FB CYC:1216 +F95C A9 40 A:01 X:AA Y:73 P:25 SP:F9 CYC:1222 +F95E 38 A:40 X:AA Y:73 P:25 SP:F9 CYC:1224 +F95F 24 01 A:40 X:AA Y:73 P:25 SP:F9 CYC:1226 +F961 60 A:40 X:AA Y:73 P:E5 SP:F9 CYC:1229 +CBC6 E9 41 A:40 X:AA Y:73 P:E5 SP:FB CYC:1235 +CBC8 20 62 F9 A:FF X:AA Y:73 P:A4 SP:FB CYC:1237 +F962 B0 0B A:FF X:AA Y:73 P:A4 SP:F9 CYC:1243 +F964 F0 09 A:FF X:AA Y:73 P:A4 SP:F9 CYC:1245 +F966 10 07 A:FF X:AA Y:73 P:A4 SP:F9 CYC:1247 +F968 70 05 A:FF X:AA Y:73 P:A4 SP:F9 CYC:1249 +F96A C9 FF A:FF X:AA Y:73 P:A4 SP:F9 CYC:1251 +F96C D0 01 A:FF X:AA Y:73 P:27 SP:F9 CYC:1253 +F96E 60 A:FF X:AA Y:73 P:27 SP:F9 CYC:1255 +CBCB C8 A:FF X:AA Y:73 P:27 SP:FB CYC:1261 +CBCC 20 72 F9 A:FF X:AA Y:74 P:25 SP:FB CYC:1263 +F972 18 A:FF X:AA Y:74 P:25 SP:F9 CYC:1269 +F973 A9 80 A:FF X:AA Y:74 P:24 SP:F9 CYC:1271 +F975 60 A:80 X:AA Y:74 P:A4 SP:F9 CYC:1273 +CBCF E9 00 A:80 X:AA Y:74 P:A4 SP:FB CYC:1279 +CBD1 20 76 F9 A:7F X:AA Y:74 P:65 SP:FB CYC:1281 +F976 90 05 A:7F X:AA Y:74 P:65 SP:F9 CYC:1287 +F978 C9 7F A:7F X:AA Y:74 P:65 SP:F9 CYC:1289 +F97A D0 01 A:7F X:AA Y:74 P:67 SP:F9 CYC:1291 +F97C 60 A:7F X:AA Y:74 P:67 SP:F9 CYC:1293 +CBD4 C8 A:7F X:AA Y:74 P:67 SP:FB CYC:1299 +CBD5 20 80 F9 A:7F X:AA Y:75 P:65 SP:FB CYC:1301 +F980 38 A:7F X:AA Y:75 P:65 SP:F9 CYC:1307 +F981 A9 81 A:7F X:AA Y:75 P:65 SP:F9 CYC:1309 +F983 60 A:81 X:AA Y:75 P:E5 SP:F9 CYC:1311 +CBD8 E9 7F A:81 X:AA Y:75 P:E5 SP:FB CYC:1317 +CBDA 20 84 F9 A:02 X:AA Y:75 P:65 SP:FB CYC:1319 +F984 50 07 A:02 X:AA Y:75 P:65 SP:F9 CYC:1325 +F986 90 05 A:02 X:AA Y:75 P:65 SP:F9 CYC:1327 +F988 C9 02 A:02 X:AA Y:75 P:65 SP:F9 CYC:1329 +F98A D0 01 A:02 X:AA Y:75 P:67 SP:F9 CYC:1331 +F98C 60 A:02 X:AA Y:75 P:67 SP:F9 CYC:1333 +CBDD 60 A:02 X:AA Y:75 P:67 SP:FB CYC:1339 +C606 20 DE CB A:02 X:AA Y:75 P:67 SP:FD CYC:1345 +CBDE EA A:02 X:AA Y:75 P:67 SP:FB CYC:1351 +CBDF A9 FF A:02 X:AA Y:75 P:67 SP:FB CYC:1353 +CBE1 85 01 A:FF X:AA Y:75 P:E5 SP:FB CYC:1355 +CBE3 A9 44 A:FF X:AA Y:75 P:E5 SP:FB CYC:1358 +CBE5 A2 55 A:44 X:AA Y:75 P:65 SP:FB CYC:1360 +CBE7 A0 66 A:44 X:55 Y:75 P:65 SP:FB CYC:1362 +CBE9 E8 A:44 X:55 Y:66 P:65 SP:FB CYC:1364 +CBEA 88 A:44 X:56 Y:66 P:65 SP:FB CYC:1366 +CBEB E0 56 A:44 X:56 Y:65 P:65 SP:FB CYC:1368 +CBED D0 21 A:44 X:56 Y:65 P:67 SP:FB CYC:1370 +CBEF C0 65 A:44 X:56 Y:65 P:67 SP:FB CYC:1372 +CBF1 D0 1D A:44 X:56 Y:65 P:67 SP:FB CYC:1374 +CBF3 E8 A:44 X:56 Y:65 P:67 SP:FB CYC:1376 +CBF4 E8 A:44 X:57 Y:65 P:65 SP:FB CYC:1378 +CBF5 88 A:44 X:58 Y:65 P:65 SP:FB CYC:1380 +CBF6 88 A:44 X:58 Y:64 P:65 SP:FB CYC:1382 +CBF7 E0 58 A:44 X:58 Y:63 P:65 SP:FB CYC:1384 +CBF9 D0 15 A:44 X:58 Y:63 P:67 SP:FB CYC:1386 +CBFB C0 63 A:44 X:58 Y:63 P:67 SP:FB CYC:1388 +CBFD D0 11 A:44 X:58 Y:63 P:67 SP:FB CYC:1390 +CBFF CA A:44 X:58 Y:63 P:67 SP:FB CYC:1392 +CC00 C8 A:44 X:57 Y:63 P:65 SP:FB CYC:1394 +CC01 E0 57 A:44 X:57 Y:64 P:65 SP:FB CYC:1396 +CC03 D0 0B A:44 X:57 Y:64 P:67 SP:FB CYC:1398 +CC05 C0 64 A:44 X:57 Y:64 P:67 SP:FB CYC:1400 +CC07 D0 07 A:44 X:57 Y:64 P:67 SP:FB CYC:1402 +CC09 C9 44 A:44 X:57 Y:64 P:67 SP:FB CYC:1404 +CC0B D0 03 A:44 X:57 Y:64 P:67 SP:FB CYC:1406 +CC0D 4C 14 CC A:44 X:57 Y:64 P:67 SP:FB CYC:1408 +CC14 EA A:44 X:57 Y:64 P:67 SP:FB CYC:1411 +CC15 38 A:44 X:57 Y:64 P:67 SP:FB CYC:1413 +CC16 A2 69 A:44 X:57 Y:64 P:67 SP:FB CYC:1415 +CC18 A9 96 A:44 X:69 Y:64 P:65 SP:FB CYC:1417 +CC1A 24 01 A:96 X:69 Y:64 P:E5 SP:FB CYC:1419 +CC1C A0 FF A:96 X:69 Y:64 P:E5 SP:FB CYC:1422 +CC1E C8 A:96 X:69 Y:FF P:E5 SP:FB CYC:1424 +CC1F D0 3D A:96 X:69 Y:00 P:67 SP:FB CYC:1426 +CC21 30 3B A:96 X:69 Y:00 P:67 SP:FB CYC:1428 +CC23 90 39 A:96 X:69 Y:00 P:67 SP:FB CYC:1430 +CC25 50 37 A:96 X:69 Y:00 P:67 SP:FB CYC:1432 +CC27 C0 00 A:96 X:69 Y:00 P:67 SP:FB CYC:1434 +CC29 D0 33 A:96 X:69 Y:00 P:67 SP:FB CYC:1436 +CC2B C8 A:96 X:69 Y:00 P:67 SP:FB CYC:1438 +CC2C F0 30 A:96 X:69 Y:01 P:65 SP:FB CYC:1440 +CC2E 30 2E A:96 X:69 Y:01 P:65 SP:FB CYC:1442 +CC30 90 2C A:96 X:69 Y:01 P:65 SP:FB CYC:1444 +CC32 50 2A A:96 X:69 Y:01 P:65 SP:FB CYC:1446 +CC34 18 A:96 X:69 Y:01 P:65 SP:FB CYC:1448 +CC35 B8 A:96 X:69 Y:01 P:64 SP:FB CYC:1450 +CC36 A0 00 A:96 X:69 Y:01 P:24 SP:FB CYC:1452 +CC38 88 A:96 X:69 Y:00 P:26 SP:FB CYC:1454 +CC39 F0 23 A:96 X:69 Y:FF P:A4 SP:FB CYC:1456 +CC3B 10 21 A:96 X:69 Y:FF P:A4 SP:FB CYC:1458 +CC3D B0 1F A:96 X:69 Y:FF P:A4 SP:FB CYC:1460 +CC3F 70 1D A:96 X:69 Y:FF P:A4 SP:FB CYC:1462 +CC41 C0 FF A:96 X:69 Y:FF P:A4 SP:FB CYC:1464 +CC43 D0 19 A:96 X:69 Y:FF P:27 SP:FB CYC:1466 +CC45 18 A:96 X:69 Y:FF P:27 SP:FB CYC:1468 +CC46 88 A:96 X:69 Y:FF P:26 SP:FB CYC:1470 +CC47 F0 15 A:96 X:69 Y:FE P:A4 SP:FB CYC:1472 +CC49 10 13 A:96 X:69 Y:FE P:A4 SP:FB CYC:1474 +CC4B B0 11 A:96 X:69 Y:FE P:A4 SP:FB CYC:1476 +CC4D 70 0F A:96 X:69 Y:FE P:A4 SP:FB CYC:1478 +CC4F C0 FE A:96 X:69 Y:FE P:A4 SP:FB CYC:1480 +CC51 D0 0B A:96 X:69 Y:FE P:27 SP:FB CYC:1482 +CC53 C9 96 A:96 X:69 Y:FE P:27 SP:FB CYC:1484 +CC55 D0 07 A:96 X:69 Y:FE P:27 SP:FB CYC:1486 +CC57 E0 69 A:96 X:69 Y:FE P:27 SP:FB CYC:1488 +CC59 D0 03 A:96 X:69 Y:FE P:27 SP:FB CYC:1490 +CC5B 4C 62 CC A:96 X:69 Y:FE P:27 SP:FB CYC:1492 +CC62 EA A:96 X:69 Y:FE P:27 SP:FB CYC:1495 +CC63 38 A:96 X:69 Y:FE P:27 SP:FB CYC:1497 +CC64 A0 69 A:96 X:69 Y:FE P:27 SP:FB CYC:1499 +CC66 A9 96 A:96 X:69 Y:69 P:25 SP:FB CYC:1501 +CC68 24 01 A:96 X:69 Y:69 P:A5 SP:FB CYC:1503 +CC6A A2 FF A:96 X:69 Y:69 P:E5 SP:FB CYC:1506 +CC6C E8 A:96 X:FF Y:69 P:E5 SP:FB CYC:1508 +CC6D D0 3D A:96 X:00 Y:69 P:67 SP:FB CYC:1510 +CC6F 30 3B A:96 X:00 Y:69 P:67 SP:FB CYC:1512 +CC71 90 39 A:96 X:00 Y:69 P:67 SP:FB CYC:1514 +CC73 50 37 A:96 X:00 Y:69 P:67 SP:FB CYC:1516 +CC75 E0 00 A:96 X:00 Y:69 P:67 SP:FB CYC:1518 +CC77 D0 33 A:96 X:00 Y:69 P:67 SP:FB CYC:1520 +CC79 E8 A:96 X:00 Y:69 P:67 SP:FB CYC:1522 +CC7A F0 30 A:96 X:01 Y:69 P:65 SP:FB CYC:1524 +CC7C 30 2E A:96 X:01 Y:69 P:65 SP:FB CYC:1526 +CC7E 90 2C A:96 X:01 Y:69 P:65 SP:FB CYC:1528 +CC80 50 2A A:96 X:01 Y:69 P:65 SP:FB CYC:1530 +CC82 18 A:96 X:01 Y:69 P:65 SP:FB CYC:1532 +CC83 B8 A:96 X:01 Y:69 P:64 SP:FB CYC:1534 +CC84 A2 00 A:96 X:01 Y:69 P:24 SP:FB CYC:1536 +CC86 CA A:96 X:00 Y:69 P:26 SP:FB CYC:1538 +CC87 F0 23 A:96 X:FF Y:69 P:A4 SP:FB CYC:1540 +CC89 10 21 A:96 X:FF Y:69 P:A4 SP:FB CYC:1542 +CC8B B0 1F A:96 X:FF Y:69 P:A4 SP:FB CYC:1544 +CC8D 70 1D A:96 X:FF Y:69 P:A4 SP:FB CYC:1546 +CC8F E0 FF A:96 X:FF Y:69 P:A4 SP:FB CYC:1548 +CC91 D0 19 A:96 X:FF Y:69 P:27 SP:FB CYC:1550 +CC93 18 A:96 X:FF Y:69 P:27 SP:FB CYC:1552 +CC94 CA A:96 X:FF Y:69 P:26 SP:FB CYC:1554 +CC95 F0 15 A:96 X:FE Y:69 P:A4 SP:FB CYC:1556 +CC97 10 13 A:96 X:FE Y:69 P:A4 SP:FB CYC:1558 +CC99 B0 11 A:96 X:FE Y:69 P:A4 SP:FB CYC:1560 +CC9B 70 0F A:96 X:FE Y:69 P:A4 SP:FB CYC:1562 +CC9D E0 FE A:96 X:FE Y:69 P:A4 SP:FB CYC:1564 +CC9F D0 0B A:96 X:FE Y:69 P:27 SP:FB CYC:1566 +CCA1 C9 96 A:96 X:FE Y:69 P:27 SP:FB CYC:1568 +CCA3 D0 07 A:96 X:FE Y:69 P:27 SP:FB CYC:1570 +CCA5 C0 69 A:96 X:FE Y:69 P:27 SP:FB CYC:1572 +CCA7 D0 03 A:96 X:FE Y:69 P:27 SP:FB CYC:1574 +CCA9 4C B0 CC A:96 X:FE Y:69 P:27 SP:FB CYC:1576 +CCB0 EA A:96 X:FE Y:69 P:27 SP:FB CYC:1579 +CCB1 A9 85 A:96 X:FE Y:69 P:27 SP:FB CYC:1581 +CCB3 A2 34 A:85 X:FE Y:69 P:A5 SP:FB CYC:1583 +CCB5 A0 99 A:85 X:34 Y:69 P:25 SP:FB CYC:1585 +CCB7 18 A:85 X:34 Y:99 P:A5 SP:FB CYC:1587 +CCB8 24 01 A:85 X:34 Y:99 P:A4 SP:FB CYC:1589 +CCBA A8 A:85 X:34 Y:99 P:E4 SP:FB CYC:1592 diff --git a/src/cpu.rs b/src/cpu.rs index c33a3b6..65b608f 100644 --- a/src/cpu.rs +++ b/src/cpu.rs @@ -148,6 +148,12 @@ impl Cpu { 0x49 => self.eor_imm(bus), 0x45 => self.eor_zp(bus), 0x55 => self.eor_zpx(bus), 0x4D => self.eor_abs(bus), 0x5D => self.eor_abx(bus), 0x59 => self.eor_aby(bus), 0x41 => self.eor_izx(bus), 0x51 => self.eor_izy(bus), + // Increments + 0xE6 => self.inc_zp(bus), 0xF6 => self.inc_zpx(bus), 0xEE => self.inc_abs(bus), + 0xFE => self.inc_abx(bus), 0xE8 => self.inx_imp(bus), 0xC8 => self.iny_imp(bus), + // Decrements + 0xC6 => self.dec_zp(bus), 0xD6 => self.dec_zpx(bus), 0xCE => self.dec_abs(bus), + 0xDE => self.dec_abx(bus), 0xCA => self.dex_imp(bus), 0x88 => self.dey_imp(bus), _ => panic!("illegal/unkown opcode {opcode:#04X} at {:#06X}", self.pc.wrapping_sub(1)), }; self.cycles += cycles as u64; @@ -185,6 +191,9 @@ impl Cpu { 0x1D => 3, /* ORA abx */ 0x19 => 3, /* ORA aby */ 0x01 => 2, /* ORA izx */ 0x11 => 2, /* ORA izy */ 0x49 => 2, /* EOR imm */ 0x45 => 2, /* EOR zp */ 0x55 => 2, /* EOR zpx */ 0x4D => 3, /* EOR abs */ 0x5D => 3, /* EOR abx */ 0x59 => 3, /* EOR aby */ 0x41 => 2, /* EOR izx */ 0x51 => 2, /* EOR izy */ + 0xE6 => 2, /* INC zp */ 0xF6 => 2, /* INC zpx */ 0xEE => 3, /* INC abs */ 0xFE => 3, /* INC abx */ + 0xE8 => 1, /* INX imp */ 0xC8 => 1, /* INY imp */ 0xC6 => 2, /* DEC zp */ 0xD6 => 2, /* DEC zpx */ + 0xCE => 3, /* DEC abs */ 0xDE => 3, /* DEC abx */ 0xCA => 1, /* DEX imp */ 0x88 => 1, /* DEY imp */ _ => 1, // fallback, would show the invalid/unknown opcode only not its parameters } } @@ -405,6 +414,22 @@ impl Cpu { base + extra } + // INC core + fn inc(&mut self, bus: &mut impl Bus, (address, _extra): (u16, u8), base: u8) -> u8 { + let value = self.read(bus, address).wrapping_add(1); + self.write(bus, address, value); + self.set_zp_flags(value); + base // NO + extra — RMW cycles are fixed + } + + // DEC core + fn dec(&mut self, bus: &mut impl Bus, (address, _extra): (u16, u8), base: u8) -> u8 { + let value = self.read(bus, address).wrapping_sub(1); + self.write(bus, address, value); + self.set_zp_flags(value); + base // NO + extra — RMW cycles are fixed + } + // NES 6502 opcode -> functions fn jmp_abs(&mut self, bus: &mut impl Bus) -> u8 { // 0x4C, 3 bytes, 3 cycles self.pc = self.fetch16(bus); @@ -968,6 +993,73 @@ impl Cpu { 2 } + // INC variants + fn inc_zp(&mut self, bus: &mut impl Bus) -> u8 { // 0xE6, 2 bytes, 5 cycles + let (address, extra) = self.address_zp(bus); + self.inc(bus, (address, extra), 5) + } + + fn inc_zpx(&mut self, bus: &mut impl Bus) -> u8 { // 0xF6, 2 bytes, 6 cycles + let (address, extra) = self.address_zpx(bus); + self.inc(bus, (address, extra), 6) + } + + fn inc_abs(&mut self, bus: &mut impl Bus) -> u8 { // 0xEE, 3 bytes, 6 cycles + let (address, extra) = self.address_abs(bus); + self.inc(bus, (address, extra), 6) + } + + fn inc_abx(&mut self, bus: &mut impl Bus) -> u8 { // 0xFE, 3 bytes, 7 cycles + let (address, extra) = self.address_abx(bus); + self.inc(bus, (address, extra), 7) + } + + // DEC variants + fn dec_zp(&mut self, bus: &mut impl Bus) -> u8 { // 0xC6, 2 bytes, 5 cycles + let (address, extra) = self.address_zp(bus); + self.dec(bus, (address, extra), 5) + } + + fn dec_zpx(&mut self, bus: &mut impl Bus) -> u8 { // 0xD6, 2 bytes, 6 cycles + let (address, extra) = self.address_zpx(bus); + self.dec(bus, (address, extra), 6) + } + + fn dec_abs(&mut self, bus: &mut impl Bus) -> u8 { // 0xCE, 3 bytes, 6 cycles + let (address, extra) = self.address_abs(bus); + self.dec(bus, (address, extra), 6) + } + + fn dec_abx(&mut self, bus: &mut impl Bus) -> u8 { // 0xDE, 3 bytes, 7 cycles + let (address, extra) = self.address_abx(bus); + self.dec(bus, (address, extra), 7) + } + + // INC register variants + fn inx_imp(&mut self, _bus: &mut impl Bus) -> u8 { // 0xE8, 1 byte, 2 cycles + self.x = self.x.wrapping_add(1); + self.set_zp_flags(self.x); + 2 + } + + fn iny_imp(&mut self, _bus: &mut impl Bus) -> u8 { // 0xC8, 1 byte, 2 cycles + self.y = self.y.wrapping_add(1); + self.set_zp_flags(self.y); + 2 + } + + // DEC register variants + fn dex_imp(&mut self, _bus: &mut impl Bus) -> u8 { // 0xCA, 1 byte, 2 cycles + self.x = self.x.wrapping_sub(1); + self.set_zp_flags(self.x); + 2 + } + + fn dey_imp(&mut self, _bus: &mut impl Bus) -> u8 { // 0x88, 1 byte, 2 cycles + self.y = self.y.wrapping_sub(1); + self.set_zp_flags(self.y); + 2 + } // all branching alternatives here, all 1 bytes fn bcs_rel(&mut self, bus: &mut impl Bus) -> u8 { self.branch(bus, self.flag(FLAG_CARRY)) } // 0xB0