CPCWiki forum

General Category => Programming => Topic started by: Fessor on 00:30, 31 October 15

Title: cpctelera/sdcc Problem w. Initialization of Variables and Arrays in headerfile
Post by: Fessor on 00:30, 31 October 15
Im taking first steps at cpctelera and SDCC and got headaches because the initialization of this array in the headerfile won't work, or partly works as in the resulting .asm a pointerlist is created and also the calculated value stored. But at accessing the variables in subroutines they behave as if not initialised. n_choices returns 0, also the array-table is full of null-pointers.
CPCTelera is OOTB and nothing changed at configuration for my project. It should work as the assembly shows but it doesn't work and i don't have any idea why it doesn't work.


.h
char *menulist[]={"Journey Onwards ",
          " Continue Game  ",
          "Create Character",
          "    Options     "}; 

int n_choices=sizeof(menulist)/sizeof(char *);


.asm

___str_7:
    .ascii "Journey Onwards "
    .db 0x00
___str_8:
    .ascii " Continue Game  "
    .db 0x00
___str_9:
    .ascii "Create Character"
    .db 0x00
___str_10:
    .ascii "    Options     "
    .db 0x00
    .area _INITIALIZER
__xinit__n_choices:
    .dw #0x0004
__xinit__menulist:
    .dw ___str_7
    .dw ___str_8
    .dw ___str_9
    .dw ___str_10


.c
void print_menu(char startx, char starty, char highlight )  {

  int i,j;

  for (i = 0; i < 4; ++i)
    {
    j=i+1;
    if (highlight==j)
      {
    printf("\037%c%c\030> %s <\030",startx,starty+i,menulist[i]);
      }
    else
      {
      printf("\037%c%c> %s <",startx,starty+i,menulist[i]);
      }
     
    }
   
  }
Title: Re: cpctelera/sdcc Problem w. Initialization of Variables and Arrays in headerfile
Post by: arnoldemu on 11:09, 31 October 15
consider using const char *.

