AsmMos6502 4.1.1

dotnet add package AsmMos6502 --version 4.1.1
                    
NuGet\Install-Package AsmMos6502 -Version 4.1.1
                    
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="AsmMos6502" Version="4.1.1" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="AsmMos6502" Version="4.1.1" />
                    
Directory.Packages.props
<PackageReference Include="AsmMos6502" />
                    
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 AsmMos6502 --version 4.1.1
                    
#r "nuget: AsmMos6502, 4.1.1"
                    
#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 AsmMos6502@4.1.1
                    
#: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=AsmMos6502&version=4.1.1
                    
Install as a Cake Addin
#tool nuget:?package=AsmMos6502&version=4.1.1
                    
Install as a Cake Tool

AsmMos6502 ci NuGet

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

AsmMos6502 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.

📖 User Guide

Suppose that we want to write a simple program in C# to assemble and disassemble the equivalent of the following 6502 assembly code:

        .org $c000             ; Start address (for example, on C64 this is an available memory area)

        ; 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

The following C# assembly would assemble this code using the AsmMos6502 library:

using var asm = new Mos6502Assembler();

asm
    .Begin(0xc000)
    .Label("START", out var startLabel)
    .LDX_Imm(0x00)             // X = 0, index into buffer
    .LDY_Imm(0x10)             // Y = 16, number of bytes to process

    .Label("LOOP", out var loopLabel)
    .LDA(0x0200, X) // Load byte at $0200 + X
    .CMP_Imm(0xFF)             // Check if byte is already 0xFF

    .LabelForward("SKIP", out var skipLabel)
    .BEQ(skipLabel)        // If so, skip incrementing
    .CLC()                 // Clear carry before addition
    .ADC_Imm(0x01)             // Add 1
    .STA(0x0200, X) // Store result back to memory

    .Label(skipLabel)      // X = X + 1
    .INX()
    .DEY()                 // Y = Y - 1
    .BNE(loopLabel)        // Loop until Y == 0

    // Call subroutine to flash border color
    .LabelForward("FLASH_BORDER", out var flashBorderLabel)
    .JSR(flashBorderLabel)

    // Infinite loop
    .Label("END", out var endLabel)
    .JMP(endLabel)

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

    .Label("FLASH_LOOP", out var flashLoopLabel)
    .STX(0xD020) // C64 border color register
    .INX()
    .CPX_Imm(0x08)
    .BNE(flashLoopLabel)
    .RTS()

    .End();                 // Mark the end of the assembly (to resolve labels)

var buffer = asm.Buffer; // Get the assembled 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

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

🪪 License

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

🤗 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
4.1.1 30 9/9/2025
4.1.0 29 9/9/2025
4.0.0 58 9/7/2025
3.0.0 135 9/1/2025
2.2.1 111 7/30/2025
2.2.0 94 7/29/2025
2.1.0 66 7/27/2025
2.0.0 64 7/27/2025
1.1.0 161 7/26/2025
1.0.0 196 7/26/2025