SDCC global constant initialized array in a fixed position in memory

Door jepmsx

Master (195)

afbeelding van jepmsx

15-01-2022, 08:57

I'm trying to define a global array with constant values. First I've tried to use const in the definition, but I think that only the pointer address is constant. So I have defined it outside the main function like

uint8_t __at(0x8200) notesFreq[12] = {
    173, 181, 192, 193, 194, 229, 242, 1, 16, 32, 39, 57 
};

But when I look at that memory position it does not have those values.

How can I define it?

Aangemeld of registreer om reacties te plaatsen

Van ToriHino

Paladin (807)

afbeelding van ToriHino

15-01-2022, 09:55

Normally SDCC puts these in the data segment, not sure if the __at even works here. You can influence the location of both the code and data segment with the compiler options --code-loc ADDRESS and --data-loc ADDRESS. So for example --data 0x8200 will start your data at address 0x8200 (using 0 for address puts it right behind the code segment).

Van geijoenr

Champion (354)

afbeelding van geijoenr

15-01-2022, 10:55

You can use const to put an array in the data segment (note that giving the size of the array is not necessary because the initialization data is specified).

const uint8_t var[] = {1,2,3,4};

the actual memory location shouldn't matter, but you can specify where the data segment starts using the linker options.

Van aoineko

Paladin (706)

afbeelding van aoineko

15-01-2022, 11:52

If you add const in front of your array, it is the pointed data that will be defined as constants (as you wanted).
This will also change the way SDCC will handle this data and where it will end up.

Const
Your table will be include "as it" in your program binary in the _CODE area.
You can set a position by hand but be careful:
- Your _CODE area will be extend to include your table (which can increase the size of your binary)
- The compiler does not handle the overwriting of manually placed data (with the __at directive). This is probably why you cannot find your data at the indicated address.

Not const
Since without the const your table can be modified, it must end up in RAM.
SDCC will store the initial values of the array in the _INITIALIZER area (usually placed just after the _CODE area by the crt0) and will also allocate the equivalent space in RAM in the _INITIALIZED area (usually just after _DATA).
At your program start, the crt0 is required to copy the contents of the _INITIALIZER area to _INITIALIZED to initialize all variables/tables for which you have defined a default value.
When you choose an address to place your array, it is the address in RAM that you can change (not the address of the data to initialize). The same limitations apply (_INITIALIZED area expansion and risk of overwriting).

Van jepmsx

Master (195)

afbeelding van jepmsx

15-01-2022, 16:03

Thanks guys for your explanation. I understand now its behaviour

Van DamnedAngel

Master (252)

afbeelding van DamnedAngel

15-01-2022, 22:37

My template solves that for you: https://github.com/DamnedAngel/MSX-Templates-for-VisualStudio
Tip: despite its name, you can use it in other environments, including under linux and macOS.