View previous topic :: View next topic |
Author |
Message |
Gazza
Joined: 09 Mar 2015 Posts: 3
|
Can't seem to locate a function within a segment |
Posted: Mon Mar 09, 2015 4:25 am |
|
|
Hi guys,
My problem is fixing a function address within a segment, I need "LoaderExec()" to be fixed at 0xfc00. The loader will be installed using the #import(FILE=..., HEX, RANGE=0xFC00:0xFFFF) function.
Code: |
#define LOADER_START 0xfC00
#org LOADER_START, 0xFFFB default
void LoaderExec() { .. }
// Other loader functions ad commands intrepeter
void __LoaderhInit();
{
// Initialise ROM 0 to point at LoaderExec
ZP_ROM [0]=make8(LOADER_EXEC,0);
ZP_ROM [1]=0xef;
ZP_ROM [2]=make8(LOADER_EXEC,1);
ZP_ROM[3]=0xF0;
... ...
reset_CPC();
}
#org 0xFFFC, 0xFFFF
void LoaderInit()
{
__LoaderhInit();
}
#org default
|
When I compile this the functions locate as follows:
Code: |
ROM Allocation:
00FC00 CRC32
00FC54 GetHexDigit
00FC76 @@FLASHWR
00FC96 @@WRITE_PROGRAM_MEMORY
00FCD8 BlockToRom
00FDC4 ExecCommand
00FF28 LoaderExec <<==============
00FFCA __LoaderInit
00FFFC LoaderInit
|
How do I get LoaderExec to locate at 0xfc00. I know I can create an address using "__ADDRESS__ LoaderExec;" but this has ROM overheads which I have little free space for.
At the moment I am copying the address of LoaderExec() from the .sym file and plugging it in to __LoaderhInit() via “LOADER_EXEC”, this cannot be right.
Any help will be gratefully received.
Gaz |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19549
|
|
Posted: Mon Mar 09, 2015 4:34 am |
|
|
The problem is the use/understanding of 'default'.
This makes the compiler put all the compiler library routines also into the same segment. These are always put first.
You'd need to assign these to somewhere in the required segment (since you presumably want these as well, to make the routine work), as a separate #org, and then do an org without using default, where you want to put the routine. Note how 'LoaderInit', which doesn't have the 'default' declaration goes where you want it.
As a comment, you can always get the address, with 'label_address'. |
|
|
Gazza
Joined: 09 Mar 2015 Posts: 3
|
|
Posted: Mon Mar 09, 2015 5:16 am |
|
|
Thanks for the reply Ttelmah,
I understand what you say about “default” and it makes perfect sense.
Does this not mean then that I need to know the actual length of LoaderExec() function to enable me to fix the remaining functions at the correct place in ROM. Again copying data from the .sym file.
Ex.
Code: |
#org 0xfc00, <0xfc00+lengh_of_ LoaderExec>
void LoaderExec() {…}
#org < 0xfc00+lengh_of_ LoaderExec + 1 >, 0xFFFB default
|
… Rest of the loader.
The problem seems to have shifted from knowing the address of the routine to knowing its length. |
|
|
Gazza
Joined: 09 Mar 2015 Posts: 3
|
|
Posted: Mon Mar 09, 2015 5:41 am |
|
|
Trying to use compiler functions to get an address as in "label_address" works in the only in on a label in the current function. Creating an address variable the __ADDRESS__ type adds too much compiler overhead.
All I really need is the compiler to supply a 16 bit number of a fixed address which it already knows because its in the .sym file.
Not to worry, I'll have to stick with hard coding the address from the sym file each time I compile the loader for a different micro. |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19549
|
|
Posted: Mon Mar 09, 2015 6:01 am |
|
|
I think you can solve the problem by doing the declarations separately.
So:
Code: |
#org LOADER_START, 0xFFFB default
//Makes this the default segment
#org LOADER_START, 0xFFFB
void LoaderExec() { .. }
..Now put 'LoaderExec' at the start of the same segment.
|
This tells the compiler to use the required segment for the default code, and then to put the LoaderExec function at the start of this segment.
Since 'default' is already specified the default routines should go into the same segment, but should now go after the routine. |
|
|
|