1
0
mirror of https://github.com/mre/mos6502.git synced 2026-03-12 06:41:39 +00:00

392 Commits

Author SHA1 Message Date
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
Sam M W
da30c8c67d change arr_to_addr to address_from_bytes 2024-04-24 15:41:25 +02:00
omarandlorraine
11499b6bc8 Starting on implementing different variants (#88)
* start on separating 6502 variants from cpu itself

* add a single variant: the NMOS one

* get examples & tests running again

* Add the Revision A variant, one that has no ROR

* disable failing lint in build-time dependencies

* Variant with no decimal mode

* Revert "disable failing lint in build-time dependencies"

This reverts commit c87975e937.

* some doc comments

* specify the variant in unit test now the API has changed

---------

Co-authored-by: Sam M W <you@example.com>
2023-10-31 16:45:15 +01:00
omarandlorraine
b52e47bbb5 Fix the PHP opcode (#92)
* unit test for php

* get test passing

---------

Co-authored-by: Sam M W <you@example.com>
2023-10-30 02:22:37 +01:00
omarandlorraine
6ce85db45c boring crate related maintenance (#95)
* remove Cargo.lock

* remove num

---------

Co-authored-by: Sam M W <you@example.com>
2023-10-30 02:20:46 +01:00
omarandlorraine
4d2621d603 use cargo test now instead of skeptic to run tests (#93)
* use cargo test now instead of skeptic to run tests

* formatting

---------

Co-authored-by: Sam M W <you@example.com>
2023-10-29 15:06:41 +00:00
Sam M W
a07df31c26 Cargo update 2023-10-29 13:47:51 +00:00
omarandlorraine
0d65eb0d8d Merge pull request #87 from omarandlorraine/update
cargo update
2023-08-18 09:07:20 +01:00
Sam M W
9752a1b8f7 cargo update 2023-08-18 09:02:16 +01:00
omarandlorraine
aa1a47a76f Fix addition and subtraction (#72)
* extract decimal logic into separate function

* squash me

* I think we should be doing unsigned arithmetic here

* squash me

* remove unused function

* update the sign checks

* cargo fmt

* get tests to compile again

* get tests passing again

* squash me

* remove pointless conversion from u8 to u8

* cargo fmt

* accumulator is now u8

* add adc test from solid65

* pass the new test

---------

Co-authored-by: Sam M W <you@example.com>
2023-06-29 12:13:49 +02:00
dependabot[bot]
65817524a2 Bump bitflags from 2.3.2 to 2.3.3 (#82)
Bumps [bitflags](https://github.com/bitflags/bitflags) from 2.3.2 to 2.3.3.
- [Release notes](https://github.com/bitflags/bitflags/releases)
- [Changelog](https://github.com/bitflags/bitflags/blob/main/CHANGELOG.md)
- [Commits](https://github.com/bitflags/bitflags/compare/2.3.2...2.3.3)

---
updated-dependencies:
- dependency-name: bitflags
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-06-29 10:52:01 +02:00