diff --git a/STATE.md b/STATE.md index 59afe9c..1ff4b36 100644 --- a/STATE.md +++ b/STATE.md @@ -24,11 +24,13 @@ - 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 73 (C7E9 AND, CYC:192), field-for-field (PC/A/X/Y/P/SP/CYC verified by label-comparison script). Next panic is on 0x29 (AND imm) at line 73, top of Batch 7 +- 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 - 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 - Batch 6 done (arithmetic): ADC (8 modes), SBC (8 modes), BIT (2 modes) via shared add_with_carry core + adc/sbc/bit cores + wrappers. SBC adds the one's complement (A + ~mem + C), which makes the V-flag math correct. Decimal flag inert (binary only). 88 of 151 official opcodes done. Big diff progress: BIT/PHP/PLA/PHA carried the log from 38 to 73 lines +- Batch 7 done (logic): AND (8 modes), ORA (8 modes), EOR (8 modes) via three cores (and/ora/eor) + wrappers + immediate variants. Only Z/N flags affected, C/V untouched. Caught a real bug in review: all three _izx wrappers used base 5 instead of 6. 112 of 151 official opcodes done. Huge diff progress: carried the log from 73 to 506 lines +- Match compaction done: step and opcode_len both reformatted to max 4 opcodes per line. step match grouped by family with header comments; opcode_len keeps per-entry /* */ mnemonics. Diff verified unchanged after compaction - trace bytes are length-aware via opcode_len (fixed-width byte field, columns align for awk diff) ## Next @@ -43,8 +45,8 @@ CPU implementation batches (by family, ordered by nestest log frequency): - Batch 4 - DONE (stores, see Done section) - Batch 5 - DONE (compares, see Done section) - Batch 6 - DONE (arithmetic, see Done section) -- Batch 7 - Logic: AND, ORA, EOR (8 modes each). Next up -- Batch 8 - Inc/Dec: INC/DEC 4 modes each (RMW), INX, INY, DEX, DEY +- Batch 7 - DONE (logic, see Done section) +- Batch 8 - Inc/Dec: INC/DEC 4 modes each (RMW), INX, INY, DEX, DEY. Next up - 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 diff --git a/ours.log b/ours.log index 5c801e3..d979fe3 100644 --- a/ours.log +++ b/ours.log @@ -70,4 +70,437 @@ C7E5 78 A:00 X:00 Y:00 P:67 SP:FB CYC:181 C7E6 F8 A:00 X:00 Y:00 P:67 SP:FB CYC:183 C7E7 08 A:00 X:00 Y:00 P:6F SP:FB CYC:185 C7E8 68 A:00 X:00 Y:00 P:6F SP:FA CYC:188 -C7E9 29 A:7F X:00 Y:00 P:6D SP:FB CYC:192 +C7E9 29 EF A:7F X:00 Y:00 P:6D SP:FB CYC:192 +C7EB C9 6F A:6F X:00 Y:00 P:6D SP:FB CYC:194 +C7ED F0 04 A:6F X:00 Y:00 P:6F SP:FB CYC:196 +C7F3 EA A:6F X:00 Y:00 P:6F SP:FB CYC:199 +C7F4 A9 40 A:6F X:00 Y:00 P:6F SP:FB CYC:201 +C7F6 85 01 A:40 X:00 Y:00 P:6D SP:FB CYC:203 +C7F8 24 01 A:40 X:00 Y:00 P:6D SP:FB CYC:206 +C7FA D8 A:40 X:00 Y:00 P:6D SP:FB CYC:209 +C7FB A9 10 A:40 X:00 Y:00 P:65 SP:FB CYC:211 +C7FD 18 A:10 X:00 Y:00 P:65 SP:FB CYC:213 +C7FE 08 A:10 X:00 Y:00 P:64 SP:FB CYC:215 +C7FF 68 A:10 X:00 Y:00 P:64 SP:FA CYC:218 +C800 29 EF A:74 X:00 Y:00 P:64 SP:FB CYC:222 +C802 C9 64 A:64 X:00 Y:00 P:64 SP:FB CYC:224 +C804 F0 04 A:64 X:00 Y:00 P:67 SP:FB CYC:226 +C80A EA A:64 X:00 Y:00 P:67 SP:FB CYC:229 +C80B A9 80 A:64 X:00 Y:00 P:67 SP:FB CYC:231 +C80D 85 01 A:80 X:00 Y:00 P:E5 SP:FB CYC:233 +C80F 24 01 A:80 X:00 Y:00 P:E5 SP:FB CYC:236 +C811 F8 A:80 X:00 Y:00 P:A5 SP:FB CYC:239 +C812 A9 00 A:80 X:00 Y:00 P:AD SP:FB CYC:241 +C814 38 A:00 X:00 Y:00 P:2F SP:FB CYC:243 +C815 08 A:00 X:00 Y:00 P:2F SP:FB CYC:245 +C816 68 A:00 X:00 Y:00 P:2F SP:FA CYC:248 +C817 29 EF A:3F X:00 Y:00 P:2D SP:FB CYC:252 +C819 C9 2F A:2F X:00 Y:00 P:2D SP:FB CYC:254 +C81B F0 04 A:2F X:00 Y:00 P:2F SP:FB CYC:256 +C821 EA A:2F X:00 Y:00 P:2F SP:FB CYC:259 +C822 A9 FF A:2F X:00 Y:00 P:2F SP:FB CYC:261 +C824 48 A:FF X:00 Y:00 P:AD SP:FB CYC:263 +C825 28 A:FF X:00 Y:00 P:AD SP:FA CYC:266 +C826 D0 09 A:FF X:00 Y:00 P:EF SP:FB CYC:270 +C828 10 07 A:FF X:00 Y:00 P:EF SP:FB CYC:272 +C82A 50 05 A:FF X:00 Y:00 P:EF SP:FB CYC:274 +C82C 90 03 A:FF X:00 Y:00 P:EF SP:FB CYC:276 +C82E 4C 35 C8 A:FF X:00 Y:00 P:EF SP:FB CYC:278 +C835 EA A:FF X:00 Y:00 P:EF SP:FB CYC:281 +C836 A9 04 A:FF X:00 Y:00 P:EF SP:FB CYC:283 +C838 48 A:04 X:00 Y:00 P:6D SP:FB CYC:285 +C839 28 A:04 X:00 Y:00 P:6D SP:FA CYC:288 +C83A F0 09 A:04 X:00 Y:00 P:24 SP:FB CYC:292 +C83C 30 07 A:04 X:00 Y:00 P:24 SP:FB CYC:294 +C83E 70 05 A:04 X:00 Y:00 P:24 SP:FB CYC:296 +C840 B0 03 A:04 X:00 Y:00 P:24 SP:FB CYC:298 +C842 4C 49 C8 A:04 X:00 Y:00 P:24 SP:FB CYC:300 +C849 EA A:04 X:00 Y:00 P:24 SP:FB CYC:303 +C84A F8 A:04 X:00 Y:00 P:24 SP:FB CYC:305 +C84B A9 FF A:04 X:00 Y:00 P:2C SP:FB CYC:307 +C84D 85 01 A:FF X:00 Y:00 P:AC SP:FB CYC:309 +C84F 24 01 A:FF X:00 Y:00 P:AC SP:FB CYC:312 +C851 18 A:FF X:00 Y:00 P:EC SP:FB CYC:315 +C852 A9 00 A:FF X:00 Y:00 P:EC SP:FB CYC:317 +C854 48 A:00 X:00 Y:00 P:6E SP:FB CYC:319 +C855 A9 FF A:00 X:00 Y:00 P:6E SP:FA CYC:322 +C857 68 A:FF X:00 Y:00 P:EC SP:FA CYC:324 +C858 D0 09 A:00 X:00 Y:00 P:6E SP:FB CYC:328 +C85A 30 07 A:00 X:00 Y:00 P:6E SP:FB CYC:330 +C85C 50 05 A:00 X:00 Y:00 P:6E SP:FB CYC:332 +C85E B0 03 A:00 X:00 Y:00 P:6E SP:FB CYC:334 +C860 4C 67 C8 A:00 X:00 Y:00 P:6E SP:FB CYC:336 +C867 EA A:00 X:00 Y:00 P:6E SP:FB CYC:339 +C868 A9 00 A:00 X:00 Y:00 P:6E SP:FB CYC:341 +C86A 85 01 A:00 X:00 Y:00 P:6E SP:FB CYC:343 +C86C 24 01 A:00 X:00 Y:00 P:6E SP:FB CYC:346 +C86E 38 A:00 X:00 Y:00 P:2E SP:FB CYC:349 +C86F A9 FF A:00 X:00 Y:00 P:2F SP:FB CYC:351 +C871 48 A:FF X:00 Y:00 P:AD SP:FB CYC:353 +C872 A9 00 A:FF X:00 Y:00 P:AD SP:FA CYC:356 +C874 68 A:00 X:00 Y:00 P:2F SP:FA CYC:358 +C875 F0 09 A:FF X:00 Y:00 P:AD SP:FB CYC:362 +C877 10 07 A:FF X:00 Y:00 P:AD SP:FB CYC:364 +C879 70 05 A:FF X:00 Y:00 P:AD SP:FB CYC:366 +C87B 90 03 A:FF X:00 Y:00 P:AD SP:FB CYC:368 +C87D 4C 84 C8 A:FF X:00 Y:00 P:AD SP:FB CYC:370 +C884 60 A:FF X:00 Y:00 P:AD SP:FB CYC:373 +C603 20 85 C8 A:FF X:00 Y:00 P:AD SP:FD CYC:379 +C885 EA A:FF X:00 Y:00 P:AD SP:FB CYC:385 +C886 18 A:FF X:00 Y:00 P:AD SP:FB CYC:387 +C887 A9 FF A:FF X:00 Y:00 P:AC SP:FB CYC:389 +C889 85 01 A:FF X:00 Y:00 P:AC SP:FB CYC:391 +C88B 24 01 A:FF X:00 Y:00 P:AC SP:FB CYC:394 +C88D A9 55 A:FF X:00 Y:00 P:EC SP:FB CYC:397 +C88F 09 AA A:55 X:00 Y:00 P:6C SP:FB CYC:399 +C891 B0 0B A:FF X:00 Y:00 P:EC SP:FB CYC:401 +C893 10 09 A:FF X:00 Y:00 P:EC SP:FB CYC:403 +C895 C9 FF A:FF X:00 Y:00 P:EC SP:FB CYC:405 +C897 D0 05 A:FF X:00 Y:00 P:6F SP:FB CYC:407 +C899 50 03 A:FF X:00 Y:00 P:6F SP:FB CYC:409 +C89B 4C A2 C8 A:FF X:00 Y:00 P:6F SP:FB CYC:411 +C8A2 EA A:FF X:00 Y:00 P:6F SP:FB CYC:414 +C8A3 38 A:FF X:00 Y:00 P:6F SP:FB CYC:416 +C8A4 B8 A:FF X:00 Y:00 P:6F SP:FB CYC:418 +C8A5 A9 00 A:FF X:00 Y:00 P:2F SP:FB CYC:420 +C8A7 09 00 A:00 X:00 Y:00 P:2F SP:FB CYC:422 +C8A9 D0 09 A:00 X:00 Y:00 P:2F SP:FB CYC:424 +C8AB 70 07 A:00 X:00 Y:00 P:2F SP:FB CYC:426 +C8AD 90 05 A:00 X:00 Y:00 P:2F SP:FB CYC:428 +C8AF 30 03 A:00 X:00 Y:00 P:2F SP:FB CYC:430 +C8B1 4C B8 C8 A:00 X:00 Y:00 P:2F SP:FB CYC:432 +C8B8 EA A:00 X:00 Y:00 P:2F SP:FB CYC:435 +C8B9 18 A:00 X:00 Y:00 P:2F SP:FB CYC:437 +C8BA 24 01 A:00 X:00 Y:00 P:2E SP:FB CYC:439 +C8BC A9 55 A:00 X:00 Y:00 P:EE SP:FB CYC:442 +C8BE 29 AA A:55 X:00 Y:00 P:6C SP:FB CYC:444 +C8C0 D0 09 A:00 X:00 Y:00 P:6E SP:FB CYC:446 +C8C2 50 07 A:00 X:00 Y:00 P:6E SP:FB CYC:448 +C8C4 B0 05 A:00 X:00 Y:00 P:6E SP:FB CYC:450 +C8C6 30 03 A:00 X:00 Y:00 P:6E SP:FB CYC:452 +C8C8 4C CF C8 A:00 X:00 Y:00 P:6E SP:FB CYC:454 +C8CF EA A:00 X:00 Y:00 P:6E SP:FB CYC:457 +C8D0 38 A:00 X:00 Y:00 P:6E SP:FB CYC:459 +C8D1 B8 A:00 X:00 Y:00 P:6F SP:FB CYC:461 +C8D2 A9 F8 A:00 X:00 Y:00 P:2F SP:FB CYC:463 +C8D4 29 EF A:F8 X:00 Y:00 P:AD SP:FB CYC:465 +C8D6 90 0B A:E8 X:00 Y:00 P:AD SP:FB CYC:467 +C8D8 10 09 A:E8 X:00 Y:00 P:AD SP:FB CYC:469 +C8DA C9 E8 A:E8 X:00 Y:00 P:AD SP:FB CYC:471 +C8DC D0 05 A:E8 X:00 Y:00 P:2F SP:FB CYC:473 +C8DE 70 03 A:E8 X:00 Y:00 P:2F SP:FB CYC:475 +C8E0 4C E7 C8 A:E8 X:00 Y:00 P:2F SP:FB CYC:477 +C8E7 EA A:E8 X:00 Y:00 P:2F SP:FB CYC:480 +C8E8 18 A:E8 X:00 Y:00 P:2F SP:FB CYC:482 +C8E9 24 01 A:E8 X:00 Y:00 P:2E SP:FB CYC:484 +C8EB A9 5F A:E8 X:00 Y:00 P:EC SP:FB CYC:487 +C8ED 49 AA A:5F X:00 Y:00 P:6C SP:FB CYC:489 +C8EF B0 0B A:F5 X:00 Y:00 P:EC SP:FB CYC:491 +C8F1 10 09 A:F5 X:00 Y:00 P:EC SP:FB CYC:493 +C8F3 C9 F5 A:F5 X:00 Y:00 P:EC SP:FB CYC:495 +C8F5 D0 05 A:F5 X:00 Y:00 P:6F SP:FB CYC:497 +C8F7 50 03 A:F5 X:00 Y:00 P:6F SP:FB CYC:499 +C8F9 4C 00 C9 A:F5 X:00 Y:00 P:6F SP:FB CYC:501 +C900 EA A:F5 X:00 Y:00 P:6F SP:FB CYC:504 +C901 38 A:F5 X:00 Y:00 P:6F SP:FB CYC:506 +C902 B8 A:F5 X:00 Y:00 P:6F SP:FB CYC:508 +C903 A9 70 A:F5 X:00 Y:00 P:2F SP:FB CYC:510 +C905 49 70 A:70 X:00 Y:00 P:2D SP:FB CYC:512 +C907 D0 09 A:00 X:00 Y:00 P:2F SP:FB CYC:514 +C909 70 07 A:00 X:00 Y:00 P:2F SP:FB CYC:516 +C90B 90 05 A:00 X:00 Y:00 P:2F SP:FB CYC:518 +C90D 30 03 A:00 X:00 Y:00 P:2F SP:FB CYC:520 +C90F 4C 16 C9 A:00 X:00 Y:00 P:2F SP:FB CYC:522 +C916 EA A:00 X:00 Y:00 P:2F SP:FB CYC:525 +C917 18 A:00 X:00 Y:00 P:2F SP:FB CYC:527 +C918 24 01 A:00 X:00 Y:00 P:2E SP:FB CYC:529 +C91A A9 00 A:00 X:00 Y:00 P:EE SP:FB CYC:532 +C91C 69 69 A:00 X:00 Y:00 P:6E SP:FB CYC:534 +C91E 30 0B A:69 X:00 Y:00 P:2C SP:FB CYC:536 +C920 B0 09 A:69 X:00 Y:00 P:2C SP:FB CYC:538 +C922 C9 69 A:69 X:00 Y:00 P:2C SP:FB CYC:540 +C924 D0 05 A:69 X:00 Y:00 P:2F SP:FB CYC:542 +C926 70 03 A:69 X:00 Y:00 P:2F SP:FB CYC:544 +C928 4C 2F C9 A:69 X:00 Y:00 P:2F SP:FB CYC:546 +C92F EA A:69 X:00 Y:00 P:2F SP:FB CYC:549 +C930 38 A:69 X:00 Y:00 P:2F SP:FB CYC:551 +C931 F8 A:69 X:00 Y:00 P:2F SP:FB CYC:553 +C932 24 01 A:69 X:00 Y:00 P:2F SP:FB CYC:555 +C934 A9 01 A:69 X:00 Y:00 P:ED SP:FB CYC:558 +C936 69 69 A:01 X:00 Y:00 P:6D SP:FB CYC:560 +C938 30 0B A:6B X:00 Y:00 P:2C SP:FB CYC:562 +C93A B0 09 A:6B X:00 Y:00 P:2C SP:FB CYC:564 +C93C C9 6B A:6B X:00 Y:00 P:2C SP:FB CYC:566 +C93E D0 05 A:6B X:00 Y:00 P:2F SP:FB CYC:568 +C940 70 03 A:6B X:00 Y:00 P:2F SP:FB CYC:570 +C942 4C 49 C9 A:6B X:00 Y:00 P:2F SP:FB CYC:572 +C949 EA A:6B X:00 Y:00 P:2F SP:FB CYC:575 +C94A D8 A:6B X:00 Y:00 P:2F SP:FB CYC:577 +C94B 38 A:6B X:00 Y:00 P:27 SP:FB CYC:579 +C94C B8 A:6B X:00 Y:00 P:27 SP:FB CYC:581 +C94D A9 7F A:6B X:00 Y:00 P:27 SP:FB CYC:583 +C94F 69 7F A:7F X:00 Y:00 P:25 SP:FB CYC:585 +C951 10 0B A:FF X:00 Y:00 P:E4 SP:FB CYC:587 +C953 B0 09 A:FF X:00 Y:00 P:E4 SP:FB CYC:589 +C955 C9 FF A:FF X:00 Y:00 P:E4 SP:FB CYC:591 +C957 D0 05 A:FF X:00 Y:00 P:67 SP:FB CYC:593 +C959 50 03 A:FF X:00 Y:00 P:67 SP:FB CYC:595 +C95B 4C 62 C9 A:FF X:00 Y:00 P:67 SP:FB CYC:597 +C962 EA A:FF X:00 Y:00 P:67 SP:FB CYC:600 +C963 18 A:FF X:00 Y:00 P:67 SP:FB CYC:602 +C964 24 01 A:FF X:00 Y:00 P:66 SP:FB CYC:604 +C966 A9 7F A:FF X:00 Y:00 P:E4 SP:FB CYC:607 +C968 69 80 A:7F X:00 Y:00 P:64 SP:FB CYC:609 +C96A 10 0B A:FF X:00 Y:00 P:A4 SP:FB CYC:611 +C96C B0 09 A:FF X:00 Y:00 P:A4 SP:FB CYC:613 +C96E C9 FF A:FF X:00 Y:00 P:A4 SP:FB CYC:615 +C970 D0 05 A:FF X:00 Y:00 P:27 SP:FB CYC:617 +C972 70 03 A:FF X:00 Y:00 P:27 SP:FB CYC:619 +C974 4C 7B C9 A:FF X:00 Y:00 P:27 SP:FB CYC:621 +C97B EA A:FF X:00 Y:00 P:27 SP:FB CYC:624 +C97C 38 A:FF X:00 Y:00 P:27 SP:FB CYC:626 +C97D B8 A:FF X:00 Y:00 P:27 SP:FB CYC:628 +C97E A9 7F A:FF X:00 Y:00 P:27 SP:FB CYC:630 +C980 69 80 A:7F X:00 Y:00 P:25 SP:FB CYC:632 +C982 D0 09 A:00 X:00 Y:00 P:27 SP:FB CYC:634 +C984 30 07 A:00 X:00 Y:00 P:27 SP:FB CYC:636 +C986 70 05 A:00 X:00 Y:00 P:27 SP:FB CYC:638 +C988 90 03 A:00 X:00 Y:00 P:27 SP:FB CYC:640 +C98A 4C 91 C9 A:00 X:00 Y:00 P:27 SP:FB CYC:642 +C991 EA A:00 X:00 Y:00 P:27 SP:FB CYC:645 +C992 38 A:00 X:00 Y:00 P:27 SP:FB CYC:647 +C993 B8 A:00 X:00 Y:00 P:27 SP:FB CYC:649 +C994 A9 9F A:00 X:00 Y:00 P:27 SP:FB CYC:651 +C996 F0 09 A:9F X:00 Y:00 P:A5 SP:FB CYC:653 +C998 10 07 A:9F X:00 Y:00 P:A5 SP:FB CYC:655 +C99A 70 05 A:9F X:00 Y:00 P:A5 SP:FB CYC:657 +C99C 90 03 A:9F X:00 Y:00 P:A5 SP:FB CYC:659 +C99E 4C A5 C9 A:9F X:00 Y:00 P:A5 SP:FB CYC:661 +C9A5 EA A:9F X:00 Y:00 P:A5 SP:FB CYC:664 +C9A6 18 A:9F X:00 Y:00 P:A5 SP:FB CYC:666 +C9A7 24 01 A:9F X:00 Y:00 P:A4 SP:FB CYC:668 +C9A9 A9 00 A:9F X:00 Y:00 P:E4 SP:FB CYC:671 +C9AB D0 09 A:00 X:00 Y:00 P:66 SP:FB CYC:673 +C9AD 30 07 A:00 X:00 Y:00 P:66 SP:FB CYC:675 +C9AF 50 05 A:00 X:00 Y:00 P:66 SP:FB CYC:677 +C9B1 B0 03 A:00 X:00 Y:00 P:66 SP:FB CYC:679 +C9B3 4C BA C9 A:00 X:00 Y:00 P:66 SP:FB CYC:681 +C9BA EA A:00 X:00 Y:00 P:66 SP:FB CYC:684 +C9BB 24 01 A:00 X:00 Y:00 P:66 SP:FB CYC:686 +C9BD A9 40 A:00 X:00 Y:00 P:E6 SP:FB CYC:689 +C9BF C9 40 A:40 X:00 Y:00 P:64 SP:FB CYC:691 +C9C1 30 09 A:40 X:00 Y:00 P:67 SP:FB CYC:693 +C9C3 90 07 A:40 X:00 Y:00 P:67 SP:FB CYC:695 +C9C5 D0 05 A:40 X:00 Y:00 P:67 SP:FB CYC:697 +C9C7 50 03 A:40 X:00 Y:00 P:67 SP:FB CYC:699 +C9C9 4C D0 C9 A:40 X:00 Y:00 P:67 SP:FB CYC:701 +C9D0 EA A:40 X:00 Y:00 P:67 SP:FB CYC:704 +C9D1 B8 A:40 X:00 Y:00 P:67 SP:FB CYC:706 +C9D2 C9 3F A:40 X:00 Y:00 P:27 SP:FB CYC:708 +C9D4 F0 09 A:40 X:00 Y:00 P:25 SP:FB CYC:710 +C9D6 30 07 A:40 X:00 Y:00 P:25 SP:FB CYC:712 +C9D8 90 05 A:40 X:00 Y:00 P:25 SP:FB CYC:714 +C9DA 70 03 A:40 X:00 Y:00 P:25 SP:FB CYC:716 +C9DC 4C E3 C9 A:40 X:00 Y:00 P:25 SP:FB CYC:718 +C9E3 EA A:40 X:00 Y:00 P:25 SP:FB CYC:721 +C9E4 C9 41 A:40 X:00 Y:00 P:25 SP:FB CYC:723 +C9E6 F0 07 A:40 X:00 Y:00 P:A4 SP:FB CYC:725 +C9E8 10 05 A:40 X:00 Y:00 P:A4 SP:FB CYC:727 +C9EA 10 03 A:40 X:00 Y:00 P:A4 SP:FB CYC:729 +C9EC 4C F3 C9 A:40 X:00 Y:00 P:A4 SP:FB CYC:731 +C9F3 EA A:40 X:00 Y:00 P:A4 SP:FB CYC:734 +C9F4 A9 80 A:40 X:00 Y:00 P:A4 SP:FB CYC:736 +C9F6 C9 00 A:80 X:00 Y:00 P:A4 SP:FB CYC:738 +C9F8 F0 07 A:80 X:00 Y:00 P:A5 SP:FB CYC:740 +C9FA 10 05 A:80 X:00 Y:00 P:A5 SP:FB CYC:742 +C9FC 90 03 A:80 X:00 Y:00 P:A5 SP:FB CYC:744 +C9FE 4C 05 CA A:80 X:00 Y:00 P:A5 SP:FB CYC:746 +CA05 EA A:80 X:00 Y:00 P:A5 SP:FB CYC:749 +CA06 C9 80 A:80 X:00 Y:00 P:A5 SP:FB CYC:751 +CA08 D0 07 A:80 X:00 Y:00 P:27 SP:FB CYC:753 +CA0A 30 05 A:80 X:00 Y:00 P:27 SP:FB CYC:755 +CA0C 90 03 A:80 X:00 Y:00 P:27 SP:FB CYC:757 +CA0E 4C 15 CA A:80 X:00 Y:00 P:27 SP:FB CYC:759 +CA15 EA A:80 X:00 Y:00 P:27 SP:FB CYC:762 +CA16 C9 81 A:80 X:00 Y:00 P:27 SP:FB CYC:764 +CA18 B0 07 A:80 X:00 Y:00 P:A4 SP:FB CYC:766 +CA1A F0 05 A:80 X:00 Y:00 P:A4 SP:FB CYC:768 +CA1C 10 03 A:80 X:00 Y:00 P:A4 SP:FB CYC:770 +CA1E 4C 25 CA A:80 X:00 Y:00 P:A4 SP:FB CYC:772 +CA25 EA A:80 X:00 Y:00 P:A4 SP:FB CYC:775 +CA26 C9 7F A:80 X:00 Y:00 P:A4 SP:FB CYC:777 +CA28 90 07 A:80 X:00 Y:00 P:25 SP:FB CYC:779 +CA2A F0 05 A:80 X:00 Y:00 P:25 SP:FB CYC:781 +CA2C 30 03 A:80 X:00 Y:00 P:25 SP:FB CYC:783 +CA2E 4C 35 CA A:80 X:00 Y:00 P:25 SP:FB CYC:785 +CA35 EA A:80 X:00 Y:00 P:25 SP:FB CYC:788 +CA36 24 01 A:80 X:00 Y:00 P:25 SP:FB CYC:790 +CA38 A0 40 A:80 X:00 Y:00 P:E5 SP:FB CYC:793 +CA3A C0 40 A:80 X:00 Y:40 P:65 SP:FB CYC:795 +CA3C D0 09 A:80 X:00 Y:40 P:67 SP:FB CYC:797 +CA3E 30 07 A:80 X:00 Y:40 P:67 SP:FB CYC:799 +CA40 90 05 A:80 X:00 Y:40 P:67 SP:FB CYC:801 +CA42 50 03 A:80 X:00 Y:40 P:67 SP:FB CYC:803 +CA44 4C 4B CA A:80 X:00 Y:40 P:67 SP:FB CYC:805 +CA4B EA A:80 X:00 Y:40 P:67 SP:FB CYC:808 +CA4C B8 A:80 X:00 Y:40 P:67 SP:FB CYC:810 +CA4D C0 3F A:80 X:00 Y:40 P:27 SP:FB CYC:812 +CA4F F0 09 A:80 X:00 Y:40 P:25 SP:FB CYC:814 +CA51 30 07 A:80 X:00 Y:40 P:25 SP:FB CYC:816 +CA53 90 05 A:80 X:00 Y:40 P:25 SP:FB CYC:818 +CA55 70 03 A:80 X:00 Y:40 P:25 SP:FB CYC:820 +CA57 4C 5E CA A:80 X:00 Y:40 P:25 SP:FB CYC:822 +CA5E EA A:80 X:00 Y:40 P:25 SP:FB CYC:825 +CA5F C0 41 A:80 X:00 Y:40 P:25 SP:FB CYC:827 +CA61 F0 07 A:80 X:00 Y:40 P:A4 SP:FB CYC:829 +CA63 10 05 A:80 X:00 Y:40 P:A4 SP:FB CYC:831 +CA65 10 03 A:80 X:00 Y:40 P:A4 SP:FB CYC:833 +CA67 4C 6E CA A:80 X:00 Y:40 P:A4 SP:FB CYC:835 +CA6E EA A:80 X:00 Y:40 P:A4 SP:FB CYC:838 +CA6F A0 80 A:80 X:00 Y:40 P:A4 SP:FB CYC:840 +CA71 C0 00 A:80 X:00 Y:80 P:A4 SP:FB CYC:842 +CA73 F0 07 A:80 X:00 Y:80 P:A5 SP:FB CYC:844 +CA75 10 05 A:80 X:00 Y:80 P:A5 SP:FB CYC:846 +CA77 90 03 A:80 X:00 Y:80 P:A5 SP:FB CYC:848 +CA79 4C 80 CA A:80 X:00 Y:80 P:A5 SP:FB CYC:850 +CA80 EA A:80 X:00 Y:80 P:A5 SP:FB CYC:853 +CA81 C0 80 A:80 X:00 Y:80 P:A5 SP:FB CYC:855 +CA83 D0 07 A:80 X:00 Y:80 P:27 SP:FB CYC:857 +CA85 30 05 A:80 X:00 Y:80 P:27 SP:FB CYC:859 +CA87 90 03 A:80 X:00 Y:80 P:27 SP:FB CYC:861 +CA89 4C 90 CA A:80 X:00 Y:80 P:27 SP:FB CYC:863 +CA90 EA A:80 X:00 Y:80 P:27 SP:FB CYC:866 +CA91 C0 81 A:80 X:00 Y:80 P:27 SP:FB CYC:868 +CA93 B0 07 A:80 X:00 Y:80 P:A4 SP:FB CYC:870 +CA95 F0 05 A:80 X:00 Y:80 P:A4 SP:FB CYC:872 +CA97 10 03 A:80 X:00 Y:80 P:A4 SP:FB CYC:874 +CA99 4C A0 CA A:80 X:00 Y:80 P:A4 SP:FB CYC:876 +CAA0 EA A:80 X:00 Y:80 P:A4 SP:FB CYC:879 +CAA1 C0 7F A:80 X:00 Y:80 P:A4 SP:FB CYC:881 +CAA3 90 07 A:80 X:00 Y:80 P:25 SP:FB CYC:883 +CAA5 F0 05 A:80 X:00 Y:80 P:25 SP:FB CYC:885 +CAA7 30 03 A:80 X:00 Y:80 P:25 SP:FB CYC:887 +CAA9 4C B0 CA A:80 X:00 Y:80 P:25 SP:FB CYC:889 +CAB0 EA A:80 X:00 Y:80 P:25 SP:FB CYC:892 +CAB1 24 01 A:80 X:00 Y:80 P:25 SP:FB CYC:894 +CAB3 A2 40 A:80 X:00 Y:80 P:E5 SP:FB CYC:897 +CAB5 E0 40 A:80 X:40 Y:80 P:65 SP:FB CYC:899 +CAB7 D0 09 A:80 X:40 Y:80 P:67 SP:FB CYC:901 +CAB9 30 07 A:80 X:40 Y:80 P:67 SP:FB CYC:903 +CABB 90 05 A:80 X:40 Y:80 P:67 SP:FB CYC:905 +CABD 50 03 A:80 X:40 Y:80 P:67 SP:FB CYC:907 +CABF 4C C6 CA A:80 X:40 Y:80 P:67 SP:FB CYC:909 +CAC6 EA A:80 X:40 Y:80 P:67 SP:FB CYC:912 +CAC7 B8 A:80 X:40 Y:80 P:67 SP:FB CYC:914 +CAC8 E0 3F A:80 X:40 Y:80 P:27 SP:FB CYC:916 +CACA F0 09 A:80 X:40 Y:80 P:25 SP:FB CYC:918 +CACC 30 07 A:80 X:40 Y:80 P:25 SP:FB CYC:920 +CACE 90 05 A:80 X:40 Y:80 P:25 SP:FB CYC:922 +CAD0 70 03 A:80 X:40 Y:80 P:25 SP:FB CYC:924 +CAD2 4C D9 CA A:80 X:40 Y:80 P:25 SP:FB CYC:926 +CAD9 EA A:80 X:40 Y:80 P:25 SP:FB CYC:929 +CADA E0 41 A:80 X:40 Y:80 P:25 SP:FB CYC:931 +CADC F0 07 A:80 X:40 Y:80 P:A4 SP:FB CYC:933 +CADE 10 05 A:80 X:40 Y:80 P:A4 SP:FB CYC:935 +CAE0 10 03 A:80 X:40 Y:80 P:A4 SP:FB CYC:937 +CAE2 4C E9 CA A:80 X:40 Y:80 P:A4 SP:FB CYC:939 +CAE9 EA A:80 X:40 Y:80 P:A4 SP:FB CYC:942 +CAEA A2 80 A:80 X:40 Y:80 P:A4 SP:FB CYC:944 +CAEC E0 00 A:80 X:80 Y:80 P:A4 SP:FB CYC:946 +CAEE F0 07 A:80 X:80 Y:80 P:A5 SP:FB CYC:948 +CAF0 10 05 A:80 X:80 Y:80 P:A5 SP:FB CYC:950 +CAF2 90 03 A:80 X:80 Y:80 P:A5 SP:FB CYC:952 +CAF4 4C FB CA A:80 X:80 Y:80 P:A5 SP:FB CYC:954 +CAFB EA A:80 X:80 Y:80 P:A5 SP:FB CYC:957 +CAFC E0 80 A:80 X:80 Y:80 P:A5 SP:FB CYC:959 +CAFE D0 07 A:80 X:80 Y:80 P:27 SP:FB CYC:961 +CB00 30 05 A:80 X:80 Y:80 P:27 SP:FB CYC:963 +CB02 90 03 A:80 X:80 Y:80 P:27 SP:FB CYC:965 +CB04 4C 0B CB A:80 X:80 Y:80 P:27 SP:FB CYC:967 +CB0B EA A:80 X:80 Y:80 P:27 SP:FB CYC:970 +CB0C E0 81 A:80 X:80 Y:80 P:27 SP:FB CYC:972 +CB0E B0 07 A:80 X:80 Y:80 P:A4 SP:FB CYC:974 +CB10 F0 05 A:80 X:80 Y:80 P:A4 SP:FB CYC:976 +CB12 10 03 A:80 X:80 Y:80 P:A4 SP:FB CYC:978 +CB14 4C 1B CB A:80 X:80 Y:80 P:A4 SP:FB CYC:980 +CB1B EA A:80 X:80 Y:80 P:A4 SP:FB CYC:983 +CB1C E0 7F A:80 X:80 Y:80 P:A4 SP:FB CYC:985 +CB1E 90 07 A:80 X:80 Y:80 P:25 SP:FB CYC:987 +CB20 F0 05 A:80 X:80 Y:80 P:25 SP:FB CYC:989 +CB22 30 03 A:80 X:80 Y:80 P:25 SP:FB CYC:991 +CB24 4C 2B CB A:80 X:80 Y:80 P:25 SP:FB CYC:993 +CB2B EA A:80 X:80 Y:80 P:25 SP:FB CYC:996 +CB2C 38 A:80 X:80 Y:80 P:25 SP:FB CYC:998 +CB2D B8 A:80 X:80 Y:80 P:25 SP:FB CYC:1000 +CB2E A2 9F A:80 X:80 Y:80 P:25 SP:FB CYC:1002 +CB30 F0 09 A:80 X:9F Y:80 P:A5 SP:FB CYC:1004 +CB32 10 07 A:80 X:9F Y:80 P:A5 SP:FB CYC:1006 +CB34 70 05 A:80 X:9F Y:80 P:A5 SP:FB CYC:1008 +CB36 90 03 A:80 X:9F Y:80 P:A5 SP:FB CYC:1010 +CB38 4C 3F CB A:80 X:9F Y:80 P:A5 SP:FB CYC:1012 +CB3F EA A:80 X:9F Y:80 P:A5 SP:FB CYC:1015 +CB40 18 A:80 X:9F Y:80 P:A5 SP:FB CYC:1017 +CB41 24 01 A:80 X:9F Y:80 P:A4 SP:FB CYC:1019 +CB43 A2 00 A:80 X:9F Y:80 P:E4 SP:FB CYC:1022 +CB45 D0 09 A:80 X:00 Y:80 P:66 SP:FB CYC:1024 +CB47 30 07 A:80 X:00 Y:80 P:66 SP:FB CYC:1026 +CB49 50 05 A:80 X:00 Y:80 P:66 SP:FB CYC:1028 +CB4B B0 03 A:80 X:00 Y:80 P:66 SP:FB CYC:1030 +CB4D 4C 54 CB A:80 X:00 Y:80 P:66 SP:FB CYC:1032 +CB54 EA A:80 X:00 Y:80 P:66 SP:FB CYC:1035 +CB55 38 A:80 X:00 Y:80 P:66 SP:FB CYC:1037 +CB56 B8 A:80 X:00 Y:80 P:67 SP:FB CYC:1039 +CB57 A0 9F A:80 X:00 Y:80 P:27 SP:FB CYC:1041 +CB59 F0 09 A:80 X:00 Y:9F P:A5 SP:FB CYC:1043 +CB5B 10 07 A:80 X:00 Y:9F P:A5 SP:FB CYC:1045 +CB5D 70 05 A:80 X:00 Y:9F P:A5 SP:FB CYC:1047 +CB5F 90 03 A:80 X:00 Y:9F P:A5 SP:FB CYC:1049 +CB61 4C 68 CB A:80 X:00 Y:9F P:A5 SP:FB CYC:1051 +CB68 EA A:80 X:00 Y:9F P:A5 SP:FB CYC:1054 +CB69 18 A:80 X:00 Y:9F P:A5 SP:FB CYC:1056 +CB6A 24 01 A:80 X:00 Y:9F P:A4 SP:FB CYC:1058 +CB6C A0 00 A:80 X:00 Y:9F P:E4 SP:FB CYC:1061 +CB6E D0 09 A:80 X:00 Y:00 P:66 SP:FB CYC:1063 +CB70 30 07 A:80 X:00 Y:00 P:66 SP:FB CYC:1065 +CB72 50 05 A:80 X:00 Y:00 P:66 SP:FB CYC:1067 +CB74 B0 03 A:80 X:00 Y:00 P:66 SP:FB CYC:1069 +CB76 4C 7D CB A:80 X:00 Y:00 P:66 SP:FB CYC:1071 +CB7D EA A:80 X:00 Y:00 P:66 SP:FB CYC:1074 +CB7E A9 55 A:80 X:00 Y:00 P:66 SP:FB CYC:1076 +CB80 A2 AA A:55 X:00 Y:00 P:64 SP:FB CYC:1078 +CB82 A0 33 A:55 X:AA Y:00 P:E4 SP:FB CYC:1080 +CB84 C9 55 A:55 X:AA Y:33 P:64 SP:FB CYC:1082 +CB86 D0 23 A:55 X:AA Y:33 P:67 SP:FB CYC:1084 +CB88 E0 AA A:55 X:AA Y:33 P:67 SP:FB CYC:1086 +CB8A D0 1F A:55 X:AA Y:33 P:67 SP:FB CYC:1088 +CB8C C0 33 A:55 X:AA Y:33 P:67 SP:FB CYC:1090 +CB8E D0 1B A:55 X:AA Y:33 P:67 SP:FB CYC:1092 +CB90 C9 55 A:55 X:AA Y:33 P:67 SP:FB CYC:1094 +CB92 D0 17 A:55 X:AA Y:33 P:67 SP:FB CYC:1096 +CB94 E0 AA A:55 X:AA Y:33 P:67 SP:FB CYC:1098 +CB96 D0 13 A:55 X:AA Y:33 P:67 SP:FB CYC:1100 +CB98 C0 33 A:55 X:AA Y:33 P:67 SP:FB CYC:1102 +CB9A D0 0F A:55 X:AA Y:33 P:67 SP:FB CYC:1104 +CB9C C9 56 A:55 X:AA Y:33 P:67 SP:FB CYC:1106 +CB9E F0 0B A:55 X:AA Y:33 P:E4 SP:FB CYC:1108 +CBA0 E0 AB A:55 X:AA Y:33 P:E4 SP:FB CYC:1110 +CBA2 F0 07 A:55 X:AA Y:33 P:E4 SP:FB CYC:1112 +CBA4 C0 34 A:55 X:AA Y:33 P:E4 SP:FB CYC:1114 +CBA6 F0 03 A:55 X:AA Y:33 P:E4 SP:FB CYC:1116 +CBA8 4C AF CB A:55 X:AA Y:33 P:E4 SP:FB CYC:1118 +CBAF A0 71 A:55 X:AA Y:33 P:E4 SP:FB CYC:1121 +CBB1 20 31 F9 A:55 X:AA Y:71 P:64 SP:FB CYC:1123 +F931 24 01 A:55 X:AA Y:71 P:64 SP:F9 CYC:1129 +F933 A9 40 A:55 X:AA Y:71 P:E4 SP:F9 CYC:1132 +F935 38 A:40 X:AA Y:71 P:64 SP:F9 CYC:1134 +F936 60 A:40 X:AA Y:71 P:65 SP:F9 CYC:1136 +CBB4 E9 40 A:40 X:AA Y:71 P:65 SP:FB CYC:1142 +CBB6 20 37 F9 A:00 X:AA Y:71 P:27 SP:FB CYC:1144 +F937 30 0B A:00 X:AA Y:71 P:27 SP:F9 CYC:1150 +F939 90 09 A:00 X:AA Y:71 P:27 SP:F9 CYC:1152 +F93B D0 07 A:00 X:AA Y:71 P:27 SP:F9 CYC:1154 +F93D 70 05 A:00 X:AA Y:71 P:27 SP:F9 CYC:1156 +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 diff --git a/src/cpu.rs b/src/cpu.rs index 1cd8113..c33a3b6 100644 --- a/src/cpu.rs +++ b/src/cpu.rs @@ -97,17 +97,17 @@ impl Cpu { let opcode: u8 = self.fetch(bus); let cycles = match opcode { // Jumps & subroutines - 0x4C => self.jmp_abs(bus), 0x20 => self.jsr_abs(bus), 0x60 => self.rts_imp(bus), + 0x4C => self.jmp_abs(bus), 0x20 => self.jsr_abs(bus), 0x60 => self.rts_imp(bus), 0x40 => self.rti_imp(bus), 0x00 => self.brk_imp(bus), // Stack - 0x48 => self.pha_imp(bus), 0x68 => self.pla_imp(bus), 0x08 => self.php_imp(bus), + 0x48 => self.pha_imp(bus), 0x68 => self.pla_imp(bus), 0x08 => self.php_imp(bus), 0x28 => self.plp_imp(bus), // Flags & misc - 0x38 => self.sec_imp(bus), 0x18 => self.clc_imp(bus), 0x58 => self.cli_imp(bus), - 0x78 => self.sei_imp(bus), 0xD8 => self.cld_imp(bus), 0xF8 => self.sed_imp(bus), + 0x38 => self.sec_imp(bus), 0x18 => self.clc_imp(bus), 0x58 => self.cli_imp(bus), + 0x78 => self.sei_imp(bus), 0xD8 => self.cld_imp(bus), 0xF8 => self.sed_imp(bus), 0xB8 => self.clv_imp(bus), 0xEA => self.nop_imp(bus), // Branches - 0x90 => self.bcc_rel(bus), 0xB0 => self.bcs_rel(bus), 0xF0 => self.beq_rel(bus), + 0x90 => self.bcc_rel(bus), 0xB0 => self.bcs_rel(bus), 0xF0 => self.beq_rel(bus), 0xD0 => self.bne_rel(bus), 0x10 => self.bpl_rel(bus), 0x30 => self.bmi_rel(bus), 0x50 => self.bvc_rel(bus), 0x70 => self.bvs_rel(bus), // Loads @@ -136,13 +136,25 @@ impl Cpu { 0xE5 => self.sbc_zp(bus), 0xF5 => self.sbc_zpx(bus), 0xED => self.sbc_abs(bus), 0xFD => self.sbc_abx(bus), 0xF9 => self.sbc_aby(bus), 0xE1 => self.sbc_izx(bus), 0xF1 => self.sbc_izy(bus), 0x24 => self.bit_zp(bus), 0x2C => self.bit_abs(bus), + // Binary - AND + 0x29 => self.and_imm(bus), 0x25 => self.and_zp(bus), 0x35 => self.and_zpx(bus), + 0x2D => self.and_abs(bus), 0x3D => self.and_abx(bus), 0x39 => self.and_aby(bus), + 0x21 => self.and_izx(bus), 0x31 => self.and_izy(bus), + // Binary - ORA + 0x09 => self.ora_imm(bus), 0x05 => self.ora_zp(bus), 0x15 => self.ora_zpx(bus), + 0x0D => self.ora_abs(bus), 0x1D => self.ora_abx(bus), 0x19 => self.ora_aby(bus), + 0x01 => self.ora_izx(bus), 0x11 => self.ora_izy(bus), + // Binary - EOR + 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), _ => panic!("illegal/unkown opcode {opcode:#04X} at {:#06X}", self.pc.wrapping_sub(1)), }; self.cycles += cycles as u64; cycles } - // NES 6502 opcode length table/matcher + // NES 6502 opcode length table/matcher; note: this one could be seem as redudant but i like it so deal with it >:3, also it would be used by the GUI later pub fn opcode_len(opcode: u8) -> u8 { match opcode { 0x4C => 3, /* JMP abs */ 0xA2 => 2, /* LDX imm */ 0x86 => 2, /* STX zp */ 0x20 => 3, /* JSR abs */ @@ -167,6 +179,12 @@ impl Cpu { 0x61 => 2, /* ADC izx */ 0x71 => 2, /* ADC izy */ 0xE9 => 2, /* SBC imm */ 0xE5 => 2, /* SBC zp */ 0xF5 => 2, /* SBC zpx */ 0xED => 3, /* SBC abs */ 0xFD => 3, /* SBC abx */ 0xF9 => 3, /* SBC aby */ 0xE1 => 2, /* SBC izx */ 0xF1 => 2, /* SBC izy */ 0x24 => 2, /* BIT zp */ 0x2C => 3, /* BIT abs */ + 0x29 => 2, /* AND imm */ 0x25 => 2, /* AND zp */ 0x35 => 2, /* AND zpx */ 0x2D => 3, /* AND abs */ + 0x3D => 3, /* AND abx */ 0x39 => 3, /* AND aby */ 0x21 => 2, /* AND izx */ 0x31 => 2, /* AND izy */ + 0x09 => 2, /* ORA imm */ 0x05 => 2, /* ORA zp */ 0x15 => 2, /* ORA zpx */ 0x0D => 3, /* ORA abs */ + 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 */ _ => 1, // fallback, would show the invalid/unknown opcode only not its parameters } } @@ -234,7 +252,7 @@ impl Cpu { (address, extra) } - fn address_ind(&mut self, bus: &mut impl Bus) -> (u16, u8) { // used by JMP instruction + hardware bug where the page wraps around + fn address_ind(&mut self, bus: &mut impl Bus) -> (u16, u8) { // used by JMP (indirect) instruction + hardware bug where the page wraps around let ptr: u16 = self.fetch16(bus); // pointer itself let low: u16 = self.read(bus, ptr) as u16; let high_ptr: u16 = (ptr & 0xFF00) | (ptr.wrapping_add(1) & 0x00FF); // Hardware bug wrap here @@ -363,6 +381,29 @@ impl Cpu { base + extra } + // AND core (AND binary operation) + fn and(&mut self, bus: &mut impl Bus, (address, extra): (u16, u8), base: u8) -> u8 { + let value = self.read(bus, address); + self.a &= value; + self.set_zp_flags(self.a); + base + extra + } + + // ORA core (OR binary operation) + fn ora(&mut self, bus: &mut impl Bus, (address, extra): (u16, u8), base: u8) -> u8 { + let value = self.read(bus, address); + self.a |= value; + self.set_zp_flags(self.a); + base + extra + } + + // EOR core (Exclusive-OR binary operation) + fn eor(&mut self, bus: &mut impl Bus, (address, extra): (u16, u8), base: u8) -> u8 { + let value = self.read(bus, address); + self.a ^= value; + self.set_zp_flags(self.a); + base + extra + } // NES 6502 opcode -> functions fn jmp_abs(&mut self, bus: &mut impl Bus) -> u8 { // 0x4C, 3 bytes, 3 cycles @@ -798,7 +839,137 @@ impl Cpu { 2 } - // all branching alternatives here all 1 bytes + // AND variants + fn and_zp(&mut self, bus: &mut impl Bus) -> u8 { // 0x25, 2 bytes, 3 cycles + let (address, extra) = self.address_zp(bus); + self.and(bus, (address, extra), 3) + } + + fn and_zpx(&mut self, bus: &mut impl Bus) -> u8 { // 0x35, 2 bytes, 4 cycles + let (address, extra) = self.address_zpx(bus); + self.and(bus, (address, extra), 4) + } + + fn and_abs(&mut self, bus: &mut impl Bus) -> u8 { // 0x2D, 3 bytes, 4 cycles + let (address, extra) = self.address_abs(bus); + self.and(bus, (address, extra), 4) + } + + fn and_abx(&mut self, bus: &mut impl Bus) -> u8 { // 0x3D, 3 bytes, 4 cycles + let (address, extra) = self.address_abx(bus); + self.and(bus, (address, extra), 4) + } + + fn and_aby(&mut self, bus: &mut impl Bus) -> u8 { // 0x39, 3 bytes, 4 cycles + let (address, extra) = self.address_aby(bus); + self.and(bus, (address, extra), 4) + } + + fn and_izx(&mut self, bus: &mut impl Bus) -> u8 { // 0x21, 2 bytes, 6 cycles + let (address, extra) = self.address_izx(bus); + self.and(bus, (address, extra), 6) + } + + fn and_izy(&mut self, bus: &mut impl Bus) -> u8 { // 0x31, 2 bytes, 5 cycles + let (address, extra) = self.address_izy(bus); + self.and(bus, (address, extra), 5) + } + + // ORA variants + fn ora_zp(&mut self, bus: &mut impl Bus) -> u8 { // 0x05, 2 bytes, 3 cycles + let (address, extra) = self.address_zp(bus); + self.ora(bus, (address, extra), 3) + } + + fn ora_zpx(&mut self, bus: &mut impl Bus) -> u8 { // 0x15, 2 bytes, 4 cycles + let (address, extra) = self.address_zpx(bus); + self.ora(bus, (address, extra), 4) + } + + fn ora_abs(&mut self, bus: &mut impl Bus) -> u8 { // 0x0D, 3 bytes, 4 cycles + let (address, extra) = self.address_abs(bus); + self.ora(bus, (address, extra), 4) + } + + fn ora_abx(&mut self, bus: &mut impl Bus) -> u8 { // 0x1D, 3 bytes, 4 cycles + let (address, extra) = self.address_abx(bus); + self.ora(bus, (address, extra), 4) + } + + fn ora_aby(&mut self, bus: &mut impl Bus) -> u8 { // 0x19, 3 bytes, 4 cycles + let (address, extra) = self.address_aby(bus); + self.ora(bus, (address, extra), 4) + } + + fn ora_izx(&mut self, bus: &mut impl Bus) -> u8 { // 0x01, 2 bytes, 6 cycles + let (address, extra) = self.address_izx(bus); + self.ora(bus, (address, extra), 6) + } + + fn ora_izy(&mut self, bus: &mut impl Bus) -> u8 { // 0x11, 2 bytes, 5 cycles + let (address, extra) = self.address_izy(bus); + self.ora(bus, (address, extra), 5) + } + + // EOR variants + fn eor_zp(&mut self, bus: &mut impl Bus) -> u8 { // 0x45, 2 bytes, 3 cycles + let (address, extra) = self.address_zp(bus); + self.eor(bus, (address, extra), 3) + } + + fn eor_zpx(&mut self, bus: &mut impl Bus) -> u8 { // 0x55, 2 bytes, 4 cycles + let (address, extra) = self.address_zpx(bus); + self.eor(bus, (address, extra), 4) + } + + fn eor_abs(&mut self, bus: &mut impl Bus) -> u8 { // 0x4D, 3 bytes, 4 cycles + let (address, extra) = self.address_abs(bus); + self.eor(bus, (address, extra), 4) + } + + fn eor_abx(&mut self, bus: &mut impl Bus) -> u8 { // 0x5D, 3 bytes, 4 cycles + let (address, extra) = self.address_abx(bus); + self.eor(bus, (address, extra), 4) + } + + fn eor_aby(&mut self, bus: &mut impl Bus) -> u8 { // 0x59, 3 bytes, 4 cycles + let (address, extra) = self.address_aby(bus); + self.eor(bus, (address, extra), 4) + } + + fn eor_izx(&mut self, bus: &mut impl Bus) -> u8 { // 0x41, 2 bytes, 6 cycles + let (address, extra) = self.address_izx(bus); + self.eor(bus, (address, extra), 6) + } + + fn eor_izy(&mut self, bus: &mut impl Bus) -> u8 { // 0x51, 2 bytes, 5 cycles + let (address, extra) = self.address_izy(bus); + self.eor(bus, (address, extra), 5) + } + + // AND immediate variant + fn and_imm(&mut self, bus: &mut impl Bus) -> u8 { // 0x29, 2 bytes, 2 cycles + self.a &= self.fetch(bus); + self.set_zp_flags(self.a); + 2 + } + + // ORA immediate variant + fn ora_imm(&mut self, bus: &mut impl Bus) -> u8 { // 0x09, 2 bytes, 2 cycles + self.a |= self.fetch(bus); + self.set_zp_flags(self.a); + 2 + } + + // EOR immediate variant + fn eor_imm(&mut self, bus: &mut impl Bus) -> u8 { // 0x49, 2 bytes, 2 cycles + self.a ^= self.fetch(bus); + self.set_zp_flags(self.a); + 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 fn bcc_rel(&mut self, bus: &mut impl Bus) -> u8 { self.branch(bus, !self.flag(FLAG_CARRY)) } // 0x90 fn beq_rel(&mut self, bus: &mut impl Bus) -> u8 { self.branch(bus, self.flag(FLAG_ZERO)) } // 0xF0