Copper6510 2.0.0

dotnet add package Copper6510 --version 2.0.0
                    
NuGet\Install-Package Copper6510 -Version 2.0.0
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="Copper6510" Version="2.0.0" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="Copper6510" Version="2.0.0" />
                    
Directory.Packages.props
<PackageReference Include="Copper6510" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add Copper6510 --version 2.0.0
                    
#r "nuget: Copper6510, 2.0.0"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package Copper6510@2.0.0
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=Copper6510&version=2.0.0
                    
Install as a Cake Addin
#tool nuget:?package=Copper6510&version=2.0.0
                    
Install as a Cake Tool

Copper6510

Copper6510 is a cycle-stepped NMOS 6510 CPU core for C64-class emulators. It supports official and common undocumented opcodes, observable bus cycles, hardware IRQ/NMI/RESET inputs, and RDY/AEC bus arbitration.

The package targets .NET 10.

Install

dotnet add package Copper6510 --version 2.0.0

Quick start

using Copper6510;

var bus = new RamBus();
bus.Memory[0x1000] = 0xA9; // LDA #$42
bus.Memory[0x1001] = 0x42;

var cpu = new Mos6510(bus);
cpu.InitializeState(0x1000); // deterministic host state injection
cpu.ExecuteInstruction();

Console.WriteLine(cpu.A); // 66

sealed class RamBus : IMos6510Bus
{
    public byte[] Memory { get; } = new byte[65536];

    public byte Read(ushort address, Mos6510BusAccessKind kind = Mos6510BusAccessKind.Read)
        => Memory[address];

    public void Write(
        ushort address,
        byte value,
        Mos6510BusAccessKind kind = Mos6510BusAccessKind.Write)
        => Memory[address] = value;
}

ExecuteInstruction() is a convenience wrapper. Cycle-driven hosts should call StepCycle() once per PHI2 cycle and inspect its allocation-free Mos6510CycleResult.

Opcode fetch selects a static microprogram descriptor. Addressing operands, effective addresses, page-cross state, and intermediate data remain in CPU microstate between calls; instructions are not executed atomically and replayed.

Pins and bus arbitration

Drive hardware inputs before the cycle on which they are sampled:

cpu.SetIrqLine(ciaIrq || vicIrq); // level-sensitive
cpu.SetNmiLine(cia2Nmi);          // rising-edge latched
cpu.SetReadyLine(rdyHigh);        // low stalls reads; writes complete
cpu.SetBusAvailable(aecHigh);     // low freezes the CPU without a bus callback
var result = cpu.StepCycle();

Drive SetResetLine(true) for at least two cycles, then release it. The core performs the seven-cycle NMOS reset sequence through $FFFC/$FFFD. Use InitializeState() only when a host intentionally injects CPU state without emulating RESET.

Every CPU-owned cycle calls exactly one Read or Write. Access kinds identify executed and discarded opcode fetches, operands, dummy reads/writes, stack accesses, and vector reads. RDY-low reads repeat; AEC-low cycles make no bus callback.

DummyRead, StackRead, and DiscardedOpcodeFetch are real electrical reads, not notifications. A bus implementation must return its normal value and apply memory-mapped side effects on every callback, including every RDY-stalled repeat. The callback address is the address observed on the NMOS 6510 bus, which can be a sequential PC, current stack address, or partially corrected indexed/branch address whose value the CPU ultimately discards.

Migrating from 1.1.x

Copper6510 1.1.x Copper6510 2.0.0
Bus callbacks receive cycleOffset Host owns the clock; one callback represents the current cycle
IMos6510Bus.Idle Removed; unused CPU cycles are real dummy reads
RequestIrq / TryRequestIrq SetIrqLine(bool)
RequestNmi / TryRequestNmi SetNmiLine(bool)
Reset(pc) InitializeState(pc) for injection or SetResetLine for hardware reset
Instruction-only execution StepCycle() plus the ExecuteInstruction() convenience wrapper

BeginSubroutine remains a synthetic, zero-time host helper. It is not a hardware JSR and should not be used when every setup bus cycle must be modeled.

Product Compatible and additional computed target framework versions.
.NET net10.0 is compatible.  net10.0-android was computed.  net10.0-browser was computed.  net10.0-ios was computed.  net10.0-maccatalyst was computed.  net10.0-macos was computed.  net10.0-tvos was computed.  net10.0-windows was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
2.0.0 78 7/18/2026
1.1.0 110 6/22/2026

Major API release: replaces offset-based and idle bus callbacks with one-cycle Read/Write callbacks, adds StepCycle and Mos6510CycleResult, models hardware IRQ/NMI/RESET entry, and adds RDY/AEC bus arbitration with cycle-accurate dummy and discarded reads.