also initialisation is done in crt. @ronaldo (http://www.cpcwiki.eu/forum/index.php?action=profile;u=1227), is this enabled for cpctelera?
Title: Re: cpctelera/sdcc Problem w. Initialization of Variables and Arrays in headerfile
Post by: Fessor on 12:02, 01 November 15
Found this, googling around

Small Device C Compiler suite / Mailing Lists (http://sourceforge.net/p/sdcc/mailman/message/33039977/)

QuoteYes - sdcc builds with the INITIALIZER section holding the data, but with all relocations for the INITIALIZED section. You simply take the INITIALIZER section of the sdcc output and move it to the INITIALZED section when creating the final binary, then you don't need to do anything in the start up code. See FUZIX/binman.c at master · EtchedPixels/FUZIX · GitHub (https://github.com/EtchedPixels/FUZIX/blob/master/Library/tools/binman.c) This reads the map file and the makebin output of the ihx file sdcc generates. Note that the binman example there makes some assumptions about how the memory is laid out by the crt0.s and bits I use. There's not really a lot to it on Z80 beyond makebin and moving the block as the bugs in the sdcc ihx output don't affect anything under 64K long. Alan
Title: Re: cpctelera/sdcc Problem w. Initialization of Variables and Arrays in headerfile
Post by: ronaldo on 13:32, 01 November 15
@Fessor (http://www.cpcwiki.eu/forum/index.php?action=profile;u=1495): We discussed this same issue months ago on the main thread about CPCtelera (http://lronaldo.github.io/cpctelera) (don't know what page at this moment).

SDCC targets embedded devices, and it's binary code is mainly thought to run from ROM. That's the main problem when dealing with global variables and static initializers. All static initializer values have to be stored in the binary (in ROM), but variables cannot be in ROM: they have to be in RAM. Therefore, a piece of code is required to copy initializer values from ROM to RAM before the program starts, to ensure RAM variables have their initial values.

This is nice on an embedded environment with RAM and ROM, but is terrible when you are creating a game that runs entirely from RAM. This behaviour in RAM means:
As current version of CPCtelera (http://lronaldo.github.io/cpctelera) is designed to run from RAM, initializer code is not included. Then, global variables are not initialized at the start, to prevent having two copies of them. Proposed solutions to use global variables with initialization are:Examples in CPCtelera (http://lronaldo.github.io/cpctelera) use both of these approaches. In your example, you could do this:

#include <cpctelera.h>
#include <stdio.h>

char* const menulist[]={"Journey Onwards ",
          " Continue Game  ",
          "Create Character",
          "    Options     "};

const u8 n_choices=sizeof(menulist)/sizeof(char *);

void main(void) {
   u8 i;
   
   for(i=0; i < n_choices; i++)
      printf("%s\n\r", menulist[i]);

   // Loop forever
   while (1);
}
However, I wouldn't use a global constant/variable for the size of menulist. It's nice to have it automatically calculated, but a #define would be generally more efficient (with respect to generated code). Also, using a signed int to store a value which is always positive and smaller than 256 is an overkill (and will cost you space and CPU cycles). it's preferably to use a u8 (unsigned char).
Take into account that "const char*" and "char* const" are not the same. On first case you are telling the compiler that the character string are constant, but the 4 pointers stored in menulist[] are variables (and thus, they end-up uninitialized). In the second case, your code says that pointers are constant, but character strings may be changed.
Title: Re: cpctelera/sdcc Problem w. Initialization of Variables and Arrays in headerfile
Post by: Fessor on 15:36, 01 November 15
I must have looked at the wrong examples then... ;)
Wonderful, that works.

I took that approach with an array as i planned to write a generalized Menuselection-Routine where i can throw in a pointer to a list of Menupoints and get back the chosen selection so i have not to reinvent the wheel every time i want to use such a routine.
May be a bit overdressed for CPC and a simple printed menu with the key to press would have done also, but i wanted a "modern" UI-like browsing through Menu-Points with the Cursor-Keys as additional comfort so the fingers can reside at the cursor keys and have not to circle like an eagle around far in the sky on lookout for a prey.


Title: Re: cpctelera/sdcc Problem w. Initialization of Variables and Arrays in headerfile
Post by: ronaldo on 18:27, 01 November 15
Quote from: Fessor on 15:36, 01 November 15
I must have looked at the wrong examples then... ;)
This behaviour is quite far from being self-evident. I think all of us have had this problem at one point in our learning curve with SDCC.

May be I should review all examples to add more clarifying information on the topic. I also have one point in my task list about writting an article on this subject. I think it's quite important and gives lot of painful moments when you stomp into it without knowing (and even sometimes knowing it).

Are you implementing utility software? I'm curious about the interface you describe and what is it for :)

Title: Re: cpctelera/sdcc Problem w. Initialization of Variables and Arrays in headerfile
Post by: Fessor on 19:29, 01 November 15
This specific problem and its solution is wonderful explained and due to the keywords in the topic-title now also easy to find i hope.

No, not utility Software, only a game. For my current Project ( Mein Winterprojekt der letzten Jahre: U4 (http://www.cpcwiki.eu/forum/programmierung/mein-winterprojekt-der-letzten-jahre-u4/15/) ) i am in need of a savegame with a characterrecord as actual (and further) ported subroutines are dependent on it. As generation is done in a seperate Boot/Intro/Startup-Program i can easily switch for that to c to speed up the development (i hope).
The last time i have programmed in c was on atari tt ~13 years ago so i am currently also experimenting with it to get back into that materia.
Title: Re: cpctelera/sdcc Problem w. Initialization of Variables and Arrays in headerfile
Post by: ronaldo on 19:38, 01 November 15
Oh, I see. Screenshots are really nice. Hope to see it working any time soon :)

Nice work! :D
Powered by SMFPacks Menu Editor Mod