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 support@ccsinfo.com

#LOCATE NOT COMPILING PROPERLY

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



Joined: 12 Sep 2003
Posts: 12
Location: Val-d'or, Quebec, Canada

View user's profile Send private message Send e-mail Yahoo Messenger MSN Messenger

#LOCATE NOT COMPILING PROPERLY
PostPosted: Mon Dec 08, 2003 7:57 am     Reply with quote

Hi! I'm experiencing some problems with the CCS compiler using the #Locate instruction. I have two 2 dimension arrays and when I compiled the program CCS gives me some bad results.

If I compile my program with these instructions:
byte buffer[6][9];
byte screan_buffer[6][9];

CCS tells me that I have used 78% of the RAM.

if I compile my program with these instructions:
byte buffer[6][9];
#locate buffer = 0x20
byte screan_buffer[6][9];
#locate screan_buffer = 0xA0

CCS tells me that I have used 78% of the RAM.

If I compile my program with these instructions:
byte buffer[6][9];
#locate buffer = 0x120
byte screan_buffer[6][9];

CCS tells me that I have used 47% of the RAM.

And finally, if I compile my program with these instructions:
byte buffer[6][9];
#locate buffer = 0x120
byte screan_buffer[6][9];
#locate screan_buffer = 0x190

CCS tells me that I have used 17% of the RAM.

In the last 2 cases, the microprocessor (16F877) does not run the program.

How can this happen? Question Thanks to you all. Laughing
Ttelmah
Guest







Re: #LOCATE NOT COMPILING PROPERLY
PostPosted: Mon Dec 08, 2003 8:11 am     Reply with quote

peterfreedom wrote:
Hi! I'm experiencing some problems with the CCS compiler using the #Locate instruction. I have two 2 dimension arrays and when I compiled the program CCS gives me some bad results.

If I compile my program with these instructions:
byte buffer[6][9];
byte screan_buffer[6][9];

CCS tells me that I have used 78% of the RAM.

if I compile my program with these instructions:
byte buffer[6][9];
#locate buffer = 0x20
byte screan_buffer[6][9];
#locate screan_buffer = 0xA0

CCS tells me that I have used 78% of the RAM.

If I compile my program with these instructions:
byte buffer[6][9];
#locate buffer = 0x120
byte screan_buffer[6][9];

CCS tells me that I have used 47% of the RAM.

And finally, if I compile my program with these instructions:
byte buffer[6][9];
#locate buffer = 0x120
byte screan_buffer[6][9];
#locate screan_buffer = 0x190

CCS tells me that I have used 17% of the RAM.

In the last 2 cases, the microprocessor (16F877) does not run the program.

How can this happen? Question Thanks to you all. Laughing

You need to add #device *=16 at the top of your program.
By default, the compiler uses 8bit pointers to RAM, which reduces the code size needed to access an address. These no not allow you to talk to addresses above 0xFF. When you locate your arrays below this address, 47% of the available RAM is used by these, and any other storage. When you locate the arrays above this point, the compiler assumes that _you_ are going to access them yourself (you can do this using the 'read_bank', and 'write_bank' instruction). Without 16 bit pointers enabled, or you manually coding the accesses with these instructions, the data is no longer accessable by the program, and hence it won't work.
So you can either switch to using 16 bit pointers (which is what the *=16 tells the compiler to do), or manually code the accesses. The former will increase the code size significantly (every RAM access will now have to assume that a bank swithc may be needed), while the latter is more work.
Look at the manual section entitled:
Why does the compiler show less RAM than there really is?

Best Wishes
peterfreedom



Joined: 12 Sep 2003
Posts: 12
Location: Val-d'or, Quebec, Canada

View user's profile Send private message Send e-mail Yahoo Messenger MSN Messenger

Thank you very much
PostPosted: Mon Dec 08, 2003 9:29 am     Reply with quote

Laughing Thank you very much for your help. It made a big difference. Laughing

Correct me if I'm wrong, but in another topic somebody told me that the maximum dimension of one array would be 96 bytes (6X16). CCS would not be able to jump from one Memory Bank to an other in the same array! Is this TRUE? Question

Thanks again.
Ttelmah
Guest







Re: Thank you very much
PostPosted: Mon Dec 08, 2003 10:11 am     Reply with quote

peterfreedom wrote:
Laughing Thank you very much for your help. It made a big difference. Laughing

Correct me if I'm wrong, but in another topic somebody told me that the maximum dimension of one array would be 96 bytes (6X16). CCS would not be able to jump from one Memory Bank to an other in the same array! Is this TRUE? Question

Thanks again.

Yes.
It is not only that it can't jump banks, but also the addresses have to be sequential. Unfortunately, since there are function registers mapped into the start of each bank, the largest contiguous lump of RAM available is that from a single bank. On the 16F877, this is 96 bytes (though banks 2 & 3, have 112 sequential addresses, the top 16 of these talk to memory already used on bank0).
It is worth remembering that you can save ROM, by not using the *=16 syntax, and you could combine this with your own 'wrapper' function for read_bank, to access memory how you want. Something like:

