# Sample linker configuration for C programs using the Atari binary file support.
# Use with: cl65 -tatarixl -Catarixl-c-xex.cfg prog.c -o prog.xex
FEATURES {
    STARTADDRESS: default = $2400;
}
SYMBOLS {
    __SYSTEM_CHECK__: type = import; # force inclusion of "system check" load chunk
    __STACKSIZE__:    type = weak,   value = $0800; # 2k stack
    __STARTADDRESS__: type = export, value = %S;
    __CHARGENSIZE__:  type = weak,   value = $0400;
    __SYSCHKHDR__:    type = export, value = 0; # Disable system check header
    __SYSCHKTRL__:    type = export, value = 0; # Disable system check trailer
}
MEMORY {
    ZP:          file = "", define = yes, start = $0082,                   size = $007E;

# "system check" load chunk
    SYSCHKCHNK:  file = %O,               start = $2E00,                   size = $0300;

# "shadow RAM preparation" load chunk
    SRPREPCHNK:  file = %O, define = yes, start = %S,                      size = $7C20 - %S - $07FF;  # $07FF: space for temp. chargen buffer, 1K aligned

# "main program" load chunk
    MAIN:        file = %O, define = yes, start = %S + __LOWBSS_SIZE__,    size = $D000 - __STACKSIZE__ - %S - __LOWBSS_SIZE__;

# memory beneath the ROM preceeding the character generator
    HIDDEN_RAM2: file = "", define = yes, start = $D800,                   size = $0800;

# address of relocated character generator (same addess as ROM version)
    CHARGEN:     file = "", define = yes, start = $E000,                   size = __CHARGENSIZE__;

# memory beneath the ROM
    HIDDEN_RAM:  file = "", define = yes, start = $E000 + __CHARGENSIZE__, size = $FFFA - $E000 - __CHARGENSIZE__;

# UNUSED - hide
    UNUSED:      file = "",               start = $0,                      size = $10;
}
FILES {
    %O: format = atari;
}
FORMATS {
    atari: runad = start,
           initad = SYSCHKCHNK: __SYSTEM_CHECK__,
           initad = SRPREPCHNK: sramprep;
}
SEGMENTS {
    ZEROPAGE:    load = ZP,                            type = zp;
    EXTZP:       load = ZP,                            type = zp,                optional = yes;

    SYSCHK:      load = SYSCHKCHNK,                    type = rw,  define = yes, optional = yes;
    LOWBSS:      load = SRPREPCHNK,                    type = bss, define = yes;  # shared btw. SRPREPCHNK and MAIN, not zero initialized
    SRPREP:      load = SRPREPCHNK,                    type = rw,  define = yes;
    SHADOW_RAM:  load = SRPREPCHNK, run = HIDDEN_RAM,  type = rw,  define = yes, optional = yes;
    SHADOW_RAM2: load = SRPREPCHNK, run = HIDDEN_RAM2, type = rw,  define = yes, optional = yes;
    STARTUP:     load = MAIN,                          type = ro,  define = yes;
    LOWCODE:     load = MAIN,                          type = ro,  define = yes, optional = yes;
    ONCE:        load = MAIN,                          type = ro,                optional = yes;
    CODE:        load = MAIN,                          type = ro,  define = yes;
    RODATA:      load = MAIN,                          type = ro;
    DATA:        load = MAIN,                          type = rw;
    INIT:        load = MAIN,                          type = bss, define = yes, optional = yes;
    BSS:         load = MAIN,                          type = bss, define = yes;
    SRPREPHDR:   load = UNUSED,                        type = ro;
    SRPREPTRL:   load = UNUSED,                        type = ro;
}
FEATURES {
    CONDES: type    = constructor,
            label   = __CONSTRUCTOR_TABLE__,
            count   = __CONSTRUCTOR_COUNT__,
            segment = ONCE;
    CONDES: type    = destructor,
            label   = __DESTRUCTOR_TABLE__,
            count   = __DESTRUCTOR_COUNT__,
            segment = RODATA;
    CONDES: type    = interruptor,
            label   = __INTERRUPTOR_TABLE__,
            count   = __INTERRUPTOR_COUNT__,
            segment = RODATA,
            import  = __CALLIRQ__;
}
