Asm6502 1.3.0

There is a newer version of this package available.
See the version list below for details.
dotnet add package Asm6502 --version 1.3.0
                    
NuGet\Install-Package Asm6502 -Version 1.3.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="Asm6502" Version="1.3.0" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="Asm6502" Version="1.3.0" />
                    
Directory.Packages.props
<PackageReference Include="Asm6502" />
                    
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 Asm6502 --version 1.3.0
                    
#r "nuget: Asm6502, 1.3.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 Asm6502@1.3.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=Asm6502&version=1.3.0
                    
Install as a Cake Addin
#tool nuget:?package=Asm6502&version=1.3.0
                    
Install as a Cake Tool

Asm6502 ci NuGet

<img align="right" width="160px" height="160px" src="https://raw.githubusercontent.com/xoofx/Asm6502/main/img/Asm6502.png">

Asm6502 is a lightweight and efficient C# library to assemble and disassemble 6502/6510 assembly code. It provides a fluent API to create 6502/6510 assembly code (e.g. a CPU powering the Commodore 64), and can be used to generate binary files or disassemble existing binaries into assembly code.

✨ Features

  • Full support for all core 6502 instructions and 6510 instructions (6502 + illegal opcodes)
  • Unique strongly typed and fluent assembler API
  • Support producing debug information (C# file and line numbers) for each instruction
  • Easily disassemble instructions and operand.
  • High performance / zero allocation library for disassembling / assembling instructions.
  • Compatible with net8.0+ and NativeAOT.
  • Integrated assembler API documentation via API XML comments. Integrated API documentation

📖 User Guide

For more details on how to use Asm6502, please visit the user guide.

Suppose the following 6502 assembly code:

       .org $c000     ; Start address
       
       ; Initialization
start: LDX #$00       ; X = 0, index into buffer
       LDY #$10       ; Y = 16, number of bytes to process
       
loop:  LDA $0200,X    ; Load byte at $0200 + X
       CMP #$FF       ; Check if byte is already 0xFF
       BEQ skip       ; If so, skip incrementing
       
       CLC            ; Clear carry before addition
       ADC #$01       ; Add 1
       STA $0200,X    ; Store result back to memory
       
skip:  INX            ; X = X + 1
       DEY            ; Y = Y - 1
       BNE loop       ; Loop until Y == 0
       
       ; Call subroutine to flash border color
       JSR flash_border
       
       ; Infinite loop
end:   JMP end

; ------------------------------
; Subroutine: flash_border
; Cycles border color between 0–7
; (Useful on C64, otherwise dummy)
; ------------------------------
flash_border:
        LDX #$00

flash_loop:
        STX $D020     ; C64 border color register
        INX
        CPX #$08
        BNE flash_loop

        RTS

And the equivalent in C# using Asm6502 library:

using var asm = new Mos6502Assembler();
asm.Org(0xc000);

// Initialization
asm.Label(out var start)
    .LDX_Imm(0x00)     // X = 0, index into buffer
    .LDY_Imm(0x10);    // Y = 16, number of bytes to process

asm.Label(out var loop)
    .LDA(0x0200, X)    // Load byte at $0200 + X
    .CMP_Imm(0xFF)     // Check if byte is already 0xFF
    .BEQ(out var skip) // If so, skip incrementing (forward label)

    .CLC()             // Clear carry before addition
    .ADC_Imm(0x01)     // Add 1
    .STA(0x0200, X);   // Store result back to memory

asm.Label(skip)        // X = X + 1
    .INX()
    .DEY()             // Y = Y - 1
    .BNE(loop)         // Loop until Y == 0

    // Call subroutine to flash border color
    .JSR(out var flash_border); // Declare a forward label

// Infinite loop
asm.Label(out var end)
    .JMP(end);

// ------------------------------
// Subroutine: FLASH_BORDER
// Cycles border color between 0–7
// (Useful on C64, otherwise dummy)
// -----------------------------
asm.Label(flash_border)
    .LDX_Imm(0x00);

asm.Label(out var flash_loop)
    .STX(0xD020)       // C64 border color register
    .INX()
    .CPX_Imm(0x08)
    .BNE(flash_loop)
    .RTS()

    .End();            // Resolve labels

// Get the assembled buffer
var buffer = asm.Buffer;

Disassembling the same code can be done using the Mos6502Disassembler class:

var dis = new Mos6502Disassembler(new Mos6502DisassemblerOptions()
{
    PrintLabelBeforeFirstInstruction = false,
    PrintAddress = true,
    PrintAssemblyBytes = true,
});

var asmText = dis.Disassemble(asm.Buffer);
Console.WriteLine(asmText);

Will generate the following disassembled code:

C000  A2 00      LDX #$00
C002  A0 10      LDY #$10

LL_02:
C004  BD 00 02   LDA $0200,X
C007  C9 FF      CMP #$FF
C009  F0 06      BEQ LL_01

C00B  18         CLC
C00C  69 01      ADC #$01
C00E  9D 00 02   STA $0200,X

LL_01:
C011  E8         INX
C012  88         DEY
C013  D0 EF      BNE LL_02

C015  20 1B C0   JSR LL_03

LL_04:
C018  4C 18 C0   JMP LL_04

LL_03:
C01B  A2 00      LDX #$00

LL_05:
C01D  8E 20 D0   STX $D020
C020  E8         INX
C021  E0 08      CPX #$08
C023  D0 F8      BNE LL_05

C025  60         RTS

🪪 License

This software is released under the BSD-2-Clause license.

🌟 Credits

Thanks to Norbert Landsteiner for providing the 6502 Instruction Set.

🤗 Author

Alexandre Mutel aka xoofx.

Product Compatible and additional computed target framework versions.
.NET net8.0 is compatible.  net8.0-android was computed.  net8.0-browser was computed.  net8.0-ios was computed.  net8.0-maccatalyst was computed.  net8.0-macos was computed.  net8.0-tvos was computed.  net8.0-windows was computed.  net9.0 was computed.  net9.0-android was computed.  net9.0-browser was computed.  net9.0-ios was computed.  net9.0-maccatalyst was computed.  net9.0-macos was computed.  net9.0-tvos was computed.  net9.0-windows was computed.  net10.0 was computed.  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.
  • net8.0

    • No dependencies.

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
1.8.1 32 10/18/2025
1.8.0 46 10/17/2025
1.7.0 48 10/17/2025
1.6.0 95 10/11/2025
1.5.0 96 10/11/2025
1.4.1 75 10/11/2025
1.4.0 92 10/10/2025
1.3.0 158 10/7/2025
1.2.0 157 10/6/2025
1.1.2 83 10/4/2025
1.1.1 164 10/2/2025
1.1.0 161 10/1/2025
1.0.0 136 9/28/2025