Accessing Multiple tables from EPROM

AllyCat

Senior Member
Hi,

I'm working on a program that uses multiple lookup tables in EPROM (probably the normal Read/Write type, to be compatible with 08M2, etc.). The tables may use most of the available memory space, so it seems obvious to start from address zero and concatenate the tables, so basically all that's needed is something like:

Code:
   DATA (1,2,4,8,16)
   DATA (1,3,9,27,81)
;... etc.
But how do I write the program to "point" to the entries in the second and subsequent tables? In most languages, I think I'd put a label before each DATA statement, but although PICaxe Basic can use "numbers" in quite surprising places, labels don't seem to be associated with a numerical value.

So, do I have to manually count the number of bytes in each DATA statement and create an appropriate SYMBOL command to define the address for the first byte in each table?. Perhaps then including the symbol name after the appropriate DATA keyword, so that at least the compiler checks for overlap errors.

If I am using Read/Write memory, I suppose I could create a separate Program to Write the data values into EPROM memory. This would also solve the issue that DATA doesn't appear to support WORD values (which most of my tables contain). But to me, one of the strengths of PICaxe Basic is that one can write a single, free-standing program "on a single sheet of paper", without recourse to Multiple Programs, Include files or Libraries, etc..

Cheers, Alan.
 

techElder

Well-known member
Alan, I've done almost exactly that in one of my programs, but I had to resort to knowing how many bytes of data there was in each block. I saved ten bytes at the beginning of eeprom for pointers to each block of data.

My data was defined at programming time rather than at runtime.
 

hippy

Technical Support
Staff member
This is how I would do it, using a SYMBOL to define the address of the table -

Code:
Symbol ENTRY1 = $00 : Data ENTRY1, (1,2,4, 8,16)
Symbol ENTRY2 = $05 : Data ENTRY2, (1,3,9,27,81)
And put that at the top of the program so the rest of the code can use the names, "ENTRY1" and "ENTRY2" here.

The only issue there is keeping the "= $xx" updated if the data contents change in size during editing. This structure will also warn about trying to use overlapped data so the only risk is that you may end up with gaps between tables.

An alternative is to use offsets from the previous but that can get a little complicated as the offset additions on each line are the number of data items on the line above ...

Code:
Symbol ENTRY1 = $00        : Data ENTRY1, (1,2,4, 8,16)
Symbol ENTRY2 = ENTRY1 + 5 : Data ENTRY2, (79,80,81)
Symbol ENTRY3 = ENTRY2 + 3 : Data ENTRY3, (1,3,9,27,81)
An example program which can be simulated on run on a physical chip below -

Code:
Symbol ENTRY1 = $00 : Data ENTRY1, (1,2,4, 8,16)
Symbol ENTRY2 = $05 : Data ENTRY2, (1,3,9,27,81)

Do
  b0 = ENTRY1 : Gosub Show
  b0 = ENTRY2 : Gosub Show
Loop

Show:
  Read b0, b1,b2,b3,b4,b5
  SerTxd( #b1,",",#b2,",",#b3,",",#b4,",",#b5,CR,LF )
  Return
Here's an example which uses the indexing trick Texasclodhopper suggests. Note that DATA statements don't have to have sequentially incrementing locations. So $10 onwards can be filled before $00 to $0F are -

Code:
Symbol ENTRY1 = $10 : Data ENTRY1, (1,2,4, 8,16)
Symbol ENTRY2 = $15 : Data ENTRY2, (1,3,9,27,81)

Symbol MSG1   = $00 : Data MSG1, ( ENTRY1 )
Symbol MSG2   = $01 : Data MSG2, ( ENTRY2 )

Do
  b0 = MSG1 : Gosub Show
  b0 = MSG2 : Gosub Show
Loop

Show:
  Read b0, b0
  Read b0, b1,b2,b3,b4,b5
  SerTxd( #b1,",",#b2,",",#b3,",",#b4,",",#b5,CR,LF )
  Return
 

AllyCat

Senior Member
Hi,

Thanks for the replies. Yes, I am using an initial index table and also one stage further by defining a symbol for the offset (length) of each table. The data tables are basically for mathematical functions (Sin, ATan, Log/Exp, etc.), potentially quite large (up to around 64 bytes) but I would like to be able to swap in/out tables of different sizes (32 bytes, 16 bytes, etc.) to optimise the accuracy / speed, etc. for any particular application.

But each table may need further symbols such as a scale factor (associated with the number of entries) so there may be a total of 4 or 5 symbols required for each table. These get rather unwieldy, particularly if attempting to conditionally compile (#IFDEFs) the alternative table sizes Thus, I was hoping to streamline the number of required symbols, not just for my own convenience, but because the aim is that the subroutines+tables could ultimately form a "library" for other users, without their need to understand the data structure in detail.

However, in practice, the table sizes are quite well-defined (generally 2^N + 1 words). Then, including a symbol at the start of each DATA statement will allow the compiler to catch any overlap errors and a quick inspection of the EEPROM data map window in the simulator should show up any significant "gaps" between the tables.

Cheers, Alan.
 

hippy

Technical Support
Staff member
I would like to be able to swap in/out tables of different sizes (32 bytes, 16 bytes, etc.) to optimise the accuracy / speed, etc. for any particular application.
One option for that is having an external program which can generate the table data, then output that and SYMBOL's for it as a .basinc file which can be included by a Basic program.

It may even possible to generate the file from within a PICAXE simulation, copy and paste generated SERTXD data rather than have an external program do it.

For sine tables and the like, as long as the data entries within them are of fixed size it should be possible to have a minimum of SYMBOL's defining them and have the program calculate the offset into them ...

Code:
  b2 = 90 : Gosub Sine
  SerTxd( "Sine(", #b2, ") = ", #w0 )

Sine:
  index = b2 * SINE_ENTRY_SIZE + SINE_TABLE_START
  Read index, b1, b0
  Return
 
Top