10.7. The default memory block

Code placed inside a segment is added to the default memory block until a block is explicitly defined (Not to be confused with the 'Default' segment):

        .segment Code [start=$1000]
        inc $d020         // Places code in the default memoryblock 
        jmp *-3           

        *=$2000           // Start a new memoryblock 
        inc $d021          
        jmp *-3           

The default memory block is special since it can be controlled by parameters given when the segment is defined. Notice the 'start=$1000' parameter that sets the start of the default memory block.

In some cases you want one segment to start after each other. This is done with the 'startAfter' parameter.

        .segmentdef Code [start=$1000]
        .segmentdef Data [startAfter="Code"]

The ability to control code in this way can be useful, for instance when you want to save memory. If you have some initialization code, that is only used once in the upstart phase, then you could place it after the rest of the code, and use the same memory for a buffer that is used after the init phase:

        .file [name="program.prg", segments="Code, InitCode"]         

        .segmentdef Code      [start=$1000]
        .segmentdef InitCode  [startAfter="Code"]
        .segmentdef Buffer    [startAfter="Code"]

        .segment Buffer
table1: .fill $100, 0
table2: .fill $100, 0

Notice that overlapping code only gives an error if it's inside the same segment. So you can place code in both 'InitCode' and 'Buffer' without getting errors. The Code and InitCode segments are saved in the file while the Buffer is thrown away.

By using the 'align' parameter together with 'startAfter' you align the default memory block.

        .segmentdef Code       [start=$8000]
        .segmentdef Virtual100 [startAfter= "Code", align=$100, virtual]
        
        .segment Code "Some code"
        ldx #$ff
        lda table,x
        
        .segment Virtual100 "Table"
 table: .fill $100,0

By the memory map printed while assembling, you see the start of the Virtual100 segment is aligned to a $100 boundary to avoid spending an extra cycle when accessing the table:

Code-segment:
  $8000-$8004 Some code

Virtual100-segment:
  *$8100-$81ff Table

In the above example was also used 'virtual' (When no '=' is present its shorthand for 'virtual=true') to declare all the memory blocks in the virtual100 segment virtual. In most cases this won't be necessary since you just don't direct the segment anywhere so the generated bytes are thrown away, but in some cases it can come in handy.

'segmentAfter' works by taking the last defined memory block (Either the default or user defined by *=) and starts where this ends. Block included in other ways (imported from other segments, included from files etc.) are not considered.