Place a sequence of JMP instructions, possibly along with other small bits of code, within a single page. One may then use something like:
jproc1: jmp proc1
jproc2a: lda #0
jproc2b: lda #1
jproc2: jmp proc2
.byte <jproc1, <jproc2a, &...
I came up with the following self-modifying code (which I know is sometimes not regarded as good practice):
So don't modify, but use an indirect JMP
LDX #whateverindex*2 * Index to be used
LDA AddressTable,X * 3/4 Low byte target address
STA IndirectPTR * 2/3 Store to pointer (+1/1 if not in ZP)
You could also use the Stack and RTS. This is code I use to reference an indexed jump table containing subroutine addresses:
ldy #$nn //  load jump address offset
lda f40.CONCODEH,y //  get control code handler address hi-byte
pha //  push to Stack
Preface: I'm not the world greatest C expert - not at least as I dislike C quite a lot :))
The general issue here is that CC65 puts the address into a pointer variable, visible when looking at the generated source:
Later that variable gets loaded onto the stack - like CC65 does with ...
DASM is not the only 6502 assembler. It wasn't the first or last, either. Nintendo had their own in-house development system, which included an assembler among other tools. I'm sure that 3rd party developers used a variety of assemblers, as well. 6502 assemblers were widespread even on non-6502 platforms by the mid-80s, so it's doubtful anyone ever wrote ...
The Japanese children's book The Stars of Famicom Games includes pictures of Super Mario Brothers 3 development for the NES/Famicom. Code was written on an HP 64000 Logic Development System and cross assembled. See also: NES (Famicom) Development Kit Hardware
Your confusion might steam from not being aware that DASM is just one of many 6502 capable assemblers which most came way before DASM - and some much later, like CA65.
The Fine Print
Would somebody care to explain how "Super Mario Bros." was released in 1985. But the DASM Assembler came out in 1987?
There is no relation between Super ...
A convenient application of segments is the handling of zeropage addresses in ca65. Often, code pieces are written in a way that they use fixed coded ZP addresses (usually defined in some config file), which makes it very difficult to avoid and debug zeropage address conflicts when having more than one module.
The standard assembler configuration for the C64 ...
Using segments offloads program code management to dedicated tools.
Not using segments replaces these tools by the a programmer doing everything by hand.
While the difference may not be a big one with short programs, it gets relevant soon.
Segments are a way to organize code and/or data on a logical level. Segments group sections of code and/or ...
This code achieves the output you want:
* = $100
I don't think the segment identifiers are really intended to be used in raw output. They're for relocatable object files, as the documentation tries to allude to:
The following pseudo-ops apply primarily to relocatable .o65 objects.
It is not strictly true that "all works fine" for ML programs with a standard BASIC header starting at $0800 vice $0801. The idea of the BASIC header is that your program is easily loaded and then started using the "RUN" command:
LOAD"MYPROG",8 REM NOTE ABSENCE OF ",1"
If you move the header one-byte down to $0800,...