Just a newby asking the 64k question again - Arduino Mega2560

...from above

But the important thing to note is that PROGMEM designates that the linker put your data into a space that is 64k in size. If you try to specify data bigger than 64k it might actually compile, but your results are going to be irratic - at least mine were using 1.0.3. Another important thing to note is that the PROGMEM attribute puts the data in a certain place, and only in that place. If you have more than 64k of data, you can put some where PROGMEM says and that spot is 64k big, but then where do you put the rest, and how do you get to it?

Now, just for the sake of discussion - there are lots of flash memory sections, used for different things. You have the .text section, and the .data section, and lots of .fini1, .fini2,.finix...etc. Code and data is marked by the attribute((section(".blah"))) tag, and then there is a corresponding note in the linker script that says what to do with things that are in section ".blah".

Some have had success putting data in the section marked with the attribute ".fini7". The AVR documentation says this is a user-definable section, and you can certainly use it to put a 64k chunk. If you have more than 64k you need more than one section.

Well, after much weeping and gnashing of teeth I got a lot of help from this:

http://www.avrfreaks.net/index.php?module=PNphpBB2&file=viewtopic&t=93874&highlight=

which explains how to set up several PROGMEM memory segments/sections. It pushes the static data into flash above the code itself, as is recommended by many. It also provides some code to address those sections. So, using that method which not only required using an include called "morepgmspace.h" - and plz note this is a modified one from Carlos Lamas's original one, as well as making mods to the linker script found as "avr6.x" - which is the script used for chips that have 256k of Flash. Other chips will have different linker scripts.

With that combination of things, I could specify constant global vars with the tags: PROGMEM_SEG1, PROGMEM_SEG2, PROGMEM_SEG3. I can them address them separately through a variety of means. The linker script is modified to place the data in locations which begin at 0x10000, 0x20000, and 0x30000 respectively.

Given that combo of linker script changes and includes I could do the following in code given the way I specified the data above:

char wordIGot[50];
uint_farptr_t theUltimateAddress  = GET_FAR_ADDRESS(myDictionary) + PROGMEM_SEGyadda_BASE_ADDRESS + (indexOfWord*sizeof(char*));

strcpy_Pyadda(wordIGot,pgm_read_byte_far(theUltimateAddress);

Note that I have not yet figured out which strcpy function to use with these addresses, so I wrote my own.

apparently, this also works in some universe but I have not yet got it to work:

#include <morepgmspace.h>
char myWord[50];
int theIndexOfTheWordIWant;
strcpy_PF(myWord, pgm_get_word_far(&myDictionary[theIndexOfTheWordIWant]));

What I have been unable to accomplish at this point, is that I cannot retrieve the char* pointers from the array of 10000 pointers I specified as "dictionary[]" above.
Just for sake of example, I have stored 64k of strings in the memory noted with the attribute PROGMEM_SEG2. I have stored the 10000 pointers to that data in PROGMEM_SEG1.

I am presuming these char* pointers are all 16-bit, so that they are addresses to the char strings all WITHIN the same memory segment, and that I will have to do something of the order of:

#include <morepgmspace.h> // note this is the MODIFIED one available on avrfreaks.com, not the original from Carlos Lamas's website
uint16_t theLocalAddress = pgm_read_word_far(&dictionaryWhichIsInSeg1[which word do I want]);

//but as I mentioned the above line doesn't seem to work always, as you can't retrieve the dictionary address through variable indexing.
//In that case, you have to do this..

 uint16_t theLocalAddress = pgm_read_word_far(GET_FAR_ADDRESS(dictionary) + PROGMEM_SEG1_BASE + whichWordDoIWant*sizeof(char*));

//but I'm not sure how well that works either

then

char* theRealAddress = pgm_read_word_far(theLocalAddress + PROGMEM_SEG2_BASE);

However, I think I may be in some sort of compiler optimization hell. It seems impossible to retrieve the pointers to the const char*s with pgm_read_word_far...but I can get to the words themselves, which are stored sequentially in PROGMEM_SEG2 and thus seem like one big long string.

I also ran into the perennial issue with the Mega2560 bootloader hanging...the new version of the bootloader hex does seem to work but I wind up with a problem on verification. It gives me a warning, but the code loads just fine.

If anyone followed all that, thanks much for your valuable time.

With kind regards
Joe