AsmMos6502 1.0.0
See the version list below for details.
dotnet add package AsmMos6502 --version 1.0.0
NuGet\Install-Package AsmMos6502 -Version 1.0.0
<PackageReference Include="AsmMos6502" Version="1.0.0" />
<PackageVersion Include="AsmMos6502" Version="1.0.0" />
<PackageReference Include="AsmMos6502" />
paket add AsmMos6502 --version 1.0.0
#r "nuget: AsmMos6502, 1.0.0"
#:package AsmMos6502@1.0.0
#addin nuget:?package=AsmMos6502&version=1.0.0
#tool nuget:?package=AsmMos6502&version=1.0.0
AsmMos6502

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