pub trait Variant {
// Required methods
fn decode(opcode: u8) -> Option<(Instruction, AddressingMode)>;
fn adc_binary(
accumulator: u8,
value: u8,
carry_set: bool,
) -> ArithmeticOutput;
fn adc_decimal(
accumulator: u8,
value: u8,
carry_set: bool,
) -> ArithmeticOutput;
fn sbc_binary(
accumulator: u8,
value: u8,
carry_set: bool,
) -> ArithmeticOutput;
fn sbc_decimal(
accumulator: u8,
value: u8,
carry_set: bool,
) -> ArithmeticOutput;
// Provided methods
fn penalty_cycles_for_decimal_mode() -> u8 { ... }
fn penalty_cycles_for_indirect_jmp() -> u8 { ... }
fn zero_page_base() -> u16 { ... }
fn stack_base() -> u16 { ... }
fn brk_vector() -> u16 { ... }
fn reset_vector() -> u16 { ... }
fn nmi_vector() -> u16 { ... }
}Expand description
Trait for different 6502 CPU variants with their historical differences.
The 6502 family evolved over decades with various manufacturers creating specialized versions for different applications:
-
Revision A (1975): Very early 6502 variant missing the ROR instruction entirely. Found in early KIM-1 systems and some Apple-1 computers. The ROR instruction was intentionally unimplemented due to design constraints, not a “bug” as commonly believed. Production ended around June 1976.
-
NMOS 6502 (1976): Complete MOS Technology processor with working ROR instruction, used in Apple II, Commodore 64, Atari 2600. Has unreliable decimal mode flags but full BCD support. This became the standard reference implementation.
-
65C02 (1983): WDC’s CMOS version with bug fixes, additional instructions, and reliable decimal mode flags. Development began in 1981 with samples released in early 1983. Used in Apple IIc/IIe and many embedded systems.
-
Ricoh 2A03 (1983): Nintendo’s cost-reduced variant for NES/Famicom (released July 15, 1983). Removed decimal mode entirely to avoid patent issues. Used as a core in their custom ASIC which also included sound generation and other features.
Choose the variant that matches your target system for accurate emulation. Note that software written for later variants may not run on earlier ones due to missing instructions (particularly ROR on Revision A).
Required Methods§
fn decode(opcode: u8) -> Option<(Instruction, AddressingMode)>
Sourcefn adc_binary(accumulator: u8, value: u8, carry_set: bool) -> ArithmeticOutput
fn adc_binary(accumulator: u8, value: u8, carry_set: bool) -> ArithmeticOutput
Sourcefn adc_decimal(accumulator: u8, value: u8, carry_set: bool) -> ArithmeticOutput
fn adc_decimal(accumulator: u8, value: u8, carry_set: bool) -> ArithmeticOutput
Sourcefn sbc_binary(accumulator: u8, value: u8, carry_set: bool) -> ArithmeticOutput
fn sbc_binary(accumulator: u8, value: u8, carry_set: bool) -> ArithmeticOutput
Sourcefn sbc_decimal(accumulator: u8, value: u8, carry_set: bool) -> ArithmeticOutput
fn sbc_decimal(accumulator: u8, value: u8, carry_set: bool) -> ArithmeticOutput
Provided Methods§
Sourcefn penalty_cycles_for_decimal_mode() -> u8
fn penalty_cycles_for_decimal_mode() -> u8
Returns the cycle penalty for ADC/SBC in decimal mode for this variant.
- NMOS/Ricoh: 0 (no penalty)
- 65C02: 1 (decimal mode adds an extra cycle)
- Future variants may have different values
Sourcefn penalty_cycles_for_indirect_jmp() -> u8
fn penalty_cycles_for_indirect_jmp() -> u8
Returns the cycle penalty for JMP (indirect) for this variant.
- NMOS/Ricoh: 0 (5 cycles total)
- 65C02: 1 (6 cycles total, also fixes page-crossing bug)
- Future HMOS 7501: 0 (5 cycles)
Sourcefn zero_page_base() -> u16
fn zero_page_base() -> u16
Base address of the zero page for this variant.
Standard 6502 family parts place the zero page at $0000. The HuC6280
relocates it to $2000 (reached through mapping register MPR1), so all
zero-page and zero-page-indirect accesses are offset by this base.
Sourcefn stack_base() -> u16
fn stack_base() -> u16
Base address of the hardware stack page for this variant.
Standard 6502 family parts place the stack at $0100. The HuC6280
relocates it to $2100 (reached through mapping register MPR1).
Sourcefn brk_vector() -> u16
fn brk_vector() -> u16
Address of the IRQ/BRK interrupt vector for this variant.
Standard 6502 family parts fetch it from $FFFE. The HuC6280 remaps the
software-interrupt (BRK) vector to $FFF6.
Sourcefn reset_vector() -> u16
fn reset_vector() -> u16
Address of the RESET vector for this variant.
Standard 6502 family parts fetch it from $FFFC. The HuC6280 relocates
its whole vector table and fetches RESET from $FFFE.
Sourcefn nmi_vector() -> u16
fn nmi_vector() -> u16
Address of the NMI vector for this variant.
Standard 6502 family parts fetch it from $FFFA. The HuC6280 has no
dedicated NMI line, so it keeps the default.
Dyn Compatibility§
This trait is not dyn compatible.
In older versions of Rust, dyn compatibility was called "object safety".