1
0
mirror of https://github.com/mre/mos6502.git synced 2026-04-19 14:16:52 +00:00

402 Commits

Author SHA1 Message Date
Matthias Endler 6e6af71449 Update CI workflow to use latest actions and simplify steps (#132) 2026-03-16 12:54:58 +01:00
Matthieu Felix ccabb92791 Bump version to 0.9.0 v0.9.0 2026-03-15 07:01:36 +00:00
Matt 1516450136 Support parameterizing the Cmos Variant 2026-03-15 07:01:36 +00:00
Matt 3ae4996fc9 Replace BBRn with BBR(u8)
As well as bbs/smr/rmb.
2026-03-15 07:01:36 +00:00
Matthieu Felix 67f0a60f92 Fix lints 2026-03-15 07:01:36 +00:00
Matthieu Felix 8a3bb391d8 Klaus Dormann 65C02 extended opcodes test 2026-03-15 07:01:36 +00:00
Matthieu Felix deb2951a9b Add 65C02 nop instructions + DEC/INC A 2026-03-15 07:01:36 +00:00
Matthieu Felix b79eb178fe Fix various flag issues 2026-03-15 07:01:36 +00:00
Matthieu Felix 935857a0e2 Add BBS/BBR/RMB/SMB instructions to 65C02
Definitions and cycle timings from https://www.masswerk.at/6502/6502_instruction_set.html.
2026-03-15 07:01:36 +00:00
Matthieu Felix 112b7c9f21 Testing improvements
1. Run Klaus Dormann tests with both NMOS and CMOS variants
2. panic when reaching an unsupported (instruction, addressing mode) combination - this indicates a programming error in the emulator, so I think it's better to fail loudly
2026-03-15 07:01:36 +00:00
Mark Schmelzenbach 93d9fc46ba Fix: Correct cycle counts for branch taken and branch page crossing (#130) 2026-03-09 22:56:00 +01:00
Matthias Endler d66c1e667d Bump version to 0.8.0 (#129)
Closes #128
v.0.8.0
2026-02-06 17:31:32 +01:00
Matthias Endler 9ff04c75f1 Add interrupt handling (NMI, IRQ) and WAI/STP wait states (#122)
Implements hardware interrupt support following the W65C02S datasheet:

Interrupt handling:
- Add nmi_pending() and irq_pending() to Bus trait
- NMI: edge-triggered (falling edge detection)
- IRQ: level-triggered, maskable by I flag
- service_interrupt() pushes PC/status, sets I flag, jumps to vector

Wait states:
- Replace `halted: bool` with WaitState enum (Running,
  WaitingForInterrupt, WaitingForReset)
- WAI instruction waits for interrupt, resumes on IRQ or NMI
- STP instruction waits for reset

Helper methods:
- Add push_address() for pushing 16-bit addresses to stack
- Add set_word() to Bus trait for writing 16-bit values

Testing:
- Integrate Klaus2m5 interrupt test suite
- Add unit tests for IRQ, NMI, and WAI behavior
- Concurrent BRK+IRQ+NMI test disabled (hardware timing edge case)

References:
- W65C02S Datasheet, Section 3.4 (IRQB) and 3.6 (NMIB)
- Klaus2m5/6502_65C02_functional_tests

Closes #64
2026-02-06 17:16:13 +01:00
Matthias 9385b99484 Add buble sort example 2026-02-06 16:42:17 +01:00
omarandlorraine c91d604efe Add support for illegal opcodes (#126)
This adds support for illegal opcodes:
lax, dcp, isc, slo, rla, sre, rra, arr, sbx, las, usbc, jam, nops, sax, xaa, alr, anc

The illegal opcodes implementation caused README doc tests to hang:

1. First example used 0xff as program terminator
   - Previously 0xff was unimplemented (returned None), stopping execution
   - Now 0xff is ISC (INC+SBC) AbsoluteX, causing infinite loop
   - Fix: Use 0x02 (JAM) which explicitly halts the CPU

2. Second example loads euclid.bin which uses BRK (0x00) to terminate
   - BRK jumps to IRQ vector at $FFFE/$FFFF
   - Uninitialized memory contains 0x00, jumping to address $0000
   - This causes infinite loop executing whatever is in low memory
   - Fix: Mark as no_run since it depends on external file anyway

- fix: make euclid.bin example runnable as doc test
- Replace BRK with JAM ($02) to halt CPU after illegal opcodes impl
- Fix assembly label structure (algo/algo_ were dead infinite loops)
- Simplify linker.cfg to output raw binary at $0010 (was 64KB image)
- Enable README doc test (remove no_run marker)

The old linker config produced a 64KB memory image with code at $0400,
but README loaded at $0010 causing address mismatch. New config outputs
only the code segment at the correct load address.

Co-authored-by: mlund <mlund@localhost>
2026-02-06 16:19:01 +01:00
Matthias Endler 3d4af71c8a Add cycle times (#124)
This add cycle times to the emulator. I did some initial research in
docs/CYCLE_TIMINGS.md. There are a few differences between the online
documentation around cycle times. I tried to find the most accurate
cycle timings possible.

In terms of implementation, I tried a few ideas and landed on calculating the cycle times when executing the instructions. That's pretty much what other emulators also do (olcNES in C++, bugzmanov/nes_ebook in Rust, NES-rust).

Things I took into account:
- Base cycles
- Page crossing penalties
- Decimal mode (65C02)
- Address space wrapping

Fixes: #119
2026-01-10 18:02:49 +01:00
Matthias Endler 196f4c118b Complete the WDC 65C02 instruction set implementation (#121)
* Complete the WDC 65C02 instruction set implementation

This commit finishes implementing the standard Western Design Center 65C02
instruction set by adding the last missing instructions.

The main additions are the two low-power instructions WAI (Wait for Interrupt)
and STP (Stop Processor), which allow the CPU to enter power-saving modes. I
also added support for the BIT instruction with indexed addressing modes (zero
page indexed and absolute indexed), and the indexed indirect jump instruction
JMP (abs,X).

Additionally, the Cmos6502 variant now has better documentation that aims to
explain all the improvements over the original NMOS 6502.

This closes issue #120.

* Return a boolean from single_step
2025-12-31 13:15:10 +01:00
Matthias Endler eee00369c9 Add CI tests badge v0.7.0 2025-12-30 19:16:26 +01:00
Matthias Endler 673e7e42e3 Functional Test (#81)
Fixes critical bugs in the 6502 emulator and successfully passes
the Klaus2m5 functional test suite, one of the most complete test
suites for 6502 emulators (~30 million instructions).

Along the way, we fixed stack operation bugs that were preventing proper execution:
- RTI: Removed extra pull_from_stack() and fixed PCH retrieval
- RTS: Removed extra pull_from_stack() and fixed PCH retrieval
- PLA, PLP, PLX, PLY: Fixed to use single pull_from_stack() call
- pull_from_stack: Fixed to increment SP before reading (6502 SP points
to next available slot, not last used)

The emulator now passes one of the most rigorous 6502 test suite that I know of, which provides high confidence in our emulation correctness.
2025-12-30 18:42:23 +01:00
Matthias Endler 4fbc79fe31 Add engaging historical documentation for 6502 variants (#118)
* Add engaging historical documentation for 6502 variants

- Add library-level documentation telling the story of the 6502
- Explain the historical context and cost revolution ( vs  Intel 8080)
- Cover famous systems that used each variant (Apple II, C64, NES, etc.)
- Explain engineering trade-offs driven by cost, patents, and innovation
- Improve Variant trait documentation with historical context
- Make the library more approachable and educational for users

* Move history to README and address PR feedback

- Add History section to README.md before Credits
- Include industrial control as a major use case (embedded systems)
- Clarify Ricoh 2A03 sound generation was in custom ASIC, not emulated
- Simplify lib.rs documentation to focus on API usage
- README already included in rustdoc via include_str macro

* Add Wozniak quote about the 6502

Brief quote from iWoz explaining why he chose the 6502: pin-compatible
with the 6800 and half the price.

* update docs
2025-12-30 17:03:40 +01:00
Matthias Endler 74fa8123c2 Improve SBC behavior for all 6502 variants (#117)
Follow-up to #109. This adds proper SBC (Subtract with Carry) implementations
for all 6502 variants - NMOS 6502, Ricoh2A03 (NES), RevisionA, and 65C02. Each
variant now has dedicated `sbc_binary` and `sbc_decimal` methods that handle the
subtle differences in flag behavior and decimal mode support.

Changes:
- Rename `AdcOutput` to `ArithmeticOutput` for use with both ADC and SBC operations
- Fix incorrect borrow detection logic in SBC implementations
- Add variant-specific SBC methods with proper documentation and processor manual references
- Refactor `Ricoh2a03::adc_binary` to call `Nmos6502::adc_binary` (DRY)
- Change `carry_set` parameter from u8 to bool
- Update all variant implementations, call sites, and tests
- Added references to official processor manuals and behavior notes for each variant.
2025-12-30 14:27:40 +01:00
Matthias Endler f7235f7981 Create NOTES.md 2025-07-31 18:48:02 +02:00
Matthias Endler dcb51dcad9 Fix ADC behavior (#109)
Fix ADC instruction implementation and improve status register management

- Split ADC instruction into separate binary and decimal mode methods
- Introduce structured `AdcOutput` with comparison traits
- Add cleaner status register access with `get_flag`/`set_flag`/`unset_flag` methods
- Improve instruction comments and documentation for Status flags
- Add tests for decimal mode functionality
- Remove deprecated decimal_mode feature flag
- Clean up CI workflow and improve carry addition logic
2025-07-30 12:27:47 +02:00
Matthias Endler 665f1c948a Update Rust edition to 2024 (#114)
* Update Rust edition to 2024

* format
2025-07-30 11:59:23 +02:00
Matthias Endler da6fa8d7e4 Add Dependabot configuration for Rust dependencies (#116)
- Configure weekly dependency updates for Cargo packages
- Limit to 10 open PRs at a time
- Use 'deps:' prefix for commit messages
2025-07-30 11:53:00 +02:00
Matthias b67d2e97c6 Update dependencies 2025-07-30 11:44:38 +02:00
Matthias Endler 4077abecf0 Update FUNDING.yml 2025-07-29 19:26:28 +02:00
Matthias 6486a015b9 format 2025-07-29 19:25:05 +02:00
Matthias d30a36b1fa Update reset sequence documentation with detailed cycle information
- Add detailed 8-cycle breakdown of the reset process
- Include reference to pagetable.com analysis
- Clarify that reset simulates BRK/IRQ/NMI sequence with reads
- Document specific stack addresses and SP decrement behavior
2025-07-29 19:25:05 +02:00
Matthias 9f86cfc2ec format 2025-07-29 19:25:05 +02:00
Matthias 5eb3b8f4d8 Implement 6502 reset sequence
Replace empty reset() method with proper hardware-accurate implementation.
- Decrements stack pointer 3 times (fake stack operations)
- Reads reset vector from /
- Sets program counter and interrupt disable flag
- Includes test for reset behavior
2025-07-29 19:25:05 +02:00
Matthias 222544e60b Fix more lints 2025-07-29 11:44:41 +02:00
Matthias 035ebe3c00 Fix clippy lints 2025-07-29 11:44:41 +02:00
Sam M W 6c6a68aa3a version bump 2024-10-18 21:01:06 +02:00
Matthias 2c65fe7e1b Fix SBC implementation and improve overflow detection
- Correct decimal mode subtraction in SBC operation
- Implement accurate overflow detection for non-decimal mode
- Fix carry flag calculation as inverse of borrow
- Add comments explaining complex bit manipulation for overflow detection
- Update tests to verify correct behavior in both decimal and non-decimal modes

This commit addresses issues with the Subtract with Carry (SBC) operation,
ensuring correct behavior in both decimal and non-decimal modes, and
improves code readability with added comments.
2024-10-18 21:01:06 +02:00
Sam M W 6b7c8a8aab bump version v0.6.1 2024-09-26 09:04:18 +02:00
Sam M W 0c8616acb0 impl Default for CPU 2024-09-26 09:04:18 +02:00
Sam M W 874422b394 impl Default for the Variant types 2024-09-26 09:04:18 +02:00
Sam M W 40710248ff #[allow(clippy::needless_doctest_main)] v0.6.0 2024-07-29 13:13:07 +02:00
Sam M W dbbb4a5ccf remove lint for pointer_structural_match, this is now a hard error 2024-07-29 13:13:07 +02:00
Sam M W b052f9150f version bump 2024-07-29 13:13:07 +02:00
omarandlorraine 265ef6941e Cmos support (#99) 2024-06-07 15:29:40 +01:00
Matthias Endler 467b3ff436 Code Cleanup (#97)
This adds some new directives for clippy and fixes all warnings.
Also updated the dependencies to their latest versions.
2024-04-27 19:51:39 +01:00
Sam M W 4847744518 correction to comment 2024-04-24 14:51:08 +01:00
Matthias Endler 11d9540729 fix typo 2024-04-24 15:41:25 +02:00
Sam M W bf06ad8924 better commenting inside of AddressingMode enum 2024-04-24 15:41:25 +02:00
Sam M W 54dd0cd536 rename IndirectWithFix to Indirect 2024-04-24 15:41:25 +02:00
Sam M W 2444ef52d1 fix typo in comment 2024-04-24 15:41:25 +02:00
Sam M W ad622bc930 formatting 2024-04-24 15:41:25 +02:00
Sam M W 97d6b3fd89 split the Indirect addressing mode into BuggyIndirect and IndirectWithFix 2024-04-24 15:41:25 +02:00