Topics

UTTORI ASM · IN DEVELOPMENT

6502 family scopes and structs

Use 6502 family scopes and structs in 6502-family and NES projects, with syntax and limits.

On this page

6502 family behavior

Main, Local, and Static Labels

A colon defines a normal label at the current logical PC:

PlayerUpdate:
  lda PlayerState
  rts

On native sources, dot labels are scoped below the current parent:

PlayerUpdate:
.loop:
  dex
  bne .loop

ca65 cheap locals use @:

DriveAudio:
@Play:
  bne @Play

A plain assignment creates a static numeric label rather than a PC label. Native uses =. Ca65 also accepts :=:

ScreenWidth = 256
Paused := $E0

Static labels can be used where a resolved numeric symbol is required. On NES/ca65, $00–$FF equates encode as zero page and $100+ as absolute unless you force width with z: / a: / .b / .w.

global Label: marks a label as global in namespace-sensitive native source.

Relative Labels

Native runs of + and - create anonymous forward and backward targets:

  beq +
  lda #$01
+:

-:
  dex
  bne -

ca65 unnamed labels are :, referenced as :+, :++, :-, :--:

  bne :+
  lda FirstNoteIndexSongNoise
  sta NoteOffsetSongNoise
  bne :-
:
  nop

On ca65 targets, unnamed labels and file-local names do not leak across .include files. .export / .import promote a name to session-global so separately assembled units in one session can share it. That is not a relocatable object record.

Namespaces and ca65 Scopes

Native namespaces:

namespace Audio
Upload:
  rts
namespace off

jsr Audio_Upload

namespace nested on builds a path. pushns / pullns save and restore it.

ca65 .scope / .proc flatten into the same file-local symbol keys. Scope::Name is rewritten to Scope_Name:

.scope Outer
Value:
  .byte $11
  lda a:Outer::Value
.endscope

.proc Sub
  rts
.endproc
  jsr Sub

Scope type declarations, address-size annotations, and object visibility metadata are not modeled. This is flattened source compatibility, not ca65's object-file scope graph.

Structs

Native structs define addressable layouts without emitting bytes, using the core struct engine. ca65 .struct / .union / .tag are not part of the documented ca65 subset.

struct Actor $200
  .x: skip 2
  .y: skip 2
endstruct

struct Enemy extends Actor
  .health: skip 2
endstruct

See the SNES manual's struct section and struct-engine.ts for the shared implementation.