I have tried to create an array of strings and to read chars from these strings. Unfortunately, it seems the accessing to the array does not work as expected. The read char is always wrong. Debugging the ASM code showed reading data by using the MOVX instruction although there is no xram.
Using __idata modifier did not help.
#include <at89x051.h>
static const char *const moe = "-- --- .";
static const char *const moi = "-- --- ..";
static const char *const mos = "-- --- ...";
static const char *const moh = "-- --- ....";
static const char *const mo5 = "-- --- .....";
static const char *const g_calls[5] = {moe, moi, mos, moh, mo5};
void main(void)
{
if (g_calls[0][0] == '-')
P3_0 = 1;
else
P3_0 = 0;
}
>sdcc main.c -o main.ihx -mmcs51 --model-small --debug --xram-size 0 --iram-size 128 --code-size 2048 --out-fmt-ihx
ain.c:12: warning 151: using generic pointer _moe to initialize g_calls
main.c:12: warning 151: using generic pointer _moi to initialize g_calls
main.c:12: warning 151: using generic pointer _mos to initialize g_calls
main.c:12: warning 151: using generic pointer _moh to initialize g_calls
main.c:12: warning 151: using generic pointer _mo5 to initialize g_calls
>sdcc -v
SDCC : mcs51/z80/z180/r2k/r2ka/r3ka/sm83/tlcs90/ez80_z80/z80n/ds390/pic16/pic14/TININative/ds400/hc08/s08/stm8/pdk13/pdk14/pdk15/mos6502 TD- 4.3.0 #14184 (MINGW64)
I also tried to use the __code modifier that helped to remove the compiler warnings, but the code still does not work as expected. The read char is a low address of the char, not the char itself.
static __code const char *const moe = "-- --- .";
static __code const char *const moi = "-- --- ..";
static __code const char *const mos = "-- --- ...";
static __code const char *const moh = "-- --- ....";
static __code const char *const mo5 = "-- --- .....";
static __code const char *const mo = "-- ---";
static __code const char * __code const g_calls[5] = {moe, moi, mos, moh, mo5};
The way to get it working is as follows. However from my point of view it is a bug, because there are 3 dereferences of the pointer there.
This workaround also does not work in all situation, because the 3rd dereferencing uses only the low address. In a case the high address is not 0, it end up with a wrong result.
Another workaround is to use a switch() statement for selecting the individual string.
Last edit: Petr Pazourek 2024-01-24
Using the second const will place the variable moe in code memory and so will the literal strings be placed there. But the first const does not change the pointer type from a generic (3-byte) pointer to a (2-byte) code pointer. So moe is a generic pointer here. Adding __code does turn it into a code pointer as you found out.
This defines an array of generic pointers and should not complain when initialized with generic pointers.
And finally,
pcall[0]should be acharand not a pointer.