Skip to content

Tutorial: Hello World in Assembly

This tutorial walks you through writing, building, and running a simple "Hello World" program in 6502 assembly for the ByteCradle OS. The example uses the cc65 toolchain, a widely used suite for 6502-based development.

Step 1: Writing the Assembly Code

Create a new file called helloworld.asm and enter the following code:

;------------------------------------------------------------------------------
; Hello World Example for ByteCradle 6502
;
; This program prints "Hello World!" to the screen using the ByteCradle OS's
; built-in output routine located at $FFE8.
;------------------------------------------------------------------------------

.PSC02                              ; Assembly for the 65C02 CPU

.import __HEADER_LOAD__             ; Provided by the linker (.cfg) as load address

.define PUTSTRNL $FFE8              ; Routine to print a null-terminated string with newline

;------------------------------------------------------------------------------
; Program Header (used by ByteCradle OS to determine deployment address)
;------------------------------------------------------------------------------
.segment "HEADER"
.word __HEADER_LOAD__               ; Deployment address (typically $0800), little-endian

;------------------------------------------------------------------------------
; Main Code Segment
;------------------------------------------------------------------------------
.segment "CODE"

start:                              ; Entry point
    lda #<hwstr                     ; Load low byte of string address
    ldx #>hwstr                     ; Load high byte of string address
    jsr PUTSTRNL                    ; Call OS routine to print string with newline
    rts                             ; Return to OS

hwstr:
    .asciiz "Hello World!"          ; Null-terminated string

How it works:

  • The program starts at the label start, which is called by the OS.
  • It loads the address of a null-terminated string and calls the OS function at $FFE8, which prints the string followed by a newline.
  • The .segment "HEADER" section includes a 2-byte deployment address required by ByteCradle OS .COM files.
  • The program ends with rts (return from subroutine), allowing the OS to regain control.

Step 2: Writing the Makefile

Create a file called Makefile in the same directory:

PROG = HELLO.COM
OBJ  = helloworld.o
CFG  = rom.cfg

all: $(PROG)

$(OBJ): helloworld.asm
    ca65 helloworld.asm -o $(OBJ)

$(PROG): $(OBJ)
    ld65 -o $(PROG) -C $(CFG) $(OBJ)

This Makefile automates the build process:

  • Assembles the source using ca65
  • Links the program using ld65 with a linker configuration file (rom.cfg)
  • Produces an output file named HELLO.COM

Step 3: Linker Configuration (rom.cfg)

You will also need a linker configuration file called rom.cfg. This tells the linker how to place the code in memory:

MEMORY {
    HEADER: start = $0800, size = 2, file = %O;             # Explicit start position
    ROM:    start = $0802, size = $7FFE, file = %O;         # Start right after HEADER
}

SEGMENTS {
    HEADER: load = HEADER, type = ro, define = yes;
    CODE:   load = ROM, type = ro;
}

This layout matches the expectations of the ByteCradle OS, which reads the first two bytes of a .COM file to determine where to load it into memory.

Step 4: Building the Program

To compile and link your program, simply run:

make

This will produce a file called HELLO.COM, ready for deployment.

Note

The resulting HELLO.COM file is only 23 bytes in size, very small. This is because the program basically only contains an instruction for a kernel function and nothing more.

Step 5: Running the Program

Copy HELLO.COM to the SD card used by the ByteCradle system.

From the ByteCradle OS shell:

  • Navigate to the folder containing the file using cd.
  • Type the base name of the file (without the .COM extension):
hello

You should see:

Hello World!

Tip

Instructions on how to deploy the program to your ByteCradle board are provided here