const int bank[17] = {1,1,1,1,1,2,2,2,2,2,2,3,3,3,3,3,3};
const int addr[17] = {0xA0,0xB0,0xC0,0xD0,0xE0,
0x90,0xA0,0xB0,0xC0,0xD0,0xE0,
0x90,0xA0,0xB0,0xC0,0xD0,0xE0 };

int read_byte(int row,int col) {
return read_bank(bank[col],addr[col]+row);
}

Will allow you to access all the memory in the upper banks as if it was a 16*17 array, with 'row' accepting values from 0-15, and 'col' accepting values from 0-16.
Obviously the arithmetic can be modified to allow the addressing to be from any numbers you want, but you can also see that the conversion needed to access bytes in the right bank and address, is not minor (to include this as standard, would make the code a lot bulkier).
You could do code to access the entire upper memory as if it was sequential with something like:

int read_upper_byte(int address) {
if (address>=0xB0) return read_bank(3,address-0x20);
else if (address>=0x50) return read_bank(2,address+0x30);
else return read_bank(1, 1,address+0xA0);
}

If I have got this right, it should allow you to access almost the entire area of memory above 0xFF, as one block of memory with 256 addresses (it will miss the top 16 useable bytes). Again you can see that the address translation is not minor...

Best Wishes
peterfreedom



Joined: 12 Sep 2003
Posts: 12
Location: Val-d'or, Quebec, Canada

View user's profile Send private message Send e-mail Yahoo Messenger MSN Messenger

Are you sure about that structure?
PostPosted: Mon Dec 08, 2003 1:16 pm     Reply with quote

Thanks Ttelma. I studied your last post and I'm wondering if I understand it. Rolling Eyes
Normaly the read_bank instruction need to have the bank number from 0-3 and the offset from 0 to 0x59 (for bank 1, 2 and 3) and 0 to 0x49 (for bank 1).

This way, accesing Row 0, Column 0 would give read_bank(1,0xA0) and accesing Row 15, Column 16 would give read_bank(3,0xEF) if I understand well.

I was wandering if it should be written like this instead:

const int bank[17] = {1,1,1,1,1,2,2,2,2,2,2,3,3,3,3,3,3};
const int addr[17] = {0x00,0x10,0x20,0x30,0x40,
0x00,0x10,0x20,0x30,0x40,0x50,
0x00,0x10,0x20,0x30,0x40,0x50};

int read_byte(int row,int col) {
return read_bank(bank[col],addr[col]+row);
}


This way, accesing Row 0, Column 0 would give read_bank(1,0) and accesing Row 15, Column 16 would give read_bank(3,0x5F). I think that this is the way to acces RAM via the read_bank instruction.

I also think that I should reserve those memory location with the #reserve instructuction? Exclamation ? What is your opinion? Question
Ttelmah
Guest







Re: Are you sure about that structure?
PostPosted: Mon Dec 08, 2003 3:15 pm     Reply with quote

peterfreedom wrote:
Thanks Ttelma. I studied your last post and I'm wondering if I understand it. Rolling Eyes
Normaly the read_bank instruction need to have the bank number from 0-3 and the offset from 0 to 0x59 (for bank 1, 2 and 3) and 0 to 0x49 (for bank 1).

This way, accesing Row 0, Column 0 would give read_bank(1,0xA0) and accesing Row 15, Column 16 would give read_bank(3,0xEF) if I understand well.

I was wandering if it should be written like this instead:

const int bank[17] = {1,1,1,1,1,2,2,2,2,2,2,3,3,3,3,3,3};
const int addr[17] = {0x00,0x10,0x20,0x30,0x40,
0x00,0x10,0x20,0x30,0x40,0x50,
0x00,0x10,0x20,0x30,0x40,0x50};

int read_byte(int row,int col) {
return read_bank(bank[col],addr[col]+row);
}


This way, accesing Row 0, Column 0 would give read_bank(1,0) and accesing Row 15, Column 16 would give read_bank(3,0x5F). I think that this is the way to acces RAM via the read_bank instruction.

I also think that I should reserve those memory location with the #reserve instructuction? Exclamation ? What is your opinion? Question

You are right, I was generating the actual address to be used, since in the past I have done this in assembler.
No, you don't need to #reserve the addresses, if you leave out the *=16. The whole point is that the C itself will only then access bank0, and it leaves you free to treat bank1,2 & 3, as your own memory. The read_bank and write_bank instructions become the only ones that will set the bank to a value other than zero, keeping the rest of the code as small as possible.

Best Wishes
peterfreedom



Joined: 12 Sep 2003
Posts: 12
Location: Val-d'or, Quebec, Canada

View user's profile Send private message Send e-mail Yahoo Messenger MSN Messenger

Thank you very much Ttelma
PostPosted: Tue Dec 09, 2003 6:39 am     Reply with quote

Laughing People like you make this forum priceless. Laughing
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