CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to CCS Technical Support

Question regarding #ROM directive, lookup tables

 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
webbone



Joined: 20 Sep 2004
Posts: 14
Location: Sacramento, CA

View user's profile Send private message

Question regarding #ROM directive, lookup tables
PostPosted: Tue Mar 01, 2005 7:57 pm     Reply with quote

I have read through many of the posts here regarding lookup tables and string storage in program memory and have determined I will need to write my own routines in assembly using the TABLxxx registers (I'm use to doing things this way on 8x51 microcontrollers).

My question is: Is there a way to utilize labels for addresses and have the assembler/linker resolve them? Specifically, doing something like this (not truly PIC assembly):
Code:

//tables
#ORG 2000
TableBase:
Msg1:
  DB  0x40,'Hello World!',0x00
Msg2:
  DB  0x40,'Goodbye All',0x00
Msg3:
  DB 0x10,'Read ERR',0x00



//Code
  MOVLW  #ADDR_UPPER[Msg1]
  MOVWF TBLPTRU
  MOVLW  #ADDR_HIGH[Msg1]
  MOVWF TBLPTRH
  MOVLW  #ADDR_LOW[Msg1]
  MOVWF TBLPTRL

READ_TABLE:
  TBLRD*+
  ...etc...


I'm assuming there isn't a way to just use &Msg1 - on other assemblers I'm used to there are SEGMENT() and OFFSET() operators to extract the appropriate part of the address. If there is something of this sort available with the CCS compiler I can manage all of the rest in assembly no problem.

Suggestions are welcome.

My fallback is to write a table generator program that calculates the lengths and creates a bunch of #ROM statements with the appropriate addresses and also a set of #DEFINE statements so I can use the "labels" later in code but that is rather messy and requires multiple, non-automated steps in order to just make some text changes, etc.
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Tue Mar 01, 2005 8:48 pm     Reply with quote

You should tell us what your overall purpose is.
Other board members may already have solved your problem.

But here is a possible answer to your immediate question.
By using the label_address() function, you can extract the
address of the string data.

Code:
#include <18F452.h>
#fuses XT, NOWDT, NOPROTECT, BROWNOUT, PUT, NOLVP
#use delay(clock = 4000000)

const char array[] = {"ABC"};

void main()
{
int16 ptr;

ptr = label_address(array);

while(1);
}

Here is part of the .LST file, which shows the address of the string data:
Code:
0006 4241           00007 DATA 41,42
0008 0043           00008 DATA 43,00

Here's the code that loads address 0x0006 and stores it in ptr.
Code:
0000                00310 ... ptr = label_address(array); 
0018 0E00           00311 MOVLW  00
001A 6E03           00312 MOVWF  03
001C 0E06           00313 MOVLW  06
001E 6E06           00314 MOVWF  06
0020 C003 F007      00315 MOVFF  03,07

Here's part of the symbol table. The RAM address of ptr is also 0x0006
but that's just a coinicidence. The string is in ROM and the ptr is in RAM.
Code:
main.ptr                          00000006
webbone



Joined: 20 Sep 2004
Posts: 14
Location: Sacramento, CA

View user's profile Send private message

PostPosted: Tue Mar 01, 2005 8:57 pm     Reply with quote

THanks for the reply. I had failed to specify that I'm working on a 18F8720 processor in this application.

My overall purpose is to be able to have string tables in ROM that can be read using the TBLPTR hardware in the processor, the end destination of which will be external hardware (mostly) and possibly one of the serial ports.

It looks like the label_address() function will do what I'm asking for, especially since I'm in Microcontroller mode and don't have to worry about the TBLPTRU value.
Ttelmah
Guest







PostPosted: Wed Mar 02, 2005 4:48 am     Reply with quote

Remember though, that the compiler is perfectly capable of doing this for you.
If you declare a 'const' array, it stores it in ROM, and handles the address calculations, and the table read operations automatically. You seem to be 'making work' for yourself...

Best Wishes
webbone



Joined: 20 Sep 2004
Posts: 14
Location: Sacramento, CA

View user's profile Send private message

PostPosted: Thu Mar 03, 2005 11:53 am     Reply with quote

Ok, I have tried the suggested method but it seems that I cannot construct items the way I showed in my first post. Specifically, this does not work:

Code:
const char Msg1[] = {0x17,"ABC",0x00};


I have tried changing datatypes to no avail as well - the error "expression must evaluate to a constant" comes up. I understand this isn't what C is expecting, but I don't want to have to write {0x17,0x41,0x42,0x43,0x00} - only the first and last "characters" need to be entered that way, all other data needs to be a string.

My "strings" have a first "character" which will either be an offset or an opcode (depending on the target they are used with), followed by the string data, followed by a terminator (0x00) or opcode (0x80-0xFF). The routine which "reads" this data understands this structure - I'm just trying to come up with a convenient way I can build messages as I showed above which I have previously been able to do just with DB.

Any suggestions will be greatly appreciated. As I mentioned earlier if I have to I will write an external program to generate include files but it would be nice not to have to do so.
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Thu Mar 03, 2005 1:05 pm     Reply with quote

Quote:
const char Msg1[] = {0x17,"ABC",0x00};

That statement won't work in any C. Load up MSVC++ 6.0 and you'll get:

error C2078: too many initializers
webbone



Joined: 20 Sep 2004
Posts: 14
Location: Sacramento, CA

View user's profile Send private message

PostPosted: Thu Mar 03, 2005 1:19 pm     Reply with quote

I now understand that C doesn't recognize what I am trying to do. I am guessing there is no convenient way to do this as I have shown so I will have to resort to writing a program to generate an include file (the progam will translate the strings so that the entire declaration is just 0x41,0x42, etc..)
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Thu Mar 03, 2005 1:49 pm     Reply with quote

You're too eager to give up. What if you look at Ttelmah's recent
post here, http://www.ccsinfo.com/forum/viewtopic.php?t=21974
and modify it a little bit, to give the test program shown below.
It displays this result on the terminal window:
17 ABC

I didn't include the last 0x00 that you have in your example,
because strings are automatically terminated with a 0x00 by
the compiler. If you still want it, you can add it to the
structure declaration.


Code:
#include <16F877.H>
#fuses XT, NOWDT, NOPROTECT, BROWNOUT, PUT, NOLVP
#use delay(clock = 4000000)
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7, ERRORS)


struct T_MSG
{
 char MsgNum;
 char Msg[4];
};

const struct T_MSG Messages[2]  =
{
{0x17, "ABC"},
{0x18, "DEF"}
};


//const char Msg1[] = {0x17,"ABC",0x00};

//============================
main()
{
char c;
char i;
char array[20];

c = Messages[i].MsgNum;
strcpy(array, Messages[i].Msg);

printf("%x  %s \n\r", c, array);

while(1);
}
Mark



Joined: 07 Sep 2003
Posts: 2838
Location: Atlanta, GA

View user's profile Send private message Send e-mail

PostPosted: Thu Mar 03, 2005 2:01 pm     Reply with quote

Code:
const char Msg1[5] = {"\27ABC"};


Will do what you want. Note that you don't have to include the 0x00 since the string is already NULL terminated. Note that the numeric code is in octal so 0x17 is 27 octal.
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group