AsmMos6502 1.0.0

There is a newer version of this package available.
See the version list below for details.
dotnet add package AsmMos6502 --version 1.0.0
                    
NuGet\Install-Package AsmMos6502 -Version 1.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="AsmMos6502" Version="1.0.0" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="AsmMos6502" Version="1.0.0" />
                    
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 1.0.0
                    
#r "nuget: AsmMos6502, 1.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 AsmMos6502@1.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=AsmMos6502&version=1.0.0
                    
Install as a Cake Addin
#tool nuget:?package=AsmMos6502&version=1.0.0
                    
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 assembly code. It provides a fluent API to create 6502 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
  • Unique strongly typed assembler API
  • 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:

// Start address (for example, on C64 this is an available memory area)
using var asm = new Mos6502Assembler(0xc000);

asm.Label("START", out var startLabel);
asm.LDX(0x00);             // X = 0, index into buffer
asm.LDY(0x10);             // Y = 16, number of bytes to process

asm.Label("LOOP", out var loopLabel);
asm.LDA(0x0200, X);        // Load byte at $0200 + X
asm.CMP(0xFF);             // Check if byte is already 0xFF
var skipLabel = new Mos6502Label("SKIP");
asm.BEQ(skipLabel);        // If so, skip incrementing

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

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

// Call subroutine to flash border color
var flashBorderLabel = new Mos6502Label("FLASH_BORDER");
asm.JSR(flashBorderLabel);

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

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

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

asm.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  A6 00      LDX $00
C002  A4 10      LDY $10

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

C00B  18         CLC
C00C  65 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  A6 00      LDX $00

LL_05:
C01D  8E 20 D0   STX $D020
C020  E8         INX
C021  E4 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
2.2.1 89 7/30/2025
2.2.0 87 7/29/2025
2.1.0 60 7/27/2025
2.0.0 59 7/27/2025
1.1.0 155 7/26/2025
1.0.0 189 7/26/2025