all 151 offical opcodes implemented
This commit is contained in:
@@ -24,8 +24,11 @@
|
||||
- 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 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 9 done (shifts): ASL, LSR, ROL, ROR (accumulator + 4 memory modes each) via four shift cores (shift_asl/lsr/rol/ror) + wrappers. ROL/ROR read carry-in before overwriting it. Memory shifts follow the RMW fixed-cycle rule. 144 of 151
|
||||
- Batch 10 done (transfers + JMP ind): TAX, TAY, TXA, TYA, TSX, TXS (all 2 cycles; TXS sets NO flags, the other five set Z/N), plus JMP (0x6C) which finally uses address_ind. Resolved the long-standing address_ind dead-code warning
|
||||
- OFFICIAL CPU COMPLETE: all 151 official opcodes implemented. Trace matches the nestest reference log through line 5003 (entire official section), 0 mismatches. Stops at line 5004 (0x04, first illegal opcode) by design
|
||||
- Fixed a latent Batch 4 bug the log caught at line 3319: the sta core added the page-cross extra, but stores have FIXED cycle counts. Fixed sta core to return base without extra, and corrected bases (sta_abx/sta_aby 5, sta_izy 6). Before the fix the diff had a +1 CYC drift from line 3319 onward
|
||||
- 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
|
||||
@@ -36,37 +39,13 @@
|
||||
|
||||
## Next
|
||||
|
||||
Finish the official CPU. Nestest analysis findings: the full 8991-line log tests illegal opcodes too (225 distinct opcodes total; first illegal is 0x04 at line 5004). So the official-only CPU is verified against lines 1-5003, then panics on 0x04 by design. Official opcodes never seen in the log: BRK 0x00, CLI 0x58.
|
||||
Official CPU milestone is COMPLETE (all 151 opcodes, nestest-verified through line 5003). The full 8991-line nestest log tests illegal opcodes too (225 distinct opcodes total; first illegal is 0x04 at line 5004). Official opcodes never seen in the log: BRK 0x00, CLI 0x58.
|
||||
|
||||
CPU implementation batches (by family, ordered by nestest log frequency):
|
||||
|
||||
- Batch 1 - DONE (see Done section)
|
||||
- Batch 2 - DONE (branches, see Done section)
|
||||
- Batch 3 - DONE (loads, see Done section)
|
||||
- Batch 4 - DONE (stores, see Done section)
|
||||
- Batch 5 - DONE (compares, see Done section)
|
||||
- Batch 6 - DONE (arithmetic, see Done section)
|
||||
- Batch 7 - DONE (logic, see Done section)
|
||||
- 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. 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)
|
||||
- Re-diff after each batch (cargo run > ours.log + awk column compare)
|
||||
- Check base cycles per mode, feed page-cross extra into the cycle total
|
||||
|
||||
Verification for this phase:
|
||||
- All 151 official opcodes implemented
|
||||
- Trace matches lines 1-5003 field-for-field (PC/A/X/Y/P/SP/CYC)
|
||||
- cargo build clean
|
||||
- Commit + update STATE.md
|
||||
|
||||
After official CPU is done (follow-ups):
|
||||
- Add MMC1 (mapper 1) to cartridge so blargg official_only.nes / all_instrs.nes can run (authoritative official check)
|
||||
Follow-up options, in any order:
|
||||
- Illegal-opcode phase: implement the undocumented opcodes (0x04 and friends) for the full 8991-line nestest pass. ~76 illegal opcodes present in the log. Reference: nesdev wiki undocumented opcode table
|
||||
- MMC1 (mapper 1) in the cartridge so blargg official_only.nes / all_instrs.nes can run (authoritative official check)
|
||||
- Run blargg mapper-0 suite (coredump, cpu_timing_test, ram_after_reset, registers)
|
||||
- Then the illegal-opcode phase for the full 8991-line nestest pass
|
||||
- Then bus/PPU/timing, GUI (egui + winit) come after the CPU milestone
|
||||
- Then PPU/bus/timing, GUI (egui + winit) come after the CPU milestone
|
||||
|
||||
## Decisions
|
||||
|
||||
|
||||
Reference in New Issue
Block a user