Crate c64_assembler

Source
Expand description

§C64 Assembler

The goal of this crate is to being able to compile C64 assembly directly from Rust.

The reasoning behind it is that in a typical C64 development workflow the programs are generated in a separate step and then being saved to a disk image. For generating disk images there are already crates out there like cmb.

However some projects require more control over the compilation stage and disk construction stage. Having a C64 assembler written in rust can build a bridge and allows custom disk formats and faster iterations during development.

§Modules and functions

An crate::Application is organized in crate::Module and crate::Function. Modules can be shared between applications. A module public API is organized in functions. Multiple variations of functions can exists. By swapping out functions in a module a module can be size-optimized or CPU cycles optimized based on the actual needs of the program.

§Usage

§Building pattern

An application can be build using builder patterns.

use c64_assembler::builder::ApplicationBuilder;
use c64_assembler::builder::ModuleBuilder;
use c64_assembler::builder::InstructionBuilder;

let application = ApplicationBuilder::default()
    .name("Set black border")
    .include_vic2_defines()
    .module(
        ModuleBuilder::default()
            .name("main")
            .instructions(
                InstructionBuilder::default()
                    .add_basic_header()
                    .label("main_entry_point")
                    .lda_imm(0x00)
                    .comment("Load black color")
                    .sta_addr("VIC2_BORDER_COLOR")
                    .rts()
                    .build(),
            )
            .build(),
    )
    .build().unwrap();

§Validating

Using the crate::validator::Validator to check for consistency.

use c64_assembler::validator::Validator;

let validation_result = application.validate();
assert!(validation_result.is_ok());

§Generating dasm source

Using the crate::generator::DasmGenerator a dasm compatible assembly source can be generated.

use c64_assembler::generator::Generator;
use c64_assembler::generator::DasmGenerator;

let source = DasmGenerator::default().generate(application).unwrap();
println!("{}", source);

Would output

; --- Application: SET BLACK BORDER ---
; NOTE: This file is generated, do not modify

  processor 6502

VIC2_BORDER_COLOR = $D020

  org $0800

; --- Module begin: MAIN ---
  byte $00, $0C, $08     ; New basic line
  ; 10 SYS 2062
  byte $0A, $00, $9E, $20, $32, $30, $36, $32
  byte $00, $00, $00     ; End basic program

main_entry_point:
  lda #$00
  sta VIC2_BORDER_COLOR
  rts
; --- Module end: MAIN ---

§Generating .PRG byte stream

Using the crate::generator::ProgramGenerator to generate the byte stream. The byte stream includes the loading address.

use c64_assembler::generator::{Generator, ProgramGenerator, print_hexdump};

let bytes = ProgramGenerator::default().generate(application).unwrap();
print_hexdump(&bytes);
0000:  00 08 00 0C  08 0A 00 9E  20 32 30 36  32 00 00 00
0010:  A9 00 8D 20  D0 60

§Using macros (work in progress)

To reduce the boilerplating macros can be used. This is still under development. Expect less stability, error messages and some instructions not supported.

use c64_assembler_macro::application;

let application = application!(
    name="Set black border"
    include_vic2_defines
    module!(
        name="main"
        instructions!(
        include_basic_header
        main_entry_point:
            "Load black color into accumulator"
            lda #$00
            sta VIC2_BORDER_COLOR
            rts
        )
    )
).unwrap();

Modules§

builder
Builder classes for application, module, function and instructions
generator
Generators to export to a .PRG or source code.
instruction
memory
validator
Validate the consistency of an application.

Structs§

Application
Application is the root container for the assembler
Function
Function is a replaceble public part of a module.
Instructions
Stream of instructions.
Module
Module